Skip to content
Skills Library
Programming · Automation

loop

/loop

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.

Repository
pair-review ↗
Licence
Apache-2.0
Last repository change
21.10.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
1
Scripts
0
HTML comments
0
URLs in SKILL.md
5
Deprecation

No signals detected. Repository changed on 21.10.2026, without references to retired models or APIs.

Licence

Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.

What it does and when to use it

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.

Triggers from the description

pair loopreview looploop until cleanreview this with pair-review and fix what it finds
Original author description

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.

How it works

  1. Hard rules
  2. Phase: Setup
  3. Running a review round
  4. Triage
  5. Fix
  6. Write triage back (optional, needs the server)
  7. Convergence judgment
  8. PR mode
  9. Reporting
Original SKILL.md headings · 237 lines, 1,860 words
SKILL.md preview
---
name: loop
description: >
  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.
arguments:
  council:
    description: "Council handle (name, name-slug, or id prefix) to review with. Defaults to the repo's default council when omitted."
    required: false
  maxRounds:
    description: "Budget for review rounds. On reaching it without convergence, stop and report honestly."
    required: false
    default: 5
  instructions:
    description: "Extra review instructions applied to every round (e.g. 'focus on security')"
    required: false
---

# 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:

1. **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.
2. **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.
3. **Sequence strictly: fix → write triage back → then run the next round.**
4. **One review at a time.** Never run two reviews concurrently for the same
   repo.
5. **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.)
6. **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.
7. **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

1. `git rev-parse --show-toplevel` → `REPO_ROOT`. All commands run from here.
2. 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.
3. If a `council` argument 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.
4. 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

```bash
pair-review --local --headless --json --council <handle> [--scope <range>] --instructions "<round instructions>"
```

- Run from `REPO_ROOT`. `--local` with no path uses the current directory.
- Omit `--council` to 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:

```bash
curl -s -X POST http://localhost:<port>/api/reviews/<run.review_id>/suggestions/<id>/status \
  -H 'Content-Type: application/json' -d '{"status": "dismissed"}'
```

- Only `"dismissed"` and `"active"` are accepted; `"adopted"` is reserved
  for the human's adopt flow — never send it.
- Current servers accept a `reason` field 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:

```bash
pair-review <pr-number-or-url> --headless --json [--council <handle>] [--instructions "..."]
```

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:

1. **Verdict** — converged (quote the final run's summary) or not converged
   (why, and what remains).
2. **Rounds table** — per round: directive, findings found, fixed, dismissed,
   asked.
3. **Triage detail** — every dismissed finding with its reason; every fix in
   one line each.
4. **The review URL** when a server is up, so the user can inspect
   everything in the web UI.
5. Working-tree status reminder: changes are uncommitted, tests run and
   their result.

Versions

RepositoryScoreLicence
This page · in-the-loop-labs/pair-review100Apache-2.0
mickeyyaya/evolve-loop100Apache-2.0
relai-ai/agent-eval-loop100Apache-2.0
SethGammon/Citadel100MIT
alirezarezvani/claude-skills100MIT
x-cmd/x-cmd100Apache-2.0
railly/skills100MIT
slogsdon/loop-and-gate-foundation100MIT
Mineru98/skills-store100MIT

Database snapshot: 13.11.2026 · package version 4a8dc8dac7f7 (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 90review-loop
    Iterative multi-model review-and-fix loop. Repeatedly runs the review-multi-model panel over the working tree, applies the verified fixes, and re-reviews - review → fix → review → fix - until a pass finds no verified bug or completeness gap (a missing story, test, or a now-false…
  • 100code-review-loop
    Push local work as a GitHub PR against a user-specified base branch and run a recurring review/fix loop combining @codex review with a separate broader review of smaller bugs, edge cases, and meaningful missing tests. Validate and push fixes, then repeat until both reviews are…
  • 100implement-review-fix-loop
    Use when the user asks an agent to implement a change and then loop review → fix until no critical, major or minor finding is left ("repeat until clean", "until nothing blocks"). Covers unit partitioning, severity definitions, the per-round protocol, convergence and stop rules,…
  • 100council-review
    Use when the user or another skill explicitly invokes council-review or requests a "council review" or "council review loop". Generic requests to review code do not trigger this skill.
  • 90user-critic
    Fetch human review comments from pair-review and make code changes to address them. Use when the user says "address review feedback", "fix review comments", "address comments", or wants to iterate on code based on feedback left by a human reviewer in pair-review.
  • 90ai-critic
    Fetch AI-generated review suggestions from pair-review and make code changes to address them. Use when the user says "address AI feedback", "address AI suggestions", "fix AI review feedback", or wants to iterate on code based on AI analysis results from pair-review.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.