Superpipeline
Overview
pipeline drives a feature from idea to a finished branch by composing
existing superpowers skills — it never reimplements brainstorming, planning,
or review. It calls those skills and manages the seams between them, plus an
autonomous per-phase implement → review → recursive-fix loop.
The one exception is implementation dispatch, which this skill owns
(references/implement.md). Every available implementation skill accepts a
task only against a review it dispatches for that task, which is a second
acceptance gate for work this skill accepts at the phase — so composing one
reviewed every phase twice. Owning the dispatch is what makes the invariant
mechanical: completing a task dispatches no reviewer.
Core principle: compose, don't reimplement. Every stage delegates to the canonical skill for that job. This skill's only original logic is the orchestration: the zero-assumption rule, the on-disk run state, the gates, the reviewer fan-out math, and the fix loop.
Reference files — read at the stage that needs them:
references/run-state.md (file formats, task-line grammar, cold-start resume,
dispatch contract), references/implement.md (Stage 4's IMPLEMENT state: how a
phase's tasks are dispatched, waved and merged, and why completing one
dispatches no reviewer), references/fix-loop.md (Stage 4's loop and guard
rails) and references/parallel.md (Rule 6: dependency annotations, waves,
lanes, worktrees and merges, and the Brain-Agent mode).
templates/ holds the run-state file templates.
Invocation
Dispatch on the argument below, before doing anything else. An empty argument means Full mode. Ignore any whitespace around the argument.
$ARGUMENTS
That is the whole argument string. Never key this table on an indexed
placeholder. \$0 is the first positional argument and it does get substituted —
but an indexed placeholder with no argument at its position is left in the prompt
verbatim, so a bare invocation renders a stray literal \$0 into exactly the arm
this table calls "no argument". \$ARGUMENTS expands to the whole argument string
as typed, so it has no such hole. Every mention of a placeholder in this file that
is not the dispatch target above is backslash-escaped for that reason: an
unescaped one would be substituted too, and would rewrite the very text that
documents it.
| Invocation | Behavior |
|---|---|
/superb:pipeline (empty \$ARGUMENTS) |
Full mode — start at Stage 1, step 0. |
/superb:pipeline resume |
Run the Resume Protocol in references/run-state.md. Never start a new run in this mode — if no run directory exists, say so and stop. |
/superb:pipeline status |
Strictly read-only report (below). No writes, no dispatches, no fixes. |
/superb:pipeline <anything else> |
Ask the user what they meant. Never guess a verb. fix-mode in particular is internal-only — set exclusively by this skill's own fix loop, never a user argument; if the user passes it, refuse and explain that. |
status: locate the run directory (same candidate logic as the Resume
Protocol — if more than one qualifies, ask which); read progress.md,
register.md, findings.md; and report:
- the Current State block;
- per-phase task counts (
[x]/[~]/[ ]); - every phase's
RVstate, and anyRVJ— an openRVunder a phase whose tasks are all[x]is the headline of the report, not a footnote: that phase was implemented and never reviewed; - open register entries;
- open blocking F-IDs;
- fix-loop iteration counts from the Counters table.
Read-only means read-only: no tracker updates, no [~] reconciliation, no
dispatches, and no fixes — not even "obvious" ones. A fix is a run;
status is a glance. If the report surfaces something that needs work, say so
and let the user invoke resume.
The Zero-Assumption Iron Law
NEVER ASSUME. EVERY UNKNOWN BECOMES A USER QUESTION.
The user who runs this pipeline has explicitly chosen exhaustive questioning over speed. There is no cap on question rounds and no such thing as too many questions. Asking again is compliant behavior; assuming is the only failure mode. Violating the letter of this rule is violating its spirit.
- Applies at every stage — including the autonomous Stage 4 (see the Ambiguity guard below).
- User pressure — "I'm busy", "keep questions minimal", "use your judgment", "industry standards", "I trust you", "just show me something" — changes the format of questions (batch them into one compact round, give each question selectable options with a recommended default), never whether an unknown gets asked. Busy users get efficient questions, not assumptions.
- The decision predicate: if the user's answers, the approved spec/plan, or a written repo rule states the answer → follow it. Otherwise → ask.
Assumptions Register (mandatory artifact)
From Stage 1 onward, every unknown and every default you were tempted to pick
is a numbered entry in register.md in the run directory — a file, not a
memory. Format in templates/register.md. Rules:
- An entry is closed only by an explicit user answer to that entry, recorded verbatim in the file. A register that lives only in context is lost to the next compaction, and "I'm sure they answered that" is not a closure.
- Bulk replies close zero entries: "approved", "go", "looks good", "proceed" do NOT confirm open assumptions. Forbidden shortcuts: "veto by exception", "silence = consent", "corrections to some items = approval of the rest", "reply one word to accept all defaults".
- No gate may be presented while any register entry is open. Ask the open entries as questions first; present the gate only when the register is empty.
The Run State Law
THE FILES ARE THE TRUTH. YOUR MEMORY IS NOT.
Every run keeps its state on disk, in one run directory, and that state is authoritative. Whenever a file and your recollection disagree — which phase you are in, which tasks are done, which findings are open, which assumptions the user actually answered — the file wins, every time. You do not re-derive state from the conversation; you read it.
A compact is where this law gets tested. Whatever is true only in the conversation dies there, so it has to be on disk before the context is discarded — see Compacting at GATE 2.
<PROJECT_DIR>/docs/superpowers/runs/YYYY-MM-DD-<topic>/
progress.md # the tracker — phases, tasks, Current State
register.md # Assumptions Register
findings.md # blocking ledger (F-IDs), iteration history, deferred Minors
kit.md # the run's shared verification apparatus (written at GATE 2)
agent-output/ # one file per dispatch; long subagent output lands here
Formats, task-line grammar, the resume procedure and the dispatch contract
are in references/run-state.md. Read it at Stage 1 step 0. Templates for
the templates ship in templates/ and are read-only — copy them, never
edit them.
Run state NEVER goes in the skill directory. A skill directory is shared across every project and every run; state written there corrupts the next run and leaks one project's work into another. If the path you are about to write to is inside a skill directory, or is not under
docs/superpowers/runs/<this run>/, stop — you have the wrong path.One run directory, created at Stage 1, its full path stated to the user in your first message and reused verbatim for the rest of the run. Fix-mode recursions inherit it and never create their own.
If the directory already exists, that is a user question — resume, start fresh, or abort — never a silent overwrite and never a silent resume. Show the user the existing Current State so the choice is informed.
Never
git adda pipeline runtime directory — anything underdocs/superpowers/runs/*/.progress.md,register.md,kit.md,findings.md, fix plans,agent-output/, review reports: that is ephemeral execution state, it belongs on disk for the run and for a resume. This repository's root.gitignorecarriesdocs/superpowers/runs/*/and a gate holds it there; in a project without that line the rule is yours to keep, and adding the line is the first thing to do. Curated permanent documentation may be deliberately committed —docs/superpowers/specs/*.md,docs/superpowers/plans/*.md, and loosedocs/superpowers/runs/*.mdrecords — when someone decides it is repository documentation. May is the whole of the permission: nothing auto-commits it.runtime directory = forbidden curated permanent document = intentional, deliberate exceptionPlan around the consequence for the runtime half: none of it survives a fresh clone or a lost machine. What has to outlive the run goes into durable artifacts — the commits themselves, and the Stage 5 hand-off (which is why Stage 5 carries the design summary and the deferred-Minors table rather than pointing at these files).
"Phase" below means both levels: the pipeline Stages 1–5, and each implementation phase of the expanded plan inside Stage 4. Every rule applies at both.
Tracker structure (fixed)
# Pipeline — Progress Tracker
## Current State
- **Lane A:** <phase id FIRST, then that lane's next unchecked line — task, RV,
or RVJ>
- **Last updated:** <timestamp>
- **Run directory:** <path>
## Phase 1 — <name> · deps: none · lane: A
- [x] T1 — <task name> · W1 · deps none — `a1b2c3d`
- [~] T2 — <task name> · W2 · deps T1 — started <timestamp> in `wt/p1-t2`
- [~] T3 — <task name> · W2 · deps T1 — started <timestamp> in `wt/p1-t3`
- [ ] T4 — <task name> · W3 · deps T2, T3
- [ ] RV — review fan-out
...
Every task line carries its wave (W<n>) and its deps (Rule 6); every
phase heading carries the phases it depends on (· deps:) and the lane that
executes it (· lane:). Tasks in the same wave may be
[~] at the same time — one of two sanctioned cases of more than one [~]
line (the other is concurrent lanes, each of which may hold its own [~] task
or RV), and each still gets its own write before its own dispatch.
The RV line — review is a tracker line, not a memory
Every implementation phase ends with an RV line, written in at GATE 2 with
its task lines. (Only implementation phases — the Stages 1–5 seeded at Stage 1
are scaffolding and carry none.) It obeys Rule 2's write-before-work and Rule 4's
reconciliation, carries no W<n>/deps, and is not a task: it never counts
toward Rule 3's 12-task cap nor toward N in ceil(N/5).
- [ ] RV — review fan-out
- [~] RV — review fan-out · N=8 → 2 slice + 1 integration · started 2026-09-01 14:31
- [x] RV — review fan-out · N=8 → 2 slice + 1 integration · boundary: the T3 contract consumed by T7
· reports p3-review-{a,b,int}.md · coverage p3-coverage.md → F-012, F-013
- [x] RV — review fan-out · N=8 → 2 slice + 0 integration · no integration boundary
· reports p5-review-{a,b}.md · coverage p5-coverage.md → no findings
The [ ] form carries nothing else: at GATE 2 no task has a hash, and the
slice count is not yet written even though ceil(N/5) already determines it.
Both are filled in at dispatch.
Closing it takes artifacts, not adjectives — these fields, each checkable by
someone who was not there, all paths relative to agent-output/:
| Field | What it must satisfy |
|---|---|
N=<tasks> → <s> slice + <i> integration |
Which number s must match depends on the regime, and the declaration's own key says which — the regimes are the table below. Whichever one sized it, i is 0 at one slice — that slice already sees the whole diff, so a second reviewer over it is duplication a boundary cannot license. Above one slice i is 1 only at a declared integration boundary, named on the round as · boundary: <what>: a Rule 3 split's siblings joining, two lanes joining, or a contract introduced in one slice and consumed in another that no single slice's range covers. Otherwise i is 0 and the round says so (· no integration boundary) — an omission and a judgement read identically, and that is how a review goes missing without anyone deciding to skip it. |
fixplan <file> |
Fix rounds only: required on a round declaring M=<m> with m >= 1, absent from an M=0 → no round record. The round's fix plan (templates/fix-plan.md), written before the first fix was dispatched — findings → fix plan → fix implementation, in that order. A round that fixed something and names no plan is a round whose fixes nobody can check against a scope. |
coverage <file> |
One file holding the slice assignment table above the git log --oneline PB..PH, and ending with the verdict line COVERED: <n>/<n> commits. All three: a bare log is the input to a coverage judgement rather than the judgement, and a table with a gap in it sits above the log just as happily as one without. Anything short of <n>/<n> does not close the line. The table's own shape is fixed, below the regimes. |
→ <F-IDs> or → no findings |
What the round produced. |
Which regime sized the round — and whether the line proves it. Every N=
row is re-derivable from the line; the others say so rather than borrowing that
guarantee.
| Key on the line | s is |
Re-derivable from the line? |
|---|---|---|
N=<n> |
ceil(N/5) |
Yes. That is what N is on the line for: the fan-out is re-derivable at closure instead of trusted from the step that gets skipped. |
N=<n> W=<w> |
ceil(N/5) — unchanged, because W is informational |
Yes. W records how many implementation waves ran, for history; it never enters the arithmetic. Implementation scheduling must not reduce formal review coverage. |
M=<m> C=<c> |
c, the file clusters in the fix diff |
As a declaration only. C makes the sizing auditable and an arithmetic slip between the two numbers red, without establishing the count itself. M sizes nothing. |
RVJ |
always 0 slice + 1 integration, its N informational |
Yes, from the form. |
What a re-review round's fan-out is checkable against is its own coverage
table, where two reviewers over one cluster show up as two rows carrying the
same range.
The coverage table's shape is fixed, because the round's own arithmetic is read off it and a later reader re-runs it: every row is keyed by its report filename, with that reviewer's exact range in the row's second cell, and every report file the round names has a row of its own — a reviewer with no row has no recorded range for anyone to check any other against. And no two rows carry the same range: two reviewers over one range read the same diff, and the integration reviewer's row is the union of the slices, so it equals no single slice's.
The line's shape is machine-checkable, and only its shape. The superb
plugin's own repository ships a linter for this grammar: from a checkout of
that repo, ./tools/check-plugin.sh --run <run-directory> reads the tracker's
closed RV/RVJ rounds and names any whose declared count and listed report
files disagree, whose N= slice count is not ceil(N/5), whose
integration count does not follow its slice count, whose RVJ is not
0 slice + 1 integration, whose M= declares no C=<n> or a C its slice
count contradicts, whose coverage field is absent, whose named report or
coverage files are not in agent-output/, whose coverage table (on a round of
two or more slices) leaves a named report without a row or gives two reviewers
the same range, or whose M=0 → no round record carries reviewer evidence.
It is not in a project's own tree unless that project is the plugin, so it is
a check a run can use, not a gate every run passes — Stage 5 is what runs it,
and says in the hand-off what came back.
On an M= re-review round it still cannot check that the fan-out was
sized right, and half of that will never be checkable from the tracker: the
duplication half is caught, since two reviewers handed one range are two rows
the linter can compare, but the count itself is not derivable from the line
there — C is on it as a declaration by whoever chose s, so one reviewer over a seven-cluster diff writes C=1 and
passes.
Every field is per round, and re-review rounds append their own. The counts are read against the round they sit in, never against the whole line:
→ round 2: M=9 C=1 → 1 slice + 0 integration · fixplan p3-fixplan-r2.md
· reports p3-rr2-a.md · coverage p3-rr2-coverage.md
→ F-012 closed, F-014 raised
The fan-out is one reviewer per file cluster in the fix diff, integration
only above one reviewer — not ceil(N/5), since fix diffs are not task-shaped,
and not a count over the findings, since findings are not diff surface — with
coverage over the fix commits. Whoever ran the round writes it, at whatever
recursion depth.
M=0 → no round is the one round that closes without reviewers. M — the
targeted-F-ID count, less every one closed by a route that leaves no ownable
commit — is defined once, with the closed list of those routes, in
references/fix-loop.md, fix loop step 3. Read it there; a second copy of a
closed list here is a copy that can drift into being a shorter one. A fix
iteration whose M comes out zero runs no fan-out — and it still writes its
round, because an absent round and a skipped one are the same absence here:
→ round 4: M=0 → no round · closures: F-021 withdrawn → malformed,
F-022 withdrawn → superseded by F-013 → no findings
no round stands where the reviewer counts would, and M=0 is the only
declaration that licenses it. In place of reports and coverage the round
carries each F-ID it closed and that F-ID's route, taken from the closed list
in references/fix-loop.md, fix loop step 3, and matching that F-ID's
Closed by cell in the ledger. pinned by <test> cannot appear here: a pin
commits a test, so it stays in M and its commit is owed a reviewer.
One behavioural fix, or one pin, in the same iteration makes M > 0, and then
the full fan-out is owed.
The one other closure: [x] RV — WAIVED by user: "<their words>", which needs
those words verbatim in register.md, applies only to the phases the user named
(if that is unclear it is an Ambiguity stop, not a guess), and is listed in the
Stage 5 hand-off. To un-waive, set it back to [ ].
A phase whose RV is not [x] is not complete, however many of its tasks
are.
RVJ — the joint review of a designed unit. A Rule 3 split, and a phase whose
deps span two or more lanes, each owe a review no single phase's RV can cover.
Same grammar and closure rules. It is always 0 slice + 1 integration — one
reviewer, seeing the unit whole — with N = the tasks across that unit, and a
discriminator naming the phases whose combined diff was reviewed, since one
phase can owe two and "lanes A+B" is not something a third party can check:
- [ ] RVJ — joint integration review · split 4a+4b
- [x] RVJ — joint integration review · lanes A+B (phases 5, 6) · N=17 → 0 slice + 1 integration
· reports j-56-int.md · coverage j-56-coverage.md → no findings
It gets its own Counters row, its own appended fix rounds, and it sits where
it must be satisfied: after a split's last sibling (a trailing RVJ), above
the first task of a joining phase (a leading RVJ). Full procedure in
references/fix-loop.md.
Closing a gate is not accepting a phase. Call the gate a fix loop belongs to
its review_gate — an RV for a phase's own review, an RVJ for a split's
or a lane join's. The loop is the same whichever it is:
review_gate → findings → FIX_PLAN → FIX_IMPLEMENT → RE_REVIEW(review_gate)
→ clean → CLOSE(review_gate)
CLOSE(review_gate) is the generic terminal. PASS is phase acceptance, and
only a phase's own RV produces it — so what a closure unlocks depends on which
gate closed:
CLOSE(RV) → phase PASS
CLOSE(trailing RVJ) → NEXT PHASE
CLOSE(leading RVJ) → IMPLEMENT JOINING PHASE
A CLEAN LEADING RVJ MUST NEVER MARK THE JOINING PHASE PASS.
A leading RVJ gates entry: it reviews the lanes that merged into this
phase, not this phase's own tasks, so after it closes the joining phase still
owes the whole of IMPLEMENT → RV → CLOSE(RV) → PASS, and the non-surviving
contributing lanes retire. A trailing RVJ closes a Rule 3 split and the
run advances past it. An RVJ is not a phase gate and never stands in for one.
A round is appended under its own gate's line. An RVJ-owned round is
ordinary — an M= C= fix round sized from the fix diff — and it hangs under the
RVJ, never under a joining phase's RV:
- [x] RVJ — joint integration review · split 4a+4b · N=17 → 0 slice + 1 integration
· reports j-4ab-int.md · coverage j-4ab-coverage.md → F-031
→ round 2: M=1 C=1 → 1 slice + 0 integration · fixplan j-4ab-fixplan-r2.md
· reports j-4ab-rr2-a.md · coverage j-4ab-rr2-coverage.md → F-031 closed
The Current State block stays at the very top so re-orienting costs one
read and nothing else. Never move it below the phase lists, never split it,
never let a lane point at a line that isn't the first unfinished one of its own
phases — or, when that lane has none, at one of the two phase-less forms done
and waiting at join Phase <id> (templates/progress.md). Timestamps
come from a real clock (date), never from your sense of elapsed time.
A lane line names the next unchecked line of that lane's phase, and an open
RV is such a line. When the last task of a phase lands, the lane's next
action is that phase's RV — never the next phase's first task. Writing the
next phase there while RV is open makes the tracker itself instruct the run
to skip review, and the tracker is the thing every rule here tells you to obey.
A lane may only name a phase its own · lane: carries, and a sequential
run has exactly one lane, Lane A.
[ ] not started · [~] started, outcome unknown · [x] done, followed by
the commit hash carrying it (or `nocommit` plus a one-line reason — never
a blank). RV/RVJ are the exception: they produced review, not code, and
close on reviewer evidence instead of a hash — see below.
Rule 1 — Read-write bookend at every phase boundary
- Before starting ANY phase: read
progress.mdin full, first — before dispatching an agent, opening a plan doc, reading source, or writing code. It is the phase's first tool call, not something you get to after "just checking one thing". - Before marking ANY phase complete: update and save the tracker first —
every task in that phase checked off with its hash, Current State
pointing at the next unchecked line — which for a joining phase is its
RVJ, sitting above that phase's first task — and this phase'sRV(and anyRVJ)[x]. A phase is complete when the file says so, not when you believe the work is done. No phase may be declared complete, and no next phase may begin, until that write is on disk.
Rule 2 — Per-task updates, not per-phase
Around each individual task, in this order:
- Before the work starts: mark the task
[~]with a timestamp. Save. - Do the task.
- On completion: mark it
[x]with the commit hash. - Update the Current State block (this lane's
**Lane <id>:**line, timestamp). - Save.
- Re-read the file and take the next unstarted line from it — which, after
a phase's last task, is that phase's
RV(then anyRVJ), not the next phase.
You never run on memory across two tasks. Re-orient from the file after
every single one. In a parallel wave (Rule 6) the same six steps run per
member: each member's [~] is written before its dispatch, each member's
[x] + hash is written as it lands — never one write for the wave.
Batching the updates — "I'll tick off the whole phase at the end", "I'll update once this agent batch returns" — is the exact failure this law exists to prevent. Step 1 is not optional bookkeeping: it is the only thing that distinguishes "never started" from "died halfway" after a crash.
Rule 3 — Twelve-task cap per phase
During Stage 3 (plan expansion), no phase may contain more than 12
tasks. A phase whose expansion yields 13+ tasks MUST be split into
sub-phases (4a, 4b, …), each ≤ 12 tasks, before any implementation
begins. Splitting after implementation starts does not satisfy this rule,
and neither does "12 tasks, some with sub-steps" — sub-steps that are
separately checkable are tasks. The split is part of the plan the user
approves at GATE 2, so it happens before the gate, not after it.
The RV and RVJ lines are not tasks and never count toward the 12.
A split phase is still one designed unit: after its last sibling passes, it gets a joint integration review over the siblings' combined diff before the run advances (see Reviewer fan-out).
Rule 4 — Verify [~] tasks before doing anything else
On any cold start — new session, context compaction, resumed run, or your
own uncertainty about what just happened — read progress.md, findings.md
and register.md, then reconcile every [~] task against the actual code
(git state + the tests covering it) before taking any other action. Fully
applied → [x] with its hash. Partially applied → revert or deliberately
complete it, and if which one is correct isn't obvious from the plan, that is
an Ambiguity-guard stop. Nothing applied → back to [ ].
A [~] task is never assumed done because it looks done, and never assumed
untouched because you don't remember it. Full procedure in
references/run-state.md.
A [~] RV/RVJ reconciles against agent-output/, not against the code:
the expected number of reviewer reports present and consolidated into
findings.md → [x] with its evidence; present but never consolidated →
consolidate them now; missing or short of the declared count → back to [ ] and
run the fan-out. Never resolve one by re-reading the diff yourself — that would
make you the reviewer, which is what the line records someone else being.
Rule 5 — Hold pointers, not payloads
Context bloat is the other half of drift. Every dispatched subagent returns
≤ ~10 structured lines (task ID, status, commit, files, tests, ≤2 lines of
notes, and a DETAIL: path). Anything longer — diffs, full /review reports,
test logs — the subagent writes to agent-output/<label>.md and returns the
path. Put that instruction in every dispatch prompt.
The orchestrator reads a detail file only when a decision depends on it,
and then reads the file rather than a remembered version. Full reviewer reports
never enter orchestrator context wholesale; the consolidated list in
findings.md is what the run reasons over. Contract in
references/run-state.md.
Rule 5b — Derive, don't restate
A brief, a plan or a comment states the source of a code fact — the symbol it lives on, or the command that regenerates it — and never a count, a line number, a signature or a file list. No method or field named as already existing, no type, no "the four reachable states".
A task's Files: block is the exception, at both ends (Rule 6): writing it
into a plan — and into a task brief cut from one — is required, and receiving it
is not grounds for the refusal below. references/parallel.md says why no
derivation can stand in for those paths. Nothing else about a task's code
travels with a brief.
The reason is mechanical: a restated fact is correct at the moment it is written and at no moment after. The orchestrator writes briefs from a tree that moves under them, so a restated fact is wrong at a rate the run cannot absorb — and because the agent receiving it treats the brief as authority, the error is only caught when that agent happens to look. In testing every such error was caught, by the agent, after it had already shaped the work.
- Writing a brief: name the symbol, not the file and line it currently sits at. Give the command that finds the call sites, not the number of them you counted.
- Receiving a brief: a brief that states a code fact is refused — send it back rather than reconciling it. You cannot tell a stale fact from a current one without deriving it, and if you are deriving it the brief's copy was worthless.
- Writing a comment: anchor to a symbol or delete the claim. A comment that
asserts a re-derivable fact is a claim finding waiting to happen — see the
closure rule in
references/fix-loop.md.
This rule binds this skill's own prose. Where these documents once counted their
own templates, they name templates/ instead: the count was true right up to
the commit that added a file to that directory, which is the same failure one
level down.
Rule 6 — Dependency waves: parallel where the plan proves it is safe
Sequential-by-default is the fallback, not the design. At Stage 3 every task is
annotated with Depends on: (task IDs it consumes) and Files: (what
it creates or modifies), and every phase with the phases it depends on. From
those the orchestrator computes waves inside a phase and lanes across
phases, before GATE 2, and the user approves them as part of the plan:
- Two tasks share a wave iff neither depends on the other (transitively)
and their
Files:sets are disjoint. Otherwise the later one waits. - Wave
kdispatches only when every task of wavek-1is[x]and merged into the phase branch with the build gates green. - A wave of one runs as today. A wave of two or more dispatches all members at once, each implementer in its own git worktree and branch cut from the phase branch head; members land independently and are merged back in task order once all of them have landed and the build gates are green. No member is reviewed before its merge.
- Phases with no dependency between them run as concurrent lanes, each an independent instance of the per-phase loop with its own Counters row.
- Missing or vague annotations are not a licence to guess — a task with no
Depends on:/Files:goes back to its expansion agent. A merge conflict inside a wave means the annotations were wrong: abort the merge, re-open the conflicting task, redo it sequentially on the merged head.
Full procedure — annotation grammar, wave computation, worktree naming, the
merge step, lane close-out — in references/parallel.md.
Brain-Agent mode (user-declared, recorded, never assumed)
The default pipeline asks the user every unknown. The user may instead
declare, in their own words, that questions go to a Brain Agent — a
dedicated subagent per question, given the full context, whose ruling closes
the register entry. That mode is on only when the user's declaring message is
copied verbatim into register.md under an "Operating mode" heading with its
date. No verbatim record → normal mode, no matter what you remember being told
(a previous run stalled for exactly this: a tracker claimed brain-agent gates,
the register had no such note, and the user had to be asked on resume).
Rules of the mode are in references/parallel.md.
When to Use
- User wants a feature carried from idea all the way to a finished branch in one mostly-autonomous run.
- User says "run the whole pipeline", "take this end to end", "implement all phases", "don't stop between phases".
When NOT to use: a single bug fix (use superb:bug-fix), a one-off change, or when
the user wants to stay hands-on at every step (run the individual skills
directly).
Two operating modes
- Full mode (default): starts at Stage 1 (interactive brainstorm).
- Fix-mode (set only by this skill's own fix loop, never by the user):
skips Stage 1 entirely, treats a set of review findings as the spec, and
writes no new top-level spec. The Ambiguity guard still applies at every
depth. See
references/fix-loop.md.
Stage flow
digraph pipeline {
"Stage 1: brainstorm question rounds (until register empty)" [shape=box];
"Stage 1b: 2-agent pressure-test (gaps -> new questions)" [shape=box];
"GATE 1: approve design (register must be empty)" [shape=diamond];
"Stage 2: master plan (writing-plans)" [shape=box];
"Stage 3: expand each phase (1 agent/phase, each runs writing-plans, annotates deps+files)" [shape=box];
"Stage 3a: split any phase over 12 tasks; compute waves and lanes (Rule 6)" [shape=box];
"GATE 2: approve expanded plan (register must be empty)" [shape=diamond];
"Stage 4 IMPLEMENT: every task in the phase, waves of tasks (ambiguity -> ask)" [shape=box];
"Stage 4 REVIEW: RV fan-out over the whole phase diff (all reviewers return first)" [shape=box];
"Stage 4 DECIDE: consolidate, dedup, F-IDs, tiers" [shape=diamond];
"Stage 4 FIX_PLAN: one scoped fix plan for this round's blocking findings" [shape=box];
"Stage 4 FIX_IMPLEMENT: fix agents, one per file cluster" [shape=box];
"Stage 4 RE_REVIEW: sized from the fix diff (C=<n>)" [shape=box];
"CLOSE(review_gate): the gate that raised the findings goes [x]" [shape=diamond];
"Stage 4 PASS: RV [x], close-out written and saved" [shape=box];
"Stage 4b: joint integration review over a split's combined diff" [shape=box];
"Stage 5: finishing-a-development-branch" [shape=doublecircle];
"Stage 1: brainstorm question rounds (until register empty)" -> "Stage 1b: 2-agent pressure-test (gaps -> new questions)";
"Stage 1b: 2-agent pressure-test (gaps -> new questions)" -> "Stage 1: brainstorm question rounds (until register empty)" [label="new unknowns"];
"Stage 1b: 2-agent pressure-test (gaps -> new questions)" -> "GATE 1: approve design (register must be empty)" [label="register empty"];
"GATE 1: approve design (register must be empty)" -> "Stage 1: brainstorm question rounds (until register empty)" [label="revise"];
"GATE 1: approve design (register must be empty)" -> "Stage 2: master plan (writing-plans)" [label="approved"];
"Stage 2: master plan (writing-plans)" -> "Stage 3: expand each phase (1 agent/phase, each runs writing-plans, annotates deps+files)";
"Stage 3: expand each phase (1 agent/phase, each runs writing-plans, annotates deps+files)" -> "Stage 3a: split any phase over 12 tasks; compute waves and lanes (Rule 6)";
"Stage 3a: split any phase over 12 tasks; compute waves and lanes (Rule 6)" -> "GATE 2: approve expanded plan (register must be empty)";
"GATE 2: approve expanded plan (register must be empty)" -> "Stage 4 IMPLEMENT: every task in the phase, waves of tasks (ambiguity -> ask)" [label="approved"];
"Stage 4 IMPLEMENT: every task in the phase, waves of tasks (ambiguity -> ask)" -> "Stage 4 REVIEW: RV fan-out over the whole phase diff (all reviewers return first)" [label="every task [x] + gates green"];
"Stage 4 REVIEW: RV fan-out over the whole phase diff (all reviewers return first)" -> "Stage 4 DECIDE: consolidate, dedup, F-IDs, tiers";
"Stage 4 DECIDE: consolidate, dedup, F-IDs, tiers" -> "CLOSE(review_gate): the gate that raised the findings goes [x]" [label="no blocking findings"];
"Stage 4 DECIDE: consolidate, dedup, F-IDs, tiers" -> "Stage 4 FIX_PLAN: one scoped fix plan for this round's blocking findings" [label="blocking findings"];
"Stage 4 FIX_PLAN: one scoped fix plan for this round's blocking findings" -> "Stage 4 FIX_IMPLEMENT: fix agents, one per file cluster";
"Stage 4 FIX_IMPLEMENT: fix agents, one per file cluster" -> "Stage 4 RE_REVIEW: sized from the fix diff (C=<n>)";
"Stage 4 RE_REVIEW: sized from the fix diff (C=<n>)" -> "Stage 4 FIX_PLAN: one scoped fix plan for this round's blocking findings" [label="blocking findings remain"];
"Stage 4 RE_REVIEW: sized from the fix diff (C=<n>)" -> "CLOSE(review_gate): the gate that raised the findings goes [x]" [label="clean"];
"CLOSE(review_gate): the gate that raised the findings goes [x]" -> "Stage 4 PASS: RV [x], close-out written and saved" [label="the gate was this phase's RV"];
"CLOSE(review_gate): the gate that raised the findings goes [x]" -> "Stage 4 IMPLEMENT: every task in the phase, waves of tasks (ambiguity -> ask)" [label="the gate was a LEADING RVJ: the joining phase now STARTS, it does not PASS"];
"CLOSE(review_gate): the gate that raised the findings goes [x]" -> "Stage 4 IMPLEMENT: every task in the phase, waves of tasks (ambiguity -> ask)" [label="the gate was a TRAILING RVJ: next phase"];
"Stage 4 PASS: RV [x], close-out written and saved" -> "Stage 4b: joint integration review over a split's combined diff" [label="last sibling of a split"];
"Stage 4b: joint integration review over a split's combined diff" -> "Stage 4 FIX_PLAN: one scoped fix plan for this round's blocking findings" [label="blocking findings"];
"Stage 4b: joint integration review over a split's combined diff" -> "CLOSE(review_gate): the gate that raised the findings goes [x]" [label="clean"];
"Stage 4 PASS: RV [x], close-out written and saved" -> "Stage 4 IMPLEMENT: every task in the phase, waves of tasks (ambiguity -> ask)" [label="next phase"];
"Stage 4 PASS: RV [x], close-out written and saved" -> "Stage 5: finishing-a-development-branch" [label="all phases done"];
}
Stage 1 — Brainstorm (interactive question rounds + agent pressure-test)
The stage order is fixed: question rounds → pressure-test → synthesis → GATE 1. Never merge these into one message, never present a design before the questions are answered, never run the pressure-test after the gate.
- Read
references/run-state.md. Create the run directory at<PROJECT_DIR>/docs/superpowers/runs/YYYY-MM-DD-<topic>/, copy in the templates, seedprogress.mdwith Stages 1–5 as phases (all[ ], Current State = Stage 1), state the full directory path in your first message to the user, then read the tracker back.kit.mdis the exception: it cannot be filled in before the plan names the gates, so GATE 2 writes it and this step does not. If the directory already exists, stop and ask — resume, fresh run, or abort — showing the user its Current State. - Invoke
superpowers:brainstormingfor the interactive Q&A. - Run as many question rounds as it takes until you can state every
requirement with zero open Assumptions Register entries. Each new answer
that reveals new unknowns spawns another round. More rounds = correct.
- The repo's commit and verification conventions go in the first round —
the ticket/issue key required in a commit subject (and this run's value
for it), any coverage floor on changed lines, and any pre-push gate. A
written repo rule is the one kind of unknown
register.md's Decided without asking table lets you settle alone, but only once you have found it, and inference is not finding. The seeded key entry asks two things and its halves go to different tables: whether this repo demands a key at all is answered by the written rule, so that half belongs in Decided without asking with the rule cited the moment you find it — and in Open only while you cannot; which key this run uses is answered by nobody but the user, so that half stays Open and blocks GATE 1 until they say it. Every task in the run commits, so a wrong answer here is wrong in every commit. Seed them as register entries, cite the rule that answers each, a
- The repo's commit and verification conventions go in the first round —
the ticket/issue key required in a commit subject (and this run's value
for it), any coverage floor on changed lines, and any pre-push gate. A
written repo rule is the one kind of unknown
…(truncated)