diff --git a/docs/AUTONOMOUS-LOOP.md b/docs/AUTONOMOUS-LOOP.md index 8fb3479f..9d548c8a 100644 --- a/docs/AUTONOMOUS-LOOP.md +++ b/docs/AUTONOMOUS-LOOP.md @@ -103,6 +103,69 @@ fires one final time, then deletes itself."* For runs longer than 7 days, the `long-term-rescheduler` skill rotates crons near expiry via `CronDelete` + `CronCreate`. +## Invariant — rediscoverable from `main` alone + +This discipline serves a load-bearing invariant: + +> **A fresh agent reading `main` alone — no chat history, +> no in-session memory, no out-of-band context — can pick +> up the next tick and continue the work cleanly.** + +The every-tick checklist below is *a* mechanism that +preserves this invariant; it is not itself the invariant. +The number of checklist steps is incidental — discoverability +from `main` alone is what's load-bearing. + +Concretely, every change to this file MUST preserve (or +strengthen) the invariant. The check is: *can a freshly +spawned agent, reading only committed-on-`main` artifacts, +find the prior tick's state and act on it?* If yes, the +invariant holds. If no, the change has broken it. + +Four properties make the invariant true today: + +- **Tick-history is on `main`.** Each tick lands a row in + `docs/hygiene-history/ticks/YYYY/MM/DD/HHMMZ.md` before + the tick stops, so the next session sees the prior tick's + context by reading the repo. +- **PR queue is on the host.** Open PRs are visible via + `gh pr list` without session state; the next tick can + poll the gate (real-dependency-wait discipline) without + remembering which PRs are in flight. +- **Substrate precedes narration.** Decisions, corrections, + and framings land as memory files / backlog rows / docs + in committed substrate BEFORE chat narration. Per + substrate-or-it-didn't-happen (Otto-363) + + non-durable-means-does-not-exist (the human maintainer, + 2026-04-30), if it isn't on `main`, the next tick + won't see it. +- **Cron is the cadence engine, not session memory.** The + every-minute heartbeat fires whenever a session is active + to receive it; `CronList` is checked end-of-tick so the + [last-check → next-fire] window is minimized; the next + tick fires without depending on the prior tick's + process state. Sessions that resume via `--resume` / + `--continue` inherit the registered cron when it's still + within its 7-day expiry; brand-new sessions re-arm via + the every-tick checklist (per the "Session-restart + recovery" section below). + +Future revisions of this file may add, drop, or restructure +the checklist below — provided the rediscoverable-from-`main` +invariant is preserved or strengthened. Treat the four +properties above as the test surface. + +> The human maintainer, 2026-04-30 (paraphrased — the original +> framing was "Six-step tick close has a satisfying property +> that should be an invariant for all future changes to this +> file" followed by a sharpening "not six step the +> rediscoverable on main part"; the bracketed gloss reflects +> the sharpening): *"[the rediscoverable-on-main part] +> should be an invariant for all future changes to this +> file."* The meta-property is what makes the discipline +> portable across sessions, agents, and forks of the +> factory. + ## The every-tick checklist This is the load-bearing bit. **Every tick**, in order: