# Supervised Dev

> Use to run a ticket end-to-end through the supervised delivery pipeline: tester writes failing tests, implementer fixes production code, reviewer inspects the diff, simplifier finds over-built surface, supervisor gives a single combined verdict. Invoked by the supervisor when the user provides a ticket.

- Skill: `alyahmedaly/supervised-dev` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add alyahmedaly/supervised-dev`
- Raw SKILL.md: https://api.skillmd.com/api/skills/alyahmedaly/supervised-dev/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: alyahmedaly (https://skillmd.com/u/alyahmedaly)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/alyahmedaly/supervised-dev

---


# Supervised Delivery

Run one ticket through the full pipeline. Serial execution, one worktree. No parallel writers.

## When this pipeline is the wrong tool

Four subagents cost four system prompts, four tool schemas, four handoffs, and four reviews before any code changes. That fixed prefix only repays itself on work with real correctness risk and enough substance to amortise it.

Downshift to the first row that covers the work:

| Work                                                | Run it as                                    |
| --------------------------------------------------- | -------------------------------------------- |
| One-line fix, typo, mechanical rename, comment      | Yourself, plus the one relevant check        |
| Bounded change, one or two files, obvious oracle    | Yourself, plus one reviewer pass on the diff |
| Copy-and-wrap or move-and-rewire: oracle is diff vs source plus existing suite | Light loop — see "Light loop" below |
| Real feature or refactor, non-obvious failure modes | Full pipeline below                          |
| Repo-wide sweep of N near-identical units           | Full pipeline, batched — see Phase 3         |

The rows have moved down over time. Current models finish multi-file features end to end without leaving
stubs when handed the complete specification up front, so work that once needed the pipeline to avoid
half-done output now sits a row lower — the pipeline buys independent judgement on a diff, not completion.
Escalating past the row the work sits in is a cost with no buyer. Name the row you picked, and why, in your first message so the user can push back before the delegation is paid for.

## Light loop

For work whose diff is verifiable by one mechanical comparison — a file moved from one directory to another with only import lines changed, plus a thin wrapper — the reviewer and simplifier re-read a diff that `diff -r` already judges. Run tester and implementer only; the supervisor does the read-only verification.

The ticket carries `loop: light` (see `references/ticket-shape.md`); Phase 0 sets it from the downshift row. Phase 4 and Phase 7's reviewer/simplifier dispatch are skipped. Everything else — tester first, implementer, oracles, push verification, ticket close — is unchanged.

Supervisor verification checklist for a light-loop ticket, run at the implementer's head SHA:

```
diff -r <source dir> <destination dir> --exclude=node_modules --exclude=dist | grep -Ev '^(<|>) *import|^(<|>) *} from|^(diff|---|Only in)'   # expect empty
git ls-files <destination dir> | grep -E 'node_modules|/dist/|\.tsbuildinfo|\.DS_Store'   # expect empty
grep -rnE "^export (type|interface|enum) <Name>" <repo source roots> for each exported type the diff adds   # one hit per name
<ticket Verification command>   # exact pass/total
```

Escalate to the full loop mid-ticket, and dispatch Phase 4 on the same head SHA, when any of these hold:

- The first diff command above prints a non-import hunk.
- The implementer's return lists a non-empty "deviations from ticket".
- The tester's parity pins needed a threshold, tolerance, or normalisation the legacy suite did not have.

Across sibling light-loop tickets, reuse the same tester and implementer agents via `SendMessage` with a delta brief — the re-read of repo and conventions is the cost being cut, and a fresh agent pays it again.

## Phase 0 — Ticket

The pipeline runs on a ticket in the shape of `references/ticket-shape.md`.

- If the user hands you a ticket, validate it against that shape: every Acceptance bullet has an
  oracle; Out of scope and Pinned rules are present; `mode: AFK`; `effort: S|M`; `loop: full|light` set per the downshift table.
- If the user hands you prose, inspect the repo and DRAFT the ticket yourself in that shape, write it
  to the repo's ticket directory, show it, and wait for approval. Phase 0 is the only place the pipeline
  blocks on the user — the ticket is the scope contract, and the intent pass below is part of that block.
- If the work is L, or is N similar units, draft a plan per `references/plan-shape.md` plus its
  tickets, and run one ticket at a time.
- Anything answerable from the repo — base SHA, commands, conventions — you fill in yourself; never
  ask the user for it.
- Run the intent pass below over every ticket that arrives with `intent_recorded: null`, before any
  delegation — one you drafted, and one the user handed you. A ticket the user wrote with an agent carries
  that agent's choices too.
- Only `mode: AFK` tickets enter Phase 1, and only with `intent_recorded:` set.
- Run the supersession check (`references/ticket-shape.md`) before writing a new ticket.

### Intent pass

A ticket an agent drafted reads as settled work, which is exactly what hides the choices the agent made
on its own. The intent pass is an interactive review of those choices: the user reads each ticket by
answering for it, and the answers land in the ticket as `## Recorded intent`.

Ask about choices, not facts. A repo fact — test command, conventions, base SHA — you answer yourself
and never ask. A load-bearing choice the drafter made unilaterally you ask **even when the ticket already
states it**: the ticket stating it is what makes the question worth asking, because a choice the user
confirmed and a choice the drafter drifted into look identical on the page.

Two passes, after every ticket is drafted and before any delegation:

1. **Plan pass.** Choices shared across tickets — framework, storage, auth, wire format — asked once and
   recorded in the plan's `## Decision`, tagged `user-decided`. Tickets reference the plan and never
   re-ask. Without this pass, ten tickets ask the framework question ten times.
2. **Ticket pass.** Enumerate every candidate question across all tickets, rank each by how much work a
   wrong answer throws away, cut to the budget, then ask in dependency order.

Budget, because attention is the scarce resource here and ten tickets at four questions each is a wall
nobody reads:

- 1 question per ticket minimum, 4 maximum.
- Plan-wide total: `<ticket count> + 4`. Spend the slack on the tickets whose wrong answer costs most.
- Pack four questions per `AskUserQuestion` call, drawn **across** tickets, with `header` naming the
  ticket id. Ten one-question tickets are three prompts, not ten.

Question shape: option 1 is what the ticket currently says, labelled `(Recommended)`, with its reason
grounded in the repo wherever the repo has evidence — "`apps/portal` already runs Next 15", not taste.
Options 2–3 are the live alternatives. Taking the recommendation is a confirmation; taking another is an
override, and an override records the user's own words verbatim.

Candidates below the cut are not dropped into silence. Write each into the ticket as an `Assumed.` entry
in `## Recorded intent`. An assumption the user can read and reverse costs no prompt; an assumption
nobody wrote down is the drift this pass exists to catch.

An override that invalidates a sibling ticket sends that sibling back for a redraft plus one more
question. One redraft round, then proceed.

## Roles and tools

| Role        | Tool                                           | Authority                                 | Model   | Effort |
| ----------- | ---------------------------------------------- | ----------------------------------------- | ------- | ------ |
| Supervisor  | — (you)                                        | Plan, delegate, gate, verdict             | inherit | high   |
| Tester      | `Agent(subagent_type: "subagent-tester")`      | Tests only; `acceptEdits`                 | sonnet  | medium |
| Implementer | `Agent(subagent_type: "subagent-implementer")` | Production changes; `acceptEdits`         | sonnet  | high   |
| Reviewer    | `Agent(subagent_type: "subagent-reviewer")`    | Read-only diff review; `dontAsk`          | sonnet  | medium |
| Simplifier  | `Agent(subagent_type: "subagent-simplifier")`  | Read-only simplification audit; `dontAsk` | sonnet  | medium |

Effort applies where the runtime exposes it (Codex `model_reasoning_effort`); on Claude Code the Model
column is the lever.

Agent definitions live in `~/.claude/agents/subagent-*.md`; if the session's agent list does not show them, stop and tell the user before Phase 2.

You coordinate and maintain the ticket, plan, and handoff documents. Production and test edits stay
with their assigned roles unless the user explicitly asks you to make them. Documentation updates are
serial too: do not write while another writer or a same-SHA review is active.

### Runtime adapter

Abstract needs, per host. Delegate a role means "hand the role's `roles/<role>.md` body plus the ticket
brief to a fresh agent." Sources are cited per cell; a cell with no confirmed source says so.

| Need                                 | Claude Code                                                    | Codex CLI                                                                                                                                                                                                                                                                                                                                           |
| ------------------------------------ | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Skill install path                   | `~/.claude/skills/supervised-dev`                              | `~/.agents/skills/supervised-dev` (user-level; repo-level is `<repo>/.agents/skills`) — symlink one dir to serve both: `ln -s ~/.claude/skills/supervised-dev ~/.agents/skills/supervised-dev`. Source: `developers.openai.com/codex/skills` (redirects to `learn.chatgpt.com/docs/build-skills`).                                                  |
| Delegate a role                      | `Agent(subagent_type: "subagent-<role>")`                      | No native subagent/spawn command found (R3; see `codex --help` command list, local codex-cli 0.153.2). Supervisor shells out per delegation: `codex exec -s <sandbox> --approve-for-me -m <model> -c model_reasoning_effort=<effort> "$(cat roles/<role>.md)"$'\n\n'"<ticket brief>"`. Source: local `codex exec --help`.                           |
| Write-capable role permissions       | `permissionMode: acceptEdits`                                  | `-s workspace-write --approve-for-me` (sandbox permits workspace writes; approvals routed through automatic review instead of prompting). Source: local `codex exec --help`.                                                                                                                                                                        |
| Read-only role permissions           | `tools:` list omits Edit/Write, plus `permissionMode: dontAsk` | `-s read-only` (sandbox blocks writes outright). Source: local `codex exec --help`.                                                                                                                                                                                                                                                                 |
| Model per role                       | `sonnet` (all four roles)                                      | unconfirmed — verify. No per-role Codex model recommendation found in R2/R4; only generic example ids (`gpt-5.6-terra` in docs, `gpt-5.3-codex-spark` in the local `codex-cli-runtime` skill for an unrelated "spark" mapping). Do not guess a model id.                                                                                            |
| Reasoning effort                     | No knob; the Model column is the lever                         | `-c model_reasoning_effort=<value>`, values `minimal, low, medium, high, xhigh`. Value vocabulary confirmed via local skill `.../codex/skills/codex-cli-runtime/SKILL.md` (`--effort` wrapper flag). Exact TOML key spelling `model_reasoning_effort` is unconfirmed — verify: `developers.openai.com/codex/config` returned HTTP 404 when fetched. |
| Handoff path                        | `docs/<feature>/handoff.md`, following repo convention          | Same tracked path; see Durable state |
| Optional scratch logs               | Outside the repo                                              | `${TMPDIR:-/tmp}/supervised-dev/<branch>/` |
| Continue a role agent across batches | `SendMessage` to the same agent                                | No native resume-a-role feature (R3). Use `codex exec resume --last` (or by session id) on that role's own subprocess session, sending only the delta instruction. Source: local `codex exec --help` ("resume Resume a previous session by id or pick the most recent with --last").                                                                |

Details, unconfirmed items, and a Codex smoke test: `references/codex-host.md`.

### Model, and the four-role cap

Model choice is the primary cost lever, not just a style knob. Pick a cheaper model for read-only roles;
step a role up only when the work demands it.

- Reviewer and simplifier run on `sonnet`. Review precision does not need the strongest model, so one
  cheap pass per SHA beats one expensive pass. Escalate a single re-review to the strongest available
  model only for a diff touching auth, credentials, or destructive operations.
- Step the implementer up to the strongest available model for demanding work: concurrency, teardown,
  wire formats, or a tracer unit that must establish the pattern for N siblings.
- **Never run a searching role on the cheapest model.** A cheaper model calls search and retrieval tools
  less and answers from memory instead. A simplifier that does this will assert "no consumer" without
  running the call-site grep that is the only thing making that finding admissible.
- Keep thinking enabled. Disabling it is the wrong cost lever — pick a cheaper model instead. With
  thinking off, an agent occasionally writes a tool call into its prose instead of calling the tool, and
  can leak internal XML tags into the return. A return that narrates a command it never ran is unexecuted
  work: re-delegate it, never read it as a result.
- A benign brief can come back as a **safeguard refusal**. Compile-check phrasing ("does this compile
  without errors?") and base64 blobs in tool output are the known triggers: ask "are there bugs in this",
  and never paste base64 into a brief. A refusal is a phrasing defect in your brief, not a finding, and
  not evidence about the code.
- **Four delivery roles is the cap.** No subagent spawning its own. The supervisor may dispatch one
  read-only context investigator for broad sweeps or costly exploration, before delivery agents run
  (see Phase 1). This is an optional context pass, not a fifth delivery role or another review gate.

Effort-specific guidance below applies where the runtime exposes an effort knob (Codex); on Claude Code
pick the model tier instead.

- **Effort labels are not portable.** The same word buys different amounts of thinking on different
  models, so a level that worked for a role last quarter is a starting point, not a setting. Confirm
  against the model actually behind each role. (Codex; on Claude Code pick the model tier instead.)
- Step the implementer to `xhigh` only for demanding work: concurrency, teardown, wire formats, or a
  tracer unit that must establish the pattern for N siblings. (Codex; on Claude Code pick the model tier
  instead.)
- **Never run a searching role at `low`.** At low effort models call search and retrieval tools less and
  answer from memory instead. A simplifier at `low` will assert "no consumer" without running the
  call-site grep that is the only thing making that finding admissible. (Codex; on Claude Code pick the
  model tier instead.)
- At `xhigh` or `max`, leave `max_tokens` headroom for the thinking _and_ the output. A long deliverable
  can get drafted inside the thinking and written again as the reply, which doubles the turn and can
  truncate it. Long prose deliverables run at `high`. (Codex; on Claude Code pick the model tier instead.)

## Sequence

### Phase 1 — Scope

Inspect the repository to understand current state. Clarify only decisions with real consequences. Record:

- Exact file scope
- Acceptance criteria (pass/fail, not vague goals)
- Out-of-scope list
- Known decisions
- Architecture rules to pin: conventions this change must not break, read from the repo's `AGENTS.md`/`CLAUDE.md` and neighbouring code
- Verification command: the cheapest relevant check for the affected workspace, read from the repo's own docs — never guessed
- Full gate set: read it off what the repo's own `verify:local` / `verify:push` / CI phase scripts actually compose. Do not hand-write the list, and do not inherit one from a previous session's handoff. A gate you never listed is a gate nobody runs (incidents.md #1).
- Expected-red inventory: list the gates that are red by construction for the whole ticket, and record why — an end-state test can stay red for an entire sweep by design (incidents.md #2). Exclude these from the per-batch loop, never hand one to an implementer to "fix" into green, and route its teardown to a tester pass.
- Oracle per criterion: the exact command or state check that decides it. A criterion with no oracle is a wish — give it one or move it out of scope. You stop when the oracles pass, not when the work looks finished. When the build emits nondeterministic artifact names, the oracle must normalize before comparing (incidents.md #3).
- CI trigger map: read the repo's own workflow files and record what actually fires the gates Phase 8 depends on — including the branch filters, not just the event names. A push can fire no CI at all if the filters exclude it (incidents.md #4); read the filters in Phase 1, do not infer them from the event list.
- Capability preflight: confirm the tools the plan leans on actually work here, before planning around them — package registry reachability, auth for any host CLI, worktree cleanliness, write access (incidents.md #23). Never route around a failure by hand-editing a lockfile.
- Working branch or worktree: create it before recording base SHA, named per repo convention, and record the branch name in the handoff. A fresh worktree has no `node_modules`, so a bare `npx <tool>` inside it can resolve a different tool version than the main checkout — run formatters and linters from an installed tree, or install first.

A ticket in the shape of `references/ticket-shape.md` already answers most of the above:

| Ticket section        | Phase 1 field                             |
| --------------------- | ----------------------------------------- |
| Recorded intent       | Known decisions                           |
| Required changes      | File scope                                |
| Out of scope          | Out-of-scope list                         |
| Pinned rules          | Architecture rules to pin                 |
| Acceptance            | Acceptance criteria, oracle per criterion |
| Verification          | Verification command, full gate set seed  |
| `source:`             | Evidence index for scoped reading         |
| `blocked_by`/`blocks` | Sequencing                                |
| `mode`/`effort`       | Eligibility                               |

The ticket does not carry the expected-red inventory, the CI trigger map, or the capability preflight — derive those in Phase 1 regardless.

A recorded-intent decision that is testable is already a pinned rule (`references/ticket-shape.md`); the
rest are constraints you carry into the briefs, not tests.

Run: `git rev-parse HEAD` to record base SHA.

#### Collect context once, refresh the delta

Before the first tester dispatch, finish the scope recon. Persist decisions and resume information in
the ticket and `docs/<feature>/handoff.md`; put detailed, source-derived assignment context in temporary
briefs when useful (see Brief hygiene). Read all sources relevant to the ticket: scoped files, callers,
tests, configuration, and representative implementations. Collect:

- Branch/worktree, base SHA, and the SHA inspected; identify any relevant uncommitted changes separately.
- Exact source paths and symbols, their responsibilities, and dependencies that affect this ticket.
- Current allowlist contents with their owning file/symbol when applicable; label these as observed
  state, separate from the ticket's required end state.
- For sweeps, a per-service/unit table: unit, exact paths, migration state, remaining work, and commit
  SHA when completed. Include every target, including blocked and untouched units.
- Sample implementation and test pattern references (`path:symbol`), with exceptions called out.
  Once the tracer passes its gates, make it the canonical reference for later batches.
- Phase 1 gate commands and tiers, expected-red inventory, CI triggers, preflight results, and gaps.
  Mark missing coverage explicitly; do not imply an unread source was inspected.

The supervisor normally does this during Phase 1. For a broad sweep or costly exploration, it may use
one read-only investigator/fork supported by the host, scoped to the ticket and these return fields.
The investigator does not edit files or spawn agents. The supervisor checks its findings and places
them in the appropriate durable document or temporary brief before delivery delegation. If that
capability is unavailable, collect locally; no new installed role is required.

Before every tester or implementer dispatch, including batches and fix/retest cycles, compare the
recorded branch, inspected SHA, and working-tree state with current state. Inspect intervening changes
and refresh affected context, including allowlists and new tests. Reuse unchanged findings rather than
repeating the full recon. A resumed Phase 1 still re-derives repository-owned gates and allowlists from
their owners. Preserve the original base SHA; a branch/base mismatch must be reconciled before using
the snapshot. Record the updated checkpoint and refresh any affected brief before dispatch.

#### Brief hygiene

Every template below is a contract, not prose. Applies to all four roles:

- **Temporary assignment briefs.** For detailed delegation, write a role/batch brief outside the repo,
  for example `/tmp/supervised-dev/<ticket>/impl-batch-fg.txt`, and instruct the agent to read it before
  starting. Include the assignment scope, source-derived values, pattern references, exact commands,
  and expected return. Shared source findings may serve several briefs. Keep short assignments inline;
  a brief does not change batch size, commit granularity, role permissions, or gate ownership.
- **Make briefs traceable.** Include the exact starting SHA, repo/worktree and branch, real ticket and
  handoff paths, and source references for collected facts. Pin the SHA after the preceding checkpoint;
  never leave it as "the previous batch's commit". Distinguish observed values from required changes.
  The ticket owns scope and decisions; a temporary brief cannot silently override them.
- **Shared context first.** Every dispatch, including re-delegation, names the ticket and handoff paths
  and any assignment brief. Read the brief first when supplied, then ticket status (`Current status`,
  or `Notes`), `Recorded intent`, recent `Updates`, and handoff findings before scoped source reading.
  The snapshot saves discovery; it does not replace the reviewer's full diff/call-path reading, the
  simplifier's consumer searches, or live gate evidence.
- **Point, do not paste.** Give `path:symbol` and SHA-qualified findings. Temporary briefs may include
  exact allowlist entries, commands, or small examples needed for the assignment; avoid copying entire
  source files or duplicating that recipe into the ticket/handoff. Agents report stale facts or missing
  context to the supervisor, who maintains the shared documents.
- **State only the delta on re-delegation.** An agent you already briefed still holds the recipe; re-sending the whole ticket invites it to redo settled work.
- **Demand exact returns, and name the fields.** SHAs, counts as `passed/total`, verbatim failure text, and the commands actually run. Ban summary adjectives: "suite is green" is not a result; `854/854` is. Ask for the fields and the table explicitly — current models reach for structure less on their own, so an unspecified return format comes back as prose you have to parse.
  Ban _adjectives_, not status lines. Do not write "hold all findings for the final response" or otherwise suppress narration: models already go quiet through long tool chains, and a silent agent is indistinguishable from a stalled one. Ask for a line when it starts, a line when it changes direction, and the exact fields at the end.
- **A sent brief is not a started task.** After delegating, confirm the agent actually picked the work up — new commits, or an agent-list check — instead of assuming a delivered message equals work in progress (incidents.md #5).
- **Say the user is not watching.** Every brief opens with it: the agent is operating autonomously, nobody can answer mid-task, so "shall I apply this?" blocks the work. Reversible steps that follow from the brief proceed without asking; only destructive actions and genuine scope changes stop. Without this, an agent describes its next step and ends the turn, and the step stays undone until you reply.
- **Point at recorded intent; never re-open it.** Briefs cite `<ticket path>` `## Recorded intent` rather
  than pasting the decisions. An agent that reconsiders a recorded choice is re-running the intent pass
  with nobody in the room, and the answer it invents outranks nothing.
- **Carry the scope clause.** Deliver what the brief asks at the scope asked; make routine judgment calls yourself; if the ticket looks mistaken, say so in one sentence and continue as asked rather than narrowing, widening, or transforming it. A pre-existing bug, a nearby performance smell, or undocumented behaviour found while working is a follow-up line in the return, not a change in this diff. Current models expand scope on their own judgment far more readily than they omit work, and an unasked-for improvement lands in the same diff the reviewer must clear.
- **Ask for surgical edits.** Say that edit tokens are to be minimized and a file should be patched, not rewritten, where that does not change the result. Left alone, models rewrite whole files for small changes — same content, but a diff the reviewer cannot read and a base SHA comparison full of noise.
- **Do not ask an agent to double-check itself.** Agents already verify their own work; "re-verify before reporting" or "add a final verification step" compounds with that and buys tokens, not quality. Brief the oracle instead — the exact command whose output decides the criterion. Supervisor verification is a different role reading a different signal, not the same agent looking twice.
- **Never brief a read-only role to be conservative.** "Only report high-severity issues" or "be conservative" is followed literally and suppresses real findings. Ask for everything at every severity; Phase 5 is the filter, and disproving a finding is cheaper than missing one.
- **Ban correction narration and mannered prose.** Returns state the final measured state, in direct language. An agent recounting what it first got wrong then fixed costs a re-read and buries the number you asked for, and metaphor in a return ("the dial worth turning") drags in connotations that make a fact ambiguous.

### Phase 2 — Tester first

Call `subagent-tester` with this template:

```
Ticket: <ticket path>
Handoff: <handoff path>
Assignment brief: <path, if used>
Read first: assignment brief if supplied, then ticket status/Notes, Recorded intent,
recent Updates, and handoff findings.
Base SHA: <sha>
Current head SHA: <checkpoint sha>
Acceptance criteria: <list>
Out of scope: <list>
Architecture rules to pin: <list from Phase 1>

Write two test classes:
1. Acceptance tests, one roughly per stated behavior. These must FAIL against
   the current production code — they assert what the ticket has not built yet.
2. Architecture-pin tests, one per architecture rule listed above. These assert
   a rule the change must not break, so they must PASS against the current
   production code. Their job is to catch the implementer breaking the rule
   later, not to fail now.
Do NOT fix production code.
Do NOT soften assertions.

Size the suite to the ticket, in the style and file layout of the neighbouring
tests. Scratch scripts and throwaway checks are yours to use and are NOT
committed as permanent test files.

Commit your test changes.
Return: test commit SHA, list of test files changed, which acceptance tests fail
and exact failure message, which architecture-pin tests pass and their names.
```

Wait for result. Confirm acceptance tests fail on base SHA and architecture-pin tests pass on base SHA. If tester edits production code, reject and re-delegate.

Count the committed test files against the criteria before accepting. Models over-commit tests on
open-ended briefs — scratch checks get promoted into permanent files, and every extra file is surface the
implementer must keep green and the reviewer must read. An unasked-for test file is an `in-diff` S1 for
the simplifier, and it is cheaper to reject it here.

### Phase 3 — Implement

Call `subagent-implementer` with this template:

```
Ticket: <ticket path>
Handoff: <handoff path>
Assignment brief: <path, if used>
Read first: assignment brief if supplied, then ticket status/Notes, Recorded intent,
recent Updates, and handoff findings.
Base SHA: <sha>
Current head SHA: <checkpoint sha>
Test commit SHA (do not modify these tests): <tester sha>
Acceptance criteria: <list>
Out of scope: <list>

You are operating autonomously; nobody can answer questions mid-task. Reversible
steps that follow from this brief proceed without asking. Stop only for a
destructive action or a real scope change.

Fix production code so the tester's tests pass.
Do NOT change test files or soften assertions.
Do NOT expand into other tickets. A pre-existing bug or nearby smell you find is a
follow-up line in your return, not an edit in this diff.
Do NOT rebase, merge, pull, fetch, or reset. If you think history must move, stop and report.
Patch files surgically; do not rewrite a whole file for a small change.
Oracle: <verification command from Phase 1>. Green on this command is the done condition.
Commit when done. Do NOT push.
Return: head SHA, changed files, verification commands run (fresh vs cached), deviations from ticket,
follow-ups you deliberately did not fix.
```

Wait for result. Confirm tester's tests pass at returned SHA without modification.

The rebase prohibition is not paranoia: an unasked rebase can move the base SHA and invalidate every later
comparison (incidents.md #6). Every "record the measured fact with its SHA" rule below collapses the
moment an agent can move the base underneath you.

Pushing is the supervisor's job, not the implementer's — see Phase 5. Then verify your own push actually
happened: "pushed" means "committed" until `git rev-parse <remote-ref>` says otherwise (incidents.md #7).
Run that command yourself after every push; do not trust the push command's own exit status as the signal.

#### Tickets made of repeatable units

N similar units is one plan and N tickets, serial where files overlap — see `references/plan-shape.md`.

When the ticket is N similar units (N services, N packages, N call sites), do not hand one agent all
N — a single oversized batch burns hours on archaeology for one file where a re-briefed batch does three
in the same span (incidents.md #8).

Batch for commit granularity and supervision, not for context — the model holds the whole ticket fine,
and it works best given the complete specification for its batch and then left alone. So each batch brief
carries the full spec for its units and nothing withheld. A batch briefed in fragments is a batch that
stalls on questions the ticket already answered.

- **Unit 1 is a tracer bullet.** Take one unit through every gate, including the aggregate-only ones —
  composed build, parity, boundaries. A pattern that passes unit-local tests and breaks the composed
  build is cheaper to find once than N times. That verified unit is then the canonical reference; name
  it in every later brief, or reviewers infer the pattern from whichever sibling they read first.
- Delegate **2–3 units per run**, and require a **commit per unit** before the next unit starts.
  Otherwise an agent finishes several units, holds them all uncommitted, and one interrupt loses the lot.
- Do the units that force a shared-config decision **last**, once the mechanical pattern is proven on
  the easy ones.
- Reuse the same agent across batches so it keeps the recipe, and state only the delta in each new brief.

#### Tier the gates

Knowing the full gate set does not mean running it per unit. Classify every gate by the smallest scope that
can change its result, and run it only at that tier — re-scanning the whole repo per batch to validate a
few new files catches almost nothing for the cost (incidents.md #9).

| Tier            | What belongs there                                                                                          |
| --------------- | ----------------------------------------------------------------------------------------------------------- |
| Per unit        | that workspace's own type-check, lint, unit tests — the mechanical-error class, in seconds                  |
| Per batch       | the aggregate-only gates whose failures interact: composed build, parity                                    |
| Once at the end | repo-wide scans no single unit can regress: boundaries, formatting, full browser suite, expected-red suites |

The tracer unit is the exception and still gets every gate — that is what makes it a tracer. Batches 2..N do not.

Split gate _ownership_ along the same line: the implementer runs the per-unit tier only, the supervisor owns
the per-batch and end tiers — a long gate handed to an implementer can burn the run in a stall-watchdog
retry loop instead of producing work (incidents.md #10).

#### Verify the report, do not transcribe it

These evidence and gate-ownership rules apply equally to Codex and Claude Code. Use whichever
command output or retained logs the host exposes; do not require a host-specific validator to run
the delivery pipeline.

An implementer's summary alone is a claim, not evidence. Inspect the underlying command output or
retained log, actual test-process exit status, pass/fail/skip counts, and evaluated SHA before accepting
the result (incidents.md #11). A supervisor need not launch the same command to verify that evidence.
Reuse an agent's measured result when those facts are available and the relevant inputs are unchanged.
If evidence is missing or ambiguous, recover it first; rerun only the smallest gate needed to resolve
the gap.

Assign one execution owner to each expensive gate before dispatch. Do not have implementer, tester,
and supervisor each run the same full suite. An already completed qualifying run satisfies that gate;
independent review and targeted regression checks provide separate scrutiny. Record elapsed time for
expensive checks so the next dispatch can avoid duplicating their cost.

Your own commands lie the same way, through the shell rather than through prose. An exit code read
through a pipe is the **last stage's** status, not the command's (incidents.md #12). Read the pass/fail
counts out of the log, or the `EXIT=` line the script itself wrote — never the status the wrapper reports.

Establish your task runner's abort semantics in Phase 1, from its own docs. A runner that stops at the
first failing task reports a total that is a truncation, not a census, so the "N total" in a wide run is
not the size of the gate until you pass whatever flag makes it keep going.

Issue independent gates in one response. Type-check, lint, and unit tests for a batch do not depend on
each other's results, and in coding loops the default drift is one tool call per turn — each extra turn
costs a round trip and a full context read for nothing. Decide what you need next, then request all of it
that has no ordering dependency at once.

Also check the brief was actually obeyed: diff the units it claims to have done against the units you
asked for. An agent told to do one batch may quietly continue through the rest of the ticket. That is
not automatically wrong, but it means nobody supervised the later units, so they need the same
verification the first batch got, not less.

Cut the other way too, before blaming an agent for a diff it could not plausibly have produced: confirm the
SHA you are diffing _from_ is still an ancestor (`git merge-base --is-ancestor`) — a diff crossing an
orphaned fork point can look like agent damage that was never there (incidents.md #13).

### Phase 4 — Review and simplify (parallel, same SHA)

Finish the handoff checkpoint first. Use its committed head as `<review head sha>` in both briefs;
the implementer's returned SHA remains the SHA of its own changes and measured checks.

Call `subagent-reviewer` with this template:

```
Review the diff from base SHA <base sha> to head SHA <review head sha>.

Ticket: <ticket path>
Handoff: <handoff path>
Assignment brief: <path, if used>
Read first: assignment brief if supplied, then ticket status/Notes, Recorded intent,
recent Updates, and handoff findings.
Acceptance criteria: <list>

Run: git diff <base sha> <review head sha>
Read the full diff and surrounding call paths.
Review production code and tests together.
Check error paths, edge cases, and false-green test risk.
Report every issue you find, at every severity. Do NOT pre-filter, and do NOT
withhold a finding for being uncertain — mark it uncertain and report it.
Do NOT edit files.
Do NOT post GitHub comments or touch any PR.
Return findings ranked by severity:
  P0: security, data loss, destructive behavior
  P1: correctness defect or explicit acceptance violation
  P2: valuable improvement, non-blocking
  P3: style or preference
For each finding: file, line, severity, problem, high-level fix.
```

Call `subagent-simplifier` with this template:

```
Audit the diff from base SHA <base sha> to head SHA <review head sha> for simplifications.

Ticket: <ticket path>
Handoff: <handoff path>
Assignment brief: <path, if used>
Read first: assignment brief if supplied, then ticket status/Notes, Recorded intent,
recent Updates, and handoff findings.
Acceptance criteria: <list>

Run: git diff <base sha> <review head sha>
Read the changed files in full plus their call sites. Follow the code; do not guess.

Find surface this diff ADDED that costs more than it buys:
- New public method, export, config knob, event, helper, or type with no consumer outside tests
- Two representations of the same fact introduced by this diff
- Defensive copies, validators, or guards on values a typed same-process caller already guarantees
- Speculative generality: options, hooks, or extension points with no current caller
- Hand-rolled code where a maintained dependency or a runtime builtin already does the job, and the swap deletes the implementation plus its dedicated tests
- Added-then-unused test scaffolding, fixtures, or snapshot entries
- Comments that restate the code, or docs that duplicate a fact owned elsewhere

For each finding classify SCOPE, then SEVERITY.

SCOPE:
  in-diff:      th

…(truncated)
