docs(specs): task loops — sequential multi-session batch runs - #1
miquido-adamk wants to merge 2 commits into
Conversation
|
🤖 The spec was written autonomously. Every question it resolved is listed here for override. Four carry
Labels: only |
🤖
|
|
🤖 The implementation of this spec is now tracked at #2 — Implement: task loops — drain a list of work items as a sequence of separate sessions. This PR stays design-only: it adds the spec, the brief and the UI evidence, and nothing else. Implementation ships on its own PR referencing it, per the pipeline's spec/implementation split. Issue #2 links back to this PR and to
The one exception recorded on the issue: Phase 0, the source-neutral launch-adapter extraction, is behavior-preserving and independently deployable, so it may proceed as soon as open-mercato#846 lands — it does not wait on the ⚠ confirmations. |
Source doc:
.ai/specs/2026-08-19-task-loops.mdDesign only — no implementation in this PR.
What this specifies
A loop: an ordered list of independent work items run as a strict sequence of ordinary cezar tasks, one session/worktree/branch per item, advancing only when the previous item's run reaches a terminal state. The counter lives in persisted project-local state driven by the workspace coordinator, so a restart resumes instead of losing the loop.
The framing that shapes everything else: a scheduled task fires when the clock strikes; a loop fires when the previous run finishes. That barrier — and the set of ways an awaited run can fail to finish — is the whole spec.
Why it is a draft
Four assumptions carry
⚠ NEEDS HUMAN CONFIRMATION; merge is gated on confirming them. See the Open Questions comment below.The most consequential: on a zero-config install a loop delivers N branches, not N landed changes.
reviewGateEnabledis off by default andsettleSuccessskips the gate entirely for autonomous runs, so every autonomous run today settles todonewith no PR. That is a general defect of autonomous runs, not of loops, so this spec deliberately does not fix it — which makes the delivered feature smaller than the original request. If that is unacceptable, this spec should not ship first.Blocked on
Not implementable until open-mercato#846 (postponed tasks, Phase 1 of epic open-mercato#771) lands. open-mercato#771 requires "one coordinator, one occurrence model, one ordinary run launch adapter" and forbids "a second scheduler, store, route family, or launch path", so this consumes that foundation rather than cloning the automations module a third time (measured: 39 files, +2872 lines). Every reference to those seams is written conditionally, because none exist in this tree yet.
The foundation spec defers "a source-neutral extraction … when a third caller needs it" — this feature is that caller, so Phase 0 performs the extraction as its own landed, behavior-preserving change.
Scope calls worth reviewing
Three earlier direction choices were reversed after the design review; each is flagged as reversible in the spec:
Corrections found by review, verified in code
monitoringitem now pauses the loop instead of advancing past it — advancing left the run alive, which breaks the width-1 invariant, andbusySlots()only exempts monitoring up tomaxMonitoringSessions().pruneOldRunsdeletes runs with no emit at all (store.ts:1177-1180) — an awaited run can vanish in total silence.waitingis not one of the traps:armIdleTimerends the session and it settles withinIDLE_TIMEOUT_MS. The real ones aremonitoring,failed+autoResumeAt, and restart-transit throughfailed.Evidence
Current-state screenshots captured from the running app (
CEZ_DRY_RUN=1) are committed under.ai/specs/assets/task-loops/and inline in the spec's UI/UX section. They corrected the design: the composer already carries×1(parallel variants) and aStart/Plan firstcontrol, so Loop is specified as the sequential sibling of×1and mutually exclusive with it.Breaking Changes
None — design only.