Prompt file imported from dmooney/Rundale (
.claude/commands/todo-drain.md). Copyright stays with the author.
Land fixes from TODO.md (Rundale demo-audit findings). Run rounds in parallel — start the next round while the previous PR's CI runs.
Workflow per round
1. Sync + worktree
Never work in the main repo directory — other sessions may be using it. Switch into (or create) a worktree off latest origin/main:
git fetch origin main
git worktree add .claude/worktrees/round-<n> -b claude/round-<n> origin/main
Then EnterWorktree to that path so all subsequent commands run inside the worktree.
2. Pick TODO item
Open TODO.md. Prefer the smallest-scope unaddressed P0/P1. If the entry has a "revise" note pointing at a different ID, follow it.
3. Write acceptance criteria FIRST
Before any code change:
.proofs/todo-<id>/acceptance-criteria.md— observable criteria, sized concretely (e.g. "frequency_penalty: Option<f32>field onInferenceRequest", not "improve repetition handling"). Include a "Deferred items" section listing anything intentionally punted from this round.limerick/testing/fixtures/play_todo-<id>.txt— harness commands that exercise the new code path inlimerick-engine --headless --script.
4. Implement
Smallest possible diff. When threading a new param through multiple layers (inference, IPC, UI), delegate the mechanical pass-through edits to a sonnet sub-agent — saves opus context.
Then decide whether this finding's category warrants a permanent guard: if it has now been fixed more than once (e.g. auto-player movement, mid-conversation farewells, mood→emoji sign), add a rubric_* test in limerick/crates/limerick-engine/tests/eval_baselines.rs in the same PR so the regression cannot silently return. See docs/agent/harness.md → "Turning a recurring mistake into a sensor".
5. Run quality gates
From within the worktree:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test -p <changed-crate>
For UI changes also:
cd limerick/apps/ui && npx vitest run && pnpm run check
6. Capture live transcript
cargo run -p limerick-engine -- --headless --script \
limerick/testing/fixtures/play_todo-<id>.txt > /tmp/transcript.txt
cp /tmp/transcript.txt .proofs/todo-<id>/transcript.json
For UI-only changes the engine harness is regression cover only — actual UI behaviour is verified in vitest. Note this in evidence.md.
7. Write evidence.md
First line must be Evidence type: live gameplay transcript. Include:
- Diff summary table (file, change).
- Acceptance-criteria → evidence map (one row per AC, citing
file:lineor test name). - Commands run.
- Transcript excerpt.
- "Why this fixes #N" explainer.
- "Deferred items" section listing what was punted with a follow-up plan.
8. Write judge.md
Independent verdict. Must end with all three lines verbatim:
Verdict: sufficient
Technical debt: clear
Acceptance criteria: met
Include risk-check (save compatibility, prompt budget, mode parity, architecture-fitness) and an acceptance-criteria audit table.
9. Commit + push + PR
- Conventional commit (
feat:/fix:/refactor:/docs:/test:/chore:). - Body explains the why, not the what; ends with
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>. - PR title prefix matches commit.
- PR body has Summary + Test plan checklist +
Proof bundle: .proofs/... posted via attach-proof.
10. Attach proof bundle
From the worktree:
bash limerick/scripts/attach-proof.sh todo-<id> <pr-num>
Do NOT call just attach-proof from a worktree — that uses the main repo's justfile and posts the wrong bundle.
11. Start next round immediately
Don't wait for CI. Branch off origin/main again with git worktree add ... -b claude/round-<n+1> and repeat 2-10.
Keep a running Monitor of all in-flight PRs:
prev=""
while true; do
s=$(for pr in <ids>; do
gh pr checks $pr --json name,bucket 2>/dev/null \
| jq -c "[.[] | {name: (\"$pr/\" + .name), bucket}]"
done | jq -s 'add')
cur=$(jq -r '.[] | select(.bucket!="pending") | "\(.name): \(.bucket)"' \
<<<"$s" | sort)
comm -13 <(echo "$prev") <(echo "$cur")
prev=$cur
jq -e 'all(.bucket!="pending")' <<<"$s" >/dev/null 2>&1 && break
sleep 60
done
echo "ALL TERMINAL"
12. Land green PRs
When monitor reports green:
gh pr merge <N> --squash --delete-branch
- The "main worktree" branch-delete error is harmless — merge succeeded on remote; verify via
gh pr view <N> --json state,mergeCommit. - Gemini
review / review: cancelis normal (auto-cancelled bot review, not a real failure).
Known CI failure patterns + fixes
-
Rust quality gate / coverage ratchet
cancel. Concurrency rule (cancel-in-progress: true) killed older runs when a new push happened. Push an empty commit to retrigger:git commit --allow-empty -m "ci: retrigger after auto-cancel" && git pushDo NOT try
gh pr close && gh pr reopenfirst — classifier may deny it. -
Agent proof gate
failon first run after PR open. Race: CI started beforeattach-proofposted the bundle comment. Retrigger via empty commit; second run finds the bundle and passes. -
gh workflow runHTTP 500. Workflow file isn't on the branch HEAD or validation issue. Use empty commit + push instead.
Boundaries
- Never commit other sessions' leaked WIP from the main repo.
- Never force-push to a PR branch — bot review threads anchor to commit SHAs and force-push detaches them.
- Never amend; always create new commits. Pre-commit hook failures didn't actually commit, so
--amendwould corrupt prior history. - Don't touch
.proofs/archives indocs/proofs/local-perfordocs/proofs/rundale-bench— bench archives, exempt from the gate. - After each landed PR, do not edit
TODO.mdto mark items done — leave it as the demo-audit record; the PR commit IS the marker.
Stop conditions
Stop when:
- User says "stop" or "pause".
TODO.mdhas no remaining unaddressed P0/P1 items.- 3+ consecutive rounds hit unrelated infra failures (signal: real bug in workflow, not your code; escalate to user).
