> **TLDR**  -  Pipeline operational primitives:
>
> - **Task IDs** auto-increment from `$HOME/.claude/logs/multi-agent/{project}/.counter` (persistent).
> - **Kill/Purge/Clear-logs** require explicit user confirm; destructive ops never chain.
> - **Resume** re-enters at `currentPhase + 1`; always re-runs Phase 7 for knowledge capture.
> - **3-iteration hard kill**: any retry loop stops after 3 attempts and hands off to the user.
> - Subagents return JSON (not prose), get only the diff + relevant files, and must reflect before each retry.

## Task ID System

Every task gets an auto-incremented short ID. Counter stored at `$HOME/.claude/logs/multi-agent/{project}/.counter` (persists across sessions).

```
/multi-agent "PROJ-12345"
-> Task #1 started  -  PROJ-12345
```

---

## Kill Logic

1. Find task by short ID (#2) or Jira ID (PROJ-67890)
2. Confirm with user: "PROJ-67890 (Task #2) will be deleted: worktree and branch. Logs will be preserved. Are you sure?"
3. `git worktree remove .worktrees/{jiraId} --force`
4. `git branch -D {branch-name}`
5. Remote branch delete ONLY if user explicitly confirms
6. Logs are preserved in `$HOME/.claude/logs/multi-agent/{project}/{task-id}/`  -  not deleted with worktree
7. Log: "Task #2 killed (logs preserved at global path)"

---

## Clear Logs

1. Confirm with user
2. Scan global log directory: `$HOME/.claude/logs/multi-agent/`
3. Delete all `agent-log.md` and `agent-state.json` files across all projects
4. **Do NOT reset counter** (`$HOME/.claude/logs/multi-agent/{project}/.counter`)  -  prevents ID collision
5. Confirm count deleted

---

## Purge (Full Reset)

1. First confirm: list what will be deleted, then a native `AskUserQuestion` picker (`Continue` / `Cancel`)
2. Second confirm (paranoia gate): a second `AskUserQuestion` picker (`Purge permanently` / `Cancel`)  -  anything other than `Purge permanently` cancels
3. Remove all worktrees, branches, logs, counter
4. Do NOT delete remote branches without explicit user approval

---

## Resume Logic

1. Find state file: `$HOME/.claude/logs/multi-agent/{project}/{task-id}/agent-state.json`
2. **Validate before re-entry** (required  -  a half-written or corrupt state silently resumes at the wrong phase):
   - `node $HOME/.claude/scripts/validate-state.mjs <state-file>` (resume-safety check: parseable JSON + `currentPhase` in 0..7 + well-formed `phases`; tolerant of legacy shapes, not a strict schema match). On non-zero exit, do NOT guess a phase: surface the error and stop with `ERR: agent-state.json is unsafe to resume; inspect it or 'kill #N' and restart.`
   - Confirm the worktree path on `state.worktreePath` / `state.projects[].worktreePath` exists and `git -C <wt> status` is clean-or-known. If the worktree is missing or locked, run the Phase 0 "Worktree stale-lock heal" before continuing.
3. Read `agent-log.md` for previous findings
4. Resume from `currentPhase + 1`. If `state.phases[currentPhase+1].subStep` is set, re-enter that phase and skip already-recorded sub-steps (see "Sub-step checkpoints").
5. **Always run Phase 7** on resume completion  -  ensures knowledge capture even if task was paused mid-pipeline
6. Log: "Resumed {jiraId} from Phase {N}"

---

## Phase Pipeline

Run phases sequentially. Log every step to `agent-log.md`.
If any phase fails, mark task as `paused` and stop  -  user can `resume` later.
Update `agent-state.json` at EVERY phase transition.

### Writing `agent-state.json` (required mechanism)

Every state update goes through `write-state.mjs`. Never write the file with a
plain read-modify-write (`jq ... > tmp && mv`, an editor tool, `cat >`):

```bash
# Merge a patch into the current state (the normal case).
echo '{"currentPhase":4,"phases":{"4":{"status":"running"}}}' \
  | node $HOME/.claude/scripts/write-state.mjs "$STATE_FILE"

# Full replacement, only when rewriting the document wholesale.
printf '%s' "$NEW_STATE" | node $HOME/.claude/scripts/write-state.mjs --replace "$STATE_FILE"
```

Why the indirection is required: multi-repo mode and concurrent worktrees share
one `agent-state.json` per task id, so two writers using read-then-write lose one
of the two updates  -  the second write is computed from a snapshot taken before
the first landed. `write-state.mjs` does tmpfile + rename (atomic on POSIX) under
an advisory `.lock`, reclaims a lock whose holder PID is dead, and releases the
lock on every error path.

Exit codes the caller must handle: `0` written, `1` invalid JSON on stdin, `2`
lock timeout (another writer held it past the acquire window  -  retry once, then
halt per the halt-visibility rule), `3` I/O error.

Reads need no wrapper; the rename makes any read see either the old or the new
document, never a truncated one.

**Halt visibility (required, autopilot included).** A halt is never silent. Whenever a phase halts on a hard error (validator failed twice, no subagent returned, dispatch error past fallback, lock irrecoverable), in addition to the `agent-log.md` line: (a) write `state.status = "paused"` and `state.haltReason = "<phase>:<cause>"`; (b) record the cause on the tracker via `phase-tracker.sh meta <phase> halt "<cause>"` and `phase-tracker.sh update <phase> failed`; (c) emit one `>&2` alert line `HALT phase <N>: <cause>  -  resume with /multi-agent:resume #<id>`; (d) if `prefs.global.usageLog.enabled` is true, emit the end-of-run report so a run that never reaches Phase 7 is still recorded with the phase it stopped at (`state.currentPhase` + `haltReason`) - the emitter no-ops when it is off or unconfigured:

```bash
node $HOME/.claude/scripts/usage-report.mjs --state "$STATE_FILE" >/dev/null 2>&1 || true
```

Autopilot suppresses *confirmations*, not *halts*  -  the user must always be able to see why an unattended run stopped without reading the log. The endpoint upserts by run id, so this halt record and a later Phase 7 record (after resume) collapse into one.

### Pipeline Best Practices

**Subagent return format**: Instruct every subagent to return structured JSON, not prose:

```
{"status": "complete", "findings": [...], "files_changed": [...], "blocking": false}
```

This keeps orchestrator context lean and enables programmatic routing.

**Context discipline**: Send subagents ONLY what they need  -  the diff + relevant files, not the whole repo context. High signal-to-noise ratio > large context.

**Retry reflection**: Before each retry, force reflection: "What failed? What specific change fixes it? Am I repeating the same approach?"  -  prevents infinite loops on broken strategies.

**Semantic revert**: Track which files each phase produces in `agent-state.json`. If Phase 5 (testing) fails, revert only Phase 4 (implementation) outputs, not Phase 2 (artifacts):

```json
"phases": {
  "4": { "status": "done", "files": ["ButtonView.swift", "ButtonConfiguration.swift"] }
}
```

**Proactive compaction + phase-boundary checkpoint**: the orchestrator follows ~2,500 lines of phase prose in one session; once context fills, it starts dropping steps  -  the single biggest cause of "it got stuck / skipped a step." Two defenses, both required on full-pipeline runs:

- *Phase-boundary checkpoint.* At every phase transition, before loading the next phase doc, write the durable state (`agent-state.json` phase status + `files[]` + `retryCount`) and append a structured handoff block to `agent-log.md` (format below). The next phase reads state + log, not the back-conversation  -  so a transition is a clean re-entry point even if context is later compacted.
- *Compaction trigger.* If conversation context exceeds ~50%, run `/compact` preserving "modified files, plan, open review findings, current phase + sub-step" before continuing. Don't wait for auto-compaction near the limit  -  it triggers exactly when context is worst and is lossy. After compaction, re-read `agent-state.json` AND the latest `## Handoff` block in `agent-log.md` to re-ground.

**Handoff block (v10.8.0)**: the structured artifact the phase-boundary checkpoint appends to `agent-log.md`. Written by the orchestrator from state it already holds  -  no agent dispatch, no extra LLM call. Cap at ~15 lines; the latest block is authoritative (earlier ones are history). This is the fresh-context re-entry contract: a resume or post-compaction session rebuilds working context from the latest handoff + `agent-state.json` + git log, never from conversation memory.

```markdown
## Handoff - end of Phase {N} ({name}) - {ISO timestamp}
- Done: {up to 3 bullets of completed outcomes, e.g. "plan approved, 4 tasks", "build green, 12 tests added"}
- Remaining: {ordered list of remaining phases / sub-steps}
- Decisions: {key decisions later phases depend on, e.g. "used existing KeychainStore, no new wrapper"}
- Open findings: {accepted-but-unresolved review findings, or "none"}
- Next: Phase {N+1} {name}, subStep {token or "start"}
```

Full `agent-log.md` shape: `$HOME/.claude/multi-agent-refs/phases/log-format.md`. Resume-side consumption: `resume.md` Step 3 reads the latest handoff FIRST, then falls back to per-phase findings for logs written before v10.8.

**Sub-step checkpoints (long phases)**: Phase 3 (dev/TDD cycles) and Phase 7 (report/channels) can run many minutes; a crash mid-phase loses everything since the last phase boundary and forces a full phase re-run on resume. For these phases, also record `state.phases[<n>].subStep` (a short token: `red`, `green`, `build`, `pr-opened`, `confluence-synced`, ...) and the `files[]` written so far after each meaningful unit of work. On resume, re-enter the phase but skip units whose `subStep` is already recorded and whose `files[]` exist in the worktree  -  re-do only the unfinished tail, never the whole phase.

**3-iteration hard kill**: Any retry loop (build fix, review fix) MUST stop after 3 attempts. On 4th failure -> pause, ask user. No exceptions.
