The cost of writing was quality control
For the past three years we have been repeating a bargain that sounded reasonable and that almost nobody argued with: let the machine write, and we will do the deciding. Execution gets delegated, judgment stays with us. The enthusiasts said it to reassure the skeptics, and the skeptics said it so as not to sound nostalgic. The industry’s entire vocabulary was built on that split: the human defines the what, the agent works out the how, and in between sits a clean boundary where somebody looks at what came out and says yes or no.
It is a good bargain. The problem is that it no longer describes what we do.
Because the split assumed judgment was being exercised somewhere specific — reading a diff, reading a spec, approving a plan — and those places have emptied out one after another, without any explicit decision ordering it. We did not delegate judgment. We delegated, one by one, every place where judgment was exercised.
The inventory of what we handed over
The full list is worth writing down, because on its own each step looks reasonable and only together do they add up to anything.
The agent writes the code. That is the starting point and nobody argues about it any more. Since the volume generated exceeds what a team can read, review gets delegated to a second agent: it is exactly what Bun did when it rewrote a million lines of Zig into Rust in eleven days, automating the review as well, and it is now the default recommendation across half the industry. The specification, which arrived as the lifeline — a human artifact at last, at last we decide — is increasingly written by the agent itself from a three-line prompt, and comes out at a length nobody reads end to end. The implementation plan is derived from that specification automatically. The tests are generated by the same model that wrote the code they are meant to verify. And when the uneasy sense that a control is missing sets in, there is always the option of handing QA to a fourth agent.
Lined up like that, the pattern is hard to miss: each layer of control is produced by the very procedure that made the previous layer uncontrollable. Review arrived to control the code and was generated like the code. The specification arrived to control the review and was generated like the review. This is not a chain of controls. It is the same operation repeated at a different level of abstraction, and every repetition inherits the defect it came to correct.
The question waiting at the end of the list is the obvious one, and it deserves a better answer than a lament: if we do not specify, do not write, do not review and do not verify, what exactly is the job?
Writing was expensive, and that was the limit of what could be reviewed
The answer starts somewhere unglamorous: a code review study Cisco and SmartBear published in 2006, two decades before any of this existed.
Its numbers are the best we have on the actual reviewing capacity of a human being, and they are brutal. The defect detection rate is 87% for reviews under a hundred lines and falls to 28% above a thousand. Performance collapses past 400 lines and past the first hour. The recommendation that came out of it — never review more than 200 to 400 lines in one sitting — has been in every style guide in the world for twenty years, is honored badly and has never been repealed, because it does not describe a methodological preference. It describes a limit of attention.
That limit was never the problem, for a reason we never had to think about until now. The cost of producing kept artifacts inside the range of what could be reviewed. Nobody hand-wrote a twelve-thousand-line pull request or a four-hundred-page specification, not out of discipline, but because it was ruinously expensive. The limit of what we could produce and the limit of what we could review roughly coincided, by accident, and that coincidence worked as a quality control that nobody designed, nobody documented and nobody ever defended in a meeting. It was there. It was free. And it was structural, not cultural.
The move has a precedent worth acknowledging, because it tells us where this goes. Clay Shirky described in 2008 the shift from “filter, then publish” to “publish, then filter”: the cost of printing had been the editorial filter of the twentieth century, and when it went away the filter was not replaced by a better one, it was simply postponed to a moment when nobody applied it any more. What we are doing with software is the same inversion, with two differences. The first is that here the filter is not postponed: it is handed to the same system that produces. The second is that it is not happening to one artifact, but to all of them at once.
The decoupling is already measurable
The useful thing about this thesis is that you do not have to take it on faith: this year’s data describes it without meaning to.
A study of roughly 33,000 pull requests written by agents found that the ones that never got merged are systematically larger, touch more files and fail CI validation more often. Size is no longer a style variable. It is a predictor. CircleCI’s figures this year show the other half of the picture: feature branch throughput rose 59% year over year while main branch throughput for the median team fell. Much more gets produced and less gets integrated, which is exactly what happens when the bottleneck moves from writing to deciding whether something is safe to merge. And 38% of developers say reviewing AI-generated code takes more effort than reviewing a colleague’s, so the load per unit of artifact has gone up too, not just the number of units.
There is a fourth data point, the most uncomfortable one, and it is from 2025: METR’s controlled trial with experienced developers on real tasks in their own repositories. They took 19% longer using AI tools, and afterwards estimated they had been 20% faster. Almost forty points between performance and the perception of performance. METR has flagged the result as historical, and rightly so — February 2025’s tools are not today’s — but the finding that matters here is not the productivity number, it is the gap: the internal signal we use to tell whether we are working well stopped being calibrated.
And that is where the argument turns psychological, though not in the way you would expect.
It is not laziness
The comfortable explanation for all of the above is that we have gone slack. That the craft demands review and we stopped doing it. That it would be enough to take it seriously again.
It is a false explanation, and we have known it for forty years through a literature built in aviation, industrial process control and medicine, long before anyone automated programming.
The central reference is Parasuraman and Manzey’s work on automation complacency, which in 2010 pulled two decades of results into a single model. Their conclusion: complacency toward an automated system is not a character trait or a training failure, but an attention allocation strategy under bounded resources. When a manual task competes for attention with a supervised task that almost always turns out fine, attention goes to the manual one. It is a calculation, not sloppiness. And two findings finish the argument off: it shows up in experts exactly as it does in novices, and it does not correct with practice.
The rest of the literature points the same way from different angles. The vigilance decrement, measured by Mackworth as early as 1948, establishes that performance on monitoring tasks degrades in under half an hour, and is not trainable. The out-of-the-loop performance problem, formalized by Endsley and Kiris in 1995, describes how automation reduces situation awareness and with it the ability to take back control when it is needed. The effect Onnasch and colleagues named the lumberjack effect in 2014 is the most useful one for our case: the higher the degree of automation, the better routine performance gets and the worse performance gets when the system fails. The two curves separate at the same time, in opposite directions.
To that, add two cognitive mechanisms that explain why reviewing does not substitute for writing. The generation effect, documented by Slamecka and Graf in 1978, establishes that we retain far better what we produce than what we read: a mental model built by reviewing is structurally weaker than one built by writing. And cognitive offloading, which Risko and Gilbert reviewed in 2016, describes our systematic tendency to delegate as soon as a reliable external store exists — a tendency that is adaptive, not lazy, and that kicks in sooner the more reliable the store looks.
Put the pieces together and the result does not admit a moral reading. A system that produces artifacts above the threshold of human attention, that is right most of the time, and whose failures are subtle rather than obvious, is the exact configuration human factors engineering identified decades ago as a generator of shallow supervision. Asking a developer to make up for that with willpower is asking them to solve a problem of attention architecture by force of character. Aviation tried it. It did not work.
Bainbridge wrote it down in 1983
All of this has a five-page founding text that today reads like a critique of our industry: Ironies of Automation, by Lisanne Bainbridge.
Her starting point is an observation about the designer, not about the operator. The designer considers the human operator unreliable and inefficient, so removes them from the system, and in doing so leaves them precisely the tasks nobody could work out how to automate. Two ironies follow, and they are worth stating plainly.
The first: automating deprives the operator of the practice they would need on the very day they have to step in. In our case, the ability to audit complex code is built by writing complex code, and that is exactly the activity we have outsourced. We are training the next generation of reviewers in an environment where nothing gets reviewed, and the previous one is losing the muscle through disuse. The problem of the vanishing bottom rung is not only a labor problem. It is an epistemological one.
The second: the human is assigned to monitor, which is the task we are worst at by construction. Not slightly worse. Worse in ways that have been measured and reproduced since 1948.
There is a third irony Bainbridge could not have foreseen, specific to this cycle. In industrial control rooms, the operator supervised a deterministic system: when it failed, it tended to fail the same way every time. Here the central component is stochastic, produces plausible and different outputs every time, and its errors are not noisy but believable. It is the worst possible case for a human supervisor: spotting the anomaly is not enough, you have to spot the correction that isn’t one.
And the split we are adopting — one part conceives, another executes — is not new either. Harry Braverman described it in 1974 as the characteristic operation of the industrial labor process: separating conception from execution, and with it separating knowledge of the system from the person who operates it. Calling it spec-driven development in 2026 changes the vocabulary, not the mechanics.
The specification arrived without a control of its own
This explains in passing why the industry’s favorite consolation does not work. The standard answer to all of the above is that what matters now is the specification, and that human judgment still lives there.
The problem is that a specification written in natural language runs into a fork the methodology’s marketing avoids looking at. Either it is precise enough to be unambiguous — and then it is code, written in a worse notation, without types, without a compiler and without anyone to tell you that you contradicted yourself on page eighty — or it is ambiguous, and then you have not specified anything: you have delegated the decision without noticing. Dijkstra put the heart of it in 1978 in a sentence that has not aged a day: the naturalness with which we use our native tongues comes down mostly to the ease with which they let us say things whose nonsense is not obvious.
A programming language was never only notation. It was also a verifier: the compiler and the type system tell you your description is inconsistent before reality does. Moving the work to the specification is not going up a level of abstraction. We changed notation and lost the verifier. The difficulty did not drop; the detector disappeared.
The industry proves the thesis without meaning to. Spec-driven development has spent two years formalizing itself — mandatory templates, executable acceptance criteria, schemas, evals, specification linters — on a trajectory that can only end in one place. It is rebuilding a programming language under another name, and it is doing so because practice taught it what we already knew.
There is also the problem Naur raised in 1985, which no quantity of document solves. Programming is building a theory of the system; the code is the residue of that theory, not the theory itself. The classic split worked because both halves persisted: the artifact in the repository and the theory in the team’s heads. Agents break the symmetry, because they rebuild their theory from scratch every session and discard it when they finish, and the human has stopped building one because they no longer write. The artifact persists. The theory persists nowhere.
Seen that way, the rise of specifications makes better sense, and without irony: they do not win by being a higher level of abstraction, they win by being the only durable store the loop has left. It is also what explains the sudden jump in the value of ADRs, of instruction files and of everything that is not the model. We are not elevating the work. We are looking for somewhere to keep what used to keep itself.
What remains is accountability
If judgment has been drained out of all of its places, something does remain, and it deserves naming precisely because it is where the analysis turns uncomfortable: what remains is accountability.
Madeleine Clare Elish called it a moral crumple zone. Just as a car’s chassis absorbs the impact to protect the passenger, the human operator of an automated system ends up absorbing the moral and legal penalty when the whole thing fails, protecting the integrity of the technical system. Attribution does not follow real control, because our notions of responsibility are still individual while control has become distributed.
The cold reading is not that this is a narrative injustice. It is a requirement of institutional design: accountability does not settle where it is most effective, it settles where it is most addressable. A system needs an entity it can turn to, and the person who approved the merge is the only one available. All that management literature celebrating the engineer turned accountable operator is describing a promotion; what it describes, more accurately, is a lightning rod.
There is enough in this to deserve more than a section, and we will come back to it. It is enough here to leave the practical consequence: any proposal that distributes accountability without distributing the capacity to intervene is not a model of governance, it is a model for assigning blame.
The limit has to be put back by hand
The operational consequence of all this is not “review more”. That recommendation already failed in three industries before ours.
What did work in aviation and in process control was attacking the problem by design, accepting the limit of attention instead of demanding that it be exceeded. Translated to what we have in front of us, it means reintroducing by hand the limit that the cost of production used to impose for free.
That means treating artifact size as a hard constraint and not as a style metric: maximum sizes for pull requests and specifications, with an obligation to split, because a three-thousand-line change is not a big change, it is an unreviewed one. It means replacing uniform review with review tiered by risk, and accepting that approving everything to the same depth amounts to approving nothing. It means that declared sampling is more honest and more effective than fictitious full approval: genuinely reviewing the 20% picked by risk catches more than running your eye over 100%. It means preferring executable verification to inferential verification wherever the option exists, because a failing test does not suffer a vigilance decrement. And above all it means recognizing that reliability is bought — in tokens, in time and in people — right when flat-rate pricing has stopped covering agents and every additional control shows up on the bill.
None of this is new. It is what human factors engineering has been doing for forty years: small batches, forced decision points, periodic manual practice, degraded-mode drills. The only new part is that now it is our turn.
We did not delegate the work
It is worth ending where the analysis stops being comfortable for either of the usual positions.
Agents have not taken programming away from us, and they have not promoted us to architects. They removed the cost of producing, and with it a quality control mechanism that had worked for decades precisely because nobody knew it was there. That mechanism was not professional judgment, or discipline, or craft: it was an economic constraint that kept everything we produced inside the range of what we could read.
The cost has not disappeared entirely. It still exists, it shows up on the bill and no flat rate covers it any more. What has disappeared is its relationship to the size of what we produce, which was the only thing that made it useful as a control.
With that coupling broken across every artifact at once, each new layer of control is born outside that range, and that is why you can walk the whole chain — specification, plan, code, review, tests, QA — without finding a single point where anybody genuinely looks.
We did not delegate the work. We delegated the mechanism that told us whether the work was any good.
Sources
- Ironies of Automation (Lisanne Bainbridge, Automatica, 1983)(en.wikipedia.org)
- Complacency and Bias in Human Use of Automation: An Attentional Integration (Parasuraman & Manzey, 2010)(journals.sagepub.com)
- Code Review at Cisco Systems (SmartBear)(static0.smartbear.co)
- Best Practices for Code Review (SmartBear)(smartbear.com)
- Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity (METR)(metr.org)
- Why Are Agentic Pull Requests Merged or Rejected? An Empirical Study(arxiv.org)
- These Aren't the Reviews You're Looking For: How Humans Review AI-Generated Pull Requests(arxiv.org)
- Human oversight of agentic systems in practice (FAccT 2026)(arxiv.org)
- AI Is Writing More Code. Review Is Becoming the Bottleneck.(mstone.ai)
- Programming (with AI agents) as theory building (Sean Goedecke)(www.seangoedecke.com)
- On the foolishness of "natural language programming" (EWD667)(www.cs.utexas.edu)
- Moral Crumple Zones: Cautionary Tales in Human-Robot Interaction (Madeleine Clare Elish)(estsjournal.org)
- Cognitive Offloading (Risko & Gilbert, Trends in Cognitive Sciences, 2016)(pmc.ncbi.nlm.nih.gov)
- Clay Shirky, Here Comes Everybody: The Power of Organizing Without Organizations (Penguin Press, 2008)
- The Breakdown of Vigilance during Prolonged Visual Search (Mackworth, 1948)(journals.sagepub.com)
- The Out-of-the-Loop Performance Problem and Level of Control in Automation (Endsley & Kiris, 1995)(journals.sagepub.com)
- Human Performance Consequences of Stages and Levels of Automation (Onnasch, Wickens, Li & Manzey, 2014)(journals.sagepub.com)
- The Generation Effect: Delineation of a Phenomenon (Slamecka & Graf, 1978)(doi.apa.org)
- Harry Braverman, Labor and Monopoly Capital: The Degradation of Work in the Twentieth Century (Monthly Review Press, 1974)
- Programming as Theory Building (Peter Naur, 1985)(gwern.net)