<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Nicolas Borson</title><description>Engineering Manager at Batch, based in Lyon, France</description><link>https://borson.fr</link><item><title>Checking the fixes an AI reviewer suggests</title><link>https://borson.fr/blog/checking-ai-reviewer-fixes</link><guid isPermaLink="true">https://borson.fr/blog/checking-ai-reviewer-fixes</guid><description>AI reviewers are often right about the problem and wrong about the correction. How to verify what they suggest, and when to stop the loop.</description><pubDate>Tue, 03 Nov 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is a failure mode that comes up in almost every account I read from teams running AI reviewers at scale. The reviewer leaves a comment. The comment is correct. The author accepts the suggested fix. The fix is wrong.&lt;/p&gt;
&lt;p&gt;Wrong in the quiet way, the kind that passes CI and gets merged.&lt;/p&gt;
&lt;p&gt;I have no number on how often it happens on our side. As a manager I am rarely the one reading the diff, and that is precisely why I want the habit written down before we lean on these tools. If the people who do read the diff have a checklist, I never need to.&lt;/p&gt;
&lt;h2&gt;A small example&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://florian.bruniaux.com&quot;&gt;Florian Bruniaux&lt;/a&gt; showed one in his talk &quot;Du code au merge&quot; at Dev With AI in Paris on October 12, from a real PR on his codebase at Méthode Aristote. A test covered two failure cases, a missing document and a forbidden access, and asserted only that each one raised an error. The reviewer flagged it: the test accepts any error, so it can pass for the wrong reason. Correct diagnosis.&lt;/p&gt;
&lt;p&gt;The bot&apos;s suggested fix was to assert the same error message in both cases. More precise than before, and still incorrect, because the two cases should produce different errors. The right fix was to assert the error specific to each case, then rerun.&lt;/p&gt;
&lt;p&gt;Three steps, and the bot got two of them. Verify the problem it reports. Then verify the correction it proposes. Two separate acts, and people skip the second because the diagnosis was so convincing.&lt;/p&gt;
&lt;h2&gt;Where the reviewer&apos;s time goes&lt;/h2&gt;
&lt;p&gt;Anthropic published numbers from their internal reviewer this month (&lt;a href=&quot;https://claude.dev/blog/solving-code-review-at-anthropic/&quot;&gt;How the Claude Code team does code review&lt;/a&gt;), and one of them explains why this matters at scale.&lt;/p&gt;
&lt;p&gt;About 59 percent of what the reviewer kept flagging in later rounds was code that was already there before the PR. Round after round, the reviewer was digging up old bugs in the surrounding code and asking the author to own them.&lt;/p&gt;
&lt;p&gt;One PR on their CLI went through more than fifty review rounds overnight before its author stopped it.&lt;/p&gt;
&lt;p&gt;Their fixes are worth copying even at a tenth of the volume.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Label the finding.&lt;/strong&gt; Important, Nit, or Pre-existing. A pre-existing bug deserves a ticket. Fixing it in this PR is someone else&apos;s call.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cap the rounds.&lt;/strong&gt; After three review-and-fix rounds, the reviewer stops suggesting and asks the author to reconsider the approach. After the first few passes, it reviews only the diff.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flag the class.&lt;/strong&gt; If the same mistake appears in five places, one comment that names the pattern, so the author fixes all five, including the four nobody pointed at.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Never repeat.&lt;/strong&gt; A finding already posted is not posted again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Every finding gets an answer.&lt;/strong&gt; Fix it, or resolve the thread with a reason. A later commit that fixes it closes the thread automatically.&lt;/p&gt;
&lt;p&gt;The results after those changes, on their internal PRs: the share passing after a single round went from 65 to 78 percent, and PRs needing five rounds or more dropped from 8.9 to 1.5 percent.&lt;/p&gt;
&lt;h2&gt;Watch it work&lt;/h2&gt;
&lt;p&gt;The second half of the problem sits with the author.&lt;/p&gt;
&lt;p&gt;Agents are good at explaining why their code works. The explanation is usually convincing and not always right. Daniel Visca at PostHog has a rule for this (&lt;a href=&quot;https://newsletter.posthog.com/p/code-review-tips&quot;&gt;Stop being the code review bottleneck&lt;/a&gt;): do not accept an argument that the code works when you can watch it work.&lt;/p&gt;
&lt;p&gt;In practice that means every change ships with a way to observe it. A command to run, a request with its expected response, a screenshot, a state dump. What gets validated is the behaviour you can see. Anthropic&apos;s version is the same: the test output goes in the PR.&lt;/p&gt;
&lt;p&gt;Which brings up the rule that Bruniaux put on one slide and that I think deserves to be printed above every merge button.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A test that is in progress, skipped or cancelled is not a passed test.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And its sibling: a new push changes what remains to be verified. Commit A was tested and reviewed. The agent pushes a fix, now the branch is at B. A validated does not mean B validated. Before merging B, which tests must rerun, and has anyone read the diff from A to B? After every fix, rerun the tests and the reviews that the fix touched, and only those.&lt;/p&gt;
&lt;h2&gt;When a bot gets it wrong twice&lt;/h2&gt;
&lt;p&gt;The loop closes on one more habit, and it is the cheapest one.&lt;/p&gt;
&lt;p&gt;When a reviewer makes the same mistake twice, or misses the same case twice, look at the harness around the reviewer before you look at the PR. Bruniaux&apos;s team opens a GitHub issue for it, with the exact case, the expected result and the linked PR. Then they fix the cause, which is usually one of three things: a missing regression test, an instruction that needs sharpening, or context the reviewer did not have. Then they replay the case and watch the next few PRs.&lt;/p&gt;
&lt;p&gt;Anthropic does the same at a larger scale. Past incident and revert PRs, confirmed by experts, form an eval set the reviewer runs against daily, and every change to the reviewer is scored against all of it. Incidents become tests for the reviewer itself.&lt;/p&gt;
&lt;p&gt;The habit is the same at both scales. The reviewer is a piece of software your team maintains. It has bugs. You file them.&lt;/p&gt;
&lt;h2&gt;The checklist I would hand the team&lt;/h2&gt;
&lt;p&gt;For a reviewer comment:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Is the problem real? Read the code before you read the comment again.&lt;/li&gt;
&lt;li&gt;Is the proposed fix right? Separate question. Often no.&lt;/li&gt;
&lt;li&gt;Is it in this PR&apos;s scope, or pre-existing? Pre-existing gets a ticket.&lt;/li&gt;
&lt;li&gt;After the fix, which tests and which reviews need to run again?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the reviewer:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Three rounds, then stop and rethink.&lt;/li&gt;
&lt;li&gt;Same miss twice, file an issue against the harness.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;None of this needs a product. The first checklist is a habit, the second is a label, a round counter and an issue template. That is also why I am writing it down now, before we have a reviewer running on every PR and before the first quiet bug. What it does need is a written statement of what a good finding looks like in your repo, and that is the subject of the next post.&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>Who merges when the reviewer is a bot</title><link>https://borson.fr/blog/who-merges-when-the-reviewer-is-a-bot</link><guid isPermaLink="true">https://borson.fr/blog/who-merges-when-the-reviewer-is-a-bot</guid><description>Under what conditions should an agent approve a pull request, or merge it? The teams that have tried it converge on the same three rules, and none of them starts with &quot;trust the model&quot;.</description><pubDate>Tue, 27 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every discussion about AI code review ends on the same question. If the bot reviews the PR, can the bot merge it?&lt;/p&gt;
&lt;p&gt;My instinct was no, and since we have not tried it yet, I spent a few weeks reading to find out whether that instinct was just habit. It turns out the teams with the most volume have already answered, and the answer is more interesting than yes or no. They do let agents merge, under rules the agent had no part in writing.&lt;/p&gt;
&lt;h2&gt;Trust belongs to the task&lt;/h2&gt;
&lt;p&gt;Jina Yoon at PostHog wrote the clearest framing I have read (&lt;a href=&quot;https://newsletter.posthog.com/p/agent-autonomy&quot;&gt;When to trust an agent&lt;/a&gt;). Trusting an agent more because the model got better is like skipping the seatbelt because you bought a nicer car. What matters is the task, and two questions are enough to classify it.&lt;/p&gt;
&lt;p&gt;Is the work easy to verify with deterministic checks?&lt;/p&gt;
&lt;p&gt;Is a mistake cheap to undo?&lt;/p&gt;
&lt;p&gt;| Verification | Cost of undo | Level |
|---|---|---|
| Hard | High | 0. The agent assists, a human does the work. |
| Hard | Low | 1. Human in the loop, the work stays a draft until someone validates it. |
| Easy | High | 2. Delegated to the agent, with one last net before merge. |
| Easy | Low | 3. Full autonomy. |&lt;/p&gt;
&lt;p&gt;Her example is worth keeping. PostHog rewrote their SQL parser in Rust and barely read it line by line, because a mechanical oracle existed to check the output. But the parser sits under every query on the platform, so the rollout went through a shadow mode in production and a gradual switch. Easy to verify, expensive to undo, so level 2 with a net.&lt;/p&gt;
&lt;p&gt;Auto-merge is level 3 only. Easy to verify and cheap to undo, which in practice means behind a feature flag with a rollback that takes minutes.&lt;/p&gt;
&lt;h2&gt;Keep the classifier away from the reviewer&lt;/h2&gt;
&lt;p&gt;The obvious shortcut is to ask the reviewing agent whether the PR is safe to merge. Resist it.&lt;/p&gt;
&lt;p&gt;First because an LLM judging its own category is exactly the setup that fails. JudgeBiasBench, a preprint from this spring (&lt;a href=&quot;https://arxiv.org/abs/2604.23178&quot;&gt;arXiv 2604.23178&lt;/a&gt;), measured LLM-as-judge at over 50 percent error on bias detection, with style bias dominating. One number from one preprint, but it matches what anyone who has watched a model grade its own homework already suspects. A lone LLM judge makes a poor production gate.&lt;/p&gt;
&lt;p&gt;Second because the useful classification is mostly deterministic. Which paths did the diff touch? Does it change a migration, a payment flow, a permission check, a CI workflow file? Does it add code behind a flag or change existing behaviour? Those are rules. A path-based labeler answers them before any model runs.&lt;/p&gt;
&lt;p&gt;Anthropic&apos;s Claude Code team, who now land more than 30,000 changes a day in their monorepo, sum it up in one rule (&lt;a href=&quot;https://claude.dev/blog/solving-code-review-at-anthropic/&quot;&gt;How the Claude Code team does code review&lt;/a&gt;): the change itself sets the risk tier, whoever wrote it.&lt;/p&gt;
&lt;p&gt;In practice, a classifier picks the tier from the diff. A second classifier checks whether a person is needed anyway. Some paths always need one: areas listed as sensitive by their owners, and any CI workflow file.&lt;/p&gt;
&lt;p&gt;| Risk | Examples | Human approvals |
|---|---|---|
| Low | Docs, copy, internal-only features, additive changes behind a flag | None, once automated and security checks are green |
| Medium | Ordinary product changes, plus sensitive areas like caching, the auto-updater, system prompts | One |
| High | The riskiest code, and paths that always need two people | Two |&lt;/p&gt;
&lt;p&gt;Two more rules from the same post, which I think are the whole thing in miniature.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An agent&apos;s approval never counts as a person&apos;s.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;An approval covers one specific commit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A new push after approval is a new PR as far as the system is concerned. &lt;a href=&quot;https://florian.bruniaux.com&quot;&gt;Florian Bruniaux&lt;/a&gt; made the same point in his talk at Dev With AI in Paris this month, &quot;Du code au merge&quot;: &quot;A validated doesn&apos;t mean B validated.&quot; Tests and reviews attach to a commit. The conversation around the PR carries nothing.&lt;/p&gt;
&lt;h2&gt;A ladder with three rungs&lt;/h2&gt;
&lt;p&gt;Put together, the teams I have read converge on a ladder. You climb it one rung at a time, and most teams should stop at the second.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The agent proposes, the author confirms.&lt;/strong&gt; Deterministic labelling by path, then an agent that proposes a label and a one-line reason. The author of the PR confirms or overrides. Bruniaux runs this with two GitHub labels, Review AI and Review Human. Review AI is for a bounded, known change that tests can verify, inside a perimeter the team has authorised. Review Human is for access rights, private data, calculations, payments, or anything whose consequences are not well understood. When in doubt, ask for a human. The labels are a signpost for people and a filter for the bots.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Auto-approve, human merges.&lt;/strong&gt; The agent review counts as an approval on low-risk PRs. A person still presses the button, which keeps ownership attached to a name. PostHog does a version of this with StampHog, a bot that approves low-risk PRs. The NextLevel case study collection on agentic code review (&lt;a href=&quot;https://agentic-code-review.netlify.app/&quot;&gt;source&lt;/a&gt;) covers eight organisations, and in every one of them a human still merges.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Auto-merge on a listed class.&lt;/strong&gt; Docs, copy, dependency bumps with green CI, additive code behind a flag. The class is written down somewhere, and nothing outside the list qualifies. Only trusted authors, in practice the owning team, get the lighter path. And the guardrail is measured: if reverts or incidents go up, the lighter path closes.&lt;/p&gt;
&lt;p&gt;Anthropic&apos;s post ends on something I find reassuring. They do not yet have the circuit breaker that tightens approval automatically when revert numbers rise, and their engineers want it before more code moves to zero-human merges. Even the team furthest along is not comfortable without it.&lt;/p&gt;
&lt;h2&gt;What scales down&lt;/h2&gt;
&lt;p&gt;We are nowhere near 30,000 changes a day, and we have not climbed any of this ladder yet. What draws me to it is that the first rung costs almost nothing. A path-based labeler, two labels, and a short written perimeter that says which kinds of changes the team is willing to let a bot read alone.&lt;/p&gt;
&lt;p&gt;The tooling is the easy half. Writing that perimeter down and agreeing on it takes a team conversation, and the next post is about what the bot does once it is inside the perimeter and finds something.&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>The bottleneck moved</title><link>https://borson.fr/blog/the-bottleneck-moved</link><guid isPermaLink="true">https://borson.fr/blog/the-bottleneck-moved</guid><description>Code got cheap to write. Review and testing did not. What a thirty-year-old factory vocabulary says about the queue forming in front of your reviewers.</description><pubDate>Tue, 20 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I manage a squad in a SaaS company. We adopted coding agents this year and we are at the very beginning of rethinking how we work around them. From where I sit, one thing already bothers me more than the quality of the generated code. The queue.&lt;/p&gt;
&lt;p&gt;Pull requests arrive faster than anyone can read them. One of my engineers reviews most of the front-end work and the pile in front of him keeps growing. On a recent project we duplicated an existing integration pattern across several new data sources in a few days, because that is exactly the kind of thing an agent does well. Then we spent far longer testing it than writing it.&lt;/p&gt;
&lt;p&gt;That is about all I have seen with my own eyes so far. Two symptoms. The rest of this post is what I found when I went looking for whether other teams had the same two, and what they did about it.&lt;/p&gt;
&lt;p&gt;None of this is specific to us. Make one step in a chain almost free and this is what you should expect.&lt;/p&gt;
&lt;h2&gt;When one step becomes free, the next one becomes the bottleneck&lt;/h2&gt;
&lt;p&gt;Software delivery is a chain. Specify, write, review, test, ship, observe. For twenty years the expensive step was writing. Teams, rituals and tooling were sized around that cost. Review was a fraction of the writing time, so one reviewer per author was enough. Manual QA could keep up with the trickle of features.&lt;/p&gt;
&lt;p&gt;Now writing is wide, and review and testing kept their old width. The bottleneck is still there. It moved one step to the right.&lt;/p&gt;
&lt;p&gt;The numbers are consistent across sources that do not share an agenda. The &lt;a href=&quot;https://cloud.google.com/blog/products/ai-machine-learning/announcing-the-2025-dora-report&quot;&gt;2025 DORA report&lt;/a&gt; describes throughput and instability rising together, with downstream bottlenecks exposed in testing and review. Its one-line thesis is that AI amplifies what a team already is. Faros AI, which sells telemetry and therefore has a stake in the story, measured 22,000 developers and found median time in review up 441 percent, PRs merged without review up 31 percent, and incidents per PR up 243 percent between low and high adoption periods (&lt;a href=&quot;https://www.faros.ai/blog/ai-acceleration-whiplash-takeaways&quot;&gt;source&lt;/a&gt;). Take the exact figures with care. The direction is not in doubt.&lt;/p&gt;
&lt;p&gt;Anthropic&apos;s own Claude Code team went from about 2,500 changes a day in their monorepo in May to more than 30,000 in September (&lt;a href=&quot;https://claude.dev/blog/solving-code-review-at-anthropic/&quot;&gt;source&lt;/a&gt;). Nobody reads 30,000 changes a day.&lt;/p&gt;
&lt;p&gt;Balint Orosz put it in a way I keep coming back to. Writing the code was always 20 percent of the job and testing it was 80 percent. The mistake is trying to compress the 80.&lt;/p&gt;
&lt;h2&gt;Three words from Toyota&lt;/h2&gt;
&lt;p&gt;When I try to explain the situation to people outside engineering, the word &quot;bottleneck&quot; falls short. It mixes three different problems. The Toyota Production System has a word for each.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mura&lt;/strong&gt; is unevenness. The flow is out of balance. Development outruns review and QA. This is the root cause, and the only one worth fixing directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Muda&lt;/strong&gt; is waste. Work that waits. Features sitting in a column called &quot;ready for test&quot; for a week. Branches that need a rebase because they aged. Context that the author has already lost by the time a comment arrives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Muri&lt;/strong&gt; is overburden. The person at the narrow step is drowning. They review faster and worse, or they review well and fall behind on everything else.&lt;/p&gt;
&lt;p&gt;The classic trap is to treat muda by manufacturing muri. The features are waiting, so we block afternoons for testing, we ask the reviewer to go faster, we add a second reviewer who is already busy. The queue shrinks for a week and the people burn.&lt;/p&gt;
&lt;p&gt;The other trap is quieter. When review becomes too heavy, two behaviours appear. Some people approve as soon as the automated review has nothing to say. Others keep reading seriously and get buried under everyone else&apos;s PRs. You lose on both sides, quality on one and people on the other.&lt;/p&gt;
&lt;h2&gt;Three conclusions I refuse to draw&lt;/h2&gt;
&lt;p&gt;That we should write less code with agents. The 20 percent got cheap, and that is good news.&lt;/p&gt;
&lt;p&gt;That a product will fix it on its own. The teams with the most data on this, Uber, Cloudflare, Anthropic, PostHog, have all ended up building their own review and verification systems after trying off-the-shelf reviewers. Monzo switched on GitHub Copilot&apos;s automated review and then switched it off by default, because the suggestions were not actionable. What counts is how many comments change what the author does, and most of those tools produce volume instead.&lt;/p&gt;
&lt;p&gt;That the bar has to come down. The question I want the team to work on is how we keep pace at this step without lowering the bar. Getting people to review more is a different question, and it leads to different experiments.&lt;/p&gt;
&lt;h2&gt;Where this goes next&lt;/h2&gt;
&lt;p&gt;Several directions at once, and one post will never cover them. Once writing is cheap, at least six other things wobble.&lt;/p&gt;
&lt;p&gt;The harness around the agent, meaning the instructions, rules and context the team shares, because an agent without a shared harness improvises with whatever pattern is most common on the internet, which is rarely the one you chose.&lt;/p&gt;
&lt;p&gt;Who gets to merge what, and whether an agent&apos;s approval should ever count.&lt;/p&gt;
&lt;p&gt;How you verify a bot&apos;s suggestion when the bot is right about the problem and wrong about the fix.&lt;/p&gt;
&lt;p&gt;What happens to prototypes when anyone can build one overnight, to team topology when a backend engineer ships their own front-end, to planning when changing your mind costs nothing, and to the quiet learning that used to happen when a junior asked a senior a question.&lt;/p&gt;
&lt;p&gt;I will take them one at a time. The next two posts are about the two I expect to hurt first: deciding who merges, and trusting a reviewer that has no name.&lt;/p&gt;
&lt;p&gt;If you have been through this and found a lever that worked, I would like to hear about it. Most of what I read comes from companies ten times our size, and I am trying to work out which parts scale down.&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item></channel></rss>