Two-Pass Review
Protocol
Pass 1 — Review
Spawn the code-reviewer agent with:
- Artifact: the file(s) or diff to review
- Criteria: what to review against
- Scope: what's in-bounds
- Output: Return a
ReviewOutput; set every finding's validated_by to reviewer, leave verdict and evidence null, and list evaluated criteria and paths in checks_run.
Auto-progression:
Pass 2 — Verify
Spawn the verifier agent with:
- Artifact: same as Pass 1
- Findings: the reviewer's full
Finding array
- Criteria: same as Pass 1
- Output: Return a
ReviewOutput with the full findings array and populated checks_run.
- Verdicts: Set every finding to
confirmed, demoted, or rejected and provide evidence.
- Severity: Adjust severity up under
confirmed or down under demoted.
- Validation: Set every finding's
validated_by to verifier.
- Boundary: Verify only Pass 1 findings; do not add findings.
Present to user
Report in this shape:
**Two-pass review results:**
- P0/P1 findings: [id: title — confirmed | demoted Px→Py | promoted Px→Py — evidence]
- Summary: [X] of [Y] P0/P1 confirmed, [W] demoted, [Z] rejected
- P2/P3 (FYI): [id: title — verdict]
- Disagreement: [none | reviewer/verifier split — rejected findings and verifier reasoning]
- Empty result: Write
None — zero P0/P1 findings after both passes when the P0/P1 list is empty.
- Severity changes: Mark each demotion (
demoted P0 → P1) and promotion (promoted P2 → P1).
- All rejected: Report zero confirmed P0/P1 findings, populate Disagreement with the rejected findings and verifier reasoning, and stop without another automatic review.
- Visibility: Hide rejected findings outside the all-rejected case and unverified P2/P3 findings unless the user asks.
Output Schema
Finding
Finding {
id: sequential number starting from 1,
severity: "P0" | "P1" | "P2" | "P3",
title: short title,
body: detailed explanation with evidence,
file: file path or null for global issues,
line_start: number or null,
line_end: number or null,
confidence: 0.0-1.0,
criterion: what was violated,
verdict: "confirmed" | "demoted" | "rejected" | null,
validated_by: "reviewer" | "verifier" | "machine" | null,
evidence: reasoning for verdict | null
}
ReviewOutput
Findings are wrapped in a ReviewOutput envelope:
ReviewOutput {
schema_version: "v1",
findings: Finding[],
checks_run: string[]
}
Severity calibration
- P0 — Must fix: breaks functionality, security breach, data loss, or violates criteria
- P1 — Fix before shipping: correct but incomplete, fragile, or reliability risk
- P2 — Should fix: quality issue, code smell, not blocking
- P3 — Nice to have: observation, style, minor improvement
Field notes
confidence — 1.0 means certain, below 0.5 means you're guessing. Be honest.
criterion — required for P0/P1 findings. Name the specific criterion violated.
verdict — initial reviewers set null; verifiers populate it after adjudication. A caller may set confirmed when routing an observed failure with honest validated_by and evidence values.
validated_by — reviewer means initial review only; verifier means independent verification; machine requires the exact check and observed failure. Missing or null means unverified.
- A machine result proves only the observed failure, not an inferred cause.
evidence — reasoning or an exact observed result supporting the verdict; use null before adjudication.
checks_run — list every criterion evaluated, file path checked, or acceptance criterion verified. For ACs, use AC-NNN-XX: PASS — [evidence] or AC-NNN-XX: FAIL — [reason].
1---2name: two-pass-review3description: Two-pass code review — a review pass hardened by an adversarial verification pass that suppresses false positives. TRIGGER when: user wants final review of completed code changes; any review where a false positive would cost real time. SKIP when: reviewing a non-code artifact (reviewer); a quick spot-check during iteration.4---56# Two-Pass Review78## Protocol910### Pass 1 — Review1112Spawn the `code-reviewer` agent with:13- **Artifact**: the file(s) or diff to review14- **Criteria**: what to review against15- **Scope**: what's in-bounds16- **Output**: Return a `ReviewOutput`; set every finding's `validated_by` to `reviewer`, leave `verdict` and `evidence` null, and list evaluated criteria and paths in `checks_run`.1718**Auto-progression:**19- Zero P0/P1 findings → terminate after Pass 1 and present the clean result in this shape:20 ```21 **Review result — clean:**22 - Checks run: [criterion / file path checked, one per line]23 - P0/P1 findings: none24 ```25- One or more P0/P1 findings → proceed automatically to Pass 2. No user prompt.2627### Pass 2 — Verify2829Spawn the `verifier` agent with:30- **Artifact**: same as Pass 131- **Findings**: the reviewer's full `Finding` array32- **Criteria**: same as Pass 133- **Output**: Return a `ReviewOutput` with the full findings array and populated `checks_run`.34 - **Verdicts**: Set every finding to `confirmed`, `demoted`, or `rejected` and provide evidence.35 - **Severity**: Adjust severity up under `confirmed` or down under `demoted`.36 - **Validation**: Set every finding's `validated_by` to `verifier`.37 - **Boundary**: Verify only Pass 1 findings; do not add findings.3839### Present to user4041Report in this shape:4243```44**Two-pass review results:**45- P0/P1 findings: [id: title — confirmed | demoted Px→Py | promoted Px→Py — evidence]46- Summary: [X] of [Y] P0/P1 confirmed, [W] demoted, [Z] rejected47- P2/P3 (FYI): [id: title — verdict]48- Disagreement: [none | reviewer/verifier split — rejected findings and verifier reasoning]49```5051- **Empty result:** Write `None — zero P0/P1 findings after both passes` when the P0/P1 list is empty.52- **Severity changes:** Mark each demotion (`demoted P0 → P1`) and promotion (`promoted P2 → P1`).53- **All rejected:** Report zero confirmed P0/P1 findings, populate Disagreement with the rejected findings and verifier reasoning, and stop without another automatic review.54- **Visibility:** Hide rejected findings outside the all-rejected case and unverified P2/P3 findings unless the user asks.5556---5758## Output Schema5960<!-- source: references/finding-schema.md#output-schema -->6162### Finding6364```65Finding {66 id: sequential number starting from 1,67 severity: "P0" | "P1" | "P2" | "P3",68 title: short title,69 body: detailed explanation with evidence,70 file: file path or null for global issues,71 line_start: number or null,72 line_end: number or null,73 confidence: 0.0-1.0,74 criterion: what was violated,75 verdict: "confirmed" | "demoted" | "rejected" | null,76 validated_by: "reviewer" | "verifier" | "machine" | null,77 evidence: reasoning for verdict | null78}79```8081### ReviewOutput8283Findings are wrapped in a `ReviewOutput` envelope:8485```86ReviewOutput {87 schema_version: "v1",88 findings: Finding[],89 checks_run: string[]90}91```9293### Severity calibration9495- **P0** — Must fix: breaks functionality, security breach, data loss, or violates criteria96- **P1** — Fix before shipping: correct but incomplete, fragile, or reliability risk97- **P2** — Should fix: quality issue, code smell, not blocking98- **P3** — Nice to have: observation, style, minor improvement99100### Field notes101102- `confidence` — 1.0 means certain, below 0.5 means you're guessing. Be honest.103- `criterion` — required for P0/P1 findings. Name the specific criterion violated.104- `verdict` — initial reviewers set `null`; verifiers populate it after adjudication. A caller may set `confirmed` when routing an observed failure with honest `validated_by` and `evidence` values.105- `validated_by` — `reviewer` means initial review only; `verifier` means independent verification; `machine` requires the exact check and observed failure. Missing or `null` means unverified.106- A machine result proves only the observed failure, not an inferred cause.107- `evidence` — reasoning or an exact observed result supporting the verdict; use `null` before adjudication.108- `checks_run` — list every criterion evaluated, file path checked, or acceptance criterion verified. For ACs, use `AC-NNN-XX: PASS — [evidence]` or `AC-NNN-XX: FAIL — [reason]`.109110<!-- /source: references/finding-schema.md#output-schema -->