---
name: why-review-loop
version: 1.1.0
description: '[Code Quality] Use when you need to combine /why-review + /fix in a recursive loop — each round runs /why-review to find validated findings then /fix to resolve them, then loops again over the CHANGED target until a fresh full /why-review produces zero findings (nothing left to fix).'
---

<!-- PROMPT-ENHANCE:STEP-TASK-ANCHOR:START -->

> **[BLOCKING]** Execute skill steps in declared order. NEVER skip, reorder, or merge steps without explicit user approval.
> **[BLOCKING]** Before each step or sub-skill call, update task tracking: set `in_progress` when step starts, set `completed` when step ends.
> **[BLOCKING]** Every completed/skipped step MUST include brief evidence or explicit skip reason.
> **[BLOCKING]** If Task tools are unavailable, create and maintain an equivalent step-by-step plan tracker with the same status transitions.

<!-- PROMPT-ENHANCE:STEP-TASK-ANCHOR:END -->

## Quick Summary

**Goal:** Drive a review target to a **clean pass** by pairing `/why-review` with `/fix` in a recursive loop — each round runs `/why-review` INLINE to surface validated findings, then `/fix` to resolve them, then loops again over the CHANGED target — stopping when a complete `/why-review` pass clears the round's exit bar: **zero findings** in rounds 1-2, and **zero CRITICAL/HIGH/MEDIUM** from round 3 (LOW-only ENDS the loop, deferred not fixed).

**Summary:**

- **Each round = `/why-review` + `/fix`** — `/why-review` is review-ONLY and never edits the target, so the loop MUST pair it with a fix half; one without the other never converges.
- **Steps (in order):** (0) resolve target + Goal Contract → (0b) bind the convergence loop (protocol loop primary + optional `/goal` accelerator) → (1) round loop { run `/why-review` INLINE → clear the **Trade-Off Gate** on the fix set → run `/fix` on the VALIDATED findings at the owning layer → log iteration } → (2) converge on a zero-findings round OR escalate on non-progress → (3) recap.
- **Convergence:** stop ONLY when a **fresh full** `/why-review` over the CURRENT (post-fix) target clears that round's exit bar — not a stale PASS predating the last fix.
- **Severity floor — from round 3, LOW stops blocking.** Rounds 1-2 converge on an **empty validated-finding set** (any severity). **From round 3 the bar is zero validated CRITICAL/HIGH/MEDIUM — a round whose validated findings are ALL LOW ENDS the loop.** Never open another round to fix LOW alone; list every deferred LOW in the recap and Goal Contract instead, and NEVER re-tier a real CRITICAL/HIGH/MEDIUM down to LOW to reach the exit.
- **Inline invariant:** run `/why-review` via the `Skill` tool, NEVER the `Agent` tool — it self-binds its OWN review-loop obligation (and a session `/goal` gate WHEN available, `why-review/SKILL.md:57-76`), which a sub-agent cannot own or carry back to this loop.
- **Apply ONLY validated findings:** `/why-review` already validates its findings to the ≥85% survival bar; the loop applies THOSE, at the lowest owning layer (Entity > Service > Handler), routed by target type — NEVER unvalidated findings.
- **Bounded:** round cap default 3; findings not shrinking across 2 rounds, or cap hit with findings still open → **STOP & escalate** via `AskUserQuestion`. Increasing findings → STOP (fixes regressing).
- **TRADE-OFF GATE before every fix (ALWAYS ASK):** (1) **is there any trade-off in this fix?** name what it sacrifices — "none" is an unfinished analysis; (2) **is it worth it?** gain vs cost, who pays, when → WORTH IT / NOT WORTH IT / UNCLEAR — NOT WORTH IT → do NOT apply, report it back instead; (3) **is the trade-off material enough to confirm with the user?** irreversible · cost shifted elsewhere · quality attribute traded · boundary crossed · high-consequence path · UNCLEAR → **STOP the loop and confirm via `AskUserQuestion` BEFORE applying**. NEVER auto-apply a material-trade-off fix just because the loop wants to converge.

**Why this skill exists (READ FIRST — it is the whole justification):** `/why-review` is **review-only** — `why-review/SKILL.md:330` (_"Review only — do NOT modify target files or implement changes"_) and `:76` (_"why-review fixes its OWN findings set, not code… Code/spec/test fixes remain the caller's job"_). Its internal self-recursive `/goal` loop (`why-review/SKILL.md:57-76`) converges its own **findings REPORT** to CLEAN — every surviving finding proof-backed, validated, ≥85% confidence — but it **never touches the code and never re-reviews a fixed target**. So a finding that demands a code/spec/doc change is validated and handed off, yet **nothing loops back to confirm the FIX is correct or that it introduced no new defect**. This skill closes that outer loop: it applies the validated fixes and re-runs a **fresh full** `/why-review` over the changed target until zero findings remain — catching fix-induced regressions and proving each fix actually resolved its finding. Without it, "why-review passed, then I fixed the findings" ships those fixes unreviewed.

**Workflow:** resolve target + Goal Contract → bind the convergence loop (protocol loop + optional `/goal` accelerator) → **round loop** { run `/why-review` INLINE → clear the Trade-Off Gate on the fix set (trade-off? worth it? material → confirm with user) → run `/fix` on the validated findings at owning layer → log iteration } → converge when a fresh full review yields zero findings → recap.

**Key Rules:**

- **Each round pairs `/why-review` (find) + `/fix` (resolve).** `/why-review` is review-only (`why-review/SKILL.md:76,330`) — it produces validated findings but never edits the target; `/fix` is the half that lands the change. A round is incomplete until BOTH have run (or the review returned zero findings).
- **MUST run INLINE in the main session — NEVER dispatch `/why-review` as a sub-agent.** It self-binds its own review-loop obligation (and a session `/goal` gate when available, `why-review/SKILL.md:57-76`); as a sub-agent that in-session guarantee is silently lost. This loop skill therefore also runs inline.
- **Convergence = a fresh full `/why-review` over the post-fix target clears the round's exit bar.** Rounds 1-2: PASS with an empty validated-finding set. **Round 3+: zero validated CRITICAL/HIGH/MEDIUM — LOW-only converges.** A PASS produced BEFORE the latest fix landed does NOT count — re-review the changed target.
- **The severity floor bounds ITERATION, never the standard.** It ends the loop; it never authorizes shipping a known CRITICAL/HIGH/MEDIUM, never lowers `/why-review`'s ≥85% finding-survival bar, and never applies to a binary gate (a failing test is a failure, not a LOW finding).
- **`/fix` applies ONLY validated findings**, at the lowest owning layer, routed by target type (code → `/fix` with its intelligent routing, or a direct edit at Entity/Service; plan/PBI → `/refine`; spec → `/spec [update]` + `/spec [mode=tests]`; docs → `/docs-update`; tests → `/integration-test`). NEVER apply an unvalidated or demoted finding.
- **The target base is FIXED across rounds; its content changes as fixes land.** Re-review the SAME target (same plan/diff/artifact) each round so convergence is measured against a stable subject.
- **Round cap (default 3)** and **findings-not-shrinking / increasing → STOP & escalate** via `AskUserQuestion`. NEVER loop open-ended.
- **ALWAYS ask the 3 trade-off questions before applying ANY fix** — is there a trade-off? is it worth it? is it material enough to confirm with the user? A MATERIAL trade-off (irreversible · cost shifted to another team/ops/maintainer/user · one quality attribute traded for another · tier/service/event/library boundary crossed · auth/money/data-integrity/breaking-change path · worth-it verdict UNCLEAR) **PAUSES the loop for an `AskUserQuestion` before the fix lands** — convergence pressure NEVER authorizes walking through a one-way door on the user's behalf. — why: an autonomous fix loop is exactly where an unpriced trade-off ships silently, because each round only asks "did findings shrink?".

---

## First Principle — Convergence, Not Motion

> A round that changes the target is progress **only if** the next fresh review finds fewer things to fix.
> The loop exists to reach a fixed point (no blocking findings), not to keep editing the target.
> The bar tightens by round: everything blocks in rounds 1-2; from round 3 only CRITICAL/HIGH/MEDIUM block, so a LOW-only round is the fixed point.
> If findings stop shrinking, that is a signal to **escalate**, not to spin another round.

---

## Step 0 — Resolve Target + Goal Contract (FIRST ACTION)

1. **Parse the review target** from the user prompt into a stable, reusable target reference — exactly the kinds `/why-review` resolves (`why-review/SKILL.md:142-161`):
    - **Plan / PBI / story** — a `plan.md` + `phase-*.md` dir, or a named PBI/story artifact.
    - **Code change** — a commit SHA, PR/merge commit, branch-to-branch or PR diff (e.g. `git diff develop...HEAD`), or uncommitted working-tree changes.
    - **Docs / spec / report** — a target artifact path whose claims are checked against source evidence.
    - Record the target type, its evidence, and confidence. **NEVER silently convert target types** (`why-review/SKILL.md:160`).
2. **Resolve/create the Goal Contract** per `SYNC:goal-contract-satisfaction-loop` (`plans/goals/{YYMMDD-HHmm}-{slug}/goal.md`, template `.claude/templates/goal-contract-template.md`). Its single **required** Success Criterion:
    > _A fresh full `/why-review` over `{target}` clears the round's exit bar: **rounds 1-2** → PASS with **zero validated findings** (no finding, weakness, or missing item of any severity); **round 3+** → **zero validated CRITICAL/HIGH/MEDIUM findings**, with any remaining LOW findings recorded as deferred rather than fixed._
    > Record the round cap (default 3), the severity floor (LOW non-blocking from round 3), and the target reference in **Constraints**.

## Step 0b — Bind the Convergence Loop (protocol-first; `/goal` is an optional accelerator)

The convergence loop is bound by TWO layers. The **protocol loop (Steps 1–2) is the BINDING mechanism** and MUST be self-driven by you, the running agent, on every host — with or without any command or hook. The **`/goal` command is an OPTIONAL accelerator** layered on top; it is never the primary mechanism, and its absence NEVER weakens the loop. This mirrors the project rule that hooks/trackers are accelerators only — correctness must not depend on them.

**1. Protocol loop — ALWAYS binding (hook/command-independent).** You are personally responsible for not stopping until the loop converges or bounded-escalates. This binds Claude, Codex, and Copilot equally, whether or not `/goal` exists:

> Repeatedly run `/why-review` INLINE over `{target}`. After each review, apply every VALIDATED finding's fix at its owning layer, then re-run a FRESH full `/why-review` over the CHANGED target. Do NOT stop while the last review still produced findings that BLOCK at the current round's bar. Converge when a fresh full `/why-review` clears that bar: **rounds 1-2** → PASS with zero validated findings; **round 3+** → zero validated CRITICAL/HIGH/MEDIUM (LOW-only ENDS the loop, with the LOWs recorded as deferred). Cap at `{N=5}` rounds; if blocking findings do not shrink across 2 consecutive rounds, findings increase, or the cap is hit with CRITICAL/HIGH/MEDIUM still open → STOP and escalate via `AskUserQuestion`. Never loop open-ended.

Treat this as a standing obligation you re-read at every Step 2 checkpoint — NOT a one-time note you can rationalize away after the first fix cycle. The Goal Contract's required Success Criterion (Step 0) is its durable, host-independent record.

**2. `/goal` command — invoke as an accelerator WHEN AVAILABLE.** If a `/goal` command exists and you are permitted to run it in this environment, ALSO invoke it (a real tool/command call, NOT a paraphrase, NOT a Goal Contract file substituted for it) with the SAME condition, so a session Stop hook mechanically enforces the loop:

```
/goal why-review convergence loop: repeatedly run /why-review INLINE over {target}. After each review, apply every VALIDATED finding's fix at its owning layer, then re-run a FRESH full /why-review over the CHANGED target. If findings>0 → apply fixes and run another round; if a fresh full /why-review returns PASS with zero validated findings → CONVERGED, clear the gate. Do NOT stop while the last review still produced findings. Cap at {N=5} rounds; if findings do not shrink across 2 consecutive rounds, findings increase, or the cap is hit with findings still open → STOP and escalate via AskUserQuestion. Never loop open-ended.
```

The `/goal` Stop hook blocks stopping until the condition holds and auto-clears when met — do not tell the user to clear it.

**If `/goal` is unavailable, unregistered, or not permitted** (e.g. Codex/Copilot, or a Claude run without the command): DO NOT error, DO NOT block, and DO NOT invent a stand-in gate. Record ONE line in the Goal Contract — `/goal accelerator unavailable — loop bound by protocol (Steps 1–2) + this Goal Contract` — and proceed. The protocol loop above plus the Goal Contract are the same gate, enforced by discipline instead of a hook.

> **Nested gates (by design, safe):** each inner `/why-review` round self-binds its OWN review-loop obligation (and installs its own `/goal` gate WHEN available, `why-review/SKILL.md:57-76`) that clears when THAT round's findings are all validated CLEAN. This OUTER loop persists across rounds and **subsumes** the inner ones (a converged loop implies every inner round ended with validated findings). All self-clear on satisfaction — no orphaned gate. Do NOT tell the user to clear either.

## Step 1 — Round Loop (`/why-review` → `/fix` → log)

Each round couples the two halves — **review to find, fix to resolve.** For each round `R` (starting at 1), do ALL of:

1. **Run `/why-review` INLINE** on `{target}` via the `Skill` tool (NEVER the `Agent` tool). Let it run its full adversarial review + its own internal Findings Validation Gate, so the findings it returns are already **validated** (proof-backed, ≥85% survival bar).
2. **Read the validated finding set** from its report (`plans/reports/why-review-*.md`). If the verdict is PASS with **zero** findings → this round converged; go to Step 2 (no fix half needed).
3. **Trade-Off Gate on the fix set (BLOCKING — before any edit lands).** For EACH validated finding's fix, ask the 3 questions: (a) **is there any trade-off?** name what applying it sacrifices — future change cost, complexity, performance, coupling, reversibility, migration/ops burden, blast radius, security, testability, delivery time; "none" is an unfinished analysis, so state the dimensions checked; (b) **is it worth it?** gain vs cost, who pays, when → **WORTH IT / NOT WORTH IT / UNCLEAR**; NOT WORTH IT → do NOT apply — report the finding back as a withdrawn-fix note and count it as still-open, never as fixed; (c) **is the trade-off material enough to confirm with the user?** MATERIAL when irreversible (one-way door) · cost shifted onto another team/ops/maintainer/user · one quality attribute traded for another · a tier/service/event/library boundary crossed · an auth/money/data-integrity/breaking-change path · or the verdict is UNCLEAR → **PAUSE the loop and confirm via `AskUserQuestion` BEFORE the edit**, stating the trade-off, both options, what each sacrifices, and your recommendation. Log each fix's trade-off verdict in the round's Iteration Log entry. — why: the loop's only convergence signal is "did findings shrink?", so a material trade-off rides in unpriced unless a gate stops the fix half specifically.
4. **Run `/fix` on the validated findings** (findings>0 only, trade-off gate cleared) — this is the half `/why-review` never does. Resolve each validated finding at its owning layer: code → `/fix` (its `--target` intelligent routing) or a direct edit at the lowest layer (Entity > Service > Handler); plan/PBI → `/refine`; spec → `/spec [update]` + `/spec [mode=tests]`; docs → `/docs-update`; behavior-changing → honor the finding's dual-feedback (spec verdict + test action per `why-review/SKILL.md:360`). Fix ONLY validated findings — never an unvalidated or demoted one.
5. **Append an Iteration Log entry** to the Goal Contract: round number, findings count (validated), files/artifacts changed this round (`file:line`), fixes applied, per-fix trade-off verdict (WORTH IT / NOT WORTH IT / UNCLEAR + material? + confirmed?), and remaining gaps.

## Step 2 — Convergence & Escalation Gate

Evaluate after every round:

| Condition                                                                                                                                                               | Action                                                                                                                                                                                                                                |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Fresh full `/why-review` returned **PASS with zero validated findings**                                                                                                 | **CONVERGED** → mark the required criterion PASS in the Goal Satisfaction matrix → clear the `/goal` gate → go to Step 3.                                                                                                             |
| Round `R ≥ 3` AND the fresh review's validated findings are **ALL LOW** (zero CRITICAL/HIGH/MEDIUM)                                                                     | **CONVERGED on the severity floor** → do NOT run another round for LOW alone → record every remaining LOW as a deferred finding in the recap + Goal Contract → mark the required criterion PASS → go to Step 3.                       |
| Blocking findings > 0 AND round `< N` AND blocking findings shrank vs prior round                                                                                       | Clear the Trade-Off Gate (Step 1.3), apply the validated fixes (Step 1.4), then run round `R+1` (fresh full re-review of the changed target). Rounds 1-2 count every severity as blocking; round 3+ counts only CRITICAL/HIGH/MEDIUM. |
| A fix carries a **MATERIAL** trade-off (irreversible · cost shifted elsewhere · quality attribute traded · boundary crossed · high-consequence path · worth-it UNCLEAR) | **PAUSE the loop → confirm via `AskUserQuestion` BEFORE applying that fix.** Convergence pressure NEVER authorizes deciding a material trade-off for the user.                                                                        |
| Findings did **not shrink** across 2 consecutive rounds (same/increasing count)                                                                                         | **STOP & escalate** via `AskUserQuestion` — a non-converging loop is a signal, not a reason to spin.                                                                                                                                  |
| Round cap `N` hit with CRITICAL/HIGH/MEDIUM still open                                                                                                                  | **STOP & escalate** via `AskUserQuestion` — report the still-open findings; do not silently continue. (LOW-only at the cap converges via the severity-floor row above.)                                                               |

> **Increasing findings = STOP.** If round `R` surfaces MORE findings than round `