diff --git a/README.md b/README.md index b52e37d..802b1b1 100644 --- a/README.md +++ b/README.md @@ -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 | diff --git a/boss/SKILL.md b/boss/SKILL.md index bb4effd..d81d3b1 100644 --- a/boss/SKILL.md +++ b/boss/SKILL.md @@ -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`. diff --git a/brainstorm/SKILL.md b/brainstorm/SKILL.md index 40460e1..540c72b 100644 --- a/brainstorm/SKILL.md +++ b/brainstorm/SKILL.md @@ -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 6 — Write the spec +### Step 5 — Hand 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 -# — 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. diff --git a/docs/migration.md b/docs/migration.md index 163103a..586833f 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -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 diff --git a/docs/pipeline.md b/docs/pipeline.md index dd64172..f40c16a 100644 --- a/docs/pipeline.md +++ b/docs/pipeline.md @@ -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. diff --git a/docs/profile-schema.md b/docs/profile-schema.md index f415483..35aaade 100644 --- a/docs/profile-schema.md +++ b/docs/profile-schema.md @@ -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 } diff --git a/specify/SKILL.md b/specify/SKILL.md new file mode 100644 index 0000000..0b348c6 --- /dev/null +++ b/specify/SKILL.md @@ -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. diff --git a/brainstorm/agents/grounding-check.md b/specify/agents/grounding-check.md similarity index 93% rename from brainstorm/agents/grounding-check.md rename to specify/agents/grounding-check.md index 53e1bc5..72ad004 100644 --- a/brainstorm/agents/grounding-check.md +++ b/specify/agents/grounding-check.md @@ -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 diff --git a/tdd/SKILL.md b/tdd/SKILL.md index 857e5d8..5f291ca 100644 --- a/tdd/SKILL.md +++ b/tdd/SKILL.md @@ -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. diff --git a/templates/project-profile.yml b/templates/project-profile.yml index 94c425c..389d39f 100644 --- a/templates/project-profile.yml +++ b/templates/project-profile.yml @@ -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 }