一键导入
prp-review-agents
Multi-agent PR review — spawns parallel specialized agents for deep code review.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Multi-agent PR review — spawns parallel specialized agents for deep code review.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Multi-agent PR review — spawns parallel specialized agents for deep code review.
Execute an implementation plan with rigorous validation loops — typecheck, lint, test, and build after every change. TDD approach with automatic failure recovery.
Create a comprehensive implementation plan by analyzing the codebase, discovering patterns, and producing a step-by-step actionable plan document.
Execute an implementation plan with rigorous validation loops — typecheck, lint, test, and build after every change. TDD approach with automatic failure recovery.
Create a comprehensive implementation plan by analyzing the codebase, discovering patterns, and producing a step-by-step actionable plan document.
Execute the complete PRP lifecycle end-to-end — issue context, smart plan, implement, commit, PR, review-fix loop (until 0 issues), merge, and cleanup. Supports --issue, --merge, --max-review-rounds, --fast, --ralph, --skip-plan, --skip-review, --no-pr, --resume, --no-interact, --dry-run, --fix-severity, --verify, --qa-delegate=<agent>, --done options.
| name | prp-review-agents |
| description | Multi-agent PR review — spawns parallel specialized agents for deep code review. |
| metadata | {"short-description":"Multi-agent PR review"} |
If your input context contains [WORKSPACE CONTEXT] (injected by a multi-agents framework),
you are running as a sub-agent. Apply these optimizations:
pr-context-*.md file path is provided in
the context files — use it directly (the upstream commit_pr agent already gathered this).$prp-implement or $prp-ralph).All agent dispatches and result aggregation run unchanged — these are where quality comes from.
PR number and optional aspects: $ARGUMENTS
Format: <pr-number> [aspects: comments|tests|errors|types|code|security|deps|docs|perf|a11y|simplify|all] [--since-last-review] [--metrics]
Perform a deep, comprehensive PR code review by spawning specialized Agent subprocesses in parallel. Each agent runs in its own isolated context window with fresh memory, enabling deep file exploration beyond the diff.
This command differs from $prp-review (single-session sequential passes) by spawning actual Agent subprocesses via the Agent tool. Each agent gets:
Report only high-confidence issues (80%+ certain).
Before gathering PR information, check if context was pre-generated by $prp-implement or $prp-ralph:
If --context <path> argument provided: Validate the path is under .prp-output/ and does not contain .. segments. Reject absolute paths. Then verify the ## PR Diff section in the file contains actual content (not empty). If empty, WARN and fall through to Phase 1. Otherwise use the context file directly.
If no --context argument, auto-detect:
BRANCH=$(git branch --show-current)
CONTEXT_FILE=".prp-output/reviews/pr-context-${BRANCH}.md"
test -f "$CONTEXT_FILE" && echo "FOUND" || echo "NOT_FOUND"
| Result | Action |
|---|---|
| FOUND | Read the context file. Use file list, implementation summary, and validation status from it. Skip Phase 1 context extraction. If --since-last-review flag present, still proceed through Phase 0.5. Display: "Token optimization: Using pre-generated context from pr-context-{BRANCH}.md — skipping context extraction." |
| NOT_FOUND | Proceed to Phase 0.5 (if --since-last-review) then Phase 1 to extract context. |
When context file is found, extract from it:
gh pr diff --name-onlyOnly when --since-last-review flag is provided. Skip this phase otherwise.
First, resolve the PR number if not already known (from $ARGUMENTS or gh pr view --json number -q '.number').
# Find previous review artifact for this PR (NUMBER must be resolved first)
REVIEW_FILE=$(ls -t .prp-output/reviews/pr-${NUMBER}-agents-review.md 2>/dev/null | head -1)
| Result | Action |
|---|---|
| Review file found | Extract timestamp from file (look for **Reviewed**: line or file modification time) |
| No review file | WARN: "No previous review found for PR #{NUMBER}. Running full review instead." Proceed to Phase 1. |
# Get files changed since last review timestamp
# Note: --since uses commit date. If commits were rebased, results may be incomplete.
# In that case, fall back to full review.
git log --since="{TIMESTAMP}" --name-only --pretty=format:"" | sort -u
| Result | Action |
|---|---|
| No changes since timestamp | "No new changes since last review at {TIMESTAMP}. Nothing to re-review." EXIT. |
| Changes found | Display: "Incremental review: {N} files changed since {TIMESTAMP}" |
When in incremental mode:
git diff {BASE}...HEAD -- {changed-files}After incremental review completes, merge with previous review:
Display delta summary:
Incremental Review Delta:
- New issues: {N}
- Resolved: {M}
- Remaining from previous: {K}
CHECKPOINT: Incremental mode active. Reviewing {N} changed files only.
Purpose: Extract PR context ONCE, share with all agents. Saves 60-70% tokens vs each agent reading diff independently.
Skip this phase if Phase 0 found an existing context file.
gh pr view <number>gh pr view (current branch's PR)gh pr view fails (no PR for this branch): STOP — "No open PR found for branch {BRANCH}. Create a PR first with gh pr create, or pass a PR number explicitly."| State | Action |
|---|---|
MERGED | STOP: "PR already merged. Nothing to review." |
CLOSED | WARN: "PR is closed. Review anyway? (historical analysis)" |
DRAFT | NOTE: "Draft PR — focusing on direction, not polish" |
OPEN | PROCEED with review |
Extract all context in ONE pass:
# PR metadata
gh pr view {NUMBER} --json number,title,body,author,headRefName,baseRefName,state,additions,deletions,changedFiles
# Record the EXACT commit being reviewed, NOW, at diff-gather time. The agents
# review THIS SHA. The safe-merge marker (see "Emit safe-merge review marker")
# MUST bind to this value — NOT a value re-queried later — so that any push
# during review invalidates the marker (marker.head != current head → re-review).
REVIEWED_HEAD_SHA=$(gh pr view {NUMBER} --json headRefOid -q '.headRefOid')
# Validate immediately — an empty/garbage capture here must fail loud NOW, not
# surface later as a silent fail-open in the marker re-bind guard.
printf '%s' "$REVIEWED_HEAD_SHA" | grep -qE '^[0-9a-f]{40}$' || \
{ echo "FATAL: could not capture reviewed head SHA ('$REVIEWED_HEAD_SHA')" >&2; exit 1; }
# Structural diff (compact overview — for agent routing)
# Use prp-diff if available, otherwise fall back to gh pr diff
if [ -x .prp/scripts/prp-diff.sh ]; then
.prp/scripts/prp-diff.sh {NUMBER}
fi
# Full PR diff (for detailed line-level review)
gh pr diff {NUMBER}
# Changed files list
gh pr diff {NUMBER} --name-only
Also read:
CLAUDE.md — project rules and conventionsls -t .prp-output/reports/*-report*.md 2>/dev/null | head -1mkdir -p .prp-output/reviews
Context File Path: .prp-output/reviews/pr-context-{BRANCH}.md
---
pr: {NUMBER}
branch: "{BRANCH}"
extracted: {ISO_TIMESTAMP}
files_changed: {N}
---
# PR Review Context: #{NUMBER} — {TITLE}
## PR Metadata
- **Author**: {author}
- **Branch**: {head} → {base}
- **State**: {state}
- **Size**: +{additions}/-{deletions} across {changedFiles} files
## Project Guidelines (from CLAUDE.md)
{relevant sections from CLAUDE.md}
## Changed Files
{list from gh pr diff --name-only}
## PR Diff
{full diff output}
## Implementation Context
{implementation report summary, if found — otherwise "No implementation report found"}
After writing the context file, verify it was created:
test -f "$CONTEXT_FILE" || echo "FATAL: Could not create context file at $CONTEXT_FILE"
If the file was not created, STOP — do not spawn agents without a context file.
CHECKPOINT: Context file created and verified. All agents will read from this file.
Check PR size after context extraction.
Calculate total changes from PR metadata: additions + deletions.
| Size | Action |
|---|---|
| <=500 lines | Proceed normally — standard review |
| 501-1000 lines | Large PR strategy — phased review by risk tier |
| >1000 lines | Large PR strategy + recommend splitting |
When large PR detected, categorize each changed file:
| Tier | Category | Examples | Review Depth |
|---|---|---|---|
| Tier 1 (Critical) | Security, auth, payment, encryption, permissions | auth/, middleware/, crypto, *.key | Full depth — all applicable agents |
| Tier 2 (Business Logic) | API endpoints, services, business rules, data processing | services/, controllers/, api/, routes/ | Full depth — all applicable agents |
| Tier 3 (Support) | Utils, helpers, shared components, configuration | utils/, helpers/, components/shared/, config/ | Core agents only (code-reviewer, security-reviewer) |
| Tier 4 (Low Risk) | Tests, documentation, config files, generated code | test/, docs/, *.config.*, *.generated.* | Core agents only (code-reviewer) |
Phase A: Review Tier 1-2 files (critical + business logic)
|- All applicable agents dispatched
|- Full depth analysis
|- Priority findings reported first
Phase B: Review Tier 3-4 files (support + low risk)
|- Core agents only
|- Quick scan for obvious issues
|- Lower priority findings
Include in review summary:
### File Coverage Map
| File | Tier | Agents Run |
|------|------|------------|
| `src/auth/login.ts` | 1 (Critical) | code, security, errors |
| `src/api/users.ts` | 2 (Business) | code, security, errors |
| `src/utils/format.ts` | 3 (Support) | code, security |
| `tests/auth.test.ts` | 4 (Low Risk) | code |
If PR >1000 lines, display:
Large PR detected ({N} lines). Consider splitting into smaller PRs for better review quality.
Suggested splits based on file categories:
- PR 1: {Tier 1-2 files} ({N} lines)
- PR 2: {Tier 3-4 files} ({M} lines)
CHECKPOINT: Large PR strategy applied. Files categorized by risk tier.
For EVERY changed file, the relevant agent should check against these 7 categories:
any, return types declared, type guardsAgents use different severity systems internally. Map all findings to these unified levels for result aggregation:
| Level | Criteria | Examples | Aggregation Category |
|---|---|---|---|
| Critical | Blocking — must fix, security/data risk | Security vulnerabilities, data loss, crashes | Critical |
| High | Should fix before merge — correctness/safety | Type safety violations, logic errors, silent failures | Important |
| Medium | Should consider — quality/consistency | Pattern inconsistencies, missing edge cases | Suggestions |
| Low | Nice to have — polish | Style preferences, minor optimizations | Suggestions |
Implementation report check: Documented deviations are intentional — only flag undocumented deviations.
| Aspect | Agent (subagent_type) | When to Run |
|---|---|---|
code | code-reviewer | Always — general quality and guidelines |
security | security-reviewer | Always — OWASP Top 10, vulnerabilities |
errors | silent-failure-hunter | Always — silent failures, error handling |
deps | dependency-analyzer | When package files changed |
docs | docs-impact-agent | When production code changed (skip for test/config-only) |
tests | pr-test-analyzer | When test files or tested code changed |
comments | comment-analyzer | When comments/docstrings added |
types | type-design-analyzer | When types added/modified |
perf | performance-analyzer | When performance-sensitive patterns detected |
a11y | accessibility-reviewer | When UI/frontend files changed |
simplify | code-simplifier | After all agents pass — polish |
all | All applicable | Default if no aspects specified |
Always run (core agents):
code-reviewer — Core quality checksecurity-reviewer — Security vulnerabilities (OWASP Top 10)silent-failure-hunter — Silent failures, error path tracingRun based on changes (conditional agents):
dependency-analyzerdocs-impact-agentpr-test-analyzercomment-analyzertype-design-analyzerRun when explicitly requested (overrides auto-detection):
perf → always run performance-analyzer regardless of file typesa11y → always run accessibility-reviewer regardless of file typesRun last (after all other agents complete):
code-simplifier — Final polishAuto-detect file types from PR diff and dispatch specialist agents automatically.
| File Pattern | Agent | Trigger |
|---|---|---|
.tsx, .jsx, .vue, .svelte, .css, .scss, .html | accessibility-reviewer | UI/frontend files changed |
.sql, imports from prisma, drizzle, knex, sequelize, typeorm | performance-analyzer | Database patterns detected |
router, endpoint, controller, handler, api/ path | performance-analyzer | API endpoint patterns detected |
for.*await, Promise.all, .map(, setInterval, setTimeout | performance-analyzer | Async/loop patterns detected |
Scan changed files from PR diff:
If UI files detected (.tsx/.jsx/.vue/.svelte/.css/.scss/.html):
Auto-add: accessibility-reviewer
If performance-sensitive patterns detected:
DB imports (prisma, drizzle, knex, sequelize, typeorm, .sql files)
API patterns (router, endpoint, controller, handler, api/ path)
Async/loop patterns (for.*await, Promise.all, .map(, setInterval)
Auto-add: performance-analyzer
When agents are auto-dispatched, display to user:
Auto-dispatching: accessibility-reviewer (3 .tsx files detected)
Auto-dispatching: performance-analyzer (DB query patterns in 2 files)
Note: Conditional dispatch adds to existing agents — it does NOT replace the always-run core agents.
CRITICAL: You MUST use the Agent tool to spawn these as separate subprocesses. Each agent runs in its own context window with fresh memory. Do NOT attempt to run these as sequential passes in this session — that defeats the purpose of this command. If you want single-session sequential passes, use $prp-review instead.
Before spawning agents, prepare the shared context information:
CONTEXT_PATH = ".prp-output/reviews/pr-context-{BRANCH}.md"
PR_NUMBER = {extracted from Phase 1}
PROJECT_GUIDELINES = {relevant sections from CLAUDE.md}
CHANGED_FILES = {list from context file}
Spawn these 3 agents simultaneously in a SINGLE message with multiple Agent tool calls:
Agent 1 — Code Quality:
Agent(
subagent_type="code-reviewer",
description="Review PR #{NUMBER} code quality",
prompt="Review PR #{NUMBER} for project guideline compliance, bugs, and quality issues.
Read the PR context file at: {CONTEXT_PATH}
This file contains the PR diff, changed files list, and project guidelines.
IMPORTANT: Also read the actual source files for deep exploration beyond the diff.
Check imports, callers, and related code to understand full impact.
Focus areas:
- Logic errors, off-by-one, null handling, race conditions
- Naming conventions, import organization, dead code
- Pattern compliance with existing codebase
- Per-file checklist: Correctness, Type Safety, Pattern Compliance, Completeness, Maintainability
EXHAUSTIVE PATTERN SWEEP: When you identify a recurring bug class (e.g., missing
type guard, falsy-value blind spot, unguarded interpolation), grep/search ALL
files changed in this PR for ALL instances of that pattern before reporting.
A bug is 'recurring' if you observe 2+ instances of the same structural defect.
List every occurrence — not just the ones you noticed first. This prevents
whack-a-mole re-review cycles where the same pattern is found piecemeal.
Report findings as structured markdown:
## Findings
| Severity | Issue | File:Line | Suggestion |
|----------|-------|-----------|------------|
Use severity levels: Critical, High, Medium, Low
Only report issues with 80%+ confidence.
Also note Strengths — what is done well.
After your Findings table, add a Pattern Sweep Results section:
## Pattern Sweep Results
| Pattern | Files Swept | Instances Found |
|---------|-------------|-----------------|
If sweep performed but 0 additional instances found, still include the row with '0 additional instances'.
If no recurring patterns detected, state: 'No recurring patterns detected — sweeps not performed.'"
)
Agent 2 — Security:
Agent(
subagent_type="security-reviewer",
description="Review PR #{NUMBER} security",
prompt="Review PR #{NUMBER} for security vulnerabilities.
Read the PR context file at: {CONTEXT_PATH}
This file contains the PR diff, changed files list, and project guidelines.
IMPORTANT: Go beyond the diff. Read actual source files:
- Check .env files for exposed secrets
- Read config files for insecure defaults
- Trace authentication flows end-to-end
- Check file permissions and access controls
- Look at related files not in the diff that may be affected
Focus on OWASP Top 10:
- Injection (SQL, NoSQL, OS command, LDAP)
- Broken authentication and session management
- Sensitive data exposure (secrets in logs, responses, error messages)
- SSRF (server-side request forgery via user-controlled URLs)
- Input validation gaps
- Unsafe deserialization
Report ONLY vulnerabilities with clear attack vectors — not theoretical issues.
Report findings as structured markdown:
## Findings
| Severity | Issue | File:Line | Attack Vector | Remediation |
|----------|-------|-----------|---------------|-------------|
Use severity levels: Critical, High, Medium, Low"
)
Agent 3 — Error Handling:
Agent(
subagent_type="silent-failure-hunter",
description="Hunt silent failures PR #{NUMBER}",
prompt="Hunt for silent failures and inadequate error handling in PR #{NUMBER}.
Read the PR context file at: {CONTEXT_PATH}
This file contains the PR diff, changed files list, and project guidelines.
IMPORTANT: Go beyond the diff. Read the actual source files:
- Trace every error path from throw to catch
- Read bash scripts and check exit codes, PIPESTATUS usage
- Verify error propagation — does the error reach the right handler?
- Check what happens when external calls fail (API, DB, filesystem)
- Look for fallback logic that may mask failures
Zero tolerance for:
- Empty catch blocks
- Catch blocks without logging or re-throw
- Generic catch(e) without specific handling
- Async operations without .catch() or try/catch
- Shell scripts without set -e or proper exit code checking
- Functions that return default values on error instead of propagating
EXHAUSTIVE PATTERN SWEEP: When you identify a recurring error-handling anti-pattern
(e.g., silent fallback, swallowed exception, missing exit code check), grep/search
ALL files changed in this PR for ALL instances of that pattern before reporting.
A pattern is 'recurring' if you observe 2+ instances of the same structural defect.
List every occurrence — not just the ones you noticed first. This prevents
whack-a-mole re-review cycles where the same pattern is found piecemeal.
Report findings as structured markdown:
## Findings
| Severity | Issue | File:Line | Error Path | Fix |
|----------|-------|-----------|------------|-----|
Use severity levels: Critical, High, Medium, Low
After your Findings table, add a Pattern Sweep Results section:
## Pattern Sweep Results
| Pattern | Files Swept | Instances Found |
|---------|-------------|-----------------|
If sweep performed but 0 additional instances found, still include the row with '0 additional instances'.
If no recurring patterns detected, state: 'No recurring patterns detected — sweeps not performed.'"
)
After determining which conditional agents are needed (from Aspect Selection Logic above), spawn them in a SINGLE message alongside or after the core agents:
If dependency files changed — dependency-analyzer:
Agent(
subagent_type="dependency-analyzer",
description="Analyze dependencies PR #{NUMBER}",
prompt="Analyze dependencies in PR #{NUMBER} for security and health.
Read the PR context file at: {CONTEXT_PATH}
Check for:
- Known CVEs in direct and transitive dependencies
- Outdated packages with available security patches
- Abandoned or deprecated dependencies (no updates >2 years)
- License compliance issues (copyleft in proprietary projects)
- Package.json/lock file consistency
Include exact remediation commands (npm audit fix, version bumps, alternatives).
Report findings as structured markdown:
## Findings
| Severity | Package | Issue | Remediation |
|----------|---------|-------|-------------|
Use severity levels: Critical, High, Medium, Low"
)
If UI/frontend files changed — accessibility-reviewer:
Agent(
subagent_type="accessibility-reviewer",
description="Review accessibility PR #{NUMBER}",
prompt="Review UI code in PR #{NUMBER} for WCAG 2.1 compliance.
Read the PR context file at: {CONTEXT_PATH}
Also read the actual source files for full component context.
Check:
- Keyboard navigation: All interactive elements focusable and operable
- Screen reader support: Proper semantic HTML, meaningful alt text
- Color contrast: 4.5:1 for normal text, 3:1 for large text
- ARIA usage: Correct roles, states, and properties
- Form labels: All inputs have associated labels
- Focus management: Proper focus order, visible focus indicators
Report issues with affected user groups.
Report findings as structured markdown:
## Findings
| Severity | Issue | File:Line | Affected Users | Fix |
|----------|-------|-----------|----------------|-----|
Use severity levels: Critical, High, Medium, Low"
)
If performance-sensitive patterns detected — performance-analyzer:
Agent(
subagent_type="performance-analyzer",
description="Analyze performance PR #{NUMBER}",
prompt="Analyze PR #{NUMBER} for performance issues.
Read the PR context file at: {CONTEXT_PATH}
Also read the actual source files for full context.
Focus on:
- N+1 queries: DB calls inside loops, missing batch/join
- Sequential awaits: await in loops that could be Promise.all
- Memory leaks: Event listeners not cleaned up, growing caches
- Unbounded operations: Missing pagination, unlimited array operations
- Unnecessary re-renders: Missing memoization, inline object creation in render
Report only issues with measurable impact. Include quantified impact estimate.
Confidence threshold 80%+.
Report findings as structured markdown:
## Findings
| Severity | Issue | File:Line | Impact Estimate | Fix |
|----------|-------|-----------|-----------------|-----|
Use severity levels: Critical, High, Medium, Low"
)
If types added/modified — type-design-analyzer:
Agent(
subagent_type="type-design-analyzer",
description="Analyze type design PR #{NUMBER}",
prompt="Analyze type design in PR #{NUMBER}.
Read the PR context file at: {CONTEXT_PATH}
Also read the actual source files for full type context.
Rate on 4 dimensions (1-10 each):
- Encapsulation: Are internals properly hidden?
- Invariant Expression: Do types enforce business rules?
- Usefulness: Do types help consumers avoid mistakes?
- Enforcement: Are types strict enough to catch errors at compile time?
Check for: any escape hatches, overly broad union types, missing discriminants.
Focus on new or modified types only.
Report findings as structured markdown:
## Findings
| Severity | Issue | File:Line | Dimension | Fix |
|----------|-------|-----------|-----------|-----|
## Type Quality Scores
| Type | Encapsulation | Invariant | Usefulness | Enforcement |
|------|---------------|-----------|------------|-------------|
Use severity levels: Critical, High, Medium, Low"
)
If production code changed (not test/config-only) — docs-impact-agent:
Agent(
subagent_type="docs-impact-agent",
description="Review docs impact PR #{NUMBER}",
prompt="Review PR #{NUMBER} and update any documentation affected by code changes.
Read the PR context file at: {CONTEXT_PATH}
Also read CLAUDE.md, README.md, and docs/ directory.
Check:
- Are new features or changed behaviors documented?
- Are removed features still referenced in docs?
- Are API changes reflected in documentation?
- Are configuration changes noted?
If you find stale docs, make the fixes, commit and push to the PR branch.
Display what was updated.
Report findings as structured markdown:
## Findings
| Severity | Issue | File:Line | Fix |
|----------|-------|-----------|-----|
## Documentation Updates Made
| File | Change |
|------|--------|
Use severity levels: Critical, High, Medium, Low"
)
If comments/docstrings added or changed — comment-analyzer:
Agent(
subagent_type="comment-analyzer",
description="Analyze comments PR #{NUMBER}",
prompt="Analyze code comments in PR #{NUMBER} for accuracy, completeness, and long-term value.
Read the PR context file at: {CONTEXT_PATH}
Also read the actual source files to verify comments match code behavior.
Check:
- Do comments accurately describe what the code does?
- Are complex algorithms or business logic explained?
- Are there stale comments that will become wrong when code changes?
- Are JSDoc/TSDoc parameter types and descriptions accurate?
Report findings as structured markdown:
## Findings
| Severity | Issue | File:Line | Fix |
|----------|-------|-----------|-----|
Use severity levels: Critical, High, Medium, Low"
)
If test files or tested code changed — pr-test-analyzer:
Agent(
subagent_type="pr-test-analyzer",
description="Analyze test coverage PR #{NUMBER}",
prompt="Analyze test coverage for PR #{NUMBER}.
Read the PR context file at: {CONTEXT_PATH}
Also read the actual test files and the code they test.
Focus on:
- Behavioral coverage — are critical paths tested?
- Edge cases — are error paths and boundary conditions covered?
- Test quality — meaningful assertions, not just snapshot tests?
- Flaky patterns — timing dependencies, shared state, non-deterministic order?
Rate each recommendation by criticality (1-10): 10 = must-have, 1 = nice-to-have.
Report findings as structured markdown:
## Findings
| Severity | Issue | File:Line | Criticality | Fix |
|----------|-------|-----------|-------------|-----|
Use severity levels: Critical, High, Medium, Low"
)
If the Agent tool is NOT available (e.g., running in a tool that doesn't support subagent spawning):
Fall back to $prp-review which performs all 11 review passes sequentially in a single session. Display:
Agent tool not available — falling back to single-session sequential review.
For parallel agent review, use Claude Code or another tool that supports the Agent tool.
Running: $prp-review {NUMBER}
After all agents complete, collect their outputs. Each agent returns a markdown report with findings.
For each agent result:
If an agent returns no findings: Note as clean — "No {aspect} issues found."
If an agent fails or times out: Note the failure and proceed with available results. Display:
WARNING: {agent-type} agent failed/timed out. {aspect} review incomplete.
Consider running $prp-review {NUMBER} {aspect} for a single-session {aspect} review.
CRITICAL: If any core agent (code-reviewer, security-reviewer, silent-failure-hunter) fails, the final verdict MUST be at minimum NEEDS FIXES with caveat: "Review incomplete — {agent-type} did not complete. Verdict may be optimistic." A READY TO MERGE verdict is never valid when a core agent is missing.
Before categorizing, deduplicate findings across agents.
Two findings are considered duplicates when BOTH conditions are met:
NOT duplicates (do not merge):
When duplicates found:
code-reviewer, silent-failure-hunterBEFORE dedup:
| Agent | Issue | Location |
|---|---|---|
| code-reviewer | Empty catch block swallows error | api.ts:45 |
| silent-failure-hunter | Catch block has no logging or re-throw | api.ts:47 |
AFTER dedup:
| Agent | Issue | Location |
|---|---|---|
| code-reviewer, silent-failure-hunter | Empty catch block swallows error — no logging or re-throw | api.ts:45-47 |
Run automated checks to catch issues that code review alone may miss.
Skip if context file contains concrete validation results (actual PASS/FAIL with counts — not template placeholders like checkmarks without details).
# Type checking (adapt to project)
npm run type-check || bun run type-check || npx tsc --noEmit
# Linting
npm run lint || bun run lint
# Tests
npm test || bun test
# Build
npm run build || bun run build
Capture for each: pass/fail status, error count, warning count, specific failures.
| Change Type | Additional Validation |
|---|---|
| New API endpoint | Test with curl/httpie |
| Database changes | Check migration exists |
| Config changes | Verify .env.example updated |
| New dependencies | Check package.json/lock file consistency |
After deduplication, categorize all findings:
| Category | Description | Action |
|---|---|---|
| Critical | Must fix before merge | Block merge |
| Important | Should fix | Address before merge |
| Suggestions | Nice to have | Consider |
| Strengths | What's good | Acknowledge |
| Condition | Verdict |
|---|---|
| No critical/important issues AND all validation passes | READY TO MERGE |
| Important issues OR validation warnings (fixable) | NEEDS FIXES |
| Critical issues OR validation failures | CRITICAL ISSUES |
Note: If validation fails, verdict is at least NEEDS FIXES regardless of agent findings.
## PR Review Summary (Multi-Agent)
### Agents Dispatched
| Agent | Status | Findings |
|-------|--------|----------|
| code-reviewer | Completed | {N} issues |
| security-reviewer | Completed | {N} issues |
| silent-failure-hunter | Completed | {N} issues |
| {conditional agents...} | ... | ... |
### Critical Issues (X found)
| Agent | Issue | Location |
|-------|-------|----------|
| security-reviewer | Description | `file.ts:line` |
### Important Issues (X found)
| Agent | Issue | Location |
|-------|-------|----------|
| silent-failure-hunter | Description | `file.ts:line` |
### Suggestions (X found)
| Agent | Suggestion | Location |
|-------|------------|----------|
| code-reviewer | Description | `file.ts:line` |
### Strengths
- Well-structured error handling
- Good test coverage for critical paths
### Validation Results
| Check | Status | Details |
|-------|--------|---------|
| Type Check | {PASS/FAIL} | {notes} |
| Lint | {PASS/WARN} | {count} warnings |
| Tests | {PASS/FAIL} | {count} passed |
| Build | {PASS/FAIL} | {notes} |
### File Coverage Map
| File | Tier | Agents Run |
|------|------|------------|
| `src/auth/login.ts` | 1 (Critical) | code, security, errors |
### Verdict
[READY TO MERGE / NEEDS FIXES / CRITICAL ISSUES]
### Recommended Actions
1. Fix critical issues first
2. Address important issues
3. Consider suggestions
4. Re-run review after fixes
Note: Agent column may list multiple agents for deduplicated findings (e.g., code-reviewer, silent-failure-hunter).
Include this frontmatter at the top of the review file:
---
pr: {NUMBER}
title: "{TITLE}"
author: "{AUTHOR}"
reviewed: {ISO_TIMESTAMP}
verdict: {READY TO MERGE / NEEDS FIXES / CRITICAL ISSUES}
agents: [{list of agents that ran}]
---
Save aggregated review to .prp-output/reviews/pr-{NUMBER}-agents-review.md before posting to GitHub.
Note: Uses
-agents-reviewsuffix (distinct from-review-claude-code.mdused by single-session$prp-review) to prevent overwriting.
mkdir -p .prp-output/reviews
Append a machine-readable, SHA-bound marker as the last line of the review file, before posting to GitHub. Because the same file is used both as the local artifact and as the --body-file for the GitHub post, the marker lands in both places. This lets safe-merge satisfy its review gate across worktrees / different-cwd repos and for -R cross-repo merges (where it currently skips review entirely).
Trust model (read this): the marker is an integrity/consistency signal for an honest reviewer, NOT an authenticity boundary. A process that can write this file can write a matching body+marker; the marker does not, by itself, prove a review happened. It does not raise the trust level above the pre-existing local-file-presence gate — it only makes that same signal portable across repos and SHA-bound.
safe-mergeis responsible for re-deriving counts from the body, re-checking the head SHA at merge time, and blocking on any inconsistency. Emit honestly.
Emit for every verdict (READY / NEEDS FIXES / CRITICAL) — safe-merge must see blocks too, and cross-checks the marker against the body.
Strict grammar (safe-merge matches the whole last line, expects exactly one marker, rejects anything off-grammar → fail-closed):
<!-- safe-merge-review: verdict=(READY_TO_MERGE|NEEDS_FIXES|CRITICAL_ISSUES) critical=<int> important=<int> agents=<csv-of [a-z0-9-] tokens, no spaces> head=<40-hex-sha> -->
Field rules:
verdict — map the aggregated verdict: READY TO MERGE→READY_TO_MERGE, NEEDS FIXES→NEEDS_FIXES, CRITICAL ISSUES→CRITICAL_ISSUES. The verdict field is authoritative for block/pass: safe-merge blocks on NEEDS_FIXES/CRITICAL_ISSUES regardless of counts (so a CRITICAL_ISSUES caused by a validation/build failure with zero agent-critical findings — see the Verdict Decision Logic — is legitimately critical=0 and still blocks).critical / important — MUST equal the integers in the body headings ### Critical Issues (N found) / ### Important Issues (N found). safe-merge recomputes them from the body and BLOCKS on mismatch. Only enforced invariant: READY_TO_MERGE ⟹ critical=0 AND important=0. (No critical>0 requirement for CRITICAL_ISSUES — a blocking verdict already blocks.)agents — comma-separated [a-z0-9-] tokens, no spaces. Do NOT emit verdict=READY_TO_MERGE unless all three core agents (code-reviewer, security-reviewer, silent-failure-hunter) are present in the aggregation — mirrors the Phase 3 rule "READY TO MERGE is never valid when a core agent is missing." If a core agent is missing, the verdict is at least NEEDS_FIXES.head — use $MARKER_HEAD derived below (never a fresh gh pr view). Default is $REVIEWED_HEAD_SHA captured in Phase 1.3 at diff-gather time, so a push during review invalidates the marker. The ONLY sanctioned exception is the artifacts-commit re-bind in "Commit artifacts BEFORE the marker" below — a docs-only advance of HEAD by this workflow's own artifact commit, mechanically verified.safe-merge matches the GitHub-side marker's head= against the PR HEAD at merge time. Flows that commit review artifacts to the PR branch (run-all, ARTIFACT-REPORT) advance HEAD past $REVIEWED_HEAD_SHA with that very commit — a marker bound to the pre-artifacts SHA is then guaranteed to block, and the tempting escape (--skip-review-check) defeats the gate. Fixed ordering:
git add/commit/push them NOW (review file, fix summaries, reports, archived plan).MARKER_HEAD=""
CURRENT_HEAD=$(git rev-parse HEAD 2>/dev/null)
# Both SHAs must be valid 40-hex BEFORE any diff. An empty/unset REVIEWED_HEAD_SHA
# makes `git diff ""..HEAD` print NOTHING and the guard would fail OPEN (verified);
# an unresolvable SHA makes git exit 128 with empty stdout — same silent fail-open
# if the exit code is swallowed by a pipeline. Fail loud on both.
if ! printf '%s' "$CURRENT_HEAD" | grep -qE '^[0-9a-f]{40}$'; then
echo "FATAL: could not resolve local HEAD ('$CURRENT_HEAD') — marker NOT emitted" >&2
elif ! printf '%s' "$REVIEWED_HEAD_SHA" | grep -qE '^[0-9a-f]{40}$'; then
echo "FATAL: REVIEWED_HEAD_SHA missing/invalid ('$REVIEWED_HEAD_SHA') — marker NOT emitted; re-run Phase 1.3" >&2
elif [ "$CURRENT_HEAD" = "$REVIEWED_HEAD_SHA" ]; then
MARKER_HEAD="$REVIEWED_HEAD_SHA" # no advance — bind to the reviewed head as before
else
# HEAD moved since diff-gather. Re-bind is legitimate ONLY if every commit in
# between touches nothing but .prp-output/ (this workflow's own artifacts).
# --no-renames: with rename detection, `git mv src/x .prp-output/y` would show
# ONLY the .prp-output destination and a reviewed file could vanish from the
# merged tree unnoticed; --no-renames lists BOTH the deletion and the addition.
# Capture git diff's exit code SEPARATELY from the grep filter — a git error
# must never be indistinguishable from "zero non-artifact files".
DIFF_OUTPUT=$(git diff --no-renames "$REVIEWED_HEAD_SHA".."$CURRENT_HEAD" --name-only 2>&1)
DIFF_EC=$?
if [ "$DIFF_EC" -ne 0 ]; then
echo "FATAL: git diff $REVIEWED_HEAD_SHA..$CURRENT_HEAD failed (exit $DIFF_EC) — cannot verify docs-only advance, refusing to re-bind:" >&2
echo "$DIFF_OUTPUT" >&2
else
NON_ARTIFACT=$(printf '%s\n' "$DIFF_OUTPUT" | grep -v '^\.prp-output/' || true)
if [ -z "$NON_ARTIFACT" ]; then
MARKER_HEAD="$CURRENT_HEAD" # docs-only advance — reviewed code state is byte-identical
else
echo "FATAL: code changed since review ($REVIEWED_HEAD_SHA -> $CURRENT_HEAD):" >&2
echo "$NON_ARTIFACT" >&2
echo "Marker NOT emitted — re-run the review against the new head." >&2
fi
fi
fi
head=$MARKER_HEAD, append to the artifact, then post to GitHub. The local file's marker may lag one docs-only commit behind its own blob — the GitHub-side post (what safe-merge reads for head-matching) carries the current-head binding.MARKER_HEAD stays $REVIEWED_HEAD_SHA — behavior unchanged.Do NOT commit again after emitting the marker (that re-invalidates it). If a later fix round changes code, the next review round re-runs this whole sequence.
Extract the counts mechanically from the file you just wrote (don't retype from memory — that drifts, and a drift makes safe-merge block):
REVIEW_FILE=".prp-output/reviews/pr-{NUMBER}-agents-review.md"
CRIT=$(grep -oiP '###\s+Critical Issues\s+\(\K\d+' "$REVIEW_FILE" | head -1); CRIT="${CRIT:-0}"
IMP=$(grep -oiP '###\s+Important Issues\s+\(\K\d+' "$REVIEW_FILE" | head -1); IMP="${IMP:-0}"
# VERDICT_TOKEN and AGENTS_CSV from your aggregation. Sanitize agents to the grammar.
AGENTS_CSV=$(printf '%s' "$AGENTS_CSV" | tr 'A-Z' 'a-z' | tr -cd 'a-z0-9,-')
# Validate VERDICT_TOKEN against the enum (defensive — an aggregation glitch must
# fail loud, not emit an off-grammar marker).
case "$VERDICT_TOKEN" in
READY_TO_MERGE|NEEDS_FIXES|CRITICAL_ISSUES) ;;
*) echo "FATAL: bad VERDICT_TOKEN ('$VERDICT_TOKEN') — marker NOT emitted" >&2; VERDICT_TOKEN="" ;;
esac
# head must be MARKER_HEAD from the re-bind block above. This regex is a FORMAT
# backstop only (rejects empty/garbage) — CORRECTNESS of the value is the re-bind
# guard's job above. (Empty MARKER_HEAD = the guard already reported FATAL:
# code drift, unresolvable SHA, or git-diff failure.)
if ! printf '%s' "$MARKER_HEAD" | grep -qE '^[0-9a-f]{40}$'; then
echo "FATAL: MARKER_HEAD missing/invalid ('$MARKER_HEAD') — marker NOT emitted; re-run Phase 1.3 / the re-bind block" >&2
elif [[ -z "$VERDICT_TOKEN" ]]; then
: # VERDICT_TOKEN already reported FATAL above — marker not emitted
else
printf '\n<!-- safe-merge-review: verdict=%s critical=%s important=%s agents=%s head=%s -->\n' \
"$VERDICT_TOKEN" "$CRIT" "$IMP" "$AGENTS_CSV" "$MARKER_HEAD" \
>> "$REVIEW_FILE"
fi
Self-review detection: Before posting a formal review, check if the current GitHub user is the PR author:
PR_AUTHOR=$(gh pr view {NUMBER} --json author --jq '.author.login')
CURRENT_USER=$(gh api user --jq '.login')
If PR_AUTHOR == CURRENT_USER: skip gh pr review (GitHub blocks self-approval) and fall back to gh pr comment directly. This is expected in single-user repos where all agents share the same GitHub identity.
| Condition | Action |
|---|---|
| READY TO MERGE | gh pr review {NUMBER} --approve --body-file .prp-output/reviews/pr-{NUMBER}-agents-review.md |
| NEEDS FIXES or CRITICAL ISSUES | gh pr review {NUMBER} --request-changes --body-file .prp-output/reviews/pr-{NUMBER}-agents-review.md |
| Draft PR | gh pr comment {NUMBER} --body-file .prp-output/reviews/pr-{NUMBER}-agents-review.md (comment only — no formal review on drafts) |
If gh pr review fails (e.g., permission denied, fork PR restrictions):
ghgh pr comment {NUMBER} --body-file .prp-output/reviews/pr-{NUMBER}-agents-review.mdAfter publishing to GitHub, append one JSONL line to .prp-output/reviews/review-metrics.jsonl:
{"timestamp":"2026-03-14T10:30:00Z","pr_number":163,"branch":"feature/auth","review_type":"agents","verdict":"NEEDS_FIXES","total_issues":5,"critical":1,"important":2,"suggestions":2,"agents_run":["code-reviewer","security-reviewer","silent-failure-hunter"],"conditional_agents":["accessibility-reviewer"],"incremental":false,"large_pr":false,"lines_changed":342,"files_changed":8}
Fields:
timestamp — ISO 8601 review completion timepr_number — PR number reviewedbranch — Branch namereview_type — Always "agents" for this command (distinguishes from single-session "single")verdict — READY_TO_MERGE / NEEDS_FIXES / CRITICAL_ISSUEStotal_issues — Total findings countcritical, important, suggestions — Counts by severityagents_run — List of all agents that ranconditional_agents — List of agents added by conditional dispatchincremental — Whether --since-last-review was usedlarge_pr — Whether large PR strategy was appliedlines_changed, files_changed — PR size metrics# Append (creates file if not exists)
mkdir -p .prp-output/reviews
echo '{...}' >> .prp-output/reviews/review-metrics.jsonl || echo "WARNING: Failed to append review metrics. Review results are saved, but metrics tracking is incomplete."
--metrics Flag: Aggregate SummaryWhen --metrics flag provided (without PR number), display aggregate summary and EXIT:
# Read metrics
cat .prp-output/reviews/review-metrics.jsonl
Display:
## Review Metrics Summary
**Total Reviews**: {N}
**Period**: {earliest timestamp} — {latest timestamp}
### Verdicts
| Verdict | Count | % |
|---------|-------|---|
| READY TO MERGE | {N} | {%} |
| NEEDS FIXES | {N} | {%} |
| CRITICAL ISSUES | {N} | {%} |
### Issues by Severity
| Severity | Total | Avg per Review |
|----------|-------|---------------|
| Critical | {N} | {avg} |
| Important | {N} | {avg} |
| Suggestions | {N} | {avg} |
### Agent Contribution
| Agent | Times Run | Issues Found |
|-------|-----------|-------------|
| code-reviewer | {N} | {total} |
| security-reviewer | {N} | {total} |
| silent-failure-hunter | {N} | {total} |
| ... | ... | ... |
### Review Type Breakdown
| Type | Count | Avg Issues |
|------|-------|------------|
| agents (parallel) | {N} | {avg} |
| single (sequential) | {N} | {avg} |
If no metrics file exists: "No review metrics found. Metrics will be collected after your first review."
After posting to GitHub, update the implementation report to close the feedback loop.
# Find report matching the PR branch
BRANCH=$(gh pr view <PR_NUMBER> --json headRefName -q '.headRefName')
ls -t .prp-output/reports/*-report*.md 2>/dev/null | head -1
If implementation report exists, append the following section to the end of the report:
---
## Review Outcome (Agents)
**Reviewed**: {ISO_TIMESTAMP}
**PR**: #{NUMBER}
**Verdict**: {READY TO MERGE / NEEDS FIXES / CRITICAL ISSUES}
**Review File**: `.prp-output/reviews/pr-{NUMBER}-agents-review.md`
**Agents Run**: {list}
| Category | Count |
|----------|-------|
| Critical | {N} |
| Important | {N} |
| Suggestions | {N} |
{If NEEDS FIXES or CRITICAL ISSUES: list of top issues to address}
If no implementation report found: Note in review output: "Implementation report not found — skipped update." (PR may not have been created via PRP workflow.)
If implementation report references a Source PRD:
| Verdict | PRD Update |
|---|---|
| READY TO MERGE | Change phase status from complete to reviewed |
| NEEDS FIXES | Add note: "Review: {N} issues to address" |
| CRITICAL ISSUES | Add note: "Blocked: {brief reason}" |
$prp-review-agents 163 # Full multi-agent review
$prp-review-agents 163 security errors # Only security + error handling agents
$prp-review-agents # Current branch's PR
$prp-review-agents 42 code docs # Only code and docs agents
$prp-review-agents 42 perf a11y # Performance + accessibility agents
$prp-review-agents 163 --since-last-review # Incremental re-review
$prp-review-agents --metrics # View review metrics
| Situation | Action |
|---|---|
| PR has 500+ changed files | Apply Large PR Strategy (Phase 1.5) — tier-based review |
gh pr diff returns empty | STOP — "No changes to review. Verify the branch is pushed and the correct base branch is set. Run gh pr diff {NUMBER} manually to diagnose." |
| No PR found for current branch | STOP — "No open PR found for branch. Create a PR first with gh pr create, or pass a PR number explicitly." |
--context path with empty diff | WARN and fall through to Phase 1 for fresh context extraction |
| No CLAUDE.md or conventions file | Proceed — rely on codebase patterns from diff |
| PR is a revert commit | Focus on: was the revert correct? Any side effects? |
| PR modifies only generated files | Skip most agents, note "generated code" in review |
| Review artifact already exists | Overwrite with new review (timestamp in frontmatter tracks versions) |
--metrics with no metrics file | Display "No review metrics found" and EXIT |
--metrics with PR number | Display metrics first, then proceed with review |
| Agent tool not available | Fall back to $prp-review (single-session sequential) |
| Agent times out or fails | Note failure, proceed with available results; if core agent failed, force verdict to NEEDS FIXES minimum |