feat(specify): add spec-production entry path; split brainstorm

Add `specify` as a third co-equal entry path into the dev cycle: it
produces an approved spec from already-settled sources (an exhaustive
issue, a long in-context design discussion, or a design brainstorm just
ratified) with review but no interview. This is the producing half of a
deliberate deciding/producing split — `brainstorm` shrinks to optional
discovery, `specify` becomes the sole spec-production gate before
`planner`, mirroring the RED->GREEN split that keeps tdd/debug honest.

What moved:
- brainstorm/SKILL.md: stripped of the hard-gate, the acceptance
  criterion, write-spec, self-review, grounding-check, user-review, and
  planner-handoff steps; terminal state is now handing a ratified design
  narrative to specify. Steps renumbered 1-5 (production steps left).
- specify/SKILL.md (new): the production core, with a precondition gate
  (Step 1.5) that bounces to brainstorm the moment the sources do not
  resolve a load-bearing decision — the same discipline tdd uses.
- The grounding-check agent moved brainstorm/agents/ -> specify/agents/
  (no-orphan-agents: it lives under its dispatcher), refs repointed.
- boss/SKILL.md: Entry-path reflection is now three-way (tdd / specify /
  brainstorm). specify dispatches autonomously (bounded, no interview)
  and pauses at its user-review gate; only a fresh brainstorm cycle
  stays a pre-dispatch bounce-back.
- pipeline.md, README, profile-schema, the profile template, and the
  migration layout updated so every pipeline rendering agrees; specify
  is a CORE node (not opt-in, unlike tdd) carrying gates: [planner].

Design alternative rejected: parallel sibling skills sharing a
docs/spec-production.md (extract-to-doc). Chosen extract-and-chain
instead — the shared surface is ~70%, so a shared doc would either
become the skill body or drift; chaining keeps one executed home for the
gates.

Verification (prose repo, no test suite): the spec's internal-
consistency grep suite (no two-path drift, no direct brainstorm->planner
edge, specify referenced in every rendering, grounding-check single home
under specify, specify structural completeness) all green. Orchestrator
inspection additionally fixed two dead step-refs the plan under-scoped
(a "(Step 4)" lift-validation pointer and a "Skipping Step 7
self-review" red flag, both pointing at steps brainstorm no longer has)
and corrected six pre-existing brainstorm->planner renderings in
pipeline.md and tdd that predated this cycle.

Known follow-ups (non-blocking): the committed spec writes
`skills/specify/` in places (typo; skill dirs are repo-top-level) — to
be corrected separately. The grounding-check hard-gate was degenerate
for this very cycle (this repo has no profile and no test suite); the
skip is documented in the spec and the session.
This commit is contained in:
2026-06-04 23:11:07 +02:00
parent d4630a538d
commit 4f83305525
10 changed files with 575 additions and 381 deletions
+3 -2
View File
@@ -18,12 +18,13 @@ The pipeline skills, each with the agents it primarily dispatches:
| Skill | Trigger | Output | Mandatory? |
|-------|---------|--------|------------|
| `brainstorm` | New cycle starting | spec under the configured spec dir | Hard-gate before plan |
| `brainstorm` | New cycle with an open design | ratified design handed to `specify` (writes no spec itself) | Optional discovery front-end |
| `specify` | Design settled in sources, or handed over by `brainstorm` | spec under the configured spec dir | Hard-gate before plan |
| `planner` | New iteration within an open cycle | plan under the configured plan dir | Hard-gate before implement |
| `implement` | Plan exists | code + tests, uncommitted in working tree | Standard iteration path |
| `audit` | Cycle closing OR baseline drift suspected | drift report + regression report | Mandatory at cycle close |
| `debug` | Bug observed | RED test in working tree + cause analysis | Mandatory RED-first for any bug |
| `tdd` | Test-specifiable feature / issue (alternative to `brainstorm`) | RED executable-spec in working tree → `implement` mini-mode | Opt-in entry path; bounces to `brainstorm` on a design fork |
| `tdd` | Test-specifiable feature / issue (third entry path, alongside `brainstorm` and `specify`) | RED executable-spec in working tree → `implement` mini-mode | Opt-in entry path; bounces to `brainstorm` on a design fork |
| `fieldtest` | Orchestrator-dispatched post-audit | example fixtures + friction spec | Per-cycle optional; milestone fieldtest is the closing gate for a surface-touching milestone |
| `docwriter` | API surface stable across N cycles | rustdoc / docstring sweep | Optional |
| `boss` | User types `/boss` | autonomous-orchestrator session — dispatches the other skills until done-state or bounce-back | User-invoked, never auto-dispatched |
+56 -48
View File
@@ -93,7 +93,8 @@ back to the user.
Pipeline:
```
brainstorm → planner → implement → audit → fieldtest
brainstorm → specify → planner → implement → audit → fieldtest
specify → planner (design settled in sources, no discovery)
+
debug (bug-triggered)
+
@@ -109,52 +110,56 @@ new feature work with no spec or plan yet, run the **Entry-path
reflection** below before dispatching anything. Read each skill's
`SKILL.md` trigger section if unsure.
**Entry-path reflection (feature work).** When the profile enables
the `tdd` phase, `brainstorm` and `tdd` are two **co-equal** entry
paths for new feature work — neither is the default, and the choice
is made by reflection every time, not by habit. Before dispatching
either, decide which fits the item in hand and record the one-line
verdict ("test-specifiable → `tdd`" / "design fork → `brainstorm`")
in the loop. The discriminator is the **design line**, not a
preference:
**Entry-path reflection (feature work).** When the profile enables the
`tdd` phase, there are **three** entry paths for new feature work, and
the choice is made by reflection every time, not by habit. Before
dispatching, decide which fits the item in hand and record the one-line
verdict ("test-specifiable → `tdd`" / "design settled → `specify`" /
"design fork → `brainstorm`") in the loop. The discriminator is the
**design line**:
- The item's desired behaviour can be pinned by one honest minimal
assertion — "calling X with Y returns Z", a backlog `feature`
issue whose body fixes one observable behaviour — then it is
**test-specifiable** and `tdd` owns it. Dispatch `tdd`
autonomously, the same way a bug issue is dispatched to `debug`:
it authors a RED executable-spec and hands the GREEN side to
`implement` mini-mode. This is **not** a new-cycle bounce-back —
the test is the spec; no `brainstorm` runs to begin.
- Writing that one assertion would force a choice between two or
three plausible behaviours with real trade-offs — a genuine design
fork — then the work needs a prose spec the user approves, and
`brainstorm` owns it. Starting a new cycle through `brainstorm` is
itself a bounce-back per §"Direction freedom" trigger 4: green-light
the cycle (and the session shape) with the user first; only then
does `brainstorm` get dispatched.
assertion — "calling X with Y returns Z" — then it is
**test-specifiable** and `tdd` owns it. Dispatch `tdd` autonomously,
the same way a bug issue is dispatched to `debug`.
- The sources resolve every load-bearing design decision — an
exhaustive issue body, a long in-context discussion — then the design
is **settled** and `specify` owns it. Dispatch `specify`
autonomously: it is bounded (no interview), produces the spec through
all the gates, and pauses only at its own user-review gate (a
problem-state notify, not a pre-dispatch checkpoint).
- Writing the spec would force a choice between two or three plausible
designs with real trade-offs — a genuine design fork — then discovery
must resolve it first, and `brainstorm` owns it. Starting a fresh
`brainstorm` cycle is itself a bounce-back per §"Direction freedom"
trigger 4: green-light the cycle (and the session shape) with the
user first; only then does `brainstorm` get dispatched.
The asymmetry in autonomy — a `tdd` dispatch proceeds, a fresh
`brainstorm` cycle bounces back — is **not** a ranking of the two
skills. It is a consequence of context budget: a fresh `brainstorm`
is high-context work the orchestrator cannot compact on its own (see
trigger 4), whereas a test-specifiable item is bounded. Do not let
that asymmetry harden into a reflex of routing borderline items to
`brainstorm` "to be safe" — that is the exact bias this reflection
exists to break; apply the design-line test honestly each time. The
one principled tilt is two-sided and lives *inside* the test, not
above it: genuine doubt about whether one assertion can pin the
behaviour *is itself* the design-fork signal, so it resolves to
`brainstorm` — not because `brainstorm` is preferred, but because
unresolved ambiguity is a fork by definition. A `tdd` bounce-back
also fires reactively: if `tdd` later reports the behaviour was not
test-specifiable after all, that escalation routes to `brainstorm`
and — being a new cycle that needs a fresh spec — is a bounce-back
to the user per the same trigger 4.
The asymmetry in autonomy — `tdd` and `specify` dispatch proceed, a
fresh `brainstorm` cycle bounces back — is **not** a ranking of the
skills. It is a consequence of context budget: `tdd` and `specify` are
both bounded (no open Q&A), whereas a fresh `brainstorm` is high-context
discovery the orchestrator cannot compact on its own (see trigger 4).
`specify` dispatched in `/boss` still pauses at its own Step-6
user-review gate to take sign-off — that is a final-sign-off notify, not
a pre-dispatch checkpoint. Do not let the asymmetry harden into a reflex
of routing borderline items to `brainstorm` "to be safe" — that is the
exact bias this reflection exists to break; apply the design-line test
honestly each time. The one principled tilt is two-sided and lives
*inside* the test: genuine doubt about whether the sources (or one
assertion) can pin the design *is itself* the design-fork signal, so it
resolves to `brainstorm` — not because `brainstorm` is preferred, but
because unresolved ambiguity is a fork by definition. A `specify` or
`tdd` bounce-back also fires reactively: if either later reports the
design was not settled / not test-specifiable after all, that escalation
routes to `brainstorm` and — being a new cycle needing a fresh
discovery — is a bounce-back to the user per the same trigger 4.
If the profile does **not** enable the `tdd` phase, `brainstorm` is
the only design entry path and the reflection collapses to it; a new
feature cycle with no spec always bounces back first.
If the profile does **not** enable the `tdd` phase, the reflection is
two-way — `specify` for a settled design, `brainstorm` for an open one.
`specify` is a core node (never profile-gated), so the settled-design
path is always available; only the `tdd` test-specifiable branch is
opt-in.
If the working tree is mid-flight (uncommitted changes left over
from a previous session): inspect first, then resume the right
@@ -327,7 +332,8 @@ actionable ask, not a wrap-up summary.
| "Notify can name the iteration code — user will figure out what it means" | No. The notify text is for the user-as-reader who did not watch the orchestrator work. Iteration codes, crate names, function identifiers, type names — all internal, all banned. |
| "The previous cycle closed cleanly and the next backlog item is obvious — just dispatch `brainstorm` and keep going" | No. Starting a new cycle is itself a bounce-back. A fresh `brainstorm` is high-context work, and the orchestrator cannot compact its own context — only the user can decide whether the next cycle wants a fresh session or a continuation of this one. The "obviousness" of the candidate is irrelevant; the *cross-cycle hop* is the checkpoint, not the topic choice. |
| "It's the same broad area as the cycle I just closed, that's not really a new cycle" | If there is no spec file for it yet and it would route through `brainstorm` to get one, it IS a new cycle for this rule's purposes. The rule keys on "needs a fresh spec", not on subjective continuity. |
| "Feature work, so route it to `brainstorm` — that's the safe default" | `brainstorm` and `tdd` are co-equal entry paths on a tdd-enabled profile; neither is the default. Routing a test-specifiable item to `brainstorm` "to be safe" is the exact bias to break — run the Entry-path reflection and pick by the design line. The only tilt toward `brainstorm` is when one honest assertion genuinely cannot pin the behaviour, and that is a design fork, not a default. |
| "Feature work, so route it to `brainstorm` — that's the safe default" | `brainstorm`, `specify`, and `tdd` are co-equal entry paths; none is the default. Routing a settled design to `brainstorm` re-litigates decided choices; routing a test-specifiable item there wastes the test path. Run the Entry-path reflection and pick by the design line. The only tilt toward `brainstorm` is a genuinely unresolved fork — and that is a fork, not a default. |
| "The issue is exhaustive but it's a new cycle, so bounce to the user before `specify`" | `specify` direct-entry is bounded and autonomously dispatchable — it is NOT the high-context `brainstorm` cycle that trigger 4 reserves for the user. Dispatch it; it will pause at its own user-review gate for sign-off. The pre-dispatch bounce is for an *open* design that needs discovery, not for a settled one that needs only production. |
| "`tdd` is opt-in / profile-gated, so it's the secondary skill" | Profile-gating is about whether the path is *available*, not about rank. Once enabled, the choice between the two is decided by fit per item, reflected on each time — not by treating `brainstorm` as primary and `tdd` as the exception. |
## Red Flags — STOP
@@ -338,7 +344,7 @@ actionable ask, not a wrap-up summary.
- About to send a notify that names a crate, an iteration code, or an agent.
- About to bounce back at every iteration boundary "just to be safe" — that's reactive deference, not direction freedom.
- About to dispatch `brainstorm` on a backlog issue that does not yet have a spec file, without first bouncing back to the user. New cycles never start autonomously.
- About to route feature work to `brainstorm` without running the Entry-path reflection — defaulting to it because it "feels safer" than `tdd`, rather than applying the design-line test. On a tdd-enabled profile the two are co-equal; the choice is reflected on each time.
- About to route feature work to `brainstorm` without running the Entry-path reflection — defaulting to it because it "feels safer" than `specify` or `tdd`, rather than applying the design-line test. The three are co-equal; the choice is reflected on each time. Routing a *settled* design to `brainstorm` (re-litigating decided choices) is as much a failure as skipping discovery on an open one.
## Cross-references
@@ -356,6 +362,8 @@ actionable ask, not a wrap-up summary.
- **Glossary write-rule:** `../docs/glossary-convention.md`
record-reality discipline for the only autonomous glossary writer.
- **Downstream skills dispatched:** `../brainstorm`,
`../planner`, `../implement`, `../audit`, `../fieldtest`,
`../debug`, `../tdd` (test-specifiable feature, profile-gated;
autonomously dispatchable like `../debug`), `../docwriter`.
`../specify` (spec-production core; autonomously dispatchable for a
settled design), `../planner`, `../implement`, `../audit`,
`../fieldtest`, `../debug`, `../tdd` (test-specifiable feature,
profile-gated; autonomously dispatchable like `../debug`),
`../docwriter`.
+72 -303
View File
@@ -1,6 +1,6 @@
---
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.
description: Use when a new cycle is starting and the design is NOT yet settled — gathers requirements, explores 2-3 approaches with trade-offs, presents a sectioned design with user approval, then hands the ratified design to the specify skill to produce the spec. 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 spec generator
@@ -9,14 +9,20 @@ description: Use when a new cycle is starting — gathers requirements, explores
## 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.
Discovery is where the orchestrator does the *deciding* work
surfacing requirements, exploring approaches, and ratifying a design
with the user. It is the front-end that resolves 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 mode the orchestrator discipline exists
to prevent.
It produces specs under the project's `paths.spec_dir`.
`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 `paths.spec_dir`, runs
the gates, and takes user sign-off. When the design is *already*
settled in the sources, `brainstorm` is skipped entirely and the work
enters through `specify` directly.
## When to Use / Skipping
@@ -28,37 +34,28 @@ Triggers:
- A cycle-scope spec is missing for an existing line of
work and one is needed retroactively.
**Skipping is permitted only** for:
**Skip `brainstorm` (enter through the named alternative) for:**
- A bug-fix iteration (use `debug` directly).
- A test-specifiable feature, on a project whose profile
enables the `tdd` phase (use `tdd` directly — the RED
executable-spec is the spec, no prose spec needed). The
boundary is the design line: the moment one honest minimal
assertion cannot pin the behaviour without choosing between
plausible designs, `tdd` bounces back here.
- A tidy iteration (use `audit` directly).
- A trivial mechanical edit (per the project's CLAUDE.md
"trivial mechanical edits" carve-out).
- A design already settled in the sources — an exhaustive issue, a
long in-context discussion, settled design docs. Use `specify`
directly: discovery would only re-litigate decisions the sources
already made.
- A test-specifiable feature, on a profile that enables `tdd` — use
`tdd` directly.
- A bug-fix iteration — use `debug` directly.
- A tidy iteration use `audit` directly.
- A trivial mechanical edit per the project's CLAUDE.md carve-out.
**Skipping is not permitted** for:
**Do not skip `brainstorm`** when the design is genuinely open:
- 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.
- A user 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 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 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 Process
@@ -76,7 +73,7 @@ Before asking any clarifying questions:
`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).
flagged for lift-time validation when `specify` writes the spec.
- `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,
@@ -117,54 +114,7 @@ approach gets:
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
### Step 4 — Present design in sections
Scale each section to its complexity (a few sentences if
straightforward, up to 200-300 words if nuanced). Cover:
@@ -175,202 +125,43 @@ straightforward, up to 200-300 words if nuanced). Cover:
- 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.
The design you present here is conceptual — the architecture,
components, data flow, error handling, and testing strategy the cycle
commits to. The concrete user-facing code and the before → after
implementation shapes are produced downstream, when `specify`
materialises this ratified design into the spec (and applies the
acceptance criterion against that worked code). Your job here is to get
the *design decision* right and ratified, not to write the artefact.
Ask after each section whether it looks right. Be ready to
revisit earlier sections if a later one surfaces a
contradiction.
### Step 6Write the spec
### Step 5Hand off to `specify`
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).
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`.
Structure:
Hand off carries the **ratified design narrative**, in-context (same
orchestrator context — no intermediate artefact):
```markdown
# <Title> — Design Spec
- the approach chosen and why
- the constraints and invariants surfaced in Q&A
- the design sections the user ratified (Step 4)
- the iteration scope ("the first iteration covers section X+Y")
**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.** Extract every fenced code block
from the spec and run it through the `spec_validation` gate
defined in `docs/profile-schema.md` (which owns the
parser-invocation protocol, the noted no-parser skip, the
malformed-entry failure, and the no-op when the profile
declares no `spec_validation`). A parse failure here 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 into the brainstorm chat: a visible trace attests
the gate fired; its absence means it was skipped.
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 — the fields `spec_path` and `iteration_scope`,
defined authoritatively under **Carrier contract** in
`agents/grounding-check.md` (note `spec_path` is an *absolute*
path). That table is the single source for those fields; it is
deliberately not restated here, so the two files cannot drift.
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")
`specify` reads this narrative as its source, applies the
acceptance criterion, writes the spec, runs the parse and
grounding-check gates, takes user sign-off, and hands off to `planner`.
The production gates live there, not here.
## 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) |
| user → `brainstorm` | new cycle request with a genuinely open design |
| `brainstorm``specify` (Step 5) | ratified design narrative (approach, constraints, ratified sections, iteration scope) — in-context; no spec file written |
## Common Rationalisations
@@ -382,10 +173,6 @@ Hand off carries:
| "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
@@ -393,42 +180,24 @@ Hand off carries:
- "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.
- **Alternative entry path / bounce-back source:**
`../tdd/SKILL.md` — on profiles that enable it, a
test-specifiable feature enters through `tdd` instead of
here; `tdd` bounces the work back to `brainstorm` the moment
the behaviour stops being test-specifiable (a genuine design
fork). Such a bounce-back arrives as a normal cycle request.
- **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
- **Output target:** `../specify/SKILL.md` the only valid next
skill. `brainstorm` hands the ratified design to `specify`, which
produces the spec and gates `planner`. There is no direct
`brainstorm → planner` edge any more.
- **Alternative entry path / bounce-back source:** `../tdd/SKILL.md`
a test-specifiable feature enters through `tdd` instead of here;
`tdd` bounces back the moment the behaviour stops being
test-specifiable. `../specify/SKILL.md` likewise bounces back here
when the sources do not resolve a design fork.
- **Ad-hoc dispatch.** The orchestrator MAY ad-hoc dispatch
`../planner/agents/plan-recon.md` during Step 1 when the cycle
enters code territory not recently read; opt-in, 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.
- **Project feature-acceptance criterion:** declared in the project's
`CLAUDE.md` — applied prospectively by `specify` (its Step 2), not
here.
+2
View File
@@ -25,6 +25,8 @@ seven skills follow once the pattern is approved.
├── boss/ (pilot: landed)
│ └── SKILL.md
├── brainstorm/
│ └── SKILL.md
├── specify/
│ ├── SKILL.md
│ └── agents/
│ └── grounding-check.md
+29 -10
View File
@@ -4,10 +4,11 @@
[new cycle] [test-specifiable feature] [bug observed]
| | |
v v v
brainstorm -> plan -> implement debug -> implement (mini)
^ |
| tdd -> implement (mini)
+----(design fork)----------/ (RED executable-spec -> GREEN, like a bug fix)
brainstorm -> specify -> plan -> implement debug -> implement (mini)
^ ^ |
| | tdd -> implement (mini)
| specify -> plan (design settled in sources)
+----(design fork)----------/ (specify/tdd bounce here; RED executable-spec -> GREEN)
(per iteration loop)
|
[cycle close — a loop step, not a milestone close]
@@ -37,7 +38,7 @@
These are two distinct axes, and conflating them is a bug.
- A **cycle** is one round in the pipeline graph above
(`brainstorm → planner → implement → audit → [fieldtest]`).
(`brainstorm → specify → planner → implement → audit → [fieldtest]`).
A cycle close is an internal loop step.
- A **milestone** is a tracker container (Gitea milestone,
GitHub milestone, Linear project — whatever the project's
@@ -85,9 +86,23 @@ close`); no skill performs it automatically.
### brainstorm
Hard-gate before plan. Gathers requirements, explores 2-3
approaches with trade-offs, presents a sectioned design with
user approval, writes the spec to the configured `spec_dir`.
Optional discovery front-end. Gathers requirements, explores 2-3
approaches with trade-offs, presents a sectioned design with user
approval, then hands the ratified design to `specify` (it writes no
spec itself). Skipped when the design is already settled in the
sources — that work enters through `specify` directly.
### specify
Hard-gate before plan — the spec-production core and the carrier of the
"no plan without an approved spec" invariant. Takes a settled design
(directly from sources, or a ratified design handed over by
`brainstorm`), applies the feature-acceptance criterion, writes the
spec to the configured `spec_dir`, runs the parse-every-block and
`grounding-check` gates, and takes user sign-off — with review but no
interview. Bounces to `brainstorm` the moment the sources do not
resolve a load-bearing design decision. A core node, not opt-in
(unlike `tdd`).
### planner
@@ -119,7 +134,7 @@ the GREEN side to the implement skill in mini mode.
### tdd
Opt-in alternative to the `brainstorm → planner` design entry,
Opt-in alternative to the `brainstorm → specify → planner` design entry,
for work whose desired behaviour is test-specifiable — expressible
as one failing test. RED-first: the `tdd-author` agent turns a
description or issue into a single minimal, autonomous RED
@@ -172,7 +187,11 @@ Reviewer agents have role-specific states:
Skipping is codified per skill, not ad hoc. Each `SKILL.md`
documents what the skill skips and under what conditions:
- `brainstorm` is never skipped at cycle start.
- `specify` is never skipped at cycle start — it is the spec-production
gate before `planner`. `brainstorm` is the *optional* discovery stage
before it: skipped when the design is already settled in the sources
(the work enters through `specify` directly), run when a load-bearing
decision is still open.
- `planner` is never skipped at iteration start, except for
the bug-driven `debug → implement (mini)` side path.
- `implement` is the iteration body; not skippable.
+14 -5
View File
@@ -9,7 +9,7 @@ lowercase snake_case. Lists are YAML sequences.
| Key | Type | Default | Description |
|---------------------|--------|------------------------|-------------|
| `spec_dir` | string | `docs/specs` | Where the brainstorm skill writes specs. |
| `spec_dir` | string | `docs/specs` | Where the specify skill writes specs. |
| `plan_dir` | string | `docs/plans` | Where the planner skill writes plans. |
| `glossary` | string | (unset) | Canonical-nomenclature file (optional). If set, it is standing reading for every role — no separate `standing_reading.always` entry is needed; unset is a documented no-op. See `glossary-convention.md`. |
| `design_ledger` | string | `docs/design/INDEX.md` | Canonical specification index (optional — projects without a design ledger can omit). |
@@ -188,7 +188,10 @@ Per-phase configuration. Each phase has its own sub-map.
```yaml
pipeline:
brainstorm:
gates: [planner] # planner cannot start until this has run
gates: [specify] # optional discovery; hands ratified design to specify
optional: true # skipped when the design is settled in the sources
specify:
gates: [planner] # core node — planner cannot start until the spec is approved
planner:
gates: [implement]
implement: {} # standard
@@ -207,6 +210,7 @@ pipeline:
debug:
trigger: bug # observable misbehaviour
red_first: true # RED test before any fix
# specify above is a CORE node (always present); tdd below is opt-in.
tdd: # opt-in: omit the key to disable the entry path
trigger: test_specifiable_feature # behaviour expressible as one failing test
red_first: true # RED executable-spec before any implementation
@@ -217,8 +221,12 @@ pipeline:
Phases not listed are disabled for the project. A project that
does not want a `fieldtest` phase simply omits the key. `tdd` is
opt-in the same way: a profile that omits it keeps
`brainstorm → planner` as the only design entry path.
opt-in the same way. `specify`, by contrast, is a **core** node — it
is the spec-production gate before `planner` on every design path,
reachable directly from settled sources or via the optional
`brainstorm` discovery stage. `tdd` opt-in only adds the
test-specifiable bypass; with `tdd` omitted, the design entry paths
are `brainstorm → specify → planner` and `specify → planner`.
## Example: minimal profile
@@ -247,7 +255,8 @@ git:
close_marker: "closes #N"
pipeline:
brainstorm: { gates: [planner] }
brainstorm: { gates: [specify], optional: true }
specify: { gates: [planner] }
planner: { gates: [implement] }
implement: {}
audit: { mandatory_at: cycle_close }
+380
View File
@@ -0,0 +1,380 @@
---
name: specify
description: Use when the design is already settled — a long in-context design discussion, an exhaustive tracker issue, or a ratified design handed over by brainstorm — and a spec must be produced from those sources with review but without an interview. The spec-production core: applies the feature-acceptance criterion, writes the spec under paths.spec_dir, runs the parse and grounding-check gates, takes user sign-off, hands off to planner. Bounces to brainstorm the moment the sources do not resolve a load-bearing design decision. Co-equal third entry path alongside brainstorm and tdd.
---
# specify — spec-production entry path
> **Violating the letter of these rules is violating the spirit.**
## Overview
`specify` is where a settled design becomes an approved spec. It
takes **given sources** — a long in-context design discussion, an
exhaustive tracker issue, settled design docs, or a ratified design
narrative handed over by `brainstorm` — and produces the spec the
planner consumes: with review, but **without an interview**.
It is the **sole home of the spec-production gates**: the
feature-acceptance criterion, the write-spec step, the
parse-every-block self-review, the `grounding-check` hard-gate, and
the user-review gate. Whichever way design work enters — fresh
through `brainstorm`'s discovery, or directly from sources that
already resolve the design — it passes through `specify` to become a
spec. `specify` carries the universal invariant **no plan without an
approved spec**.
`specify` is the *producing* half of a deliberate split. `brainstorm`
owns *deciding* — interview, approaches, ratification. `specify` owns
*producing* — rendering that decision into the canonical artefact and
clearing the gates. The split is the toolchain's deepest discipline
applied one level up: `tdd → implement` and `debug → implement` split
RED from GREEN across two dispatches so the spec stays honest;
`specify` splits deciding from producing so the producing phase reads
the decision as a *source* rather than making it inline.
This skill is **not** opt-in. Unlike `tdd` (a profile-gated bypass),
`specify` is a core pipeline node: it is the gate before `planner` on
every design path that is not a bug fix or a test-specifiable feature.
## When to Use / Skipping
Triggers:
- The design is settled in the sources and a spec must be written:
an exhaustive issue body, a long in-context design discussion, or
a ratified design `brainstorm` just handed over.
- A cycle-scope spec is missing for settled work and one is needed.
**Use the named alternative instead for:**
- A genuine design fork — the sources do **not** resolve a
load-bearing decision. Use `brainstorm` (its discovery is what
resolves the fork). `specify` itself bounces here the moment it
detects this (see The Iron Law and Step 1.5).
- A test-specifiable feature, on a profile that enables `tdd` — the
RED executable-spec is the spec. Use `tdd` directly.
- An observed bug — use `debug` directly (RED-first).
- A tidy iteration — use `audit` directly.
- A trivial mechanical edit — per the project's CLAUDE.md carve-out.
**Skipping a gate is never permitted.** The interview is `brainstorm`'s,
and its absence here is the whole point — but the *production gates*
(criterion, parse-every-block, grounding-check, user-review) are
non-negotiable regardless of how the work entered. "The issue looks
exhaustive, skip the grounding-check" is the reactive-deference failure
this skill must not reintroduce.
## The Iron Law
```
THE SOURCES MUST RESOLVE EVERY LOAD-BEARING DESIGN DECISION BEFORE THE SPEC IS WRITTEN.
IF WRITING THE SPEC FORCES A CHOICE BETWEEN PLAUSIBLE DESIGNS THE SOURCES DO NOT RESOLVE,
STOP AND BOUNCE TO brainstorm. DO NOT SILENTLY PICK ONE.
THE PRODUCTION GATES — ACCEPTANCE CRITERION, PARSE-EVERY-BLOCK, GROUNDING-CHECK, USER-REVIEW —
ARE NON-NEGOTIABLE REGARDLESS OF ENTRY PATH.
NO PLAN, SCAFFOLDING, OR DOWNSTREAM SKILL UNTIL THE SPEC HAS BEEN PRESENTED AND THE USER HAS APPROVED IT.
```
Every clause is non-negotiable. The precondition gate is what makes
the no-interview path legitimate rather than merely convenient: it is
the honest fork-check that `tdd`'s "is this test-specifiable?" is for
test work.
## The Process
### Step 1 — Explore / re-ground context
Before producing anything, establish what the sources actually say:
- **Direct entry** (from sources): read the sources in full — the
tracker issue body, the in-context design discussion, any settled
design docs. This IS the design input. Then `git log -5
--format=full` for the current state of the project.
- **Chain entry** (from `brainstorm`): the ratified design narrative
is already in-context. Re-ground lightly — fresh `git log`, the
files the design touches — rather than re-deriving it.
- If the project has a design ledger under `paths.design_ledger`,
walk to the contracts the work touches. Note any `status:
aspirational` source: its code is a target, not verified fact —
track it for the Step-4 parse gate.
### Step 1.5 — Precondition gate (bounce-back)
Enumerate the **load-bearing design decisions** the spec must encode
— the choices that, decided differently, would change what ships.
For each, ask the honest question:
> Do the sources **resolve** this, or am I about to **pick** it
> myself?
If every load-bearing decision is resolved by the sources, proceed to
Step 2. If even one is unresolved — the sources leave a genuine fork
between plausible designs with real trade-offs — **STOP and bounce to
`brainstorm`** (see Error handling / The Bounce-Back). Do not silently
pick one and bake it into the spec; a guessed design ratified into a
spec is harder to dislodge than an open question, and it is exactly
the reactive-deference failure the gate exists to prevent.
Genuine doubt about whether the sources resolve a decision *is itself*
the fork signal — it resolves to a bounce, not to a guess.
### Step 2 — 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 declares no 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 the
unfalsifiable hand-wave the criterion exists to prevent: write the
code the user would write, then judge whether it is what the criterion
demands. For an infrastructure cycle with **no** user surface there is
still concrete code: show the code the cycle *delivers* — frequently a
test fixture whose correct behaviour is rejection — plus a *minimal,
honest* slice of the north-star program the infrastructure serves. "No
surface so no code to show" is the rationalisation to refuse.
**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 `status: aspirational` source, per Step 1), it carries no
validation by default. Treat it as the spec's most suspect bytes: it
must clear the Step-4 parse-every-block gate before PASS.
### Step 3 — 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.
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-2 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. The before → after implementation
shape (struct / signature / match-arm) for each load-bearing change
follows as an explicitly secondary subsection, never first. Prose may
*explain* code, never *replace* it. Exact bytes / line-numbers remain
the planner's job — the spec owns the *shape*, shown.
### Step 4 — 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 read two ways? 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.
6. **Parse-every-block gate.** Extract every fenced code block and run
it through the `spec_validation` gate defined in
`docs/profile-schema.md` (which owns the parser-invocation
protocol, the no-parser skip, the malformed-entry failure, and the
no-op when the profile declares no `spec_validation`). A parse
failure is a self-review failure — fix the spec; do not pass
unparsed bytes downstream. Paste the parse-trace into the chat: a
visible trace attests the gate fired; its absence means it was
skipped.
Fix issues inline.
### Step 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, and for each
searches the workspace for a currently-green test that ratifies it.
Dispatch carrier — the fields `spec_path` and `iteration_scope`,
defined authoritatively under **Carrier contract** in
`agents/grounding-check.md` (note `spec_path` is an *absolute* path).
That table is the single source for those fields; it is deliberately
not restated here, so the two files cannot drift.
The agent returns `PASS` / `BLOCK` / `INFRA_ERROR`. Interpretation:
| Agent status | Orchestrator action |
|--------------|---------------------|
| `PASS` | Proceed to Step 6. The report goes into the 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 and proceed to Step 6. |
| `INFRA_ERROR` | Abort. 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, NOT `git rm`; never committed).
2. Open a backlog issue (via the project's issue-tracker create
command) pointing forward to a future re-design. Include:
- **Title:** one-line identity of the deferred work
- **Label:** matching the project's vocabulary (`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 needs its own spec on resumption
(multi-iteration, cross-subsystem), file it as a **milestone
container** instead of a single issue.
3. Tell the user the spec was retired and which backlog entry was
filed. No commit is needed — the issue tracker is the live store.
After the failure-mode procedure runs, the session ENDS. There is no
Step 6, no Step 7. The idea is parked until the dependency ships.
**Re-dispatch on any post-PASS edit.** The PASS report is bound to the
exact bytes of the spec at dispatch time. Any subsequent edit — polish,
a user-requested change, a wording tighten — invalidates the PASS
report and requires a fresh dispatch of `grounding-check` before the
Step-6 sign-off and commit. Step 5 is the *last* step that touches the
spec file; nothing slips between it and the commit.
### Step 6 — 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 4 AND re-dispatch Step 5**
(the previous PASS report no longer covers the edited bytes), then
return here. Only proceed after approval AND a fresh Step 5 PASS.
The orchestrator commits the approved spec after sign-off (suggested
commit subject: `spec: <cycle> <topic>`). The skill does not perform
the commit itself.
**In `/boss` (autonomous):** `specify` is dispatched autonomously —
it is bounded (no interview). It runs the criterion, parse, and
grounding-check gates without a checkpoint, then **pauses here** as a
problem-state notify ("spec X ready, please sign off"). This is the
final sign-off pause, not a pre-dispatch checkpoint — the distinction
from `brainstorm`, which `/boss` bounces *before* dispatch.
### Step 7 — Hand off to `planner`
The terminal state of `specify` is invoking `planner`. NO other skill
is invoked from `specify`. 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")
## The Bounce-Back
`specify` returns to `brainstorm` whenever the precondition fails — the
sources do not resolve a load-bearing design decision (Step 1.5), or a
`grounding-check` `BLOCK` reveals an unratified mechanism the user does
not override (Step 5 failure-mode routes to a re-design). On a
precondition bounce:
1. Nothing was written yet (the gate fires *before* Step 3), so there
is no working-tree artefact to discard.
2. Invoke `brainstorm` with the unresolved design question as the
cycle request. From there the normal `brainstorm → specify →
planner` path runs.
The bounce-back is not a failure of this skill; it is the skill
correctly refusing to ratify an un-chosen design into a spec — the same
discipline `tdd` applies when behaviour is not test-specifiable.
## Handoff Contract
| Direction | Carrier |
|-----------|---------|
| user / issue (design settled) → `specify` | the sources: issue body, in-context design discussion, design docs |
| `brainstorm``specify` | ratified design narrative (approaches chosen, constraints, sections approved) — in-context; brainstorm writes no spec file |
| `specify``grounding-check` (Step 5) | `spec_path` (absolute) + `iteration_scope` |
| `specify``planner` (Step 7, on PASS or overridden BLOCK) | path to spec + iteration scope |
| `specify``brainstorm` (precondition bounce) | the unresolved design question as a cycle request; no spec written |
| `specify` → issue backlog (Step 5, no-override BLOCK) | new issue naming the unratified dependency; spec file deleted from the working tree |
## Common Rationalisations
| Excuse | Reality |
|--------|---------|
| "The issue looks exhaustive — skip the grounding-check / criterion too" | The interview is what `specify` skips, by design. The production gates are not the interview; they are what keeps the spec honest no matter how it entered. Skipping a gate because the sources look thorough is the exact reactive-deference failure this skill must not reintroduce. |
| "There's a small open fork but the sources mostly decide it — I'll pick the rest" | "Mostly decided" with one real fork left is an unresolved design, and a guessed design baked into a spec is harder to dislodge than an open question. That is the bounce-back trigger — stop and go to `brainstorm`. |
| "Genuine doubt whether the sources resolve this — but bouncing feels like overkill" | Doubt about whether the sources resolve a decision *is* the fork signal. It resolves to a bounce, not a guess. The bounce is cheap (nothing is written yet); a wrong guess in a ratified spec is not. |
| "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 acceptance criterion is unjudgeable without the worked code. |
| "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. If a parser is configured for the fence label, run it and paste the trace. |
| "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 attestation no longer covers them. Re-dispatch is cheap. |
| "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. Code lifted from a `status: aspirational` source must clear the Step-4 parse gate like any other block. |
## Red Flags — STOP
- An unresolved design fork silently picked instead of bounced (any flavour)
- "The sources are thorough, skip a gate" thoughts (any flavour)
- 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 chat
- Lifting code verbatim from a `status: aspirational` source without
flagging it for the Step-4 parse gate
- Editing the spec file after a Step 5 PASS without re-dispatching
- Jumping straight from spec to `implement` (must go via `planner`)
- Running an interview here (that is `brainstorm`'s job — if the work
needs one, bounce)
## Cross-references
- **Output target:** `../planner/SKILL.md` — only valid next skill.
- **Discovery front-end / bounce-back target:** `../brainstorm/SKILL.md`
— produces the ratified design `specify` consumes on the chain path,
and reclaims the work when the sources do not resolve a design fork.
- **Sibling fast path:** `../tdd/SKILL.md` — the same
bounce-to-`brainstorm`-on-fork discipline, for test-specifiable work;
its RED executable-spec is the spec, so it skips both `specify` and
`planner`.
- **Agent dispatched:** `agents/grounding-check.md` — dispatched in
Step 5 as a hard-gate. 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 work enters
code territory not recently read; opt-in, not part of the standard
process.
- **Project feature-acceptance criterion:** declared in the project's
`CLAUDE.md`. Applied prospectively in Step 2.
@@ -1,6 +1,6 @@
---
name: grounding-check
description: Read-only grounding-check reviewer for spec drafts. Dispatched by the brainstorm skill in Step 7.5, between linguistic self-review and user-approval. Reads the draft with fresh context, extracts its load-bearing assumptions about current codebase behaviour, and for each one searches the workspace for a currently-green test that ratifies it; also validates the spec's own fenced code blocks against the project's configured parsers. Reports PASS or BLOCK. Does NOT propose fixes, does NOT edit files.
description: Read-only grounding-check reviewer for spec drafts. Dispatched by the specify skill in Step 5, between linguistic self-review and user-approval. Reads the draft with fresh context, extracts its load-bearing assumptions about current codebase behaviour, and for each one searches the workspace for a currently-green test that ratifies it; also validates the spec's own fenced code blocks against the project's configured parsers. Reports PASS or BLOCK. Does NOT propose fixes, does NOT edit files.
tools: Read, Glob, Grep, Bash
---
@@ -18,9 +18,9 @@ recover from — multiple prep-iter band-aids before someone
demands that the spec — not the plan — be corrected at the
root.
This agent is dispatched between the brainstorm's linguistic
This agent is dispatched between specify's linguistic
self-review (Step 7) and user-approval (Step 8). The
brainstorm-driven orchestrator has spent 30+ minutes building
specify-driven orchestrator has spent its budget building
the spec and is biased toward shipping it. You, by contrast,
arrive fresh: no sunk-cost, no investment in the framing.
Your only loyalty is to the question "does the codebase,
@@ -60,9 +60,9 @@ the dispatching skill references it rather than restating it.
| Field | Content |
|-------|---------|
| `spec_path` | absolute path to the spec draft you are checking |
| `iteration_scope` | which sections of the spec are in scope for the imminent first iteration (verbatim from brainstorm) |
| `iteration_scope` | which sections of the spec are in scope for the imminent first iteration (verbatim from specify) |
The controller is the `brainstorm` skill's Step 7.5. You
The controller is the `specify` skill's Step 5. You
receive the carrier inline in the dispatch prompt; do NOT
open the plan directory or any other spec to "fill in" the
carrier.
@@ -202,9 +202,9 @@ down to one iteration.
| Status | Meaning |
|--------|---------|
| `PASS` | All extracted load-bearing assumptions ratified. brainstorm proceeds to Step 8. |
| `BLOCK` | At least one load-bearing assumption is unratified. brainstorm presents the report to the user. |
| `INFRA_ERROR` | The dispatch cannot complete (spec file missing, type-check broken, etc.). brainstorm aborts; orchestrator debugs out-of-band. |
| `PASS` | All extracted load-bearing assumptions ratified. specify proceeds to Step 6. |
| `BLOCK` | At least one load-bearing assumption is unratified. specify presents the report to the user. |
| `INFRA_ERROR` | The dispatch cannot complete (spec file missing, type-check broken, etc.). specify aborts; orchestrator debugs out-of-band. |
There is no `NEEDS_CONTEXT`. The standing reading list is
the full context you get. If you cannot decide, you flag the
+9 -4
View File
@@ -1,6 +1,6 @@
---
name: tdd
description: Use when a feature description or tracker issue has test-specifiable behaviour — the "how it should work" can be pinned as a single failing test. Authors a minimal RED executable-spec and hands the GREEN side to implement mini-mode, exactly as a bug fix is handled. The alternative entry path to brainstorm→planner for test-specifiable work; bounces back to brainstorm the moment the behaviour is not test-specifiable (genuine design forks). Distinct from the per-task TDD the implementer already practices inside implement.
description: Use when a feature description or tracker issue has test-specifiable behaviour — the "how it should work" can be pinned as a single failing test. Authors a minimal RED executable-spec and hands the GREEN side to implement mini-mode, exactly as a bug fix is handled. The alternative entry path to brainstorm→specify→planner for test-specifiable work; bounces back to brainstorm the moment the behaviour is not test-specifiable (genuine design forks). Distinct from the per-task TDD the implementer already practices inside implement.
---
# tdd — executable-spec-first entry path
@@ -11,7 +11,7 @@ description: Use when a feature description or tracker issue has test-specifiabl
For work whose desired behaviour is expressible as a test, the
test *is* the spec. This skill is the alternative to the
`brainstorm → planner` design path: instead of a prose spec the
`brainstorm → specify → planner` design path: instead of a prose spec the
user approves, it produces a single minimal **RED executable-spec**
that says "this is how it should work", then treats that test
exactly like a bug to be fixed — handing the GREEN side to the
@@ -74,7 +74,7 @@ prevent, and it is no less a failure for being dressed as a test.
This skill is an opt-in entry path. A project enables it by
listing a `tdd` phase in its profile `pipeline:` block (see
`docs/profile-schema.md`); a profile that omits it keeps
`brainstorm → planner` as the only design entry path.
`brainstorm → specify → planner` as the only design entry path.
## The Iron Law
@@ -153,7 +153,7 @@ orchestrator:
worse than no test).
2. Invokes `brainstorm` with the design question the agent
surfaced as the cycle request. From there the normal
`brainstorm → planner → implement` path runs.
`brainstorm → specify → planner → implement` path runs.
The bounce-back is not a failure of this skill; it is the skill
correctly refusing to ratify an un-chosen design into a test.
@@ -211,6 +211,11 @@ iteration and gets queued for a separate one.
This is the same mini-mode handoff `../debug/SKILL.md` uses.
- **Bounce-back target:** `../brainstorm/SKILL.md` — reclaims the
work when the behaviour is not test-specifiable.
- **Sibling fast path:** `../specify/SKILL.md` — the other bounded
entry path that shares this skill's bounce-to-`brainstorm`-on-fork
discipline. Where `tdd` owns work whose behaviour one assertion can
pin, `specify` owns work whose design the sources already resolve;
both fall back to `brainstorm` when their precondition fails.
- **Sibling RED-first skill:** `../debug/SKILL.md` — same two-stage
RED→GREEN shape, but triggered by an observed bug rather than a
new-behaviour description.
+2 -1
View File
@@ -67,7 +67,8 @@ notifications:
# command: "" # e.g. "~/.claude/notify.sh"; boss falls back to chat if empty
pipeline:
brainstorm: { gates: [planner] }
brainstorm: { gates: [specify], optional: true } # optional discovery; skipped when design is settled
specify: { gates: [planner] } # core node: spec-production gate before planner
planner: { gates: [implement] }
implement: {}
audit: { mandatory_at: cycle_close }