The PR review agent
Build this one first: it needs nowhere to deploy to and writes nothing on its own. Its unit of work is the difference against the destination branch as it stands now — not the commits the author pushed, which is a different and moving thing.
Think of a proofreader given a chapter to check. What matters is how the chapter reads in the book as it stands today, not the list of edits the writer made — because someone else has been editing the chapter before it in the meantime.
If you build one agent, build this one. It needs no deployment target, no error tracking and no versioned releases. It writes nothing on its own. It runs on changes that already exist, on the day you switch it on, and it tells you within a week what a review actually costs — which is the number that decides whether the rest of the plan is affordable.
The unit of review is not the commits#
The obvious answer is that a review agent reviews the change. The useful answer is more specific: it reviews the difference between the change and the destination branch as the destination stands now. Those are not the same thing, and the gap between them opens every time somebody else merges while the branch is open.
Two changes that were each correct against the base they forked from can be wrong together — a signature that moved, a column that was renamed, an assumption one of them stopped being allowed to make. Reading only the author’s commits cannot show that, because the conflict is not in either set of commits. It is in the space between them, which is exactly the region the shaded band covers.
Making that the unit has a practical consequence: the destination head belongs in whatever identifies a review run. If the destination moves, the effective difference has changed and the change is worth re-reading, even though the author pushed nothing. And the inverse — a run keyed by an immutable description of what it read means an unchanged input state is never paid for twice, which is most of what keeps re-review affordable when somebody is pushing every four minutes. A short quiet timer collapses that burst into one run.
Build status is the deliberate exception and it belongs outside that key. A pipeline can go from running to green without a byte of code changing, so folding it into the identity of the run would invalidate a review for a reason that has nothing to do with the code. It is refreshed separately and read as evidence.
What the build already owns#
The fastest way to make a review agent expensive and annoying is to let it re-decide questions the build has already answered. Formatting has a formatter. Lint rules have a linter. Coverage has a threshold. Static analysis has a tool with a verdict. Each of those produces the same answer every time, for free, before any model is involved — and a model that disagrees with one of them has not found a defect, it has produced a second opinion on a settled question.
So the agent honours those gates and never argues with them. What it spends its attention on is the set of things no script can decide. Does the change do what the work item asked, and is there implementation evidence for each acceptance criterion? Is the scope coherent, or has something unrelated ridden along? Are the error cases handled, and is the security-sensitive path actually the one that got the care? Do the tests exercise the behaviour that changed — and, the question that matters most and gets asked least, was an assertion weakened to make something pass?
That last one deserves its own standing rule, and it extends past the reviewer. An agent must never quarantine, weaken or rewrite an unstable test without a person seeing it. A flaky test that is silently retried away is a defect that has been converted into a habit, and a factory produces enough changes that the habit forms fast. Log it, name it, fix the cause — and keep the fixing out of the hands of the thing under time pressure to go green.
Independence costs something#
There is a design decision here that looks like an optimisation and is not. When the reviewer finds something fixable, it could simply push the fix — the branch is right there, the build will re-run, the loop closes in one step instead of two. It is genuinely faster.
It also costs four things at once. The reviewer stops being independent, because it is now re-checking its own work. Authorship blurs, so nobody can say afterwards whether the builder or the reviewer wrote the line that broke. The reviewer needs write credentials it would otherwise never hold, which widens what a compromised comment could reach. And the findings become interleaved with the changes, so the record of what was wrong is buried in the record of what was done about it.
The alternative costs a round trip: the reviewer reports structured findings, the builder produces the repair commit, and the reviewer re-checks something it did not write. On a first implementation that trade is worth taking — latency is recoverable, and an independent second read is the entire point of the step. Mechanical exceptions can be revisited later, once there is data about what the round trip actually costs.
What the agent never does is approve. It classifies risk, it says what it found, and it leaves the change for a person — which is not a limitation of the current generation of models but a property of the design. Its own credentials should make that literal: a separate identity from the builder, no merge permission, comments only. And like every other agent, when it is genuinely unsure it stops and asks, rather than producing a confident review of something it did not understand — the escalation route the readiness step needs for the same reason.
IF YOU REMEMBER ONE THING
Review the difference against the destination as it stands now, not the commits the author pushed. The bug that gets through is usually in the gap between two changes that were each fine on their own.
Questions people also ask
4 QUESTIONSWhy is a review agent the right first agent to build?
Because it has almost no dependencies and almost no blast radius. It needs no deployment target, no error tracking and no versioned releases — only the ability to read a change and write a comment. Everything downstream of a merge inherits infrastructure that takes months. A review agent can run advisory on real changes in days and measures its own cost while it does.
What should a review agent not check?
Anything the build already decides. Formatting, lint rules, coverage thresholds and static analysis all produce a deterministic verdict, and a model re-deciding them adds cost, adds disagreement and adds a second answer to a question that already had one. The agent reads those results as evidence and spends its attention on what no script can judge.
Should the reviewer push fixes to the author's branch?
Not in a first implementation. It ends the reviewer's independence, blurs who authored the final change, requires write credentials the reviewer would otherwise never need, and means a comment on the pull request can influence a code write. Reporting structured findings and letting the builder produce the repair commit costs a round trip and keeps the re-check honest.
How does re-review stay affordable when a branch is pushed to constantly?
By reviewing input states rather than pushes. A short quiet timer collapses a burst of small pushes into one run, and every run is keyed by an immutable description of what it read — the source commit and the destination head — so an unchanged input state is never paid for twice. Build status stays outside that key, because it changes without the code changing.