Replace brainstorm's ~10 serial user round-trips with a parallel populate-then-triage: enumerate the load-bearing forks, populate them with a grounded synthetic-user swarm (mandatory per-answer citation), and triage — a fork the swarm settles on a cited shared ground is decided (user vetoes), a split or ungrounded-consensus is a direction fork the user settles. A cross-check surfaces any fork the orchestrator's own enumeration held open but the swarm closed. A fire-check + grounding floor skip the swarm when it would be ceremony. Under /boss the swarm runs autonomously: convergent forks are decided and recorded on the reference issue, only a divergent direction fork (or a sub-floor greenfield design) bounces. Retires trigger-4's "fresh brainstorm is too high-context to run autonomously" rationale — the swarm is the compaction. - brainstorm/agents/synthetic-user.md: new read-only swarm agent - brainstorm/SKILL.md: full rewrite to the swarm flow + new Iron Law - boss/SKILL.md: autonomous swarm-brainstorm (Iron Law, trigger 4, asymmetry, notifications, rationalisations, red flag) - docs/pipeline.md: brainstorm phase description - specify/SKILL.md: brainstorm characterised as swarm discovery, not interview closes #19
20 KiB
name, description
| name | description |
|---|---|
| brainstorm | Use when a new cycle is starting and the design is NOT yet settled — enumerates the load-bearing design forks, populates them with a parallel swarm of grounded synthetic-user stances instead of a serial interview, triages the result (forks the swarm settles on a cited ground are decided; forks it splits on are the user's call), then hands the ratified design to specify. The optional discovery front-end; when the design is already settled in the sources, skip to specify directly. Applies even when the user says they have a clear vision. |
brainstorm — cycle discovery front-end
Violating the letter of these rules is violating the spirit.
Overview
Discovery is where the orchestrator does the deciding work — surfacing the load-bearing forks a new cycle forces, resolving the ones it can ground an answer for, and putting the rest to the user. It is the front-end that settles a genuine design fork before any spec is written. Skipping it when the design is genuinely open means shipping the user's intuition unfiltered, which is exactly the reactive-deference failure the orchestrator discipline exists to prevent.
What brainstorm no longer does is run a serial interview — one question
per message, a per-section ratification gate — to get there. That ceremony
spent ~10 blocking round-trips per cycle to catch a divergence from the
orchestrator's recommendation that, across a whole project, materialises about
once. Instead brainstorm populates the design space in parallel: it
enumerates the forks, dispatches a swarm of grounded, genuinely-opposed
synthetic-user stances to answer them, and triages the result. Where the
stances converge on a cited common ground the fork was derivable — it is
decided, and the user only vetoes. Where they genuinely split, no source
settles it — it is a direction fork, and that is the user's call. Direction
is never delegated downstream; it is set here, by the user, on exactly the
forks that turn out to be theirs.
brainstorm does not write the spec. Its terminal state is handing the
ratified design to specify (the spec-production core), which applies the
acceptance criterion, writes the spec under docs/specs, runs the gates, and
takes sign-off. When the design is already settled in the sources,
brainstorm is skipped entirely and the work enters through specify.
When to Use / Skipping
Triggers:
- A new cycle is starting (a new feature area, a new subsystem, or a major refactor of an existing one) whose design is genuinely open.
- A cycle-scope spec is missing for an existing line of work and one is needed retroactively, and the design behind it was never settled.
Skip brainstorm (enter through the named alternative) for:
- A design already settled in the sources — an exhaustive issue, a long
in-context discussion, settled design docs. Use
specifydirectly: discovery would only re-litigate decisions the sources already made. - A test-specifiable feature — use
tdddirectly. - A bug-fix iteration — use
debugdirectly. - A tidy iteration — use
auditdirectly. - A trivial mechanical edit — per the project's CLAUDE.md carve-out.
Do not skip brainstorm when the design is genuinely open:
- A request framed as "I have a clear vision, just plan it" whose vision still hides an unresolved fork.
- A cycle where a load-bearing decision is not yet made.
The discriminator is the design line: if the sources resolve every
load-bearing decision, the work belongs to specify; if writing the spec
would force you to pick one, discovery is what resolves it, and that is
brainstorm.
The Iron Law
ENUMERATE EVERY LOAD-BEARING DESIGN FORK BEFORE POPULATING ANYTHING — THIS
ENUMERATION IS ALSO THE ORCHESTRATOR'S OWN INDEPENDENT SIGNAL, USED LATER TO
CROSS-CHECK THE SWARM.
A FORK THE SWARM SETTLES ON A *CITED SHARED GROUND* WAS DERIVABLE -> PRESENT IT
DECIDED (USER VETOES), AND RECORD THE GROUND. A FORK THE SWARM SPLITS ON, OR
AGREES ON WITH *NO CITABLE GROUND* (UNGROUNDED-CONSENSUS), IS A DIRECTION
FORK -> THE USER'S CALL. THE LINE IS GROUNDED-DERIVABILITY VS PREFERENCE,
NOT SMALL VS LARGE, AND NOT BARE AGREEMENT.
A FORK THE ORCHESTRATOR'S OWN ENUMERATION FLAGGED OPEN BUT THE SWARM CLOSED IS
SURFACED TO THE USER ANYWAY — THE SWARM NEVER ERASES A FORK THE ORCHESTRATOR
INDEPENDENTLY HELD OPEN.
THE DECIDING WORK IS NEVER SKIPPED. A DESIGN PRESENTED WITHOUT THE FORK
ENUMERATION + SWARM + TRIAGE DONE IS THE RUBBER-STAMP BETRAYAL, NOT DISCOVERY.
DESIGN DIRECTION IS SET HERE BY THE USER — NEVER DELEGATED TO THE SWARM, NEVER
TO `specify`.
Every clause is non-negotiable. The swarm is evidence, not an oracle: it
populates the space and exposes where stances split, but the convergent-vs-
direction verdict is the orchestrator's derivability judgement (the same one
specify Step 1.5 applies), and bare agreement among same-model stances is
never that judgement — only agreement on a citable ground is.
The Process
Step 1 — Explore project context
Before enumerating anything:
git log -5 --format=fullfor the full bodies of the most recent iter / audit commits — current state of the project.- If the project has a design ledger (its CLAUDE.md project facts name it), walk to the relevant contracts for the invariants the new cycle might touch.
- When reading any file under the project's design models, note its
status/validated-againstfrontmatter if present:status: aspirationalmeans its code is a target, not verified fact. Track which content is flagged for lift-time validation whenspecifywrites the spec. git log --oneline -20for the chronological scan.- Identify scope: is this one cycle, or does it need to be decomposed into sub-cycles first? If multi-subsystem, decompose.
Step 2 — Enumerate the load-bearing forks
List the load-bearing design forks the cycle forces — the choices that, decided differently, would change what ships — exactly as the clarifying questions you would otherwise have put to the user. Cover at least:
- Purpose: what problem does this solve?
- Constraints: what semantic / performance / compatibility invariants must hold?
- Success criteria: how do we know it shipped?
- Scope: what is OUT of scope?
For each fork, privately note whether you think it is derivable or genuinely open. This enumeration is the swarm's input and your own independent signal: a fork you flagged open that the swarm later closes is surfaced to the user anyway (the Iron Law cross-check). Do not interview the user here — no serial questions.
Step 2.5 — Fire-check (skip the swarm when it would be ceremony)
The swarm is justified only when there are multiple non-trivial forks whose derivability is genuinely uncertain and there is enough checked-in ground to answer them honestly. Skip it, and resolve inline, when:
- Too few forks. Zero or one real fork — answer it directly (a single derivable fork is decided and noted; a single open one is one question to the user). Spinning up a swarm for one fork is more machinery than the ceremony it replaced.
- Grounding floor not met. No design ledger, a thin or absent glossary, an
under-specified audience — a greenfield or new-territory project. With
nothing to cite, every synthetic stance confabulates and "convergence" is
100% hallucination wearing a quorum. Below this floor the swarm is NOT
dispatched; fall back to a direct human interview (and under
/boss, that is a bounce-back — see § Under/boss).
Record the skip reason in the cycle's notes / the run's reference issue. The swarm is an optimization for context-rich mature projects, not an unconditional default.
Step 3 — Populate the space with the synthetic-user swarm
Dispatch the read-only agents/synthetic-user.md agent in parallel, one per
stance, in a single turn — the same ad-hoc fan-out brainstorm already uses
for plan-recon and specify uses for spec-skeptic. No Workflow wrapper: a
one-shot stateless fan-out has no re-loop, no ordering, and no in-code verdict
to enforce, so it is a direct dispatch, not an implement-loop-style script.
The roster is fixed convention (no per-project config knob; only the grounding — the project's declared audience / ledger / glossary, reached via standing reading — varies):
- minimalist — convention over config, the smallest change that ships.
- power-user / composability — capability, extension, what it unlocks.
- maintainer / future-self — invariants, drift cost, long-term carry.
- skeptic — does this need to exist at all (the feature-acceptance criterion incarnate).
- off-ledger wildcard — advocates the direction the project does not imply. Inherently ungrounded by design, so it can only ever surface a fork, never close one; it exists to keep the swarm from collapsing into status-quo unanimity.
Each stance answers the whole fork_set with a mandatory per-answer source
citation or an honest ungrounded:true (the agent's Iron Law). The swarm
ONLY answers the forks; it never authors approaches.
Step 4 — Triage and present the populated space
This is the one user stop in interactive mode. Cluster the stances'
answers per fork and apply the derivability test — the same one specify
Step 1.5 uses, measured here against the swarm:
- Converged on a cited shared ground → DECIDED. Present it as decided with the ground shown; the user only vetoes. Record the ground.
- Split, or converged with no citable ground (ungrounded-consensus) → DIRECTION FORK. The user's call. Surface the conflicting positions (and the wildcard's off-ledger alternative where it raised one) as the things to weigh. Bare agreement among same-model stances is not a decision — demote it.
- Cross-check. Any fork your own Step-2 enumeration flagged open that the swarm closed is surfaced anyway, never auto-decided.
Then author the 2-3 approaches yourself — the orchestrator's job, never the swarm's. They crystallise out of the populated space: the converged axes are fixed; each genuine direction fork's conflicting answers is an approach the user weighs. Lead with your recommended option and why; for each:
- concrete code first, prose second. The primary artefact is the actual program or invocation that should work under this approach, in the project's canonical authoring or consumer form. The implementation shape (changed struct / signature / match-arm, before → after) is secondary supporting detail, never a substitute for the user-facing code.
- substantive trade-offs (semantic fit, schema impact, performance, composability).
- effort observation (NOT effort as rationale — see the project's CLAUDE.md on design rationale ≠ implementation effort).
Present the conceptual design alongside — Architecture, Components, Data flow,
Error handling, Testing strategy — each scaled to complexity. This design is
conceptual: the concrete user-facing code and the before → after shapes are
materialised downstream when specify writes the spec and applies the
acceptance criterion. Your job here is to get the design decision right and
ratified, not to write the artefact.
If the populated space shows every candidate approach is bad, that is the "problem is mis-framed" signal — STOP and escalate to the user, do not ratify a known-bad shape. Three unsatisfying approaches mean the problem is wrong, not that one must be picked.
Step 5 — Deepen the forks the user opens
Deepening is free chat with the orchestrator by default — the user's
native mode, and the one place they have chosen to engage. A direction fork is
by definition one the swarm could not ground, so re-running the swarm on it
asks the machinery that already failed to converge to try again; do not make a
second swarm round the default. It is an optional tool the orchestrator MAY
reach for, scoped to one fork, only to populate in-direction sub-options once
the user has tilted toward a direction, or to rescue a fork that turns out to
be mis-framed — spec-skeptic-style, a tool reached for, not a gate.
Capture the resolution. Whatever the chat settles is folded into the
ratified design narrative handed to specify, and minuted on the run's
reference issue (the specify Step-1.5 reconciliation-comment / boss
decision-log discipline). The free-chat deliberation that used to evaporate now
lands in the pipeline.
Step 6 — Hand off to specify
The terminal state of brainstorm is invoking specify. NO spec file is
written here; NO other skill is invoked; NO direct jump to planner or
implement.
Hand off carries the ratified design narrative, in-context (same orchestrator context — no intermediate artefact):
- the approach chosen and why
- the constraints and invariants surfaced in the swarm + deepening
- the design sections the user ratified (Step 4)
- the decided forks with their cited grounds, and the resolved direction
forks with the user's choice — so
specify's chain-entry (Step 1.5, "re-ground lightly … rather than re-deriving it") reads them as already settled instead of re-litigating them - the iteration scope ("the first iteration covers section X+Y")
specify reads this narrative as its source, applies the acceptance criterion,
writes the spec, runs the parse and grounding-check gates, takes sign-off, and
hands off to planner. The production gates live there, not here.
Under /boss (autonomous)
When the user is away, the swarm runs autonomously — the discovery is now
bounded and context-compacting (the orchestrator gets back a triaged populated
space, not a 10-round interview transcript), so a fresh brainstorm is no
longer a mandatory pre-dispatch bounce. The autonomous contract mirrors
specify's bold-decide stance:
- Decide the convergent forks. A fork the swarm settles on a cited shared
ground is decided autonomously and recorded on the run's reference issue
with the ground (the
boss§ Direction-freedom decision-log discipline) — exactly asspecifyStep 1.5 records a derived fork. - Bounce only the divergent direction forks. A genuine direction fork (split, or ungrounded-consensus, or one the Step-2 cross-check held open) is the user's call; there is no user present, so it routes to a problem-state bounce — a vetoable notify naming, in the user's terms, the design choice that needs them. The convergent decisions ride along; only the genuine forks stop the loop.
- Grounding floor → bounce. If Step 2.5's grounding floor is not met (greenfield, no ledger), the swarm cannot run honestly and the work needs a human interview — that remains a bounce-back, on grounding grounds, not on the retired "fresh brainstorm is too high-context" rationale.
See ../boss/SKILL.md § Direction freedom (trigger 4) and the Entry-path
reflection for how this folds brainstorm into the autonomous cascade.
Handoff Contract
| Direction | Carrier |
|---|---|
user → brainstorm |
new cycle request with a genuinely open design |
brainstorm → synthetic-user swarm (Step 3) |
fork_set + one stance per dispatch + grounding pointers; read-only, parallel, no Workflow |
brainstorm → user / reference issue (Step 4 / /boss) |
the triaged populated space: decided forks + cited grounds, direction forks surfaced for the user's call |
brainstorm → specify (Step 6) |
ratified design narrative (approach, constraints, ratified sections, decided forks + grounds, resolved direction choices, iteration scope) — in-context; no spec file written |
Common Rationalisations
| Excuse | Reality |
|---|---|
| "User says 'clear vision, just plan it' — skip the discovery" | "Clear vision" is a starting point, not a settled design. Enumerate the forks; the swarm will show which the vision actually resolves and which it papers over. The ones it papers over are the user's to settle. |
| "Present my own derived design without the swarm — I already know the answer" | Deriving one answer alone and presenting it polished is the single-guess rubber-stamp. The swarm's diversity is what surfaces the constraint you did not think to derive; the cross-check is what stops your own prior from erasing a fork. Run the swarm (above the fire-check floor) or you are shipping unfiltered intuition with extra steps. |
| "The swarm all agreed, so the fork is decided" | Only if they agreed on a cited shared ground. Same-model stances agree by shared prior all the time — that is ungrounded-consensus, and it is a direction fork for the user, not a decided one. Bare agreement is the false-convergence trap, not a verdict. |
| "There's a direction fork left — re-run the swarm on it to be thorough" | A direction fork is the one the swarm could not ground; re-swarming asks the same non-oracle the same unanswerable question at higher resolution, and the extra detail only makes the guess more persuasive. Deepen it in free chat with the user; a scoped re-swarm is optional and only for in-direction sub-options after the user has tilted. |
| "Three approaches in, none feel right — ship the least bad" | Three unsatisfying approaches usually means the problem is mis-framed. Stop, capture what fails about each, escalate to the user. End-of-day pressure is the worst signal to resolve a design fork. |
| "Spec exists from previous cycle, append to it" | The previous cycle's spec was retired at its close (see ../docs/conventions.md § Lifecycle) — there is nothing to append to. New cycle = new spec file; mixing scopes makes drift review unreadable. |
| "Let the swarm author the approaches — it has the stances already" | The swarm answers forks; the orchestrator authors approaches. A finished design from the swarm delegates design DIRECTION to a fan-out — the same downstream-delegation sin the reform exists to prevent, just relocated from specify to the agents. |
Red Flags — STOP
- "Skip the discovery" thoughts (any flavour) on a genuinely open design.
- Presenting a design without having enumerated the forks, run the swarm (above the fire-check floor), and triaged it.
- Treating bare swarm agreement as a decision — an ungrounded-consensus silently auto-decided instead of surfaced as the user's call.
- A fork your own Step-2 enumeration held open, quietly closed by the swarm and not surfaced (the cross-check skipped).
- Letting the swarm author the 2-3 approaches, or delegating any design direction to it.
- Re-running the swarm on a direction fork as the default deepening path instead of free chat with the user.
- Running the swarm below the grounding floor (greenfield, no ledger) and trusting its confabulated convergence.
- "The 2-3 approaches all suck, just pick one" — that is the mis-framed-problem escalation, not a forced pick.
- Inventing a design rationale that's actually about effort, not semantics.
Cross-references
- Agent dispatched:
agents/synthetic-user.md— the read-only synthetic design-stance respondent, dispatched as a parallel swarm in Step 3. Aspec-skepticsibling: a fixed read-only lens family that returns a finding, never a verdict. - Output target:
../specify/SKILL.md— the only valid next skill.brainstormhands the ratified design tospecify, which produces the spec and gatesplanner. There is no directbrainstorm → planneredge. - Shared derivability test:
../specify/SKILL.mdStep 1.5 — the derivable-vs-pure-preference linebrainstormmeasures against the swarm is the same onespecifyapplies to the sources; defined there, referenced here, so the two cannot drift. - Alternative entry path / bounce-back source:
../tdd/SKILL.md— a test-specifiable feature enters throughtddinstead;tddbounces back the moment the behaviour stops being test-specifiable.../specify/SKILL.mdlikewise bounces back here when the sources do not resolve a design fork. - Autonomous behaviour:
../boss/SKILL.md§ Direction freedom (trigger 4) and the Entry-path reflection — how the autonomous swarm-brainstorm decides convergent forks and bounces only divergent ones. - Ad-hoc dispatch. The orchestrator MAY also ad-hoc dispatch
../planner/agents/plan-recon.mdduring Step 1 when the cycle enters code territory not recently read; ad-hoc, not part of the standard process. - Project feature-acceptance criterion: declared in the project's
CLAUDE.md— applied prospectively byspecify(its Step 2), not here.