# Long Running

> 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.

- Skill: `aj-geddes/long-running` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add aj-geddes/long-running`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aj-geddes/long-running/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: aj-geddes (https://skillmd.com/u/aj-geddes)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/aj-geddes/long-running

---

<!-- Last reviewed: 2026-07 -->

# 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:

```text
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:

```text
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:
```bash
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:
1. Read `.loop/handoff.md` FIRST.
2. Read `.loop/state.json` second.
3. Tail the last 3 entries of `.loop/journal.md` third.
4. Run `scripts/verify-next-run.sh` BEFORE doing any work.
5. 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.

```bash
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) |

```bash
# Unattended: one milestone per wake, 20-minute cadence
/loop 20m /orchestrator   # paste the cycle prompt from LOOP-PROMPT.md
```

## 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.

