Set up a REVIEW.md and two reviewer agents so Claude reports bugs that would hurt users, not style nits.
Most AI code reviews fail in the same way: twenty comments about naming and one real bug buried at position fourteen. This guide is for builders who already use Claude Code and want reviews they can trust. At the end you will have a written definition of "real bug" for your repository, a read-only reviewer agent that checks its own findings with a second agent, and a CI job that fails a branch only when something important is wrong.
What you will have at the end
A REVIEW.md that tells every reviewer what counts as a finding, what to skip and how much evidence it needs.
A bug-hunter subagent that reviews your branch without editing anything.
A finding-checker subagent that tries to disprove each finding before you see it.
The built-in /code-review command following the same rules.
A CI script that runs the reviewer with a turn and budget cap and fails on Important findings.
Before you start
Claude Code installed and signed in. The --max-findings flag on /code-review needs v2.1.288 or later, so update if you are behind.
A git repository with a main branch and a feature branch that has some changes on it.
The attached review-pack/ folder. It holds every file in this guide, ready to copy.
You do not need a Team or Enterprise plan. The managed Code Review service that comments on GitHub pull requests is limited to Team and Enterprise, but the local /code-review command works on any plan, and the custom subagents in this guide are plain files in your repository.
Step 1: Write down what a real bug is
Create REVIEW.md at the root of your repository. Here is the core of the template from the pack:
# Review instructions
Report only findings that would hurt a user, lose data, leak data, cost money or break a deploy. Every finding needs `file:line` and a one-sentence failure scenario: the input, then the wrong result.
## What Important means here
Important is for findings that change behavior in production:
- Wrong logic: an off-by-one, an inverted condition, a missing `await`, a race between two requests.
- Data loss: a write that can overwrite or delete rows it should not touch, a migration that cannot roll back.
- Data exposure: one user's data reachable by another, secrets or personal data in logs, error messages or client bundles.
- Auth and money: a permission check that can be skipped, a payment or quota path that can be bypassed or applied twice.
- Input at a trust boundary used without validation or escaping.
Style, naming and refactoring ideas are Nit at most.
## Evidence rules
- A claim about behavior needs a `file:line` citation in the source, not an inference from a function name.
- A claim that something is "unused" or "never called" needs the search you ran.
- If you cannot describe the input that triggers the bug, it is not a finding.
## Do not report
- Anything CI already enforces: formatting, lint, type errors.
- Generated files, lockfiles and vendored code.
- Test code that breaks production rules on purpose.
## Cap the nits
Report at most three Nits per review.
The full file in the pack adds an "Always check" list and a section for paths that deserve a higher bar.
Why each part matters:
The opening rule sets the bar. A reviewer with no bar reports everything it notices, and you stop reading. "Would hurt a user, lose data, leak data, cost money or break a deploy" is short enough to apply to every line.
The failure scenario is the strongest filter you have. If the reviewer has to write "a logged-out user with an expired cookie gets the full paid text", it has to trace a real path. Vague findings like "this might cause issues" cannot pass this test, so they disappear.
Evidence rules target the most common false positive: guessing what a function does from its name. The Claude Code docs suggest exactly this kind of rule, for example requiring that "behavior claims need a file:line citation in the source, not an inference from naming", to cut false positives.
Do not report removes noise your tools already handle. If CI runs a linter, a review comment about lint is pure cost.
A nit cap keeps the report short even when the reviewer finds many small things. The official example caps nits at five; we use three.
Now open the "Always check" section in the pack's REVIEW.md and replace the sample rules with the bugs your team has actually shipped. Good rules are testable: "every query that reads user data is scoped to the caller" works, "code should be secure" does not.
That file alone already improves reviews if you paste it into a prompt. The next steps make it automatic: a reviewer that reads it every time, a second agent that throws out wrong findings, and a CI gate.