Vivian Voss

The Merge Is the Signature

philosophy code review ai engineering

Somewhere in your repository history is a commit that carries your name in the approval field. You have no memory of it. It went past on a Thursday, the diff was long, the branch was blocking two other people, and the tests were green. You wrote LGTM, or you clicked the green button, and the work moved on.

Nobody needs to apologise for that; it is what the job looks like from the inside. What deserves examination is the mark you left, because that mark is read by people who were not in the room, and it is read as a statement about the code.

The claim under examination here is the one nobody makes out loud, because everybody assumes it: an approval means a person understood this change.

What an Approval Used to Carry

Reviewing a colleague's work involved a craft that nobody ever wrote down.

You were reconstructing a train of thought. Every line was evidence of a decision somebody made, and you read it the way you read an argument. The variable with the vague name told you the author was unsure what it held. The branch that handled the empty case and forgot the null case told you they had lists in mind while the database was somewhere else entirely, which is exactly where you then went looking.

A human mistake carries a biography. It sits where the author's attention ran out, and the shape of it tells you where to look next. A code review is a forensic skill dressed up as a reading exercise, and the question underneath it has always been the same one: what did they think they were doing?

Generated code does not answer that question, because there was no thinking to reconstruct. The machine tires as well. A conversation that goes on degrades: across six generation tasks, the leading models lost an average of 39 per cent when the same work arrived over several turns instead of in one, and the loss showed up mainly as unreliability. Output quality also falls as the input grows, well before any context window is full, an effect called context rot by the team that measured it. Instructions from an hour ago quietly lose their grip.

What does not arrive is the seam. The output stays equally confident from the first line to the last, the naming never frays, and so the decay signs nothing. The oldest instrument a reviewer owns is the mark that fatigue leaves in code, and here the fatigue is real while the mark is absent. An interface that does not exist arrives with the same fluency as one that does, and an error path looks handled because it is mentioned.

So the reviewer applies a technique whose premise has quietly expired, and calls the result approval. The trouble is what that word now covers.

The Same Mark for Three Different Events

The mark itself says nothing about where it came from.

Behind it may stand somebody who read the change and understood what it would do in production. It may equally stand for a colleague who opened four hundred lines at half past four, saw whose branch was blocked behind it, and clicked. Or nobody looked at all, because a rule merged it: Renovate ships automerge as a built-in option, and Dependabot reaches the same result through a small Actions workflow. A merge queue sits slightly apart, since it does not waive a required approval; it only moves the merge away from the person who gave it, sometimes by hours.

Three afternoons, one identical trace READ AND UNDERSTOOD someone followed the change through to production minutes to hours of attention OPENED AND CLICKED four hundred lines at half past four, a branch blocked seconds of attention NOBODY LOOKED a rule merged it: automerge or a small Actions workflow no attention at all approved and merged The auditor, the incident responder and the engineer bisecting a regression at midnight all read that one line. The signal cannot distinguish deliberation from a scheduling rule.

Each of those events leaves an identical trace. Downstream, the auditor, the incident responder, the engineer bisecting a regression at midnight and the compliance officer reading a control statement all see the same thing, which is that the change was approved and merged. The signal cannot distinguish between deliberation and a scheduling rule.

There is measurement on this, from a study presented at ICSME in 2024 examining code reviews across five large-scale projects. In that sample, 64.7 per cent of pull requests were approved with no review comment at all, and those comment-free reviews exhibited what the literature calls the LGTM smell some three and a half times more often than commented ones.

The same paper also compared what happened after approval. Comment-free approvals were followed by more late commits, meaning commits pushed after the reviewer had already approved. The signature is attached to a state of the code that was subsequently edited and, in those cases, to something nobody signed off on at all.

Comment-free reviews (ICSME 2024, five large-scale projects) 64.7% of pull requests approved with no review comment at all 3.5× more LGTM smell than commented reviews more late commits, pushed after the reviewer had approved WHAT THE HISTORY RECORDS commented review approved and merged comment-free review approved and merged Identical entry, and in the second case the code moved again afterwards. The signature sits on a state of the code that was subsequently edited.

Why It Got Worse This Year

The obvious retort is that none of this is new, and it deserves a fair hearing: rubber-stamping predates the current tooling by decades, and the 64.7 per cent figure is measured on repositories where much of that code was written by hand. Quite so.

What changed is the species doing the producing.

Sloppy review used to be a failure that ran at the pace of our own kind. Code arrived as fast as a colleague could type it, mistakes arrived at the same rate, and a bad week of reviewing meant a handful of changes waved through. The failure was real, and it was survivable, because both sides of the desk degraded on the same clock.

What sits on the desk now is sold as the fabled do-everything animal: quick beyond argument, and flawless so long as you steer it well. The promise rarely survives an afternoon. Sometimes it simply refuses. Sometimes, deep into a long session, it loses hold of itself. The person steering it degrades on the same slope. By the fifth correction typed into the prompt, four hours in, still hoping for the quick result the tool was bought for, nobody at that desk is reading any more. They are skimming, at the exact moment the material has become least skimmable. The review at the end of such a session is signed by two exhausted parties, and one of them is you.

The numbers put this politely. A vendor survey fielded between January and March this year, 2,847 usable responses drawn from the firm's own newsletters and client networks, found the median respondent spending 11.4 hours a week reviewing generated code against 9.8 hours writing new code, which reverses what the same outfit measured at the end of 2024. Two larger surveys supply the temperature, one of them run by a company that sells code quality tooling and therefore worth reading with a hand on your wallet. Sonar asked over 1,100 professional developers and found 96 per cent who do not fully trust generated code to be functionally correct, with the machine-written or assisted share of committed code at 42 per cent. Stack Overflow, across 49,009 responses, found trust in the accuracy of the output down to 29 per cent from 40 per cent in previous years. Almost nobody is confident in the material, and almost none of that caution survives contact with the calendar.

Hours a week, and which way they point reviewing generated code 11.4 h writing new code 9.8 h At the end of 2024 the same survey had writing ahead by roughly four hours. AND THE CONFIDENCE BEHIND THOSE HOURS 96% do not fully trust generated code to be functionally correct 42% of committed code is machine- written or assisted 29% trust the accuracy of the output, down from 40% Almost nobody is confident in the material, and almost none of that caution survives contact with the calendar.

And none of this lands on a reading culture in good condition. An attention span trained on headlines and fifteen-second clips was already struggling with a four-hundred-line diff before a machine began producing those diffs faster than anyone can read them.

The Limit

Two things stand against the argument, and both are stronger than the argument finds comfortable.

Trust is not a defect in a team, it is the mechanism that lets a team ship. An organisation where every line is treated as suspect has replaced engineering with an inspection regime, and inspection regimes are famously good at producing documents and bad at producing software. A reviewer who waves through a colleague's small refactor is spending scepticism where it buys the most, which is the correct instinct, and any proposal that abolishes it will be quietly ignored within a fortnight, deservedly.

And automatic merging is genuinely good practice in its place. A patch-level dependency bump with green tests, merged by a rule at three in the morning, is better than the same bump sitting unattended for six weeks while a human who would not have read the diff anyway fails to find time for it. Removing that capability would make security worse, not better.

A third deserves adding, since I have just complained about attention spans: complaints about the attention of the young are older than television, and the culture of skimming is one we all read in now, screens included, mine included. What stands is the observation about the material: it got longer and less forgiving while the reading got shorter.

None of these objections touches the actual claim, which was never that approvals are sometimes automatic or sometimes cursory. It is that all three cases produce a mark reading as considered judgement, and that everything downstream is built on the assumption that it was.

The Point

None of this calls for more process, and a team that responds to it by adding a checklist has misread it entirely.

It calls for a handful of sentences in your definition of done, and they can be proposed at the next planning meeting without a budget or a tool.

Begin with authorship. Whoever approves a change is the person named when it fails, whatever produced the diff. That is already how incidents get investigated once the room gets serious, and writing it down changes behaviour precisely because it removes the comfortable ambiguity beforehand.

Then put the origin of a change into the pull request itself. This is an instruction to the reviewer rather than a confession by the author, because the two kinds of code fail differently and reward different questions. Reviewing a machine's output with a technique designed for reading a colleague's mind is how plausible nonsense gets merged with a green tick.

The last one costs a configuration change and no argument at all: automatic merges must remain legible as automatic for the rest of their lives in the history. A rule may absolutely merge your dependency bumps at three in the morning. It may not leave behind a mark that somebody will later mistake for judgement. The switches for that live in branch protection already; what is missing is the sentence saying which of them you meant.

Everything else in your delivery pipeline treats the approval as a fact about the code. It is a fact about a moment, and moments vary enormously in what they contained.