AI 资讯
SOLID Design Principles: Stop Writing Code That Breaks When You Touch It
Guidelines, not rules. Here's the difference — and why it matters. What is SOLID? SOLID is a set of software design guidelines — not hard rules, but principles that guide how we organize our code. The goal is simple: as your codebase grows and your team scales, things should get easier to change, not harder. SOLID is what makes that possible. Five principles. One goal. Let's walk through each one with real code. S — Single Responsibility Principle A class, function, or method should have one and only one reason to change. The Violation class Bird : def __init__ ( self , name : str , bird_type : str ): self . name = name self . bird_type = bird_type def make_sound ( self ): # two jobs — deciding the type AND making the sound if self . bird_type == " parrot " : print ( " Squawk! " ) elif self . bird_type == " eagle " : print ( " Screech! " ) elif self . bird_type == " owl " : print ( " Hoot! " ) else : print ( " ... " ) make_sound() has two responsibilities — deciding which bird type it is AND making the sound. That's two reasons to change. Add a new bird? Touch make_sound() . Change how sounds work? Touch make_sound() again. Two different reasons, one method. SRP violated. The Fix from abc import ABC , abstractmethod class Bird ( ABC ): def __init__ ( self , name : str ): self . name = name @abstractmethod def make_sound ( self ): pass class Parrot ( Bird ): def make_sound ( self ): print ( " Squawk! " ) class Eagle ( Bird ): def make_sound ( self ): print ( " Screech! " ) class Owl ( Bird ): def make_sound ( self ): print ( " Hoot! " ) # Usage birds = [ Parrot ( " Polly " ), Eagle ( " Sam " ), Owl ( " Oliver " )] for bird in birds : bird . make_sound () Now each class has one responsibility. Parrot.make_sound() only changes if parrots change how they sound. Nothing else touches it. O — Open/Closed Principle A class should be open for extension but closed for modification. SRP and OCP go hand in hand. When you fixed SRP in the Bird example above — you also fixed OCP.
AI 资讯
Glow emerges from stealth at $1.2B valuation to challenge endpoint security in the AI era
Glow is targeting a new class of endpoint risks created by the rapid adoption of AI agents and developer tools inside enterprises.
AI 资讯
Exploring the Deep Learning Library in Modern Computer Vision
Picking the right deep learning library shapes almost everything about a computer vision project, from how fast you can prototype a model to how painful it is to ship one into production. Two frameworks dominate this decision today: PyTorch and TensorFlow. Neither has definitively won, but the split between them has become clearer than it was five years ago, and understanding that split is the fastest way to stop guessing and start building. Why the Choice of Framework Still Matters It's tempting to think framework choice is a solved problem — just pick whatever's popular and move on. But vision work has quirks that make the library underneath your code more than a technical footnote. Custom data augmentation pipelines, non-standard loss functions for tasks like instance segmentation, and the need to export models to mobile or edge devices all behave differently depending on the ecosystem you're in. Market data backs up the idea that this is still a genuinely contested space. TensorFlow holds a larger footprint in enterprise deployment, with roughly 37% market share and tens of thousands of companies using it in production, largely thanks to TensorFlow Serving, TensorFlow Extended, and TensorFlow Lite running across billions of devices. PyTorch, meanwhile, has become the default in research settings, with a majority of recent computer vision papers shipping PyTorch reference implementations first. Job postings mentioning PyTorch have also edged ahead of TensorFlow in recent hiring data, reflecting how much prototyping and applied research work now happens in that ecosystem. PyTorch: The Researcher's Default PyTorch's dynamic computation graph is the feature people mention first, and for good reason. Because the graph is built as your code runs, you can set breakpoints, inspect tensors mid-forward-pass, and change model behavior conditionally without recompiling anything. For anyone iterating on a novel architecture — a new attention mechanism for object detection, s
AI 资讯
HollowGraph Malware Uses Microsoft 365 Calendar Events as Dead-Drop C2 Channel
What Happened On July 20, 2026, cybersecurity firm Group-IB disclosed a new espionage implant dubbed HollowGraph that hijacks compromised Microsoft 365 mailboxes to run a command-and-control (C2) channel hidden inside calendar events. The malware attaches encrypted files to calendar entries dated May 13, 2050 — far enough in the future that a mailbox owner would never scroll to them — and retrieves operator instructions from the same dead drop. All traffic moves through the Microsoft Graph API, making the activity indistinguishable from legitimate M365 usage. At least 12 systems have been infected, with three actively communicating with the threat actor between June 3 and July 9, 2026. The indicators point to a targeted espionage campaign focused on Israeli organizations . Technical Analysis HollowGraph is a lightweight .NET DLL that supports only two commands: GET and SEND . To receive tasking, it queries the compromised mailbox's calendar for an event titled in the format "Event ID: <7-char-taskID>", downloads the attached file, and decrypts it using RSA and AES-256-GCM. To exfiltrate data, the implant creates a new calendar entry titled "Boss{..}ID{..}" and uploads stolen files encrypted with the attacker's public RSA key. The Group-IB research team described the mailbox calendar as a "covert dead-drop," with HollowGraph retrieving commands from events scheduled within a fixed one-hour window between 22:00 and 23:00 UTC on the far-future date. The hybrid encryption scheme uses separate RSA key pairs for inbound and outbound channels, keeping them cryptographically isolated. A second, unencrypted channel runs over DNS tunneling . HollowGraph refreshes its Microsoft Entra ID (Azure AD) credentials by querying IPv6 AAAA records from the attacker-controlled domain cloudlanecdn[.]com . Each returned IPv6 address yields 14 usable payload bytes, which the malware assembles and decodes as UTF-8 text to update its logAzure.txt configuration file — a file masquerading as a
AI 资讯
Stack Overflow Is Dying. The AI That Killed It Could Be Next.
Stack Overflow's question volume has been falling since ChatGPT went public in November 2022 ( OpenAI ). The site that trained a generation of developers, and most of the AI tools those developers now use, is slowly emptying out. In October 2023, Stack Overflow laid off 28% of its staff ( Stack Overflow Blog ). CEO Prashanth Chandrasekar framed it as a restructuring toward profitability. Everyone in the industry understood the real cause. Traffic was down. The thing causing it was sitting in every developer's browser tab. This is not another "AI killed Stack Overflow" piece. That take is everywhere and it misses the actual problem. The interesting part is the feedback loop, and it points somewhere uncomfortable for the AI industry itself. The conventional story, and what it misses The popular version goes like this. Developers used to paste error messages into Google and land on a Stack Overflow thread. Now they paste the same error into ChatGPT, Claude, or Copilot and get a direct answer. Why click through to a forum, risk a condescending comment, and wait for a human when a model answers in two seconds? That part is true. It explains the traffic drop. It does not explain why the people building the AI should be worried. The seed corn problem Here is the part most coverage skips. Every large language model trained on internet text consumed a huge amount of Stack Overflow. The site's archive of voted, edited, human-reviewed answers is one of the highest-quality programming datasets in existence. It is the reason an AI can answer your Python error at all. Now run the loop forward. AI tools answer questions directly. Developers stop posting on Stack Overflow. The archive stops growing. The next round of models trains on a corpus that is increasingly old, increasingly stale, and missing everything that happened after 2022. When you train an AI on data generated by another AI, quality degrades. Researchers proved this formally. Shumailov and colleagues showed that model
AI 资讯
A Practical Workflow for Contributing to a Large, Structured Codebase
This is the workflow I follow before I use AI agents to implement any feature or bug fix. 🧭 Requirements/Specification ↓ Design/Architecture ↓ AI Code Generation ↓ Human Review ↓ Build & Static Analysis ↓ Testing & Validation ↓ Defect Resolution ↓ Security & Compliance Review ↓ Release ↓ Production Monitoring vs Claude Code ↓ Implements feature ↓ Codex QA Agent ↓ Runs application ↓ Tests happy path ↓ Tests edge cases ↓ Tests error handling ↓ Produces QA report This will resolve the self-review bias, confirmation bias, or AI-to-AI bias. 1️⃣ Understand Before Writing Code Before touching any code, I try to understand what I'm building and why . I usually start by reading: specs/<module>/<TICKET>-<slug>.md plan/<module>/<TICKET>-<slug>.md status.md Then I review the project conventions: specs/CONVENTIONS.md specs/conventions/core-porting.md Finally, I read the existing implementation (entities, services, mappers, etc.) so my changes follow the existing architecture instead of introducing a new style. 💡 Pro-Tip Good code fits into the codebase. Great code looks like it was always there. 2️⃣ Plan the Change Once I understand the requirements, I identify which architectural layers are affected. I always respect the dependency order: Schema / Entities / DAOs ↓ Mappers / DTOs ↓ Service Layer ↓ Application Layer ↓ Controllers I don't jump ahead of dependencies. If a change is complicated or ambiguous, I document the approach before writing code. --- ## 3️⃣ Write the Code While implementing, I follow the repository's rules. Some examples: | Rule | Detail |---|---|---| | DTOs | Generated from `schema.yml` — never handwritten | | Status values | Sourced only from the Core Porting specification | | Traceability | Every ported behavior includes a source citation | Citation formats I use: - `← Source <path>` - `← PS §...` - `← BR-###` Beyond repository rules, I also try to: - ✅ Match existing naming conventions - ✅ Keep comments minimal and meaningful - ✅ Make small, focused chang
AI 资讯
How to Build an AI Agent with n8n
Building an AI agent with n8n is the fastest, cheapest way to turn a large language model into a useful worker — if you stay within its sweet spot. The honest truth, informed by the custom agents we ship, is that n8n carries a well-scoped agent further than most people expect. An LLM node, a few tool/webhook nodes and a trigger are all you need. This guide walks you through that exact workflow and, just as importantly, names the precise moment n8n stops cutting it and a custom build must take over. What You Need Before You Start You'll need a running n8n instance (self-hosted or cloud) and API keys for the services you want to integrate. Grab a Gemini or OpenAI key from their respective developer consoles — n8n's official AI agent builder documentation lists the full compatibility. The quick-start template also gives you a one-click import to see an agent's skeleton immediately. How to Build an AI Agent with n8n: The Core Workflow The core is a chain of nodes: a trigger wakes the agent, an LLM node reasons, and tool/webhook nodes take action. That's the entire pattern. Here's how to assemble it. Set the trigger Drag a Webhook node onto the canvas if you want the agent called via HTTP, or a Schedule node to run it periodically. For our example, we'll use a webhook that receives a customer question. Add the LLM node Attach an OpenAI Chat Model (or Gemini) node. In the node's parameters, craft a system prompt that scopes the agent. For a support bot, something like: You are a helpful support agent for our SaaS product. Use the tools provided to answer questions. If you don't know, say you need human help. This prompt is the boundary of the agent's autonomy. Keep it specific — vagueness leads to hallucinations. Attach tool and webhook nodes Here's where n8n shines. Drag a Function node to run custom JavaScript (e.g., querying a database) or a HTTP Request node to call an external API. Wire them as "tools" by connecting them to the LLM node's tool output. In the LLM node
AI 资讯
Designing a Three Reviewer Consensus Platform for Digital Harm Reporting
The Problem Real411 is a South African platform where citizens report digital harms: misinformation, incitement, hate speech, and harassment. When someone submits a complaint, it needs to be reviewed by multiple people, assessed against legal criteria, and resolved with a public verdict. The process must be transparent, auditable, and fair. I joined this project early and worked on it extensively over a long period. A senior solutions architect consulted on the database schema design. There was a cloud person who helped with parts of the infrastructure. Other coworkers contributed at different stages. I spent most of my time on the API layer and the frontend components. This article covers the architecture decisions I worked with, what I learned from the senior architect's design choices, and how the system evolved. The Status Machine Most applications model status as a column on a table. You update the value and the old state is gone. That works for simple workflows but fails when you need to know not just where a complaint is now, but how it got there and who made each decision. The senior architect who consulted on the database design suggested an append only status log. Instead of a single status column, the complaint_status table records every transition as a separate row. Each row has the status code, the user who made the change, a timestamp, and optional notes. The current status is derived by querying the most recent row. I implemented this pattern across the API layer. Every status transition became an insert operation rather than an update. It took some adjustment to shift from mutable state to event sourced state, but the benefits were immediate. Auditing became straightforward. The state machine also became easier to implement because each transition is a simple insert with a business logic check, not a conditional update. The schema has seventeen status codes covering the full lifecycle: received, claimed, under assessment, pending secretariat review,
产品设计
Solution to Feynman's reverse sprinkler puzzle also applies to "silly sprinklers"
New study confirms 2024 "momentum flux theory" on how angular momentum of water flows drives rotation.
AI 资讯
They Asked for My AI Rules. But I Could Not Just Hand Them Over.
A team lead announces that the team will start using AI-assisted development. Everyone nods. Nobody asks what that actually means on Monday morning. Some times ago I was in that position. A project I was working on needed to start using AI-assisted development, and the team was new to it. Nobody had rules written down for an agent to follow. Nobody had skills defined for it to load. There was no shared idea of how this should work inside our specific repo. Someone had to go first. That someone was me. The rules worked because I built them for one repo I spent time curating a set of rules and skills for that project. Not generic ones. I shaped them tightly around how that repo was actually structured, its conventions, its layout, the things a new engineer usually has to learn by asking around. I wanted an agent working inside that codebase to already know what a human teammate would have picked up in the first two weeks. I gave a demo. It landed well. Well enough that it got shared further across team, as something other teams could learn from. I gave the demo again. Same reaction. Then a few developers reached out for the actual rules and skills files. I said sure, and then I actually looked at what I would be handing them. The problem showed up the moment other people wanted in It was not copy-paste-able. The rules referenced folder names, module boundaries, and patterns specific to one repo. Handing them over as-is would have meant handing over advice that was wrong for their project, dressed up as a shortcut. So I told them to use it as a reference. Look at the structure, understand the reasoning, adapt it to your own repo. That is correct advice. I watched people nod at it and then quietly missing it. I was solving the wrong problem the whole time I had been thinking about this as a documentation problem. Write good rules, explain them well, let people copy the idea. What I actually had was a generation problem. The rules that worked were the ones rendered speci
AI 资讯
Article: Removing a Hidden Round Trip from a Multi-Region AWS API
When a series of regional outages forced a rethink of a multi-region AWS API, the team discovered that an obstacle to global failover was hiding in plain sight: a pre-flight discovery call baked into every client session years earlier as the only available option. This article describes what it took to remove it, and what the rollout actually cost. By Suresh Gururajan
AI 资讯
Pipeline, Flow, or Chain? Picking the Right Tool to Wire LLM Calls Together
In the previous post I argued that agents are great planners and DAGs are great executors . This one is the practical follow-up: when you actually sit down to wire several LLM calls together, what tool do you reach for? Because the moment one prompt's output feeds the next, you've built a workflow — whether you call it that or not. download transcript → summarize → translate (tool) (LLM) (LLM) That tiny pipeline is already the whole problem in miniature: a non-LLM step (fetch a YouTube transcript), then a model call, then another model call that depends on the first. Run it as one giant prompt and you lose visibility; split it into steps and you gain debuggability — at the cost of more calls and more state to manage. The naming trap Half the confusion is vocabulary. The same idea ships under a dozen labels: Name What it whispers Chain sequential, output → input Pipeline stages, data flowing through Flow branches and conditions Workflow general orchestration Agent workflow the model also decides The word sets expectations. "Chain" promises a straight line; "agent workflow" promises the thing might re-plan on you mid-run. Pick the label that matches how much autonomy you're actually handing over — calling a deterministic two-step pipeline an "agent" only invites disappointment. The real choice: library or orchestrator? There are two families of tools, and they solve different problems. LLM-native chaining libraries — LangChain , LlamaIndex Workflows , Azure Prompt Flow , or visual layers like Flowise . These understand LLM-specific concerns out of the box: prompt templating, passing context between steps, token budgets, streaming, retries on a flaky model. General orchestrators — Airflow , Prefect , AWS Step Functions , Azure Logic Apps . These treat each LLM call as just another task in a DAG, and give you the heavyweight reliability machinery: durable state, scheduling, checkpointing, audit trails, human approval. The rule of thumb that falls out of the last post: F
AI 资讯
From Prompts to Pipelines: How I Use Agentic Coding as an Engineering Workflow
I am interested in agentic coding for the same reason I care about good engineering process in general: I want work to move forward in a way that is inspectable, repeatable, and resilient once the task gets messy. A lot of AI-assisted coding still feels like improvisation. You ask for something, get a result, adjust the prompt, try again, and hope the useful reasoning is still somewhere in the scrollback. That can work for tiny edits. It gets much less convincing when the task starts touching architecture, tests, review, or pull requests. What I want instead is a workflow where the model helps me think and execute, but inside a structure I can inspect afterwards. I want artifacts, gates, and something I can resume tomorrow without reconstructing the entire mental state from memory. That is why I use po8rewq/agentic-skills . It gives me a practical way to do agentic coding as an engineering workflow rather than as a long sequence of chat turns. A task moves through requirements, architecture, implementation, checks, review, and pull request creation. Each stage leaves something I can read, verify, and challenge. What makes this interesting to me The interesting part is not just that there is a CLI. Plenty of tools have a CLI. What matters to me is that it turns AI-assisted coding into a staged system: requirements force the task to become explicit architecture makes risks visible before code is written implementation happens against a plan instead of against a vague prompt checks and review happen as part of the flow, not as an afterthought runs are resumable, so interruptions do not destroy context That changes the feel of the work quite a bit. Instead of asking "what should I prompt next?", I am usually asking "what stage is this task in, and what should exist before I move on?" Where this really clicked for me was when I noticed I was spending less energy trying to preserve context in my head and more energy evaluating actual outputs. What the repository actually
AI 资讯
Why I Choose Lovable for Building Full-Stack Applications with AI
Why I Choose Lovable for Building Full-Stack Applications with AI Over the last year, AI-assisted software development has evolved from generating code snippets to building complete web applications. We've all seen tools like Cursor, Claude Code, GitHub Copilot, Replit Agent, Bolt, and many others enter the market. Each has its strengths, but after experimenting with several of them, I keep coming back to Lovable whenever I want to build a new web application from scratch. This isn't a sponsored post—it's simply the workflow that has worked well for me. If you're interested in trying Lovable, you can use my referral link below. Disclosure: new users receive additional signup credits, and I receive referral credits if you sign up through it. Referral: https://lovable.dev/invite/AQ02SOZ Why Lovable Stands Out Most AI coding assistants help you write code. Lovable helps you build an application. Instead of focusing on individual functions or files, it takes a higher-level approach where you describe what you want, and it generates a complete full-stack application that you can continue refining. A typical workflow looks like this: Idea │ ▼ Describe the application │ ▼ Lovable generates • Frontend • Backend • Database • Authentication • API integration │ ▼ Preview instantly │ ▼ Connect GitHub │ ▼ Iterate and Deploy Unlike traditional no-code platforms, you're not locked into a proprietary editor. Lovable supports GitHub synchronization, native Supabase integration for authentication and PostgreSQL-backed data, and deployment options ranging from Lovable-hosted apps to your own infrastructure. Why I Keep Choosing Lovable After building several side projects, these are the reasons I continue to use it. 1. Rapid idea-to-production workflow The biggest productivity gain isn't AI-generated code. It's reducing the number of decisions needed before users can interact with your application. Instead of spending hours creating project structure, authentication, routing, database
AI 资讯
Workflow Series (05): Evaluation Framework — Three-Layer Testing and Trace Tracking
Why Workflows Need a Dedicated Evaluation Framework Traditional software testing covers code correctness. Workflows add two layers of uncertainty: LLM output is non-deterministic : the same input can produce different results across runs Cross-step dependencies : a Phase 3 problem may only surface at Phase 7, making the debugging chain long Without an evaluation framework, every workflow change requires a full end-to-end run: slow, expensive, incomplete coverage. Three-layer testing decomposes the problem. Three-Layer Evaluation Structure Layer 3: End-to-end tests (Workflow level) Full pipeline from trigger to completion Test cases: eval/cases.yaml Metrics: completion rate, Phase 4 avg rounds, gate trigger rate Layer 2: Integration tests (Phase level) Cross-step data flow is correctly passed Cross-phase routing logic fires correctly Layer 1: Unit tests (Step level) Each subagent's output matches its output contract No real LLM calls — validates JSON schema only Test priority: Layer 1 should be the most numerous and fastest — catches contract violations in seconds. Layer 3 is the slowest and most expensive — run it only when changes affect the main pipeline. Layer 1: Step-Level Unit Tests Unit tests verify that subagent output files match the declared schema. No real LLM calls needed. # tests/unit/test_phase3_output.py import json from pathlib import Path def test_analysis_output_schema (): """ Phase 3 output must conform to analysis_final.json schema """ output = json . loads ( Path ( " test_fixtures/phase3/analysis_final.json " ). read_text ()) assert " passed " in output assert isinstance ( output [ " passed " ], bool ) assert " confidence " in output assert 0.0 <= output [ " confidence " ] <= 1.0 assert " root_cause " in output assert isinstance ( output [ " root_cause " ], str | type ( None )) assert " evidence " in output assert isinstance ( output [ " evidence " ], list ) # on failure, error field must be present and non-empty if not output [ " passed " ]: ass
AI 资讯
Libby will filter out AI content, kind of
This is Lowpass by Janko Roettgers, a newsletter on the ever-evolving intersection of tech and entertainment, syndicated just for The Verge subscribers once a week. "AI is the new frontier for us," says Marc DeBevoise, who took over as the new CEO of OverDrive last week. OverDrive is best known for the ebook lending app […]
AI 资讯
The Workflow is the Product: Why Enterprise AI Must Move Beyond Copilots
For the last few years, many enterprise AI conversations have started with the same question: “Where can we add an AI copilot?” It is an understandable starting point. Copilots are familiar. They sit inside existing tools, help users draft content, summarize information, search documents, write code, or answer questions. For teams experimenting with AI, they feel safe. But after 10 years of building mobile apps, web platforms, AI systems, internal tools, and enterprise-grade products, I have learned something that sounds simple but changes the whole strategy: The workflow is the product. Not the chatbot. Not the prompt box. Not the model. Not the dashboard. The workflow. Enterprise AI only becomes valuable when it changes how work actually moves across people, systems, approvals, decisions, and data. That is why companies now need to move beyond standalone copilots and toward AI workflow automation, enterprise AI agents, and agentic workflows that are designed around real operational outcomes. Copilots Help. Workflows Transform. An AI copilot is useful when a person needs assistance inside a task. It can draft an email, summarize a meeting, search policy documents, or help an engineer understand code. These are valuable use cases. But they usually improve a single moment of work, not the complete business process. A workflow, on the other hand, connects the full chain. For example, consider enterprise customer onboarding. A copilot may summarize the sales call. A workflow system can take that summary, extract requirements, identify missing information, create onboarding tasks, notify customer success, update the CRM, generate a kickoff plan, check billing setup, and flag delivery risks. That is a very different level of impact. AI Copilot AI Workflow Automation Assists one user Coordinates work across teams Responds when asked Triggers actions automatically Works inside a tool Connects multiple systems Improves productivity Improves operating performance Helps with
AI 资讯
Solving IP Endianness in x64 Assembly: A Single-Pass Algorithm
Research Context When doing low-level network programming in Assembly, you experience firsthand the immense chaos running behind the scenes of operations we solve with a single line in high-level languages (Python, C, etc.). While developing the Nested-ICMP-Communication Analysis project, specifically an Encapsulated ICMP framework, I hit exactly this kind of wall: extracting an IP address from a packet header and printing it to the screen in the correct format. Sounds simple, right? However, when x86 architecture and network protocols are involved, seeing 5.1.168.192 instead of 192.168.1.5 on your terminal is extremely common. So why does this happen, and what kind of algorithm did I develop to overcome this issue during the debugging process? Let's dive into the background. The Endianness Problem in Network Headers When you capture a packet coming over the network and read the source/destination IP address inside the sockaddr_in structure, the data arrives in Network Byte Order (Big-Endian) format. This means the most significant byte is stored at the lowest memory address. However, the x86/x64 processor architectures we use rely on Little-Endian (Host Byte Order). When the processor pulls this 4-byte IP data into a register, the reading direction is effectively reversed for our purposes. The result? A packet that arrives as 192.168.1.5 appears scrambled if we try to naively print it from memory. The inet_ntoa() function in high-level languages handles this conversion in the background. But if you are writing a custom sniffer in pure Assembly, you must do this conversion byte by byte yourself. Debugging Hell: The Problems Encountered While writing this conversion, I encountered a few critical issues that cost me hours in GDB (GNU Debugger): Register Clashes: While separating each octet (byte) of the IP address and converting it to an ASCII character (string), you must use the AX register for division operations (DIV). If you don't carefully manage your remainders
AI 资讯
GitHub Actions adds a background marker, and the linear job stops being the only shape
A small word that changes the rhythm of a job For as long as I have been writing Actions workflows I have been carrying a quiet workaround in my head. Want to warm a cache while the build runs? Append & to the shell command, then squint at logs that arrive out of order and pray the job doesn't exit on you. It worked, sort of. It also meant that anything more interesting than "run one thing, then the next thing" lived as folklore, hidden inside run: blocks. GitHub closed that gap this week. On June 25 the Actions changelog announced that steps inside a job can now run concurrently, marked with a new background keyword and supported by helpers to wait for them and cancel them. Until now, the changelog notes, every step in a workflow ran in sequence, with each step starting only after the previous one completed. That single rule has shaped every workflow I have ever written. It is gone, and the replacement is the kind of feature you don't notice until the day you reach for it and it's there. What the keywords actually do There are four pieces, all of them documented in the announcement. background: true is the entry point. Set it on a step and that step starts running, and the next step starts immediately. It does not block the job. wait and wait-all are the rendezvous. wait pins on one or more named background steps and pauses until they finish. wait-all is the same idea against every background step still in flight. Either way you get back into a linear flow on your terms. cancel is the cleanup. It gracefully terminates a background step when you no longer need it, which is the missing piece if you have ever tried to kill a long-running side process from inside a job and ended up shelling out to kill . parallel is the convenience wrapper. The changelog describes it as taking a group of steps and converting them into background steps with a wait placed after. For the common "fan out, then join" shape, you write one block instead of decorating five steps by hand. Where
AI 资讯
How the World Cup became a US streaming success story
This is Lowpass by Janko Roettgers, a newsletter on the ever-evolving intersection of tech and entertainment, syndicated just for The Verge subscribers once a week. The 2026 World Cup is breaking streaming records around the world: Brazil's CazéTV YouTube livestream of that country's opening game against Morocco surpassed 12 million concurrent viewers, a new milestone […]