Skip to content

Automated code review in Claude Code puts a second, independent reader on every diff before a person sees it: /code-review in the session, /security-review for sensitive paths, a claude -p pre-push gate with a structured verdict, and claude ultrareview for high-risk branches. A seeded-bug branch proves the setup catches the defects that matter.

This page is for developers who want Claude to catch their own mistakes before a teammate does, and for tech leads who own the review rules. Your sessions now open more pull requests than your reviewers can read. The human comments repeat: a missing error path, an unvalidated input, a test that covers only the happy path. Faros AI’s April 2026 AI Engineering Report measured median time in review up 441.5% across 22,000 developers. The mechanical part of review belongs to a machine, so people keep their attention for judgment calls. Commands on this page were checked against Claude Code v2.1.283 on the latest channel.

What automated review in Claude Code gives you

Section titled “What automated review in Claude Code gives you”
  • A /code-review routine for every branch, with the effort level and target chosen on purpose.
  • A pre-push hook that blocks a push only on a critical defect it can name by file and line.
  • One set of review rules in CLAUDE.md that the local review, the GitHub Action and managed Code Review all read.
  • A team review skill that runs in a fresh context, so the reviewer never shares the author’s reasoning.
  • A seeded-bug fixture that measures what your reviewer catches, rerun whenever the rules, the model or Claude Code change.

Which Claude Code review tool fits which moment?

Section titled “Which Claude Code review tool fits which moment?”

Use the cheapest private check first, so the public review stays worth reading.

ToolWhen it runsWhat it gives youLimits (checked 2026-09-26)
/code-reviewIn the session, before commitCorrectness bugs plus cleanup suggestions; --fix applies them, --comment posts them to the pull requestReads CLAUDE.md, not REVIEW.md
/security-reviewBefore a pull request that touches auth, input handling or secretsSecurity review of the branch diffDiff only; for a whole-repository audit see security audits with Claude Code
Pre-push claude -p gateOn git pushA pass or block verdict your script reads from JSONgit push --no-verify skips it, so CI stays the real gate
claude ultrareviewBefore merging a high-risk branchA cloud fleet of reviewer agents; every finding is independently reproducedNeeds a claude.ai login; three one-time free runs on Pro and Max, then “typically $5 to $25” in usage credits; not available with Zero Data Retention or on Bedrock, Google Cloud or Foundry
Managed Code ReviewOn pull requests, once after opening, on every push, or on @claude review, depending on the repository’s trigger; runs on Anthropic infrastructureInline comments ranked Important, Nit or Pre-existing; its check run always ends neutral, so it never blocks a merge by itselfTeam and Enterprise, research preview, “averages $15-25” per review; not available with Zero Data Retention or with the HIPAA configuration (Claude Code Code Review page, checked 2026-10-12); setup lives in running Claude Code in CI/CD

Prices and availability are Anthropic’s own figures from the Code Review and Ultrareview documentation.

/code-review is a bundled skill. /review is now its alias, not a separate command. With no argument it reviews your branch’s commits ahead of its upstream plus any uncommitted changes. It runs as a background subagent with its own context window, so you keep working while it reads.

  1. Run the review at an explicit effort level. In the Claude Code prompt:

    /code-review medium

    At low and medium the review reports only the findings it is most confident in. high through max broaden coverage and let in findings it is less sure of. Type the level every time: a bare /code-review reuses the last level you typed, even from an earlier session. From v2.1.290 (latest channel only on 2026-10-12), medium on models without tuned review settings, including Opus 5.5 and Sonnet 5.5, also reports cleanup and CLAUDE.md-convention findings, so a medium run reads longer than before on those models.

  2. Point it at something other than your working tree when you need to. The target comes after the level and flags:

    /code-review high main...feature/billing-retry
    /code-review src/payments/
    /code-review 142

    The first reviews a ref range, the second a path, the third pull request 142.

  3. Commit before you use --fix. A background review applies its --fix edits outside your session’s checkpoints, so /rewind does not undo them. With a clean commit behind you, git diff shows exactly what the fix changed and git restore . takes it back.

    /code-review medium --fix
  4. Post the findings where the team works. --comment puts them on the GitHub pull request as inline comments, or on a GitLab merge request as one note through the glab CLI:

    /code-review medium --comment 142
  5. Change how many findings you get when the usual limit is wrong for the diff. --max-findings <n> reports up to n findings and --max-findings all reports every finding, in place of the review’s usual limit (v2.1.288, latest channel only on 2026-10-12). Later reviews reuse the value until you pass --max-findings default:

    /code-review high --max-findings all main...feature/billing-retry

The failing test is the point of this prompt. A fix with a test that went from red to green is evidence you can check in a second; a fix without one is another diff someone has to read.

A review that does not know your conventions reports the wrong things. Put the rules in one place that every reviewer reads.

  • CLAUDE.md is read by /code-review, by the GitHub Action and by managed Code Review. Managed Code Review flags new violations of it as nits.
  • REVIEW.md at the repository root is read only by managed Code Review. Local /code-review ignores it, so a rule that must hold everywhere belongs in CLAUDE.md.

Add a short review section to the project CLAUDE.md:

## Review rules
- Blocking: missing authorization on a route under src/api/, SQL built from strings,
an error swallowed in src/payments/, a migration that is not backward compatible,
a test assertion removed or loosened.
- Do not flag: formatting, naming, import order (dprint and oxlint own those),
anything under src/gen/, any lockfile.
- The `any` type under src/legacy/ is intentional. Do not flag it.
- Every finding cites file:line and names the test or command that demonstrates it.

Then give the team one review command. A skill with context: fork runs as a separate subagent that starts from the skill text alone, without the author’s conversation, which is the independence you want from a reviewer. Save this as .claude/skills/pr-check/SKILL.md:

---
description: Independent pre-PR review of the current branch against origin/main. Use before opening a pull request.
disable-model-invocation: true
context: fork
allowed-tools: Read Grep Glob Bash(git diff *) Bash(git log *)
---
## Changes under review
!`git diff --stat origin/main...HEAD`
## Instructions
Review the diff between origin/main and HEAD. Read each changed file in full, not only
the hunks. Apply the "Review rules" section of CLAUDE.md. You never edit files.
Check, in this order: authorization and input validation, error handling at every
boundary, data and migration safety, and whether each changed behaviour has a test
that would fail without it.
Reply in exactly this shape:
VERDICT: APPROVE | REQUEST_CHANGES
FINDINGS:
- [blocker|major|minor] path:LINE: problem. Evidence: <test or command>
UNTESTED: <changed behaviour with no covering test, or "none">
CHECKED: <each command you ran>

allowed-tools pre-approves these tools; it does not remove the others, so “You never edit files” is an instruction, not a restriction. For a reviewer that cannot edit at all, use a subagent with a tools list (see custom subagents).

Do not name it review: /review already belongs to /code-review. disable-model-invocation: true means only a person starts it. For a reviewer Claude can delegate to on its own, with its own tool list and model, write a subagent instead; see custom subagents. Skill mechanics are covered in custom commands and skills.

A pre-push hook is the last private check. It must be fast, it must fail only on something it can name, and your script, not the model’s prose, decides the outcome. The hook below pipes the diff into claude -p, allows only read tools, caps spend, and reads the verdict from structured_output, which --json-schema validates.

  1. Save the hook as .githooks/pre-push and make it executable (chmod +x .githooks/pre-push). The hook needs jq on PATH; without it the hook prints a warning and lets the push through:

    #!/usr/bin/env bash
    set -uo pipefail
    command -v jq >/dev/null || { echo "pre-push: jq missing; review skipped" >&2; exit 0; }
    base=$(git merge-base origin/main HEAD) || exit 0
    diff=$(git diff --no-color "$base"...HEAD)
    [ -z "$diff" ] && exit 0
    if [ "$(printf '%s' "$diff" | wc -l)" -gt 1500 ]; then
    echo "pre-push: diff over 1500 lines; run /code-review high before you push." >&2
    exit 0
    fi
    schema='{"type":"object","properties":{"verdict":{"enum":["pass","block"]},"findings":{"type":"array","items":{"type":"string"}}},"required":["verdict","findings"]}'
    if ! out=$(printf '%s' "$diff" | claude -p \
    "Review this diff for blocking defects only, as defined in the Review rules section of CLAUDE.md. Ignore style. Return verdict block only for a defect you can name by file and line; write each as 'file:line - problem - fix'." \
    --output-format json --json-schema "$schema" \
    --permission-mode dontAsk --allowedTools "Read" "Grep" "Glob" \
    --max-budget-usd 0.50); then
    echo "pre-push: Claude review did not complete; push allowed, CI still gates the merge." >&2
    exit 0
    fi
    if [ "$(jq -r '.structured_output.verdict // "missing"' <<< "$out")" = "block" ]; then
    echo "pre-push: blocked by Claude review:" >&2
    jq -r '.structured_output.findings[]' <<< "$out" >&2
    echo "Fix the findings, or push with --no-verify and say why in the pull request." >&2
    exit 1
    fi
  2. Point Git at the tracked hooks directory, once per clone:

    Terminal window
    git config core.hooksPath .githooks
  3. Prove it blocks. On a scratch branch, add a route that reads a user ID from the query string and returns that user’s record with no authorization check, commit it, and push. The hook must print a file:line finding and exit 1. If it passes, tighten the Review rules until it fails.

Three choices in that script are deliberate. --permission-mode dontAsk denies every tool call that would prompt, so the review cannot edit files unless you allow it. The hook fails open when Claude cannot finish (network, budget, outage), because a local hook that blocks on an outage gets bypassed with --no-verify for good. And it skips very large diffs, because a quick check on 3,000 lines is theatre; those need /code-review high or Ultrareview. Do not add --bare to make the hook start faster: bare mode skips CLAUDE.md, so the Review rules the prompt depends on would never load. The headless flags are covered in depth in task automation with headless mode.

Review security-sensitive changes with /security-review

Section titled “Review security-sensitive changes with /security-review”

When a branch touches authentication, session handling, input parsing, file paths or secrets, run /security-review before you open the pull request. It reviews the branch diff with a security focus. For a check that runs while Claude writes, install the security-guidance plugin, which runs as hooks. It needs Python 3.8 or later on PATH:

Terminal window
claude plugin install security-guidance@claude-plugins-official

Scanners, the Claude Security plugin and exploit tests as proof are covered in security audits with Claude Code. Security gates for agents from other vendors are compared in agent security gates.

Get a second opinion on a high-risk branch

Section titled “Get a second opinion on a high-risk branch”

Some changes deserve more than one reader: payments, permissions, data migrations, anything that is hard to roll back. Two options go deeper than /code-review.

Ultrareview runs a cloud fleet of reviewer agents and reproduces each finding before it reports it. From the shell:

Terminal window
claude ultrareview # current branch against the default branch
claude ultrareview 142 # pull request 142
claude ultrareview 142 --post # also post the findings to the pull request as you
claude ultrareview --json > bugs.json

In a session the same review is /code-review ultra. It needs a claude.ai login (an API-key-only session must run /login first) and typically takes 5 to 10 minutes. A review covers up to 500 changed files and 8,000 changed lines by default, for a branch or a pull request; split a larger change. If the repository itself is too large to bundle, push the branch, open a draft pull request and run claude ultrareview <number>. Running claude ultrareview yourself is also how you consent to usage-credit billing; a claude -p '/code-review ultra' run stops before launching when the review would bill credits. Where Ultrareview is unavailable (Zero Data Retention, Bedrock, Google Cloud, Foundry), /code-review ultra falls back to a local review.

The pr-review-toolkit plugin from Anthropic’s claude-plugins-official marketplace adds /pr-review-toolkit:review-pr and six specialised subagents, such as a silent-failure hunter and a test analyser. Pass aspects to run only the ones you need:

Terminal window
claude plugin install pr-review-toolkit@claude-plugins-official --scope project
/pr-review-toolkit:review-pr tests errors

It costs about 2,000 tokens of always-on context per session (measured with claude plugin details on Claude Code 2.1.283), so install it at project scope in the repositories that need it rather than globally. Note that the plugin named code-review in the same marketplace is invoked as /code-review:code-review; a plain /code-review always runs the built-in skill.

How do you know the reviewer catches what matters?

Section titled “How do you know the reviewer catches what matters?”

A review that reports nothing looks the same whether the code is clean or the reviewer is blind. Measure it the way you measure a test suite: plant defects and count what comes back.

  1. Keep a fixture branch, review-fixture, with five planted defects, one per class you care about: a missing authorization check, SQL built from strings, an error swallowed in a payment path, an off-by-one in pagination, and a test assertion loosened so it always passes. Keep the list of planted defects off the branch; a reviewer that can read the answer key is not being measured.

  2. Run each reviewer three times on that branch — /code-review medium main...review-fixture, /pr-check, and the pre-push prompt through claude -p. Models are not deterministic, so one run proves little.

  3. Record four numbers per reviewer: planted defects caught (out of five), findings that were not planted and are wrong (false positives), wall-clock time, and total_cost_usd from the JSON output.

  4. Rerun the fixture whenever you change the Review rules, the model, the effort level or the Claude Code version. A drop in the catch rate is a regression, the same as a failing test.

Who signs off on what:

EvidenceOwner
Catch rate and false-positive rate on the fixture, rerun after each changeTech lead, who owns the Review rules
pass verdict from the pre-push gate and a clean /code-reviewThe author
Tests, types and lint green in CI, outside Claude’s controlCI
Approval on CODEOWNERS paths: migrations, auth, money, tests, CI config, CLAUDE.mdA named code owner

Managed Code Review never fails a check on its own: its Claude Code Review check run always completes neutral. To make Important findings block a merge, read the severity counts from that check run in your own CI job and fail when normal (the Important count) is above zero:

Terminal window
gh api repos/OWNER/REPO/check-runs/CHECK_RUN_ID \
--jq '.output.text | split("bughunter-severity: ")[1] | split(" -->")[0] | fromjson'

This prints counts such as {"normal": 2, "nit": 1, "pre_existing": 0} (format from Anthropic’s Code Review documentation, checked 2026-09-26). Enabling managed Code Review is covered in running Claude Code in CI/CD.

An automated review is a sensor, not the approval. What a person reads instead of the full diff is set out in reviewing an agent’s pull request without reading every line, and what the pull request must carry in the evidence bundle.

SymptomCauseRecovery
The team stops reading Claude’s findingsStyle and low-confidence findings drown the real onesRun /code-review at medium, and list “Do not flag” categories in CLAUDE.md
Findings suddenly broaden or narrowA bare /code-review reused a level typed in an earlier sessionAlways type the level; pin it in the team skill or hook
/rewind did not undo the review’s fixesBackground --fix edits sit outside checkpointsCommit before --fix; revert with git restore or git revert
A REVIEW.md rule is ignored locallyLocal /code-review does not read REVIEW.mdMove rules that must hold everywhere into CLAUDE.md
The pre-push gate passes a branch it should failThe prompt did not ask for that defect classAdd the class to the Review rules and rerun the fixture until it is caught
Pushes hang or fail during an API outageThe hook waits on the networkKeep the fail-open branch; CI remains the blocking gate
The reviewer approves code the same session wroteReviewer and author share contextUse the forked /pr-check, a fresh session, or claude ultrareview
A pull request loosens its own reviewThe branch edits CLAUDE.md, .claude/ or .githooks/Put those paths under CODEOWNERS; review rule changes like code
/code-review:code-review and /code-review give different resultsThey are different reviewers: the marketplace plugin and the built-in skillPick one per stage and write it down in the team’s contributing guide
Ultrareview does not startZero Data Retention, a cloud provider without Ultrareview, an API-key-only login, or -p stopped for billing consentRun /login with a claude.ai account, run claude ultrareview yourself, or fall back to /code-review high locally
Ultrareview refuses the diff as too largeThe branch or pull request is over the default limit of 500 files or 8,000 linesSplit the change into smaller pull requests
Ultrareview asks for PR mode instead of a branch reviewThe repository is too large to bundle for uploadPush the branch, open a draft pull request and review it by number: claude ultrareview <number>
Managed Code Review found a bug, yet the pull request mergedIts check run is always neutral and never blocksFail your own CI job when the check run’s normal count is above zero

Using another agent as well? The same job is covered in code review with Codex and code review with Cursor.