Execute one autopilot-director Spec run: drive a spec issue and its child
tickets to a single Spec PR. Every state transition goes through the director
CLI; a change the CLI cannot record did not happen.
Vocabulary lives in CONTEXT.md ("Autopilot Director"); the decisions behind
it are ADR 0046 (role-pinned models), ADR 0047 (one Spec PR, one commit per
ticket) and ADR 0048 (two-axis gate, absolute-zero bar, escalation).
Parameters
| parameter |
default |
meaning |
| spec issue |
required |
the spec to complete |
| worker model |
deepseek-flash |
the Role-pinned model the Worker is spawned on |
| auto-merge |
off |
off: open the Spec PR and stop for human approval; on: merge once CI is green and both gates are at zero |
| worktree |
current checkout |
run state lives in its git-ignored .director/ |
Preconditions
director --help works. When the toolkit is installed, prefer the path in
~/.agents/skills/.autopilot/director.env (AUTOPILOT_DIRECTOR_BIN) and
fall back to the stable ~/.agents/skills/.autopilot/bin/director; in a
source checkout, cargo build --release -p director-cli.
gh is authenticated for the spec's repository.
- You are in the target worktree; never bypass the CLI's
.director/
git-ignore enforcement.
Sub-agent dispatch model (Codex)
- Worker — spawn with an explicit model override:
spawn_agent(agent_type: "worker", model: "<worker model>", fork_turns: "none", message: <dispatch>).
The model pin is per dispatch and never committed. fork_turns: "none" (or a
positive count; MultiAgentV1's equivalent is fork_context: false) is
required: a full-history spawn inherits the lead model and cannot be pinned.
- The Worker's dispatch message carries the ticket issue reference, the
worktree, the branch, the ticket's
Seam: annotation (or your
Seam(inferred)), the instruction to read
~/.agents/skills/autopilot-director/runtime/default/references/worker-contract.md
(references/worker-contract.md in a source checkout) and follow the upstream
tdd skill, and — on a fix round — the findings to resolve.
- Reviewers — one spawn per axis per round, both on the default (lead)
model, each fresh, each receiving only its own axis prompt: the smell
baseline pasted in full, the standards sources listed, the spec content
quoted. Never pass Worker context to a reviewer.
- Spawn fallback — deliver every dispatch as a file pointer: write the
brief to a file, then send "read
<path> and execute it end to end". A
pointer survives a payload that arrives empty. If a spawned agent still
returns without a payload or without its WORKER_REPORT:, re-dispatch once
through a follow-up (send_input on MultiAgentV1; followup_task on v2);
record the dead attempt first, as
director dispatch finish --ticket <n> --outcome failed --reason "no payload"
so the retry budget and the audit ledger show what happened. If the retry
fails too, do that piece of work yourself and record the fallback in the run
report. Do not spend the run fighting the spawn path.
The loop
1. Read the spec
gh issue view <spec> --json number,title,body; list children with
gh issue list --state open --json number,title,body (children carry a
Parent section). The Blocked by sections define the task graph and its
frontier; v1 runs tickets serially off that frontier.
2. Open or resume the run
- Fresh:
director init --worktree <wt> --spec-issue <N> --slug <slug> (the
slug of codex/spec-<N>-<slug>), then
director run transition --worktree <wt> --to running.
- Resuming:
director resume --worktree <wt>; a drift error stops the run
until a human settles or explicitly accepts the drift
(--accept-drift).
director ticket add --worktree <wt> --ticket <n> --title <title> [--blocked-by <m>]... for every child ticket, once.
3. Per-ticket loop
director ticket transition --ticket <n> --to implementing.
director dispatch begin --ticket <n> --worker <label>.
- Spawn the Worker (see dispatch model). Wait for it, then
director report validate --ticket <n> (stdin) or --file <path>, and
director dispatch finish --ticket <n> --outcome ok|failed [--reason <text>].
Malformed envelope, a blocked report, or no commits: failed dispatch. The
state machine permits one same-Worker retry, then escalates on its own.
- Run the repo's test gates yourself; Worker claims are never gate evidence.
Gates failing sends the same Worker back (
--to implementing).
director ticket transition --ticket <n> --to gating, then the review
rounds:
director round open --ticket <n>;
- spawn the two fresh axis reviewers (the Standards axis also carries this
repo's two review rules: a guard names its single implementation and tests
the contract's boundary state at the decision point; a rename moves every
usage string, help text, doc comment and inventory count); record every finding with
director finding record --ticket <n> --round <k> --axis <standards|spec> --id <id> --hash <hash> --summary <text>;
director round close --ticket <n> --round <k>;
- adjudicate each finding —
director finding dispose ... --fixed <commit> or
director finding dispose ... --rejected "<written reason>";
director gate --ticket <n> must exit 0. Otherwise
director ticket transition --ticket <n> --to fixing, hand the findings
back to the same Worker, and open the next round. Three rounds per layer
maximum: a fourth round open refuses and escalates the layer.
4. Ticket boundary commit
At zero, squash the ticket's work-in-progress commits into one
feat: <title> (ticket #N) commit, then
director ticket transition --ticket <n> --to done.
5. Aggregate gate and the Spec PR
- All tickets
done → director run transition --to spec-gating.
- Same two-axis gate over the aggregate diff (
--spec), same zero bar, same
three-round cap.
- Push the branch only now; open the one Spec PR listing every ticket with
Closes #…; director run transition --to pr-open.
- Auto-merge off (default): stop and hand the PR to the human. Auto-merge on:
wait for CI green and
director gate at zero, merge with a merge commit
(squash-merge would flatten the boundary commits), then
director run transition --to done.
- Confirm every ticket issue closed; report the run.
Escalation
Stop the run and report — finding evolution across rounds, the Worker's
self-reports, your diagnosis, and the decision you need (grant more rounds,
implement directly, or abandon the ticket). Resume only on an explicit human
decision through the legal edges (escalated → reviewing buys another cap's
worth of rounds; escalated → implementing means you implement it directly).
Boundaries
- One Spec PR per run; never per-ticket PRs, never squash-merges.
- Never assert a gate result:
director gate is the only source of truth.
- Leave
autopilot-orchestrator and autopilot-reviewer untouched.
- Workers never review; reviewers never implement; you never hand a judgment to
a subagent that you can check with the CLI.
1---2name: autopilot-director-23description: Codex autopilot-director Spec run: one spec, one PR, Workers on a pinned fast model, a code-owned state machine, and a two-axis gate that must reach absolute zero.4---56Execute one autopilot-director **Spec run**: drive a spec issue and its child7tickets to a single Spec PR. Every state transition goes through the `director`8CLI; a change the CLI cannot record did not happen.910Vocabulary lives in `CONTEXT.md` ("Autopilot Director"); the decisions behind11it are ADR 0046 (role-pinned models), ADR 0047 (one Spec PR, one commit per12ticket) and ADR 0048 (two-axis gate, absolute-zero bar, escalation).1314## Parameters1516| parameter | default | meaning |17| --- | --- | --- |18| spec issue | required | the spec to complete |19| worker model | `deepseek-flash` | the Role-pinned model the Worker is spawned on |20| auto-merge | off | off: open the Spec PR and stop for human approval; on: merge once CI is green and both gates are at zero |21| worktree | current checkout | run state lives in its git-ignored `.director/` |2223## Preconditions24251. `director --help` works. When the toolkit is installed, prefer the path in26 `~/.agents/skills/.autopilot/director.env` (`AUTOPILOT_DIRECTOR_BIN`) and27 fall back to the stable `~/.agents/skills/.autopilot/bin/director`; in a28 source checkout, `cargo build --release -p director-cli`.292. `gh` is authenticated for the spec's repository.303. You are in the target worktree; never bypass the CLI's `.director/`31 git-ignore enforcement.3233## Sub-agent dispatch model (Codex)3435- **Worker** — spawn with an explicit model override:36 `spawn_agent(agent_type: "worker", model: "<worker model>", fork_turns: "none", message: <dispatch>)`.37 The model pin is per dispatch and never committed. `fork_turns: "none"` (or a38 positive count; MultiAgentV1's equivalent is `fork_context: false`) is39 required: a full-history spawn inherits the lead model and cannot be pinned.40- The Worker's dispatch message carries the ticket issue reference, the41 worktree, the branch, the ticket's `Seam:` annotation (or your42 `Seam(inferred)`), the instruction to read43 `~/.agents/skills/autopilot-director/runtime/default/references/worker-contract.md`44 (`references/worker-contract.md` in a source checkout) and follow the upstream45 `tdd` skill, and — on a fix round — the findings to resolve.46- **Reviewers** — one spawn per axis per round, both on the default (lead)47 model, each fresh, each receiving only its own axis prompt: the smell48 baseline pasted in full, the standards sources listed, the spec content49 quoted. Never pass Worker context to a reviewer.50- **Spawn fallback** — deliver every dispatch as a file pointer: write the51 brief to a file, then send "read `<path>` and execute it end to end". A52 pointer survives a payload that arrives empty. If a spawned agent still53 returns without a payload or without its `WORKER_REPORT:`, re-dispatch once54 through a follow-up (`send_input` on MultiAgentV1; `followup_task` on v2);55 record the dead attempt first, as56 `director dispatch finish --ticket <n> --outcome failed --reason "no payload"`57 so the retry budget and the audit ledger show what happened. If the retry58 fails too, do that piece of work yourself and record the fallback in the run59 report. Do not spend the run fighting the spawn path.6061## The loop6263### 1. Read the spec6465`gh issue view <spec> --json number,title,body`; list children with66`gh issue list --state open --json number,title,body` (children carry a67`Parent` section). The `Blocked by` sections define the task graph and its68frontier; v1 runs tickets serially off that frontier.6970### 2. Open or resume the run7172- Fresh: `director init --worktree <wt> --spec-issue <N> --slug <slug>` (the73 slug of `codex/spec-<N>-<slug>`), then74 `director run transition --worktree <wt> --to running`.75- Resuming: `director resume --worktree <wt>`; a drift error stops the run76 until a human settles or explicitly accepts the drift77 (`--accept-drift`).78- `director ticket add --worktree <wt> --ticket <n> --title <title>79 [--blocked-by <m>]...` for every child ticket, once.8081### 3. Per-ticket loop82831. `director ticket transition --ticket <n> --to implementing`.842. `director dispatch begin --ticket <n> --worker <label>`.853. Spawn the Worker (see dispatch model). Wait for it, then86 `director report validate --ticket <n>` (stdin) or `--file <path>`, and87 `director dispatch finish --ticket <n> --outcome ok|failed [--reason <text>]`.88 Malformed envelope, a `blocked` report, or no commits: failed dispatch. The89 state machine permits one same-Worker retry, then escalates on its own.904. Run the repo's test gates yourself; Worker claims are never gate evidence.91 Gates failing sends the same Worker back (`--to implementing`).925. `director ticket transition --ticket <n> --to gating`, then the review93 rounds:94 - `director round open --ticket <n>`;95 - spawn the two fresh axis reviewers (the Standards axis also carries this96 repo's two review rules: a guard names its single implementation and tests97 the contract's boundary state at the decision point; a rename moves every98 usage string, help text, doc comment and inventory count); record every finding with99 `director finding record --ticket <n> --round <k> --axis <standards|spec>100 --id <id> --hash <hash> --summary <text>`;101 - `director round close --ticket <n> --round <k>`;102 - adjudicate each finding —103 `director finding dispose ... --fixed <commit>` or104 `director finding dispose ... --rejected "<written reason>"`;105 - `director gate --ticket <n>` must exit 0. Otherwise106 `director ticket transition --ticket <n> --to fixing`, hand the findings107 back to the same Worker, and open the next round. Three rounds per layer108 maximum: a fourth `round open` refuses and escalates the layer.109110### 4. Ticket boundary commit111112At zero, squash the ticket's work-in-progress commits into one113`feat: <title> (ticket #N)` commit, then114`director ticket transition --ticket <n> --to done`.115116### 5. Aggregate gate and the Spec PR1171181. All tickets `done` → `director run transition --to spec-gating`.1192. Same two-axis gate over the aggregate diff (`--spec`), same zero bar, same120 three-round cap.1213. Push the branch only now; open the one Spec PR listing every ticket with122 `Closes #…`; `director run transition --to pr-open`.1234. Auto-merge off (default): stop and hand the PR to the human. Auto-merge on:124 wait for CI green and `director gate` at zero, merge with a **merge commit**125 (squash-merge would flatten the boundary commits), then126 `director run transition --to done`.1275. Confirm every ticket issue closed; report the run.128129## Escalation130131Stop the run and report — finding evolution across rounds, the Worker's132self-reports, your diagnosis, and the decision you need (grant more rounds,133implement directly, or abandon the ticket). Resume only on an explicit human134decision through the legal edges (`escalated → reviewing` buys another cap's135worth of rounds; `escalated → implementing` means you implement it directly).136137## Boundaries138139- One Spec PR per run; never per-ticket PRs, never squash-merges.140- Never assert a gate result: `director gate` is the only source of truth.141- Leave `autopilot-orchestrator` and `autopilot-reviewer` untouched.142- Workers never review; reviewers never implement; you never hand a judgment to143 a subagent that you can check with the CLI.