d4630a538d
Bite-sized plan for the specify spec-production entry path: create specify/SKILL.md (full body inlined), move the grounding-check agent to its new dispatcher, shrink brainstorm to discovery, and propagate the three-path topology across boss, tdd, pipeline.md, README, profile-schema, the profile template, and the migration layout. Verification is grep-based internal-consistency checks (prose repo, no test suite).
1124 lines
56 KiB
Markdown
1124 lines
56 KiB
Markdown
# `specify` Spec-Production Entry Path — Implementation Plan
|
||
|
||
> **Parent spec:** `docs/specs/2026-06-04-specify-entry-path-design.md`
|
||
>
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: use the
|
||
> `implement` skill to run this plan. Steps use `- [ ]`
|
||
> checkboxes for tracking.
|
||
|
||
**Goal:** Add a `specify` skill as the sole spec-production gate before
|
||
`planner`, reachable directly from settled sources or via `brainstorm`
|
||
(now optional discovery), and propagate the three-path topology across
|
||
every pipeline rendering.
|
||
|
||
**Architecture:** `specify/SKILL.md` (new) owns the production steps that
|
||
move out of `brainstorm` (acceptance criterion, write-spec, self-review,
|
||
grounding-check, user-review, planner-handoff), preceded by a precondition
|
||
gate that bounces to `brainstorm` on an unresolved design fork. The
|
||
`grounding-check` agent moves with its dispatcher. `brainstorm` shrinks to
|
||
discovery and hands a ratified design to `specify`. `boss`, `tdd`,
|
||
`docs/pipeline.md`, `README.md`, `docs/profile-schema.md`,
|
||
`templates/project-profile.yml`, and `docs/migration.md` update to agree.
|
||
|
||
**Tech Stack:** Prose / Markdown skill plugin. No build, no executable
|
||
tests — verification is grep-based internal-consistency checks plus
|
||
Markdown structural review.
|
||
|
||
---
|
||
|
||
**Files this plan creates or modifies:**
|
||
|
||
- Create: `specify/SKILL.md` — the spec-production core skill
|
||
- Move: `brainstorm/agents/grounding-check.md` → `specify/agents/grounding-check.md` (with internal brainstorm→specify reference updates)
|
||
- Modify: `brainstorm/SKILL.md` — shrink to discovery; terminal → specify
|
||
- Modify: `boss/SKILL.md` — three-way entry-path reflection; pipeline diagram; rationalisations; red flags; cross-refs
|
||
- Modify: `tdd/SKILL.md:201-218` — cross-references gain specify sibling
|
||
- Modify: `docs/pipeline.md` — ASCII graph; add `### specify` phase; trim `### brainstorm`; skip rules
|
||
- Modify: `README.md:19-29` — skill table: add specify row, flip brainstorm mandatory cell
|
||
- Modify: `docs/profile-schema.md` — pipeline yaml ×2 (gates move, specify core node); prose; spec_dir desc
|
||
- Modify: `templates/project-profile.yml:69-79` — pipeline yaml (gates move)
|
||
- Modify: `docs/migration.md:27-30` — agent tree: grounding-check under specify
|
||
|
||
**Note on paths:** skill directories are repo-top-level (`brainstorm/`,
|
||
`tdd/`, `boss/`), NOT under a `skills/` subtree. The spec's `skills/specify/`
|
||
naming is a typo; the canonical path is `specify/` at repo top level. (Spec
|
||
text gets a separate trivial correction outside this plan.)
|
||
|
||
---
|
||
|
||
### Task 1: Create `specify/SKILL.md`
|
||
|
||
**Files:**
|
||
- Create: `specify/SKILL.md`
|
||
|
||
- [ ] **Step 1: Write the new skill file**
|
||
|
||
Create `specify/SKILL.md` with exactly this content:
|
||
|
||
````markdown
|
||
---
|
||
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.
|
||
````
|
||
|
||
- [ ] **Step 2: Verify the file follows the skill template and renders**
|
||
|
||
Run: `grep -nE '^## (Overview|When to Use|The Iron Law|The Process|Handoff Contract|Common Rationalisations|Red Flags|Cross-references)' specify/SKILL.md`
|
||
Expected: all eight section headers present, in order.
|
||
|
||
Run: `grep -c 'Step 1.5' specify/SKILL.md`
|
||
Expected: ≥1 (the precondition gate is present).
|
||
|
||
---
|
||
|
||
### Task 2: Move the `grounding-check` agent to its new dispatcher
|
||
|
||
**Files:**
|
||
- Move: `brainstorm/agents/grounding-check.md` → `specify/agents/grounding-check.md`
|
||
|
||
- [ ] **Step 1: Move the file with git**
|
||
|
||
Run: `git mv brainstorm/agents/grounding-check.md specify/agents/grounding-check.md`
|
||
Expected: exit 0; `brainstorm/agents/` now empty (and removed by git), `specify/agents/grounding-check.md` tracked.
|
||
|
||
- [ ] **Step 2: Repoint the agent's internal references from brainstorm to specify**
|
||
|
||
Apply these exact edits to `specify/agents/grounding-check.md`:
|
||
|
||
Edit 1 — frontmatter description (line ~3), replace:
|
||
`Dispatched by the brainstorm skill in Step 7.5, between linguistic self-review and user-approval.`
|
||
with:
|
||
`Dispatched by the specify skill in Step 5, between linguistic self-review and user-approval.`
|
||
|
||
Edit 2 — replace (line ~21-24, the "This agent is dispatched between…" sentence):
|
||
`This agent is dispatched between the brainstorm's linguistic`
|
||
with:
|
||
`This agent is dispatched between specify's linguistic`
|
||
|
||
Edit 3 — replace the next occurrence (line ~23):
|
||
`brainstorm-driven orchestrator has spent 30+ minutes building`
|
||
with:
|
||
`specify-driven orchestrator has spent its budget building`
|
||
|
||
Edit 4 — carrier-contract `iteration_scope` row (line ~63), replace:
|
||
`| `iteration_scope` | which sections of the spec are in scope for the imminent first iteration (verbatim from brainstorm) |`
|
||
with:
|
||
`| `iteration_scope` | which sections of the spec are in scope for the imminent first iteration (verbatim from specify) |`
|
||
|
||
Edit 5 — controller line (line ~65), replace:
|
||
`The controller is the `brainstorm` skill's Step 7.5. You`
|
||
with:
|
||
`The controller is the `specify` skill's Step 5. You`
|
||
|
||
Edit 6 — status table rows (lines ~205-207), replace the three cells:
|
||
`| `PASS` | All extracted load-bearing assumptions ratified. brainstorm proceeds to Step 8. |`
|
||
→ `| `PASS` | All extracted load-bearing assumptions ratified. specify proceeds to Step 6. |`
|
||
`| `BLOCK` | At least one load-bearing assumption is unratified. brainstorm presents the report to the user. |`
|
||
→ `| `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.). brainstorm aborts; orchestrator debugs out-of-band. |`
|
||
→ `| `INFRA_ERROR` | The dispatch cannot complete (spec file missing, type-check broken, etc.). specify aborts; orchestrator debugs out-of-band. |`
|
||
|
||
- [ ] **Step 3: Verify no stale brainstorm dispatcher references remain in the agent**
|
||
|
||
Run: `grep -niE 'brainstorm' specify/agents/grounding-check.md`
|
||
Expected: no line that names brainstorm as the *dispatcher* of this agent. (A cross-reference to brainstorm as a sibling discovery skill is acceptable if present; a line asserting brainstorm dispatches/controls this agent is NOT.)
|
||
|
||
Run: `test -d brainstorm/agents && ls brainstorm/agents || echo "brainstorm/agents gone"`
|
||
Expected: `brainstorm/agents` no longer contains grounding-check.md (empty or removed).
|
||
|
||
---
|
||
|
||
### Task 3: Shrink `brainstorm/SKILL.md` to discovery
|
||
|
||
**Files:**
|
||
- Modify: `brainstorm/SKILL.md`
|
||
|
||
Apply the edits below. Use unique-anchor find/replace (not line numbers — earlier edits shift them).
|
||
|
||
- [ ] **Step 1: Reframe the frontmatter description**
|
||
|
||
Replace the `description:` value (line 3):
|
||
`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.`
|
||
with:
|
||
`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.`
|
||
|
||
- [ ] **Step 2: Reframe the Overview**
|
||
|
||
Replace the Overview body (the paragraph block under `## Overview`, from `The spec is where the orchestrator does the design work.` through `It produces specs under the project's` paragraph) with:
|
||
|
||
```markdown
|
||
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.
|
||
|
||
`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.
|
||
```
|
||
|
||
- [ ] **Step 3: Remove the Hard-Gate block**
|
||
|
||
Delete the entire `## The Hard-Gate` section (from the `## The Hard-Gate` header through the paragraph ending `before any plan or code work begins.`, immediately before `## The Process`). The hard-gate now lives in `specify`; `brainstorm` is no longer itself a gate.
|
||
|
||
- [ ] **Step 4: Reframe "When to Use / Skipping" so brainstorm is optional**
|
||
|
||
Under `## When to Use / Skipping`, replace the `**Skipping is permitted only** for:` list and the `**Skipping is not permitted** for:` list with:
|
||
|
||
```markdown
|
||
**Skip `brainstorm` (enter through the named alternative) for:**
|
||
|
||
- A design already settled in the sources — an exhaustive issue, a
|
||
long in-context discussion, settled design docs. Use `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.
|
||
|
||
**Do not skip `brainstorm`** when the design is genuinely open:
|
||
|
||
- 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 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`.
|
||
```
|
||
|
||
- [ ] **Step 5: Remove Step 4 (acceptance criterion — moves to specify)**
|
||
|
||
Delete the entire `### Step 4 — Apply the project's feature-acceptance criterion` section (header through the end of its last paragraph, immediately before `### Step 5 — Present design in sections`). Its content now lives in `specify` Step 2 (Task 1).
|
||
|
||
- [ ] **Step 6: Trim Step 5 to discovery ratification**
|
||
|
||
In `### Step 5 — Present design in sections`, keep the section-presentation and per-section ratification, but remove the spec-production prose. Replace the paragraph that begins `**Concrete code is the headline; the implementation shape is supporting.**` (through `the user-facing program foremost.`) with:
|
||
|
||
```markdown
|
||
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.
|
||
```
|
||
|
||
- [ ] **Step 7: Replace Steps 6–9 with a single hand-off-to-specify step**
|
||
|
||
Delete everything from `### Step 6 — Write the spec` through the end of `### Step 9 — Hand off to `planner`` (i.e. the whole production run: write-spec, self-review, grounding-check, user-review gate, planner hand-off). Replace the entire deleted span with:
|
||
|
||
```markdown
|
||
### Step 6 — Hand off to `specify`
|
||
|
||
The terminal state of `brainstorm` is invoking `specify`. NO spec file
|
||
is written here; NO other skill is invoked; NO direct jump to `planner`
|
||
or `implement`.
|
||
|
||
Hand off carries the **ratified design narrative**, in-context (same
|
||
orchestrator context — no intermediate artefact):
|
||
|
||
- the approach chosen and why
|
||
- the constraints and invariants surfaced in Q&A
|
||
- the design sections the user ratified (Step 5)
|
||
- the iteration scope ("the first iteration covers section X+Y")
|
||
|
||
`specify` reads this narrative as its source, applies the
|
||
acceptance criterion, writes the spec, runs the parse and
|
||
grounding-check gates, takes user sign-off, and hands off to `planner`.
|
||
The production gates live there, not here.
|
||
```
|
||
|
||
- [ ] **Step 8: Update the Handoff Contract table**
|
||
|
||
Replace the entire `## Handoff Contract` table body (the rows between the header row and the next `##` section) with:
|
||
|
||
```markdown
|
||
| Direction | Carrier |
|
||
|-----------|---------|
|
||
| user → `brainstorm` | new cycle request with a genuinely open design |
|
||
| `brainstorm` → `specify` (Step 6) | ratified design narrative (approach, constraints, ratified sections, iteration scope) — in-context; no spec file written |
|
||
```
|
||
|
||
- [ ] **Step 9: Prune production-bound Rationalisations and Red Flags**
|
||
|
||
In `## Common Rationalisations`, delete the rows whose left cell begins with each of these (they bind to the moved production gates):
|
||
- `"Just polishing a wording after PASS, no need to re-dispatch"`
|
||
- `"The shape is clear from the prose, I don't need to paste the code"`
|
||
- `"The block obviously parses — I wrote it carefully"`
|
||
- `"It's in a model doc / the design ledger, so it's canonical"`
|
||
|
||
Keep the discovery-bound rows ("clear vision", "cycle is small", "three approaches", "user is busy", "spec exists from previous cycle", "approaches A,B,C are all bad").
|
||
|
||
In `## Red Flags — STOP`, delete these entries (production-bound):
|
||
- the `A load-bearing change described in prose with no before → after code block…` entry
|
||
- the `A spec carrying a code block whose fence label has a configured spec_validation parser…` entry
|
||
- the `Lifting code verbatim from a status: aspirational source…` entry
|
||
- the `Editing the spec file after a Step 7.5 PASS without re-dispatching` entry
|
||
- the `Jumping straight from spec to implement (must go via planner)` entry
|
||
|
||
Keep the discovery-bound flags ("Skip the spec" thoughts, "One paragraph is enough", "User said it's clear", "2-3 approaches all suck", "Skipping Step 7 self-review", "Inventing a design rationale that's actually about effort").
|
||
|
||
- [ ] **Step 10: Repoint Cross-references**
|
||
|
||
Replace the `## Cross-references` bullets with:
|
||
|
||
```markdown
|
||
- **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` — applied prospectively by `specify` (its Step 2), not
|
||
here.
|
||
```
|
||
|
||
- [ ] **Step 11: Verify brainstorm carries no orphaned production language**
|
||
|
||
Run: `grep -niE 'grounding-check|parse-every-block|Step 7\.5|## The Hard-Gate|Write the spec' brainstorm/SKILL.md`
|
||
Expected: no matches (all production language has moved to specify).
|
||
|
||
Run: `grep -nE 'planner' brainstorm/SKILL.md`
|
||
Expected: only the ad-hoc `plan-recon` reference remains; no line names `planner` as brainstorm's terminal/next skill.
|
||
|
||
Run: `grep -nE 'specify' brainstorm/SKILL.md`
|
||
Expected: ≥3 matches (Overview, Step 6 hand-off, Handoff Contract, Cross-references).
|
||
|
||
---
|
||
|
||
### Task 4: Update `boss/SKILL.md` to the three-way reflection
|
||
|
||
**Files:**
|
||
- Modify: `boss/SKILL.md`
|
||
|
||
- [ ] **Step 1: Insert specify into the pipeline ASCII diagram**
|
||
|
||
In the `### Step 3` pipeline fence, replace:
|
||
```
|
||
brainstorm → planner → implement → audit → fieldtest
|
||
+
|
||
debug (bug-triggered)
|
||
+
|
||
tdd → implement (mini) (test-specifiable feature, if profile enables it)
|
||
+
|
||
docwriter (post-stability)
|
||
```
|
||
with:
|
||
```
|
||
brainstorm → specify → planner → implement → audit → fieldtest
|
||
specify → planner (design settled in sources, no discovery)
|
||
+
|
||
debug (bug-triggered)
|
||
+
|
||
tdd → implement (mini) (test-specifiable feature, if profile enables it)
|
||
+
|
||
docwriter (post-stability)
|
||
```
|
||
|
||
- [ ] **Step 2: Rewrite the Entry-path reflection from two-way to three-way**
|
||
|
||
Replace the `**Entry-path reflection (feature work).**` paragraph and the two bullet points that follow it (the `brainstorm`/`tdd` co-equal pair, through the bullet ending `green-light the cycle (and the session shape) with the user first; only then does `brainstorm` get dispatched.`) with:
|
||
|
||
```markdown
|
||
**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" — 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.
|
||
```
|
||
|
||
- [ ] **Step 3: Rewrite the autonomy-asymmetry paragraph**
|
||
|
||
Replace the paragraph beginning `The asymmetry in autonomy — a `tdd` dispatch proceeds, a fresh `brainstorm` cycle bounces back — is **not** a ranking` (through its end, the sentence ending `is a bounce-back to the user per the same trigger 4.`) with:
|
||
|
||
```markdown
|
||
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.
|
||
```
|
||
|
||
- [ ] **Step 4: Update the `tdd`-only collapse sentence**
|
||
|
||
Replace:
|
||
`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.`
|
||
with:
|
||
`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.`
|
||
|
||
- [ ] **Step 5: Add the specify rationalisation rows**
|
||
|
||
In `## Common Rationalisations`, after the row whose left cell is `"Feature work, so route it to `brainstorm` — that's the safe default"`, update that row's right cell to name three paths and add one new row. Replace the existing row right cell:
|
||
`| "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. |`
|
||
with:
|
||
`| "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. |`
|
||
|
||
Then add this new row immediately after it:
|
||
`| "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. |`
|
||
|
||
- [ ] **Step 6: Update the entry-path Red Flag**
|
||
|
||
Replace the Red Flag entry:
|
||
`- 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.`
|
||
with:
|
||
`- 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.`
|
||
|
||
- [ ] **Step 7: Add specify to the dispatched-skills cross-reference**
|
||
|
||
In `## Cross-references`, in the `**Downstream skills dispatched:**` line, replace:
|
||
`` `../brainstorm`,
|
||
`../planner`, `../implement`, `../audit`, `../fieldtest`,
|
||
`../debug`, `../tdd` (test-specifiable feature, profile-gated;
|
||
autonomously dispatchable like `../debug`), `../docwriter`. ``
|
||
with:
|
||
`` `../brainstorm`,
|
||
`../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`. ``
|
||
|
||
- [ ] **Step 8: Verify boss names three paths consistently**
|
||
|
||
Run: `grep -nE 'three (entry )?paths|specify' boss/SKILL.md`
|
||
Expected: ≥6 matches (diagram, reflection, asymmetry, collapse sentence, rationalisation, red flag, cross-ref).
|
||
|
||
Run: `grep -niE 'two co-equal|two entry paths|brainstorm and tdd are' boss/SKILL.md`
|
||
Expected: no matches (no leftover two-path assertion).
|
||
|
||
---
|
||
|
||
### Task 5: Update `tdd/SKILL.md` cross-references
|
||
|
||
**Files:**
|
||
- Modify: `tdd/SKILL.md:201-218`
|
||
|
||
- [ ] **Step 1: Add specify as a sibling fast path**
|
||
|
||
In `## Cross-references`, after the `**Bounce-back target:** `../brainstorm/SKILL.md`` bullet, insert:
|
||
|
||
```markdown
|
||
- **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.
|
||
```
|
||
|
||
- [ ] **Step 2: Verify**
|
||
|
||
Run: `grep -nE 'specify' tdd/SKILL.md`
|
||
Expected: ≥1 match (the new sibling bullet).
|
||
|
||
---
|
||
|
||
### Task 6: Update `docs/pipeline.md`
|
||
|
||
**Files:**
|
||
- Modify: `docs/pipeline.md`
|
||
|
||
- [ ] **Step 1: Add specify to the top ASCII pipeline graph**
|
||
|
||
In the top fence, replace the line:
|
||
` brainstorm -> plan -> implement debug -> implement (mini)`
|
||
with:
|
||
` brainstorm -> specify -> plan -> implement debug -> implement (mini)`
|
||
|
||
And replace:
|
||
` ^ |`
|
||
` | tdd -> implement (mini)`
|
||
` +----(design fork)----------/ (RED executable-spec -> GREEN, like a bug fix)`
|
||
with:
|
||
` ^ ^ |`
|
||
` | | tdd -> implement (mini)`
|
||
` | specify -> plan (design settled in sources)`
|
||
` +----(design fork)----------/ (specify/tdd bounce here; RED executable-spec -> GREEN)`
|
||
|
||
- [ ] **Step 2: Trim the `### brainstorm` phase description**
|
||
|
||
Replace the `### brainstorm` block body:
|
||
`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`.`
|
||
with:
|
||
`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.`
|
||
|
||
- [ ] **Step 3: Add a `### specify` phase description**
|
||
|
||
Immediately after the `### brainstorm` block (before `### planner`), insert:
|
||
|
||
```markdown
|
||
### 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`).
|
||
```
|
||
|
||
- [ ] **Step 4: Update the skip rules**
|
||
|
||
Replace the bullet:
|
||
`- `brainstorm` is never skipped at cycle start.`
|
||
with:
|
||
`- `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.`
|
||
|
||
- [ ] **Step 5: Verify the four-rendering consistency for pipeline.md**
|
||
|
||
Run: `grep -nE 'brainstorm *-> *specify|specify *-> *plan' docs/pipeline.md`
|
||
Expected: the graph shows brainstorm→specify and a direct specify→plan edge.
|
||
|
||
Run: `grep -nE '^### specify' docs/pipeline.md`
|
||
Expected: 1 match (the new phase block).
|
||
|
||
---
|
||
|
||
### Task 7: Update the `README.md` skill table
|
||
|
||
**Files:**
|
||
- Modify: `README.md:19-29`
|
||
|
||
- [ ] **Step 1: Flip the brainstorm row and add a specify row**
|
||
|
||
Replace the brainstorm table row:
|
||
`| `brainstorm` | New cycle starting | spec under the configured spec dir | Hard-gate before plan |`
|
||
with these two rows (brainstorm reframed, specify added immediately after):
|
||
`| `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 |`
|
||
|
||
- [ ] **Step 2: Reword the tdd row's "alternative to brainstorm" phrasing**
|
||
|
||
Replace the tdd row:
|
||
`| `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 |`
|
||
with:
|
||
`| `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 |`
|
||
|
||
- [ ] **Step 3: Verify**
|
||
|
||
Run: `grep -nE '^\| `specify`' README.md`
|
||
Expected: 1 match (the new row).
|
||
|
||
Run: `grep -nE 'Hard-gate before plan' README.md`
|
||
Expected: now on the `specify` row (and `planner` row), not brainstorm.
|
||
|
||
---
|
||
|
||
### Task 8: Update the profile pipeline yaml (schema + template)
|
||
|
||
**Files:**
|
||
- Modify: `docs/profile-schema.md`
|
||
- Modify: `templates/project-profile.yml:69-79`
|
||
|
||
- [ ] **Step 1: Move `gates: [planner]` to a new specify node in the schema's main pipeline yaml**
|
||
|
||
In `docs/profile-schema.md` `## pipeline` yaml block, replace:
|
||
```yaml
|
||
brainstorm:
|
||
gates: [planner] # planner cannot start until this has run
|
||
```
|
||
with:
|
||
```yaml
|
||
brainstorm:
|
||
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
|
||
```
|
||
|
||
- [ ] **Step 2: Update the tdd opt-in comment to contrast specify as core**
|
||
|
||
In the same yaml block, replace:
|
||
```yaml
|
||
tdd: # opt-in: omit the key to disable the entry path
|
||
```
|
||
with:
|
||
```yaml
|
||
# specify above is a CORE node (always present); tdd below is opt-in.
|
||
tdd: # opt-in: omit the key to disable the entry path
|
||
```
|
||
|
||
- [ ] **Step 3: Update the prose after the pipeline yaml**
|
||
|
||
Replace:
|
||
`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.`
|
||
with:
|
||
`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. `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`.`
|
||
|
||
- [ ] **Step 4: Move `gates: [planner]` in the minimal-profile example**
|
||
|
||
In the `## Example: minimal profile` yaml block, replace:
|
||
```yaml
|
||
brainstorm: { gates: [planner] }
|
||
planner: { gates: [implement] }
|
||
```
|
||
with:
|
||
```yaml
|
||
brainstorm: { gates: [specify], optional: true }
|
||
specify: { gates: [planner] }
|
||
planner: { gates: [implement] }
|
||
```
|
||
|
||
- [ ] **Step 5: Update the `spec_dir` description (brainstorm no longer writes specs)**
|
||
|
||
In the `## paths` table, replace the `spec_dir` row description:
|
||
`| `spec_dir` | string | `docs/specs` | Where the brainstorm skill writes specs. |`
|
||
with:
|
||
`| `spec_dir` | string | `docs/specs` | Where the specify skill writes specs. |`
|
||
|
||
- [ ] **Step 6: Apply the same gates shift to the template**
|
||
|
||
In `templates/project-profile.yml` `pipeline:` block, replace:
|
||
```yaml
|
||
brainstorm: { gates: [planner] }
|
||
planner: { gates: [implement] }
|
||
```
|
||
with:
|
||
```yaml
|
||
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] }
|
||
```
|
||
The commented `# tdd:` line at `:75` already carries `alt_to: brainstorm` — leave it unchanged (tdd still bounces to brainstorm).
|
||
|
||
- [ ] **Step 7: Verify the gates pin moved in all three yaml renderings**
|
||
|
||
Run: `grep -nE 'brainstorm.*gates.*planner|gates: \[planner\]' docs/profile-schema.md templates/project-profile.yml`
|
||
Expected: every `gates: [planner]` now sits on a `specify` node (or the `planner→implement` line); none on `brainstorm`.
|
||
|
||
Run: `grep -nE 'specify' docs/profile-schema.md`
|
||
Expected: ≥4 matches (two yaml nodes, the contrast comment, the prose).
|
||
|
||
---
|
||
|
||
### Task 9: Update the `docs/migration.md` agent tree
|
||
|
||
**Files:**
|
||
- Modify: `docs/migration.md:27-30`
|
||
|
||
- [ ] **Step 1: Move grounding-check under specify in the expected-layout tree**
|
||
|
||
Replace:
|
||
```
|
||
├── brainstorm/
|
||
│ ├── SKILL.md
|
||
│ └── agents/
|
||
│ └── grounding-check.md
|
||
├── planner/
|
||
```
|
||
with:
|
||
```
|
||
├── brainstorm/
|
||
│ └── SKILL.md
|
||
├── specify/
|
||
│ ├── SKILL.md
|
||
│ └── agents/
|
||
│ └── grounding-check.md
|
||
├── planner/
|
||
```
|
||
|
||
- [ ] **Step 2: Verify**
|
||
|
||
Run: `grep -nE 'specify/|grounding-check' docs/migration.md`
|
||
Expected: grounding-check.md now appears under a `specify/` subtree, not `brainstorm/`.
|
||
|
||
(Note: this tree is already partially stale — it predates `tdd`, `glossary`, `pseudo`, `issue`, `postmortem`. Bringing those entries current is pre-existing drift outside this cycle's scope; only the grounding-check move, which THIS cycle causes, is corrected here.)
|
||
|
||
---
|
||
|
||
### Task 10: Whole-cycle internal-consistency verification
|
||
|
||
**Files:** (read-only — no edits unless a check fails)
|
||
|
||
This task is the spec's § Testing strategy made executable as greps.
|
||
|
||
- [ ] **Step 1: No path-count drift — nothing still asserts two paths**
|
||
|
||
Run: `grep -rniE 'two (co-equal )?(entry )?paths|brainstorm and tdd are (the )?(two|co-equal)' --include=*.md . | grep -v docs/specs/ | grep -v docs/plans/`
|
||
Expected: no matches. Any hit is a leftover two-path assertion to fix.
|
||
|
||
- [ ] **Step 2: specify is referenced everywhere the topology renders**
|
||
|
||
Run: `for f in specify/SKILL.md brainstorm/SKILL.md boss/SKILL.md tdd/SKILL.md docs/pipeline.md README.md docs/profile-schema.md templates/project-profile.yml docs/migration.md; do printf '%s: ' "$f"; grep -c specify "$f"; done`
|
||
Expected: every file reports ≥1.
|
||
|
||
- [ ] **Step 3: No skill still routes brainstorm directly to planner**
|
||
|
||
Run: `grep -rnE 'brainstorm *(→|->) *planner|brainstorm.*gates.*planner' --include=*.md --include=*.yml . | grep -v docs/specs/ | grep -v docs/plans/`
|
||
Expected: no matches (the edge is now brainstorm→specify→planner).
|
||
|
||
- [ ] **Step 4: The grounding-check agent has exactly one home, under specify**
|
||
|
||
Run: `git ls-files '*grounding-check.md'`
|
||
Expected: exactly `specify/agents/grounding-check.md` (not under brainstorm).
|
||
|
||
Run: `grep -rnE 'brainstorm/agents/grounding-check|agents/grounding-check' --include=*.md . | grep -v 'specify/'`
|
||
Expected: no path reference points at a brainstorm-homed grounding-check.
|
||
|
||
- [ ] **Step 5: specify/SKILL.md structural completeness**
|
||
|
||
Run: `grep -nE '^## (Overview|When to Use / Skipping|The Iron Law|The Process|The Bounce-Back|Handoff Contract|Common Rationalisations|Red Flags|Cross-references)' specify/SKILL.md`
|
||
Expected: all nine headers present.
|
||
|
||
Run: `grep -nE '^### Step (1|1\.5|2|3|4|5|6|7) ' specify/SKILL.md`
|
||
Expected: the eight process steps (1, 1.5, 2–7) present, in order.
|
||
|
||
---
|
||
|
||
## Self-review (planner Step 5)
|
||
|
||
1. **Spec coverage:** every spec section maps to a task — Architecture/Components → Tasks 1-9; Data flow (carriers) → Task 1 Handoff Contract + Task 3 Step 8; Error handling (bounce, BLOCK, /boss pause) → Task 1 Steps (Iron Law, 1.5, 5, 6) + The Bounce-Back; Testing strategy → Task 10. ✓
|
||
2. **Placeholder scan:** no "TBD/TODO/implement later/similar to Task/add appropriate". Every edit shows exact old→new text. ✓
|
||
3. **Type/name consistency:** skill name `specify`, path `specify/SKILL.md`, agent `specify/agents/grounding-check.md`, step numbers (1, 1.5, 2–7) consistent across all tasks. ✓
|
||
4. **Step granularity:** each step is one file edit or one grep, 2–5 min. The large Task-1 Step-1 is a single file-create with the full body inlined (one paste), not a multi-decision step. ✓
|
||
5. **No commit steps:** none. The orchestrator commits the working tree at iter end. ✓
|
||
6. **Pin/replacement contiguity:** the grep filter strings in Task 10 (`two paths`, `brainstorm → planner`, `grounding-check`) match content this plan deliberately removes or relocates — they assert *absence*, the safe direction. The presence-greps (`specify`, headers) name strings this plan writes verbatim in Task 1 / the edits. ✓
|
||
7. **Compile-gate ordering:** N/A — prose repo, no compilation unit. Task ordering (specify created before brainstorm strips its production steps; agent moved before consistency check) is logical, not compile-forced. ✓
|
||
8. **Verification-filter strings resolve:** Task 10's greps either assert absence (a no-match is the pass) or name headers/strings written verbatim in this plan. Step 2's per-file loop counts ≥1 against files this plan guarantees contain `specify`. ✓
|
||
9. **Parse-the-bytes gate:** no `dev-cycle-profile.yml` exists → `spec_validation` is unconfigured → the parse gate is a documented no-op (per profile-schema). The only fenced bodies inlined are Markdown/YAML skill content, not a surface-language with a configured parser. No-op recorded. ✓
|
||
|
||
**Note on grounding-check during *this* plan's parent spec:** already
|
||
documented as a conscious skip in the spec (§ Testing strategy) and the
|
||
brainstorm chat — degenerate setup (no profile, no test suite).
|