skills/fix-verify-loop/SKILL.md
Bounded resolver for confirmed P0/P1 findings. For each finding: fix → verify resolution via the verifier agent → up to 2 attempts → escalate. Scoped to per-finding resolution; regressions are the caller's job.
npx skillsauth add preetamnath/agent-skills fix-verify-loopInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
fix-verify-loop is a bounded resolver. Input: confirmed P0/P1 findings. Output: staged code where each listed finding is resolved, OR an escalation list of findings it could not resolve in 2 attempts.
It verifies ONLY per-finding resolution. Regression detection, finding new issues, and reviewing the diff as a whole are explicitly NOT its job — those belong to whoever reviews the diff next (caller's choice).
After a two-pass-review (or any review) produces confirmed P0/P1 findings that need fixing. Also after test failures that need code or test fixes.
Intake filter: Only process findings where verdict = "confirmed" and severity in ["P0", "P1"]. Ignore P2/P3 findings — they are out of scope. Note: findings with verdict: "confirmed" are accepted regardless of source — the caller is responsible for confirmation quality (e.g., plan-runner sets this as an orchestrator escape hatch for per-wave review findings that have no verifier pass).
Pre-gate (findings without an independent verifier pass): A finding requires a verifier pre-gate BEFORE Round 1 if it has not been verifier-validated. Detect via:
evidence field is null or missing, ORevidence field starts with "Orchestrator-confirmed".Confidence is the reviewer or verifier's honest signal — it does not by itself trigger pre-gate. Pre-gate's job is to catch findings that haven't been independently verified, not findings that the verifier already vouched for at low confidence.
For these findings, run this pre-gate first:
verifier agent with: Artifact = the finding's file (or surrounding context), Findings = the single finding, Criteria = "is this finding real?".rejected → adds to dropped bucket → drop the finding from fix-verify-loop. Skip to next finding.confirmed or demoted (still real) → proceed to Round 1 normally.Findings that pass the intake filter and either don't trigger the pre-gate or pass it proceed to Round 1.
Process findings sequentially, one at a time. Do not batch. For each finding, run Round 1; if not resolved, run Round 2; if still not resolved, escalate. Round 1 and Round 2 mirror each other in shape — same fix-then-verify dispatch, same verifier question.
This check fires in Round 1 only, AFTER the fix subagent declares files_changed and BEFORE staging. The fix subagent doesn't know what files it will touch until it runs, so the Round 1 order is: spawn fix → check pre-staged hunks → stage → verify. In Round 2, any pre-existing staged content is from Round 1's prior attempt and not user-authored — the check would fire spuriously, so we skip it. Round 2 order is: spawn fix → stage → verify.
Before staging (Round 1 only):
git diff --staged -- <files the fix will touch> (the files_changed returned by the fix subagent).AskUserQuestion tool with options "Commit pre-existing first", "Stash pre-existing", "Proceed (treat as part of this fix)". Include a one-line summary of what was found (e.g., "3 hunks in auth.js totaling 18 lines, no overlap with fix's edits"). Surface the heuristic recommendation as the first option labeled "(Recommended)".{ files_changed: [paths], summary: string, concerns: [string] | null }.files_changed.git add <files_changed> — do NOT commit. The user decides when to commit.verifier agent with:
git diff --staged -- <files_changed>)confirmed → still real and still in scope (P0/P1) → not resolved → proceed to Round 2.rejected → not a real issue → adds to resolved bucket → done.demoted → check the new severity:
demoted bucket → done (the issue exists at lower severity; hand-off implicit).Same shape as Round 1. The only difference is the fix subagent gets Round 1 context.
{ files_changed: [paths], summary: string, concerns: [string] | null }.git add <files_changed>. (No pre-staging check in Round 2 — see Preconditions for why.)confirmed → still real and still in scope (P0/P1) → not resolved → adds to escalated bucket → escalate (do not attempt Round 3).rejected → not a real issue → adds to resolved bucket → done.demoted → check the new severity:
escalated bucket → escalate.demoted bucket → done (the issue exists at lower severity; hand-off implicit).escalated bucket → escalate. No retry loop.If Round 2 still has the finding unresolved:
git diff --staged --stat -- <files_changed>, e.g., "Currently staged: R2's changes to auth.js, +12/-4 lines")AskUserQuestion tool with options: "Manual fix", "Try a different approach", "Defer this finding", "Discard R2 changes and revert". Recommended: "Defer this finding"After all findings are processed, return a FixVerifyLoopOutput envelope with four buckets:
Bucket assignment by verdict path:
rejected → droppedconfirmed or demoted → proceed to Round 1rejected → resolvedconfirmed (still real, P0/P1) → proceed to Round 2demoted to [P0, P1] → proceed to Round 2demoted to [P2, P3] → demotedrejected → resolvedconfirmed (still real, P0/P1) → escalateddemoted to [P0, P1] → escalateddemoted to [P2, P3] → demoted{ needs_scope_expansion: true, additional_files: [paths], justification: string } instead of making edits. The parent then uses the AskUserQuestion tool with options: "Approve expanded scope", "Reject — fix within original scope only", "Defer this finding". Recommended: "Approve expanded scope" (include the justification and file list). On approval, re-dispatch the subagent with expanded scope. Additional files are included in verification.The skill returns this envelope after all findings are processed:
{
resolved: [Finding.id, ...], // fixed in R1 or R2
escalated: [{ // could not be fixed in 2 attempts
id: Finding.id,
attempts: [string, string], // R1 + R2 summaries
evidence: string | null, // verifier's evidence (null if R2 was inconclusive)
staged_summary: string // e.g., "R2's changes to auth.js, +12/-4 lines"
}, ...],
dropped: [{ // pre-gate verifier rejected as not-real
id: Finding.id,
reason: string // verifier's rejection evidence
}, ...],
demoted: [{ // demoted to P2/P3 (out of scope)
id: Finding.id,
new_severity: "P2" | "P3",
evidence: string // verifier's demotion reasoning
}, ...]
}
<!-- source: references/finding-schema.md -->
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,
evidence: reasoning for verdict | null
}
Findings are wrapped in a ReviewOutput envelope:
ReviewOutput {
schema_version: "v1",
findings: Finding[],
checks_run: string[]
}
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 — populated by the verifier in two-pass review. Set to null when producing findings directly.evidence — verifier's reasoning for the verdict. Set to null when producing findings directly.checks_run — list every criterion evaluated, file path checked, or acceptance criterion verified. For ACs, use AC-N: PASS — [evidence] or AC-N: FAIL — [reason].documentation
Collapse a multi-clause instruction into one positive line of trigger + action. TRIGGER when: user says 'tighten this rule', 'make this leaner', 'make this simpler' in a skill, CLAUDE.md, agent prompt, or style guide.
documentation
File-level tightening pass on an instruction file (CLAUDE.md, skill, agent prompt, style guide) using `tighten-instruction` as the lens. TRIGGER when: user says 'tighten/simplify this file/skill/CLAUDE.md', 'cut this down'; user points at a verbose instruction file and wants it leaner.
testing
Anchored second-opinion on one concrete proposal: dispatch a subagent to rate the fix, generate ranked alternatives, and flag blind spots, then synthesize back. TRIGGER when: user says 'second opinion', 'rate my fix', 'weigh in on my approach', 'what alternatives am I missing', or wants their candidate edit/decision evaluated against alternatives. SKIP when: multiple decisions on a larger artifact — use `panel-review`.
development
Multi-reviewer panel on N focused questions about a near-final artifact (plan, design, code, prose). R0 (you) plus two parallel reviewer subagents, per-question table with disagreement preserved, walk decisions one at a time. TRIGGER when: user says 'panel review', 'multi-agent review'; user has a mostly-done artifact and focused micro-decisions to validate. SKIP when: only one proposal under review — use `second-opinion`.