Skip to content

review-loop

review-loop

Iterates code review until convergence — addressing every comment, re-requesting review, and stopping only when the diff is clean and approved. Use after opening a pull request, when review feedback arrives in batches, or when closing out comments one-by-one loses track of what remains.

Category
Category: loop-engineering
  • code-review
  • pull-request
  • iteration
  • feedback
  • convergence

Install this skill

npx . --tool claude-code --only review-loop

Run from a git checkout of this repo — see the README for details.

When to apply

Use whenever a change is under review: after opening a pull request, when review comments arrive, or when fixes spawn further comments. The loop's exit condition is an approved, comment-free diff — not "I replied to everything".

Workflow

  1. Inventory — List every review comment and CI check. Each gets an entry: comment → owner (you) → state (open/done/disputed).
  2. Triage each comment into:
    • Fix — address exactly as asked
    • Clarify — comment was based on a misreading; answer precisely, change nothing
    • Dispute — you believe the reviewer is wrong; state your reasoning and evidence, offer to defer
  3. Apply fixes in the review's priority order — blocking comments before nits. Keep each fix minimal (see minimal-fix).
  4. Re-run the verification chain — typecheck, tests, build. A comment addressed by code that breaks CI was not addressed.
  5. Re-request review with a summary: what changed per comment, what's disputed and why.
  6. Check convergence:
    • New comments on previously-commented lines → keep looping
    • Only style nits remain → apply or dispute once, then loop
    • Zero open comments + green CI + approval → done

Worked example

PR #42: "Add user profile page"

Round 1 review — 3 comments:
| # | Comment                              | State    | Action                          |
|---|--------------------------------------|----------|---------------------------------|
| 1 | "Loading state missing"              | open     | Fix: add Suspense fallback      |
| 2 | "Why not use useQuery here?"         | open     | Clarify: useQuery needs a cache  |
|   |                                      |          | we don't have yet; noted in TODO |
| 3 | "Rename `data` to `profile`"         | open     | Fix: renamed                    |

Apply fixes → run tests → re-request review with summary:
  "1: fixed (added Suspense fallback). 2: clarified (no query cache yet,
  filed #43). 3: fixed (renamed)."

Round 2 review — 1 comment:
| # | Comment                              | State    | Action                          |
|---|--------------------------------------|----------|---------------------------------|
| 4 | "Fallback should show skeleton"      | open     | Fix: replaced spinner w/ skeleton |

Apply → test → re-request. Round 3: LGTM, CI green. **Done.**

Stop conditions

  • Approver says LGTM and no blocking checks remain → exit success
  • A dispute cannot be resolved after two exchanges → escalate to a human decision, don't relitigate
  • Loop count exceeds ~5 on the same comment → something is structurally wrong with the change; propose closing and splitting it

Rules

  • Never mark a comment "done" without the diff to show for it.
  • Replies to every comment, even the ones you fix silently — reviewers shouldn't diff your diff to discover your response.
  • Do not add unrelated improvements mid-review; they reset the review and the loop.

Related skills

  • minimal-fix — The shape of each individual fix inside the loop.
  • loop-verifier — What the reviewer is (ideally) running on their side.