Review the current PR using a parallel agent swarm, then address all findings.
Agent findings persist to docs/reviews/ so reviews survive session crashes.
Single-Agent Mode
If the user specifies agent names, run only those agents instead of auto-detecting:
/pr-swarm security — run only the security agent
/pr-swarm python typescript — run only Python and TypeScript agents
Valid agent short names: api, code, csharp, docs, dry, efficiency, errors, frontend, go, java, javascript, kotlin, python, rust, security, simplify, swift, tests, types, typescript, web3.
When in single-agent mode, skip Phase 1 detection flags — just launch the requested agents directly. The rest of the workflow (state, collection, compile, fix) is unchanged.
Branch Safety
All phases run on the PR branch. NEVER git checkout main or switch branches.
Phase 0: Recovery Check
Before anything else, check for existing review state:
Detect the current PR:
- Run
gh pr view --json number,url,title,baseRefName 2>/dev/null || echo "NO_PR"
- If no PR found, ask the user for the PR number or URL
- Extract
baseRefName — this is BASE_BRANCH for all diffs
- Verify
gh CLI is available — if not, STOP: "GitHub CLI (gh) required. Install: https://cli.github.com"
Check for existing review state:
- Run
cat docs/reviews/PR-{NUMBER}/_state.json 2>/dev/null || echo "NO_STATE"
- If state exists:
- Read
_state.json to get the full list of agents
- Check which
{agent-name}.md files exist on disk — these agents completed regardless of what _state.json says
- Compare
HEAD SHA against head_sha in state. If different, warn about changes since last review.
- Tell user: "Found previous review for PR #{N}. {X}/{Y} agents completed."
- Ask: "Resume (run remaining agents) or restart fresh?"
- If resume: skip to Phase 2 Step 2b. Only launch agents whose file does NOT exist.
- If restart: delete directory and continue normally
- If no state: continue to Phase 1
Phase 1: Detect PR and Scope
Get changed files and diff:
gh pr diff --name-only 2>/dev/null | head -50
git diff BASE_BRANCH...HEAD --stat
Set detection flags from changed files:
has_frontend: .tsx, .jsx, .css, .scss, .vue, .svelte files
has_tests: .test., .spec., _test. files
has_types: .ts, .tsx files OR .py files with type hints
has_code: any source files (not just docs/config)
has_error_handling: files with try/catch, catch blocks, except clauses
has_api: route/endpoint definitions, OpenAPI specs, GraphQL schemas, protobuf files
has_web3: .sol files OR files importing ethers, viem, web3.js, @solana/web3.js, anchor
has_security_surface: auth, API, input handling, env, or config files
has_deps: package.json, requirements.txt, go.mod, Cargo.toml, Gemfile, build.gradle changes
is_docs_only: ONLY .md, .txt, .json, or config files
Detect primary language(s) by file extension count:
.py → Python, .ts/.tsx → TypeScript, .js/.jsx → JavaScript
.go → Go, .rs → Rust, .java → Java, .cs → C#
.kt/.kts → Kotlin, .swift → Swift, .sol → Solidity
Inform user: "Running full review on PR #___ (N files changed, areas: ...)"
Phase 2: Initialize State and Launch Agent Swarm
HARD GATE: If has_code, minimum 3 agents. If is_docs_only, minimum 1.
A single-agent review misses cross-cutting concerns — security issues invisible to a code quality reviewer, duplication invisible to a security reviewer. The value of the swarm is overlapping coverage.
Step 2a: Create review state
mkdir -p docs/reviews/PR-{NUMBER}
Write docs/reviews/PR-{NUMBER}/_state.json:
{
"pr_number": "{NUMBER}",
"pr_title": "{TITLE}",
"branch": "{BRANCH}",
"base_branch": "{BASE_BRANCH}",
"head_sha": "{HEAD_SHA}",
"started_at": "{ISO_TIMESTAMP}",
"agents": {
"code": { "status": "pending", "file": null }
},
"phase": "launching",
"compiled": false
}
Step 2b: Select and launch agents
Agent selection based on detection flags:
Always run (skip only if is_docs_only):
code — general code quality
security — security + deps + infra
Run when applicable:
errors — if has_error_handling or has_code
simplify — if has_code
dry — if has_code
docs — if has_code or is_docs_only
types — if has_types
tests — if has_tests
efficiency — if has_code
api — if has_api
frontend — if has_frontend
web3 — if has_web3
Language-specific (auto-select based on detected languages):
python — if Python detected
typescript — if TypeScript detected
javascript — if JavaScript detected
go — if Go detected
rust — if Rust detected
java — if Java detected
csharp — if C# detected
kotlin — if Kotlin detected
swift — if Swift detected
For each selected agent:
- Locate the bundled agents directory. Search in order:
~/.agents/skills/pr-swarm/agents/ (universal path)
~/.claude/skills/pr-swarm/agents/ (Claude Code)
~/.cursor/skills/pr-swarm/agents/ (Cursor)
./skills/pr-swarm/agents/ (local repo fallback)
- Use the first path that contains
.md files
- Read the agent's prompt file:
{agents_dir}/{agent-short-name}.md (e.g., agents/security.md)
- Extract the prompt content (everything after the frontmatter
---)
- Launch as
general-purpose Agent with run_in_background: true
Each agent prompt MUST include:
- The extracted skill prompt
- PR number, branch, base branch, changed files list
- Instruction:
Review ONLY changed files. Use git diff {BASE_BRANCH}...HEAD to see the diff.
- Self-persistence instruction (below)
- Git safety instruction (below)
Self-Persistence Instruction (REQUIRED in every agent prompt):
After completing your review, you MUST write your findings to docs/reviews/PR-{NUMBER}/{agent-short-name}.md (e.g., security.md, python.md) using the Write tool. Format:
- Summary (1-2 sentences)
- Must Fix (bulleted list with
file:line references)
- Suggestions (bulleted list with
file:line references)
- Nitpicks (bulleted list with
file:line references)
- If no findings in a category, write "None"
Writing this file is your MOST IMPORTANT action — do it before returning.
Git Safety Instruction (REQUIRED in every agent prompt):
Do NOT run git checkout, git switch, or any command that changes the current branch. You are on the PR branch — stay on it. Use git diff {BASE_BRANCH}...HEAD for diffs. Never checkout main.
After dispatching all agents, update _state.json: set phase to collecting.
Phase 3: Collect Agent Results
Agents run in background. You are notified as each completes — do NOT poll or sleep.
As each agent returns:
- Report: "{agent-name} completed ({X}/{N} done)"
- If error/empty output, check if
.md file exists on disk. Write fallback if needed.
- Update
_state.json: set agent status to completed or failed.
Do NOT proceed early — wait for all agents. Compiling a partial report means de-duplication misses cross-agent overlap (agents often flag the same issue differently). Starting fixes while agents run risks editing files an agent is actively reading, corrupting its review.
- Do NOT start reading findings before all agents return
- Do NOT start compiling the report before all agents return
- Do NOT skip ahead to Phase 4 while any agent is running
- Do NOT start fixing code while agents are running
Timeout: If one agent hasn't returned but all others completed 10+ minutes ago, mark as timed_out and proceed.
Failed agent retry policy: If any agent fails or times out, you MUST retry it once before moving on. Re-read the agent prompt file and re-launch. Only after a second failure may you mark it as failed and proceed without it. Do NOT silently skip failed agents — every selected agent was selected for a reason and its coverage area will have zero findings if skipped.
After all agents returned (including retries):
- List all
*.md files in docs/reviews/PR-{NUMBER}/. Report: "{X}/{N} produced findings."
- If any agents failed after retry, warn the user: "Agents {list} failed after retry — their review areas have no coverage."
- Update
_state.json: set phase to compiling.
Phase 4: Compile Report
Read all findings from files — read each docs/reviews/PR-{NUMBER}/{agent-name}.md from disk.
De-duplicate: If multiple agents flag the same file:line for overlapping reasons, consolidate and note which agents flagged it.
Categorize findings:
- Must Fix — bugs, security issues, correctness problems, broken logic
- Suggestions — improvements, better patterns, performance, readability
- Nitpicks — style, naming, minor preferences
Number every finding sequentially — assign a single global number (1, 2, 3…) across all categories. Must Fix items come first, then Suggestions, then Nitpicks. This number is the finding's permanent ID and MUST be used consistently in the compiled report, the PR comment, the in-conversation presentation, and the resolution checklist in Phase 5. If the compiled report has 14 findings, they are numbered 1–14 — no gaps, no duplicates.
Write compiled report to docs/reviews/PR-{NUMBER}/compiled-report.md
The report must list every finding with its number, location, source agent(s), and description. Use this structure:
# Compiled Review — PR #{NUMBER}: {TITLE}
**Summary:** N files reviewed, M agents ran, T total findings
## Must Fix (X items)
**#1** · `file:line` · [agent1, agent2]
Description of the finding.
**#2** · `file:line` · [agent1]
Description of the finding.
## Suggestions (Y items)
**#3** · `file:line` · [agent1]
Description of the finding.
## Nitpicks (Z items)
**#4** · `file:line` · [agent1]
Description of the finding.
---
**Total findings: T** (Must Fix: X, Suggestions: Y, Nitpicks: Z)
The Total findings line at the bottom is a hard requirement — it anchors the count so the resolution checklist in Phase 5 can verify nothing was dropped.
Update _state.json: set phase to done, compiled to true
Post as PR comment:
gh pr comment {NUMBER} --body "$(cat <<'EOF'
## PR Review Swarm — Findings
**Summary:** N files reviewed, M agents ran, T total findings
**Must Fix (X items)**
- [ ] #1 · `file:line` — [agent] description
- [ ] #2 · `file:line` — [agent] description
**Suggestions (Y items)**
- [ ] #3 · `file:line` — [agent] description
**Nitpicks (Z items)**
- [ ] #4 · `file:line` — [agent] description
**Total findings: T** (Must Fix: X, Suggestions: Y, Nitpicks: Z)
*Agents: {list of agents that ran}*
EOF
)"
Present the report to the user in conversation using the exact format below. This is a hard requirement — do NOT summarize, abbreviate, omit categories, show only counters, or skip lower-severity findings. Every single finding from the compiled report must appear in the table, regardless of severity. The user needs the full picture to make an informed decision.
Required in-conversation format:
## PR Review — PR #{NUMBER}: {TITLE}
**Summary:** N files reviewed, M agents ran, T total findings
### Must Fix (X items)
| # | Location | Agents | Finding |
|---|----------|--------|---------|
| #1 | `file:line` | agent1, agent2 | Description of the finding |
| #2 | `file:line` | agent1 | Description of the finding |
### Suggestions (Y items)
| # | Location | Agents | Finding |
|---|----------|--------|---------|
| #3 | `file:line` | agent1 | Description of the finding |
### Nitpicks (Z items)
| # | Location | Agents | Finding |
|---|----------|--------|---------|
| #4 | `file:line` | agent1 | Description of the finding |
**Total findings: T** (Must Fix: X, Suggestions: Y, Nitpicks: Z)
Violations — do NOT do any of the following:
- Do NOT show only Must Fix items and mention "there are also N suggestions and M nitpicks" — list them all in the tables
- Do NOT replace the tables with a bullet list, prose paragraph, or summary
- Do NOT show only finding counts or the report file path — the user must see every finding inline
- Do NOT truncate or collapse any category — every finding from the compiled report must appear
- If a category has 0 items, show the heading with "(0 items)" and write "None" instead of a table
Ask: "Want me to address all findings, pick specific items, or skip?"
Interpreting the user's response:
- "address all" / "fix all" / "all" → Every finding must be resolved. "Resolved" means the code is changed to address it. The only acceptable exceptions are findings that are genuinely not applicable (the agent's analysis was wrong, or the code doesn't exist). "Intentionally deferred" is NOT allowed when the user says "all" — they are explicitly telling you not to defer. Do not silently downgrade suggestions or nitpicks to deferred. Do not skip items because they seem minor. The user said all and they mean all.
- "pick specific items" → User will list items by number. Only address those.
- "skip" → Do not fix anything.
Phase 5: Fix Pass (Sequential)
STOP. Read this entire gate checklist before touching any code file.
You are not allowed to edit, write, or modify any source file until every single gate below is TRUE. No exceptions. No "I'll present the report after." No "I'll fix this obvious one while waiting." The user has explicitly asked for this workflow — report first, then approval, then fixes. Violating this order means the user sees changes they never approved.
All five gates must be TRUE:
- Every agent has returned or been retried and failed (Phase 3 complete)
- Compiled report written to disk (Phase 4 step 5)
- Findings posted as PR comment (Phase 4 step 7)
- Report presented to user in conversation (Phase 4 step 8)
- User has responded with their choice — you received an explicit message from the user (Phase 4 step 9)
If ANY gate is false, do NOT open, edit, or write any code file. Wait.
Step 5a: Plan fix order
- Priority order: must-fix → suggestions → nitpicks
- Group findings touching same function/block (apply together)
- Report plan before starting
Step 5b: Apply fixes sequentially
- Read target file(s) before editing
- Each logical fix or small group = 1 commit with descriptive message
- Scope guard: Only change what the finding describes
- Deferral policy: You may defer a finding ONLY if the user chose "pick specific items" and did not include it, or if fixing it would require changes to files/systems outside this PR's scope (e.g., database migrations, third-party API changes). Suggestions and nitpicks are not automatically deferrable — they are real findings that the reviewers flagged for a reason. When the user said "address all", treat every category (must-fix, suggestions, nitpicks) with equal obligation.
Step 5c: Verify
Run full test suite once after all fixes.
- Pass: proceed to Step 5d
- Fail: identify breaking commit(s), revert, note as "skipped — broke tests"
Step 5d: Resolution checklist
Before pushing, produce a resolution checklist that accounts for EVERY finding in the compiled report. No finding may be omitted — if the compiled report has 14 items, the checklist has 14 entries. Use the same #N numbers from the compiled report.
Each finding gets exactly one disposition:
- fixed — code was changed to address this finding
- intentionally deferred — not addressed in this PR, with a specific reason (ONLY allowed when user did NOT say "address all")
- not applicable — the finding was incorrect, or the code it references doesn't exist / was already changed by another fix
Present the checklist to the user in conversation BEFORE pushing. The user must see every item and its disposition. If they object to any disposition, revise before pushing.
Hard rule: The total number of items across both sections (Fixed + Unresolved) MUST equal the total findings count from the compiled report. If they don't match, you missed something — go back and account for every item.
Step 5e: Push and comment
Push all commits
Post follow-up PR comment. Use properly formatted markdown tables — header row, separator row (|---|), then data rows. Do NOT output raw pipe characters as plain text — the table must render as a formatted table in GitHub and in the terminal.
gh pr comment {NUMBER} --body "$(cat <<'EOF'
## Review Fixes — Resolution Checklist
### Fixed (N items)
| # | Category | Finding | Detail |
|---|----------|---------|--------|
| #1 | Must Fix | `file:line` — description | commit abc1234 |
| #2 | Suggestion | `file:line` — description | commit def5678 |
| #5 | Nitpick | `file:line` — description | commit ghi9012 |
### Unresolved (N items)
| # | Category | Finding | Disposition |
|---|----------|---------|-------------|
| #3 | Nitpick | `file:line` — description | **not applicable:** finding was incorrect because X |
| #4 | Suggestion | `file:line` — description | **deferred:** requires database migration outside PR scope |
**Total: T findings** — X fixed, Y not applicable, Z deferred
*All changes in latest push*
EOF
)"
The Unresolved table keeps the original #N index from the compiled report so the user can instantly cross-reference what was skipped and why. If everything was fixed, write "### Unresolved (0 items)" with "None" underneath — do not omit the section.
1---2name: pr-swarm3description: Orchestrate a parallel PR review agent swarm — detect, launch, collect, compile report, fix findings. Crash-resilient.4---56Review the current PR using a parallel agent swarm, then address all findings.7Agent findings persist to `docs/reviews/` so reviews survive session crashes.89## Single-Agent Mode1011If the user specifies agent names, run only those agents instead of auto-detecting:1213```14/pr-swarm security — run only the security agent15/pr-swarm python typescript — run only Python and TypeScript agents16```1718Valid agent short names: `api`, `code`, `csharp`, `docs`, `dry`, `efficiency`, `errors`, `frontend`, `go`, `java`, `javascript`, `kotlin`, `python`, `rust`, `security`, `simplify`, `swift`, `tests`, `types`, `typescript`, `web3`.1920When in single-agent mode, skip Phase 1 detection flags — just launch the requested agents directly. The rest of the workflow (state, collection, compile, fix) is unchanged.2122## Branch Safety2324All phases run on the PR branch. NEVER `git checkout main` or switch branches.2526## Phase 0: Recovery Check2728Before anything else, check for existing review state:29301. Detect the current PR:31 - Run `gh pr view --json number,url,title,baseRefName 2>/dev/null || echo "NO_PR"`32 - If no PR found, ask the user for the PR number or URL33 - Extract `baseRefName` — this is `BASE_BRANCH` for all diffs34 - Verify `gh` CLI is available — if not, STOP: "GitHub CLI (gh) required. Install: https://cli.github.com"35362. Check for existing review state:37 - Run `cat docs/reviews/PR-{NUMBER}/_state.json 2>/dev/null || echo "NO_STATE"`38 - If state exists:39 - Read `_state.json` to get the full list of agents40 - Check which `{agent-name}.md` files exist on disk — these agents completed regardless of what `_state.json` says41 - Compare `HEAD` SHA against `head_sha` in state. If different, warn about changes since last review.42 - Tell user: "Found previous review for PR #{N}. {X}/{Y} agents completed."43 - Ask: "Resume (run remaining agents) or restart fresh?"44 - If **resume**: skip to Phase 2 **Step 2b**. Only launch agents whose file does NOT exist.45 - If **restart**: delete directory and continue normally46 - If no state: continue to Phase 14748## Phase 1: Detect PR and Scope49501. Get changed files and diff:51 - `gh pr diff --name-only 2>/dev/null | head -50`52 - `git diff BASE_BRANCH...HEAD --stat`53542. Set detection flags from changed files:5556 - `has_frontend`: .tsx, .jsx, .css, .scss, .vue, .svelte files57 - `has_tests`: *.test.*, *.spec.*, *_test.* files58 - `has_types`: .ts, .tsx files OR .py files with type hints59 - `has_code`: any source files (not just docs/config)60 - `has_error_handling`: files with try/catch, catch blocks, except clauses61 - `has_api`: route/endpoint definitions, OpenAPI specs, GraphQL schemas, protobuf files62 - `has_web3`: .sol files OR files importing ethers, viem, web3.js, @solana/web3.js, anchor63 - `has_security_surface`: auth, API, input handling, env, or config files64 - `has_deps`: package.json, requirements.txt, go.mod, Cargo.toml, Gemfile, build.gradle changes65 - `is_docs_only`: ONLY .md, .txt, .json, or config files66673. Detect primary language(s) by file extension count:68 - `.py` → Python, `.ts/.tsx` → TypeScript, `.js/.jsx` → JavaScript69 - `.go` → Go, `.rs` → Rust, `.java` → Java, `.cs` → C#70 - `.kt/.kts` → Kotlin, `.swift` → Swift, `.sol` → Solidity71724. Inform user: "Running full review on PR #___ (N files changed, areas: ...)"7374## Phase 2: Initialize State and Launch Agent Swarm7576**HARD GATE: If `has_code`, minimum 3 agents. If `is_docs_only`, minimum 1.**7778A single-agent review misses cross-cutting concerns — security issues invisible to a code quality reviewer, duplication invisible to a security reviewer. The value of the swarm is overlapping coverage.7980### Step 2a: Create review state8182```bash83mkdir -p docs/reviews/PR-{NUMBER}84```8586Write `docs/reviews/PR-{NUMBER}/_state.json`:8788```json89{90 "pr_number": "{NUMBER}",91 "pr_title": "{TITLE}",92 "branch": "{BRANCH}",93 "base_branch": "{BASE_BRANCH}",94 "head_sha": "{HEAD_SHA}",95 "started_at": "{ISO_TIMESTAMP}",96 "agents": {97 "code": { "status": "pending", "file": null }98 },99 "phase": "launching",100 "compiled": false101}102```103104### Step 2b: Select and launch agents105106**Agent selection based on detection flags:**107108**Always run** (skip only if `is_docs_only`):109- `code` — general code quality110- `security` — security + deps + infra111112**Run when applicable:**113- `errors` — if `has_error_handling` or `has_code`114- `simplify` — if `has_code`115- `dry` — if `has_code`116- `docs` — if `has_code` or `is_docs_only`117- `types` — if `has_types`118- `tests` — if `has_tests`119- `efficiency` — if `has_code`120- `api` — if `has_api`121- `frontend` — if `has_frontend`122- `web3` — if `has_web3`123124**Language-specific** (auto-select based on detected languages):125- `python` — if Python detected126- `typescript` — if TypeScript detected127- `javascript` — if JavaScript detected128- `go` — if Go detected129- `rust` — if Rust detected130- `java` — if Java detected131- `csharp` — if C# detected132- `kotlin` — if Kotlin detected133- `swift` — if Swift detected134135**For each selected agent:**1361371. Locate the bundled agents directory. Search in order:138 - `~/.agents/skills/pr-swarm/agents/` (universal path)139 - `~/.claude/skills/pr-swarm/agents/` (Claude Code)140 - `~/.cursor/skills/pr-swarm/agents/` (Cursor)141 - `./skills/pr-swarm/agents/` (local repo fallback)142 - Use the first path that contains `.md` files1432. Read the agent's prompt file: `{agents_dir}/{agent-short-name}.md` (e.g., `agents/security.md`)1443. Extract the prompt content (everything after the frontmatter `---`)1454. Launch as `general-purpose` Agent with `run_in_background: true`146147**Each agent prompt MUST include:**148- The extracted skill prompt149- PR number, branch, base branch, changed files list150- Instruction: `Review ONLY changed files. Use git diff {BASE_BRANCH}...HEAD to see the diff.`151- Self-persistence instruction (below)152- Git safety instruction (below)153154**Self-Persistence Instruction (REQUIRED in every agent prompt):**155156> After completing your review, you MUST write your findings to `docs/reviews/PR-{NUMBER}/{agent-short-name}.md` (e.g., `security.md`, `python.md`) using the Write tool. Format:157> - **Summary** (1-2 sentences)158> - **Must Fix** (bulleted list with `file:line` references)159> - **Suggestions** (bulleted list with `file:line` references)160> - **Nitpicks** (bulleted list with `file:line` references)161> - If no findings in a category, write "None"162>163> Writing this file is your MOST IMPORTANT action — do it before returning.164165**Git Safety Instruction (REQUIRED in every agent prompt):**166167> Do NOT run `git checkout`, `git switch`, or any command that changes the current branch. You are on the PR branch — stay on it. Use `git diff {BASE_BRANCH}...HEAD` for diffs. Never checkout main.168169After dispatching all agents, update `_state.json`: set phase to `collecting`.170171## Phase 3: Collect Agent Results172173Agents run in background. You are notified as each completes — do NOT poll or sleep.174175**As each agent returns:**1761. Report: "{agent-name} completed ({X}/{N} done)"1772. If error/empty output, check if `.md` file exists on disk. Write fallback if needed.1783. Update `_state.json`: set agent status to `completed` or `failed`.179180**Do NOT proceed early — wait for all agents.** Compiling a partial report means de-duplication misses cross-agent overlap (agents often flag the same issue differently). Starting fixes while agents run risks editing files an agent is actively reading, corrupting its review.181182- Do NOT start reading findings before all agents return183- Do NOT start compiling the report before all agents return184- Do NOT skip ahead to Phase 4 while any agent is running185- Do NOT start fixing code while agents are running186187**Timeout:** If one agent hasn't returned but all others completed 10+ minutes ago, mark as `timed_out` and proceed.188189**Failed agent retry policy:** If any agent fails or times out, you MUST retry it once before moving on. Re-read the agent prompt file and re-launch. Only after a second failure may you mark it as `failed` and proceed without it. Do NOT silently skip failed agents — every selected agent was selected for a reason and its coverage area will have zero findings if skipped.190191**After all agents returned (including retries):**1921. List all `*.md` files in `docs/reviews/PR-{NUMBER}/`. Report: "{X}/{N} produced findings."1932. If any agents failed after retry, warn the user: "Agents {list} failed after retry — their review areas have no coverage."1943. Update `_state.json`: set phase to `compiling`.195196## Phase 4: Compile Report1971981. **Read all findings from files** — read each `docs/reviews/PR-{NUMBER}/{agent-name}.md` from disk.1992002. **De-duplicate:** If multiple agents flag the same file:line for overlapping reasons, consolidate and note which agents flagged it.2012023. **Categorize findings:**203 - **Must Fix** — bugs, security issues, correctness problems, broken logic204 - **Suggestions** — improvements, better patterns, performance, readability205 - **Nitpicks** — style, naming, minor preferences2062074. **Number every finding sequentially** — assign a single global number (1, 2, 3…) across all categories. Must Fix items come first, then Suggestions, then Nitpicks. This number is the finding's permanent ID and MUST be used consistently in the compiled report, the PR comment, the in-conversation presentation, and the resolution checklist in Phase 5. If the compiled report has 14 findings, they are numbered 1–14 — no gaps, no duplicates.2082095. **Write compiled report** to `docs/reviews/PR-{NUMBER}/compiled-report.md`210211 The report must list every finding with its number, location, source agent(s), and description. Use this structure:212213 ```markdown214 # Compiled Review — PR #{NUMBER}: {TITLE}215216 **Summary:** N files reviewed, M agents ran, T total findings217218 ## Must Fix (X items)219220 **#1** · `file:line` · [agent1, agent2]221 Description of the finding.222223 **#2** · `file:line` · [agent1]224 Description of the finding.225226 ## Suggestions (Y items)227228 **#3** · `file:line` · [agent1]229 Description of the finding.230231 ## Nitpicks (Z items)232233 **#4** · `file:line` · [agent1]234 Description of the finding.235236 ---237 **Total findings: T** (Must Fix: X, Suggestions: Y, Nitpicks: Z)238 ```239240 The **Total findings** line at the bottom is a hard requirement — it anchors the count so the resolution checklist in Phase 5 can verify nothing was dropped.2412426. **Update `_state.json`:** set phase to `done`, compiled to `true`2432447. **Post as PR comment:**245 ```bash246 gh pr comment {NUMBER} --body "$(cat <<'EOF'247 ## PR Review Swarm — Findings248249 **Summary:** N files reviewed, M agents ran, T total findings250251 **Must Fix (X items)**252 - [ ] #1 · `file:line` — [agent] description253 - [ ] #2 · `file:line` — [agent] description254255 **Suggestions (Y items)**256 - [ ] #3 · `file:line` — [agent] description257258 **Nitpicks (Z items)**259 - [ ] #4 · `file:line` — [agent] description260261 **Total findings: T** (Must Fix: X, Suggestions: Y, Nitpicks: Z)262263 *Agents: {list of agents that ran}*264 EOF265 )"266 ```2672688. **Present the report** to the user in conversation using the **exact format below**. This is a hard requirement — do NOT summarize, abbreviate, omit categories, show only counters, or skip lower-severity findings. Every single finding from the compiled report must appear in the table, regardless of severity. The user needs the full picture to make an informed decision.269270 **Required in-conversation format:**271272 ```273 ## PR Review — PR #{NUMBER}: {TITLE}274275 **Summary:** N files reviewed, M agents ran, T total findings276277 ### Must Fix (X items)278279 | # | Location | Agents | Finding |280 |---|----------|--------|---------|281 | #1 | `file:line` | agent1, agent2 | Description of the finding |282 | #2 | `file:line` | agent1 | Description of the finding |283284 ### Suggestions (Y items)285286 | # | Location | Agents | Finding |287 |---|----------|--------|---------|288 | #3 | `file:line` | agent1 | Description of the finding |289290 ### Nitpicks (Z items)291292 | # | Location | Agents | Finding |293 |---|----------|--------|---------|294 | #4 | `file:line` | agent1 | Description of the finding |295296 **Total findings: T** (Must Fix: X, Suggestions: Y, Nitpicks: Z)297 ```298299 **Violations — do NOT do any of the following:**300 - Do NOT show only Must Fix items and mention "there are also N suggestions and M nitpicks" — list them all in the tables301 - Do NOT replace the tables with a bullet list, prose paragraph, or summary302 - Do NOT show only finding counts or the report file path — the user must see every finding inline303 - Do NOT truncate or collapse any category — every finding from the compiled report must appear304 - If a category has 0 items, show the heading with "(0 items)" and write "None" instead of a table3053069. **Ask:** "Want me to address all findings, pick specific items, or skip?"307308 **Interpreting the user's response:**309 - **"address all" / "fix all" / "all"** → Every finding must be resolved. "Resolved" means the code is changed to address it. The only acceptable exceptions are findings that are genuinely not applicable (the agent's analysis was wrong, or the code doesn't exist). "Intentionally deferred" is NOT allowed when the user says "all" — they are explicitly telling you not to defer. Do not silently downgrade suggestions or nitpicks to deferred. Do not skip items because they seem minor. The user said all and they mean all.310 - **"pick specific items"** → User will list items by number. Only address those.311 - **"skip"** → Do not fix anything.312313## Phase 5: Fix Pass (Sequential)314315**STOP. Read this entire gate checklist before touching any code file.**316317You are not allowed to edit, write, or modify any source file until every single gate below is TRUE. No exceptions. No "I'll present the report after." No "I'll fix this obvious one while waiting." The user has explicitly asked for this workflow — report first, then approval, then fixes. Violating this order means the user sees changes they never approved.318319**All five gates must be TRUE:**3203211. Every agent has returned or been retried and failed (Phase 3 complete)3222. Compiled report written to disk (Phase 4 step 5)3233. Findings posted as PR comment (Phase 4 step 7)3244. Report presented to user in conversation (Phase 4 step 8)3255. User has responded with their choice — you received an explicit message from the user (Phase 4 step 9)326327**If ANY gate is false, do NOT open, edit, or write any code file. Wait.**328329### Step 5a: Plan fix order3301. Priority order: must-fix → suggestions → nitpicks3312. Group findings touching same function/block (apply together)3323. Report plan before starting333334### Step 5b: Apply fixes sequentially335- Read target file(s) before editing336- Each logical fix or small group = 1 commit with descriptive message337- **Scope guard:** Only change what the finding describes338- **Deferral policy:** You may defer a finding ONLY if the user chose "pick specific items" and did not include it, or if fixing it would require changes to files/systems outside this PR's scope (e.g., database migrations, third-party API changes). Suggestions and nitpicks are not automatically deferrable — they are real findings that the reviewers flagged for a reason. When the user said "address all", treat every category (must-fix, suggestions, nitpicks) with equal obligation.339340### Step 5c: Verify341Run full test suite once after all fixes.342- Pass: proceed to Step 5d343- Fail: identify breaking commit(s), revert, note as "skipped — broke tests"344345### Step 5d: Resolution checklist346347Before pushing, produce a resolution checklist that accounts for EVERY finding in the compiled report. No finding may be omitted — if the compiled report has 14 items, the checklist has 14 entries. Use the same `#N` numbers from the compiled report.348349Each finding gets exactly one disposition:350- **fixed** — code was changed to address this finding351- **intentionally deferred** — not addressed in this PR, with a specific reason (ONLY allowed when user did NOT say "address all")352- **not applicable** — the finding was incorrect, or the code it references doesn't exist / was already changed by another fix353354Present the checklist to the user in conversation BEFORE pushing. The user must see every item and its disposition. If they object to any disposition, revise before pushing.355356**Hard rule:** The total number of items across both sections (Fixed + Unresolved) MUST equal the total findings count from the compiled report. If they don't match, you missed something — go back and account for every item.357358### Step 5e: Push and comment3593601. Push all commits3612. Post follow-up PR comment. Use properly formatted markdown tables — header row, separator row (`|---|`), then data rows. Do NOT output raw pipe characters as plain text — the table must render as a formatted table in GitHub and in the terminal.362363 ```bash364 gh pr comment {NUMBER} --body "$(cat <<'EOF'365 ## Review Fixes — Resolution Checklist366367 ### Fixed (N items)368369 | # | Category | Finding | Detail |370 |---|----------|---------|--------|371 | #1 | Must Fix | `file:line` — description | commit abc1234 |372 | #2 | Suggestion | `file:line` — description | commit def5678 |373 | #5 | Nitpick | `file:line` — description | commit ghi9012 |374375 ### Unresolved (N items)376377 | # | Category | Finding | Disposition |378 |---|----------|---------|-------------|379 | #3 | Nitpick | `file:line` — description | **not applicable:** finding was incorrect because X |380 | #4 | Suggestion | `file:line` — description | **deferred:** requires database migration outside PR scope |381382 **Total: T findings** — X fixed, Y not applicable, Z deferred383384 *All changes in latest push*385 EOF386 )"387 ```388389 The **Unresolved** table keeps the original `#N` index from the compiled report so the user can instantly cross-reference what was skipped and why. If everything was fixed, write "### Unresolved (0 items)" with "None" underneath — do not omit the section.