Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Run pixtuoid's review protocol at either scope — the mandatory pre-merge DIFF gate (2+ differentiated-lens agents on the diff) or a whole-codebase AUDIT (subsystem × factor fan-out over the whole tree). Both draw ONE shared factor taxonomy + verify contract + disposition; they differ only in population and orchestration. Use before merging ANY PR, on 'review this PR/branch' / 'is this ready to merge' (diff scope), or on 'whole-codebase review' / pre-release / periodic audit (whole-codebase scope
.claude/skills/ivanwng97-two-lens-review/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 145% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 78% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 145% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 137% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 84% | 0% |
ONE protocol, two SCOPES over the SAME factors:
the two-lens review" — workspace CLAUDE.md, "Things NOT to do"; PR #23 merged unreviewed with a critical path-traversal). 2+ differentiated-lens agents on the diff, disposition in the PR thread.
an audit scan DIFFERENT populations (fix-introduced-in-one-change vs existing code + cross-PR accumulation), so the audit is a SEPARATE pass, not a bigger PR review — but it runs the same factors, verify contract, and disposition.
The factors, the fill-in-the-slots lens briefs, the five hard requirements, the escalation triggers, AND the whole-codebase fan-out orchestration are all canonical in .github/prompts/pr-review.prompt.md — read it; fill from THAT file, never a paraphrase here (a copy here is the exact two-copies-drift class Lens 2 hunts — when the prompt gains a factor or trigger, a copy here silently lags). This skill owns only when to invoke each scope, how to orchestrate, and the red-flag self-checks.
Diff scope:
exemption — lens count can shrink, the gate can't).
Whole-codebase scope:
sweep; a periodic drift/design-debt pass.
Two agents MINIMUM (diff scope), lenses differentiated (a shared lens makes their misses re-correlate); lens/finder count scales with blast radius (or tree size). The quality lever is never the lens NAME — it's the change-specific checklist filled into the <...> slots, and the FACTOR COVERAGE (no family silently dropped).
two sessions on one tree race on HEAD). Note path, branch, base sha.
its brief from pr-review.prompt.md, <...> slots FILLED with this change's specific claims (a lazily-filled slot turns both reviewers generic). Give each the worktree path + git -C <path> diff <base>..HEAD. Then add an escalation lens for EVERY trigger the prompt's "When two lenses aren't enough" section matches on this change — that trigger→lens list is canonical THERE; don't restate it here (a copy would be the two-copies-drift class the header names — a new trigger added to the prompt must reach reviews without a manual mirror).
toward the lens floor — a one-word summary or "test"/placeholder findings is a STUB (a dispatch, not a review); re-run that lens as a single focused agent (PR #455's a11y lens stubbed under an APPROVE-WITH-NITS aggregate; its re-run caught a real AA failure). Then for every MEDIUM+ finding, verify the premise yourself before coding a fix — reviewers have incomplete design context; read the crate's SHARP-EDGES.md entry first (its CLAUDE.md only INDEXES them — the index line is not the entry; tests/, Raycast and site keep theirs inline in the guide), and if a finding is deliberate design, REFUTE it by citing (or ADDING) that entry.
reviewer-flagged plan-misses as plan-miss: lines in its message.
merging, read the online bot review's LATEST COMMENT verdict (Findings: N) + mergeStateStatus — the review JOB passes even when it posts findings, so the check table alone can't gate (#448). If the bot ERRORED or left no findings comment at HEAD (it can fail on a very large diff — error_max_turns with no comment — or on a spent quota, which the workflow now states itself in an <!-- absent-<marker>:<sha> --> comment; do NOT read that as a review), the gate is unsatisfiable as written: split the PR smaller, else fall back to one extra differentiated lens + owner merge, recorded in the PR thread. State the condition behaviorally (errored/absent), never a fixed LOC ceiling.
The full fan-out template (subsystem finders + whole-tree specialist sweeps → adversarial verify → dedup → ranked report) is the "Whole-codebase scope — orchestration" section of pr-review.prompt.md. In brief:
specialist sweeps (arch-invariants, concurrency/liveness, security, drift — the aggregate-only lenses). Each finder carries the FULL factor checklist. Prefer a Workflow (pipeline per cell); degrade to parallel Agent fan-out.
construct a repro or refute) — a separate skeptic per finding, never the finder self-certifying.
grouped by factor family, KEEPING the refuted-as-deliberate list (coverage proof + sharp-edge context for the next agent).
grep == 0.
Scale to the ask: "any bugs?" → a few finders, single-vote verify; "thoroughly audit / be comprehensive" → larger finder pool, multi-vote adversarial verify, synthesis. Do the involved/cross-crate refactors it surfaces IN-ARC (design-debt lens); defer only genuinely big/refactor work to issues.
Drive every reviewer/finder/bot finding to exactly one terminal state: FIXED · REFUTED-with-trace (cite or ADD the relevant per-crate SHARP-EDGES.md entry, or the guide's inline section where no sibling exists — that keeps the next agent's context accurate) · ISSUE-FILED (no-deferral rule: only big/refactor defers). "Acknowledged, no action" is NOT a state — #40's ignored finding became a 0.4.1 blocker (#46). Diff scope: in the PR thread. Whole-codebase scope: in the ranked report. Sweep at the FINAL merge head — a finding that lands after the local lenses ran is the #283/#383 drop class; and check WHICH commit a bot re-flag was raised against before re-litigating (#316's were stale).
| Thought | Reality | |---------|---------| | "It's a tiny/doc-only PR" | The gate has no size exemption; run it (lens count can shrink, the gate can't). | | "CI is green, that's enough" | CI can't see design, blast radius, drift, or a deliberate-looking real bug. | | "The reviewer said X, so fix X" | Verify the premise first — check sharp edges; a wrong fix contradicts a design decision. | | "One thorough agent is fine" | Two differentiated lenses is the floor; one lens's blind spots go uncaught. | | "I'll note the finding and move on" | Every finding needs a terminal state — dropped findings become release blockers. | | "The diff looks clean, we're done" (audit) | The diff scope can't see drift accumulation / design-debt accretion / arch erosion — those need the whole-codebase pass. | | "The verdict row shows N lenses ran" | Count REAL returns, not dispatches — a stubbed lens under a clean aggregate hid a real AA failure (#455). | | "The bot says it's still broken" | Check WHICH commit it reviewed — #316's re-flags were raised against an old commit; five were already fixed (REFUTED-STALE). | | "The finder found it, report it" (audit) | Findings self-certify nothing — a separate skeptic must try to REFUTE each survivor first. | | "Just unify the duplication" | Some duplication is documented deliberate separation (per-source decoders, per-CLI targets); check the sharp edge before proposing a merge. |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 6,798 | 7,199 | +6% | 1 | 1 | 0% | 1,075 | 2,711 | +152% | 0 | 0 | — |
case-02 | fail→fail | 38,435 | 6,587 | -83% | 1 | 1 | 0% | 6,214 | 2,638 | -58% | 0 | 0 | — |
case-03 | fail→fail | 5,919 | 7,592 | +28% | 1 | 1 | 0% | 326 | 2,662 | +717% | 0 | 0 | — |
case-04 | fail→pass | 9,238 | 6,553 | -29% | 1 | 1 | 0% | 1,355 | 3,324 | +145% | 0 | 0 | — |
case-05 | fail→pass | 10,574 | 4,658 | -56% | 1 | 1 | 0% | 1,693 | 3,021 | +78% | 0 | 0 | — |
case-06 | pass→pass | 8,252 | 4,659 | -44% | 1 | 1 | 0% | 1,216 | 2,953 | +143% | 0 | 0 | — |
case-07 | pass→pass | 10,687 | 3,834 | -64% | 1 | 1 | 0% | 1,439 | 2,876 | +100% | 0 | 0 | — |
case-22 | pass→pass | 3,378 | 2,898 | -14% | 1 | 1 | 0% | 551 | 2,714 | +393% | 0 | 0 | — |
case-08 | fail→pass | 8,146 | 4,318 | -47% | 1 | 1 | 0% | 1,207 | 2,962 | +145% | 0 | 0 | — |
case-09 | fail→pass | 9,004 | 5,920 | -34% | 1 | 1 | 0% | 1,423 | 3,378 | +137% | 0 | 0 | — |
case-10 | pass→pass | 12,684 | 4,456 | -65% | 1 | 1 | 0% | 1,791 | 3,007 | +68% | 0 | 0 | — |
case-11 | fail→pass | 12,025 | 7,123 | -41% | 1 | 1 | 0% | 1,811 | 3,329 | +84% | 0 | 0 | — |
case-12 | fail→pass | 13,429 | 7,450 | -45% | 1 | 1 | 0% | 1,831 | 3,316 | +81% | 0 | 0 | — |
case-13 | pass→pass | 14,272 | 5,132 | -64% | 1 | 1 | 0% | 2,108 | 2,861 | +36% | 0 | 0 | — |
case-14 | pass→pass | 8,759 | 4,559 | -48% | 1 | 1 | 0% | 1,224 | 3,002 | +145% | 0 | 0 | — |
case-15 | fail→pass | 14,961 | 16,168 | +8% | 1 | 1 | 0% | 2,197 | 4,891 | +123% | 0 | 0 | — |
case-16 | pass→pass | 16,549 | 2,090 | -87% | 1 | 1 | 0% | 2,280 | 2,568 | +13% | 0 | 0 | — |
case-17 | fail→pass | 7,714 | 3,368 | -56% | 1 | 1 | 0% | 1,063 | 2,828 | +166% | 0 | 0 | — |
case-18 | pass→pass | 14,522 | 8,946 | -38% | 1 | 1 | 0% | 2,028 | 3,445 | +70% | 0 | 0 | — |
case-19 | fail→pass | 12,574 | 5,528 | -56% | 1 | 1 | 0% | 1,932 | 3,105 | +61% | 0 | 0 | — |
case-20 | pass→pass | 8,114 | 4,481 | -45% | 1 | 1 | 0% | 1,436 | 3,093 | +115% | 0 | 0 | — |
case-21 | pass→pass | 7,911 | 6,312 | -20% | 1 | 1 | 0% | 1,296 | 3,186 | +146% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 19 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +41 percentage points is the difference between those two pass rates over the 19 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.