execute-task
The execution loop. Three sources converge:
- Plan (HOW) —
docs/superpowers/plans/*.md produced by GENERATE
- TaskMaster (WHAT) —
.taskmaster/tasks/tasks.json with
dependencies and complexity scores
- CDD (PROOF) — acceptance cards per task, evidence-gated
execute-task is the single skill that runs the full build from "tasks are
ready" to SHIP_CHECK_OK. It is autonomous — no AskUserQuestion inside the
loop. Any gap that would require user input is surfaced through the recon
escalation ladder (step 11) or the inbox (steps 4 and 8), never via a modal
prompt.
Entry
This skill is invoked either:
- Directly by the user once HANDOFF has completed and a task-execution
mode (A/B/C) has been dispatched, or
- By the
prd-taskmaster orchestrator when current_phase is EXECUTE.
On entry, confirm that:
.atlas-ai/state/pipeline.json exists and records phase: EXECUTE
.taskmaster/tasks/tasks.json exists with at least one ready task
.atlas-ai/customizations/system-prompt-template.md is present (may be
empty — absence is a setup bug, empty is fine)
If any of the above are missing, report the gap and halt. Do NOT attempt to
bootstrap the missing artifact from inside this loop — that is the
orchestrator's job.
Cycle (per iteration)
Each pass through this cycle moves exactly one TaskMaster task from pending
to done. Do the 13 steps in order. Do not skip.
Heartbeat check: verify the execute-task heartbeat timer is running.
If missing, register one via CronCreate("execute-task-heartbeat", "* * * * *", "echo heartbeat").
Abort the iteration if the timer cannot be created — a missing heartbeat
means a missing stuck-session detector, and that is load-bearing.
Inbox reconciliation: read .atlas-ai/state/pipeline.json,
.taskmaster/tasks/tasks.json, and the current TodoWrite list.
Diff them. If the three are stale by more than 5 tasks (i.e. TodoWrite
says 10 done but tasks.json says 3 done), report the diff and halt — do
not paper over bookkeeping drift by silently reconciling.
Pick next task: run backend op next with the plugin's project-root
pointer. Use exactly this invocation:
python3 script.py next-task
Parse the JSON result.
- If no ready tasks and all tasks are
done, run .atlas-ai/ship-check.py,
emit SHIP_CHECK_OK on success, exit the loop.
- If no ready tasks but pending tasks exist, the dependency graph is
deadlocked — report and halt.
Load plan step: search for the matching task ID in this priority
order, halting only after all three fail:
docs/superpowers/plans/*.md (the superpowers GENERATE default output)
.taskmaster/docs/plan.md (the prd-taskmaster HANDOFF default output,
whose path is also recorded in
pipeline.json:phase_evidence.HANDOFF.plan_file_path)
- Any custom path declared in
pipeline.json:phase_evidence.HANDOFF.plan_file_path (in case
a future handoff variant writes elsewhere)
If none of the three contains the matching task ID, the task was
invented downstream of the plan — mark the task blocked, inbox the
parent orchestrator with message_type="blocker", and continue to the
next iteration.
(Codified 2026-06-04 — yesterday's ai-human-tasker run had its plan at
.taskmaster/docs/plan.md only, while this step previously read
docs/superpowers/plans/*.md exclusively. The controller silently
improvised; a cold-start successor would have hit the blocked path on
every task.)
Generate CDD card: convert the task's subtasks field into a
testing_plan. Each subtask becomes a verifiable check with a concrete
evidence path (file, command output, or test name). Write the card to
.atlas-ai/cdd/task-<id>.json. A task without subtasks is treated as a
single RED card.
Set in-progress: run backend op set-status from the current project
root:
python3 script.py set-status --id <N> --status in-progress
This flip is
observable by watchers and anchors the iteration in TaskMaster itself.
Dispatch implementer subagent — NEVER in-session. The controller
must:
- Provide the FULL task text to the subagent. Never tell the subagent to
"read tasks.json" — per spec §12, the controller serialises the task
into the dispatch prompt.
- Inject the plugin customisation block at
.atlas-ai/customizations/system-prompt-template.md
into the subagent's system prompt. If the file is empty, inject nothing
and continue.
- Tier the model by TaskMaster complexity score:
1-4 fast — use the fast tier (Haiku-class)
5-7 standard — use the standard tier (Sonnet-class)
8-10 capable — use the capable tier (Opus-class)
- Wait for the subagent to return a terminal status:
DONE,
DONE_WITH_CONCERNS, NEEDS_CONTEXT, or BLOCKED.
Rationale: complexity-tiered dispatch keeps the dollars-per-task curve
sensible. A complexity-2 boilerplate task does not need Opus; a
complexity-9 architectural task should not be given to Haiku.
Route by status: the subagent's return status drives the next move.
- DONE — proceed to the spec gate, then the quality gate. If both
pass, advance to step 9.
- DONE_WITH_CONCERNS — the subagent completed but flagged concerns.
Address each concern before advancing; re-dispatch if needed.
- NEEDS_CONTEXT — the subagent requested more context. Provide the
requested context and re-dispatch. Retry cap at 2 — if the subagent
still returns NEEDS_CONTEXT after two re-dispatches, escalate via the
recon ladder (step 11).
- BLOCKED — the subagent cannot proceed. Try one model-tier upgrade
first (e.g. standard -> capable). If still blocked, break the task
into smaller subtasks via backend op
expand
(python3 script.py expand --id <N>). If still
blocked, set status=blocked, inbox parent, halt this iteration.
Do NOT invent new status values. The four above are the only terminal
returns. Any other string from the subagent is a protocol violation and
should be logged + treated as BLOCKED.
Triple verification — the plugin's core quality gate, per spec §11.4.
Three independent checks must agree.
Hard exit-code gate (MANDATORY — bypasses agreement count). Before
invoking the three checkers, run .atlas-ai/ship-check.py --dry-run. If
it reports any non-zero Exit status N in evidence files, the task
FAILS regardless of how the agent narratives read. SHIP_CHECK_FAIL is
NOT a warning. Narrative claiming the exit code is "expected" or
"infrastructure noise" does NOT override this gate — write a separate
task-fix-N to address the underlying failure instead. Override only
via --override SHIP_CHECK_OVERRIDE_ADMIN, which is logged to
execute-log.jsonl as an audit event. (Codified 2026-06-04 after T12
in ai-human-tasker was marked DONE while pnpm test exited 1 with 11
failing tests.)
The three checks (run only if the hard gate passes):
- Plugin-native check: evidence file count vs declared subtask count
(from the CDD card in step 5). Missing evidence = fail.
/doubt skill — adversarial doubt sweep on the claimed completion.
/validate skill — deterministic validation pass (lint / tests / exit
codes).
- External
Opus subagent sanity pass — asks a fresh subagent "would
you merge this?" with the task spec + diff + evidence.
3+ agree pass -> task passes. Disagreement -> halt this iteration,
surface to inbox.
Mark done + propagate state:
a. Run backend op set-status for the parent task:
python3 script.py set-status --id <N> --status done.
b. Subtask writeback: for each subtask S in task.subtasks whose
evidence file (per the CDD card from step 5) exists, run
python3 script.py set-status --id <N>.<S> --status done. Subtasks left
pending while the parent is done are a data-integrity violation
that breaks any tool computing progress from subtask state.
(Codified 2026-06-04 — yesterday's run left all 39 subtasks
pending despite 13/13 parent tasks done.)
c. Update .atlas-ai/state/pipeline.json per-task: call
mcp__plugin_prd_go__update_pipeline_task_status(task_id=<N>, status="done") if the MCP tool is available. If not, fall back to
atomic read-modify-write using the pattern in
mcp-server/pipeline.py:locked_update() — read, append <N> to
phase_evidence.EXECUTE.tasks_completed, write to temp, rename.
Never leave pipeline.json and tasks.json mutually inconsistent.
(Codified 2026-06-04 — yesterday's run promised this write in
SKILL.md but never executed it. pipeline.json froze at HANDOFF
transition through all 85 minutes of execution.)
Check stepback triggers: if 15 minutes have passed with no task
moving to done, OR 5 consecutive iterations have failed on the same
task class, the recon escalation ladder is MANDATORY. Climb the ladder
in this exact order, not out of order:
/stepback -> /research-before-coding -> /question -> pivot
/stepback — reassess the architectural assumption. Was the plan
wrong?
/research-before-coding — feed the blocker into the Perplexity +
Context7 + GitHub pipeline for fresh external context.
/question — batch-research the unresolved unknowns in parallel.
pivot — the plan step itself is unsound; kick the task back to the
plan author (inbox parent with message_type="plan_pivot_requested").
The ladder is append-only — if /stepback surfaces a fix, apply it and
return to step 3. Only climb if the prior rung did not yield progress.
Render gamify score — emit the atlas-gamify one-line score for this
iteration (tasks done / tasks total, complexity-weighted). This is the
human-visible progress signal and also feeds the dogfood debrief.
Loop: back to step 1 until SHIP_CHECK_OK or a halt condition fires.
Termination
The termination sequence is strict — three steps, in order, no shortcuts:
- Run
.atlas-ai/ship-check.py. If it does NOT exit 0, halt. Do NOT
emit any completion signal. Investigate the gate failure, fix, retry.
- MANDATORY: invoke
Skill(skill: "sync") to refresh the memory
bank (session-context/CLAUDE-*.md, MEMORY.md, capability inventory).
This MUST happen BEFORE the SHIP_CHECK_OK token is printed.
Orchestrators tail-watch the token; if the memory bank is stale when
they react, successor sessions inherit a wrong picture of the world.
(Codified 2026-06-04 — yesterday's ai-human-tasker run shipped 15.6k
LOC while session-context/CLAUDE-activeContext.md still said
"Scaffold complete. No application code yet".)
- Print
SHIP_CHECK_OK to stdout. This is the ONLY place in your
output where the token may appear — emit it nowhere else, to avoid
false-positive matches by log-watchers.
The ship-check script is deterministic. Its gates are documented at the
top of ${CLAUDE_PLUGIN_ROOT}/skel/ship-check.py (copied to .atlas-ai/ship-check.py at setup):
- Gate 1:
pipeline.json current_phase == "EXECUTE"
- Gate 2: every
master.tasks[].status == "done"
- Gate 3: every task has a CDD card (
task-<id>.json or combined variant)
- Gate 4: plan file exists at
.taskmaster/docs/plan.md OR docs/superpowers/plans/*.md
- Gate 5 (HARD): no non-zero
Exit status N line in any evidence file
Gate 5 is the convergent must-do from the 2026-06-04 audit — a "PASS"
label on a non-zero-exit test is structurally impossible after this
script runs (modulo the explicit --override SHIP_CHECK_OVERRIDE_ADMIN
audit-logged bypass).
Do not emit SHIP_CHECK_OK on a mere "DONE" keyword in a subagent reply.
Do not emit on "all tasks marked done" without the explicit ship-check.
Do not emit before /sync has been called.
Red flags
These are the most common pressure points where the loop silently degrades
from "verified" to "performative". If you catch yourself thinking any of
them, stop and repair the gap.
- "Close enough, mark it done" -> NO. Evidence OR nothing.
- "Let me skip the doubt step this time" -> NO. Triple verification is non-negotiable.
- "I'll retry with same model+prompt" (BLOCKED) -> NO. Escalate.
- "The task says done, don't check evidence files" -> NO. Task status must reflect evidence.
Observability
Every iteration appends a structured row to
.atlas-ai/state/execute-log.jsonl. Field types are strict — text
narrative in a typed field is a logging bug, not compliance. The schema:
iteration (integer, or "FINAL" / "OVERRIDE" for terminal markers)
timestamp (ISO 8601 string)
task_id (string)
complexity (integer or human label)
tier (string: "fast" | "standard" | "capable")
subagent_status (string: "DONE" | "DONE_WITH_CONCERNS" | "NEEDS_CONTEXT" | "BLOCKED")
retry_count (integer)
triple_verify (string: "PASS" / "FAIL" plus free-text rationale)
stepback_triggered (boolean, REQUIRED — true iff /stepback was
invoked this iteration). Putting narrative-text in this field is a
violation; use stepback_narrative instead.
stepback_narrative (string, nullable — explanation when
stepback_triggered: true; null otherwise)
ladder_rung (string, nullable — which rung was reached if escalated)
gamify (string — atlas-gamify one-line score)
The stepback fields were split (2026-06-04) after a FINAL iteration entry
wrote a paragraph of narrative into the boolean stepback field and was
treated as compliance with the stepback_mandatory rule. Boolean trigger
- nullable narrative is the correct schema.
This log is the dogfood artifact — debrief tools consume it, the
orchestrator greps it, and future runs read it for retrospective analysis.
Composition
- Orchestrator handoff: this skill is invoked post-HANDOFF. It does
not call
/handoff — that direction is one-way.
- Plan editing: if the plan is unsound, the ladder escalates to
pivot, which inboxes the plan author. This skill does not mutate the
plan in place.
- Ship-check:
.atlas-ai/ship-check.py is the terminal gate. This
skill calls it; it does not reimplement the checks.
Non-exits
This skill uses no explicit process termination. A halt condition reports
the reason in the structured log and returns control to the caller (the
user or the orchestrator). Never kill the shell — the caller owns the
session lifecycle.
1---2name: execute-task-23description: Execute the next TaskMaster task using the implementation plan with CDD verification. Picks the next ready task, matches it to the plan step, implements via a dispatched subagent, verifies subtasks with evidence, marks the task done, and loops until every task is complete. Wraps the TaskMaster next -> in-progress -> done lifecycle with CDD GREEN / RED / BLUE verification and the plugin's triple-verification rule. Autonomous by design — no user prompts inside the loop.4---5
6# execute-task
7
8The execution loop. Three sources converge:
9
10- **Plan** (HOW) — `docs/superpowers/plans/*.md` produced by GENERATE
11- **TaskMaster** (WHAT) — `.taskmaster/tasks/tasks.json` with
12 dependencies and complexity scores
13- **CDD** (PROOF) — acceptance cards per task, evidence-gated
14
15execute-task is the single skill that runs the full build from "tasks are
16ready" to SHIP_CHECK_OK. It is autonomous — no AskUserQuestion inside the
17loop. Any gap that would require user input is surfaced through the recon
18escalation ladder (step 11) or the inbox (steps 4 and 8), never via a modal
19prompt.
20
21## Entry
22
23This skill is invoked either:
24
251. Directly by the user once HANDOFF has completed and a task-execution
26 mode (A/B/C) has been dispatched, **or**
272. By the `prd-taskmaster` orchestrator when `current_phase` is `EXECUTE`.
28
29On entry, confirm that:
30
31- `.atlas-ai/state/pipeline.json` exists and records `phase: EXECUTE`
32- `.taskmaster/tasks/tasks.json` exists with at least one ready task
33- `.atlas-ai/customizations/system-prompt-template.md` is present (may be
34 empty — absence is a setup bug, empty is fine)
35
36If any of the above are missing, report the gap and halt. Do NOT attempt to
37bootstrap the missing artifact from inside this loop — that is the
38orchestrator's job.
39
40## Cycle (per iteration)
41
42Each pass through this cycle moves exactly one TaskMaster task from `pending`
43to `done`. Do the 13 steps in order. Do not skip.
44
451. **Heartbeat check**: verify the execute-task heartbeat timer is running.
46 If missing, register one via `CronCreate("execute-task-heartbeat", "* * * * *", "echo heartbeat")`.
47 Abort the iteration if the timer cannot be created — a missing heartbeat
48 means a missing stuck-session detector, and that is load-bearing.
49
502. **Inbox reconciliation**: read `.atlas-ai/state/pipeline.json`,
51 `.taskmaster/tasks/tasks.json`, and the current TodoWrite list.
52 Diff them. If the three are stale by more than 5 tasks (i.e. TodoWrite
53 says 10 done but tasks.json says 3 done), report the diff and halt — do
54 not paper over bookkeeping drift by silently reconciling.
55
563. **Pick next task**: run backend op `next` with the plugin's project-root
57 pointer. Use exactly this invocation:
58
59 ```bash
60 python3 script.py next-task
61 ```
62
63 Parse the JSON result.
64 - If no ready tasks and all tasks are `done`, run `.atlas-ai/ship-check.py`,
65 emit SHIP_CHECK_OK on success, exit the loop.
66 - If no ready tasks but pending tasks exist, the dependency graph is
67 deadlocked — report and halt.
68
694. **Load plan step**: search for the matching task ID in this priority
70 order, halting only after all three fail:
71
72 1. `docs/superpowers/plans/*.md` (the superpowers GENERATE default output)
73 2. `.taskmaster/docs/plan.md` (the prd-taskmaster HANDOFF default output,
74 whose path is also recorded in
75 `pipeline.json:phase_evidence.HANDOFF.plan_file_path`)
76 3. Any custom path declared in
77 `pipeline.json:phase_evidence.HANDOFF.plan_file_path` (in case
78 a future handoff variant writes elsewhere)
79
80 If none of the three contains the matching task ID, the task was
81 invented downstream of the plan — mark the task `blocked`, inbox the
82 parent orchestrator with `message_type="blocker"`, and continue to the
83 next iteration.
84
85 (Codified 2026-06-04 — yesterday's ai-human-tasker run had its plan at
86 `.taskmaster/docs/plan.md` only, while this step previously read
87 `docs/superpowers/plans/*.md` exclusively. The controller silently
88 improvised; a cold-start successor would have hit the `blocked` path on
89 every task.)
90
915. **Generate CDD card**: convert the task's `subtasks` field into a
92 `testing_plan`. Each subtask becomes a verifiable check with a concrete
93 evidence path (file, command output, or test name). Write the card to
94 `.atlas-ai/cdd/task-<id>.json`. A task without subtasks is treated as a
95 single RED card.
96
976. **Set in-progress**: run backend op `set-status` from the current project
98 root:
99
100 ```bash
101 python3 script.py set-status --id <N> --status in-progress
102 ```
103
104 This flip is
105 observable by watchers and anchors the iteration in TaskMaster itself.
106
1077. **Dispatch implementer subagent** — NEVER in-session. The controller
108 must:
109
110 - Provide the FULL task text to the subagent. Never tell the subagent to
111 "read tasks.json" — per spec §12, the controller serialises the task
112 into the dispatch prompt.
113 - Inject the plugin customisation block at `.atlas-ai/customizations/system-prompt-template.md`
114 into the subagent's system prompt. If the file is empty, inject nothing
115 and continue.
116 - Tier the model by TaskMaster complexity score:
117 - `1-4 fast` — use the fast tier (Haiku-class)
118 - `5-7 standard` — use the standard tier (Sonnet-class)
119 - `8-10 capable` — use the capable tier (Opus-class)
120 - Wait for the subagent to return a terminal status: `DONE`,
121 `DONE_WITH_CONCERNS`, `NEEDS_CONTEXT`, or `BLOCKED`.
122
123 Rationale: complexity-tiered dispatch keeps the dollars-per-task curve
124 sensible. A complexity-2 boilerplate task does not need Opus; a
125 complexity-9 architectural task should not be given to Haiku.
126
1278. **Route by status**: the subagent's return status drives the next move.
128
129 - **DONE** — proceed to the spec gate, then the quality gate. If both
130 pass, advance to step 9.
131 - **DONE_WITH_CONCERNS** — the subagent completed but flagged concerns.
132 Address each concern before advancing; re-dispatch if needed.
133 - **NEEDS_CONTEXT** — the subagent requested more context. Provide the
134 requested context and re-dispatch. Retry cap at 2 — if the subagent
135 still returns NEEDS_CONTEXT after two re-dispatches, escalate via the
136 recon ladder (step 11).
137 - **BLOCKED** — the subagent cannot proceed. Try one model-tier upgrade
138 first (e.g. standard -> capable). If still blocked, break the task
139 into smaller subtasks via backend op `expand`
140 (`python3 script.py expand --id <N>`). If still
141 blocked, set status=blocked, inbox parent, halt this iteration.
142
143 Do NOT invent new status values. The four above are the only terminal
144 returns. Any other string from the subagent is a protocol violation and
145 should be logged + treated as BLOCKED.
146
1479. **Triple verification** — the plugin's core quality gate, per spec §11.4.
148 Three independent checks must agree.
149
150 **Hard exit-code gate (MANDATORY — bypasses agreement count).** Before
151 invoking the three checkers, run `.atlas-ai/ship-check.py --dry-run`. If
152 it reports any non-zero `Exit status N` in evidence files, the task
153 FAILS regardless of how the agent narratives read. SHIP_CHECK_FAIL is
154 NOT a warning. Narrative claiming the exit code is "expected" or
155 "infrastructure noise" does NOT override this gate — write a separate
156 `task-fix-N` to address the underlying failure instead. Override only
157 via `--override SHIP_CHECK_OVERRIDE_ADMIN`, which is logged to
158 `execute-log.jsonl` as an audit event. (Codified 2026-06-04 after T12
159 in ai-human-tasker was marked DONE while `pnpm test` exited 1 with 11
160 failing tests.)
161
162 The three checks (run only if the hard gate passes):
163
164 - Plugin-native check: evidence file count vs declared subtask count
165 (from the CDD card in step 5). Missing evidence = fail.
166 - `/doubt` skill — adversarial doubt sweep on the claimed completion.
167 - `/validate` skill — deterministic validation pass (lint / tests / exit
168 codes).
169 - External `Opus subagent` sanity pass — asks a fresh subagent "would
170 you merge this?" with the task spec + diff + evidence.
171
172 3+ agree pass -> task passes. Disagreement -> halt this iteration,
173 surface to inbox.
174
17510. **Mark done + propagate state**:
176 a. Run backend op `set-status` for the parent task:
177 `python3 script.py set-status --id <N> --status done`.
178 b. **Subtask writeback**: for each subtask `S` in `task.subtasks` whose
179 evidence file (per the CDD card from step 5) exists, run
180 `python3 script.py set-status --id <N>.<S> --status done`. Subtasks left
181 `pending` while the parent is `done` are a data-integrity violation
182 that breaks any tool computing progress from subtask state.
183 (Codified 2026-06-04 — yesterday's run left all 39 subtasks
184 `pending` despite 13/13 parent tasks `done`.)
185 c. Update `.atlas-ai/state/pipeline.json` per-task: call
186 `mcp__plugin_prd_go__update_pipeline_task_status(task_id=<N>,
187 status="done")` if the MCP tool is available. If not, fall back to
188 atomic read-modify-write using the pattern in
189 `mcp-server/pipeline.py:locked_update()` — read, append `<N>` to
190 `phase_evidence.EXECUTE.tasks_completed`, write to temp, rename.
191 Never leave pipeline.json and tasks.json mutually inconsistent.
192 (Codified 2026-06-04 — yesterday's run promised this write in
193 SKILL.md but never executed it. pipeline.json froze at HANDOFF
194 transition through all 85 minutes of execution.)
195
19611. **Check stepback triggers**: if 15 minutes have passed with no task
197 moving to done, OR 5 consecutive iterations have failed on the same
198 task class, the recon escalation ladder is MANDATORY. Climb the ladder
199 in this exact order, not out of order:
200
201 `/stepback` -> `/research-before-coding` -> `/question` -> `pivot`
202
203 - `/stepback` — reassess the architectural assumption. Was the plan
204 wrong?
205 - `/research-before-coding` — feed the blocker into the Perplexity +
206 Context7 + GitHub pipeline for fresh external context.
207 - `/question` — batch-research the unresolved unknowns in parallel.
208 - `pivot` — the plan step itself is unsound; kick the task back to the
209 plan author (inbox parent with `message_type="plan_pivot_requested"`).
210
211 The ladder is append-only — if `/stepback` surfaces a fix, apply it and
212 return to step 3. Only climb if the prior rung did not yield progress.
213
21412. **Render gamify score** — emit the atlas-gamify one-line score for this
215 iteration (tasks done / tasks total, complexity-weighted). This is the
216 human-visible progress signal and also feeds the dogfood debrief.
217
21813. **Loop**: back to step 1 until SHIP_CHECK_OK or a halt condition fires.
219
220## Termination
221
222The termination sequence is strict — three steps, in order, no shortcuts:
223
2241. Run `.atlas-ai/ship-check.py`. If it does NOT exit 0, halt. Do NOT
225 emit any completion signal. Investigate the gate failure, fix, retry.
2262. **MANDATORY**: invoke `Skill(skill: "sync")` to refresh the memory
227 bank (session-context/CLAUDE-*.md, MEMORY.md, capability inventory).
228 This MUST happen BEFORE the SHIP_CHECK_OK token is printed.
229 Orchestrators tail-watch the token; if the memory bank is stale when
230 they react, successor sessions inherit a wrong picture of the world.
231 (Codified 2026-06-04 — yesterday's ai-human-tasker run shipped 15.6k
232 LOC while `session-context/CLAUDE-activeContext.md` still said
233 "Scaffold complete. No application code yet".)
2343. Print `SHIP_CHECK_OK` to stdout. This is the ONLY place in your
235 output where the token may appear — emit it nowhere else, to avoid
236 false-positive matches by log-watchers.
237
238The ship-check script is deterministic. Its gates are documented at the
239top of `${CLAUDE_PLUGIN_ROOT}/skel/ship-check.py` (copied to `.atlas-ai/ship-check.py` at setup):
240
241- Gate 1: `pipeline.json current_phase == "EXECUTE"`
242- Gate 2: every `master.tasks[].status == "done"`
243- Gate 3: every task has a CDD card (`task-<id>.json` or combined variant)
244- Gate 4: plan file exists at `.taskmaster/docs/plan.md` OR `docs/superpowers/plans/*.md`
245- Gate 5 (HARD): no non-zero `Exit status N` line in any evidence file
246
247Gate 5 is the convergent must-do from the 2026-06-04 audit — a "PASS"
248label on a non-zero-exit test is structurally impossible after this
249script runs (modulo the explicit `--override SHIP_CHECK_OVERRIDE_ADMIN`
250audit-logged bypass).
251
252Do not emit SHIP_CHECK_OK on a mere "DONE" keyword in a subagent reply.
253Do not emit on "all tasks marked done" without the explicit ship-check.
254Do not emit before `/sync` has been called.
255
256## Red flags
257
258These are the most common pressure points where the loop silently degrades
259from "verified" to "performative". If you catch yourself thinking any of
260them, stop and repair the gap.
261
262- "Close enough, mark it done" -> NO. Evidence OR nothing.
263- "Let me skip the doubt step this time" -> NO. Triple verification is non-negotiable.
264- "I'll retry with same model+prompt" (BLOCKED) -> NO. Escalate.
265- "The task says done, don't check evidence files" -> NO. Task status must reflect evidence.
266
267## Observability
268
269Every iteration appends a structured row to
270`.atlas-ai/state/execute-log.jsonl`. Field types are strict — text
271narrative in a typed field is a logging bug, not compliance. The schema:
272
273- `iteration` (integer, or `"FINAL"` / `"OVERRIDE"` for terminal markers)
274- `timestamp` (ISO 8601 string)
275- `task_id` (string)
276- `complexity` (integer or human label)
277- `tier` (string: `"fast"` | `"standard"` | `"capable"`)
278- `subagent_status` (string: `"DONE"` | `"DONE_WITH_CONCERNS"` | `"NEEDS_CONTEXT"` | `"BLOCKED"`)
279- `retry_count` (integer)
280- `triple_verify` (string: `"PASS"` / `"FAIL"` plus free-text rationale)
281- `stepback_triggered` (boolean, REQUIRED — true iff `/stepback` was
282 invoked this iteration). Putting narrative-text in this field is a
283 violation; use `stepback_narrative` instead.
284- `stepback_narrative` (string, nullable — explanation when
285 `stepback_triggered: true`; `null` otherwise)
286- `ladder_rung` (string, nullable — which rung was reached if escalated)
287- `gamify` (string — atlas-gamify one-line score)
288
289The stepback fields were split (2026-06-04) after a FINAL iteration entry
290wrote a paragraph of narrative into the boolean `stepback` field and was
291treated as compliance with the `stepback_mandatory` rule. Boolean trigger
292+ nullable narrative is the correct schema.
293
294This log is the dogfood artifact — debrief tools consume it, the
295orchestrator greps it, and future runs read it for retrospective analysis.
296
297## Composition
298
299- **Orchestrator handoff**: this skill is invoked post-HANDOFF. It does
300 not call `/handoff` — that direction is one-way.
301- **Plan editing**: if the plan is unsound, the ladder escalates to
302 `pivot`, which inboxes the plan author. This skill does not mutate the
303 plan in place.
304- **Ship-check**: `.atlas-ai/ship-check.py` is the terminal gate. This
305 skill calls it; it does not reimplement the checks.
306
307## Non-exits
308
309This skill uses no explicit process termination. A halt condition reports
310the reason in the structured log and returns control to the caller (the
311user or the orchestrator). Never kill the shell — the caller owns the
312session lifecycle.