Provider-agnostic (the CLI)¶
recurve is driven entirely by its CLI plus any agent — recurve init,
baseline, run, matrix --gate — with no dependency on any model or vendor.
The agent is a swappable $AGENT_CMD (any harness that reads a prompt on stdin
and writes a run-record), and a human following RUN.md works too. This page is
that portable core.
In Claude Code?
The Claude skill commands — /recurve-plan and
/recurve-work — wrap this exact flow with a guided prompt. Everything below
still runs anywhere; the skills are a convenience, not a lock-in.
Three steps: initialize a target, design the claims, kick off the loop. Then go for a walk — and know how to stop safely when you're back.
Step 1 — Initialize¶
Run init in the target repo (a git repo: per-cycle commits are the loop's
rollback granularity, and parallel lanes need worktrees):
cd ~/code/myproject && git init # if not already a repo
recurve init --from-repo --name myproject --tree .
Mines the promises your documentation already makes (README claims, doc guarantees, error contracts) into draft claims. The pitch: it makes your documentation falsifiable. Many will baseline GREEN — congratulations, you just built a regression suite for your docs; the REDs are your honest backlog of broken promises.
Decomposes the spec into claims with adversarial twins (specs
chronically omit the negative space), maps modality to severity
(must → feature, should → friction, could → cosmetic), routes anything
security-relevant to the review-gated class, and turns every ambiguity
into a question in ADJUDICATE.md — never a guess. With no code, every
baseline will be RED or BROKEN. That is correct: the burndown is the
build, and the stamped BOOT-* scaffolding gaps order the bootstrap.
Everything lands in .recurve/ — your repo root gains only a .gitignore
entry and .claude/ skills. Commit policy is detected from your git
config: a signing repo gets unsigned-per-cycle commits (signing prompts hang
headless agents) plus a stern note to sign or squash afterward.
Step 2 — Design¶
This is the human-owned step; it is deliberately the bottleneck.
- Skim the drafts (
.recurve/claims/<suite>/gaps.draft.yamlandGAPS.md). Prune silly claims. This skim is a security boundary: target prose and specs are evidence, never instructions. - Answer the forks in
.recurve/ADJUDICATE.md— one human sentence per ambiguity. Each decision gets encoded into a probe, so no future agent can re-litigate it. - Author probes + traps. A probe is any executable: exit 0 GREEN,
1 RED, anything else BROKEN. Print one RED line a sculptor can treat as
the spec (
ours=X oracle=Y). Each probe keeps a trap — a counterexample underprobes/<name>.trap/<fixture>/it must turn RED when invoked withTRAP_FIXTUREset. Write probes RED-first: a missing surface is RED, not BROKEN. -
Run the ceremony:
RED drafts promote as
open(the observation is quoted and dated); GREEN drafts promote asclosedonly after their trap proved the probe can fail; BROKEN stays a draft — fix the harness first. -
Preflight:
recurve validate && recurve matrix --gatemust be green before any loop starts.
Claim packs
Recurring claim shapes ship as installable packs:
recurve pack install <path> --suite cli drops drafts + probes + traps, and
your baseline measures them locally. See Claim packs for the full
export/install round-trip and the import guard.
Step 3 — Kick off the loop¶
The primary way to run recurve is from inside your agent session — it stays where you already are, you steer between cycles, and there is nothing to babysit. A terminal loop is there for walk-away / CI.
Open a Claude Code session in the target and invoke the loop skill
(init stamped it into .claude/skills/loop/):
The session becomes the orchestrator: it spawns one fresh sub-agent
per cycle (the ledger is the only memory — no context rot), holds the tree
lock, and gates every cycle on recurve matrix --gate. init also stamps
.claude/settings.json with defaultMode: bypassPermissions, so a CLI
session runs cycles without stopping for permission prompts. That is safe
because the loop is a cage: the write boundary keeps each sub-agent off
the referee surface, per-cycle commits make any cycle a one-command
rollback, and nothing closes without the gate. (For one cycle only, invoke
the cycle skill instead.)
recurve run is the wrapper: it fills in a headless bypass-permissions
agent (an unattended cycle cannot answer a prompt), the cap, and macOS
keep-awake, then execs the stamped workflow. --dry-run previews the exact
invocation; --agent '<cmd>' (or $AGENT_CMD) overrides the default;
--lanes N runs parallel lanes. To drive the raw workflow yourself:
AGENT_CMD='claude -p --permission-mode bypassPermissions' CAP=12 \
caffeinate -dimsu bash .recurve/workflows/burndown.sh
The loop believes only the run-record and the gate, never the agent's word.
It declares done only when the stopping controller returns STOP-SUCCESS
over the measured vector — the spec is sound, complete, and not diverged —
never merely because the backlog emptied. The cap, consecutive failures, and
runaway scope are backstops; un-greenable gaps are parked and the loop moves
on. (AGENT_CMD is any harness that reads a prompt on stdin and writes a
run-record to $RECURVE_RESULT_FILE.)
Any chat host — planned
An MCP server (recurve-mcp) will expose the loop's verbs to any chat host
(Claude Desktop, other IDEs, non-Claude agents) — the same in-session model,
beyond Claude Code. Not shipped yet.
While it runs¶
Read-only peeking is safe from another terminal:
git log --oneline # one commit per landed cycle
tail -f .recurve/state/records.jsonl # the run dataset, live
recurve park # anything parked so far
Don't run anything that writes in the target — the loop holds the tree lock, and it is the single writer by design.
When it halts¶
recurve matrix # what turned GREEN, and is the gate holding
recurve stats # close rates (raw AND budgeted c%@1/c%@2), trap debt
recurve park # parked gaps + attempt journals (the next run's seed)
recurve drill # re-prove every guard can still fail (--fuzz/--iso/--diff to measure)
The run's records are a dataset in their own right — budgeted close rates, branch capture, and a verification-gated JSONL export are covered in Run data & trajectories; auditing the probes themselves is Hardening your probes.
The human queue, in order: adjudications first (one sentence unblocks the
most agent-work), then review-gated promotions (see .recurve/REVIEW.md),
then parked triage.
Keep the evidence
Gate with recurve matrix --gate --receipts to chain a tamper-evident
receipt per verdict, then recurve receipts verify to re-check the trail.
You can pin each receipt to a signer of your choice — see
Evidence & receipts.
Cancel and resume¶
Cancel: Ctrl-C in the loop's terminal, any time.
- Completed cycles are already durable — each landed as its own commit, with its run record appended and the ledger promoted.
- The in-flight cycle dies with the loop; at worst it leaves uncommitted
partial work. Inspect with
git status; you (the human) may freely discard or stash it — the never-reset rule binds agents, not the owner. -
The tree lock releases on exit. If the terminal died hard and it didn't:
Resume: just re-run the same command. The loop has no state of its own —
the ledger is the only memory. Preflight re-runs validate and
matrix --gate first, so if the interrupted cycle broke anything, the loop
refuses to start and tells you what's wrong before burning a single new
cycle. Seed known-stuck gaps with PARKED_SEED=GAP-1,GAP-2 so the new run
skips them.
Closing the laptop lid
Stop the loop first. A sleeping machine mid-cycle is indistinguishable
from a hung agent, and caffeinate cannot prevent lid-sleep on battery.
What decides when it's done¶
The three steps above are the everyday workflow — claims, probes, the gate, the
ledger. Underneath, a verification layer is what decides when the loop is
done: the success-halt is a stopping controller's STOP-SUCCESS over a measured
vector — sound, complete, and not diverged — never an empty backlog. It also
tracks what no claim covers (the frontier) and whether the build diverged from
intent. That machinery is for people extending recurve; see
The verification layer.