Field Notes

Mapping Anthropic's code review stack onto my one-person repo

Mapping Anthropic's code review stack onto my one-person repo

On 15 October the Claude Code team published how they do code review now that Claude writes most of their code. Their goal is "the minimum amount of human review time that doesn't raise reverts or incidents". Between June and September their merged PRs more than doubled, and the share of changes that got reverted fell by more than 40 percent.

I came across an infographic summarising the post and read it next to my own setup: one repository, one Hetzner box, four hosts, and a /ship skill that takes a change from branch to production. This post covers what I copied, what I changed, and what I deliberately left out. It also covers the two things that went wrong on the first run.

Infographic summarising Anthropic's code review stack: six layers from pre-PR verification to staged release, plus reviewer tuning, convergence rules and where humans still matter
The summary that started it. Infographic by The Generative Programmer, based on the Anthropic post.

The idea in one paragraph

Review is no longer one human gate at the end. It is a chain of layers, and each one catches a different kind of failure. First the author agent verifies its own work. Then an AI reviews every PR, a security review can block, CI is required, human approval scales with risk, a merge queue re-checks against main, and the whole thing rests on fast detection and rollback. The part I found most useful was not a layer at all. It was the section on convergence. One of their PRs ran through more than fifty review rounds overnight because an agent author and an agent reviewer kept answering each other. Their fixes are a three-round cap, re-reviewing only the diff after the first passes, flagging bug classes instead of single lines, and never repeating a finding.

What I already had

More than I expected. CV Next already had a CLAUDE.md that names the dangerous places: the shared Traefik router rule that takes four hosts offline if you get it wrong, Flyway migrations V1 to V6 that must stay byte-identical, the outbox wire format both runtimes must read, and a FOCUS token that allows exactly two endpoints. Hooks enforce the rules prose cannot, like no commits on master, no edits to frozen migrations, and no secret dumps. ci.yml runs the backend against a real PostgreSQL, plus the agent, MCP server, frontend and the hook tests. The LGTM stack on obs.zakaria.lu covers detection.

The gap was layer two. /ship ran /code-review locally before committing, in the same session that had just written the code. That review shares the author's context and assumptions. The post's point is that a fresh context finds different things.

Table mapping Anthropic's seven review layers to my setup: pre-PR verification kept, AI review on every PR built, security review changed to weekly manual, required CI kept, risk-scaled approval changed, merge queue not adopted, detection and rollback kept
Only one layer was missing. Two I changed on purpose, and one does not fit a single box.

What I built

A new workflow, claude-review.yml, runs on every non-draft PR into master. I kept it separate from ci.yml because that workflow runs PR code and is deliberately secret-free. The review job needs one secret, so it only runs for branches of this repository, never forks.

Three design choices matter more than the YAML.

A REVIEW.md written from CLAUDE.md

The post says a good REVIEW.md describes "what failure looks like in that repo". Mine is mostly the risk sections of CLAUDE.md rewritten as review rules, with one rule per area and a blocking default. It also tells the reviewer to read any .claude/rules/*.md file whose paths: match a changed file, so the path-scoped rules I already maintain feed the review for free. Every finding needs a path:line and a concrete failure scenario. Nits are out of scope, because lint and types already run in CI.

The model writes; the shell decides

The reviewer gets read tools, git diff, and permission to write a single file. It cannot comment, push or approve. A plain shell step reads the first line, which must be VERDICT: CLEAN, FINDINGS or BLOCKING. It posts the comment and fails the check on BLOCKING. The comment starts with a marker tied to the commit it reviewed:

<!-- claude-review sha=294a0bd43c20ce1ed6b89bd192388b5a537625db round=2 verdict=CLEAN -->

That sha does a lot of work. /ship uses it to spot a stale verdict. The next round uses it to review only the commits since the last reviewed head. The round count, capped at three, comes from these markers too.

/ship waits, and gets one fix round

I am on GitHub's free plan, so these checks cannot be required for merging. /ship is the gate instead. Step 5.5 waits for CI and the verdict on the current head, applies clear fixes, and asks me about anything debatable. It gets one fix round. If the second review still blocks, the ship stops and comes to me. I removed the local pre-commit review entirely. It only comes back as a fallback when no verdict appears, for example during an outage or after the round cap.

What I chose not to copy

Security review on every PR. I run a security review weekly, by hand. On this repository, a security pass on every PR is too heavy for the risk it covers. REVIEW.md still flags obvious boundary breaks, like a widened token allowlist, but it explicitly does not run an audit.

Risk-scaled human approval. Their tiers are zero, one or two approvers. Mine are all me. What carries over is the risk map. REVIEW.md marks the paths where a finding blocks by default.

Merge queue, flags, staged releases. One box with image-only CD cannot do canaries. The nearest thing I have is a rollback guarantee in the data. The outbox protocol must stay readable by both the old and new runtime.

Voting verifiers, incident evals, noise measurement. These are the parts that make Anthropic's reviewer good at scale. My hook tests are a small version of "incidents become evals", where every guard exists because something went wrong once. Measuring which findings I actually act on is the next thing worth adding.

The first run reviewed nothing, and passed

The review step went green in about two seconds. The action had refused to run. Its default GitHub App authentication rejects any workflow file that differs from the copy on the default branch, so a PR cannot rewrite its own reviewer. On the PR that adds the reviewer, that means no review at all.

The verdict check caught it, because "no review file" fails the job. Without that check, I would have merged on a green tick that had reviewed nothing. The fix was to pass the job's own github_token. My reviewer never writes to GitHub, so it does not need the app at all. The guard also protected nothing here, because GitHub already runs a same-repository branch's workflows with secrets, and forks are excluded.

Its first real finding was about itself

Round one returned FINDINGS with two non-blocking issues, and both were real. The first was that my round and sha parsing scanned every line of earlier review comments. A review that quoted a marker, which is likely on PRs about this very workflow, could inflate the round count or point the next diff at the wrong commit. The second was that Dependabot runs get no secrets, so every dependency PR would show a red check that people learn to ignore. I fixed both, parsing only each comment's first line and skipping Dependabot, and pushed one commit. Round two ran in incremental mode on that commit alone and came back clean, listing what it had resolved.

GitHub PR comment from github-actions: Claude review, round 2, incremental, commit 294a0bd, CLEAN, with a Resolved list covering the marker parsing fix and the Dependabot skip
Round two reviewed only the fix commit and closed out round one's findings instead of repeating them.
GitHub Checks tab for commit 294a0bd showing two passing workflows, CI and Claude review, both triggered on pull_request
Two workflows on every PR. CI stays secret-free, and the review runs beside it.

That is the convergence section of the post, working at a small scale: one full pass, one diff-only pass, no repeats, done. The PR merged and deployed without me writing a single review comment. I still read the verdict before merging. That is the part the post says stays human: someone owns what ships.

Keep reading