e1d33369f5
Adds self-review check #6 to brainstorm Step 7: when the profile declares `spec_validation.parsers`, every fenced spec block whose fence label has an entry is written to a temp file (entry `ext`) and run through the entry `cmd` ({file} substituted); non-zero exit is a self-review failure that must be fixed before the spec proceeds. The parse-trace goes into the brainstorm chat as the attestation the gate fired. Labels with no entry are skipped-and-documented; a malformed entry surfaces as a profile error; no `spec_validation` -> no-op. Placed in Step 7 (not Step 4 as the issue's prose suggested) because the spec file — and thus its code blocks — exists only after Step 6; Step 7 also already re-runs on post-PASS edits, so a changed block re-triggers the gate for free. Also adds a Common Rationalisation ("it obviously parses") and a Red Flag (configured parser, no trace in chat). refs #1 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
415 lines
18 KiB
Markdown
415 lines
18 KiB
Markdown
---
|
|
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.
|
|
- `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.
|
|
|
|
### 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
|
|
# <Title> — 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 `<path>::<name>` 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 <spec_path>` — 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: <name of the unratified mechanism>`
|
|
- `context: <why this is deferred>`
|
|
|
|
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 `<path>` (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: <cycle>
|
|
<topic>`). 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. |
|
|
|
|
## 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
|
|
- 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.
|