Loop Tasks Driver
SkillProductivityLets your agent run a task graph from start to finish, making commits, QA checks, and reviews until the work is done.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Loop Tasks Driver skill
About this capability
Run a requested Compozy spec delivery loop through task checkpoints, scoped QA, review, and PR CI.
What this skill tells your AI
The instructions your AI receives, as published by compozy/compozy in .agents/skills/cy-loop-tasks/SKILL.md and read by ahel’s review.
Drive a Compozy spec to completion as a self-healing continue loop: each
iteration detects the current phase, runs exactly one phase action,
writes memory, updates state.yaml, and prints the iteration summary —
then continues at detect unless the outcome is an evidence-backed external
blocker or Phase E. A failed command stays inside the current phase action:
diagnose, repair, and rerun it before writing iteration state. Filesystem state
still resumes cleanly if the session ends mid-loop.
The loop is a five-phase state machine:
| Phase | Action | Executor |
|---|---|---|
| 0 | bootstrap | orchestrator |
| B | one task or slice + verify + checkpoint commit | orchestrator, or herdr frontend worker |
| C | qa_report, then qa_execution | Fable 5 herdr worker, then orchestrator |
| D | deep-review rounds until SHIP + checkpoint commit per round | orchestrator |
| E | done-signature | orchestrator |
Compatible with ~/dev/ai/codex-loop-plugin goal mode; the plugin itself
is never modified. Prefer in-session continue over waiting for a
Stop→restart — restarts are a resume safety net, not the driver.
Inputs
<slug>— directory name under.compozy/tasks/.<goal_text>— verbatim[[CODEX_LOOP goal="..."]]text or the manual reason for the run. Captured once at bootstrap intostate.yaml.goal_signature.--frontend <claude|cursor>— optional. Selects the frontend worker agent and activates the herdr frontend lane for the whole loop. Captured once at bootstrap intostate.yaml.frontend_agent; when absent, every task runs locally. Syntax examples inreferences/goal-header-template.md.--stacked— optional, default off, tasks mode only. Publishes each Phase B checkpoint as one layer of a GitHub stacked-PR chain (gh stack). Captured once at bootstrap intostate.yaml.stacked. When present, readreferences/stacked-prs.mdin full during bootstrap and verify its prerequisites before the first Phase B iteration.- A pre-authored
.compozy/tasks/<slug>/_spec.md. Without it, bootstrap stops with a blocker.
Helper scripts
Bundled under .agents/skills/cy-loop-tasks/scripts/ — stdlib-only
Python 3.11+, no network, no model calls. Invoke by the explicit repo-root
paths shown in the workflow steps.
| Script | Role | Phase |
|---|---|---|
_state_io.py | private strict state codec (imported, not invoked) | all state helpers |
init-state.py | bootstrap (mutating once) | 0 |
detect-phase.py | read-only | every iteration |
update-state.py | mutating | every iteration |
commit-checkpoint.py | mutating (git commit) | B, D |
test_scripts.py | read-only self-test | skill maintenance only |
Herdr delegation lanes
Two lanes dispatch work to herdr worker TUIs. Before any dispatch, read
references/herdr-delegation.md in full and activate the
herdr-orchestration skill it builds on.
- Frontend lane (Phase B) — active only when
state.frontend_agentis set. While active, every frontend task or slice is dispatched to the selected worker (claude→ Claude Code Opus at xhigh effort,cursor→cursor-agent --yolo --model grok-4.5); the orchestrator session stays in orchestration mode and never implements frontend work itself. - QA-report lane (Phase C) — always active.
qa_reportis produced by a Claude Fable 5 worker (claude --permission-mode auto --model claude-fable-5), launched direct — never plan-first. The orchestrator runsqa_executionitself.
Workflow
Each iteration is one detect → phase action → memory → state → summary cycle. After a completed (non-blocked) summary that is not Phase E, continue at Step 1 in the same turn — do not end the session between rounds.
If any command, gate, worker, or artifact check fails during a phase action,
read references/recovery-loop.md in full immediately and run its repair loop.
Do not write final iteration state or print the summary for an intermediate
failure.
Step 1 — Detect.
- Print
pwdand confirm the working directory is the repo root (the directory containing.compozy/tasks/). On mismatch, locate that root, change into it, and confirm again; block only when the task tree is absent. - Activate
cy-workflow-memoryso its protocol is loaded for later use (once per session is enough; re-activate only if context was dropped). - Run
python3 .agents/skills/cy-loop-tasks/scripts/detect-phase.py <slug>. The printed line decides the whole iteration; the output catalog and entry/exit conditions are inreferences/phase-transitions.md.
Done when: detect-phase emitted exactly one supported phase/action line and the matching branch below is selected.
Step 2 — Run exactly one phase branch.
Phase 0 — Bootstrap
- Confirm
.compozy/tasks/<slug>/_spec.mdexists. Missing → scaffoldmemory/MEMORY.mdfromreferences/memory-protocol.md, record the blocker under## Open Risks, print the iteration summary withoutcome=blocked, and stop (state.yamldoes not exist yet, so there is no update-state call). - Run
python3 .agents/skills/cy-loop-tasks/scripts/init-state.py <slug> --goal "<goal_text>", adding--frontend <claude|cursor>and/or--stackedwhen the invocation text carries the parameter (for--stacked, first readreferences/stacked-prs.mdin full and verify its prerequisites). Mode auto-detects:taskswhen_tasks.mdplus at least onetask_*.mdexist, elsefree. - Activate
cy-spec-preflightfor the phase the next iteration enters (tasks, ortask-bodywhen a single concrete file is next). - Scaffold
.compozy/tasks/<slug>/memory/MEMORY.mdwith the canonical sections fromreferences/memory-protocol.md. - Run
python3 .agents/skills/cy-loop-tasks/scripts/update-state.py <slug> --phase 0 --action "bootstrap (mode=<mode>)" --outcome completed --memory-written "memory/MEMORY.md".
Done when: state.yaml exists and memory/MEMORY.md has the canonical
sections.
Phase B mode=tasks — execute one task
- Take the task printed by detect-phase (
task=<stem>). Read.compozy/tasks/<slug>/<stem>.mdand confirm frontmatterstatus:ispendingorin_progress. Frontmatter wins — on drift, reconcile withupdate-state.py <slug> --task-completed <stem>for already-finished tasks or--reconcile-tasksfor a late-authored graph, then re-run detect-phase. - Mark the task active: flip its frontmatter
status:toin_progress, then runpython3 .agents/skills/cy-loop-tasks/scripts/update-state.py <slug> --task-current <stem>(a marker call — it records no iteration;--task-completedclears it automatically at step 8). - Activate
cy-spec-preflightintask-bodymode for the picked file. - Resolve the shared and current memory paths from
references/memory-protocol.mdand pass them into the lane that executes the work. - Frontend lane — when detect-phase printed
lane=frontend agent=<x>: dispatch the task to that worker perreferences/herdr-delegation.md. The worker owns implementation, memory updates, focused validation, andcy-final-verifyevidence. It never commits. Skip step 6. - Local lane — activate
cy-execute-taskon the picked file with auto-commit disabled. Run the task's focused validation — the commands the task file names plus scoped tests for touched packages; no project-wide gate here (gate map: Critical Rules). Run the task's## Shippable Outcomeverification tier and record its evidence in the task memory:gateis already covered by focused validation;proberuns its named CLI/HTTP/UDS command;smokeopens the surface through its real entry path and captures the touched Visual Contract sections. Thency-final-verifywith the narrow per-task claim. Per-task peer-review requests stay deferred to Phase D and full QA cycles stay in Phase C — flagdocs/qa/scenarios/per the diff and move on. - Confirm memory is updated (written locally, or verified from the worker)
and that
cy-final-verifyevidence is PASS before any state flip. For the frontend lane, verify the worker's evidence instead of re-running verify. - Run
python3 .agents/skills/cy-loop-tasks/scripts/update-state.py <slug> --phase B --task-completed <stem> --action "executed <stem>" --outcome completed --memory-written "memory/<stem>.md,memory/MEMORY.md" --verify-pass. - Run
python3 .agents/skills/cy-loop-tasks/scripts/commit-checkpoint.py <slug> --task <stem>. Stdout starts with a commit SHA orSKIP: no changes; copy it into the iteration summary (in stacked mode astack: submittedline follows — the script owns the layer branch and PR submission, seereferences/stacked-prs.md). On exit 1, enter the repair loop and retry the normal checkpoint after its root cause is fixed. Never bypass the hook with--no-verify.
Done when: task frontmatter, memory, state.yaml, and the checkpoint result
all reflect the same completed task.
Phase B mode=free — execute one slice
- Re-read
_spec.mddeliverables and acceptance in full; compare againststate.progress.checklist[]. - Pick the smallest coherent slice (≤ ~4 hours) that advances at least one acceptance criterion; capture its text exactly.
- Run
python3 .agents/skills/cy-loop-tasks/scripts/update-state.py <slug> --add-progress "<slice text>" --action "slice picked" --outcome completed. - Re-read
state.yaml; the current memory file ismemory/free-iter-<NNN>.md,<NNN>= the new checklist entry'siteration, zero-padded to three digits. - Frontend lane — when
state.frontend_agentis set AND the slice's owned paths are exclusively frontend surfaces (classification inreferences/herdr-delegation.md): dispatch per that reference. The worker owns implementation, memory updates, focused validation, andcy-final-verifyevidence; it never commits. Skip step 6. - Local lane — implement the slice, record decisions and learnings in
the current memory file, run the slice's focused validation (slice-named
commands + scoped tests for touched packages; no project-wide gate) —
for a slice that touches UI, include a smoke pass through the surface's
real entry path — then
cy-final-verifywith the narrow per-slice claim. - Confirm memory is updated and
cy-final-verifyevidence is PASS. For the frontend lane, verify the worker's evidence instead of re-running verify. - Acceptance self-check: when every spec criterion has a completed
checklist entry, add
--deliverables-completeto the step 9 call. - Run
python3 .agents/skills/cy-loop-tasks/scripts/update-state.py <slug> --phase B --complete-progress "<slice text>" [--deliverables-complete] --action "slice <text>" --outcome completed --memory-written "memory/free-iter-<NNN>.md,memory/MEMORY.md" --verify-pass. - Run
python3 .agents/skills/cy-loop-tasks/scripts/commit-checkpoint.py <slug> --slice "<slice text>"with the exact step 3 text — same SKIP / exit-1 semantics as mode=tasks step 8.
Done when: the slice's checklist entry is completed and the checkpoint
result is recorded.
Phase C — QA
Run only the printed action.
qa_report — dispatched, never authored locally:
- Run the B→C boundary gate: one
make gate, repaired to green through the recovery loop before any QA action — cross-task drift surfaces here, not inside a QA cycle. - When release-grade runtime scope needs a lab and no active
bootstrap-manifest.jsonexists, activate the project's QA bootstrap skill first (e.g.eng-qa-bootstrapin Compozy) when installed. - Dispatch the Fable 5 worker per
references/herdr-delegation.md(QA-report lane). The worker activatesqa-reportwithqa-docs-path=docs/qaand updates journey flows,docs/qa/scenarios/files, and cycle charters. - Verify the worker evidence (each reported artifact exists, no worker
commit), then run
python3 .agents/skills/cy-loop-tasks/scripts/update-state.py <slug> --phase C --qa-report-done --action "qa-report produced" --outcome completed --memory-written "memory/qa-report.md,memory/MEMORY.md".
qa_execution — local:
- Activate
qa-executionwithqa-docs-path=docs/qa; it writes the dated run report atdocs/qa/reports/<YYYY-MM-DD>-<slug>.mdand updates scenario-file verdicts. - When the report is "not ready" or a Blocks-Completion/Data-Loss bug is
open, keep the Phase C action open: repair every in-scope bug, rerun the
affected QA, and repeat
qa-executionthrough the recovery loop. Do not set--qa-execution-doneon an intermediate report. - Once the report is ready, run
python3 .agents/skills/cy-loop-tasks/scripts/update-state.py <slug> --phase C --qa-execution-done --action "qa-execution produced" --outcome completed --memory-written "memory/qa-execution.md,memory/MEMORY.md" --verify-pass.
mode=tasks addition: when the printed QA action corresponds to the pending QA
task file, flip that task's frontmatter status: to completed and add
--task-completed <stem> to the same update-state call so tasks.pending
drains.
Done when: the printed QA artifact exists on disk and its flag is recorded in
state.yaml.
Phase D — peer-review rounds until SHIP
One round per iteration; detect-phase re-emits peer_review until the
verdict is SHIP on a verify-PASS tree. Enter this phase only after every
Phase B task or slice is complete and both QA flags are true.
- Activate
deep-reviewfor the round number printed by detect-phase, scoped to the loop's full diff:--base= the ref the loop started from when known (defaultmain),--spec .compozy/tasks/<slug>(contract conformance),--subagent codex(cross-LLM reviewer lane — the implementing model never solely reviews its own work). Later rounds ride deep-review's incremental state; never pass--fullmid-loop. - The loop is the deciding authority over the round: remediate every confirmed finding and every nitpick from the round's review.md in this same iteration, then re-run the project's scoped gate (PR CI is Phase E's). The round's verdict is the SHIP/FIX_BEFORE_SHIP/REWORK value in review.md/state.json.
- Update
memory/peer-review.md(a## Round <N>section per round), then runpython3 .agents/skills/cy-loop-tasks/scripts/update-state.py <slug> --phase D --review-round-done <SHIP|FIX_BEFORE_SHIP|REWORK> --action "peer-review round <N> (<verdict>)" --outcome completed --memory-written "memory/peer-review.md,memory/MEMORY.md" --verify-pass. The call uses--verify-pass: a failed post-remediation gate stays inside the repair loop, and a SHIP verdict on a failing tree is void. - Run
python3 .agents/skills/cy-loop-tasks/scripts/commit-checkpoint.py <slug> --review-round <N>— same SKIP / exit-1 semantics as Phase B.
Done when: the round's review.md exists with a verdict, every confirmed
finding and nitpick from it is remediated (or the verdict was SHIP), and
state.yaml records the round.
Phase E — done
- Run
make gateand a finalcy-final-verifyfor the local pre-push claim, then confirmstate.verify.last_status=PASS. - Push the current head and create or update its draft PR. In stacked mode,
resubmit the stack and include every open layer; otherwise use the current
branch PR. Record pending evidence with
update-state.py <slug> --phase E --action "await exact-head PR CI" --outcome partial --ci-pending --pr-url <url> --head-sha <sha>; repeat the paired URL/SHA flags in stack order. - Watch every PR's checks to terminal state (
gh pr checks --watch --interval 20). A pending or red check keeps Phase E open; diagnose, repair, rerun the affected local gate, checkpoint, push, and watch the new head. Only green required checks at the recorded head pass. Then record fresh terminal evidence withupdate-state.py <slug> --phase E --action "exact-head PR CI passed" --outcome completed --ci-pass --pr-url <url> --head-sha <sha> --ci-check <name>(repeat paired PR and check flags as needed). The script rejects stale heads and empty check sets. - Walk the Phase E section of
references/checklist.md; every box must pass. - Print the iteration summary block from
assets/iteration-summary.template.mdwithphase_out=Eand checkpoint fieldn/a (phase != B/D), followed by every entry frommemory/MEMORY.md## Open Questions— the decisions defaulted mid-loop surface to the user here, in one batch. - Print the literal contents of
assets/done-signature.txton its own line — the codex-loop goal-check confirmation scans for it. - Stop — Phase E is the only successful terminal.
Done when: the local gate and exact-head PR CI are green, the Phase E checklist passes, and the done-signature is the final output line.
Step 3 — Self-audit, summarize, then continue.
- Walk
references/checklist.mdfor the phase just executed; every box must pass before summarizing. - Print the iteration summary block from
assets/iteration-summary.template.md(Phase E already printed it and adds only the done-signature line). - Continue gate: stop only when
phase_out=Eor the external-blocker criteria inreferences/recovery-loop.mdare proven andoutcome=blocked. Otherwise re-enter Step 1 immediately — the summary marks the round; it does not end the session.
Done when: the phase checklist passes, its summary is printed, and control either returned to Step 1 or stopped at a permitted terminal.
Memory protocol
Memory goes through the cy-workflow-memory skill — the exact paths per
phase are in references/memory-protocol.md. Update memory before
flipping any tracking field.
Goal-mode integration
The canonical [[CODEX_LOOP ...]] header, the manual invocation text, and
--frontend syntax live in references/goal-header-template.md.
Critical Rules
- One phase action per iteration; repair failures inside that action, then continue at detect until Phase E or a proven external blocker — never idle between rounds waiting for a restart or re-invocation.
- The loop never stops to ask. Any decision — orchestrator included —
resolves autonomously via
cy-execute-task's Authority ladder; record the pick and any user-facing question undermemory/MEMORY.md## Open Questionsand continue. Questions reach the user in one batch in the Phase E summary. state.yamlmutates only throughinit-state.pyandupdate-state.py; hand-edits void resume guarantees. There is no top-levelcurrent_phase—detect-phase.pyderives it from durable state and filesystem truth every run.goal_signature— and the[[CODEX_LOOP]]goal text it mirrors — is write-once at bootstrap: no rewording, no re-init, no deletingstate.yaml. Mid-loop scope changes land in memory.- Frontmatter
status:ontask_NN.mdis the source of truth; reconcilestate.yamlwhen they disagree. - Memory updates precede status flips. Always.
- Gate map — Phase B runs focused validation then
cy-final-verifybefore each checkpoint;make gateruns at the Phase C boundary, after Phase D remediation, and once before the final push. The PR's parallel CI run owns the full gate at Phase E. A FAIL opens the repair loop; only exact-head CI PASS closes the phase action. - Peer review (
deep-review) runs only in Phase D. Per-task peer-review instructions inside task files or specs are superseded by this loop's phase machine — note "deferred to Phase D" in the task memory and move on. - Full QA cycles (journeys, charters, dated reports) run only in Phase C.
Phase B owns each task's proportional verification — the
## Shippable Outcometier (gate|probe|smokewith Visual Contract capture) with evidence in the task memory — plus scenario flagging: add/resetdocs/qa/scenarios/files per the task's diff, note "full walk deferred to Phase C" in the task memory, and move on. A UI slice's smoke evidence is Phase B work; relocating it to a later phase is the gate relocation this rule exists to prevent. - Checkpoint commits (Phases B and D) belong to the orchestrator:
cy-execute-taskruns with auto-commit disabled, and every worker packet forbids committing. The checkpoint captures code, memory, task frontmatter, the master tasks file, and the advancedstate.yamlin one atomic, restorable snapshot. Whenstate.stacked=true, the checkpoint script also owns the stack layer and PR submission (references/stacked-prs.md); the loop never merges the stack. - Checkpoint commits capture the whole tree (
git add -Ais the script's contract): files this loop did not author ride into the snapshot by design — the untouched-files rule forbids reverting them, not committing them. Never pause to triage a dirty tree. - Phase E requires
qa.report_done=true,qa.execution_done=true,review.ship=true, andverify.last_status=PASS. - Do not regenerate the loop's input graph with
cy-create-tasks,cy-create-spec,cy-tasks-tail-qa-pair, orcy-web-docs-impact.
Error Handling
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 3k
- Forks
- 177
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
cy-loop-tasks- Source
- github.com/compozy/compozy