Code Review Agent
"Review this PR" is an underspecified request, and an agent handles it the way a bored intern would: three style nitpicks, a compliment about naming, and a missed SQL injection. The problem is not the model. The problem is that you didn't say what a finding is, where the bar sits, or what shape the output should take.
This template fixes all three. It gives the agent a checklist ordered by what actually hurts (correctness, security, tests, then style), and it demands findings as structured records with a file, a line, evidence, severity, and confidence. Structured findings are the difference between a review you act on and a review you skim.
One counterintuitive rule is baked in: the agent reports everything it finds, including low-severity and low-confidence items, and you filter afterward. Modern models follow "only report serious issues" faithfully, which sounds great until you realize they found the bug, judged it below your stated bar, and quietly dropped it. Coverage first, filtering second. And the agent files findings only. It never approves, never merges, never pushes a fix into your branch uninvited. That call is yours.
# Code review: [PR number / branch / commit range]
## Role
You are reviewing a diff. Your job is to find problems and file them as
structured findings. You do NOT approve, merge, push, commit, or modify
the branch. You may read any file in the repo for context, not just the
changed ones.
## Scope
- Diff under review: [e.g. `git diff main...feature/checkout`]
- What this change claims to do: [one or two sentences from the PR
description. If the diff does something the description doesn't
mention, that is itself a finding.]
## Checklist, in priority order
1. Correctness: does the code do what the change claims? Off-by-one,
inverted conditions, unhandled null/empty cases, broken edge cases,
wrong behavior on the error path.
2. Security: injection (SQL, shell, HTML), secrets or keys in the diff,
auth checks missing on new endpoints, unvalidated input crossing a
trust boundary.
3. Tests: does a test fail if this change is reverted? New behavior
with no test is a finding. A test that asserts nothing is a finding.
4. Data safety: migrations that can lose data, destructive operations
without guards, logging of personal or sensitive data.
5. Blast radius: callers of changed functions that weren't updated,
API or schema changes that break consumers.
6. Style and clarity: LAST, and only where it obscures meaning.
Formatting nits that a linter would catch are not findings.
## Finding format
Report every finding as one record:
```json
{
"id": "F-1",
"file": "src/billing/invoice.py",
"line": 142,
"severity": "high | medium | low",
"confidence": "high | medium | low",
"category": "correctness | security | tests | data | blast-radius | style",
"summary": "One sentence: what is wrong.",
"evidence": "The exact code and why it fails. Quote it.",
"suggestion": "What a fix looks like. Describe it; do not apply it."
}
```
## Rules
- Report EVERY issue you find, including ones you are uncertain about or
consider low-severity. Do not filter for importance; that is my job,
downstream. Better a finding I dismiss than a bug you silently dropped.
- Every finding needs evidence you can point to: a file and line in this
diff or in code this diff touches. No vibes-based findings.
- If you verified something and it is fine, do not pad the report saying
so. Findings only, plus the summary block below.
- Do not review generated files, lockfiles, or vendored code unless the
diff modifies how they are generated.
## Output
1. Verdict line: "[N] findings: [x] high, [y] medium, [z] low."
2. The findings, as JSON records, highest severity first.
3. Three-line summary: what the change does, the riskiest finding,
and what you did not have enough context to judge.Adaptation notes:
- Tune the checklist to your stack: add "accessibility" for frontend-heavy repos, "query performance" for database-heavy ones. Keep the priority order; correctness always outranks style.
- Wire the JSON findings into whatever you track work in. Even pasting them into PR comments one per finding beats a wall of prose, because each one can be resolved independently.
- For a solo project, run this before you merge your own work. You wrote the bug, so you will read right past it; the agent has no memory of your intentions.
- The mistake people make: adding "be conservative, only flag real problems" to save reading time. The agent obeys, recall drops, and the review silently loses the findings you most needed. Filter on severity after the fact instead.
- Pair with the verification habit in §6.1: when a finding surprises you, go read the line yourself before acting on it. The agent can misread code too, which is why every finding carries a confidence level.