| name | deep-review |
| description | Deep code review of a GitHub PR or the local working diff. Runs independent, scoped sub-agent reviews defined in reviewers/*.md and any project-specific reviewers, scores each finding 0-100 for confidence, reports only findings with score >= 50, and for the user's own PRs auto-fixes, commits, pushes, and updates the PR body. |
| argument-hint | [PR number or URL | omit to review the local working diff] |
| disable-model-invocation | false |
| effort | high |
deep-review skill
Self-contained code review pipeline โ no external plugins. Reviews a GitHub PR or the local working diff using independent parallel sub-agents and confidence scoring.
Mode detection
- PR mode (argument provided): extract PR number or URL, use
gh pr diff / view to get the diff. Eligible for autofix.
- Local diff mode (no argument): compute base with
git merge-base origin/<current-branch> HEAD and diff with git diff <base>..HEAD plus working-tree changes. Report only โ no autofix or commit.
Steps
Execute the following steps strictly in order.
Step 1: Eligibility check (PR mode only)
Launch a Haiku sub-agent to verify the PR does not fall into any of these categories. Abort and report the reason if it does:
- Closed
- Auto-generated (Renovate, dependabot, etc.) or trivially simple
- The current GitHub user (run
gh api user --jq '.login' to detect) has already posted a code-review comment
Step 2: Collect CLAUDE.md / rules content
Launch a Haiku sub-agent to collect the following files and return both
their paths and full file content (not paths alone) โ Step 5/6 sub-agents
receive this content directly so they don't need to re-Read these files
themselves:
- Root
CLAUDE.md of the repository
CLAUDE.md files in directories containing changed files
- All
*.md files under ~/.claude/rules/
Output format: for each file, its path followed by its full content (e.g. a
path: ... / content: ... pair per file, or one Markdown section per
file) โ any format is fine as long as Step 5/6 can tell which content came
from which path.
Step 3: Summarise changes
Launch a Haiku sub-agent to retrieve and return:
- PR mode:
gh pr view <PR> --json title,body,additions,deletions,files and gh pr diff <PR>
- Local diff mode:
git diff <base>..HEAD --stat and git diff <base>..HEAD
Step 3.5: Lightweight precheck for docs-only changes
Using the changed-file list already retrieved in Step 3, check whether
every changed file path matches at least one of these patterns: *.md,
*.txt, docs/**. Do this with plain pattern matching โ do not launch an
additional sub-agent for this check.
- If all changed files match: in Step 5, run only
a-claude-md-compliance and c-history-context; skip
b-bugs-correctness, e-code-comment-quality, f-security,
g-performance, h-error-handling, i-type-design-tests.
- If any changed file does not match: run all reviewers as usual (no
skipping).
This applies in both PR mode and local diff mode.
Step 4: Explore project and consider project-specific reviewers
First, explore the project using the Explorer agent. If you already have a deep understanding of the project, skip this step.
Then, using the exploration results and the diff information, use a Haiku sub-agent to consider up to three project-specific review perspectives.
Step 5: Parallel perspective reviews
Load reviewer definitions, then launch one independent general-purpose sub-agent per loaded reviewer, all in parallel.
-
Read every file under ~/.claude/skills/deep-review/reviewers/*.md (the fixed reviewers, one file per perspective), then apply Step 3.5's docs-only skip list if it triggered.
-
Filter by mode: in Local diff mode, exclude any reviewer file whose frontmatter applies_to is pr-only.
-
Each reviewer file uses this format:
---
id: <one-letter id, fixed reviewers only>
name: <slug>
title: <display title>
applies_to: all | pr-only
---
## Scope
<scope text, passed verbatim to the sub-agent>
If applies_to is missing, empty, or not one of all/pr-only, treat it as all.
-
Pass each sub-agent: the shared false-positive suppression instructions
below, the ## Scope body of its reviewer file, and the CLAUDE.md /
rules content collected in Step 2 (the full file content, not just
paths โ tell the sub-agent explicitly: "The CLAUDE.md/rules files below
have already been read; do not re-Read them yourself"). Additionally,
depending on whether the reviewer's scope depends on diff content:
- Diff-dependent reviewers (all fixed reviewers except
c-history-context, and any project-specific reviewer): pass the full
diff and the change summary from Step 3.
c-history-context (its scope reads git history / PR history via
commands, not diff text): pass only the list of changed file paths
(from the Step 3 change summary), not the full diff.
Every reviewer sub-agent is dispatched in background mode, whether given a name or left anonymous. Its initial prompt MUST also include this explicit reporting instruction, verbatim: "Before you stop taking actions for any reason (completion, being blocked, uncertainty, or anything else), you MUST call SendMessage to report your findings to the parent session. Never go idle without reporting โ plain text output alone is not visible to the caller." Without this, the sub-agent may write its findings as plain text and stop without calling , producing a repeated idle notification instead of a completed result (see 's "Proactive complement" section).
Each agent returns findings as: problem summary + evidence + file:line reference.
Instructions passed to every agent (false-positive suppression):
Do NOT report the following:
- Pre-existing issues on lines not touched by this PR
- Issues that linters, type checkers, or CI already catch (formatting, import errors, type errors, etc.)
- Intentionally suppressed issues (lint-ignore comments, etc.)
- General code quality concerns (test coverage, documentation) unless explicitly required in CLAUDE.md or explicitly listed as a specific reviewer's scope (e.g. the
e-code-comment-quality.md reviewer's redundant/stale-comment checks)
- Functional changes that are clearly intentional given the broader context
- Anything asserted without a concrete
file:line citation
Fixed reviewers: see ~/.claude/skills/deep-review/reviewers/*.md for the full list and scope of each (a-claude-md-compliance, b-bugs-correctness, c-history-context, e-code-comment-quality, f-security, g-performance, h-error-handling, i-type-design-tests).
Idle sub-agent follow-up: these reviewer sub-agents run in the background per rules/workflow-sub-agents.md's "Handling Idle Notifications from Background Sub-Agents" โ apply that procedure here, made concrete for this step:
- When dispatching the reviewers above, note which reviewer slug (e.g.
f-security) each sub-agent corresponds to, along with its dispatch
identifier โ its name if one was assigned, otherwise its agentId โ
so it can actually be nudged via SendMessage later.
- On any idle notification from one of these sub-agents, nudge it
immediately via
SendMessage โ do not wait for the next check-in.
- Right after dispatch, set up a
CronCreate check-in every 15 minutes
with this prompt: "For any of the deep-review reviewer sub-agents from
Step 5 that are not yet completed: send a SendMessage nudge to any
that have gone idle and haven't been nudged yet, and re-dispatch (once,
same reviewer definition) any that are still not completed 30 minutes
after their nudge." This check-in exists both to catch any real-time
nudge that was missed and to perform the timeout/re-dispatch step.
- If a reviewer still hasn't completed after its one re-dispatch, record
its findings as unavailable ("reviewer sub-agent did not respond;
its scope was not checked in this run") instead of silently omitting it
โ carry that note through to Step 13's final report. Step 6 onward
proceeds with whichever reviewers did complete, so one unresponsive
reviewer never blocks the rest of the pipeline.
- Once every reviewer is either completed or marked unavailable,
CronDelete the check-in created above.
Step 6: Confidence scoring (batched)
Launch a single Haiku sub-agent to score all findings returned by
Step 5 in one call โ do not launch one sub-agent per finding.
Pass this agent: the full list of findings (each finding's problem summary
- evidence + file:line), the CLAUDE.md/rules content from Step 2, and the
diff sections relevant to each finding (not the full diff resend).
Use the following rubric verbatim:
Score the issue on a scale of 0-100 based on your level of confidence that it is a real issue:
- 0: Not confident at all. This is a false positive that doesn't stand up to light scrutiny, or is a pre-existing issue.
- 25: Somewhat confident. This might be a real issue, but may also be a false positive. The agent wasn't able to verify that it's a real issue. If the issue is stylistic, it is one that was not explicitly called out in the relevant CLAUDE.md.
- 50: Moderately confident. The agent was able to verify this is a real issue, but it might be a nitpick or not happen very often in practice. Relative to the rest of the PR, it's not very important.
- 75: Highly confident. The agent double checked the issue, and verified that it is very likely it is a real issue that will be hit in practice. The existing approach in the PR is insufficient. The issue is very important and will directly impact the code's functionality, or it is an issue that is directly mentioned in the relevant CLAUDE.md.
- 100: Absolutely certain. The agent double checked the issue, and confirmed that it is definitely a real issue, that will happen frequently in practice. The evidence directly confirms this.
For issues sourced from CLAUDE.md, double-check that the CLAUDE.md actually mentions that specific issue before scoring high.
Findings from a reviewer's explicitly listed scope (e.g. the e-code-comment-quality.md reviewer's redundant/stale-comment checks) are not "unscoped stylistic nitpicks" for the purpose of the 25-point band above โ score them on the same real-world-impact basis as any other finding (how likely the comment is to mislead a future reader or drift from the code it describes).
Instruct the agent to output one line per finding, in the format:
Finding <N>: Score: <0-100> (where <N> is the finding's 1-based index
in the order passed in). This preserves the Score: <0-100> substring the
Stop hook extracts, while adding the Finding <N>: prefix so the batch
output can be parsed back per-finding.
Step 7: Score filtering
Parse Step 6's batched output into individual (finding index, score)
pairs (splitting on the Finding <N>: Score: <0-100> lines), matching each
score back to its corresponding Step 5 finding by index. Discard all
findings with score < 50. If no findings remain, report "No issues found"
and stop.
If the parsed indices don't cleanly cover every Step 5 finding exactly once
(a missing index, a duplicate, an out-of-range index, or a parsed line count
that doesn't match the input finding count), do not silently drop the
unmatched findings as if they scored below 50. Re-dispatch a single Haiku
sub-agent to re-score only the unmatched findings, using the same rubric.
If a second parse also fails to cover them, treat each still-unmatched
finding as score 50 (fail open into the report, not out of it) and note in
the final report that its score could not be automatically confirmed.
Step 8: Re-check eligibility (PR mode only)
Launch a Haiku sub-agent to repeat the Step 1 eligibility check. Abort if the PR is now ineligible.
Step 9: PR author check (PR mode only)
Run gh api user --jq '.login' to get the current GitHub user login.
Then run gh pr view <PR> --json author --jq '.author.login' to get the PR author.
- Author matches the current user login, or is a bot created by the current user โ proceed to Step 10 (autofix).
- Any other author (Renovate, dependabot, external contributors) โ skip to Step 13 (report only).
Step 10: Autofix (own PRs only)
Fix all findings with score โฅ 50. Do not commit yet โ fix all issues first.
For each issue:
- Read the affected file with the Read tool.
- Apply the fix with the Edit tool.
- Confirm the fix addresses the issue.
Step 11: Commit (own PRs only)
Commit all fixes:
git add to stage all modified files.
- Commit following Conventional Commits.
fix: ใณใผใใฌใใฅใผๆๆไบ้
ใไฟฎๆญฃ
- [list of fixed issues]
Co-Authored-By: Claude <noreply@anthropic.com>
git push origin <branch> (use SSH).
Step 12: Update PR body (own PRs only)
Run gh pr edit <PR> --body "..." to note that review issues were automatically fixed.
Step 13: Report results
- PR mode: post with
gh pr comment <PR> --body "...".
- Local diff mode: present results directly to the user.
Output format
When issues were found and autofixed:
### Deep Review
Found X issues and **automatically fixed them** in commit [sha]:
1. <brief issue description>
Score: <score>
<https://github.com/<owner>/<repo>/blob/<full_sha>/<path>#L<start>-L<end>>
**Fixed**: <description of the fix applied>
When issues were found (other author's PR, no autofix):
### Deep Review
Found X issues:
1. <brief issue description>
Score: <score>
<https://github.com/<owner>/<repo>/blob/<full_sha>/<path>#L<start>-L<end>>
When no issues were found:
### Deep Review
No issues found. Checked for bugs, CLAUDE.md compliance, security (incl. AI-PR risks), performance, error handling, silent failures, type design, and test coverage.
If any reviewer sub-agent from Step 5 was marked unavailable (see Step 5's idle sub-agent follow-up), note it explicitly in the report so the reader knows that perspective was not checked in this run, e.g. add a line such as Reviewer unavailable: <slug> (did not respond; its scope was not checked in this run) alongside the findings.
Formatting rules
- GitHub code links must use the full SHA +
#L<line> format. Do not embed $(git rev-parse HEAD) โ it will not expand in Markdown.
- No emoji.
- Each finding must include
Score: <number> (the Stop hook extracts scores using this exact format).
- Cite both the code (
file:line) and the relevant CLAUDE.md rule for each finding.