Install
$ agentstack add skill-ccomkhj-skills-pair-iterate ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
pair-iterate
Phase 3 of pair-goal. The work you do on each /goal turn: race two implementers, keep the better diff. You are the orchestrator — you judge and merge, you do not implement the target yourself. Implementing it directly throws away the entire reason for two racers.
The contract
- Two racers, full isolation. A Claude racer (model
RACER_CLAUDE, which must differ from your ownORCH_MODEL) and a Codex racer (modelRACER_CODEX) each work in their own git worktree off the same base commit. They never see each other. - Nothing is kept unless it's the measured winner. Each round you run the goal's stated check in both worktrees, pick a winner by an explicit rubric, and merge only the winner. A round can end with neither kept if both fail the check.
- Every round's proof lands in chat. After merging, re-run the check on the main tree and surface its output — that's what the
/goalevaluator reads to decide whether to continue.
Setup — source the helpers
source ~/.claude/skills/pair-goal/reference/handoff.sh # or ~/.agents/...
Provides goal_race, goal_wait_race, goal_teardown, plus human-side goal_watch/goal_status/goal_inject/goal_takeover. These encapsulate the CLI-spawn hazards (see [Hazards](#hazards)) — don't hand-roll the invocations.
The model-selection gate — once, before round 1
Ask the user two things and write them to STATE.md:
- Claude racer model (
RACER_CLAUDE) — must differ fromORCH_MODEL. The point is a different Claude perspective. Refuse a model equal to the orchestrator's and re-ask. - Codex racer model (
RACER_CODEX) — the model Codex runs with.
Empty values are allowed (each CLI uses its own default), but the Claude racer must still not silently match the orchestrator. Confirm both before racing.
One round
Each /goal turn does exactly one round. ROUND in STATE.md is the counter.
- Address user notes. If
.pairgoal/USER_NOTES.mdhasStatus: unaddresseditems, fold them into this round's brief, then mark them addressed. - Write the brief. Compose
.pairgoal/R-brief.md: the improvement target and constraints (fromGOAL.md/UNDERSTANDING.md) plus what the previous round fell short on (fromR.md). This is the shared instruction both racers get; keep it goal-focused, not solution-prescriptive — let them diverge. - Race.
STATUS: RACING: R, thengoal_race. It createswt-claude/+wt-codex/offHEAD, embeds the brief, and spawns both racers detached on their chosen models. - Wait. Immediately
goal_wait_race— in Claude Code via Bashrun_in_background=trueso the harness wakes you when both finish. The racers arenohup'd and invisible to the harness; without this you idle. Exit 3 = a racer likely died → inspect logs, treat that racer as a no-submission. - Judge. For each worktree: confirm it committed, run the goal's stated check there, and capture
git -C .pairgoal/wt- diff ..HEAD --stat. Pick the winner by this rubric, in order: - Goal-condition progress — does the check pass / move closest to the threshold?
- Correctness — tests/behavior intact; constraints from
GOAL.mdrespected. - Diff quality — smaller, clearer, fewer incidental changes (tiebreak).
Write R.md (template in [../pair-goal/reference/file-formats.md](../pair-goal/reference/file-formats.md)) with both attempts, both check outputs, and the verdict.
- Merge the winner. Apply the winning worktree's commit(s) to the main tree (e.g.
git cherry-pickthe racer branch, orgit merge --squash pairgoal/r-then commit). If neither passes, merge nothing and record why. - Prove it on the main tree. Re-run the stated check on the main tree and print its output in chat — this is the transcript the
/goalevaluator judges. Note inR.mdwhat's still short of the goal. - Tear down + advance.
goal_teardown(removes both worktrees, deletes their temp branches). BumpROUND. Append a one-lineRentry toSTATE.md's round log. Then end the turn —/goaldecides whether to start another.
When does iteration stop
You don't poll the goal yourself — /goal does. It clears automatically when the evaluator sees the condition met in the transcript, and the next thing you do is summarize. But hold and surface to the user (don't burn turns) when:
ROUNDreachesROUNDS(cap) without the goal clearing → stop, report partial, ask whether to raise the cap or accept.- Two consecutive rounds keep nothing (both racers fail the check) → likely the goal or approach is wrong; surface rather than grind.
- A racer CLI disappears or git worktrees fail →
STATUS: BLOCKED, surface.
Surfacing each round in chat
After judging, print a 5–10 line digest before ending the turn so the user (and the /goal evaluator) see progress:
**R3 race:** winner = codex
- claude: check FAILED (2 tests red), diff 3 files +40/-12
- codex: check PASSED, p95 38ms (goal " ` (flags after prompt) | Hangs the CLI. Flags first; `goal_race` enforces it. |
| `claude --add-dir ""` (variadic eats prompt) | `--` terminator before the prompt. Enforced. |
| `killall claude` / `pkill codex` to recover | Kills the user's main session. Use `goal_racer_status` / `goal_takeover` (PID-scoped). |
| Two racers editing one tree | Corruption. Each gets its own worktree off the same base — never the main tree. |
| Keeping a diff you didn't check | A win must pass the stated check in its worktree AND on the main tree after merge. No check, no keep. |
| Racer model == orchestrator model | Defeats the second-perspective design. The gate refuses it. |
| Leaving worktrees behind | `goal_teardown` every round and on every abort path; `git worktree prune`. |
| Idling after `goal_race` | Racers are `nohup`'d, invisible to the harness. Always follow with `goal_wait_race` (background in Claude Code). |
## Resuming mid-round
If re-invoked while `STATUS: RACING: R`: run `goal_status`. If both
`.pairgoal/wt-*/.pairgoal-done` exist, judge now. If only logs are growing, the
race is live — `goal_wait_race `, don't launch a second `goal_race`.
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [ccomkhj](https://github.com/ccomkhj)
- **Source:** [ccomkhj/skills](https://github.com/ccomkhj/skills)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.