I always assumed code review descended from academic peer review, the practice the sciences use to make sure a result holds up before anyone builds on it. It would be a good lineage to claim. It is also not the one we have.
Code review descends from a set of constraints we no longer have. Every time those constraints shifted, the practice changed shape to match them. Which means the change I want to argue for here is not a break with the tradition. It is the tradition.
In the beginning, computer time was the expensive part. Running a program meant scarce hours on a machine that needed its own air-conditioned room and dwarfed anything sitting in a house today. So you checked the program on paper first. You executed your own code by hand, line by line, before the tape or the cards went anywhere near the reader. These were the first code reviews: a desk check, often a self-review, sometimes with someone pulled in to sit beside you, aimed at not wasting an expensive compute run.1
Apollo changed what “correct” had to mean. The guidance computer’s programs weren’t loaded, they were woven, threaded through magnetic cores by hand at Raytheon, which meant the software had to be verified before the memory could be manufactured. You couldn’t write a patch later, it had to work the first time and every time. The “rope mother” was responsible for documenting every decision and every line of code along with how it affected the rest of the program.2 Review was no longer about not wasting expensive compute time, it was about a system that lives depended on, with no way to send it new code once the spacecraft was gone.
![]()
Photo by Nova13, CC BY-SA 3.0.
The next shift was about our psychology rather than the attributes of the machines. As creators, we identify with our code the way an artist identifies with their art. It is the kind of closeness that makes us bad at catching our own errors. In 1971 Weinberg argued for detaching the ego from the artifact so that other people could find what the author could not.3 By 1976 Fagan had turned that into a process with defined roles and measured outcomes, and formal inspection by someone other than the author became the standard.4 We were buying distance, and, we hoped, greater accuracy.
Once other people were reading the code, we started getting something we hadn’t designed for. Review moved mental models between people. As the systems got larger, that turned out to be essential for keeping them running, and evolving.
Over time, and with changing resources, the evolution of how we prepare code for production continued. Extreme programming took the argument to its conclusion: if review is valuable, review continuously.5 Distributed version control made it possible to compose small change sets into large changes without the file locking of earlier systems, and open source built a review culture on top of that new functionality. The practices that emerged there and the practices inside large companies converged on roughly the same thing: small changes, few reviewers, fast turnaround.6 Meanwhile, runtime got cheap, and the original desk check got handed off, first to QA and then to automated suites, because it had become cheaper to run the program than to trace it by hand.
Which brings us to now. One author, one reviewer, and a volume of generated code that exceeds what a person can read line by line, let alone absorb into their model of the system. The constraints have moved again, so the practice should as well.
If you and your team aren’t buried under a pile of code reviews from the increased throughput of agentic code authoring, then this article may not be for you. But it was that very problem that led us to carefully consider what it means to review code, why we do it, and where to focus it. Because review isn’t a gate that you pass, it’s a learning moment where we build shared understanding of a system’s shape and function, as well as ensuring the completeness and quality of the work.
”Obviously No Mistakes” vs. “No Obvious Mistakes”
In CloudBees’ 2026 State of Code Abundance report, which surveyed more than 200 enterprise technology leaders, they found that 81% had seen an increase in production issues tied to AI-generated code, even though 92% expressed confidence in its production readiness. This points out the difficulty of taking advantage of tools that allow the production of code at much higher speeds, while still maintaining quality in what is produced.
It also signals the need to shift mindsets around what it means to review code. We believe we should change the approach to focus, as Cory Brown, one of our team leads, put it, on ensuring that “there are obviously no mistakes rather than there are no obvious mistakes.”7
In the past we have often looked for obvious mistakes, focusing on catching them rather than on ensuring that there are “obviously no mistakes.” This suffuses its way into the authoring as well as the reviewing, as we seek to use patterns and tools that help drive out the obvious mistakes: guardrails like linters, strong typing, automated line-by-line code review agents, unit tests, end-to-end tests, and automated architectural pattern enforcement. These become the guardrails that ensure there are obviously no mistakes in the code authored by generative AI models.
Focusing on these as infrastructure concerns, or rails, while we are building allows us to focus on what we really want out of a code review.
The Real Goal: A shared mental model
After some disastrous software releases, Microsoft went on to do an enormous amount of research into the causes of, and remedies for, bug generation in software. One of the core findings was that a poor ownership model, through low contribution to a file or binary, resulted in higher bug creation rates8.
As AI encompasses more and more of the code creation involved in software authoring, this problem grows, making the documentation, sharing, and communication of mental models even more important.
At Voze we get some of this from pairing during the technical design phase, which helps to forge a common mental model. But as with any piece of software, a key element of code review becomes the propagation, and rapid acquisition of shared mental models between the maintainers of the code, and then validation of that mental model. This is critical to the later troubleshooting, incident management, augmentation, and security of the code.
“Our study reveals that while finding defects remains the main motivation for review, reviews are less about defects than expected and instead provide additional benefits such as knowledge transfer, increased team awareness, and creation of alternative solutions to problems.”9
As Davis Hyer, another of our engineers, said in that same team discussion, it’s about “becoming an equal owner to the author of the code.”10
This is even more of a challenge when the actual author of the code is not a human, and has already lost context by the time you could query it for information about its mental model. Which means that the shape of our code review needs to facilitate the acceleration of this process.
What this looks like in practice
These ideas are all interesting, but what does it look like in practice?
Before it is ready for review (for the author)
You own if it works, make sure that you have tested that it does. Run it, walk through it, make sure it does what it needs to do. Write your PR body, make sure you make it clear in human terms what is happening and why.
1. Run the changes
Running it is the first step in a code review itself. You have to be able to answer the question of “Does it do what it is supposed to do?”
In the spirit of “obviously no mistakes,” the review goes beyond that to making sure that it doesn’t do what it shouldn’t. This requires putting on a different hat than building, as you push beyond the happy path. What happens if you drop the complete works of Shakespeare into that text box?
2. Understand the change
Correctness is only one piece of the code review, and in a world where systems understanding is increasingly the realm of the software engineer, creating the shared mental model quickly is equally important. With this in mind, we hand off the line-by-line review of the code to agents that are tailored to the task. They run on every PR, and every change to a PR, and their prompting and model choice will change as we monitor their output. All of the data we have shows that this is something they do well, and will continue to improve at.
You need to understand how this change fits into the larger system. How it affects the evolution of the system in the future. This involves understanding the change itself, but as important, the context around the change. This is not a line-by-line reading, and may involve AI. It is an interrogation of the change in order to create a consistent mental model for yourself. Reading documentation changes, looking at tickets for the work, understanding any product documentation around intent.
Part of what you are trying to do here is reduce cognitive and intent debt: the gap between what the code does and what the team understands about it, and the gap between what the code does and why it was meant to do it. In closing these gaps, we will reduce bug generation and ensure the stability of the system as we continue its evolution.
The other thing to consider here is if the current guardrails around software generation for this change were sufficient, or if they can be improved. That could either be changes as part of this work, or could be broken out into tickets to be managed afterwards to strengthen the quality of what we are working on.
Questions to consider in this phase:
- Does this work the way that I think it does?
- Does the work here match the intent of the change?
- Does this implementation produce more optionality in the future or less for our system?
- Does your mental model of the change match the author’s mental model?
- Are there changes to our guardrails that are needed based on this change?
3. Approve it
Once you’ve gone through the process to understand it, and worked through any changes that you and the author felt were needed for it to be complete, you get to approve it.
By approving code, we are raising our hand to say it is ready to go, and are willing to share in the responsibility for that code with the author.
Conclusion
This marks a radical rethinking of what it means to review software. But one that will help us move forward into the future of software with the appropriate checks in place. It forces us to center the thinking of what we do in both the development and review process, which is the final human in the loop of this cycle.
Footnotes
-
Wilkes, Wheeler, and Gill’s The Preparation of Programs for an Electronic Digital Computer (1951), generally considered the first book on programming, came directly out of this practice on the EDSAC at Cambridge. ↩
-
MIT wrote its own process up and it is public. Johnson and Giller, MIT’s Role in Project Apollo, Volume V: The Software Effort (R-700, March 1971) is the account of how the software was actually built, reviewed, and verified. The Virtual AGC document library hosts the working paper trail underneath it: the Software Control Board minutes, the Program Change Requests and Notices, the software development plans, the anomaly reports. It is a change management process you would recognize immediately. For the rope memory and the rope mother role, see “Software as Hardware: Apollo’s Rope Memory” in IEEE Spectrum and “Rope Mother: Margaret Hamilton” from the Smithsonian National Air and Space Museum. ↩
-
Gerald M. Weinberg, The Psychology of Computer Programming (1971). The chapter on egoless programming is where the idea gets its name, and the argument that review has to be separated from the author’s identification with the code starts there. ↩
-
Michael Fagan, “Design and Code Inspections to Reduce Errors in Program Development”, IBM Systems Journal 15(3), 1976. Fagan’s five-step process (overview, preparation, inspection, rework, follow-up) is the direct ancestor of every formal review process since. ↩
-
Kent Beck, Extreme Programming Explained: Embrace Change (1999). The reasoning is stated plainly: if code reviews are good, we’ll review code all the time. ↩
-
Peter C. Rigby and Christian Bird, “Convergent Contemporary Software Peer Review Practices”, ESEC/FSE 2013. They compared review at Google, Microsoft, and AMD against six open source projects and traditional inspection at Lucent, and found the parameters converged despite wildly different cultures and incentives. ↩
-
This idea is also discussed in some depth in Designing with Types: Making illegal states unrepresentable from the F# team. ↩
-
See https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/bird2011dtm.pdf I am extrapolating a bit from this, but the data and the broader discussion of team communication being a root cause of this in the paper support the idea I am surfacing here. ↩
-
“Expectations, Outcomes, and Challenges of Modern Code Review” (Microsoft Research, ICSE 2013) ↩
-
This idea of “ownership, not inspection” is also echoed by Google’s Code Review standard which emphasizes the shared responsibility for the codebase’s overall health. ↩
For papers, posts, and the curious.
BibTeX, plain text, and a permanent URL — for if you want to point your future self back here.
title = "Why We Code Review, or: Why Does This Bottleneck Need To Be HeRE?!",
author = "Sellers, Daniel",
year = 2026,
series = "Voze Lab",
volume = 1,
number = 6,
url = "https://lab.voze.com/why-we-code-review"
}