Your code review was tuned for tired humans
I have a confession. Last week, I merged some code in a project that I hadn’t read and was written by something that isn’t a person. I’ll also confess that this was far from the first time.
Luckily the project in question was a small prototype of little consequence. This project, codename Infinite Horizon, has exactly one developer and user (it’s just me). It’s about as low stakes as you can get. Even so, I reflexively still reach for best practices. I keep it under source control on GitHub, I enable branch protection, and I require review (even though it’s just me again) before integrating branches into main.
Feeling impatient, and with a small change in front of me, I asked Claude Code to “just go ahead and merge it”.
Claude reached for what was there and obediently ran gh pr merge.
GitHub refused, saying all merges to the default branch needed an approval. Claude then ran gh pr review --approve && gh pr merge.
Having previously authenticated with gh login, GitHub noted the approval and merged the code not caring that it was not my keystrokes that had issued the command.
And because this project uses GitHub Actions to do continuous deployment, the code was shipped off to serve its purpose unaware that its pedigree was not human attestation of a best effort code review, but of the rubber stamp that wasn’t even applied by a person.
But what if something went wrong downstream? What could I tell myself or a colleague about what went wrong and how? Project Infinite Horizon is far from being the subject of a SOC 2 report, but what if I had to explain the process to an auditor?
Let’s look at the evidence I could produce. GitHub said that the code was reviewed and the CI checks had all passed. Those were my primary controls for this project, and on paper every control was satisfied, and the process went fine.
You might object: I gave the command. Claude followed my instructions. That’s what I get for routing around my own controls. But there are two problems with this:
- I didn’t specifically ask for Claude to bypass the control.
- There is no artifact I can look at later to see that the control was bypassed.
So, agents can bypass controls, and there isn’t a good way to tell that they did after the fact. Sit with that for a moment.
And notice that Claude never went rogue. I pointed it at a destination; it hit a roadblock; it worked around the roadblock. In any other context I’d be thrilled it didn’t get stuck. The property that defeated my control is the property I generally want from Claude.
For many projects, like project Infinite Horizon, this is an acceptable risk. The consequences of shipping a breaking change are low, and I’d gladly trade control in that domain for the speed I can get with agentic development. But there is a gradient of risk. The ceiling for bad outcomes is a lot higher if Waymo ships a breaking change than if Netflix does. And while not every product has life or death consequences for change management, most commercial projects understandably still want reliable control mechanisms in their software development process.
So what do we do when it matters?
Let’s take a step back and examine a ritual where the most important change-management controls live: code review.
Many practicing software engineers have done all or almost all of their code review in the form of Pull Request or PR on GitHub. But the PR is just the lightest, latest form of a ritual much older. Its ancestor, the Fagan Inspection, was formalized in the seventies by Michael Fagan at IBM. These early code reviews were heavy. Meetings. Plural. And purposefully rate limited to read only a couple hundred LOC per hour.
In 50 years, we have distilled that into a green checkmark on a GitHub PR. The ritual could shrink because the ritual was never what mattered. What matters is a human author who asserts the change, and a reviewer who can ask why and hear the defense. After this negotiation, both parties stake their reputation and agree to be accountable for the change.
Agents break all of this.
For an agentically generated implementation, there is no author to ask. There is just a diff. You can’t interrogate the agent after the fact. The state of that inference run was discarded from the GPU circuitry the moment the tokens were emitted. If you ask why after the fact, a fresh instance will happily generate an explanation for you. But that’s reconstruction, not recollection. A human defending their change is testifying, but an agent explaining a diff is speculating about another agent’s work. They might share all of the same parameters (model, effort level, etc.), but it’s a different inference. And even the thinking tokens captured at generation time are only narration; whether that narration is faithful to what actually produced the diff is an open question in interpretability.
A human reviewer has no partner to negotiate with. They are alone, and having to review far more code than they ever had to before. The reviewer’s job has changed from let’s work together to understand the effectiveness of this change to I have to assert the effectiveness of this change on my own.
It gets even murkier when an agent also does the review. An agentic system produced a patch to which another agentic system said LGTM. Assuming a human is still asserting control at the merge approval step, what is their task? Are they necessarily a reviewer, or are they just a notary asserting an agent review took place?
Worth noting that the evidence, the checkmark on GitHub, and the CI checks passing, still look the same no matter how much of the process was done agentically. Measurement intact, but the meaning is gone.
We built code review for tired humans. Code review has to be tolerant of humans that are rushed, and whose attention will predictably lapse. We tuned it over 50 years to work for human errors. Human errors are fatigue shaped and carelessness shaped. We get tired at the end of a long function. We want to go home on Friday afternoon. Our brains go stale working on one problem too long, so the fix was always a fresh pair of eyes.
Agents are the opposite. They are tireless, diligent, occasionally and confidently wrong, and at a velocity no human can match. The distribution of failure has shifted. Rather than clustering around human fatigue and attention, agents fail by being wrong fluently, at any point in the chain.
So let’s take a closer look at the artifacts produced during code review.
For many teams, approval is a row in a mutable database hosted by GitHub. It records an account name and a timestamp. It does not record what the reviewer saw. If I spend an hour carefully reasoning through a code review, and Claude spends 11 seconds running calls to an MCP server, the row looks the same.
The row is also mutable. Anyone with admin credentials can dismiss a review, override branch protection rules, or force push history. While noticeably thin as a control, this was sufficient in a human-only world.
Provenance is an old word from the art world: the documented history of where a thing came from — the chain of custody that lets you tell an original from a forgery. Software has always had provenance too. We just never needed the word, because the answer was always “a person”. An admin action was a human decision linked to an identifiable person’s credentials. We could assume that if identity could be verified, we could also assume provenance.
This is true no longer. In an agentic world, identity no longer implies provenance.
So, how can we update our software development process to improve the control it gives us? If you are thinking about this problem too, I’d love to hear from you.