In April I was in Silicon Valley, talking with engineers at Anthropic about a problem that had not gone public yet. Coding agents were getting fast enough that the slow part of shipping software was no longer writing the code. It was everything after: CI, validation, deployment. The pipeline.
This week Linear published a post about hitting that same wall. Their test suites almost quadrupled since January. They add roughly 2,000 tests a week, and agents write the majority of them. Every pull request still has to pass through a CI system designed for a world where humans wrote code at human speed. Wait times and infrastructure costs went up together, so their CTO opened an issue: “CI costs are high.” Also, make it faster.
Their writeup is worth reading. They moved off GitHub Actions to faster runners, cut one checkout step from 94 seconds to 20, deleted redundant setup everywhere, batched seven tiny jobs into two, and rebalanced test shards. PR wait time fell from over 6 minutes to just over 5, and runner time per test dropped by about half. Solid engineering.
But reading it, I noticed something about the shape of the work. Every single optimization was a human tuning the pipeline so agents could go faster. Humans repairing the road so the robots can drive.
I hit the same wall months earlier, and I made a different choice. Instead of only making the pipeline faster, I started handing the pipeline’s decisions to the agents.
Pipelines are guardrails built for humans #
CI/CD pipelines were designed as guardrails for careless humans. Deterministic, exhaustive, and dumb by design. Every step runs every time, because a script cannot judge whether it needs to. Every deploy rebuilds and redeploys everything, because the script does not know what changed.
That design made sense when the alternative was trusting a tired engineer at 11pm. It makes less sense when the entity doing the work can read the diff, understand the dependency graph, and state exactly what it touched.
Every fixed decision in a pipeline exists because the old executor could not be trusted with judgment. The executor has changed. The judgment calls have not moved.
What I changed #
My deployment used to be all or nothing. Every release rebuilt and redeployed everything, about 15 minutes, even when the change touched one small piece. I changed the deploy interface so the agent passes parameters describing what actually changed, and the pipeline deploys only that. Everything unchanged stays put. The agent got a degree of freedom, inside boundaries I defined.
The setup work Linear’s post describes in detail, caching strategies, lean images, installing only what each job needs, I did a long time ago. That part is table stakes now.
The more interesting trade is on the other side. The same agents write far more test cases than I ever wrote by hand, and that adds CI time back. Linear saw the same thing at scale: agent-written code demands agent-written tests, so validation load grows faster than code output. I accept the cost. The reliability is worth it, and the right response to more validation work is not less testing. It is a cheaper pipeline, maintained continuously.
That last word matters. I do not tune the pipeline once and walk away. The agents keep optimizing it as the codebase grows, within a cost budget I set. Pipeline efficiency stops being a project and becomes a maintained property of the system, like uptime.
The math compounds #
Here is why I think this is the only sustainable path. Agent-written code needs agent-written tests to be trustworthy. More tests mean more validation work. Validation work grows faster than the code itself, because every new feature adds tests that run on every future change. The load is superlinear.
Against a superlinear load, a one-time optimization is a delay, not a fix. Linear’s own numbers show it: without this year’s rebuild, their suite would take 11 minutes today instead of 5. Great. But they are still adding 2,000 tests a week, and their post ends by admitting the work does not end. A pipeline that only gets faster when humans stop to fix it will always lag the traffic.
A pipeline that agents maintain compounds differently. Each optimization sticks, and the next one starts from a better baseline. You are still going to lose ground some months. But you are fighting superlinear growth with something that can also grow.
The obvious objection #
“You let an agent decide what gets deployed?”
Not quite. The agent does not get permissions, it gets parameters. I define the interface, the options, and the blast radius. Within that box it exercises judgment I used to exercise by hand, like deciding whether this change justifies redeploying the whole system or one service. Bounded autonomy, not free rein. The day it makes a bad call inside the box, the box gets smaller. So far the box has only gotten bigger.
This is the same pattern I use everywhere else with agents: guardrail decisions become typed parameters, routine cases flow through, and only the weird ones interrupt me.
The bottleneck always moves to the next human #
There is an old pattern here. Every time a production tool gets 10x faster, the bottleneck moves downstream to the next human in the loop. Compilers moved it to code review. Code review moved it to QA. Now agents have moved it to the pipeline, and the pipeline is the last place where every decision was frozen in YAML by a human who is no longer the one doing the work.
Linear answered by making the road faster. I think the real answer is to let the drivers run the road. If you maintain a pipeline today, go look for its fixed decisions: the steps that run every time simply because the script cannot tell whether they are needed. Each one is a candidate for agent judgment. Start with the least destructive one. For me it was deploy scope. Fifteen minutes became a parameter, and I have not thought about it since.