kennethzychew's picture
seed: specs + loop scaffolding
3a5b10f
|
Raw
History Blame Contribute Delete
4.77 kB
# LOOP.md β€” How to Run This Overnight
This runs the **TONIGHT** scope in `PROGRESS.md` unattended and stops at the
`β›” STOP` boundary. It builds the deterministic core (schema, validation,
routing, backend interface + offline stub, stub-backed core pipeline). It needs
**no Gemini key and no Ollama** β€” those are tomorrow.
## Before you start
- Be on a throwaway branch or an isolated worktree so the night's work is
contained and easy to review:
`git switch -c overnight-build` (or `git worktree add ../overnight overnight-build`).
- Have these in the repo root: `CLAUDE.md`, `PROGRESS.md`, `LOOP.md`,
`.claude/agents/verifier.md`, and the specs in `docs/`.
- Be logged into Claude Code as usual. The loop uses your existing auth; on a
subscription it counts against your normal weekly rate limit, on an API key it
bills pay-as-you-go (the `--max-budget-usd` guard below applies in that case).
## Recommended: the driver loop (one task per iteration, commit each)
A fresh context per iteration means no context-window drift over a long night,
each task is its own commit, and a single crashed iteration just resumes from
the ledger next loop.
```bash
#!/usr/bin/env bash
# run-overnight.sh β€” stops itself at the PROGRESS.md β›” STOP boundary
set -u
for i in $(seq 1 20); do
echo "=== iteration $i ==="
claude -p "Read PROGRESS.md, CLAUDE.md, and the specs in docs/. Do the NEXT
unchecked task in the TONIGHT section only β€” exactly one. Implement it per
docs/05_build_plan.md. Run that task's Check command and paste the output.
If it passes: commit just that task's changes with its Commit message, then
tick its box in PROGRESS.md and commit that. If it fails after reasonable
attempts: add a one-line note under BLOCKED in PROGRESS.md, commit, and move
on. NEVER start a TOMORROW task. NEVER add a dependency outside task N1's
night set. NEVER edit files in docs/. When every TONIGHT box is checked, run
'uv run pytest -q' and 'uv run ruff check .'; if both are clean, print
exactly DONE_ALL." \
--allowedTools "Read,Edit,Write,Bash" \
--permission-mode acceptEdits \
--max-turns 25 \
--max-budget-usd 0.75 \
--output-format json | tee "run_$i.json"
if grep -q "DONE_ALL" "run_$i.json"; then
echo "All TONIGHT tasks complete."; break
fi
done
```
Launch it and walk away:
```bash
chmod +x run-overnight.sh
nohup ./run-overnight.sh > overnight.log 2>&1 &
```
(`nohup ... &` keeps it running if the terminal closes. For a laptop that
sleeps, run it in `tmux` on a machine that stays awake.)
## Alternative: a single `/goal` session
Simpler, one process. `/goal` keeps the session going until a small evaluator
model confirms the condition from the transcript, so the condition ends by
running the proof commands. It has no built-in budget, hence the turn cap.
```bash
claude -p "/goal Every task in the TONIGHT section of PROGRESS.md is checked
off, and 'uv run pytest -q' exits 0, and 'uv run ruff check .' reports no
errors. Work one TONIGHT task at a time, top to bottom; after each task's
Check passes, commit it with its PROGRESS.md message and tick its box. Never
start a TOMORROW task. Never add a dependency outside task N1's night set.
Never edit docs/. Prove completion by running pytest and ruff and printing
'cat PROGRESS.md' at the end. Stop after 60 turns regardless." \
--allowedTools "Read,Edit,Write,Bash" \
--permission-mode acceptEdits
```
The driver loop is the safer choice for a long unattended night; `/goal` is
fine if you prefer one process and will glance at it.
## Guardrails (why this is safe to leave)
- **Hard scope:** both the ledger and the prompt forbid starting TOMORROW work
or adding model dependencies, so it cannot wander into Gemini/Ollama.
- **Isolation:** running on a branch/worktree means the morning review is a
clean diff and nothing touched `main`.
- **Caps:** `--max-turns` (and `--max-budget-usd` on API billing) stop a runaway
iteration; the loop caps total iterations.
- **Broad Bash is granted** so it can run `uv`, `pytest`, and `git` β€” which is
exactly why you keep it on an isolated branch.
## In the morning
1. `git log --oneline` β€” you should see roughly one commit per N-task.
2. **Read the diffs.** Agents are good at *looking* done; the test suite is the
real gate, but skim the code. `uv run pytest -q` yourself.
3. Check `PROGRESS.md`: which TONIGHT boxes are ticked, and read any **BLOCKED**
entries β€” those are your first fixes.
4. Then continue with TOMORROW: set up the Gemini key (and/or Ollama), implement
the Docling/OCR parsing and the two backends, wire the real `acquire` into
`core.py`, then persistence, the watcher, the web demo, and the eval harness.