October 18, 2026 · 7 min read
AI-written pull requests pass tests and still have bugs
By Anna, co-founder, build and content
An AI-written pull request that passes its tests has proved one thing: the code does what its author meant. It has not proved the code does what your system needs. The fix is a reviewer that did not write the change, ideally a stronger model that reads the diff line by line and is told which other parts of the system depend on it, with a person deciding anything that changes routing, status or deletion rules.
We learned this the expensive way in September 2026, and the research agrees with us.
Why do AI pull requests pass tests and still have bugs?
Tests written alongside a change, usually by the same agent, encode the same assumptions as the change. If the agent misunderstood a rule, its code and its tests misunderstand it together, and the suite goes green. The bug lives in the code that depends on the change, which neither the author nor its tests ever opened.
METR measured the size of the gap in March 2026. Four maintainers from three open-source projects reviewed 296 AI-generated pull requests that had passed the automated grader. Roughly half would not have been merged, and the maintainer merge rate came in about 24 percentage points below the benchmark score. METR is careful to say the agents had a single attempt with no feedback, so this is not a ceiling on what agents can do. It is a measurement of what “tests pass” is worth when nobody looks.
We covered that finding from the “is it really done” side in a recent post on checking an agent’s claim of done. This one is about the next question. Once you accept that someone has to look, who is it, and what are they?
What happened when we merged on a summary review
In September 2026 a batch of behaviour changes was built by agents running on a mid-tier model. Each change had a full green test suite. They were reviewed at summary level, meaning someone read what each one said it did, and they were merged.
A stronger model then read the actual diffs line by line. It found a critical defect and several high-severity ones. In one change, a rule meant to collapse repeated failures had quietly turned a streak counter into a permanent single, so a downstream alert that fires only after a streak could never fire for the most common kind of failure. In another, a label was written before the classifier that decided it had returned. In a third, a de-duplication rule blocked a re-dispatch while still counting it as done.
Every one of those had a plausible test. Several older tests had been reshaped so the new code could pass them. The workers’ tests proved the code did what the worker meant. The defects sat in consumers the worker never opened.
One detail made it worse. Our automation merges bot-authored pull requests as soon as checks go green, so “open it now, review it later” did not exist for those branches. We contained it by switching the affected behaviour off in production and fixing forward. The lesson we wrote down is the rule below.
Who should review: author model, other model, or a person?
Match the reviewer to what the change can break. A formatting fix needs the test suite. A change to routing, gating, status meaning or dedup rules needs a stronger model reading the diff before it is mergeable, and a person who owns the system signing off.
| Change type | Reviewer | Gate before merge |
|---|---|---|
| Docs, copy, formatting, pure refactor with unchanged tests | Tests plus a linter | Green checks |
| New feature behind a switch that is off | Different-model reviewer, summary plus diff | Switch stays off until reviewed |
| Changes to routing, status, gating, dedup or collapse rules | Stronger model, line by line, told which consumers to check | Draft pull request until the verdict is in |
| Security helpers, parsing of untrusted input | Stronger model told to break it with runnable probes, several rounds | Person signs off the verdict |
| Anything touching money, deletion or customer messages | Person | Person merges |
The middle rows are where the savings are. Most changes sit in the first two rows, and a mid-tier model builds them well. The expensive reviewer is reserved for the narrow set of changes whose failure is silent.
Does it matter that the reviewer is a different model?
A little, and the evidence is more mixed than the folk wisdom. The common advice is to review with a different model family so the reviewer does not share the author’s blind spots. The research on judges favouring their own output supports a modest version of that advice and no more.
A paper accepted to ICML 2026, “Are LLM Evaluators Really Narcissists?” by Roytburg and colleagues (first posted January 2026), re-examined earlier self-preference results. Once they controlled for how well each judge handles the question at all, only about 51% of the previously reported self-preference cases stayed statistically significant. Much of the apparent bias was a weak judge being uncertain, not a judge recognising its own writing.
So “use a different vendor” is not a magic fix. A reviewer’s strength relative to the task matters at least as much as its family. That is why our rule names strength first: a stronger model reviews a weaker model’s work, whichever family it comes from.
What does an AI reviewer get wrong?
It over-rejects, and it can be steered. Two 2026 papers measured both.
Jin and Chen’s “Are LLMs Reliable Code Reviewers?” (arXiv, 28 February 2026) found that models often label correct implementations as non-compliant. Worse, prompts that asked the model to explain its verdict and propose a fix raised the misjudgment rate. Asking for more detail made the reviewer less reliable, not more. Their proposed safeguard treats the model’s suggested fix as a hypothesis and checks both versions against tests.
Zhao, Esmaeili and Fard’s “Bias in the Loop” (arXiv, 18 April 2026) audited code judges and found verdicts highly sensitive to prompt bias even when the code was identical. A prompt that leans toward “this looks fine” or “this looks wrong” moves the answer.
Three practices follow, and we apply all three.
- Name the consumers. Tell the reviewer which readers of the changed column, status or rule to open. A reviewer given only the diff reviews only the diff.
- Treat a changed old test as a finding. If a pre-existing test was edited so new code passes, the author must justify it in writing. It never counts as passing.
- Hold suspicious findings to evidence. When a reviewer flags a bug, ask for a runnable probe. A finding with a failing probe is real. A finding without one is a question.
How do you keep the reviewer from costing more than the change?
Spend the strong model only where silence is expensive, and measure it. We run workers on a mid-tier model by default, keep the largest model for planning and hard judgement, and pin the model explicitly, because an unpinned agent inherits whatever the expensive default is. An unpinned build runner on the default model is how we got a surprise bill in August 2026.
The cost of review is mostly tokens for the reviewer plus human minutes for the sign-off, and the second is usually larger. The full arithmetic is in our breakdown of what an agent costs per task. The short version: a line-by-line review of a few hundred changed lines is cheap next to one wrong status rule running unattended for a week.
Resuming the same reviewer between rounds also helps. A reviewer that already knows which probe families it tried finds the second-round gaps faster than a fresh one, and it keeps the verdict honest: merge, fix then merge, or do not merge.
What a tomte does in this loop
A tomte, our word for one production agent with one defined job, never reviews its own work. In the pull request loop we run, one tomte builds, a different one verifies against a stated command, and a stronger model reviews the diffs that can fail silently. Each hand-off leaves a written record, so a person can sign off in a minute instead of reconstructing the change. You can see how that fleet is governed on our agent fleet proof page.
Where we are not done
Review by a stronger model is a habit we enforce on the change types in the table, not a gate that blocks every merge by itself. The automated checks catch the shape of a problem. The silent logic defects still need a reader. We state that plainly because it is the honest position as of October 2026.
If you are putting AI-written code into production and have no rule for who reviews what, an AI Workforce Sprint builds a working agent on your infrastructure with the review loop built in, at a fixed price and fixed scope. To begin, Start async: write to us, and we reply in writing within one business day. No meetings, ever.