/iterate-code — codebase Ralph loop
Same objective fed back every iteration until genuinely complete. No simulator, no UI — source, tests, and tooling only. Your memory is the filesystem: the ledger, the journal, and git history. An iteration that didn't update the ledger didn't happen.
Completion promise: output ITERATE-CODE COMPLETE: all ledger items done or explicitly deferred ONLY when literally true. If blocked on something only a human can do, output ITERATE-CODE BLOCKED: <exact ask> and stop. Never emit either to escape the loop.
State files
.iterate/ledger.md — the work queue. One line per unit: [state] ID — title | acceptance: <command or named check> | evidence: <last result>. States: todo, doing (max ONE at a time), done, stuck, blocked-human, deferred. This is the single source of truth for progress; never track progress only in your head or the chat.
.iterate/journal.md — one section per iteration: what you did, evidence observed, what you learned, note-to-future-self. Plus a META block (see below).
- Git history — commit per green unit, message
iterate(N): <unit ID> <what>. History must stay bisectable: every commit analyzes/builds clean.
Iteration 0 — bootstrap (only if the ledger doesn't exist)
- Read the objective and its source documents fully. (In
fartwithfriends, the backlog source is docs/plan/05-beta-contract.md §12 plus the Session Handoff in docs/plan/README.md — do not invent a parallel plan.)
- Decompose into the smallest independently verifiable units — a unit is too big if you can't name its acceptance command, too small if verifying it proves nothing. Order leaf-first by dependency.
- For every unit, write the acceptance check before any code: a test command, an analyzer/typecheck gate, a grep that must return empty, a script exit code. "Looks right" is not an acceptance check.
- Write the ledger; commit it.
Every iteration
- Re-orient (fresh eyes, ~2 min): read the ledger, the last two journal sections, and
git log --oneline since the last journal entry — other agents or your past self may have moved things. Reconcile the ledger to reality before working: a done claim you can't tie to a commit and evidence gets demoted back to todo.
- Select: exactly one
todo unit — the highest-priority unblocked one. Mark it doing. Never hold two doing items; never start a new unit to avoid finishing a hard one.
- Verify-first: run the unit's acceptance check now, before changing anything. If it already passes, mark
done with evidence and select again (inherited work is real work). If it fails, you now have the exact target.
- Work small: implement in the smallest diffs that could move the check. Run focused tests as you go, the full affected-domain check before commit. Match surrounding style; no drive-by refactors — if you spot adjacent debt, add it to the ledger as a new unit instead of fixing it inline.
- Verify with evidence: re-run the acceptance check and read its actual output. Green from a stale run, a skipped test, or a weakened assertion is not green. Forbidden moves: deleting/skipping a failing test to pass, loosening the contract the check encodes, rerunning flaky checks until they happen to pass (fix or ledger the flake instead).
- Commit the unit atomically (source + tests + docs it touched). Mark
done with the evidence line. If other agents share the tree, stage explicit paths only.
- Journal, including a one-line note-to-future-self: the thing you'd want to know if you woke up here with no memory.
Stuck protocol
- Three genuine fix attempts on the same failure → mark
stuck with the exact failing evidence and your best hypothesis, then move on. Grinding a stuck item burns iterations that other units could use, and the answer often falls out of later work.
- Revisit
stuck items only when something material changed (a dependency landed, new information in the journal). Two revisits later, escalate to blocked-human with a precise question.
- Distinguish stuck (you can't make the check pass) from blocked-human (credentials, approvals, product decisions, live targets). Never force the latter; never park the former as the latter to avoid hard work.
META block (append to the journal every 3 iterations)
Answer honestly, in four lines:
- Velocity: units done per iteration, trending up or down? If down two checks in a row, your units are too big — re-split.
- Drift: re-read the original objective; does the ledger still serve it, or have you been optimizing something adjacent? Kill drifted units.
- Patterns: any failure appearing across units (same flaky harness, same misunderstood API)? Fix the cause once as its own unit instead of paying it per-unit.
- Regression canary: re-run the acceptance check of one random
done unit. If it fails, something you did since broke it — that's the new top priority, and a sign your checks are too narrow.
Ending
Cap at 15 iterations by default (override via argument). On completion, cap, or block: write a final journal section — done/deferred/stuck/blocked table with evidence links, remaining risks ranked, and the exact next command a successor should run — then output the completion or blocked line. Leave the ledger accurate; a truthful half-finished ledger is worth more than an optimistic finished-looking one.
1---2name: iterate-code3description: Codebase-only Ralph loop — decompose an objective into small verifiable work units, complete and verify them one per iteration with evidence-first discipline, and track both progress and the meta of the run (velocity, stuck patterns, drift) in a persistent ledger. Use when asked to /iterate-code, grind through a backlog/plan, or autonomously work a codebase to completion without a UI/simulator.4---56# /iterate-code — codebase Ralph loop78Same objective fed back every iteration until genuinely complete. No simulator, no UI — source, tests, and tooling only. Your memory is the filesystem: the ledger, the journal, and git history. An iteration that didn't update the ledger didn't happen.910**Completion promise:** output `ITERATE-CODE COMPLETE: all ledger items done or explicitly deferred` ONLY when literally true. If blocked on something only a human can do, output `ITERATE-CODE BLOCKED: <exact ask>` and stop. Never emit either to escape the loop.1112## State files1314- `.iterate/ledger.md` — the work queue. One line per unit: `[state] ID — title | acceptance: <command or named check> | evidence: <last result>`. States: `todo`, `doing` (max ONE at a time), `done`, `stuck`, `blocked-human`, `deferred`. This is the single source of truth for progress; never track progress only in your head or the chat.15- `.iterate/journal.md` — one section per iteration: what you did, evidence observed, what you learned, note-to-future-self. Plus a **META** block (see below).16- Git history — commit per green unit, message `iterate(N): <unit ID> <what>`. History must stay bisectable: every commit analyzes/builds clean.1718## Iteration 0 — bootstrap (only if the ledger doesn't exist)19201. Read the objective and its source documents fully. (In `fartwithfriends`, the backlog source is `docs/plan/05-beta-contract.md` §12 plus the Session Handoff in `docs/plan/README.md` — do not invent a parallel plan.)212. Decompose into the **smallest independently verifiable units** — a unit is too big if you can't name its acceptance command, too small if verifying it proves nothing. Order leaf-first by dependency.223. For every unit, write the acceptance check **before any code**: a test command, an analyzer/typecheck gate, a grep that must return empty, a script exit code. "Looks right" is not an acceptance check.234. Write the ledger; commit it.2425## Every iteration26271. **Re-orient (fresh eyes, ~2 min):** read the ledger, the last two journal sections, and `git log --oneline` since the last journal entry — other agents or your past self may have moved things. Reconcile the ledger to reality before working: a `done` claim you can't tie to a commit and evidence gets demoted back to `todo`.282. **Select:** exactly one `todo` unit — the highest-priority unblocked one. Mark it `doing`. Never hold two `doing` items; never start a new unit to avoid finishing a hard one.293. **Verify-first:** run the unit's acceptance check now, before changing anything. If it already passes, mark `done` with evidence and select again (inherited work is real work). If it fails, you now have the exact target.304. **Work small:** implement in the smallest diffs that could move the check. Run focused tests as you go, the full affected-domain check before commit. Match surrounding style; no drive-by refactors — if you spot adjacent debt, add it to the ledger as a new unit instead of fixing it inline.315. **Verify with evidence:** re-run the acceptance check and read its actual output. Green from a stale run, a skipped test, or a weakened assertion is not green. Forbidden moves: deleting/skipping a failing test to pass, loosening the contract the check encodes, rerunning flaky checks until they happen to pass (fix or ledger the flake instead).326. **Commit** the unit atomically (source + tests + docs it touched). Mark `done` with the evidence line. If other agents share the tree, stage explicit paths only.337. **Journal**, including a one-line note-to-future-self: the thing you'd want to know if you woke up here with no memory.3435## Stuck protocol3637- Three genuine fix attempts on the same failure → mark `stuck` with the exact failing evidence and your best hypothesis, then **move on**. Grinding a stuck item burns iterations that other units could use, and the answer often falls out of later work.38- Revisit `stuck` items only when something material changed (a dependency landed, new information in the journal). Two revisits later, escalate to `blocked-human` with a precise question.39- Distinguish *stuck* (you can't make the check pass) from *blocked-human* (credentials, approvals, product decisions, live targets). Never force the latter; never park the former as the latter to avoid hard work.4041## META block (append to the journal every 3 iterations)4243Answer honestly, in four lines:44- **Velocity:** units done per iteration, trending up or down? If down two checks in a row, your units are too big — re-split.45- **Drift:** re-read the original objective; does the ledger still serve it, or have you been optimizing something adjacent? Kill drifted units.46- **Patterns:** any failure appearing across units (same flaky harness, same misunderstood API)? Fix the *cause* once as its own unit instead of paying it per-unit.47- **Regression canary:** re-run the acceptance check of one random `done` unit. If it fails, something you did since broke it — that's the new top priority, and a sign your checks are too narrow.4849## Ending5051Cap at 15 iterations by default (override via argument). On completion, cap, or block: write a final journal section — done/deferred/stuck/blocked table with evidence links, remaining risks ranked, and the exact next command a successor should run — then output the completion or blocked line. Leave the ledger accurate; a truthful half-finished ledger is worth more than an optimistic finished-looking one.