Deliver
SkillAI & modelsTake a plan all the way to a ready-to-merge pull request — review the plan (scaled to risk), implement it test-first, code-review and fix, run the CI gate, open the PR, and watch it green. Use after you have an approved plan (from plan mode, or the Plan agent); pass `issue <n>` to deliver a specific GitHub issue you name, or `next` to take the top startable issue off the project board's Ready column — either way it re-verifies, claims and plans the issue first. Invoking it with a plan already in hand is itself plan approval — it then runs autonomously to a single hard stop: ready-to-merge.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Deliver skill
What this skill tells your AI
The instructions your AI receives, as published by adamayoung/tmdb in .claude/skills/deliver/SKILL.md and read by ahel’s review.
Drive the current plan through the whole feature pipeline to a PR that is
green and ready to merge. This skill is an orchestrator — it sequences the
existing skills and adds the safety gates; the expertise lives in the pieces
it invokes. It runs autonomously from invocation (which is itself plan
approval) to a single hard stop — ready-to-merge — auto-scaling its
machinery to the change's risk, and writing a short retrospective that
rides the delivery's own PR. Every run happens in its own git worktree
(Phase 1; torn down on merge, Phase 12) so the user's main checkout stays
free. The plan is created first in plan mode (or with the Plan agent;
there is no /plan skill) — /deliver picks up from there. A selection run
supplies its own plan: /deliver next takes the top startable issue off the
project board's Ready column and /deliver issue <n> takes the one you name,
then drafts a plan for it (Phase 0;
references/next-mode.md).
you approve the plan ─▶ /deliver ─────▶ entry gate (ACs?) ─▶ worktree ─▶ [review-plan] ─▶
(or: /deliver next | issue <n> ─▶ select ─▶ re-verify ─▶ claim ─▶ draft ─▶ approve ─┘)
implement ─▶ code-review + fix ─▶ security-review + fix ─▶
rubric check (ACs met?) ─▶ capture ─▶ retro (pre-PR) ─▶ /pr reviewed ─▶ /watch-pr ─▶
GATE: ready-to-merge ─▶ wrap-up (wiki + recurring-pattern scan)
▲ the only hard stop
… then, when the PR actually merges (maybe a later session): teardown (Phase 12)
Detail on demand: procedures, traps, incident history and design rationale
live in references/ — read the named file when its phase
arrives, not up front.
Agent Behaviour Contract
Non-negotiable. Do these by default, without being reminded.
- Invoking
/deliveris plan approval — run autonomously to the one gate (the diagram above), with no second "is the plan ok?" prompt. The only legitimate mid-run pauses: a blocker from/review-plan(Phase 2), a red gate you cannot triage (§4), or — on an attended selection run, under either policy — the one approval stop on a plan/deliverdrafted for itself (Phase 0): invoking the skill approves the plan you brought, and a selection run brought none. Naming the issue yourself settles what to build, not how, so/deliver issue <n>gets that stop exactly as/deliver nextdoes. Inautoit is not a pause at all — thephase0n-selectionpanel rules instead. - Delegate to the existing skills — don't reinvent them:
/review-plan,/implement-plan,/review-changes,/security-review,/capture-knowledge,/pr,/watch-pr,/fix-integration-failures. - Never work on
main— always in a fresh worktree, entered before/review-planor any file edit (CLAUDE.mdforbids editingmain). - A red gate triages before it stops. In-diff failure → fix test-first
and re-run. Pre-existing/unrelated (typically a flaky live integration
test) → route to
/fix-integration-failuresand re-run — never hard-stop on someone else's flake. Only a genuine, in-diff, unfixable break stops the pipeline. - Test-first all the way. Every review-loop fix follows
canon-tdd— failing test first. No untested patches. - Keep two records: a
TaskCreateledger and a run file. The ledger is the live view (one task per phase, statuses current, branch, PR number, weight); the run file is the durable one, because the ledger does not surviveEnterWorktree, an MCP reconnect, or a plan-mode exit. Phase 0 writes it, Phase 1 records the reconcile into it, Phases 4/5/6 each stamp it on convergence (stamps.reviewedClean/securityClean/rubricGraded— that is what makes a resume able to skip a pass already done), and Phase 6 reads the rubric from it — so a skipped step fails loudly at a later phase instead of silently. Every phase that writes is named here, so if a phase you are in is absent, nothing writes on its behalf and you must not assume something else did. (Two non-phase writers exist and are documented where they apply: an async run writes the file before anyScheduleWakeup, and Phase 1's adopt path flipsentrybefore re-locking — seereferences/.) Location and schema:references/worktree-lifecycle.md. Every run-file write afterEnterWorktreegoes throughScripts/deliver-runfile.py— the worktree guard refuses ad-hoc writes to.git/deliver/, sometimes silently — and the script verifies its own postcondition: exit 0 printsverified: …; anything else means the write did not land and is a hard stop for the phase making it. Never carry on assuming state you did not read back — the #493 delivery certified a plan revision to the juror panel that two silent refusals had kept off disk. A template→replicate delivery adds thePhase 4a — reference-unit reviewgate task, which blocks Phase 9. A multi-deliverable plan keeps one ledger sub-tree per deliverable. - Jot knowledge candidates the moment a learning occurs (a lookup, a
gotcha, a live-API surprise, a non-obvious decision) — one line each
(
<category>: <gist> [where]), in the ledger. Mirror the list into the run file (deliverables.<n>.knowledgeCandidates, viadeliver-runfile.py) at Phase 7 entry at the latest — the ledger does not surviveEnterWorktree, and the resume rule restores candidates from the file, so an unmirrored list is one a resumed run silently loses. Phase 7 curates them; reconstruction later loses the best material. - Auto-start after plan-mode approval.
ExitPlanModeapproval IS the start signal — invoke/deliverimmediately; pause first only if Phase 0's entry gate fires.
Invocation — /deliver [auto] [merge] [next | issue <n>]
The four keywords are recognised only as whole, standalone tokens in a
leading run — parsing stops at the first token that is not one of them, and
everything from there on is the named plan target Phase 0 resolves. So
/deliver auto merge next is three keywords, and /deliver auto fix the merge handling plan is one keyword plus the target "fix the merge handling plan" —
not an auto-merge. A keyword found after the target has begun is part of
the target; say so rather than acting on it — nobody notices an auto-merge they
did not ask for until it has happened.
issue takes exactly one operand — the issue number, with an optional
leading #. So /deliver auto issue 480 is two keywords plus an operand.
(issue is a keyword with an operand, not a bare-number selector, so the
leading-run rule never has to distinguish a selector from a plan target whose
first word happens to be a number.)
Four contradictions — report and stop before any board write, worktree or edit, rather than silently picking one:
issue <n>with a named plan targetissue <n>together withnext(two selection policies)- two
issueoperands issuewith no operand, or a non-numeric one
next and a named target contradict each other for the same reason. Either
selector takes precedence over a plan already in the conversation, and says so
before drafting.
Echo the parse before acting on it — one line, first thing, before any board write, worktree or edit:
parsed: auto=on · merge=off · select=issue#480 · target=(none)
select= renders as issue#<n> for an explicit pick, next for the
top-of-run-list policy, or (none) when neither was requested. The echo exists
because no grammar can disambiguate a target whose first token is a keyword
(/deliver merge conflict handling plan) — a mis-parse must become visible in
the second before it matters, not at the moment an unrequested squash-merge
lands. Phase 0 writes the same parse to the run file at the same instant.
auto— unattended; every stop-and-ask becomes a juror panel (below).merge— squash-merge once the PR is green, instead of stopping at the gate (Phase 10).next— no plan needed: requests thetop-of-run-listselection policy, which takes the top startable issue off the board's Ready column and drafts one (Phase 0;references/next-mode.md).issue <n>— no plan needed: requests theexplicitselection policy, which takes the issue you name and drafts one. Same path from there on — re-verify, claim, draft, and release the claim on any stop before the PR opens. Unlikenextit may name an issue in Backlog: choosing it yourself is the triage judgement the Ready test otherwise stands in for.
Both selectors require the user-scoped GitHub Projects MCP — explicit still
has to claim the issue — so both are unavailable on a GitHub Actions
runner.
Auto mode & async invocation
/deliver auto replaces every stop-and-ask decision with an adversarial
panel of three independent Opus jurors — a dead panel is never a proceed,
and every panel convened leaves an audit line in the ledger. Decision points
are marked Auto: below. Never delegated: a data-loss or
breaking-change plan blocker is a hard stop even in auto, and in
auto merge a breaking issue is never merged unattended: under next it is
not selectable at all, and under issue <n> the merge opt-in is dropped
so the PR waits at the gate (references/next-mode.md
§5). /deliver can also be queued headless (the plan + ACs must travel in the
trigger prompt — unless a selection policy supplies them, which only works
where the Projects MCP is mounted). Panel procedure and queuing caveats:
references/auto-and-async.md. In attended
mode the Auto: branches do not apply — stop and ask, as written.
Delivery weight — auto-scale to risk
Judge from the plan; re-confirm from the diff after Phase 3; record in the
ledger. Lite — small, mechanical, single-unit, no risky surface (no
concurrency, networking/HTTPClient, or Decodable/CodingKeys changes; no
new public API beyond a simple additive method; under a few hundred changed
lines) ⇒ skip /review-plan's critics; /review-changes takes its
single-reviewer path. Full — anything risky or large ⇒ the three-critic
/review-plan and the fan-out + adversarial-verify /review-changes.
When unsure, prefer full. The vocabulary is binary — a hybrid run
(e.g. a pre-reviewed plan with the full review machinery) records as full
with the skipped machinery noted, in the ledger and the retro; never invent a
third tier.
One named override exists, and it is not a third tier. An auto selection
run — under either policy — drafted its own plan with no human between the
issue and the implementation, so it always runs /review-plan's critics
whatever the weight (Phase 2). Record that as planReview: forced — auto-<policy> in the run file and the retro, leaving weight itself
untouched; a lite run stays lite for Phases 4 and 5. explicit is covered
too: naming the issue yourself puts a human between you and the issue, not
between anyone and the plan, and it is the plan the critics read. An
attended selection run is not covered: its Phase 0 approval stop is the
same consent ExitPlanMode gives every other run, so it follows weight as
normal.
Multi-deliverable plans — one run, several PRs
A plan that is a program of cohesive deliverables becomes one PR per
deliverable. Decompose in Phase 0 with a dependency graph: dependent
(consumes a type/API/helper/file another introduces or substantially
changes) → sequence it (branch off its dependency, or wait for its merge);
independent → own worktree + branch + PR; unsure → treat as dependent.
Execution is serial implement, concurrent watch: one deliverable at a time
through Phases 1→9, but once its PR is open, start its /watch-pr in the
background and move to the next. The gate reports the batch; each
worktree is torn down as its PR merges; a stuck PR never blocks the others.
The full per-deliverable pipeline applies unchanged. (Genuinely parallel
implementation = separate /deliver sessions.)
Context & isolation (by design)
-
The conductor stays lean (plan reference, ledger, gate, short per-phase summaries); heavy work is already isolated in Workflows/subagents — keep it that way.
-
Implement runs inline — on purpose (the TDD list stays visible). Do not convert it to a silent subagent.
-
The gate stays in the main agent; phases hand off via git / disk / the PR, not context.
-
Separate worktrees get separate
.builddirs. NoSCRATCH_PATHoverride is needed — that flag is only for multiple agents sharing one working directory. -
One Swift process per worktree — at any instant, across every agent. Not "each agent runs its builds sequentially": one build in the whole worktree, full stop. The conductor owns it. Concretely:
- Only the conductor and the
tooling-runnerit spawns may build. Reviewer, security and grader subagents must be told not to build — their prompts say so, and/review-changesand Phase 6 already carry that instruction. - Never run two analysis phases concurrently. Phase 4 and Phase 5 read the same commits and feel independent — but they serialise on disk, not on tokens. Finish one, then start the next.
- Never spawn a
tooling-runnerin the background, and never two at once.
Every target shares one scratch directory, and a
build-docsrun flips theSWIFTCI_DOCCmanifest, which invalidates a concurrent build's plan rather than queueing behind it — the processes then redo each other's work in a cycle (knowledge/gotchas.md→ Docs builds need their own scratch path). - Only the conductor and the
Phase 0 — Preconditions
-
A plan must exist (named target → plan-mode plan → most recent in conversation). None → stop; ask for one in plan mode. Never invent one — except on the one sanctioned path: a selection run selects one instead. Under
top-of-run-list(next) it takes the top startable issue off the board's Ready column; underexplicit(issue <n>) it takes the issue you named, which may sit in Backlog. Either way it then re-verifies againstorigin/main, claims it, and drafts a plan with thePlanagent — and continues through the rest of this phase unchanged. Procedure, exclusions and theselectionblock:references/next-mode.md. Selection is part of Phase 0 rather than a phase of its own so the run file keeps one writer and the knowledge consult below still precedes the drafting that consumes it. Nothing startable, or no Projects MCP → stop before the worktree; never fall through to the "no plan" stop, which reads as an unrelated failure. Write the parsed invocation into the run file when you parse the keywords — before selection runs, not after. Record every keyword, not just this one ("mode": "auto merge next", or"mode": "auto explicit"forissue <n>—nextandexplicitare the two selection-policy tokens, and every gate keys on that rather than on the literal wordnext), plus the raw argument string asinvocation, plusconductorPid— this session's PID. Why the ordering and each field matter:references/worktree-lifecycle.md→ Run state. Auto: the approval stop below becomes thephase0n-selectionpanel — proceed with this self-picked issue and self-drafted plan, vs stop. -
A plan born from a review finding is a hypothesis — verify against the code (quick
Explore) before planning or asking strategy questions. -
State the goal in a sentence; judge the weight; open the ledger.
-
Pull wiki context best-effort (
get_contexton the goal); degrade silently if thewikiMCP is absent. -
Consult the knowledge base — skim the entry headings of
knowledge/gotchas.mdandknowledge/tmdb-api-notes.md, read the entries (and anyknowledge/decisions/ADR) relevant to the goal's area, and record oneconsulted: <entries | none relevant>line in the run file (and the ledger for convenience). Captured knowledge only compounds if it is read at entry, and the line must live where it survives — the ledger alone is not enough, because Phase 1'sEnterWorktreeclears it. Phase 8 copies it into the retro, which is the committed, human-reviewed copy. -
Identify the issue this delivers, and record it. Record
issue: <number>on the deliverable in the run file (orissue: nullwhen the work is genuinely untracked). Per-deliverable, not run-scoped: a multi-deliverable plan can close a different issue per PR, or none. Phase 1 moves it to In progress and Phase 10 to In review, so an unrecorded issue is one the board silently never reflects. A selection run has already made the In progress move itself, at the pick (Phase 1's move then finds it set and no-ops), and its claim carries an obligation: any stop before the PR opens releases it back toselection.claimedFrom— the column it was claimed from (references/next-mode.md§6). -
Flag a reflexive delivery. If the plan touches any of the reflexive set —
.claude/skills/**,.claude/agents/**,.claude/workflows/**,.claude/docs/**or.github/CODE_REVIEW.md— this run is rewriting the machinery that runs it. Recordreflexive: truein the run file. When in doubt about a path, resolve it as reflexive — a false positive costs one human merge; a false negative is the pipeline silently editing its own gates.This list is the reflexive set, and it is quoted in two other places —
references/next-mode.md§5b, which refuses such an issue inmergemode, andreferences/worktree-lifecycle.md's run-file schema. Change all three or none —Scripts/tests/test_deliver_selection_prose.pyasserts they agree, because a prose cross-reference alone did not survive one delivery (the drift history lives with the schema).Then read
references/reflexive.mdnow and hold its four consequences for the rest of the pipeline: no dogfooding before merge, verification pinned to the original text, the whole-footprint sweep (re-swept after every review-loop fix), and Phases 4/5 running even on a markdown diff. -
Decompose a multi-deliverable plan (rules above); single-deliverable plans skip this.
-
Entry gate — a gradeable rubric required. Plans are expected as "As a <user-type> I want <feature> so that <reason>" + acceptance criteria. Extract the ACs verbatim as the delivery rubric (consumed in Phase 6) into the run file (and the ledger for convenience), and record
rubricProvenance: supplied. Three cases, and only the last one stops:- ACs supplied → the above.
- ACs absent but derivable — the plan has a definition of done in the
wrong shape rather than none at all: a linked issue stating observable
before/after behaviour, or an explicit
canon-tddtest list. Derive the ACs into "Given X, when Y, then Z" form, recordrubricProvenance: derived — <the source>, and say in the PR body that the rubric was derived. Bug fixes land here routinely; stopping to ask a question the plan already answers is ceremony, not rigour. A selection-run-drafted plan always lands here, under either policy: recordderived — issue <number>, neversupplied—suppliedmeans a human set the bar, and here the run that gets graded wrote its own rubric. Do not "simplify" it back. - Neither → stop and ask for them ("Given X, when Y, then Z") — don't
enter the worktree. Auto: panel — proceed rubric-less (Phase 6 no-ops)
vs stop; record that as
rubric: none, which is present-and-empty, not a missing file.
Reject a knowledge-shaped AC — it cannot pass. An AC whose evidence is a
knowledge/artifact ("an ADR records X", "a gotcha is captured") is guaranteed to fail its first grading, because Phase 7 writes that artifact after Phase 6 grades — deliberately, so capture observes the delivery's final state. Drop such an AC from the rubric when extracting it (the work still happens, enforced by Phase 7's own contract), say which ACs you dropped and why, and when deriving, don't write one in the first place.Derive to grade yourself honestly, not to pass: write the ACs from the source's own words before implementing, never after, and never soften one because the implementation went another way. Provenance makes a derived rubric auditable; Phase 6's independent grader is what stops a self-serving one.
-
Read the plan's content into context now —
EnterWorktreeswitches CWD (clearing the plans cache), and a fresh worktree lacks uncommitted local files; the plan must travel in the conversation.
Phase 1 — Reconcile prior runs, then enter an isolated worktree
Procedures and traps:
references/worktree-lifecycle.md.
- Reconcile before
EnterWorktree(the run file already exists — Phase 0 wrote it; record the sweep into it, never mint a second one). Enumerate withgit worktree list --porcelain(neverls .claude/worktrees/), scoped to<main-root>/.claude/worktrees/, and classify every one first-match-wins:live(lock PID alive — never touch) /report/reclaim(merged and Phase 12's two proofs) /resumable/settled. Report, never remove, anything that doesn't prove reclaimable, and verify a directory is gone before counting it reclaimed. Recordreconciled:in the ledger, thereconciledblock in the run file, and the retro (Phase 8) — never asswept:, which is Phase 7's knowledge sweep and will silently take the slot.
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 176
- Forks
- 47
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
deliver- Source
- github.com/adamayoung/tmdb