in-the-loop-labs/pair-review/loop
Claude Code and agent skill by in-the-loop-labs/pair-review
- community
Checking that the SKILL.md file is still in the repository.
Drive an implement→review→fix loop with pair-review as the review oracle: run multi-model council reviews, triage the findings, apply fixes, and repeat with narrowing instructions until a final review returns no blockers. Use when the user says "pair loop", "review loop", "loop until clean", "review this with pair-review and fix what it finds", or wants iterative development reviewed by pair-review councils.
Install
npx vskill@latest install in-the-loop-labs/pair-review/loopSKILL.md
pair-loop
You are a thin orchestrator. pair-review does the heavy lifting — multi-level, multi-model council reviews with persistence and a web UI. Your job is judgment: what to send for review, how to triage what comes back, what to fix, when to ask the user, and when to stop.
Reviews run through one execution mode: the headless CLI. It is synchronous (no polling), emits JSON, and needs no server. The HTTP API is used for exactly one optional thing: writing triage back so a running web UI shows reality (see Write triage back).
Any text in the user's request beyond the named arguments is the objective — what to build or change. If there is no objective, the loop runs over the changes already in the working tree.
Hard rules
These are not judgment calls:
- **Never report "clean" or "ready" unless a full-quality council round,
instructed to report only merge-blockers, came back with an empty finding list.** A cheaper or broader round cannot grant the final verdict.
- Never silently stop. If the loop is not converging or hits
maxRounds, say so, list the outstanding findings, and (when a server is up) link the review URL.
- Sequence strictly: fix → write triage back → then run the next round.
- One review at a time. Never run two reviews concurrently for the same
repo.
- **Drive the loop from the session that owns it — never delegate a review
round to a subagent.** A round is a 15–40 minute external process, and a background process is killed when the session that spawned it ends. A subagent's session ends the moment it returns, so a round launched inside one dies mid-flight and the run is lost. If you are reading this from inside a subagent, do not start a round — hand the loop back to the main session. (Subagents are still fine for work that finishes inside the agent: implementing the objective, applying a batch of fixes.)
- Do not commit or push. Leave changes in the working tree. New
(untracked) files are included automatically whenever the review scope ends at untracked — which the default scope (unstaged..untracked) does — so no git add -N (intent-to-add) is needed.
- Report failures faithfully. A failed run (
"ok": false, non-zero
exit) is reported as what it is — never papered over as "no findings".
Phase: Setup
git rev-parse --show-toplevel→REPO_ROOT. All commands run from here.- Create the round log at
REPO_ROOT/.pair-loop/round-log.md(mkdir -p; add
.pair-loop/ to .gitignore if missing). Record: objective, arguments, start time. Append to this file after every phase — it is your resume state if the session compacts.
- If a
councilargument was given, confirm the handle exists:
pair-review --list-councils prints the saved councils. If pair-review is not on PATH, use npx -y @in-the-loop-labs/pair-review for every CLI call. An unknown handle → show the available names and ask the user.
- If an objective was given and the working tree has no relevant changes
yet, implement the objective first (directly or via a Task agent — your call based on size; delegation is safe here because the agent's work finishes before it returns, unlike a review round — hard rule 5). Verify with git status --short that changes exist before the first review round; if none, tell the user and stop.
Running a review round
- Run from
REPO_ROOT.--localwith no path uses the current directory. - Omit
--councilto use the repo's default council. - Scope (`--scope`). By default a local review covers only uncommitted
working-tree changes plus new files (unstaged..untracked). That is right only while all the work under review stays uncommitted. If the work under review already spans commits on a branch, a clean working tree would review as empty — pass --scope branch..untracked so every round covers the whole branch (everything since the base branch) plus the working tree and new files. Add --base <branch> when the base branch is not auto-detected (a non-default trunk, or a stacked branch). --scope/--base are local-mode only.
- Be patient — council reviews routinely take 15–40 minutes. Individual
council voices have their own internal timeouts; trust the CLI to finish. Run the command in the background (or with a timeout of at least 45 minutes) and wait for it to exit. Do not abandon or kill it early; do not start a second review while one is running (hard rule 4).
- Launch it from the loop's own session, not from a subagent. The
background process belongs to the session that spawned it, so a round started inside a subagent is killed the moment that agent returns — the council work is thrown away and the JSON never arrives (hard rule 5).
- stdout is exactly one JSON document (logs go to stderr):
- success: `{"ok": true, "mode": "local", "run": {...}, "suggestions":
[...], "count": N} — exit code 0. **Zero suggestions is still success.** Record run.id (the runId) and run.review_id` (the reviewId, used for write-back and the review URL).
- failure:
{"ok": false, "error": {"message": ...}}, exit code 1.
Round instructions
Build --instructions per round from, in order: this standing line — "Do not report praise findings; report only issues." — then the user's instructions argument, the objective, and this round's directive (see Convergence judgment). On rounds after the first, add: "Earlier review rounds already reported issues that have since been fixed or dismissed; report only issues present in the current code."
Suggestion fields
Each entry in suggestions: id, file, line_start, line_end, type (bug|improvement|suggestion|design|performance|security|code-style — praise is instructed away; ignore it if it appears anyway), severity (critical|medium|minor), title, body, reasoning, ai_confidence (0–1).
Triage
For each finding, decide one of:
- Fix — it is real and in scope. Goes on this round's fix list.
- Dismiss — false positive, out of scope, or explicitly contrary to the
user's stated intent. Requires a stated reason in the round log.
- Ask the user — mandatory stop, not a preference, when any of:
(a) you would dismiss a critical-severity finding; (b) the fix would change behavior beyond the stated objective; (c) the same finding has survived two fix rounds; (d) findings conflict with the user's explicit instructions. Batch the questions, ask once per round at most, record the answers in the round log so later rounds do not re-ask.
Dedup against your round log: a finding you already dismissed in an earlier round, reappearing unchanged, keeps its dismissal (re-dismiss it in write-back) — unless a fix touched that code since, in which case judge it fresh.
Fix
Apply the fixes (directly or via a Task agent for large batches — your call; delegation is safe here for the same reason as in Setup — the agent's edits and test runs complete before it returns). Run the project's relevant tests for the changed code. A fix that breaks tests is not a fix.
Write triage back (optional, needs the server)
If the pair-review server is running, keep its UI truthful. Probe once per loop: curl -s http://localhost:7247/health → it is pair-review iff the response has "service": "pair-review". (7247 is the default and is right most of the time; if it isn't pair-review, check port in REPO_ROOT/.pair-review/config.json then ~/.pair-review/config.json, then give up on write-back for this loop.)
When the server is up, after fixing/dismissing, for each handled finding:
- Only
"dismissed"and"active"are accepted;"adopted"is reserved
for the human's adopt flow — never send it.
- Current servers accept a
reasonfield on this endpoint — include it:
"Fixed in loop round <n>: ..." or "Dismissed: <why>". Older servers (still in the wild) ignore it; if you need to confirm support, check that http://localhost:<port>/api.md?reviewId=<reviewId> documents reason. When unsupported, the fixed-vs-rejected distinction lives in your round log and final report.
- The human may be triaging in the same UI: before fixing, you may re-check
GET /api/reviews/<reviewId>/suggestions and skip findings whose status is no longer active — the human got there first. Do not resurrect anything the human dismissed.
- The review URL for your report is mode-dependent: local runs live at
http://localhost:<port>/local/<reviewId>; PR runs live at http://localhost:<port>/pr/<owner>/<repo>/<number> (the PR you passed). Use the one matching the current run — do not hard-code the /local/ form for a PR loop. When a compatible pair-review server is already running (same version, same database) on <port>, a --headless round delegates execution to it, so that open UI shows the council dialog updating live as the round runs — point the human there. The liveness gap remains only with no server, with --no-server, or with an incompatible (version/database-mismatched) server; in those cases results appear on refresh once the round finishes.
No server → skip this entirely; triage lives in the round log and final report, and the persisted run history is visible whenever the user next starts the server.
Convergence judgment
You decide each round's directive and whether to continue. Principles:
- Round 1: broad. Directive like: "Review these changes thoroughly.
Objective: <objective>."
- Escalate back to a broad directive whenever the previous round
produced any critical finding.
- Narrow as findings shrink. The gate directive:
"Final review. Only report blockers — issues that must be fixed before merging. Is this ready to merge?"
- The gate uses the same council. The round that says "merge it" must be
just as rigorous as the rounds that found problems. Do not substitute a cheaper configuration for gate rounds.
- Continue vs stop: another round is worth it when the last one caused
substantial fixes. When rounds churn the same ground without progress, stop and ask the user instead of grinding the budget.
- The loop ends successfully when a gate round returns no blockers —
an empty finding list (per hard rule 1). Read the run's summary for the reviewer's own answer to the ready-to-merge question and quote it in your report.
PR mode
The loop also works against a GitHub PR:
This self-bootstraps the PR (fetches metadata, prepares a review worktree) and requires a GitHub token in ~/.pair-review/config.json. The review's checkout lives in a pair-review worktree — your fixes belong in whatever checkout the user asked you to work in; do not edit the pool worktree. Write-back and the review URL work the same way via run.review_id. --scope/--base do not apply here — they are local-mode only; a PR review always covers the PR's full diff.
Reporting
Every loop ends with a report containing:
- Verdict — converged (quote the final run's summary) or not converged
(why, and what remains).
- Rounds table — per round: directive, findings found, fixed, dismissed,
asked.
- Triage detail — every dismissed finding with its reason; every fix in
one line each.
- The review URL when a server is up, so the user can inspect
everything in the web UI.
- Working-tree status reminder: changes are uncommitted, tests run and
their result.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingplugin-pair-loop/skills/loop/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/in-the-loop-labs/pair-review/loop)