How do you run two AI code reviewers without review loops?
Give each reviewer a different job, rank every finding by severity, and let only verified blockers stop a merge. One agent finds, a second agent confirms, intent notes tell both which choices were deliberate, high-risk changes go to a human whatever the bots say, and any lines rewritten twice in the same pull request stop the run and escalate. Those five rules are the whole setup. The rest of this page is the configuration behind each one.
The problem they solve is a loop. Reviewer A flags a missing null check on a value that cannot be null. The coding agent adds the check. Reviewer B flags the new branch as dead code. The agent removes it, and on the next pass reviewer A flags the missing check again. Each step looks reasonable on its own, and the pull request never closes.
Why do AI code reviewers flag unlikely edge cases?
They are scored, implicitly, on finding something. A reviewer that returns “looks fine” on most diffs looks like it did nothing, so the prompt and the product both lean toward volume. Add a second reviewer and you double the volume without adding any rule for which findings matter.
I have run CodeRabbit against real pull requests and compared it with Greptile, GitHub’s own review features and a coding agent configured to review diffs. The test I applied to all of them was whether they catch what a competent reviewer would miss, or mostly restate what a linter already said. Severity, proof and a stop rule are what move a reviewer toward the first group.
How should AI review findings be ranked by severity?
Four levels, written into both reviewers’ instructions, with one rule each:
| Severity | Definition | What happens |
|---|---|---|
| Blocker | Wrong result, security hole or data loss on a path that real input can reach | Blocks merge, but only once verified |
| Major | Real defect with limited reach, or a missing test for changed behavior | Needs a written reply: fix it, or say why not |
| Minor | Edge case with no shown trigger, weak naming, small duplication | Logged, never blocks, not fixed in this pull request |
| Nit | Style and preference | Dropped unless a linter rule exists for it |
The line that does the work is “minor findings don’t block.” Without it, every comment is a de facto blocker, the coding agent tries to satisfy all of them, and the loop starts. With it, a minor finding is a note for later and nothing more.
Each reviewer also has to name the severity before it writes the explanation. A reviewer that has to commit to “blocker” up front is less likely to dress up a style point as a defect.
What is the finder and verifier split?
The finder reads the diff and lists everything it suspects, with a severity on each. It is allowed to be wrong. The verifier gets one finding at a time, along with the diff and the surrounding code, and has to answer one question: what input, call path or failing test makes this happen?
If the verifier can show it, the finding keeps its severity. If it cannot, the finding drops to minor and stops blocking. The verifier is told not to add findings of its own, because a second finder is how you get the loop back.
Put a different model in the verifier seat than in the finder seat where you can, on the reasoning that two different models are less likely to share the same blind spot. A separate prompt and a narrower context on the same model is the minimum. The coding agent that wrote the change never verifies its own findings.
What are intent notes, and where do they go?
An intent note is a one-line comment next to a deliberate choice that a reviewer would otherwise flag:
// INTENT: retries capped at 3 on purpose. The upstream API rate-limits
// at the account level, and more retries turn one failure into an outage.
const MAX_RETRIES = 3;
Both reviewers get the same instruction: do not flag a choice that an intent note explains, and flag it only when the code contradicts its own note. The note also helps the next human, who otherwise has to guess whether the odd-looking line was a decision or an accident.
The cheaper half of this happens before any code exists. When the coding agent plans the change, it should write down the assumptions it is making, so a person can settle the ones that matter before any code is written. Small changes help here too. A diff that fits on one screen leaves the reviewers less room to invent context.
Which changes go to a human no matter what the bots say?
Anything in a high-risk area. I already keep that list in my instructions for coding agents, and the same list routes review: schema migrations, authentication logic, payments, deleting user data, APIs that outside consumers depend on, infrastructure and security-sensitive changes. If a diff touches one of those, a person reviews it, and a clean bot verdict changes nothing.
This is the same split I describe in AI agent risk tiers. A mistake in a formatting change is cheap to notice and cheap to undo, so the bots can clear it. A mistake in a migration fails both halves of that test.
What is the loop breaker?
A counter on lines. If the same lines in the same pull request get rewritten twice in response to review findings, the run stops. Nothing merges, and the pull request goes to a human with both findings and both diffs attached.
Two rewrites is a deliberately low bar. The first rewrite is normal. The second means the reviewers disagree with each other, or one of them keeps flagging something an intent note should have settled, and neither agent will resolve that by trying a third time. The person who gets the escalation usually has one of three jobs: write the missing intent note, downgrade the finding, or tighten the reviewer prompt.
What does the whole configuration look like?
In one place, as the rules I would hand both reviewers and the coding agent:
- Rank every finding as blocker, major, minor or nit before explaining it.
- Only verified blockers block a merge. Majors need a written reply. Minors and nits are logged and left alone.
- The finder lists suspects. The verifier proves each one with an input, call path or failing test, or downgrades it to minor. The verifier adds no findings.
- Do not flag a choice an intent note explains. Flag code that contradicts its note.
- Changes in high-risk areas go to a human regardless of the review result.
- Lines rewritten twice in one pull request stop the run and escalate to a human.
Does it save time?
I have no numbers on this yet. What I expect is fewer review rounds per pull request and fewer findings that a person has to read and dismiss. A fair test would count blocking findings per pull request, the share the verifier downgrades, and how often the loop breaker fires, before and after the rules go in. I have not run that count, and I will not claim a saving until I have.
Who does this fit, and how do I start?
It fits a team or a single builder that already runs an AI reviewer on every pull request and has started to see the same lines change back and forth. If one reviewer is enough and its comments are rare, the extra agent adds cost without much gain.
Start with the severity table and the “minor findings don’t block” rule, since those two remove most of the noise on their own. Add the verifier next, then the loop breaker. Intent notes accumulate as the loop breaker fires, because each escalation tends to end with one.
For the wider argument about where review becomes the bottleneck once agents write more of the code, see AI code review: when the bottleneck moves on aistrategy.guide. For tool choice, ctaio.dev keeps a ranking of AI code review tools. To write the rules down for a whole team, ctaio.dev has a copy-paste AI code review policy template.
This page belongs to the Compounding CEO series.
Frequently Asked Questions
Why do two AI code reviewers end up in a loop?
Each reviewer is rewarded for finding something, and neither knows which choices in the code were deliberate. The coding agent fixes what the first reviewer flagged, the second reviewer flags the fix, and the agent changes it back. Without a severity bar and a stop rule, nothing in the setup ever says the pull request is done.
Should minor AI review findings block a merge?
No. In this setup only a verified blocker stops a merge. Majors need a written reply, either a fix or a reason, and minors and nits are logged for later. If every comment blocks, the team learns to ignore the bot, and then it ignores the serious finding too.
What does a verifier agent do that the finder does not?
The finder casts a wide net and is allowed to be wrong. The verifier gets one finding at a time and has to show the input, call path or failing test that triggers it. A finding the verifier cannot reproduce is downgraded to minor, which removes most of the unlikely edge cases from the blocking list.
What is an intent note in code?
It is a short comment next to a deliberate choice that says why the code looks the way it does, for example a retry cap that exists because of an upstream rate limit. Reviewers are told not to flag what an intent note explains, and to flag only code that contradicts its note. It records the decision where both people and agents will read it.
When should an AI-reviewed pull request still go to a human?
Whenever it touches a high-risk area, whatever the bots concluded. My list covers schema migrations, authentication, payments, deleting user data, APIs that outside consumers depend on, infrastructure and security-sensitive changes. A human also takes over when the loop breaker fires.
Do I need two different AI models for finder and verifier?
It helps, because two different models are less likely to make the same mistake. A different prompt and a narrower context on the same model is the minimum. What matters most is that the verifier is asked to prove a finding and not to produce new ones.
Ready to Transform Your AI Strategy?
Get personalized guidance from someone who's led AI initiatives at Adidas, Sweetgreen, and 50+ Fortune 500 projects.