| name | long-running |
| description | Orchestrates long-running, multi-iteration tasks with Fable-5-style checkpointing, resume packs, self-paced scheduling, and per-iteration enforcement gates. ALWAYS trigger on "long running task", "keep working", "work overnight", "autonomous loop", "checkpoint", "resume where we left off", "iterate until done", "multi-session task", "self-pacing", "background build". Use when a task spans multiple iterations, sessions, or context windows. Different from orchestrator which routes a single pass -- this skill manages state, pacing, and enforcement across iterations. |
Long-Running Tasks
This skill mimics the Fable 5 long-horizon harness by enabling multi-iteration workflows with durable state, self-pacing, and iterative enforcement. It adds two core primitives: durable .loop/ state files that persist across sessions, and the unicorn-team:loop-assist GO/NO-GO gate that enforces quality and coherence at every iteration boundary.
Fable 5 gets this machinery from its harness: scheduled wakeups, context continuation, a durable
workflow journal, and between-turn verification. On sonnet or opus none of that exists, so this
skill reconstructs each piece from files, agents, and commands the plugin already has. The
operating principle: the loop is only as durable as its state files.
When to Use
| Situation | Use this skill? |
|---|
| Task spans multiple iterations/sessions/context windows | Yes |
| Overnight/unattended build-out via /loop | Yes |
| Babysitting an external system (CI, deploy) | Yes |
| Migration or backfill touching many modules over hours | Yes |
| Long build/suite you would otherwise poll | Yes (see background discipline) |
| Single-pass implementation that fits one context window | No, route via orchestrator |
| One-off question or small fix | No, answer or delegate directly |
1. Fable Parity
| Fable 5 harness capability | Plugin equivalent |
|---|
| ScheduleWakeup self-pacing (delaySeconds, cache windows) | Pacing table + /loop interval guidance in long-running skill |
| Context summarization + continuation | .loop/handoff.md resume pack, rewritten every iteration for a fresh-context reader |
| Workflow journal + resumeFromRunId | .loop/journal.md append-only iteration log + deterministic re-entry protocol |
| Background tasks + task notifications | run_in_background + check-on-wake discipline (never busy-poll) |
| Token-budget directives (+500k style) | budget block in .loop/state.json + stop conditions |
| Harness verify/enforcement | unicorn-team:loop-assist GO/NO-GO gate each iteration |
Full per-capability detail lives in references/fable-parity.md.
2. Iteration Lifecycle
The lifecycle is: ORIENT -> EXECUTE -> VERIFY -> CHECKPOINT -> ENFORCE -> PACE.
| Step | What happens | Agent / tier | Artifact touched |
|---|
| ORIENT | Read .loop/handoff.md then .loop/state.json; never re-derive state from raw git history. Cheap (haiku-grade reading). | haiku | handoff.md, state.json |
| EXECUTE | Delegate next milestone to unicorn-team:developer @ sonnet; TDD mandatory (RED -> GREEN -> REFACTOR). | sonnet | code + tests |
| VERIFY | unicorn-team:qa-security @ sonnet for risky milestones; otherwise run tests + lint directly. | sonnet | tests, lint output |
| CHECKPOINT | Update state.json (milestone status, iteration++), APPEND journal.md, REWRITE handoff.md from scratch. | self | state.json, journal.md, handoff.md |
| ENFORCE | Spawn unicorn-team:loop-assist @ haiku. GO -> continue; NO-GO -> re-delegate fix-list (max 2 rounds); STOP -> finalize. | haiku | state.json, handoff.md |
| PACE | Choose next interval from pacing table, or end loop. | self | pacing table |
ORIENT
- Read
.loop/handoff.md to reconstruct the current goal and context.
- Parse
.loop/state.json to identify the next milestone and its status.
- Confirm no conflicting state (e.g., more than one milestone marked in_progress).
- Validate that state.json is syntactically valid and contains required fields.
- Discard any assumptions derived from prior context; treat as fresh reader.
EXECUTE
- Delegate the next milestone using the following prompt template:
Agent tool -> unicorn-team:developer @ sonnet
Milestone ID: {milestone-id}
Title: {milestone-title}
Acceptance Criteria:
{acceptance-criteria}
TDD Mandate: RED -> GREEN -> REFACTOR
- Write failing test first (RED)
- Implement minimal code to pass (GREEN)
- Refactor for clarity and maintainability (REFACTOR)
- Run the FULL test suite before committing
- Commit message format: `feat({milestone-id}): <description>`
- Do not commit debug code, console.log, or temporary files
- Do not modify any files outside the scope of this milestone
VERIFY
- For high-risk milestones: invoke unicorn-team:qa-security @ sonnet for security and correctness review.
- For standard milestones: execute
pytest --tb=short and ruff check directly.
- Capture and log all test output, lint warnings, and type-check results.
- Fail fast if any test fails or lint rule is violated.
- Ensure coverage metrics meet minimum thresholds if defined in state.json.
CHECKPOINT
- Increment
iteration counter in .loop/state.json.
- Set current milestone status to
done in milestones[].
- Commit code and state together; the commit is the checkpoint boundary.
- Append a new
## Iteration N -- <ISO date> entry to .loop/journal.md with:
- Actions taken
- Verification results
- Deficiencies found
- Next step summary
- Overwrite
.loop/handoff.md with a fresh, self-contained summary including:
- Current goal
- Summary of completed work
- Exact next step with acceptance criteria
- Known risks or landmines
- Verify commands and key file pointers
ENFORCE
- Invoke
unicorn-team:loop-assist @ haiku with the following prompt template:
Agent tool -> unicorn-team:loop-assist @ haiku
Run: scripts/verify-next-run.sh
Evaluate the following checks:
E1: state.json is coherent (parses, one unambiguous next milestone, acceptance testable)
E2: regression baseline is green (full test suite passes)
E3: verification harness is in place (runner, lint, type config exist; acceptance expressible as failing tests)
E4: working tree is clean (committed, no stray files, no debug code, no unresolved task markers)
E5: handoff.md is fresh (rewritten this iteration, sufficient for fresh agent)
E6: journal.md has appended this iteration's entry
E7: stop conditions are evaluated (budget, iterations, repeated failures, user triggers)
Return exactly one of: GO, NO-GO, or STOP
Include evidence per check (e.g., "E1: two milestones marked in_progress" -> NO-GO)
Repair .loop/ artifacts yourself only when they are the sole deficiency; return
code deficiencies as a fix-list with an owner agent per item.
NO-GO handling
- loop-assist repairs
.loop/ artifacts itself (state.json, journal.md, handoff.md) when they are the only deficiency, then re-runs the checks.
- loop-assist never touches code. Code deficiencies (failing tests, missing tests, uncommitted logic, debug code) come back as a fix-list.
- The orchestrator re-delegates the fix-list to unicorn-team:developer @ sonnet, then re-enforces.
- Maximum 2 remediation rounds per iteration. If the third enforcement still returns NO-GO, stop the loop and report the unresolved deficiencies.
PACE
- Consult the Pacing table to select the next interval.
- If all milestones are done, or stop conditions are met, terminate the loop.
- If NO-GO was returned, remediate and re-enforce now; do not pace until the gate returns GO or STOP.
- If waiting on external system (CI, deploy), use 60-270s.
- If no external dependency, use 1200s as default fallback.
- Never use intervals below 60s or above 1800s unless explicitly justified.
3. Pacing
| Waiting on | Interval | Why |
|---|
| External state that changes in minutes (CI, deploy, queue) | 60-270s | Stays inside the 5-min prompt-cache window |
| Anything "about 5 minutes" | 270s, never ~300s | 300s pays the cache miss without amortizing it |
| Work that takes tens of minutes / idle heartbeat | 1200-1800s | One cache miss buys a long wait |
| Harness-tracked background work | Long fallback only (1200s+) | Completion re-invokes you; polling is waste |
Stop conditions
Evaluated at ENFORCE from state.json stop_conditions[] and budget. Canonical triggers:
- All milestones done.
- Iteration budget (budget.iterations_max) exhausted.
- Same failure occurs 3 iterations in a row.
- Any user-declared stop_conditions[] entry met.
On STOP: finalize journal + handoff, report final state, end loop. Record which stop
condition fired in the final journal entry.
Worked example
- Overnight FastAPI build-out: milestones sized 50-200 lines ->
/loop 20m
- Waiting on CI between milestones -> 270s
- Suite running via
run_in_background -> 1200s fallback only
- No external dependencies, no CI -> 1200s default
- Manual intervention required -> use 1800s to allow human response window
4. State Files
| File | Discipline | Contents |
|---|
.loop/state.json | machine-readable, single source of milestone truth | goal, milestones[] {id, title, acceptance, status: pending / in_progress / done}, iteration, stop_conditions[], budget {iterations_max, notes}, updated (ISO date) |
.loop/journal.md | APPEND-ONLY | One ## Iteration N -- <date> entry per cycle: did / verified / deficiencies / next |
.loop/handoff.md | REWRITTEN each iteration | Goal, current state summary, exact next step + acceptance criteria, known risks/landmines, verify commands, pointers to key files |
Quickstart bash block:
skills/long-running/scripts/loop-state.sh init "Bookstore inventory REST API"
skills/long-running/scripts/loop-state.sh status
skills/long-running/scripts/loop-state.sh next
skills/long-running/scripts/loop-state.sh check
Never hand-edit state.json mid-iteration; ORIENT (read) and CHECKPOINT (write) are the only
touch points. Full schemas + worked examples in references/state-format.md.
5. Resume Protocol
For a fresh session or fresh context window:
- Read
.loop/handoff.md FIRST.
- Read
.loop/state.json second.
- Tail the last 3 entries of
.loop/journal.md third.
- Run
scripts/verify-next-run.sh BEFORE doing any work.
- If loop-assist returns NO-GO, repair state artifacts before resuming.
On NO-GO:
- Do NOT begin work on the next milestone.
- Repair only .loop/ artifacts: handoff.md, state.json, journal.md.
- Never modify source code, tests, or configuration files.
- Re-run
verify-next-run.sh to confirm all checks pass before continuing.
cat .loop/handoff.md
skills/long-running/scripts/loop-state.sh status
tail -40 .loop/journal.md
skills/long-running/scripts/verify-next-run.sh
The whole resume should cost a few hundred lines of reading, not a re-derivation of history;
that is what the handoff is for.
6. Background Work Discipline
- Use
run_in_background for long builds or test suites.
- Check results on wake; never busy-poll.
- For harness-tracked work (completion re-invokes you), use only long fallback intervals (1200s+).
- Never poll for completion; rely on system re-invocation.
- Always log background task start and end times in journal.md.
- If background task fails, treat as NO-GO in next iteration.
7. How to Run It
| You want | Do this |
|---|
| Interactive session | Drive the lifecycle inline yourself, step by step |
| Unattended interval loop | /loop <interval> with LOOP-PROMPT.md; pick interval from the pacing table |
| Exactly one enforced iteration | /long-task workflow (available after skills/orchestrator/scripts/install-workflows.sh) |
/loop 20m /orchestrator
8. Enforcement Contract
| Check | Certifies | Mechanical or judgment |
|---|
| E1: state coherent | state.json parses, exactly one unambiguous next milestone, testable acceptance | mechanical + judgment |
| E2: baseline green | full suite passes NOW | mechanical |
| E3: harness in place | runner + lint/type config exist; acceptance expressible as failing tests | judgment |
| E4: tree clean + no markers/debug code | committed, no stray files, no unresolved task markers, no debug code | mechanical |
| E5: handoff fresh | rewritten this iteration, sufficient for a fresh-context agent | mechanical (mtime) + judgment |
| E6: journal appended | this iteration's entry exists | mechanical |
| E7: stop conditions | recommend STOP over GO when met | judgment |
The mechanical half is scripts/verify-next-run.sh (exit code = number of failed checks).
Full check definitions and the may-fix vs must-re-delegate table live in agents/loop-assist.md.
References
references/fable-parity.md -- Maps Fable 5 harness features to plugin equivalents.
references/state-format.md -- Full JSON schema and worked examples for .loop/ state files.
scripts/loop-state.sh -- CLI tool to initialize, query, and validate .loop/ state.
scripts/verify-next-run.sh -- Validates enforcement contract; exits with count of failed checks.
agents/loop-assist.md -- Definition of the GO/NO-GO gate agent and its decision logic.
LOOP-PROMPT.md -- Template for unattended loop prompts; defines context and pacing intent.
skills/orchestrator/SKILL.md -- Routing and tiering for the agents this loop delegates to.