---
name: brainstorm
description: Use when a new cycle is starting — gathers requirements, explores 2-3 approaches with trade-offs, presents a sectioned design with user approval, writes the spec under paths.spec_dir. Hard-gate before any plan or code work; applies even when the user says they have a clear vision.
---
# brainstorm — cycle spec generator
> **Violating the letter of these rules is violating the spirit.**
## Overview
The spec is where the orchestrator does the design work. It
is the artefact that future iterations, the architect agent,
and any future reader read to understand WHAT the cycle
delivers and WHY. Skipping the spec means shipping the user's
intuition unfiltered, which is exactly the reactive-deference
failure mode the orchestrator discipline exists to prevent.
It produces specs under the project's `paths.spec_dir`.
## When to Use / Skipping
Triggers:
- A new cycle is starting (e.g. user proposes a new feature
area, a new subsystem, or a major refactor of an existing
one).
- A cycle-scope spec is missing for an existing line of
work and one is needed retroactively.
**Skipping is permitted only** for:
- A bug-fix iteration (use `debug` directly).
- A tidy iteration (use `audit` directly).
- A trivial mechanical edit (≤1 file, ≤30 LOC, no design
judgement).
**Skipping is not permitted** for:
- A user request framed as "I have a clear vision, just plan
it".
- A cycle described as "small, only two iterations".
- A cycle where you are confident you know what to build.
The first two cases above are the most common pressure to
skip; both are explicitly resisted by this skill (see Common
Rationalisations).
## The Hard-Gate
```
NO IMPLEMENTATION, SCAFFOLDING, OR DOWNSTREAM SKILL INVOCATION
UNTIL A SPEC HAS BEEN PRESENTED AND THE USER HAS APPROVED IT.
```
The hard-gate applies regardless of perceived simplicity.
The spec can be short for a small cycle (a few sections),
but it MUST exist and be approved before any plan or code
work begins.
## The Process
### Step 1 — Explore project context
Before asking any clarifying questions:
- `git log -5 --format=full` for the full bodies of the most
recent iter / audit commits — current state of the project.
- If the project has a design ledger configured under
`paths.design_ledger`, walk to the relevant contracts for
the invariants the new cycle might touch.
- When reading any file under `paths.design_models` (or the
ledger's "model" rows), note its `status` /
`validated-against` frontmatter if present: `status:
aspirational` means its code is a target, not verified fact.
Track which content you may lift from such a source — it is
flagged for lift-time validation (Step 4).
- `git log --oneline -20` for 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 — Ask clarifying questions, one at a time
Multiple-choice when possible (easier to answer). One
question per message — no batching. Focus on:
- **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?
### Step 3 — Propose 2-3 approaches with trade-offs
Lead with your recommended option and explain why. Each
approach gets:
- core idea (1-2 sentences)
- **concrete code first, prose second.** The *primary*
artefact is the actual program or invocation that should
work under this approach — written in the project's
canonical authoring or consumer form. Show it. The
implementation shape (changed struct / signature / match-
arm, before → after) is *secondary supporting* detail —
"also useful, not the point" — include it but never let it
stand in for the concrete user-facing code. "The approach
extends the struct with a field" is not an approach; the
user-facing program it makes work (or correctly reject) is.
- 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)
Wait for user choice before proceeding.
### Step 4 — Apply the project's feature-acceptance criterion
The project's `CLAUDE.md` declares the criterion a feature
must satisfy to ship. Apply it now, prospectively. The
typical shape is some combination of:
- the project's intended audience naturally reaches for the
feature,
- the feature measurably improves correctness or removes
redundancy,
- the feature reintroduces no class of failure the project's
core constraint exists to eliminate.
If the project does not declare a criterion, the default is
"the feature solves a real user-facing problem and does not
contradict a stated design commitment". The orchestrator
applies the criterion; do not delegate it to the user.
**The criterion is unjudgeable without concrete code.** For
any cycle with authoring or consumer surface, the spec MUST
contain the actual program / invocation / configuration a
user would write — and that example *is* the criterion's
empirical evidence. A prose assertion ("a user naturally
reaches for X") with no shown code is exactly the
unfalsifiable hand-wave the criterion exists to prevent:
write the code the user would write, then judge whether it
is in fact what the criterion demands. For an infrastructure
cycle with **no** user surface there is still concrete code:
show the actual code the cycle *delivers* — frequently a
test fixture whose correct behaviour is rejection (wrong
code must fail the relevant check) — plus a *minimal,
honest* slice of the north-star program the infrastructure
exists to serve. "This cycle has no surface so there's no
code to show" is the rationalisation to refuse: an infra
cycle that cannot be tied to concrete code is speculative
infra.
**Code lifted from an aspirational source is a hypothesis, not
evidence.** If the concrete code here is lifted from a
`design_models` file (or any source marked `status: aspirational`,
per Step 1), it carries no validation by default — the marker
exists precisely because no one has run it through the live tool.
Its `design/` location is not ratification. Treat it as the spec's
most suspect bytes: it must clear the Step-7 parse-every-block
gate before PASS. The marker tells you *which* blocks to distrust
first.
### Step 5 — Present design in sections
Scale each section to its complexity (a few sentences if
straightforward, up to 200-300 words if nuanced). Cover:
- Architecture
- Components
- Data flow
- Error handling
- Testing strategy
**Concrete code is the headline; the implementation shape is
supporting.** The `## Concrete code shapes` section leads
with the user-facing program (the Step-4 empirical evidence),
or — for an infra cycle — the delivered fixture and a
north-star slice. The before → after implementation shape
(struct / signature / match-arm) follows as a clearly
secondary subsection — "also useful, not the point" — never
first, never a substitute for the user-facing code. Prose may
*explain* code, never *replace* it. Exact bytes / line-
numbers remain the planner's job (planner Iron Law) — the
spec owns the *shape*, shown, with the user-facing program
foremost.
Ask after each section whether it looks right. Be ready to
revisit earlier sections if a later one surfaces a
contradiction.
### Step 6 — Write the spec
Path: under `paths.spec_dir`, with a name per the project's
`naming.policy` (see profile schema). Determine the next
slot per the policy (e.g. for `stable_per_directory_4digit`:
look at the latest counter and add 1).
Structure:
```markdown
#
— Design Spec
**Date:** YYYY-MM-DD
**Status:** Draft — awaiting user spec review
**Authors:** orchestrator + Claude
## Goal
## Architecture
## Concrete code shapes
## Components
## Data flow
## Error handling
## Testing strategy
## Acceptance criteria
```
`## Concrete code shapes` is mandatory and **leads with the
user-facing program**: the worked author example for a
surface cycle (= the Step-4 empirical evidence), or — for a
no-surface infra cycle — the code the cycle *delivers* (often
a must-fail fixture) plus a minimal honest north-star slice
(Step 4). The before → after implementation shape for each
load-bearing change follows as an explicitly secondary
subsection, never first.
### Step 7 — Self-review
Inline checklist (not a subagent dispatch):
1. **Placeholder scan:** any "TBD", "TODO", incomplete
sections, vague requirements? Fix.
2. **Internal consistency:** sections must not contradict.
Architecture must match component descriptions.
3. **Scope check:** focused enough for one plan, or does it
need sub-cycle decomposition?
4. **Ambiguity check:** could any requirement be interpreted
two ways? If so, pick one and make it explicit.
5. **Concrete-code check:** does `## Concrete code shapes`
exist and carry before → after code for every load-bearing
change (plus the worked user-facing example for a surface
cycle)? A load-bearing change described only in prose is
a self-review failure to fix, exactly like a placeholder.
6. **Parse-every-block gate.** If the project profile declares
`spec_validation.parsers`, extract every fenced code block
from the spec. For each block whose fence label has a
`parsers` entry: write the block to a temp file with the
entry's `ext`, run the entry's `cmd` with `{file}`
substituted, and require exit 0. A non-zero exit is a
self-review failure — the spec inlines code that does not
parse against the live tool — fix the spec before proceeding;
do not pass the unparsed bytes downstream. Paste the
parse-trace (the Run block and its output) into the
brainstorm chat: a visible trace is what attests the gate
fired, and its absence means the gate was skipped. A block
whose fence label has no `parsers` entry is skipped and the
skip is noted ("no parser for fence label X"); never a silent
pass. A malformed entry (`cmd` without `{file}`, or `ext` /
`cmd` missing) is a profile error to surface, not a skip. If
the profile declares no `spec_validation`, this check is a
documented no-op.
Fix issues inline. No need to re-review — fix and commit.
### Step 7.5 — Grounding-check (hard-gate)
Dispatch the read-only `grounding-check` agent. The agent
reads the just-written spec with fresh context, extracts its
load-bearing assumptions about *current* behaviour of the
codebase (compiler, type-checker, runtime, schema, API,
whatever the project owns), and for each one searches the
workspace for a currently-green test that ratifies it.
Dispatch carrier:
| Field | Content |
|-------|---------|
| `spec_path` | path to the spec just written in Step 6 |
| `iteration_scope` | which sections cover the imminent first iteration (verbatim from the brainstorm session) |
The agent returns a `PASS` / `BLOCK` / `INFRA_ERROR` report.
Orchestrator interpretation:
| Agent status | Orchestrator action |
|--------------|---------------------|
| `PASS` | Proceed to Step 8. The report goes into the brainstorm chat for the record. |
| `BLOCK` | Present the report to the user. User either: (a) accepts discard → execute the failure-mode procedure below; or (b) overrides in free chat ("Test `::` ratifies that") → log the override note in the brainstorm chat and proceed to Step 8. |
| `INFRA_ERROR` | Abort the brainstorm. The spec stays as-is on disk; debug the workspace out-of-band and re-dispatch the agent. |
**Failure-mode procedure (no-override `BLOCK`):**
1. Delete the just-written spec file from the working tree
(`rm ` — a shell delete on the working tree,
NOT `git rm`; the file was never committed).
2. Open a backlog issue (via the project's issue-tracker
create command — `tea issues create` for Gitea,
`gh issue create` for GitHub, analogous for Linear /
Jira / etc.) pointing forward to a future re-brainstorm.
Include in the issue:
- **Title:** one-line identity of the deferred work
- **Label:** matching the project's vocabulary (often
`feature` / `bug` / `idea`; promote to `BLOCKER` if
the unratified mechanism is on a core-functionality
path)
- **Body:** short description, plus two structured
lines:
- `depends on: `
- `context: `
If the deferred work is large enough to need its own
spec on resumption — multi-iteration scope, cross-
subsystem — file it as a **milestone container**
instead (Gitea milestones, GitHub milestones, Linear
projects, whatever the project's tracker calls a
long-running work scope), not as a single issue.
3. Tell the user the spec was retired and which backlog
entry was filed (include the issue or milestone number).
No commit is needed for the backlog entry — the issue
tracker is the live store.
After the failure-mode procedure runs, the brainstorm
session ENDS. There is no Step 8, no Step 9. The idea is
parked until the dependency ships, at which point a fresh
brainstorm session re-derives the spec from scratch.
**Re-dispatch on any post-PASS edit.** The grounding-check
PASS report is bound to the exact bytes of the spec at
dispatch time. Any subsequent edit to the spec file —
orchestrator-side polish, a user-requested change in free
chat, a wording tighten, anything — invalidates the PASS
report and requires a fresh dispatch of `grounding-check`
before Step 8 commit. Step 7.5 is the *last* step that
touches the spec file; nothing slips between it and the
commit.
### Step 8 — User-review gate
The spec sits in the working tree as an unstaged file. Tell
the user:
> Spec written to `` (uncommitted). Please review it
> and let me know if you want changes before we start the
> implementation plan. The orchestrator will commit it once
> you approve.
Wait for the user's response. If they request changes, edit
the file in place (still uncommitted), **re-run Step 7 AND
re-dispatch Step 7.5** (the previous PASS report no longer
covers the edited bytes), then return here. Only proceed to
the next step after approval AND a fresh Step 7.5 PASS.
The orchestrator commits the approved spec after the user
signs off (suggested commit subject: `spec:
`). The brainstorm skill does not perform the commit
itself.
### Step 9 — Hand off to `planner`
The terminal state of `brainstorm` is invoking `planner`. NO
other skill is invoked from `brainstorm`. NO direct jump to
`implement`.
Hand off carries:
- path to the spec under `paths.spec_dir`
- iteration scope ("the first iteration covers section X+Y
of the spec")
## Handoff Contract
| Direction | Carrier |
|-----------|---------|
| user → `brainstorm` | new cycle request |
| `brainstorm` → `grounding-check` (Step 7.5) | `spec_path` + `iteration_scope` |
| `brainstorm` → `planner` (Step 9, on PASS or overridden BLOCK) | path to spec + iteration scope |
| `brainstorm` → issue backlog (Step 7.5, on no-override BLOCK) | new issue opened via the project's issue-tracker create command naming the unratified dependency; spec file deleted from the working tree (no commit needed) |
## Common Rationalisations
| Excuse | Reality |
|--------|---------|
| "User says 'clear vision, just plan it' — skip the spec" | "Clear vision" is a starting point, not a spec. The user's intuition hasn't priced in semantic commitments the project carries. Write the spec; frame it as "load-bearing decisions this idea forces on us". |
| "Cycle is small, two iterations, no spec needed" | Iteration count isn't the metric — feature surface is. A two-iter feature touching design-ledger invariants needs a spec; a CLI flag does not. Assess what the feature changes in invariants. |
| "Three approaches in, none feel right, ship the least bad" | Three unsatisfying approaches usually means the problem is mis-framed. Stop, capture the three approaches and what fails about each in the spec's design notes (or escalate to the user), sleep on it. End-of-day pressure is the worst signal to resolve a design fork. |
| "User is busy, present my own design without Q&A" | Reactive deference disguised as decisiveness. The Q&A surfaces constraints the user hasn't articulated; skipping it means shipping the user's defaults, not their intent. |
| "Spec exists from previous cycle, append to it" | New cycle = new spec file. The architect agent reads spec files per cycle; mixing scopes makes drift review unreadable. |
| "Approaches A, B, C are all bad — proceed with A" | This is exactly the moment to surface "the problem is mis-framed" rather than ratify a known-bad shape into the design ledger. Escalate to the user. |
| "Just polishing a wording after PASS, no need to re-dispatch" | The grounding-check report attests to specific bytes. A polish edit changes the bytes; the previous attestation no longer covers them. Re-dispatch is cheap; the alternative is a commit with an attestation that doesn't match the file. |
| "The shape is clear from the prose, I don't need to paste the code" | If it's clear, pasting it is free; if pasting it is hard, it wasn't clear. The feature-acceptance criterion is unjudgeable without the worked code; "a user reaches for it" with no shown code is the exact hand-wave the criterion exists to kill. |
| "The block obviously parses — I wrote it carefully" | Careful authoring is not a parse. A spec's code blocks are hypotheses until the live tool accepts them; treating them as truth is the compound-hallucination failure the parse-every-block gate exists to kill. If a parser is configured for the block's fence label, run it and paste the trace. |
| "It's in a model doc / the design ledger, so it's canonical" | A `models` / RFC / proposal doc holds aspirational code — a target, not verified fact; its `design/` location is not ratification. Code lifted from a `status: aspirational` source must clear the Step-7 parse gate like any other block, and is in fact the most suspect bytes in the spec. |
## Red Flags — STOP
- "Skip the spec" thoughts (any flavour)
- "One paragraph is enough"
- "User said it's clear, who am I to push back"
- "The 2-3 approaches all suck, just pick one"
- Skipping Step 7 self-review because "I wrote it carefully"
- A load-bearing change described in prose with no
before → after code block; a surface cycle with no worked
user-facing example
- A spec carrying a code block whose fence label has a
configured `spec_validation` parser, committed without a
parse-trace in the brainstorm chat
- Lifting code verbatim from a `status: aspirational` source (a
`models` / RFC / proposal file) into the spec without flagging
it for the Step-7 parse gate
- Editing the spec file after a Step 7.5 PASS without
re-dispatching
- Jumping straight from spec to `implement` (must go via
`planner`)
- Inventing a design rationale that's actually about effort,
not semantics
## Cross-references
- **Output target:** `../planner/SKILL.md` — only valid next
skill.
- **Agent dispatched:** `agents/grounding-check.md` —
dispatched in Step 7.5 as a hard-gate. The agent reads the
spec with fresh context and reports PASS / BLOCK /
INFRA_ERROR.
- **Ad-hoc dispatch.** The orchestrator MAY also ad-hoc
dispatch `../planner/agents/plan-recon.md` during Step 1
when the cycle enters code territory the orchestrator has
not recently read; this is opt-in and not part of the
standard process.
- **Project feature-acceptance criterion:** declared in the
project's `CLAUDE.md` (or a contract the CLAUDE.md
points to). Applied prospectively in Step 4.