The New Bottleneck: From Writing Code to Trusting It
A coding agent disappears for six minutes and comes back with an implementation, tests, updated docs, and a pull request.
Great.
Now somebody has to decide whether any of it is safe to ship.
That part hasn’t gotten six-minutes fast.
For most of software engineering history, producing a change consumed a meaningful chunk of the work. You had to understand the problem, find the relevant code, write the implementation, debug it, write tests, clean things up, and eventually open a PR.
The work itself acted as a kind of natural throttle.
AI is removing that throttle.
An engineer can now hand off several implementation tasks in parallel and get back more code than they could reasonably have written themselves. Agents can work across repositories, generate tests, fix CI failures, respond to review comments, and keep going long after the initial prompt.
That’s a real productivity gain.
But it creates an uncomfortable systems problem:
we made one stage of software delivery dramatically faster without making the rest of the system dramatically faster.
Reviewers didn’t get ten times more attention.
Integration tests didn’t get ten times cheaper.
Staging environments didn’t become infinitely parallel.
And production didn’t suddenly become understandable from the repository alone.
So the bottleneck moves.
When one part of the system gets faster
There’s a tendency to talk about AI developer productivity as though engineering throughput is approximately:
developer output × AI multiplier
But that’s not how systems work.
If one stage can produce 40 changes a day and the next stage can only reliably consume 12, you don’t have a 4× faster system – you have a queue.
The same thing happens in factories, networks, databases, and engineering organizations. Speeding up a component only increases system throughput until something else becomes the constraint.
AI didn’t remove the software engineering bottleneck, it exposed it.
And increasingly, the scarce resource is confidence.
Not:
Can we make this change?
But:
Do we have enough evidence to trust it?
What exactly does a review mean now?
The pull request workflow makes sense partly because of an assumption we’ve had for years:
the person reviewing a change can build a reasonable mental model of it.
Someone writes 300 lines.
Someone else reads 300 lines.
They ask a few questions, notice a suspicious edge case, maybe request another test. Inevitably, the time-honoured message appears: LGTM.
That model gets weird when producing another 2,000 lines costs almost nothing.
A reviewer can still inspect a 1,500-line agent-generated pull request, of course. The question is what kind of inspection is realistically happening. Did they reconstruct the intent behind every change? Did they understand the generated tests? Did they notice the infrastructure edit buried halfway through the diff? Did they reason through every interaction with the existing system?
Sometimes yes. Often, probably not.
That doesn’t make human review useless. Far from it. Humans remain very good at the parts of engineering that require judgment: whether an architecture makes sense, whether a change matches product intent, whether a tradeoff is reasonable, whether the implementation is creating complexity the local diff doesn’t justify.
But it does suggest that we should be more deliberate about what we expect a reviewer to certify. “LGTM” used to aspire to something like:
I understand what this change is doing, and I don’t see a reason not to ship it.
At sufficient volume, it starts drifting toward:
Nothing looked obviously terrifying in the time I had.
Those aren’t the same thing.
A this point you might be tempted to think that that humans should stop reviewing code – but that’s not the right conclusion.
There are parts of a change where human judgment becomes more important in an AI-heavy workflow:
- Is this actually the right solution?
- Does it fit the architecture?
- Are we introducing a weird long-term dependency?
- Is the scope sane?
- Is the agent solving the problem we intended it to solve?
- Is this change risky enough to deserve deeper scrutiny?
But that is different from pretending every generated line deserves the same amount of human attention.
If machines can create changes much faster than humans can consume them, the SDLC needs other forms of evidence to carry more of the validation load.
So why not let AI review the AI?
The obvious next step is automated review, and we’re already seeing it happen. AI reviewers can catch suspicious patterns, missing tests, inconsistent behavior, security problems, and implementation mistakes at a scale that human reviewers can’t match.
That’s super useful! But it still leaves us with a deeper problem: a reviewer can only reason from the information available to it.
Give an agent the repository, the diff, the ticket, and the test results, and it may develop a very good understanding of the software as represented in those artifacts. But software has another life outside the repository.
It runs.
Real users take paths through it that the code does not rank by importance. Dependencies degrade in ways tests did not anticipate. A seemingly minor helper can sit underneath the busiest endpoint in the application. A retry that looks perfectly reasonable from the caller can make an already overloaded downstream service collapse faster.
None of those situations require the code reviewer to be “bad.” The missing ingredient is evidence.
Static code tells you what can happen.
Tests tell you what you expect to happen.
Production tells you what is actually happening.
Those are different sources of information, and mature engineering decisions usually rely on more than one of them.
Confidence isn’t an approval
We tend to compress software validation into binary events.
PR approved.
Tests passed.
CI green.
Deployment successful.
Those events are useful – but none of them individually means this change is safe.
Different signals establish different things: Code review can tell you whether an implementation looks sensible, tests tell you whether behavior we’ve anticipated still works, static analysis tells you whether the change violates properties we can infer from the code, CI tells you whether the change survives the automated checks we’ve chosen to run, and production context tells you where this code actually participates in the running system, why it failed or slowed down, and how it performed under real traffic.
These signals overlap, but they are not interchangeable, which leads to a more useful mental model:
Confidence is accumulated from evidence, not granted by one gate.
Flip from repository to reality
Production context supplies a different class of evidence and once you have it, some engineering questions change.
Instead of:
What files does this PR modify?
you can ask:
Which production flows actually execute the functions we’re changing?
Instead of:
Did the tests covering this package pass?
you can ask:
Are we touching a path responsible for a large amount of real traffic?
Instead of:
Did deployment succeed?
you can ask:
What changed in the behavior of the new version once traffic arrived?
This matters for humans and it matters even more for agents.
An experienced engineer has accumulated years of weird contextual knowledge:
- Be careful with that function, anybody that touches it breaks the checkout.
- This DB query is aggregated this way on purpose.
- That dependency is fragile during traffic spikes.
- This looks like a safe retry but we’ve been burned by it before.
- We have legacy frontend clients that will break if this changes.
Agents don’t automatically have that intuition.
If we want to hand them more autonomy, we need to replace some of that informal human context with evidence they can actually consume.
Consider a concrete example. You’re reviewing an AI-generated change to an arbitrary function called buildSessionContext(). The agent wants to cache session lookups to avoid repeated calls to the session service.
async function buildSessionContext(req) {
– return await getSession(req.headers)
+ return sessionCache.get(req.sessionId)
+ ?? sessionCache.set(
+ req.sessionId,
+ await getSession(req.headers)
+ )
}It’s a plausible optimization, and the diff alone doesn’t tell you whether to worry about it. What follows is the same change viewed with two different kinds of evidence.
Review should become risk-based
Once code generation becomes abundant, treating every change identically gets expensive very quickly.
The alternative isn’t “no controls.”
It’s smarter controls.
A modern validation system should be able to ask:
- What changed?
- Where does it run?
- How important is that path?
- What evidence already exists?
- What do we still need to establish?
That can lead to very different workflows.
A low-risk change might get:
automated review → targeted tests → merge.
A higher-risk change might trigger:
human architectural review → expanded test set → production-aware validation → progressive rollout → automatic comparison.
The point isn’t the exact sequence.
The point is that human attention and machine validation should follow risk rather than ceremony.
That’s a very different philosophy from:
Every PR needs two approvals because that is our process.
Or:
Every service runs the full test suite because that is our process.
Or:
Production validation happens after the deployment because that is where observability lives.
When code becomes cheaper, fixed-cost ceremony gets more expensive relative to the thing being produced – the SDLC has to adapt.
The SDLC can’t stop at the pull request
Look at how good coding agents are becoming at the development loop:
Plan → Code → Test → Review → PR
That’s a remarkably useful loop – but it is also an oddly arbitrary place to stop.
The pull request is important to our development process, but production does not care that GitHub displayed a green check mark. Software becomes useful — and dangerous — after it leaves that environment.
So a genuinely agentic SDLC eventually has to extend beyond:
Plan → Code → Test → Review → Gate → Merge → Roll out → Validate → Fix
That doesn’t mean an agent should blindly deploy anything it creates. Autonomy should expand where the evidence and guardrails support it. If our agents become dramatically better at producing changes while our confidence systems still terminate at “PR opened,” we haven’t completed the transformation. We’ve simply automated the front half of the pipeline.
The important addition isn’t one particular product feature – it’s closing the evidence loop.
Optimize for Time To Confidence
For a long time, engineering organizations optimized heavily for how quickly developers could produce software. We improved editors, languages, frameworks, build systems, CI, local environments, and eventually code generation itself.
That work paid off. Creating software has become extraordinarily cheap.
The next optimization target is different.
When an agent finishes a change in six minutes, another minute saved in code generation is probably not the thing holding the organization back. The harder question is how long it takes before that change has accumulated enough evidence that you’re comfortable moving it forward.
Sometimes that answer should be seconds. A tiny change on an unimportant path shouldn’t spend half a day waiting for ceremony.
Sometimes it should take much longer. A three-line change to authentication, payments, or a heavily used dependency may deserve more scrutiny than a thousand-line generated refactor.
The goal isn’t maximum automation, and it isn’t maximum caution. It’s getting the amount of confidence appropriate to the risk without paying for evidence you don’t need.
That makes time to confidence a useful way to think about the next generation of software delivery.
How quickly can we understand what a change affects?
How quickly can we gather the evidence that matters?
How quickly can we discover when our assumptions were wrong?
And when they are wrong, how quickly does what we learned make the next change better?
AI didn’t remove the engineering bottleneck.
It moved it.
Code is becoming abundant. The ability to trust changes at the same pace is not.
The teams that adapt best won’t simply be the ones whose agents write the most software. They’ll be the ones that build an SDLC capable of keeping up.