Plan Execution
Execute approved plans with coordinated agent teams. Each code task gets a dedicated Executor, Reviewer, and Tester that work together through a structured pipeline — planning, implementation, code review, and testing happen automatically. An ops task (deploy, verify, monitor — classified during planning) runs a solo Executor that operates the system and verifies the success criteria itself; there is no code to review and no suite to run.
Team members run as tmux panes — persistent, separately-running sessions that message each other live. This requires teammateMode: "tmux" in ~/.claude/settings.json and launching Claude inside a tmux session (both configured by /uc:setup). Without them, named teammates default to in-process with no panes; plan-execution detects this at startup and stops with a remediation rather than silently running a degraded in-process pipeline.
At startup the Lead also names the tmux window UC::P-NNN::<plan title> so it is identifiable in the status bar. Planning modes set a mode-form name on entry (UC::Feature::<subject>, UC::Debug::<subject>) and upgrade to the plan form once the plan is written — the plan ID takes priority. You can set it by hand any time with /uc:rename-window.
Running a plan
/uc:plan-execution {plan-name}
Execution reads each task's type and executor model from its task.md (recorded during planning — tasks without the fields run as code + Opus) and spawns teams accordingly. No upfront cost estimate is shown; the Project Manager's post-run report covers what was actually spent.
The task pipeline
Each task in your plan gets a dedicated mini-team that self-coordinates:
| Role | Model | What it does |
|---|---|---|
| Executor | Per task: Sonnet / Opus (default) / Fable | Explores codebase, writes implementation plan, implements code, drives the review/test cycle. On an ops task it runs solo: executes the runbook, verifies criteria, holds any monitoring window |
| Reviewer | Sonnet | Reads standards and architecture before code is written, gives plan feedback, performs formal code review |
| Tester | Sonnet | Sends an upfront TESTER TAKE (acceptance-case list), authors black-box acceptance tests, verifies against product docs and success criteria, validates UI in browser |
One plan-wide teammate supports all tasks:
- Project Manager (Sonnet) — monitors progress and liveness, tracks per-task budgets, maintains live execution state files
Knowledge lives per-task in each tasks/task-N/task.md's **Research:** section — a list of pointers to durable files under documentation/technology/research/, populated by planning Stage 2 via /uc:research. Lead reviews research coverage per-task just before spawning each team and fills any gaps. Mid-execution, teammates send QUERY: {question} to Lead for external docs; Lead runs /uc:research (which dispatches its researcher in the background, so the Lead stays responsive to other teammates), replies with an ANSWER: when the findings arrive, and appends the new pointer to the task's task.md so it's durable for re-spawns and future teammates. The distinction between Teammates (the Agent tool in teammate mode — name + run_in_background: true, stateful, tracked on the team graph) and Subagents (the Agent tool in one-shot mode — no name, explicit run_in_background: sync false when the result gates the next step, fan-out true for parallel workers collected via completion notifications; stateless, invisible to the team graph) keeps the team focused on pipeline work while allowing cheap isolated research lookups.
How a task flows
- Planning modes have already written
tasks/task-N/task.mdfor every task (authoritative content: description, files, patterns, Research pointers, success criteria, dependencies). The plan README holds a flat task heading index only. - Lead runs its pre-spawn checklist — reviews task.md's Research pointers, runs
/uc:researchfor any gap or staleness, then spawns Executor + Reviewer + Tester in parallel (minimal pointer prompts; agents read the task directory on startup). An ops task spawns its solo Executor here instead and skips the review/test steps below — it executes its runbook, verifies the success criteria itself, and reports done. - Reviewer and Tester speak first. After its startup read, Reviewer synthesizes a
REVIEWER TAKEfrom task.md + standards + architecture + patterns; in parallel, Tester derives aTESTER TAKEfrom success criteria + product docs (persisted astest-strategy.md) — the acceptance-case list plus the unit-layer cases the Executor's own tests must cover. Both takes are sent to Executor before it plans. - Executor reads task.md and explores the codebase while the takes are being built. It blocks on both takes before writing
tasks/task-N/plan.md— waiting time is productive exploration and mental drafting, not idle. Once they arrive, plan.md is written once, with the takes baked in, as a thin execution delta (approach per file, criterion-to-approach mapping by ID, take incorporation, risks). It does not restate task.md content. - Executor runs a deviation self-check against task.md. If clean (all files in scope, all criteria mapped, no take contradictions) it proceeds directly to implementation — no Lead gate. If the plan deviates, Executor sends
ADVICE REQUEST task-N [deviation]and waits for APPROVED (Lead amends task.md and broadcasts) or AMEND. - Executor implements — source code plus its own unit/integration tests (test authorship splits dev/QA style: Executor owns the white-box layer, Tester owns black-box acceptance tests in files the Executor never edits). Reviewer reads files as they're written via progress updates; Tester may draft acceptance tests against interfaces declared in task.md.
- The moment code is done — before writing impl.md — Executor signals "code complete" to Lead (fire-and-forget). Lead advances stage bookkeeping and may pre-spawn the next dependent task's team into a pipeline-wait gate.
- Executor writes
tasks/task-N/impl.md(delta only — created/modified files, exports, INTEGRATION, GOTCHA), broadcasts viaCommunicateTeam, then requests review and test viaCommunicateTeamMemberwith signal backup. - Reviewer and Tester run in parallel. Both must PASS. Reviewer's scope is the Executor's work (code + its tests, held to the test-strategy contract); Tester verifies independently and finalizes its acceptance tests — missing unit coverage is a FAIL naming the exact cases, never patched by the Tester. Verdicts are sent via
CommunicateTeamMember(with signal + content files for FAIL details). Executor usesWaitForTeamMemberto receive verdicts. If either fails, Executor fixes, updates impl.md, re-broadcasts, and re-submits. - Both pass → Executor commits the Tester's acceptance test files verbatim → task done. Lead sends
Implementation approvedto any parked pipeline successor, shuts the team down, and fills the slot with the next unblocked task.
An optional ADVICE channel is open throughout for Executor to ask Lead for judgment on complicated problems, deep-reasoning design calls, or knowledge about orchestration context (other tasks in flight, plan history, user intent). ADVICE is non-blocking except for the mandatory [deviation] case.
Concurrency
Multiple tasks run in parallel based on plan size:
| Plan size | Concurrent teams |
|---|---|
| 1–3 tasks | 1–2 |
| 4–8 tasks | 2–3 |
| 9+ tasks | 3–4 |
Tasks normally spawn when their dependencies are completed and a slot is available. As a pipeline optimization, when an Executor signals "code complete", the Lead may pre-spawn the next dependent task into a planning stage if a concurrency slot is free — that successor researches and plans during the predecessor's review/test window, then begins coding only after the predecessor fully passes.
What you see during execution
- Execution state — the PM maintains JSON state files showing task status, active stages, and timing
- Escalation notices — if a task exceeds 10 fix cycles or discovers something plan-invalidating, the question is queued to
shared/escalations.mdwith a reversible standing order applied in the meantime (hold the team for a guided retry, defer the gap), and unaffected tasks keep running. Answer whenever you're back — the Lead never blocks on a prompt, so an overnight run survives its own questions - Completion summary — tasks completed, files modified, decisions made, test results, and follow-up items
- Backlog review & triage — while the PM writes the operational report, backlog items and follow-up items the plan resolved are closed automatically and listed for you; each remaining issue detected during execution is then asked about individually (fix now, add to backlog, ignore, or discuss — with a recommendation), deduplicated against the reviewed backlog
Between these, the system runs silently. The Lead doesn't narrate what agents are doing.
Checkpoints and session recovery
Checkpoints save automatically every 3 completed tasks, and whenever a usage soft/limit block is recorded. If your session dies mid-execution:
- Run the same
/uc:plan-execution {plan-name}command again - The system detects the checkpoint and shows you the progress so far
- Confirm resume — completed tasks are skipped, incomplete tasks are re-spawned with their context
All progress is preserved in the plan directory: task artifacts, shared notes, and checkpoint files survive across sessions.
Task directory as the team's single source of truth
Every task gets its own directory at documentation/plans/{plan}/tasks/task-N/ containing these files:
task.md— written by the planning mode at Stage 4 (Lead may amend mid-execution). Authoritative task brief: description, files, patterns,**Research:**pointers, success criteria, dependencies. Every team member reads this on startup.signals.jsonl— append-only JSONL file managed by the execution communication protocol. All agents useCommunicateTeamMember/CommunicateTeamto write signals; each agent arms one persistenttail -F"inbox" monitor at startup that follows this file and wakes it the instant any signal relevant to its role is appended (soWaitForTeamMemberis just "yield your turn" — no per-wait monitors, no re-arm churn) — SendMessage is the primary (immediate) channel; the signal file is the durable shared state log (crash recovery + observability) and the authoritative delivery channel, not merely a backup. 23 signal types cover the full pipeline lifecycle. Critical for crash recovery — re-spawned agents infer precise pipeline state from the signal log, which a live-only channel like SendMessage cannot provide.plan.md— written by the Executor during its Phase 3. A thin execution delta that extends task.md — concrete function/class/signature choices per file, criterion-to-approach mapping by ID, take incorporation (reviewer + tester), risks. Does not restate task.md content.impl.md— written by the Executor during Phase 4.5 after code complete. An implementation delta — created/modified files with line ranges, exports, INTEGRATION notes for other tasks, GOTCHA notes for library quirks. Does not restate task.md or plan.md content.take.md— written by the Reviewer before sending the REVIEWER TAKE. Persistent copy of the standards-aware perspective that shapes the Executor's plan.test-strategy.md— written by the Tester before sending the TESTER TAKE. Persistent copy of the acceptance-case list and unit-layer test contract, plus the running list of tester-owned test files (the ownership boundary the Executor must not cross).review-feedback.md— written by the Reviewer on FAIL verdict. Structured failure details (overwritten on each re-review cycle).test-feedback.md— written by the Tester on FAIL verdict. Structured failure details (overwritten on each re-test cycle).
Spawn prompts carry no inline task content — they're minimal pointers. All team members (including pipeline successors and crash re-spawns) follow the shared task-team-startup protocol to read the task directory on their first action. File writes broadcast FILE-UPDATED task-N/{file}: reason to active teammates so state stays in sync without verbose messages.
Why Reviewer and Tester speak first
Reviewer's unique value is standards / architecture / patterns knowledge — the stuff it reads from documentation/technology/standards/ and documentation/technology/architecture/ that Executor doesn't touch. Tester's unique value is the requirements-side view: what "done" means per success criterion and which cases must be provable. In the old model, that knowledge only surfaced after Executor had already written a plan (or worse, after code was written), making it an advisory round-trip on work that was already done.
In the new model, both front-load their knowledge — a REVIEWER TAKE and a TESTER TAKE sent to Executor before plan.md is written. Executor incorporates them directly into plan.md as primary inputs. Three wins:
- Parallelizes work. Reviewer reads standards and Tester derives its acceptance cases while Executor explores the codebase — no serial bottleneck.
- Plan.md gets written once. Executor blocks on both takes before writing, so plan.md is authored a single time with them baked in — no draft/feedback/rewrite cycle.
- Test gaps surface before code exists. The unit-layer contract is known at planning time, so missing coverage is priced in upfront instead of discovered as a late FAIL cycle.
Both later roles (formal code review on "ready for review", independent verification on "ready for test") are unchanged. The upfront voices are new; the backend gates are the same.
Lead plan review is gone — ADVICE and deviation self-check
The old blocking "Lead plan review" gate is removed. Rationale: task.md already encodes the authoritative scope (user-approved at Stage 4), REVIEWER TAKE covers standards/architecture fit, and Executor's plan.md is structurally a thin delta that can't silently expand scope without visible deviation.
Before implementing, Executor runs a deviation self-check:
- Every file plan.md proposes to touch appears in task.md's Files list
- Every success criterion in task.md has a mapping entry in plan.md
- plan.md does not contradict any constraint from the REVIEWER TAKE or the TESTER TAKE
If all three pass, Executor proceeds to implementation with zero Lead round-trips. If any fails, Executor sends ADVICE REQUEST task-N [deviation]: {reason} and waits for APPROVED (Lead amends task.md and broadcasts) or AMEND: {instructions}.
Executor can also pull Lead's judgment at any time (planning or implementation) via ADVICE REQUEST task-N [complicated|deep-reasoning|knowledge]: {context + question}. Those cases are non-blocking — Executor decides whether to wait. ADVICE is distinct from QUERY: (external library docs via /uc:research): ADVICE is for Lead's judgment and orchestration context, QUERY is for external knowledge.
Execution communication protocol
SendMessage is unreliable (silent failures, name/ID mismatches, orphaned inboxes — multiple open bugs in Claude Code). All agents use a unified communication protocol with three procedures (named conventions defined by the protocol — not Claude Code tools, so they won't appear in a tool search). Each composes the real primitives SendMessage and Monitor (both loaded via ToolSearch at startup) with an append to signals.jsonl:
CommunicateTeamMember(to, message, signal?, content_file?)— send to one agent. Writes content file (if any), appends signal tosignals.jsonl(if any), then attempts SendMessage (best-effort). The ordering is load-bearing: content before signal, signal before SendMessage.CommunicateTeam(message, signal?, content_file?)— broadcast to all active teammates + Lead. Same ordering, SendMessage to each recipient.WaitForTeamMember(signal, from?)— wait to receive a signal. SendMessage is the primary wake and is processed immediately; the durable, authoritative channel is a single persistenttail -Finbox monitor each agent arms once at startup, which followssignals.jsonland wakes the agent the instant any signal relevant to its role is appended (~0 latency, even if SendMessage silently drops). A "wait" is therefore just yield your turn — the agent arms no per-wait monitor and never re-arms, so an agent blocked on two producers (review + test) is woken by that one inbox, not two monitors. There is no per-agent timeout and silence alone is never escalated — long tool calls look identical to real stalls, so alerting on raw silence produced noise no one could act on. Instead the protocol enforces a yield rule: an agent may end its turn only with a named wait recorded (aWAITING_ON/BLOCKED_ONappend naming what it awaits) — if it can't name an awaited signal, it isn't waiting and must keep working. The liveness monitor quietly traces >10 min of task silence as asilence_observedevent inevents.json, and emits aNUDGEcandidate to PM only for a protocol violation: silent, no named wait, and no file activity anywhere in the repo. PM verifies, then pings the executor — the ping itself cures a wrongly-parked-but-alive agent — and escalates to the Lead only on a confirmed non-response.
23 signal types cover the full pipeline lifecycle, including signals added to close visibility gaps: PLAN_READY (executor wrote plan.md), CODE_COMPLETE (all source code done), ADVICE_RESPONSE (Lead replied to an advice request), and three state-only signals from the yield rule — WAITING_ON (named wait recorded before parking), BLOCKED_ON (held on an external condition like another task's file), and PROGRESS (optional heartbeat before a long no-write phase). Signals may carry an optional one-line note payload (e.g. a verdict).
Token overhead is minimal: parked agents burn zero tokens (the inbox never self-terminates, so there is no idle re-arm churn) and each relevant event is one small re-invocation, ~1K–5K tokens total per task.
Failure handling
Failures are handled internally within each task team:
- Reviewer or Tester sends FAIL → Executor fixes → re-submits for review/test
- Up to 10 fix cycles before queueing a non-blocking escalation — the team is held alive for a guided retry while independent tasks continue
- If a team member crashes, it's re-spawned with full context from task artifacts — but only after a liveness probe (team config → tmux pane → ping) proves it actually died. A usage limit parks agents rather than killing them, so a quiet agent is usually alive; re-spawning over one would put two writers on the same task
- If the Lead discovers a plan-invalidating issue, it stops spawning new tasks, lets in-flight work finish, and queues a non-blocking escalation until you decide how to proceed
Usage management
Usage limits are handled reactively — there is no usage question at plan start and nothing proactively stops in-flight work. The limit itself is the pause; the limit sentinel is the resume. A session that hits the limit simply parks at its composer with full context:
- Limit sentinel: one machine-global background process (
scripts/limit-sentinel.sh, installed by/uc:setup— a script, not an agent). It detects limit hits via aStopFailurehook, knows every account’s reset time, and at reset (+90s margin) wakes the whole fleet: durableRESUMEsignals appended to each in-progress task’ssignals.jsonlplus tmux pane injection — including standalone (non-plan) Claude sessions. Wakes are automatic, fleet-wide, and idempotent. After a reset the Lead verifies rather than re-spawns: agents parked by the limit are still alive with their context, so it probes before treating any of them as crashed. - Soft band at 90%: the sentinel injects a
SENTINEL ADVISORYinto the Lead pane — the Lead stops starting new tasks while in-flight work rides to 100%. The same soft-band rule gates every spawn via a one-shotusage-monitor.sh statuscheck, so new work never starts over a tightening budget. A fleet that stops itself this way is woken at the reset like any other: nothing was limit-killed, so nothing is parked, and the Lead also arms its own backup wake before going idle. - Weekly (7d) limit: a days-long park is a user decision, not an automation problem — the sentinel notifies you, and the Lead presents the options (wait for the weekly reset, switch account, or park the plan).
Still two agents, not three: PM (which owns the liveness monitor — NUDGE verification — and per-task budget bookkeeping) and the Lead. Usage limits moved out of agents entirely, into the one machine-wide sentinel process. There is no usage-mode question (opt out with an explicit “full speed” instruction — reset wakes still happen), no 90/95% hard stop, and no sacrificed window margin: execution uses 100% of every window and auto-resumes across windows, including fully unattended overnight runs. Per-task budget data (usage % at start/end) is tracked in plan.json for the operational report.