Products Writing Track Record Expertise Contact
← Back to Writing
2026-09-22 · AI Engineering

AI Made My Pipeline the Bottleneck, So I Let AI Run It

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 optimization is a static change frozen back into config. Faster runners, shallower checkouts, merged jobs, rebalanced shards. Whether humans or agents wrote those patches, the pipeline itself still decides nothing at runtime. They made the road faster. The road still does not get to decide anything.

I hit the same wall months earlier, and I made a different choice. Instead of only making the pipeline faster, I started handing some of its decisions to the agents.

Pipelines are guardrails. The mistake is freezing them.

CI/CD pipelines exist as guardrails, and that does not expire in the agent era. An agent can be wrong just like a tired engineer at 11pm, so the rails stay. What is outdated is how we built them. We expressed every safeguard as a frozen decision. Every step runs every time, because the script cannot judge whether it is needed. Every deploy rebuilds everything, because the script does not know what changed.

The fix is not removing the rails. It is separating the rail from the judgment. In development, where iteration speed is everything, the agent gets freedom: skip what provably did not change, deploy only what did. Production keeps strict gates: full checks, explicit approvals for anything risky. Freeze the rail, not the judgment.

The admission ticket: verifiable outcomes, cheap corrections

How do I decide which decisions an agent is allowed to make? One test: is the outcome verifiable, and is a mistake cheap to correct?

A partial deploy in development passes both halves. The agent deploys what changed, verification runs, and if something was missed the agent can see it and fill the gap itself. The loop closes without me. Production fails both halves. Verification is slower, mistakes are expensive, and here is the part people skip: production never needed the five minutes anyway. Speed is a requirement of the development loop, where you iterate all day. Production ships a handful of times. Saving five minutes there buys nothing and risks everything.

So the split is not a compromise. Development gets autonomy because autonomy is safe and valuable there. Production keeps gates because gates are cheap there and speed is worthless there.

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.

This works because the admission test holds. A deploy in development is verifiable, so the agent checks its own work afterward. If a partial deploy missed something, it notices and ships the rest itself. I stopped being the verification layer for routine releases.

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 admits the work does not end. A pipeline that only gets faster when someone stops 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 still 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?”

Only where the admission test holds. 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. The day it makes a bad call inside the box, the box gets smaller. So far the box has only gotten bigger. And where the test fails, where outcomes are slow to verify and mistakes are expensive, there is no box at all. Production keeps its gates.

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 config by people who are no longer the ones doing the work.

Linear answered by making the road faster. My answer is to let the drivers run the parts of the road where their mistakes are verifiable and cheap, and to keep the toll gates exactly where they were. If you maintain a pipeline today, go look for its frozen decisions: the steps that run every time simply because the script cannot tell whether they are needed. Check each one against the admission test. If the outcome is verifiable and the correction is cheap, hand it over. 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.

Wellington, New Zealand