Deep Review
Path convention: ./references/… below is relative to this skill's own base directory —
announced as "Base directory for this skill" when the skill is invoked. A Bash tool call's working
directory is the user's project, not the skill directory, so prefix these with that base directory
when reading them. Paths written without the leading ./ refer to the target project being
reviewed, or — where the text names the owning plugin, as with adversarial-review's
scripts/gemini-review.sh — to that plugin's own directory, not to this skill.
A two-phase convergence harness for high-assurance review of a changeset. Phase 1 drives
specialized reviewers in fix->re-review rounds until they stop finding actionable issues. Phase 2
runs an adversarial Claude<->Gemini cross-examination so only findings the opposing model confirms
survive. The output is a changeset that passed both a depth gauntlet and a cross-model gauntlet,
with every confirmed issue fixed and verified.
Announce at start: "Using deep-review to run iterative + adversarial review to convergence."
When to use
- The user wants more than a single review pass — they want convergence ("until it's clean").
- High-stakes changes (security-sensitive, load-bearing guards, release candidates).
- The user explicitly asks for adversarial / multi-model / Gemini review.
Not for: a quick one-shot look (use /pr-review-toolkit:review-pr alone) or a trivial diff.
Arguments
/deep-review # auto: PR diff if branch has an open PR, else working-tree vs base
/deep-review <PR#> # target a specific PR
/deep-review local # force working-tree-vs-base mode
/deep-review --phase1-only # iterative review only (skip adversarial)
/deep-review --phase2-only # adversarial only (skip iterative)
/deep-review --max-rounds N # cap Phase-1 rounds (default 4)
Prerequisites & composition
This skill ORCHESTRATES two existing capabilities; it does not reimplement them:
- Phase 1 uses the
pr-review-toolkit reviewer sub-agents
(pr-review-toolkit:code-reviewer, :pr-test-analyzer, :silent-failure-hunter,
:type-design-analyzer, :comment-analyzer). If that plugin is absent, fall back to the
feature-dev:code-reviewer / Explore agents or a general-purpose reviewer with the same
per-dimension prompts.
- Phase 2 uses the
adversarial-review skill's engine + agents
(adversarial-review:adversarial-bug-hunter, :adversarial-convention-reviewer,
:adversarial-cross-examiner, and scripts/gemini-review.sh). If that plugin is absent, run the
pipeline manually per the steps below.
Discover whether they're installed before relying on them; degrade with a stated fallback, never
silently skip a phase.
Phase 0 — Scope
- Establish repo + change scope:
git branch --show-current; find an open PR for the branch (gh pr list --head <branch>).
- Default base = the PR base, else the repo default branch (
develop/main).
- Build the diff:
git diff <base>...HEAD (PR mode) or git diff <base> (local mode). Exclude generated/derived artifacts (e.g. rendered *.html, lockfiles, build output) from the diff handed to reviewers — review their source instead, as a single-line source change can inflate the diff with hundreds of KB of generated output and waste reviewer budget.
- Enumerate changed files and classify (code / tests / docs / config). This drives which
reviewers are applicable.
- Include out-of-tree artifacts that are part of the same change-set if the user mentions
them (e.g. live runtime config, instruction files not tracked in the repo). Reviewers should
judge the whole change, not just what git shows.
- Give every reviewer the intent context that isn't obvious from the diff (e.g. "this module
is deliberately retired", "this file is the live regression guard"). Grounding context prevents
wasted cycles re-flagging intentional decisions — but never use it to suppress a real defect.
- Record any environment or toolchain coverage gaps relevant to the diff. If a portability
concern depends on a toolchain the review host cannot execute (for example GNU
tar or gawk
behaviour from a macOS/BSD environment), label it explicitly as not executed locally and
deferred to CI — after confirming a CI job actually covers that environment
(ls .github/workflows, check the job's runs-on). If none does, label it UNCOVERED, not
deferred. Recommend a concrete cross-platform check when feasible (gtar, gawk, or a
Linux container), and never treat the local suite as covering the unavailable environment.
Phase 1 — Iterative review to convergence
Loop until a full round produces zero actionable (Critical/Important) issues from every
dimension AND the previous round's fixes introduced nothing new.
Each round
- Dispatch applicable reviewers in parallel (one message, multiple agents). Map dimensions to
the changed files: always run general code review; add test-coverage if tests changed,
silent-failure if error handling/guards changed, type-design if types added, comment/doc if
docs/comments changed. Each reviewer gets: the diff command, the file list, repo read access,
the intent context, and an instruction to return findings grouped CRITICAL / IMPORTANT /
SUGGESTION with file:line + concrete fix, and to say so plainly if clean — do not invent
issues to seem thorough.
- Aggregate. Deduplicate convergent findings (multiple reviewers flagging the same thing ->
higher confidence). Note which are factual vs judgment calls.
- Fix all Critical/Important via a single implementer sub-agent given the exact,
numbered fix spec (read-then-edit in its own context; this also sidesteps any parent-side
router restrictions on Read/Edit). Address cheap Suggestions too when they reduce future review
noise. The implementer must verify empirically — run the tests, and for any new guard/check,
prove it fails-first (a planted-regression that would pass even when the code is broken is a
silent defect; see Red Flags). Do not commit per-round by default — checkpoint at phase end to
avoid preflight churn. Before advancing to the re-review, verify the implementer's claims against ground truth in your own context per
./references/delegated-verification.md — a sub-agent can report "done" without writing, or "committed" with only a subset of files. A failed verification is a failure, not a silent retry.
- Re-review (next round). Re-query the same reviewers (continuing them via SendMessage
preserves their codebase context) with TWO asks: (a) verify each prior finding is actually
resolved against the new diff — not assumed; (b) check whether the fixes introduced any new
bug, inconsistency, or regression. A reviewer replies either with new CRITICAL/IMPORTANT items
or "CONVERGED — no actionable issues."
- Converge or iterate. If all dimensions report CONVERGED -> Phase 1 done. Else apply the new
fixes and run another round. Respect
--max-rounds (default 4); if not converged at the cap,
surface the remaining items to the user rather than looping forever.
Phase 1 convergence is real only when
- Every dimension returned CONVERGED in the SAME round, and
- That round was a re-review after the latest fixes (so "converged" reflects the current tree),
and
- Fixes were verified by running tests/build, not by inspection alone — except concerns explicitly
recorded under Phase 0 step 5 as not executable locally, recorded during Phase 0, before any fix
round (a concern added to that list after a fix cannot retroactively excuse it), which converge
as deferred to CI (or UNCOVERED) rather than as verified.
Commit Phase 1 with a clear message summarizing rounds + classes of issues fixed. Follow the
repo's commit discipline (run any preflight; if a hook requires preflight and commit as separate
calls, do so; respect changelog/branch rules).
Phase 2 — Multi-round Gemini-primary adversarial review
Goal: cross-model confirmation. A finding only "survives" when the opposing model confirms it;
single-model findings are retained as UNCONFIRMED, never silently dropped.
Step 2.0 — Ensure the adversary (Gemini)
Run the adversarial-review skill's ensure-gemini.sh --check (or check command -v gemini +
whether ~/.gemini/.env has GEMINI_API_KEY). Interactive Google login is NOT sufficient —
headless calls need an API key.
- If Gemini is installed + headless-authed -> proceed.
- If not -> PROMPT THE USER at runtime (this skill's chosen policy): offer to (a) install/auth
Gemini now (
npm i -g @google/gemini-cli; add GEMINI_API_KEY=<key> to ~/.gemini/.env), or
(b) proceed Claude-only (self-cross-examination: a second independent Claude agent judges the
first's findings) with a loud banner that cross-model confirmation was skipped. Do not decide
silently.
Step 2.1 — R1: blind parallel discovery
In one message, launch (none seeing the others):
- Claude bug-hunter (opus) — bugs/security/perf/correctness, grounded in source.
- Claude convention-reviewer (sonnet) — convention/maintainability/doc-drift.
- Gemini finder — run a direct
gemini -m gemini-2.5-pro -p "<brief + diff>" call (build a
prompt file combining the review brief and the diff; parse the JSON findings array from stdout).
NOTE: the adversarial-review plugin's scripts/gemini-review.sh is R2-judge-only (--diff <file> --findings <r1.json> [--model <m>] [--out <r2.json>]) — it has NO discovery/--mode find mode, so do NOT use it for
R1.
Give all the byte-identical diff (same-diff invariant). Merge Claude findings -> C-001..;
Gemini -> G-001... Emit an R1 digest (counts by severity/category). An empty findings array is a
respectable, valid answer.
Step 2.2 — R2: symmetric cross-examination
In one message:
- Claude cross-examiner (opus) judges every Gemini finding ->
confirm|refute with reason,
grounded in the current source (findings can be stale if Phase 1 already fixed them).
- Gemini judges every Claude finding (
gemini-review.sh --diff <DIFF> --findings <claude-r1.json> [--out <r2.json>]).
- Reliability note: the wrapper fails open to nothing if Gemini's JSON lacks
verdicts
(observed: ADVERSARY_UNAVAILABLE: ... missing verdicts key -> empty result). Fall back to a
direct gemini -m gemini-2.5-pro -p "<brief + each Claude finding, ask for JSON {id, verdict:confirm|refute, reason}>" call (same approach R1 uses) and parse it yourself; treat
the direct call as primary, the wrapper as convenience.
Emit an R2 digest (confirmed/refuted/unjudged each direction).
Step 2.3 — R3: counter-round (the "let the primary counter" round)
This is what makes it >=3 rounds and forces genuine convergence rather than a stalemate:
- For each finding the opponent refuted, send it back to the originator to concede or
defend, grounded in source. Feed the refuter's reason and the relevant current file facts.
- Settle factual disputes with direct evidence, not opinion. If one model claims "X already
exists / the catch is empty / the name has a space", run the actual
grep/read and put the
evidence in front of both. Evidence ends the dispute (in this skill's origin run, a grep of
all check-name assignments settled a naming dispute and the primary conceded).
- A judgment-call disagreement (e.g. keep-vs-delete dead code) can be legitimately defended by
either side on its real merits — if it stays split after evidence, escalate it to the user as an
explicit decision rather than forcing a verdict.
Step 2.4 — Converge (survivor rule)
| Finding origin |
Survives when |
| Claude (C-NNN) |
Gemini confirms (R2), or concedes its refutation (R3) |
| Gemini (G-NNN) |
Claude confirms (R2), or concedes its refutation (R3) |
- Survivors — both models agree -> fix them.
- Unconfirmed — opponent abstained -> report, fix at discretion.
- Rejected — opponent refuted and originator conceded -> record with reason; do not fix.
If the adversarial-review skill is installed, synthesize.py applies this rule; otherwise apply it
by hand and print survivors / unconfirmed / rejected counts.
Step 2.5 — Fix survivors + finalize
Fix all survivors via an implementer sub-agent (same verify-empirically discipline as Phase 1).
Before finalizing, verify the implementer's fixes against ground truth in your own context per ./references/delegated-verification.md — never trust the sub-agent's narration that the survivors were fixed.
Then finalize:
- Re-run the full test/build suite; confirm green.
- Sync any deployed/derived artifacts the change affects (e.g. re-run an installer that copies
a test suite to a runtime location; regenerate a generated doc/architecture page). A repo's own
CLAUDE.md often mandates this in the same change-set.
- Commit Phase 2 with a message naming the survivors and noting what the adversarial pass
dismissed (and why). Push; if the repo polls CI after push, check it.
Final report
Summarize for the user:
- Phase 1: rounds run, count + classes of issues found and fixed, convergence confirmation.
- Phase 2: R1 counts, what survived cross-examination, what was dismissed and why, any unresolved
judgment call escalated to them.
- Verification evidence (test results, exit codes), commits/SHAs, push + CI status.
- Portability concerns that were not executable locally: for each, either the exact CI/toolchain
coverage it was deferred to, or an explicit UNCOVERED marker when no CI job covers that
environment — plus any concrete command recommended for pre-CI reproduction.
Red Flags — do not
- Declare convergence without a re-review after the last fix. "Converged" must reflect the
current tree, in a round that ran after the fixes.
- Trust a finding-resolved claim without checking the diff. Re-review verifies against source,
not memory. Likewise, a reviewer judging stale findings must read the current file.
- Accept a planted-regression test that can pass vacuously. Every new guard/check needs a
fail-first negative: confirm the assertion FAILS when the code is broken. A test asserting on a
static string that's always present is the classic vacuous trap.
- Accept an "expect nothing" assertion with no positive control. An absent-pattern fixture
catches a guard stuck ON; only a present-pattern fixture catches one stuck OFF, where "correctly
reports nothing" and "hardcoded empty" produce the same green. (Downstream side effects can
sometimes tell them apart — assert on what the code was supposed to write, not only on what it
reported.) Require both directions for any detector or guard, and prefer proving it by mutation —
patch the guard to
false &&, confirm the suite goes red — over inspection. Fixture
reachability is a third axis, independent of both: a fixture that cannot reach the failing half
yields a green assertion over an uncovered path, so check that each assertion's fixture can
actually express the failure, not merely that the assertion exists.
- Let the adversarial pass rubber-stamp. The point is the opposing model. If running
Claude-only, use a genuinely independent second agent and say cross-model confirmation was
skipped.
- Silently drop a single-model finding. Retain as UNCONFIRMED.
- Force a verdict on a genuine judgment call. Escalate keep-vs-delete / design-taste splits to
the user.
- Fix in the parent context. Dispatch an implementer sub-agent (clean context, no router
friction); the parent orchestrates.
- Skip syncing deployed artifacts after changing a suite/config the runtime consumes.
- Imply portability coverage from an unavailable toolchain. A green BSD/macOS run does not
verify GNU/Linux behaviour (or vice versa). State what was not executed, defer that concern to the
matching CI job (or mark it UNCOVERED when no such job exists), and recommend a concrete
alternate-toolchain check where possible.
- Hand a fix to re-review without self-checking it. A new guard needs its planted-regression in the same edit; retiring/disabling/renaming code needs a sweep of every descriptor string (manifest, README tagline, comments), not just the banner — don't let the next round be the first to catch your fix's new gap.
Integration
pr-review-toolkit:review-pr — the per-dimension reviewers Phase 1 drives.
adversarial-review:adversarial-review — the Claude<->Gemini engine Phase 2 drives.
- Repo
CLAUDE.md — commit/branch/preflight discipline and any "keep X in sync" mandates.
1---2name: deep-review3description: Use when the user wants a thorough, high-assurance review of code changes — phrases like "review this until it's clean", "converge to zero issues", "adversarial review", "have Gemini and Claude review", "deep review this PR", or "make this change ironclad". Runs TWO phases on a PR or working-tree diff: (1) iterative multi-reviewer review that loops fix->re-review until a round finds zero actionable issues, then (2) a multi-round Gemini-primary adversarial cross-examination (Gemini finds -> Claude judges -> Gemini counters), fixing every confirmed finding. Repeatable across any project/PR. Use when: (1) the user wants a thorough, high-assurance review that converges to zero actionable issues, (2) the user asks for an adversarial or Gemini-and-Claude cross-examination review of a code diff, (3) deep-reviewing a PR or working-tree diff before merge, (4) the user wants to make a change ironclad.4---56# Deep Review78> **Path convention:** `./references/…` below is relative to this skill's own base directory —9> announced as "Base directory for this skill" when the skill is invoked. A Bash tool call's working10> directory is the user's project, not the skill directory, so prefix these with that base directory11> when reading them. Paths written without the leading `./` refer to the **target project** being12> reviewed, or — where the text names the owning plugin, as with `adversarial-review`'s13> `scripts/gemini-review.sh` — to that plugin's own directory, not to this skill.1415A two-phase convergence harness for high-assurance review of a changeset. Phase 1 drives16specialized reviewers in fix->re-review rounds until they stop finding actionable issues. Phase 217runs an adversarial Claude<->Gemini cross-examination so only findings the *opposing* model confirms18survive. The output is a changeset that passed both a depth gauntlet and a cross-model gauntlet,19with every confirmed issue fixed and verified.2021**Announce at start:** "Using deep-review to run iterative + adversarial review to convergence."2223## When to use2425- The user wants more than a single review pass — they want *convergence* ("until it's clean").26- High-stakes changes (security-sensitive, load-bearing guards, release candidates).27- The user explicitly asks for adversarial / multi-model / Gemini review.2829Not for: a quick one-shot look (use `/pr-review-toolkit:review-pr` alone) or a trivial diff.3031## Arguments3233```34/deep-review # auto: PR diff if branch has an open PR, else working-tree vs base35/deep-review <PR#> # target a specific PR36/deep-review local # force working-tree-vs-base mode37/deep-review --phase1-only # iterative review only (skip adversarial)38/deep-review --phase2-only # adversarial only (skip iterative)39/deep-review --max-rounds N # cap Phase-1 rounds (default 4)40```4142## Prerequisites & composition4344This skill ORCHESTRATES two existing capabilities; it does not reimplement them:4546- **Phase 1** uses the `pr-review-toolkit` reviewer sub-agents47 (`pr-review-toolkit:code-reviewer`, `:pr-test-analyzer`, `:silent-failure-hunter`,48 `:type-design-analyzer`, `:comment-analyzer`). If that plugin is absent, fall back to the49 `feature-dev:code-reviewer` / `Explore` agents or a `general-purpose` reviewer with the same50 per-dimension prompts.51- **Phase 2** uses the `adversarial-review` skill's engine + agents52 (`adversarial-review:adversarial-bug-hunter`, `:adversarial-convention-reviewer`,53 `:adversarial-cross-examiner`, and `scripts/gemini-review.sh`). If that plugin is absent, run the54 pipeline manually per the steps below.5556Discover whether they're installed before relying on them; degrade with a stated fallback, never57silently skip a phase.5859---6061## Phase 0 — Scope62631. Establish repo + change scope:64 - `git branch --show-current`; find an open PR for the branch (`gh pr list --head <branch>`).65 - Default base = the PR base, else the repo default branch (`develop`/`main`).66 - Build the diff: `git diff <base>...HEAD` (PR mode) or `git diff <base>` (local mode). Exclude generated/derived artifacts (e.g. rendered `*.html`, lockfiles, build output) from the diff handed to reviewers — review their source instead, as a single-line source change can inflate the diff with hundreds of KB of generated output and waste reviewer budget.672. Enumerate changed files and classify (code / tests / docs / config). This drives which68 reviewers are applicable.693. **Include out-of-tree artifacts that are part of the same change-set** if the user mentions70 them (e.g. live runtime config, instruction files not tracked in the repo). Reviewers should71 judge the *whole* change, not just what git shows.724. Give every reviewer the **intent context** that isn't obvious from the diff (e.g. "this module73 is deliberately retired", "this file is the live regression guard"). Grounding context prevents74 wasted cycles re-flagging intentional decisions — but never use it to suppress a real defect.755. Record any **environment or toolchain coverage gaps** relevant to the diff. If a portability76 concern depends on a toolchain the review host cannot execute (for example GNU `tar` or `gawk`77 behaviour from a macOS/BSD environment), label it explicitly as **not executed locally** and78 **deferred to CI** — after confirming a CI job actually covers that environment79 (`ls .github/workflows`, check the job's `runs-on`). If none does, label it **UNCOVERED**, not80 deferred. Recommend a concrete cross-platform check when feasible (`gtar`, `gawk`, or a81 Linux container), and never treat the local suite as covering the unavailable environment.8283---8485## Phase 1 — Iterative review to convergence8687Loop until a full round produces **zero actionable (Critical/Important) issues from every88dimension** AND the previous round's fixes introduced nothing new.8990### Each round91921. **Dispatch applicable reviewers in parallel** (one message, multiple agents). Map dimensions to93 the changed files: always run general code review; add test-coverage if tests changed,94 silent-failure if error handling/guards changed, type-design if types added, comment/doc if95 docs/comments changed. Each reviewer gets: the diff command, the file list, repo read access,96 the intent context, and an instruction to **return findings grouped CRITICAL / IMPORTANT /97 SUGGESTION with file:line + concrete fix**, and to **say so plainly if clean — do not invent98 issues to seem thorough.**992. **Aggregate.** Deduplicate convergent findings (multiple reviewers flagging the same thing ->100 higher confidence). Note which are factual vs judgment calls.1013. **Fix** all Critical/Important via a single **implementer sub-agent** given the exact,102 numbered fix spec (read-then-edit in its own context; this also sidesteps any parent-side103 router restrictions on Read/Edit). Address cheap Suggestions too when they reduce future review104 noise. The implementer must **verify empirically** — run the tests, and for any new guard/check,105 **prove it fails-first** (a planted-regression that would pass even when the code is broken is a106 silent defect; see Red Flags). Do not commit per-round by default — checkpoint at phase end to107 avoid preflight churn. Before advancing to the re-review, verify the implementer's claims against ground truth in *your own* context per `./references/delegated-verification.md` — a sub-agent can report "done" without writing, or "committed" with only a subset of files. A failed verification is a failure, not a silent retry.1084. **Re-review (next round).** Re-query the same reviewers (continuing them via SendMessage109 preserves their codebase context) with TWO asks: (a) verify each prior finding is *actually*110 resolved against the new diff — not assumed; (b) check whether the fixes **introduced** any new111 bug, inconsistency, or regression. A reviewer replies either with new CRITICAL/IMPORTANT items112 or "CONVERGED — no actionable issues."1135. **Converge or iterate.** If all dimensions report CONVERGED -> Phase 1 done. Else apply the new114 fixes and run another round. Respect `--max-rounds` (default 4); if not converged at the cap,115 surface the remaining items to the user rather than looping forever.116117### Phase 1 convergence is real only when118119- Every dimension returned CONVERGED in the SAME round, and120- That round was a re-review *after* the latest fixes (so "converged" reflects the current tree),121 and122- Fixes were verified by running tests/build, not by inspection alone — except concerns explicitly123 recorded under Phase 0 step 5 as not executable locally, **recorded during Phase 0, before any fix124 round** (a concern added to that list after a fix cannot retroactively excuse it), which converge125 as *deferred to CI* (or *UNCOVERED*) rather than as verified.126127Commit Phase 1 with a clear message summarizing rounds + classes of issues fixed. Follow the128repo's commit discipline (run any preflight; if a hook requires preflight and commit as separate129calls, do so; respect changelog/branch rules).130131---132133## Phase 2 — Multi-round Gemini-primary adversarial review134135Goal: cross-model confirmation. A finding only "survives" when the *opposing* model confirms it;136single-model findings are retained as UNCONFIRMED, never silently dropped.137138### Step 2.0 — Ensure the adversary (Gemini)139140Run the adversarial-review skill's `ensure-gemini.sh --check` (or check `command -v gemini` +141whether `~/.gemini/.env` has `GEMINI_API_KEY`). **Interactive Google login is NOT sufficient** —142headless calls need an API key.143144- If Gemini is installed + headless-authed -> proceed.145- **If not -> PROMPT THE USER at runtime** (this skill's chosen policy): offer to (a) install/auth146 Gemini now (`npm i -g @google/gemini-cli`; add `GEMINI_API_KEY=<key>` to `~/.gemini/.env`), or147 (b) proceed Claude-only (self-cross-examination: a second independent Claude agent judges the148 first's findings) with a loud banner that cross-model confirmation was skipped. Do not decide149 silently.150151### Step 2.1 — R1: blind parallel discovery152153In one message, launch (none seeing the others):154- Claude bug-hunter (opus) — bugs/security/perf/correctness, grounded in source.155- Claude convention-reviewer (sonnet) — convention/maintainability/doc-drift.156- Gemini finder — run a direct `gemini -m gemini-2.5-pro -p "<brief + diff>"` call (build a157 prompt file combining the review brief and the diff; parse the JSON findings array from stdout).158 NOTE: the adversarial-review plugin's `scripts/gemini-review.sh` is R2-**judge-only** (`--diff <file> --findings <r1.json>159 [--model <m>] [--out <r2.json>]`) — it has NO discovery/`--mode find` mode, so do NOT use it for160 R1.161162Give all the **byte-identical diff** (same-diff invariant). Merge Claude findings -> `C-001..`;163Gemini -> `G-001..`. Emit an R1 digest (counts by severity/category). An empty findings array is a164respectable, valid answer.165166### Step 2.2 — R2: symmetric cross-examination167168In one message:169- Claude cross-examiner (opus) judges every Gemini finding -> `confirm|refute` with reason,170 grounded in the **current** source (findings can be stale if Phase 1 already fixed them).171- Gemini judges every Claude finding (`gemini-review.sh --diff <DIFF> --findings <claude-r1.json> [--out <r2.json>]`).172 - **Reliability note:** the wrapper fails open to nothing if Gemini's JSON lacks `verdicts`173 (observed: `ADVERSARY_UNAVAILABLE: ... missing verdicts key` -> empty result). Fall back to a174 direct `gemini -m gemini-2.5-pro -p "<brief + each Claude finding, ask for JSON {id,175 verdict:confirm|refute, reason}>"` call (same approach R1 uses) and parse it yourself; treat176 the direct call as primary, the wrapper as convenience.177178Emit an R2 digest (confirmed/refuted/unjudged each direction).179180### Step 2.3 — R3: counter-round (the "let the primary counter" round)181182This is what makes it >=3 rounds and forces genuine convergence rather than a stalemate:183- For each finding the opponent **refuted**, send it back to the originator to **concede or184 defend**, grounded in source. Feed the refuter's reason and the relevant current file facts.185- **Settle factual disputes with direct evidence, not opinion.** If one model claims "X already186 exists / the catch is empty / the name has a space", run the actual `grep`/read and put the187 evidence in front of both. Evidence ends the dispute (in this skill's origin run, a `grep` of188 all check-name assignments settled a naming dispute and the primary conceded).189- A judgment-call disagreement (e.g. keep-vs-delete dead code) can be legitimately *defended* by190 either side on its real merits — if it stays split after evidence, escalate it to the user as an191 explicit decision rather than forcing a verdict.192193### Step 2.4 — Converge (survivor rule)194195| Finding origin | Survives when |196|---|---|197| Claude (C-NNN) | Gemini confirms (R2), or concedes its refutation (R3) |198| Gemini (G-NNN) | Claude confirms (R2), or concedes its refutation (R3) |199200- **Survivors** — both models agree -> fix them.201- **Unconfirmed** — opponent abstained -> report, fix at discretion.202- **Rejected** — opponent refuted and originator conceded -> record with reason; do not fix.203204If the adversarial-review skill is installed, `synthesize.py` applies this rule; otherwise apply it205by hand and print `survivors / unconfirmed / rejected` counts.206207### Step 2.5 — Fix survivors + finalize208209Fix all survivors via an implementer sub-agent (same verify-empirically discipline as Phase 1).210Before finalizing, verify the implementer's fixes against ground truth in *your own* context per `./references/delegated-verification.md` — never trust the sub-agent's narration that the survivors were fixed.211Then finalize:212- Re-run the full test/build suite; confirm green.213- **Sync any deployed/derived artifacts** the change affects (e.g. re-run an installer that copies214 a test suite to a runtime location; regenerate a generated doc/architecture page). A repo's own215 CLAUDE.md often mandates this in the same change-set.216- Commit Phase 2 with a message naming the survivors and noting what the adversarial pass217 dismissed (and why). Push; if the repo polls CI after push, check it.218219---220221## Final report222223Summarize for the user:224- Phase 1: rounds run, count + classes of issues found and fixed, convergence confirmation.225- Phase 2: R1 counts, what survived cross-examination, what was dismissed and why, any unresolved226 judgment call escalated to them.227- Verification evidence (test results, exit codes), commits/SHAs, push + CI status.228- Portability concerns that were not executable locally: for each, either the exact CI/toolchain229 coverage it was deferred to, or an explicit **UNCOVERED** marker when no CI job covers that230 environment — plus any concrete command recommended for pre-CI reproduction.231232## Red Flags — do not233234- **Declare convergence without a re-review after the last fix.** "Converged" must reflect the235 current tree, in a round that ran *after* the fixes.236- **Trust a finding-resolved claim without checking the diff.** Re-review verifies against source,237 not memory. Likewise, a reviewer judging stale findings must read the *current* file.238- **Accept a planted-regression test that can pass vacuously.** Every new guard/check needs a239 fail-first negative: confirm the assertion FAILS when the code is broken. A test asserting on a240 static string that's always present is the classic vacuous trap.241- **Accept an "expect nothing" assertion with no positive control.** An absent-pattern fixture242 catches a guard stuck ON; only a present-pattern fixture catches one stuck OFF, where "correctly243 reports nothing" and "hardcoded empty" produce the same green. (Downstream side effects can244 sometimes tell them apart — assert on what the code was supposed to *write*, not only on what it245 reported.) Require both directions for any detector or guard, and prefer proving it by mutation —246 patch the guard to `false &&`, confirm the suite goes red — over inspection. **Fixture247 reachability is a third axis, independent of both:** a fixture that cannot reach the failing half248 yields a green assertion over an uncovered path, so check that each assertion's fixture can249 actually express the failure, not merely that the assertion exists.250- **Let the adversarial pass rubber-stamp.** The point is the *opposing* model. If running251 Claude-only, use a genuinely independent second agent and say cross-model confirmation was252 skipped.253- **Silently drop a single-model finding.** Retain as UNCONFIRMED.254- **Force a verdict on a genuine judgment call.** Escalate keep-vs-delete / design-taste splits to255 the user.256- **Fix in the parent context.** Dispatch an implementer sub-agent (clean context, no router257 friction); the parent orchestrates.258- **Skip syncing deployed artifacts** after changing a suite/config the runtime consumes.259- **Imply portability coverage from an unavailable toolchain.** A green BSD/macOS run does not260 verify GNU/Linux behaviour (or vice versa). State what was not executed, defer that concern to the261 matching CI job **(or mark it UNCOVERED when no such job exists)**, and recommend a concrete262 alternate-toolchain check where possible.263- **Hand a fix to re-review without self-checking it.** A new guard needs its planted-regression in the *same* edit; retiring/disabling/renaming code needs a sweep of *every* descriptor string (manifest, README tagline, comments), not just the banner — don't let the next round be the first to catch your fix's new gap.264265## Integration266267- `pr-review-toolkit:review-pr` — the per-dimension reviewers Phase 1 drives.268- `adversarial-review:adversarial-review` — the Claude<->Gemini engine Phase 2 drives.269- Repo `CLAUDE.md` — commit/branch/preflight discipline and any "keep X in sync" mandates.