| name | pair-loop |
| description | Coder<->reviewer handoff loop (Claude<->Codex, roles swappable) with self-instrumented per-round cost tracking. Loops locally via HANDOFF.md until approved, then opens a PR with the full transcript. |
| category | lifecycle |
| tier | core |
| slash_command | /pair-loop |
Pair-Loop โ Coder <-> Reviewer Handoff
Runs a formal review loop between a coder and a reviewer (default: you as coder,
Codex as reviewer โ swap via ~/.100xprism/config.json's pair_loop section).
Each round is recorded in HANDOFF.md and self-instrumented into a cost
manifest the token dashboard reads. Do NOT ask for permission to start or to
run rounds โ only stop for the outcomes listed in "When to stop" below.
Step 1 โ Start
PROJECT_ROOT=$(git rev-parse --show-toplevel)
cd "$PROJECT_ROOT"
python3 ~/100xprism/scripts/pair-loop.py start --task "<one-line task description>"
If this fails with a "dirty" error, commit or stash first โ do not force-start
on uncommitted work. Save the printed run_id, handoff_path, max_rounds,
coder, and reviewer โ you'll pass run_id to every subsequent command.
Step 2 โ Budget check (before every round)
python3 ~/100xprism/scripts/pair-loop.py budget-check --run "$RUN_ID"
Exit code 2 means the per-run budget cap is hit โ STOP and ask the user
whether to continue or stop; do not proceed to another round silently. Exit
code 0 with "level": "warn" in the output means print a one-line warning
and continue.
Step 3 โ Coder round
Implement the task (or address the reviewer's findings from the prior round).
Run the project's quick checks (tests + lint) before recording the round. Do not commit โ leave all changes in the working tree so review diffs stay accurate across rounds; commit only in Step 5 (PR phase). Then:
python3 ~/100xprism/scripts/pair-loop.py coder-done --run "$RUN_ID" \
--summary "<what you implemented/fixed, files touched, how you verified it>" \
--findings-addressed <N>
Step 4 โ Reviewer round
python3 ~/100xprism/scripts/pair-loop.py review --run "$RUN_ID"
This shells out to the configured reviewer (falling back to the coder's vendor
if that CLI is missing โ the output will say "fallback_used": true; mention
this to the user once, don't repeat it every round) and returns
{"verdict":, "findings": [...], "fallback_used":}.
"verdict": "APPROVED" โ go to Step 5 (PR phase).
"verdict": "CHANGES_REQUESTED" and you have rounds remaining (round count
reported by start as max_rounds) โ go back to Step 2 for the next round.
"verdict": "CHANGES_REQUESTED" at max_rounds โ STOP. Present the open
findings to the user and ask whether to ship as-is, do another round anyway,
or abandon. Do not silently exceed the configured round cap.
Step 5 โ PR phase
python3 ~/100xprism/scripts/pair-loop.py finish --run "$RUN_ID" --verdict APPROVED
(Omit --pr on this first call โ you don't have a PR number yet.) This prints
pr_body_path. Run the branch and pr skills to push and open the PR,
passing that file as the PR body (gh pr create --body-file <pr_body_path>).
Once you have the real PR number, re-run finish with --pr <number> so the
manifest records it for the dashboard's $/merged-PR metric:
python3 ~/100xprism/scripts/pair-loop.py finish --run "$RUN_ID" --verdict APPROVED --pr <NUMBER>
If pair_loop.pr_final_round is true in the config, run one more review
round against the pushed PR diff before this step, and post any findings as a
PR comment via gh pr comment โ then do exactly one more local coder round to
address them before finishing.
When to stop and ask the user
- Budget cap hit (Step 2, exit code 2).
- Round cap hit without approval (Step 4).
- Never auto-merge โ a human merges the PR, always.
Note: If the reviewer CLI fell back to the coder's vendor, mention it to the user once (the output will say "fallback_used": true), but do not block โ this is not a stop condition.