From 9ca2c8ab87932c7f3e0e062b8789cba59cffadad Mon Sep 17 00:00:00 2001 From: Brummel Date: Thu, 2 Jul 2026 11:38:55 +0200 Subject: [PATCH] chore: remove this repo's own committed specs/plans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These four cycles' specs and plans (glossary integration + skill, milestone-close gate, specify entry path) were self-development artefacts committed before specs/plans became gitignored working files (08bc2aa). They are all long shipped and nothing references them. Remove them from HEAD to match the new convention — git history retains them, and docs/specs/ + docs/plans/ are now globally gitignored. --- docs/plans/2026-05-31-glossary-integration.md | 421 ------ docs/plans/2026-05-31-glossary-skill.md | 506 -------- docs/plans/2026-05-31-milestone-close-gate.md | 732 ----------- docs/plans/2026-06-04-specify-entry-path.md | 1123 ----------------- .../2026-05-31-glossary-integration-design.md | 252 ---- .../specs/2026-05-31-glossary-skill-design.md | 299 ----- .../2026-05-31-milestone-close-gate-design.md | 241 ---- .../2026-06-04-specify-entry-path-design.md | 308 ----- 8 files changed, 3882 deletions(-) delete mode 100644 docs/plans/2026-05-31-glossary-integration.md delete mode 100644 docs/plans/2026-05-31-glossary-skill.md delete mode 100644 docs/plans/2026-05-31-milestone-close-gate.md delete mode 100644 docs/plans/2026-06-04-specify-entry-path.md delete mode 100644 docs/specs/2026-05-31-glossary-integration-design.md delete mode 100644 docs/specs/2026-05-31-glossary-skill-design.md delete mode 100644 docs/specs/2026-05-31-milestone-close-gate-design.md delete mode 100644 docs/specs/2026-06-04-specify-entry-path-design.md diff --git a/docs/plans/2026-05-31-glossary-integration.md b/docs/plans/2026-05-31-glossary-integration.md deleted file mode 100644 index 1eca882..0000000 --- a/docs/plans/2026-05-31-glossary-integration.md +++ /dev/null @@ -1,421 +0,0 @@ -# Glossary Integration — Implementation Plan - -> **Parent spec:** `docs/specs/2026-05-31-glossary-integration-design.md` -> -> **For agentic workers:** REQUIRED SUB-SKILL: use the -> `implement` skill to run this plan. Steps use `- [ ]` -> checkboxes for tracking. - -**Goal:** Add an optional `paths.glossary` profile slot whose file -becomes standing reading for every role, a convention doc that owns -the format and the boss write-rule, and a dogfooded `docs/glossary.md` -for the plugin's own vocabulary. - -**Architecture:** The glossary rides the existing standing-reading -mechanism — one optional path slot, no new delivery path. The -"set ⇒ standing reading for every role" semantics are single-sourced -at the `paths.glossary` row in `profile-schema.md`; `agent-template.md` -and `pipeline.md` carry one referencing sentence each. The format and -write-rule live once in `docs/glossary-convention.md`; `boss/SKILL.md` -only points to it. - -**Tech Stack:** Markdown docs, one YAML template. No executable -surface — this repo has no test runner, so each task verifies with a -`grep` presence assertion against the file it touched. - ---- - -## Note on verification & the parse gate - -This repo ships **no** `.claude/dev-cycle-profile.yml`, so -`commands.test` is empty and `spec_validation` is undeclared. Per the -planner self-review parse gate (`docs/profile-schema.md` -§ `spec_validation`), the inlined blocks here are `markdown` / `yaml` -fences with **no configured parser** — the parse-the-bytes-you-inline -gate is a documented no-op for this plan. Each task therefore closes -on a `grep` assertion whose pattern is named to match ≥1 real line in -the file just written (self-review item 8), not a test-runner result. - ---- - -## Task 1: Create `docs/glossary-convention.md` - -The single source for the glossary format, the standing-reading -obligation, and the boss record-reality write-rule. Created first so -later tasks can cross-reference it. - -**Files:** -- Create: `docs/glossary-convention.md` - -- [ ] **Step 1: Write the convention doc** - -Create `docs/glossary-convention.md` with exactly this content (the -outer fence is four backticks so the inner three-backtick format -example below survives — write only the inner content to the file): - -````markdown -# Glossary convention - -A project's glossary pins canonical nomenclature so terminology does -not drift over time, and so that LLM-driven work reuses the -established term for a concept instead of coining a fresh synonym each -session. This file owns the format, the reading obligation, and the -write discipline; an individual project's glossary is an instance of -this convention. - -## Where it lives - -A project opts in by setting `paths.glossary` in its -`.claude/dev-cycle-profile.yml` (see `profile-schema.md` § `paths`). -When the slot is set, the file it names is standing reading for every -role — no separate `standing_reading.always` entry is required. When -the slot is unset, the whole feature is a documented no-op. - -## Format - -The glossary is a flat list of per-term blocks (not a table), so an -appended entry produces a clean line-wise diff. Each block has exactly -three fields: - -1. a level-3 heading naming the **canonical term** to use; -2. an **Avoid:** line listing known synonyms that must NOT be used; -3. a definition of at most two sentences. - -``` -### canonical-term -**Avoid:** synonym-one, synonym-two -A definition of at most two sentences. -``` - -A term with no known synonyms still carries an `**Avoid:** —` line so -every block has the same three-field shape. - -## Reading obligation - -Every skill and agent reads the glossary as part of its standing -reading and, when producing prose or naming a concept, uses the -canonical term and avoids the listed synonyms. If a concept is not -listed, reuse the closest existing term — do not silently coin a new -one. - -## Extending the glossary (user + boss only) - -The user may edit the glossary at any time. In a `/boss` session the -orchestrator may extend it autonomously — but only to **record -reality, never to invent**: - -- A term already used consistently across shipped artefacts but not - yet listed → add it, with its known synonyms under **Avoid**. -- A drift the orchestrator just resolved (two terms for one concept) - → record the winner as the canonical entry, the loser under - **Avoid**. - -The orchestrator never coins a brand-new term into the glossary: a -term earns its entry by already being in consistent use. All other -skills and agents are read-only consumers of the glossary. -```` - -- [ ] **Step 2: Verify the three load-bearing parts are present** - -Run: `grep -c -e '## Format' -e 'reality, never to invent' -e 'standing reading' docs/glossary-convention.md` -Expected: a count of at least `3` (the format section, the -record-reality rule, and the reading obligation are all present). -The `reality, never to invent` pattern matches the unwrapped line in -the verbatim content (the words `record reality` are split across a -line break, so a `record reality` pattern would spuriously miss). - ---- - -## Task 2: Create `docs/glossary.md` (dogfood) - -The plugin's own glossary, proving the format on real vocabulary. -Content is lifted verbatim from the spec's primary artefact (spec -lines 58-92). - -**Files:** -- Create: `docs/glossary.md` - -- [ ] **Step 1: Write the dogfood glossary** - -Create `docs/glossary.md` with exactly this content: - -```markdown -# Glossary - -Canonical nomenclature for this project. Use the **canonical term**; -never use a term under **Avoid**. If you need a concept that is not -listed here, reuse the closest existing term — do not silently coin -a new one. New entries are added only to record nomenclature already -in consistent use; see `glossary-convention.md`. - ---- - -### cycle -**Avoid:** release, epic, round, sprint -One round in the pipeline graph (design → plan → execute → review → -close). Not the top-level container — that is a *milestone*. - -### milestone -**Avoid:** epic, phase, big-ticket -A tracker container spanning potentially many cycles; closes only -when its promised work is complete and functional. A cycle close is -never a milestone close. - -### iteration -**Avoid:** sprint, story, step -The default sub-unit of a cycle; one pass through the inner loop. A -project may rename it via `vocabulary.subcycle`. - -### drift -**Avoid:** divergence, rot, skew -Accumulated mismatch between the codebase and its design ledger. -Surfaced by the architect agent at audit, not by any synonym check. - -### hard-gate -**Avoid:** checkpoint, barrier, blocker -A pipeline point that forbids downstream work until an artefact -exists and is approved (e.g. an approved spec before any plan). -``` - -- [ ] **Step 2: Verify every entry conforms to the three-field shape** - -Run: `grep -c '^\*\*Avoid:\*\*' docs/glossary.md` -Expected: `5` (one Avoid line per term: cycle, milestone, iteration, -drift, hard-gate). - ---- - -## Task 3: Document the slot in `docs/profile-schema.md` - -Add the `glossary` row to the `paths` table (single source for the -"set ⇒ standing reading" semantics) and a referencing sentence in the -`standing_reading` section. - -**Files:** -- Modify: `docs/profile-schema.md:13` (paths table) and `:152` - (standing_reading tail) - -- [ ] **Step 1: Add the `glossary` row after the `plan_dir` row** - -Exact-string replace this anchor: - -``` -| `plan_dir` | string | `docs/plans` | Where the planner skill writes plans. | -``` - -with: - -``` -| `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`. | -``` - -- [ ] **Step 2: Add the cross-reference sentence at the end of `standing_reading`** - -Exact-string replace this anchor (end of the `standing_reading` -section, just before `## \`git\``): - -``` -Entries may be shell commands as well as file paths — they are -read as opaque strings the agent should fetch / execute, e.g. -`"git log -10 --format=full"`. - -## `git` -``` - -with: - -``` -Entries may be shell commands as well as file paths — they are -read as opaque strings the agent should fetch / execute, e.g. -`"git log -10 --format=full"`. - -A set `paths.glossary` is implicitly appended to every role's -`always` list — it does not need its own entry here. The slot's -authoritative semantics live at the `paths` row above. - -## `git` -``` - -- [ ] **Step 3: Verify both edits landed** - -Run: `grep -c 'glossary' docs/profile-schema.md` -Expected: a count of `2` (the new `paths` table row line, and the one -new sentence line in the `standing_reading` section). `grep -c` counts -matching lines, so the table row counts once even though it names the -glossary twice. - ---- - -## Task 4: Add the commented slot to `templates/project-profile.yml` - -**Files:** -- Modify: `templates/project-profile.yml:9` (paths block) - -- [ ] **Step 1: Insert the commented `glossary` line after `plan_dir`** - -Exact-string replace this anchor: - -``` - spec_dir: docs/specs - plan_dir: docs/plans - # design_ledger: design/INDEX.md # optional -``` - -with: - -``` - spec_dir: docs/specs - plan_dir: docs/plans - # glossary: docs/glossary.md # optional — if set, read as - # standing reading by every role - # design_ledger: design/INDEX.md # optional -``` - -- [ ] **Step 2: Verify the commented slot is present** - -Run: `grep -c 'glossary: docs/glossary.md' templates/project-profile.yml` -Expected: `1`. - ---- - -## Task 5: Add the standing-reading sentence to `docs/agent-template.md` - -**Files:** -- Modify: `docs/agent-template.md:125` (Standing reading list section) - -- [ ] **Step 1: Append the `paths.glossary` sentence to the standing-reading paragraph** - -Exact-string replace this anchor: - -``` -and passes the resolved list to the agent via the carrier. The -agent's body says, prosaically: "Read everything in the standing -reading list before doing anything else." - -The agent file itself does not hardcode file paths. -``` - -with: - -``` -and passes the resolved list to the agent via the carrier. The -agent's body says, prosaically: "Read everything in the standing -reading list before doing anything else." - -A set `paths.glossary` is implicitly part of `always`, so every role -reads the project glossary without a per-role entry (see -`profile-schema.md` § `paths`). - -The agent file itself does not hardcode file paths. -``` - -- [ ] **Step 2: Verify the sentence landed** - -Run: `grep -c 'paths.glossary' docs/agent-template.md` -Expected: `1`. - ---- - -## Task 6: Add the standing-reading sentence to `docs/pipeline.md` - -`pipeline.md` does not currently mention standing reading; the -natural home is the tail of the "Pipeline configuration" section, -which already cross-references the profile. - -**Files:** -- Modify: `docs/pipeline.md:178` (end of Pipeline configuration) - -- [ ] **Step 1: Append the glossary sentence after the configuration cross-reference** - -Exact-string replace this anchor (the final line of the file): - -``` -See `profile-schema.md` for the syntax. -``` - -with: - -``` -See `profile-schema.md` for the syntax. - -If the profile sets `paths.glossary`, that file is standing reading -for every role — the canonical-nomenclature source every skill and -agent consults (see `glossary-convention.md`). Unset, it is a no-op. -``` - -- [ ] **Step 2: Verify the sentence landed** - -Run: `grep -c 'paths.glossary' docs/pipeline.md` -Expected: `1`. - ---- - -## Task 7: Add the cross-reference pointer to `boss/SKILL.md` - -Boss gets a pointer to the convention's write-rule in two places: the -loop (Step 4) and the Cross-references list. No rule text is -duplicated. - -**Files:** -- Modify: `boss/SKILL.md` (Step 4 loop area; Cross-references section) - -- [ ] **Step 1: Add the write-rule pointer after the Step-4 decision bullets** - -Exact-string replace this anchor: - -``` - fieldtest green and stays a deliberate manual act (see - `../docs/pipeline.md` § Milestone-close gate). - -### Step 5 — On done-state: Notify -``` - -with: - -``` - fieldtest green and stays a deliberate manual act (see - `../docs/pipeline.md` § Milestone-close gate). - -If a term-drift is resolved during the loop — two names collapsed to -one, or a settled term not yet listed — record it in the project -glossary per `../docs/glossary-convention.md`: record reality, never -invent. This is the only glossary write authority outside the user. - -### Step 5 — On done-state: Notify -``` - -- [ ] **Step 2: Add the Cross-references bullet** - -Exact-string replace this anchor: - -``` -- **Queue:** the URL configured under `git.issue_tracker.url` in - the profile; CLI command at `git.issue_tracker.list_cmd`. -- **Downstream skills dispatched:** `../brainstorm`, -``` - -with: - -``` -- **Queue:** the URL configured under `git.issue_tracker.url` in - the profile; CLI command at `git.issue_tracker.list_cmd`. -- **Glossary write-rule:** `../docs/glossary-convention.md` — - record-reality discipline for the only autonomous glossary writer. -- **Downstream skills dispatched:** `../brainstorm`, -``` - -- [ ] **Step 3: Verify both pointers landed** - -Run: `grep -c 'glossary-convention.md' boss/SKILL.md` -Expected: `2`. - ---- - -## Final acceptance sweep - -- [ ] **Step 1: Confirm all spec acceptance criteria are covered** - -Run: `ls docs/glossary.md docs/glossary-convention.md && grep -l 'glossary' docs/profile-schema.md templates/project-profile.yml docs/agent-template.md docs/pipeline.md boss/SKILL.md` -Expected: both new files listed, and all five modified files reported -as containing `glossary`. diff --git a/docs/plans/2026-05-31-glossary-skill.md b/docs/plans/2026-05-31-glossary-skill.md deleted file mode 100644 index 987e57d..0000000 --- a/docs/plans/2026-05-31-glossary-skill.md +++ /dev/null @@ -1,506 +0,0 @@ -# glossary skill — Implementation Plan - -> **Parent spec:** `docs/specs/2026-05-31-glossary-skill-design.md` -> -> **For agentic workers:** REQUIRED SUB-SKILL: use the `implement` -> skill to run this plan. Steps use `- [ ]` checkboxes for tracking. - -**Goal:** Add a `glossary` utility skill (two procedures — maintain and -bootstrap) plus its dedicated read-only `glossary-extractor` agent, and -wire three single-sentence references, so a project can build and -conformance-check its glossary. - -**Architecture:** A new top-level `glossary/` skill directory (picked up -by `install.sh`'s existing glob) holding `SKILL.md` (mode dispatch -`maintain | bootstrap`) and `agents/glossary-extractor.md` -(template-conforming, read-only). The skill applies the rules in -`docs/glossary-convention.md` and restates none. Three referencing edits -in `boss/SKILL.md`, `docs/glossary-convention.md`, and `README.md`. - -**Tech Stack:** Markdown skill + agent files; docs/prose-only repo, no -test runner — every task closes on a `grep` presence-assertion against -the touched file, each calibrated against a verified zero baseline. - ---- - -**Files this plan creates or modifies:** - -- Create: `glossary/SKILL.md` — the mode-dispatch utility skill. -- Create: `glossary/agents/glossary-extractor.md` — read-only per-slice prose extractor. -- Modify: `boss/SKILL.md:131` — append the bootstrap bounce-back sentence to the glossary-write paragraph. -- Modify: `docs/glossary-convention.md:66` — append the one-line tooling pointer to § Extending. -- Modify: `README.md:17,28` — reword the count-pinned framing line; add a utility-skills note after the table. - -Read-only references (not edited): `docs/glossary.md` (collision-scan -example), `docs/profile-schema.md` § `paths` (slot semantics), -`docs/agent-template.md` (agent skeleton), `install.sh` (glob covers the -new dir — AC 8, no edit). - ---- - -### Task 1: `glossary/SKILL.md` - -**Files:** -- Create: `glossary/SKILL.md` - -- [ ] **Step 1: Create the directory and write the skill file** - -Create `glossary/SKILL.md` with exactly this content: - -````markdown ---- -name: glossary -description: Use when adding, changing, or removing a glossary entry (maintain), or building a new glossary for an existing project from its prose surface (bootstrap). The skill applies the rules in docs/glossary-convention.md — it restates none of them. maintain keeps the existing user-any-time / boss-record-reality write authority and adds a conformance check; bootstrap is user-only (high-context multi-agent work; boss may recommend it via bounce-back but never runs it). ---- - -# glossary — build and maintain a project's glossary - -> **Violating the letter of these rules is violating the spirit.** - -## Overview - -A project's glossary pins canonical nomenclature so terminology does not -drift over time, and so LLM-driven work reuses the established term for a -concept instead of coining a fresh synonym each session. -`../docs/glossary-convention.md` owns the rules — the three-field format, -the reading obligation, the record-reality write-rule, and the -glossary-as-source-of-truth declaration. This skill is the *procedure* -that applies those rules; it restates none of them. - -It carries two procedures. **maintain** adds, changes, or removes a -single entry under a conformance check. **bootstrap** builds a fresh -glossary for a project that has none, by fanning out read-only -`glossary-extractor` agents over the project's prose surface and -synthesising their observations into conforming entries. - -## When to Use / Skipping - -Triggers: - -- **maintain** — a term is to be added, changed, or removed in an - existing glossary, by the user any time, or by boss to record reality - (a term already in consistent use, or a drift boss just resolved). -- **bootstrap** — a project has terminology to pin but no glossary - (`paths.glossary` unset, or naming an empty file), and the user invokes - the build. - -Skip or refuse: - -- maintain asked with no `paths.glossary` slot set: there is nowhere to - write. Stop and instruct the user to set `paths.glossary` (see - `../docs/profile-schema.md` § `paths`) first. -- bootstrap asked on a glossary that already has entries: do not clobber. - Stop with the entry count and recommend maintain. -- bootstrap asked in a boss (autonomous) session: refuse. bootstrap is - user-only; boss may recommend it via bounce-back but never runs it (see - Authority). - -## Authority - -maintain inherits the existing write authority unchanged -(`../docs/glossary-convention.md` § Extending): the user any time; boss -autonomously but only to record reality, never to invent. This skill adds -the conformance check around that authority; it does not widen it. - -bootstrap is **user-only**. It is high-context multi-agent work analogous -to a fresh `brainstorm`, which boss bounces back rather than starting -autonomously. In a boss session, recommend a bootstrap via bounce-back -when a project lacks a glossary and drift is visible — do not run one. - -## Mode dispatch - -On invocation, route on the argument: - -- `maintain` (or `add` / `change` / `remove`) → the maintain procedure. -- `bootstrap` → the bootstrap procedure (user-only). - -If the mode is ambiguous, ask once; do not guess. - -## The maintain procedure - -1. **Read the glossary and the convention.** Read the file named by - `paths.glossary` and `../docs/glossary-convention.md`. If - `paths.glossary` is unset, stop (see When to Use / Skipping). -2. **Take the proposed entry.** A canonical-term heading, an `**Avoid:**` - line, and a definition — the user's, or (in a boss session bound by - record-reality) the term already in consistent use. -3. **Run the local conformance check** against the proposed entry and the - rest of the glossary: - - the three-field shape the convention defines; - - the definition is at most two sentences; - - collision scan: the proposed canonical term must not already sit - under another entry's **Avoid**, and a proposed **Avoid** synonym - must not be another entry's canonical term. - On any failure, REJECT — name the violated rule, do not write the - entry, and ask for a corrected one. -4. **Run the stale-usage sweep** (on add / change / rename): grep the - prose surface for the old canonical term (change/rename) and for each - **Avoid** synonym, and report the hits as drift the user may want to - fix. The sweep reports; it does not block — guidance, not enforcement. -5. **Write the conforming entry UNSTAGED.** Add, edit, or remove the - entry in the glossary file, preserving the flat per-term-block shape so - the diff stays line-wise clean. Leave it unstaged for review. -6. **Hand back** to the user for review. In a boss session, the - record-reality discipline governs whether the write was permitted at - all (boss never coins). - -## The bootstrap procedure (user-only) - -1. **Guard.** Read `paths.glossary`. If it names a file that already has - entries, stop with the count and recommend maintain. If the slot is - unset, continue, and note the build will also propose setting the slot - (see `../docs/profile-schema.md` § `paths`). -2. **Partition the prose surface into slices** — the readable prose of - the project: `docs/`, `README.md`, the design ledger (if - `paths.design_ledger` is set), the spec directory. One slice per - coherent group, sized so a single agent can sweep it. -3. **Fan out one `glossary-extractor` per slice.** Dispatch the read-only - agent (`agents/glossary-extractor.md`) with the carrier: the slice and - the extraction task. Agents do not nest; the skill curates each - carrier. -4. **Merge and cluster.** Collect the reports. Cluster variants that name - the same concept across slices, summing frequencies. -5. **Synthesise.** For each cluster: - - a clear cluster (one dominant variant) → auto-include it as a - conforming entry: canonical heading = the dominant variant, - **Avoid** = the other variants, a ≤2-sentence definition drawn from - the observed usage; - - a contested cluster (≥2 comparable variants) → surface it to the user - with the variants, frequencies, and locations, and ask which is - canonical. Never decide a contested canonical yourself. -6. **Handle the unresolved.** A contested cluster the user does not - resolve is left OUT of the glossary and noted as deferred. Never coin a - term to fill a gap. -7. **Assemble UNSTAGED.** Write the conforming glossary to - `paths.glossary` (proposing the slot value if it was unset), in the - convention's flat per-term-block format. Leave it unstaged for review. - -## Iron Law - -``` -THE CONVENTION OWNS THE RULES; THIS SKILL ONLY APPLIES THEM — RESTATE NOTHING. -A NON-CONFORMING ENTRY IS REJECTED, NOT WRITTEN. -BOOTSTRAP IS USER-ONLY. NEVER COIN A TERM — RECORD REALITY. -``` - -## Handoff Contract - -| Direction | Carrier | -|-----------|---------| -| user → glossary (maintain) | the proposed entry + the operation (add / change / remove) | -| user → glossary (bootstrap) | the build request | -| glossary → glossary-extractor (bootstrap) | one prose slice + the extraction task | -| boss → user (bounce-back) | a recommendation to run a bootstrap; boss never runs one itself | - -## Common Rationalisations - -| Excuse | Reality | -|--------|---------| -| "The entry is obviously fine, skip the conformance check" | The check is the skill's whole reason to exist over hand-editing. Run it. | -| "Two variants are close; I'll pick the more frequent as canonical" | A contested cluster is a nomenclature judgement that belongs to the user. Surface it; do not decide it. | -| "The concept clearly needs a term, I'll coin one" | The glossary records reality, never invents. An unresolved concept is left out and deferred. | -| "boss is running and the project has no glossary, I'll bootstrap it" | bootstrap is user-only. Recommend it via bounce-back; do not run it. | -| "I'll restate the format here so the skill is self-contained" | The convention is the single source for the rules. Cite it; restating it is the cross-doc drift this split exists to prevent. | -| "The stale-usage hits should block the write" | The sweep is guidance, not enforcement. Report the drift; write the entry regardless. | - -## Red Flags — STOP - -- About to write a non-conforming entry instead of rejecting it. -- About to pick a canonical term for a genuinely contested cluster. -- About to coin a term for a concept that has no observed term. -- About to run a bootstrap in a boss / autonomous session. -- About to restate the convention's format or write-rule in this file. -- About to clobber a populated glossary with a bootstrap. - -## Cross-references - -- **Rules (the single source):** `../docs/glossary-convention.md` — - format, reading obligation, write-rule, glossary-as-SoT. This skill - applies these; it restates none. -- **Slot semantics:** `../docs/profile-schema.md` § `paths` — the - `paths.glossary` slot (set ⇒ standing reading for every role; unset ⇒ - no-op). -- **Agent dispatched:** `agents/glossary-extractor.md` — read-only - per-slice prose extraction, fanned out in bootstrap. -- **Glossary instance (dogfood):** `../docs/glossary.md` — this plugin's - own glossary. -- **boss write authority:** `../boss/SKILL.md` — the record-reality rule - for the only autonomous glossary writer, and the bootstrap bounce-back. -```` - -- [ ] **Step 2: Verify the file is present and conforming** - -Run: `grep -c "BOOTSTRAP IS USER-ONLY" glossary/SKILL.md` -Expected: `1` (the Iron-Law fence line; baseline before this task: file does not exist). - -Run: `grep -c "^## The bootstrap procedure (user-only)$" glossary/SKILL.md` -Expected: `1` (the bootstrap-procedure heading is present). - -Run: `grep -c "^name: glossary$" glossary/SKILL.md` -Expected: `1` (frontmatter `name` slug is correct). - ---- - -### Task 2: `glossary/agents/glossary-extractor.md` - -**Files:** -- Create: `glossary/agents/glossary-extractor.md` - -- [ ] **Step 1: Create the agents directory and write the agent file** - -Create `glossary/agents/glossary-extractor.md` with exactly this content: - -````markdown ---- -name: glossary-extractor -description: Read-only per-slice prose extractor for glossary bootstrap. Sweeps one slice of a project's prose surface and reports the recurring domain-concept terms and their competing synonyms as actually written, with frequencies and locations. Coins nothing; dispatched fan-out by the glossary skill's bootstrap procedure. -tools: Read, Glob, Grep, Bash ---- - -> Violating the letter of these rules is violating the spirit. - -## What this role is for - -This role exists to prevent an orchestrator from sweeping a whole -project's prose in its own context to coin a glossary — which blows the -context window, conflates orchestration with execution, and tempts -invention over observation. The extractor sweeps exactly one assigned -slice, reports the concept terms and competing variants it actually -finds, and coins nothing. The glossary skill fans out one extractor per -slice and merges their reports. - -## Standing reading list - -Read everything in the standing reading list passed in the carrier before -doing anything else. A set `paths.glossary` is part of every role's -standing reading, and `docs/glossary-convention.md` defines what a -glossary-worthy concept term is versus incidental vocabulary — consult it -so you report concepts, not every capitalised word. - -## Carrier contract - -| Field | Content | -|-------|---------| -| `slice` | the one prose region this agent sweeps (e.g. `docs/`, `README.md`) — do not read outside it | -| `task` | the extraction instruction: recurring domain-concept terms and their competing synonyms, as actually written | - -You receive the carrier inline in the dispatch prompt. Do NOT widen your -sweep beyond the assigned slice; another extractor covers the rest. - -## Iron Law - -``` -REPORT TERMS YOU OBSERVE IN THE SLICE. NEVER COIN A TERM. -EVERY REPORTED VARIANT CARRIES A FREQUENCY AND AT LEAST ONE LOCATION. -SWEEP ONLY THE ASSIGNED SLICE. -A CANONICAL CHOICE IS NOT YOURS TO MAKE — REPORT VARIANTS, NOT A WINNER. -``` - -## The Process - -1. Read the standing reading list, then `docs/glossary-convention.md` for - what counts as a concept term. -2. Enumerate the files in the assigned slice (`Glob` / `ls`). -3. Sweep for recurring domain-concept terms: nouns and noun-phrases that - name a project concept and recur across the slice. Use `grep -c` for - frequencies and `grep -n` for locations. -4. Cluster variants that name the same concept within the slice (e.g. - "design ledger" / "design index"). Do not decide which is canonical. -5. Drop incidental vocabulary: terms that appear once, generic English, - and code identifiers that are not concept names. -6. Emit the report in the format below. If the slice yields no recurring - concept terms, say so — fabricate nothing. - -## Status protocol - -| Status | Meaning | -|--------|---------| -| `DONE` | The slice was swept; the report lists every recurring concept term found (possibly none). | -| `PARTIAL` | The slice was too large to finish; report what was swept and name the unswept files. | -| `BLOCKED` | The slice could not be read (missing path, permission). Explanation in the report. | -| `NEEDS_CONTEXT` | The carrier is ambiguous (no slice, or an unreadable task). | - -This is a read-only role: it writes no files under any status. - -## Output format - -Plain text, word-budgeted. One block per concept: - -``` -- concept: - variants: [ (x), (x), ...] - locations: [, , ...] -``` - -End with a one-line `Swept: files in ` summary. On an empty -slice, emit `No recurring concept terms found in .` - -## Common Rationalisations - -| Excuse | Reality | -|--------|---------| -| "This concept obviously needs a canonical term, I'll mark one" | Picking the canonical is the skill's job (and the user's for contested clusters). Report variants, not a winner. | -| "There's a clearly better word the project should use" | You report what is written, not what should be. Coining is forbidden. | -| "The neighbouring slice has related terms, let me peek" | Sweep only your slice. Another extractor covers the rest; merging is the skill's job. | -| "This term appears once but feels important" | A single occurrence is not a recurring concept. Drop it, or the merge fills with noise. | -| "I'll skip frequencies, the list is enough" | Frequencies are how the skill tells a clear cluster from a contested one. Every variant carries a count. | - -## Red Flags — STOP - -- About to write or edit any file. -- About to report a term that does not appear in the slice. -- About to name a canonical winner instead of listing variants. -- About to read files outside the assigned slice. -- About to report a variant with no frequency or no location. -```` - -- [ ] **Step 2: Verify the agent file is present and conforming** - -Run: `grep -c "NEVER COIN A TERM" glossary/agents/glossary-extractor.md` -Expected: `1` (the Iron-Law fence line; baseline before this task: file does not exist). - -Run: `grep -c "^name: glossary-extractor$" glossary/agents/glossary-extractor.md` -Expected: `1` (frontmatter slug correct). - -Run: `grep -c "^tools: Read, Glob, Grep, Bash$" glossary/agents/glossary-extractor.md` -Expected: `1` (read-only tool set, AC 2). - ---- - -### Task 3: `boss/SKILL.md` — bootstrap bounce-back sentence - -**Files:** -- Modify: `boss/SKILL.md:131` - -- [ ] **Step 1: Append the bootstrap sentence to the glossary-write paragraph** - -Find this exact line (`boss/SKILL.md:131`, the tail of the Step-4 -glossary-write paragraph): - -``` -invent. This is the only glossary write authority outside the user. -``` - -Replace it with: - -``` -invent. This is the only glossary write authority outside the user. -Building a glossary from scratch (the `glossary` skill's bootstrap) is -*not* this authority — it is high-context, user-only work; when a project -lacks a glossary and drift is visible, recommend a bootstrap via -bounce-back, never run one autonomously. -``` - -This keeps maintain-by-boss (record-reality) and bootstrap (user-only) -consistent with the existing "only glossary write authority outside the -user" claim on the same line. - -- [ ] **Step 2: Verify the sentence landed** - -Run: `grep -c "bootstrap" boss/SKILL.md` -Expected: `≥1` (verified baseline before this task: `0`). - ---- - -### Task 4: `docs/glossary-convention.md` — tooling pointer - -**Files:** -- Modify: `docs/glossary-convention.md:66` - -- [ ] **Step 1: Append the tooling pointer to § Extending** - -Find this exact line (`docs/glossary-convention.md:66`, the last line of -the file / § Extending): - -``` -skills and agents are read-only consumers of the glossary. -``` - -Append immediately after it (new paragraph at the section tail): - -``` -skills and agents are read-only consumers of the glossary. - -The `glossary` skill (`../glossary/SKILL.md`) is the executable procedure -for building and extending a glossary under these rules: this file stays -the rules, the skill applies them. -``` - -- [ ] **Step 2: Verify the pointer landed** - -Run: `grep -c "glossary/SKILL.md" docs/glossary-convention.md` -Expected: `≥1` (verified baseline before this task: `0`; `glossary/SKILL.md` -is a contiguous token, no line-wrap risk). - ---- - -### Task 5: `README.md` — list glossary, reconcile the stale framing - -**Files:** -- Modify: `README.md:17` (the count-pinned framing line) -- Modify: `README.md:28` (append a utility-skills note after the table) - -- [ ] **Step 1: Reword the count-pinned framing line** - -Find this exact line (`README.md:17`): - -``` -Eight skills, each with the agents it primarily dispatches: -``` - -Replace it with (count-free, since the table omits the existing utility -skill `issue` and now also `glossary`): - -``` -The pipeline skills, each with the agents it primarily dispatches: -``` - -- [ ] **Step 2: Add a utility-skills note after the skill table** - -Find the last table row (`README.md:28`): - -``` -| `boss` | User types `/boss` | autonomous-orchestrator session — dispatches the other skills until done-state or bounce-back | User-invoked, never auto-dispatched | -``` - -Append immediately after it (a blank line, then the note): - -``` -| `boss` | User types `/boss` | autonomous-orchestrator session — dispatches the other skills until done-state or bounce-back | User-invoked, never auto-dispatched | - -Two further **utility skills** are invoked on demand rather than as -pipeline phases: `issue` (file or update a tracker item) and `glossary` -(build or maintain the project glossary — see `docs/glossary-convention.md`). -``` - -- [ ] **Step 3: Verify the listing change landed** - -Run: `grep -c "glossary" README.md` -Expected: `≥1` (verified baseline before this task: `0`). - -Run: `grep -c "utility skills" README.md` -Expected: `≥1` (the reconciled framing names the utility-skill class; baseline: `0`). - ---- - -### Final sweep - -- [ ] **Step F1: All new and changed surfaces present** - -Run: -``` -test -f glossary/SKILL.md && \ -test -f glossary/agents/glossary-extractor.md && \ -grep -q "bootstrap" boss/SKILL.md && \ -grep -q "glossary/SKILL.md" docs/glossary-convention.md && \ -grep -q "glossary" README.md && \ -echo ALL_PRESENT -``` -Expected: `ALL_PRESENT` - -- [ ] **Step F2: install.sh glob covers the new skill (AC 8, no edit needed)** - -Run: `bash -n install.sh && grep -c 'SKILL.md' install.sh` -Expected: `bash -n` exits 0 (installer still parses) and the glob gate on -`SKILL.md` is present (`≥1`); confirms the new `glossary/` dir with its -`SKILL.md` + `agents/` subdir is linked with no installer change. diff --git a/docs/plans/2026-05-31-milestone-close-gate.md b/docs/plans/2026-05-31-milestone-close-gate.md deleted file mode 100644 index b425deb..0000000 --- a/docs/plans/2026-05-31-milestone-close-gate.md +++ /dev/null @@ -1,732 +0,0 @@ -# Milestone-close gate Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Make `audit` unable to imply a milestone is finished — separate `cycle` (a pipeline round) from `milestone` (a tracker container closed only when complete ∧ functional), and add a milestone-wide fieldtest as the closing gate. - -**Architecture:** Documentation/skill-file change across the plugin. The milestone-close gate is defined **once** in `docs/pipeline.md`; `audit`, `fieldtest`, `boss` reference it without restating it (single-source, matching the repo's recent carrier/handoff single-sourcing). The milestone fieldtest is a carrier-scope variant of the existing `fieldtest` skill — its carrier contract is extended in the authoritative agent file. The root conflation `cycle ≡ milestone` is corrected in `README.md`, `templates/project-profile.yml`, and `docs/profile-schema.md`. - -**Tech Stack:** Markdown skill/agent files; YAML profile template. No code. "Tests" are `grep` assertions over file content and a YAML parse check — the observable verification this repo admits. Each task: a RED check that pins the current state, the edit(s), a GREEN check that confirms the new state, then a commit. - -**Spec:** `docs/specs/2026-05-31-milestone-close-gate-design.md` - -**Scope note:** The spec's edit list named seven files. This plan adds an eighth — `fieldtest/agents/fieldtester.md` — because the carrier contract the spec references (`milestone_promise`) lives there authoritatively; documenting the variant in `fieldtest/SKILL.md` without defining it in the agent file would be a dangling reference. Task 2 covers it. - -**Task order rationale:** `docs/pipeline.md` first (it is the single source the others reference); then the fieldtester agent (single source of the carrier contract); then the referencing skills; then the vocabulary/profile layer; then a final cross-file verification sweep. - ---- - -### Task 1: `docs/pipeline.md` — the single-source gate definition - -**Files:** -- Modify: `docs/pipeline.md` (ASCII graph lines 10 & 15; new sections after the graph, before `## Phase descriptions`) - -- [ ] **Step 1: RED — confirm the conflated wording and the absence of the gate** - -Run: -```bash -cd ~/dev/skills -grep -n "\[cycle close\]\|--(clean)-+" docs/pipeline.md -grep -c "Milestone-close gate\|Cycle vs. milestone" docs/pipeline.md -``` -Expected: the first grep prints the two ASCII lines (`[cycle close]` and `--(clean)-+`); the second prints `0` (neither new section exists yet). - -- [ ] **Step 2: Relabel the cycle-close ASCII node** - -In `docs/pipeline.md`, replace: -``` - [cycle close] -``` -with: -``` - [cycle close — a loop step, not a milestone close] -``` - -- [ ] **Step 3: Rename the audit `clean` edge to `drift-clean`** - -In `docs/pipeline.md`, replace: -``` - --(clean)-+ -``` -with: -``` - --(drift-clean)-+ -``` - -- [ ] **Step 4: Add the two single-source sections** - -In `docs/pipeline.md`, immediately after the closing ``` ``` of the ASCII diagram (the line before `## Phase descriptions`), insert: - -```markdown -## Cycle vs. milestone - -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]`). - A cycle close is an internal loop step. -- A **milestone** is a tracker container (Gitea milestone, - GitHub milestone, Linear project — whatever the project's - tracker calls a long-running work scope). A milestone spans - potentially many cycles and closes only when the work it - promised is **complete and functional** (see the gate below). - -`audit` runs at cycle close and proves *drift-clean* — the code -matches the design ledger. It is blind to whether the work is -*functional* from a downstream consumer's point of view; that is -what `fieldtest` measures. So no `audit` result closes a -milestone, and neither does a `/boss` done-state. - -## Milestone-close gate - -A milestone may be closed in the tracker only when **both** legs -hold: - -1. **Complete** — every cycle filed under the milestone is - `audit` drift-clean (or its drift explicitly ratified), and - the milestone container has no open iterations / issues left. -2. **Functional** — the **milestone fieldtest** has run its - curated end-to-end scenarios against the milestone's promise - and its status roll-up is `clean`: every scenario - demonstrably delivers what the milestone promised; no open - `bug` findings; `friction` / `spec_gap` findings resolved or - ratified into the design ledger. - -The milestone fieldtest is the milestone-wide variant of the -`fieldtest` skill: the same fieldtester agent, a carrier scoped -to the milestone's promise rather than one cycle's surface. Its -scenarios are chosen top-down from what the milestone as a whole -promised, not assembled as the union of per-cycle axes. - -A milestone whose entire scope is internal (no user-visible -surface) is exempt from the functional leg — the milestone -fieldtest is *not applicable* and the complete leg suffices. - -This gate defines *when* a milestone is closeable. The actual -close stays a deliberate human / orchestrator act (`tea -milestone close`, or the tracker equivalent); no skill performs -it automatically. - -``` - -- [ ] **Step 5: GREEN — confirm the rename and the new sections** - -Run: -```bash -cd ~/dev/skills -grep -n "a loop step, not a milestone close\|--(drift-clean)-+" docs/pipeline.md -grep -c "## Milestone-close gate" docs/pipeline.md -grep -c "## Cycle vs. milestone" docs/pipeline.md -grep -n "\-\-(clean)-+" docs/pipeline.md || echo "OK: no bare clean edge remains" -``` -Expected: first grep prints both relabelled lines; the two `grep -c` print `1`; the last prints `OK: no bare clean edge remains`. - -- [ ] **Step 6: Commit** - -```bash -cd ~/dev/skills -git add docs/pipeline.md -git commit -m "docs(pipeline): single-source the milestone-close gate - -Define the cycle/milestone distinction and the complete-and-functional -close gate once in pipeline.md; rename audit's cycle-close edge to -drift-clean so it no longer reads as a milestone close." -``` - ---- - -### Task 2: `fieldtest/agents/fieldtester.md` — milestone-scope carrier variant - -**Files:** -- Modify: `fieldtest/agents/fieldtester.md` (Carrier contract section, after line 73) - -- [ ] **Step 1: RED — confirm the carrier knows only the cycle scope** - -Run: -```bash -cd ~/dev/skills -grep -c "milestone_promise\|Milestone-scope variant" fieldtest/agents/fieldtester.md -``` -Expected: `0` (no milestone carrier variant defined). - -- [ ] **Step 2: Add the milestone-scope variant to the carrier contract** - -In `fieldtest/agents/fieldtester.md`, immediately after the line: -``` -both are also empty, return `NEEDS_CONTEXT`. -``` -(the last line of the empty-`axis_hints` fallback, before `## The Iron Law`), insert: - -```markdown - -### Milestone-scope variant - -When dispatched as the **milestone fieldtest** — the closing -gate for a tracker milestone (see `../../docs/pipeline.md` -§ Milestone-close gate) — the carrier is scoped to the -milestone's promise rather than one cycle's surface: - -| Field | Content | -|-------|---------| -| `milestone_id` | e.g. `milestone-7` | -| `milestone_promise` | the milestone's stated goal / acceptance from the tracker (and its spec, if one exists) — what the work as a whole promises to deliver | -| `commit_range` | `..HEAD` | - -In this mode, Phase 1 derives 2-4 **curated end-to-end -scenarios top-down from `milestone_promise`** — each scenario a -realistic downstream task that, run end to end, demonstrates the -milestone delivers what it promised. Do **not** assemble the -scenarios as the union of per-cycle axes; the per-cycle -fieldtests already covered axis-local surface. There is no -`axis_hints` fallback in this mode: if `milestone_promise` is -empty, infer it from the milestone's spec / tracker entry, and -if that is also empty, return `NEEDS_CONTEXT`. -``` - -- [ ] **Step 3: GREEN — confirm the variant exists and references the gate** - -Run: -```bash -cd ~/dev/skills -grep -n "### Milestone-scope variant" fieldtest/agents/fieldtester.md -grep -n "milestone_promise" fieldtest/agents/fieldtester.md -grep -n "docs/pipeline.md.*Milestone-close gate" fieldtest/agents/fieldtester.md -``` -Expected: each grep prints at least one matching line. - -- [ ] **Step 4: Commit** - -```bash -cd ~/dev/skills -git add fieldtest/agents/fieldtester.md -git commit -m "fieldtester: add milestone-scope carrier variant - -Authoritative carrier contract for the milestone fieldtest: scoped to -milestone_promise, scenarios derived top-down rather than as a union of -per-cycle axes." -``` - ---- - -### Task 3: `fieldtest/SKILL.md` — document the milestone fieldtest variant - -**Files:** -- Modify: `fieldtest/SKILL.md` (new section after the Overview ending at line 35, before `## When to Use / Skipping`; Cross-references block) - -- [ ] **Step 1: RED — confirm the skill documents only the per-cycle scope** - -Run: -```bash -cd ~/dev/skills -grep -c "milestone fieldtest\|Two scopes" fieldtest/SKILL.md -``` -Expected: `0`. - -- [ ] **Step 2: Add a "Two scopes" section after the Overview** - -In `fieldtest/SKILL.md`, immediately before the line `## When to Use / Skipping`, insert: - -```markdown -## Two scopes: per-cycle and milestone - -`fieldtest` runs at two scopes, both using the same fieldtester -agent — the carrier picks the scope: - -- **Per-cycle fieldtest** (the default this file otherwise - describes): dispatched after a surface-touching cycle's audit, - carrier scoped to that cycle (`cycle_id` / `cycle_scope`). - Catches cycle-local friction early. Optional / orchestrator - judgement, as below. -- **Milestone fieldtest**: the closing gate for a tracker - milestone. Carrier scoped to the milestone's promise - (`milestone_id` / `milestone_promise`); the fieldtester - derives curated end-to-end scenarios top-down from that - promise and proves the shipped implementation delivers it. Its - green status roll-up is required before a surface-touching - milestone may be closed. - -Both carriers are defined authoritatively under **Carrier -contract** in `agents/fieldtester.md` (the milestone variant -under its **Milestone-scope variant** sub-heading). The gate the -milestone fieldtest feeds is defined once in -`../docs/pipeline.md` § Milestone-close gate — not restated -here. The milestone fieldtest is skippable on the same terms as -the per-cycle one, lifted to milestone level: a milestone whose -entire scope is internal (no user-visible surface) is exempt. - -``` - -- [ ] **Step 3: Add a gate cross-reference to the Cross-references block** - -In `fieldtest/SKILL.md`, find the `**Upstream gate:**` bullet: -``` -- **Upstream gate:** `../audit/SKILL.md` runs first; - fieldtest comes after a clean (or ratified) audit. -``` -Replace it with: -``` -- **Upstream gate:** `../audit/SKILL.md` runs first; - fieldtest comes after a clean (or ratified) audit. -- **Closing gate it feeds:** `../docs/pipeline.md` - § Milestone-close gate — the milestone fieldtest's green - roll-up is the functional leg of that gate. -``` - -- [ ] **Step 4: GREEN — confirm both additions** - -Run: -```bash -cd ~/dev/skills -grep -n "## Two scopes: per-cycle and milestone" fieldtest/SKILL.md -grep -n "Closing gate it feeds" fieldtest/SKILL.md -``` -Expected: each grep prints one matching line. - -- [ ] **Step 5: Commit** - -```bash -cd ~/dev/skills -git add fieldtest/SKILL.md -git commit -m "fieldtest: document the milestone fieldtest variant - -Name the per-cycle vs milestone scopes; the milestone fieldtest feeds -the functional leg of the milestone-close gate (single-sourced in -pipeline.md)." -``` - ---- - -### Task 4: `audit/SKILL.md` — drift-gate wording and the milestone red flag - -**Files:** -- Modify: `audit/SKILL.md` (Step 2 table line 74; carry-on path lines 107-110; Red Flags list) - -- [ ] **Step 1: RED — confirm "Audit can close" and no milestone red flag** - -Run: -```bash -cd ~/dev/skills -grep -n "Audit can close" audit/SKILL.md -grep -c "milestone" audit/SKILL.md -``` -Expected: first grep prints the Step 2 table line; the count is `0`. - -- [ ] **Step 2: Reword the green-exit row to a drift gate** - -In `audit/SKILL.md`, replace: -``` -| `0` | Green | All metrics within tolerance vs. the script's baseline. Audit can close. | -``` -with: -``` -| `0` | Green | All metrics within tolerance vs. the script's baseline. The cycle's drift gate is clear (drift-clean, not a milestone close — see `../docs/pipeline.md` § Milestone-close gate). | -``` - -- [ ] **Step 3: Annotate the carry-on commit body as drift-clean** - -In `audit/SKILL.md`, replace: -``` -- **carry-on path:** the audit-close commit body says - `cycle tidy (clean)` and ratifies whatever the - regression check drove. Audit commits always exist at cycle - close — they carry the architect findings, the regression - numbers, and the resolution. -``` -with: -``` -- **carry-on path:** the audit-close commit body says - `cycle tidy (clean)` and ratifies whatever the - regression check drove. Here `clean` means *drift-clean* — - the cycle's code matches the ledger; it is **not** a milestone - close, which additionally requires a green milestone fieldtest - (see `../docs/pipeline.md` § Milestone-close gate). Audit - commits always exist at cycle close — they carry the architect - findings, the regression numbers, and the resolution. -``` - -- [ ] **Step 4: Add the milestone red flag** - -In `audit/SKILL.md`, in the `## Red Flags — STOP` list, after the line: -``` -- "We'll re-run after the holidays" without a dated backlog issue -``` -add: -``` -- Declaring a milestone closeable on the strength of an - audit-clean while the milestone fieldtest has not run green — - audit proves drift-clean, never functional (see - `../docs/pipeline.md` § Milestone-close gate) -``` - -- [ ] **Step 5: GREEN — confirm all three edits** - -Run: -```bash -cd ~/dev/skills -grep -n "drift-clean, not a milestone close" audit/SKILL.md -grep -n "Here \`clean\` means \*drift-clean\*" audit/SKILL.md -grep -n "Declaring a milestone closeable" audit/SKILL.md -grep -n "Audit can close" audit/SKILL.md || echo "OK: stale wording gone" -``` -Expected: the first three print a line each; the last prints `OK: stale wording gone`. - -- [ ] **Step 6: Commit** - -```bash -cd ~/dev/skills -git add audit/SKILL.md -git commit -m "audit: clarify clean means drift-clean, not milestone close - -Reword the green-exit row, annotate the carry-on commit body, and add a -red flag: an audit-clean never licenses closing a milestone — that needs -a green milestone fieldtest (gate in pipeline.md)." -``` - ---- - -### Task 5: `boss/SKILL.md` — done-state references the gate - -**Files:** -- Modify: `boss/SKILL.md` (Done-state bullet, lines 120-121) - -- [ ] **Step 1: RED — confirm done-state restates the formula locally** - -Run: -```bash -cd ~/dev/skills -grep -n "audit clean, fieldtest clean if applicable" boss/SKILL.md -grep -c "Milestone-close gate\|not an automatic milestone close" boss/SKILL.md -``` -Expected: first grep prints the done-state line; the count is `0`. - -- [ ] **Step 2: Point done-state at the single-source gate** - -In `boss/SKILL.md`, replace: -``` -- **Done-state** — queue is empty AND the cycle is fully - ratified (audit clean, fieldtest clean if applicable). Go to - Step 5. -``` -with: -``` -- **Done-state** — queue is empty AND the cycle is fully - ratified (audit drift-clean, fieldtest clean if applicable). - Go to Step 5. A `/boss` done-state means this run has nothing - left to dispatch; it is **not** an automatic milestone close — - closing a tracker milestone needs its end-to-end milestone - fieldtest green and stays a deliberate manual act (see - `../docs/pipeline.md` § Milestone-close gate). -``` - -- [ ] **Step 3: GREEN — confirm the reference** - -Run: -```bash -cd ~/dev/skills -grep -n "not an automatic milestone close" boss/SKILL.md -grep -n "docs/pipeline.md.*Milestone-close gate" boss/SKILL.md -``` -Expected: each grep prints one matching line. - -- [ ] **Step 4: Commit** - -```bash -cd ~/dev/skills -git add boss/SKILL.md -git commit -m "boss: done-state is not a milestone close - -Reference the single-source gate; a /boss done-state means the queue is -empty, not that the tracker milestone may be closed." -``` - ---- - -### Task 6: `README.md` — fix the root cycle≡milestone conflation - -**Files:** -- Modify: `README.md` (lines 30-32; the `fieldtest` table row line 26) - -- [ ] **Step 1: RED — confirm the conflation and the bare "Optional" row** - -Run: -```bash -cd ~/dev/skills -grep -n "AILang calls a cycle a \*milestone\*" README.md -grep -n "surface-touching cycle | example fixtures" README.md -``` -Expected: both grep print their respective lines. - -- [ ] **Step 2: Rewrite the vocabulary paragraph to separate the axes** - -In `README.md`, replace: -``` -Vocabulary is configurable. AILang calls a cycle a *milestone* -and a sub-cycle an *iteration*; your project may call them -*release* and *sprint*, or *epic* and *story*, or whatever fits. -``` -with: -``` -Vocabulary is configurable. A **cycle** is one round in the -pipeline graph; your project may call it a *release*, an *epic*, -or whatever fits, and its sub-unit (the default *iteration*) a -*sprint* or a *story*. A **milestone** is a distinct, higher -axis — a tracker container (Gitea/GitHub milestone, Linear -project) that spans potentially many cycles and closes only when -the work it promised is complete *and* functional (see -`docs/pipeline.md` § Milestone-close gate). A cycle close is a -loop step; it is never a milestone close. -``` - -- [ ] **Step 3: Nuance the `fieldtest` table row** - -In `README.md`, replace: -``` -| `fieldtest` | Orchestrator-dispatched post-audit, surface-touching cycle | example fixtures + friction spec | Optional | -``` -with: -``` -| `fieldtest` | Orchestrator-dispatched post-audit | example fixtures + friction spec | Per-cycle optional; milestone fieldtest is the closing gate for a surface-touching milestone | -``` - -- [ ] **Step 4: GREEN — confirm the conflation is gone** - -Run: -```bash -cd ~/dev/skills -grep -n "calls a cycle a \*milestone\*" README.md || echo "OK: conflation removed" -grep -n "A \*\*milestone\*\* is a distinct, higher" README.md -grep -n "milestone fieldtest is the closing gate" README.md -``` -Expected: first prints `OK: conflation removed`; the other two print a line each. - -- [ ] **Step 5: Commit** - -```bash -cd ~/dev/skills -git add README.md -git commit -m "docs(readme): cycle is not a milestone - -Separate the pipeline-round axis (cycle) from the tracker-container axis -(milestone); note the milestone fieldtest as the closing gate." -``` - ---- - -### Task 7: `templates/project-profile.yml` — vocabulary and pipeline phase - -**Files:** -- Modify: `templates/project-profile.yml` (vocabulary block lines 40-43; pipeline block lines 66-74) - -- [ ] **Step 1: RED — confirm the wrong comment and missing milestone slots** - -Run: -```bash -cd ~/dev/skills -grep -n "what a top-level work unit is called" templates/project-profile.yml -grep -c "milestone" templates/project-profile.yml -``` -Expected: first grep prints the `cycle:` comment line; the count is `0`. - -- [ ] **Step 2: Fix the vocabulary block** - -In `templates/project-profile.yml`, replace: -``` -vocabulary: - cycle: cycle # what a top-level work unit is called - subcycle: iteration # what a sub-unit is called - ledger_entry: contract # what one design-ledger entry is called -``` -with: -``` -vocabulary: - cycle: cycle # one round in the pipeline graph (NOT the top-level container) - subcycle: iteration # a sub-unit of a cycle - milestone: milestone # tracker container spanning many cycles; closes only when complete AND functional - ledger_entry: contract # what one design-ledger entry is called -``` - -- [ ] **Step 3: Add the milestone-fieldtest phase to the pipeline block** - -In `templates/project-profile.yml`, replace: -``` - # fieldtest: { boss_only: true, when: surface_touch } -``` -with: -``` - # fieldtest: { boss_only: true, when: surface_touch } # per-cycle usability test - # milestone_fieldtest: { boss_only: true, when: surface_touch, gates_close: milestone } # closing gate: end-to-end proof of the milestone's promise -``` - -- [ ] **Step 4: GREEN — confirm the slots and that the YAML still parses** - -Run: -```bash -cd ~/dev/skills -grep -n "milestone: milestone" templates/project-profile.yml -grep -n "milestone_fieldtest" templates/project-profile.yml -python3 -c "import yaml,sys; yaml.safe_load(open('templates/project-profile.yml')); print('YAML OK')" -``` -Expected: first two grep print a line each; the python prints `YAML OK` (commented lines do not affect the parse, and the active vocabulary block stays valid). - -- [ ] **Step 5: Commit** - -```bash -cd ~/dev/skills -git add templates/project-profile.yml -git commit -m "profile: add milestone vocabulary slot and milestone_fieldtest phase - -Correct the cycle comment (a cycle is a pipeline round, not the -top-level container); add the milestone tracker-container slot and a -commented milestone_fieldtest phase that gates the milestone close." -``` - ---- - -### Task 8: `docs/profile-schema.md` — schema doc for the new slots - -**Files:** -- Modify: `docs/profile-schema.md` (vocabulary table line 130; pipeline example lines 184-186; minimal-profile example line 213) - -- [ ] **Step 1: RED — confirm the same conflation in the schema doc** - -Run: -```bash -cd ~/dev/skills -grep -n "What a top-level work unit is called" docs/profile-schema.md -grep -n " cycle: milestone" docs/profile-schema.md -grep -c "milestone_fieldtest" docs/profile-schema.md -``` -Expected: the first two grep print their lines (the table row and the minimal-profile example); the count is `0`. - -- [ ] **Step 2: Fix the vocabulary table row and add the milestone row** - -In `docs/profile-schema.md`, replace: -``` -| `cycle` | string | `cycle` | What a top-level work unit is called. Examples: `milestone`, `release`, `epic`. | -| `subcycle` | string | `iteration` | What a sub-unit is called. Examples: `iteration`, `sprint`, `story`. | -``` -with: -``` -| `cycle` | string | `cycle` | One round in the pipeline graph (NOT the top-level container). Examples: `cycle`, `release`, `epic`. | -| `subcycle` | string | `iteration` | A sub-unit of a cycle. Examples: `iteration`, `sprint`, `story`. | -| `milestone` | string | `milestone` | Tracker container spanning many cycles; closes only when complete AND functional (see `pipeline.md` § Milestone-close gate). Examples: `milestone`, `epic`, `release`. | -``` - -- [ ] **Step 3: Fix the minimal-profile example so it stops equating cycle with milestone** - -In `docs/profile-schema.md`, replace: -``` -vocabulary: - cycle: milestone - subcycle: iteration -``` -with: -``` -vocabulary: - cycle: cycle - subcycle: iteration -``` - -- [ ] **Step 4: Document the milestone-fieldtest phase in the pipeline section** - -In `docs/profile-schema.md`, in the `## pipeline` fenced YAML example, replace: -``` - fieldtest: - boss_only: true # only orchestrator dispatches - when: surface_touch # condition tag (orchestrator judgement) -``` -with: -``` - fieldtest: - boss_only: true # only orchestrator dispatches - when: surface_touch # condition tag (orchestrator judgement) - milestone_fieldtest: - boss_only: true - when: surface_touch # end-to-end proof of the milestone's promise - gates_close: milestone # its green roll-up is the functional leg of the milestone-close gate -``` - -- [ ] **Step 5: GREEN — confirm the schema doc is consistent** - -Run: -```bash -cd ~/dev/skills -grep -n "One round in the pipeline graph (NOT the top-level container)" docs/profile-schema.md -grep -n "| \`milestone\` | string" docs/profile-schema.md -grep -n "gates_close: milestone" docs/profile-schema.md -grep -n "^ cycle: milestone" docs/profile-schema.md || echo "OK: minimal example no longer equates cycle with milestone" -``` -Expected: the first three print a line each; the last prints the `OK:` message. - -- [ ] **Step 6: Commit** - -```bash -cd ~/dev/skills -git add docs/profile-schema.md -git commit -m "docs(schema): document milestone slot and milestone_fieldtest phase - -Correct the cycle vocabulary description, add the milestone container -slot, fix the minimal-profile example, and document the -milestone_fieldtest phase that gates the milestone close." -``` - ---- - -### Task 9: Final cross-file verification sweep - -**Files:** none modified — verification only. - -- [ ] **Step 1: No file still equates cycle with milestone** - -Run: -```bash -cd ~/dev/skills -grep -rn "calls a cycle a \*milestone\*\|top-level work unit\|^ cycle: milestone" \ - README.md docs/ templates/ audit/ fieldtest/ boss/ \ - && echo "FAIL: stale conflation remains" || echo "OK: no conflation remains" -``` -Expected: `OK: no conflation remains`. - -- [ ] **Step 2: The gate is defined once and referenced, not restated** - -Run: -```bash -cd ~/dev/skills -echo "definition (expect exactly 1, in pipeline.md):" -grep -rln "^## Milestone-close gate" docs/ audit/ fieldtest/ boss/ README.md -echo "references (expect audit, fieldtest, boss, README, profile-schema):" -grep -rln "Milestone-close gate" docs/ audit/ fieldtest/ boss/ README.md -``` -Expected: the definition list contains exactly `docs/pipeline.md`; the reference list additionally contains `audit/SKILL.md`, `fieldtest/SKILL.md`, `boss/SKILL.md`, `README.md`, `docs/profile-schema.md`. - -- [ ] **Step 3: The milestone carrier is single-sourced in the agent file** - -Run: -```bash -cd ~/dev/skills -echo "carrier definition (expect fieldtester.md):" -grep -rln "### Milestone-scope variant" fieldtest/ -echo "milestone_promise mentions:" -grep -rln "milestone_promise" fieldtest/ -``` -Expected: the variant heading appears only in `fieldtest/agents/fieldtester.md`; `milestone_promise` appears in both `fieldtest/agents/fieldtester.md` and `fieldtest/SKILL.md` (the skill references the field, the agent defines it). - -- [ ] **Step 4: The profile template still parses** - -Run: -```bash -cd ~/dev/skills -python3 -c "import yaml; yaml.safe_load(open('templates/project-profile.yml')); print('YAML OK')" -``` -Expected: `YAML OK`. - -- [ ] **Step 5: No commit needed** — this task only verifies. If any check fails, return to the owning task and fix before proceeding. - ---- - -## Notes for the executor - -- This repo commits directly on a working branch (`milestone-close-gate`); do not open PRs unless asked. `main` is sacrosanct — never reset/revert it. -- All prose is English (repo rule: anything committed is English). -- There is no build/test toolchain here; the `grep`/YAML checks above are the verification. Do not invent a test runner. -- Single-source discipline is the spine of this change: if a check in Task 9 shows the gate defined in more than one place, the fix is to replace the duplicate with a reference to `docs/pipeline.md`, not to keep both. diff --git a/docs/plans/2026-06-04-specify-entry-path.md b/docs/plans/2026-06-04-specify-entry-path.md deleted file mode 100644 index 4a2df2e..0000000 --- a/docs/plans/2026-06-04-specify-entry-path.md +++ /dev/null @@ -1,1123 +0,0 @@ -# `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 -# — 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). diff --git a/docs/specs/2026-05-31-glossary-integration-design.md b/docs/specs/2026-05-31-glossary-integration-design.md deleted file mode 100644 index c5cd260..0000000 --- a/docs/specs/2026-05-31-glossary-integration-design.md +++ /dev/null @@ -1,252 +0,0 @@ -# Glossary Integration — Design Spec - -**Date:** 2026-05-31 -**Status:** Draft — awaiting user spec review -**Authors:** orchestrator + Claude - -## Goal - -Give consuming projects a single, canonical place that pins -nomenclature so terminology does not drift over time, and so that -LLM-driven work reuses the established term for a concept instead of -coining a fresh synonym each session. The glossary is **guidance, -not enforcement**: it becomes standing reading for every skill and -agent, but no tool scans artefacts for forbidden synonyms. - -The plugin stays mechanics-only. This cycle adds: - -1. an optional profile slot `paths.glossary`, -2. a convention doc that owns the glossary format and the write - discipline, -3. standing-reading wiring so a set `paths.glossary` is read by - every role automatically, -4. a boss write-rule (record reality, never invent), -5. a dogfooded `docs/glossary.md` in this repo proving the format - on the plugin's own vocabulary. - -## Architecture - -The glossary rides the **existing standing-reading mechanism** -rather than introducing a new delivery path. One optional path slot -carries the whole feature: - -- `paths.glossary` (optional). **If set, the file it points to is - automatically standing reading for every agent** — no separate - `standing_reading.always` entry is required. If unset, the whole - feature is a documented no-op, exactly matching the plugin's - existing "missing optional slot = silent skip" contract. - -Semantics ("set ⇒ standing reading for all roles") live in -`docs/profile-schema.md` next to the slot, so the wiring is -single-sourced and a project cannot set the path yet forget to make -it read. - -The format and the write discipline live in a new -`docs/glossary-convention.md`, following the established -`docs/`-doc pattern (`pipeline.md`, `profile-schema.md`). Skills and -`boss` cross-reference it rather than restating it. - -## Concrete code shapes - -### 1. The delivered `docs/glossary.md` (dogfood — primary artefact) - -This is the actual file the feature produces, shown on the plugin's -own vocabulary. Per-term blocks (not a table) so boss-appended -entries produce clean line-wise diffs. - -```markdown -# Glossary - -Canonical nomenclature for this project. Use the **canonical term**; -never use a term under **Avoid**. If you need a concept that is not -listed here, reuse the closest existing term — do not silently coin -a new one. New entries are added only to record nomenclature already -in consistent use; see `docs/glossary-convention.md`. - ---- - -### cycle -**Avoid:** release, epic, round, sprint -One round in the pipeline graph (design → plan → execute → review → -close). Not the top-level container — that is a *milestone*. - -### milestone -**Avoid:** epic, phase, big-ticket -A tracker container spanning potentially many cycles; closes only -when its promised work is complete and functional. A cycle close is -never a milestone close. - -### iteration -**Avoid:** sprint, story, step -The default sub-unit of a cycle; one pass through the inner loop. A -project may rename it via `vocabulary.subcycle`. - -### drift -**Avoid:** divergence, rot, skew -Accumulated mismatch between the codebase and its design ledger. -Surfaced by the architect agent at audit, not by any synonym check. - -### hard-gate -**Avoid:** checkpoint, barrier, blocker -A pipeline point that forbids downstream work until an artefact -exists and is approved (e.g. an approved spec before any plan). -``` - -### 2. The profile slot (worked author example) - -What a consuming project writes — one line opts the whole project -in: - -```yaml -# <project>/.claude/dev-cycle-profile.yml -paths: - spec_dir: docs/specs - plan_dir: docs/plans - glossary: docs/glossary.md # optional — if set, every agent reads - # it as standing reading - code_roots: [src] -``` - -### 3. The boss write-rule (lives in `docs/glossary-convention.md`) - -`boss/SKILL.md` carries only a cross-reference pointer; the rule -text itself is single-sourced here: - -```markdown -## Extending the glossary (user + boss only) - -The user may edit the glossary at any time. In a `/boss` session the -orchestrator may extend it autonomously — but only to **record -reality, never to invent**: - -- A term already used consistently across shipped artefacts but not - yet listed → add it, with its known synonyms under **Avoid**. -- A drift the orchestrator just resolved (two terms for one concept) - → record the winner as the canonical entry, the loser under - **Avoid**. - -The orchestrator never coins a brand-new term into the glossary: a -term earns its entry by already being in consistent use. All other -skills and agents are read-only consumers of the glossary. -``` - -### Implementation shape (secondary — before → after) - -**`templates/project-profile.yml`**, `paths:` block: - -```yaml -# before -paths: - spec_dir: docs/specs - plan_dir: docs/plans - # design_ledger: design/INDEX.md # optional - code_roots: [src] - -# after -paths: - spec_dir: docs/specs - plan_dir: docs/plans - # glossary: docs/glossary.md # optional — if set, read as - # standing reading by every role - # design_ledger: design/INDEX.md # optional - code_roots: [src] -``` - -**`docs/profile-schema.md`**, `paths` section: add a `glossary` -entry documenting the slot AND the "set ⇒ standing reading for all -roles" semantics, and a no-op-when-unset note. - -**`docs/agent-template.md`** and **`docs/pipeline.md`**: where -standing reading is described, add one sentence: a set -`paths.glossary` is part of every role's standing reading. - -**`boss/SKILL.md`**: add a short pointer (in the process/loop and a -cross-reference entry) to `docs/glossary-convention.md` for the -record-reality write-rule. No rule text duplicated. - -## Components - -- **`docs/glossary.md`** (new) — dogfooded glossary for the plugin's - own vocabulary; the lived proof of the format. -- **`docs/glossary-convention.md`** (new) — single source for the - format (three fields: canonical term, Avoid synonyms, ≤2-sentence - definition), the standing-reading obligation, and the boss - record-reality write-rule. -- **`paths.glossary` slot** — in `templates/project-profile.yml` - (commented) and `docs/profile-schema.md` (documented). -- **Standing-reading wiring** — one sentence each in - `docs/agent-template.md` and `docs/pipeline.md`. -- **`boss/SKILL.md`** — cross-reference pointer to the convention. - -## Data flow - -Author/consume: - -1. A project sets `paths.glossary: docs/glossary.md` and writes the - file using the convention's three-field block format. -2. Every dispatched skill/agent, per the standing-reading contract, - reads the glossary alongside `CLAUDE.md` and the git-log entries. -3. When producing prose or naming a concept, the role uses the - canonical term and avoids the listed synonyms. - -Extend (boss): - -1. In `/boss`, when the orchestrator observes a term already in - consistent use but unlisted, or has just resolved a two-term - drift, it appends/edits one block per the convention. -2. The edit is an ordinary working-tree change committed under the - only-orchestrator-commits rule; no separate gate. - -Unset: - -- No `paths.glossary` ⇒ standing reading omits it, the convention - doc is inert reference, boss has nothing to extend. Documented - no-op. - -## Error handling - -- **Slot set but file missing:** a role that cannot read the - glossary treats it as it treats any missing standing-reading - source — notes the gap, proceeds; this is a profile error for the - project to fix, not a plugin failure. -- **Boss tempted to invent:** guarded by the convention's - red-flag/rationalisation framing ("a term earns its entry by - already being in use"); mirrors the existing boss anti-invention - discipline. -- **Convention vs. glossary drift:** the convention owns format and - rule; `docs/glossary.md` is an instance. The dogfood file is - expected to conform and serves as the conformance example. - -## Testing strategy - -This is a docs/profile cycle with no executable surface; the plugin -has no test runner (`commands.test` is empty for this repo). The -acceptance evidence is therefore the concrete artefacts above plus -two manual conformance checks: - -1. **Dogfood conformance:** every block in `docs/glossary.md` has - exactly the three fields the convention mandates (canonical term - heading, **Avoid:** line, ≤2-sentence definition). -2. **No-op proof:** the wording added to `profile-schema.md`, - `agent-template.md`, and `pipeline.md` states the unset-slot case - so a profile without `glossary` provably skips the feature. - -No fenced block in this spec targets a configured `spec_validation` -parser (this repo declares none); the parse-every-block gate is a -documented no-op here. - -## Acceptance criteria - -- `paths.glossary` documented in `docs/profile-schema.md` (slot + - "set ⇒ standing reading" semantics + unset no-op) and present - commented in `templates/project-profile.yml`. -- `docs/glossary-convention.md` exists and owns: the three-field - format, the standing-reading obligation, and the boss - record-reality write-rule (with the never-invent guard). -- `docs/agent-template.md` and `docs/pipeline.md` each state that a - set `paths.glossary` is standing reading for every role. -- `boss/SKILL.md` cross-references the convention for the write-rule - without duplicating its text. -- `docs/glossary.md` exists, dogfoods the plugin vocabulary, and - every entry conforms to the three-field format. -- With no `paths.glossary` set, the feature is a provable no-op. diff --git a/docs/specs/2026-05-31-glossary-skill-design.md b/docs/specs/2026-05-31-glossary-skill-design.md deleted file mode 100644 index 8238b4e..0000000 --- a/docs/specs/2026-05-31-glossary-skill-design.md +++ /dev/null @@ -1,299 +0,0 @@ -# glossary skill — Design Spec - -**Date:** 2026-05-31 -**Status:** Draft — awaiting user spec review -**Authors:** orchestrator + Claude - -## Goal - -Give the plugin an executable procedure for a project's glossary. Today -`docs/glossary-convention.md` declares the rules (three-field format, -reading obligation, the boss record-reality write-rule, glossary-as-SoT) -and `docs/glossary.md` dogfoods them — but nothing *does* anything. Two -gaps follow: - -- **No way to build a glossary for an existing project.** The convention - assumes a glossary already exists and is hand-maintained. A project - with terminology drift but no glossary has no on-ramp. -- **Hand-maintenance has no conformance check.** A user (or boss) adding - a term can silently break the three-field shape, exceed the - two-sentence limit, or collide with another entry (a new **Avoid** - synonym that is some other entry's canonical term, or vice versa). - -The `glossary` skill closes both gaps with one skill carrying two -procedures: **maintain** (guided, conformance-checked add / change / -remove of a single entry) and **bootstrap** (a fan-out of read-only -extraction agents that build a fresh glossary from a project's prose -surface). The skill is the executable procedure; the convention stays -the rules. The skill never restates the convention's format or -write-rule — it points to it and applies it. - -## Architecture - -`glossary` is a **utility skill**, invoked on demand like `issue` — not a -pipeline phase. It does **not** appear in the `design → plan → implement -→ audit` loop, takes no `pipeline:` profile entry, and gates nothing. - -It lives at `glossary/` with the standard layout: - -- `glossary/SKILL.md` — a mode dispatch at the head (`maintain` | - `bootstrap`) followed by the two procedures. -- `glossary/agents/glossary-extractor.md` — one dedicated, read-only, - template-conforming agent. - -`install.sh` links any top-level directory with a `SKILL.md` (and its -`agents/` subdir) by glob; the new skill and agent are picked up with no -change to the installer. - -**Role split, single-sourced.** `docs/glossary-convention.md` owns the -rules: the three-field format, the reading obligation, the boss -record-reality write-rule, and the glossary-as-source-of-truth -declaration. The `glossary` skill owns the *procedure* that applies those -rules. The skill points to the convention for every rule it enforces and -restates none of them, exactly as `boss/SKILL.md` points to the -convention for the write-rule rather than copying it. - -**Authority.** - -- *maintain* is governed by the existing write authority unchanged: the - user any time; boss autonomously but only to record reality, never to - invent (`glossary-convention.md` § Extending). The skill adds the - conformance check around that authority; it does not widen it. -- *bootstrap* is **user-only**. It is high-context multi-agent work - analogous to a fresh `brainstorm`, which boss bounces back rather than - starting autonomously. boss MAY recommend a bootstrap via a bounce-back - when a project lacks a glossary and drift is visible, but never runs - one itself. - -## Concrete code shapes - -### User-facing: a bootstrap run - -``` -User: /glossary bootstrap - -Skill: - 1. read paths.glossary → file is unset or empty (else: refuse, see Error handling) - 2. partition the prose surface into slices: - docs/, README.md, design-ledger (if paths.design_ledger set), specs/ - 3. fan out one glossary-extractor per slice (read-only) - 4. merge reports → cluster variants of the same concept - 5. clear cluster (one dominant variant) → draft entry, auto-included - contested cluster (≥2 comparable variants) → surface to user - 6. assemble the conforming glossary, write it UNSTAGED to paths.glossary - 7. user reviews the working-tree file -``` - -### Carrier and report (the glossary-extractor contract) - -``` -# carrier skill → glossary-extractor -slice: docs/ # the one prose slice this agent sweeps -task: "extract recurring domain-CONCEPT terms and their competing - synonyms as actually written; do NOT coin terms" - -# report glossary-extractor → skill (word-budgeted, structured) -- concept: cycle - variants: [cycle (41x), round (6x), sprint (2x)] - locations: [docs/pipeline.md:3, README.md:30] -- concept: design ledger - variants: [design ledger (12x), design index (9x)] - locations: [docs/profile-schema.md:15, docs/specs/...] -``` - -### Synthesis — a clear cluster becomes a conforming entry automatically - -``` -### cycle -**Avoid:** round, sprint, release, epic -One round in the pipeline graph (design -> plan -> execute -> review -> -close). Not the top-level container — that is a milestone. -``` - -### A contested cluster is surfaced, never auto-decided - -``` -Contested: "design ledger" (12x, docs/) vs "design index" (9x, specs/) -name the same concept. Which is canonical? - [design ledger] [design index] [other] -``` - -If the user does not resolve it, the concept is left OUT of the glossary -and noted as deferred — never coined. - -### User-facing: a maintain run, and the must-reject case - -``` -User: /glossary add (proposes) - ### design ledger - **Avoid:** drift - The canonical specification index ... <three sentences> ... - -Skill (local conformance, before writing): - REJECT — two violations, entry not written: - 1. definition is 3 sentences; the format allows at most 2. - 2. "drift" under **Avoid** is the canonical term of an existing - entry (docs/glossary.md "### drift"). A synonym cannot be - another entry's canonical term. - Fix and resubmit. -``` - -A conforming add, by contrast, passes the local check, then triggers the -stale-usage sweep: - -``` -Skill: conformance OK. Stale-usage sweep for the **Avoid** terms: - "design index" still appears at docs/profile-schema.md:15, specs/foo.md:8 - → these are drift you may want to fix; entry written UNSTAGED regardless. -``` - -### Implementation shape (secondary — what files change) - -New files: - -- `glossary/SKILL.md` — head: `> Violating the letter...` lead-in, - Overview, When to Use / Skipping, a **Mode dispatch** section routing - `maintain` vs `bootstrap`, then the two numbered procedures, Handoff - Contract, Common Rationalisations, Red Flags, Cross-references. -- `glossary/agents/glossary-extractor.md` — per `docs/agent-template.md`: - frontmatter (`name: glossary-extractor`, third-person description, - `tools: Read, Glob, Grep, Bash`), spirit-letter lead-in, What this role - is for, Standing reading list, Carrier contract, Iron Law, The Process, - Status protocol, Output format, Common Rationalisations, Red Flags. - -Edited files (one referencing sentence each — no rule restated): - -- `boss/SKILL.md` — in § Direction freedom / Notifications, one sentence: - boss may recommend a bootstrap via bounce-back when a project lacks a - glossary and drift is visible, but never runs one autonomously (it is - high-context work like a fresh brainstorm). -- `docs/glossary-convention.md` — in § Extending, one tooling pointer: - the `glossary` skill is the executable procedure for building and - extending a glossary; this file stays the rules. -- `README.md` — the skill listing is updated to include `glossary` as a - utility skill (like `issue`). Note the current README has **no** - agent-roster note to extend (its "Eight skills" table carries only - Trigger / Output / Mandatory columns), and that "Eight skills" framing - is already stale — it omits the existing utility skill `issue`. The - edit therefore adds `glossary` to the listing and reconciles the - framing so the listing is accurate, rather than appending to a roster - note that does not exist. No agent-roster surface is created — the - agent roster lives in the per-skill `agents/` directories, not in - README. - -## Components - -### `glossary/SKILL.md` - -A mode-dispatch skill. The head routes on the invocation: - -- **maintain** — add / change / remove one entry. Steps: (1) read the - glossary and the convention; (2) take the proposed entry; (3) run the - **local conformance check** — three-field shape, definition ≤ 2 - sentences, and the collision scan (a proposed canonical term must not - already sit under another entry's **Avoid**; a proposed **Avoid** - synonym must not be another entry's canonical term); reject with the - named rule on failure, do not write; (4) on add / change / rename, run - the **stale-usage sweep** — grep the old canonical and the **Avoid** - synonyms across the prose surface and report the hits as drift the user - may want to fix; (5) write the conforming entry UNSTAGED; (6) hand back - to the user (or, in a boss session, the boss record-reality discipline - governs whether the write was permitted at all). - -- **bootstrap** — build a new glossary. Steps as in § Concrete code - shapes: empty/unset check, partition, fan-out, merge + cluster, - auto-include clear winners, surface contested clusters, assemble - UNSTAGED, user review. - -The skill restates none of the convention's rules; it cites -`docs/glossary-convention.md` for the format and the write-rule and -`docs/profile-schema.md` § `paths` for the `paths.glossary` semantics. - -### `glossary/agents/glossary-extractor.md` - -A read-only extraction agent. **Failure mode it exists to prevent:** an -orchestrator sweeping a whole project's prose in its own context to coin -a glossary — blowing context and conflating orchestration with -execution, and tempting invention over observation. The agent sweeps one -slice, reports *observed* concept terms and their competing variants with -frequencies and locations, and coins nothing. The skill fans out one -agent per slice and curates each carrier; agents do not nest (Claude Code -platform constraint). - -## Data flow - -**maintain.** proposal → local conformance (format, ≤2 sentences, -collision scan) → reject-with-rule on failure / continue on pass → (add / -change / rename) stale-usage sweep → report stale hits → write conforming -entry UNSTAGED → user review. boss-initiated writes stay bound to -record-reality. - -**bootstrap.** user invokes → empty/unset guard → partition prose surface -into slices → fan out N × glossary-extractor → merge reports → cluster -variants → clear cluster auto-included as entry / contested cluster -surfaced to user for the canonical choice → unresolved contested cluster -left out (deferred, never coined) → assemble conforming glossary file -UNSTAGED → user review. - -## Error handling - -- **`paths.glossary` unset.** bootstrap still builds a glossary and - proposes setting the slot (pointing at `docs/profile-schema.md` § - `paths`); maintain has no target and stops, instructing the user to set - the slot first. -- **bootstrap on a populated glossary.** No clobber. The skill stops with - a diagnosis ("glossary already has N entries") and recommends maintain - for incremental work. -- **conformance failure in maintain.** The entry is rejected with the - specific rule cited and is NOT written. (This is the must-fail evidence - for the feature-acceptance criterion: a wrong entry must fail the - check.) -- **glossary-extractor returns empty or BLOCKED.** The skill reports the - empty slice and fabricates no terms — record reality, never invent. -- **contested cluster the user does not resolve.** Left out of the - glossary entirely and noted as deferred. The skill never picks a - canonical term for a genuinely contested cluster on its own. - -## Testing strategy - -This repo ships no test runner; it is docs / prose only. Following the -glossary-integration cycle precedent, each implementation task closes on -a grep presence-assertion against the file it touches, calibrated against -a verified zero baseline (the `git log` for that cycle records the -mis-calibrated-grep failure mode to avoid: assert against the unwrapped -line, not a pattern that straddles a line break). - -The behavioural evidence is the worked examples embedded in § Concrete -code shapes: a conforming entry accepted, a non-conforming entry rejected -with the named rule, and a contested cluster surfaced to the user. These -are the empirical evidence the feature-acceptance criterion demands for a -no-executable-surface infra cycle. - -No `spec_validation` parser is configured for this repo, so the -brainstorm parse-every-block gate is a documented no-op here: the fenced -blocks in this spec are illustrative CLI / prose, none carrying a fence -label with a configured parser. - -## Acceptance criteria - -1. `glossary/SKILL.md` exists with a mode dispatch (`maintain` | - `bootstrap`) and both procedures. -2. `glossary/agents/glossary-extractor.md` exists, conforms to - `docs/agent-template.md`, and is read-only (`tools: Read, Glob, Grep, - Bash`). -3. The skill single-sources against `docs/glossary-convention.md`: it - cites the format and write-rule and restates neither. -4. bootstrap is user-only; `boss/SKILL.md` carries one sentence wiring - the boss-may-recommend-via-bounce-back rule. -5. maintain runs the local conformance check plus the stale-usage sweep; - a non-conforming proposed entry is rejected with the named rule and - not written. -6. bootstrap surfaces contested clusters to the user, auto-includes clear - winners, and never coins a contested canonical term. -7. `README.md`'s skill listing includes `glossary` as a utility skill and - the stale "Eight skills" framing (which omits the existing `issue` - utility skill) is reconciled so the listing is accurate; no - agent-roster note is added (none exists). `docs/glossary-convention.md` - carries a one-line tooling pointer to the skill. -8. `install.sh` links the new skill and agent with no change to the - installer (the existing glob covers them). diff --git a/docs/specs/2026-05-31-milestone-close-gate-design.md b/docs/specs/2026-05-31-milestone-close-gate-design.md deleted file mode 100644 index a4f692d..0000000 --- a/docs/specs/2026-05-31-milestone-close-gate-design.md +++ /dev/null @@ -1,241 +0,0 @@ -# Milestone-close gate: separating `cycle` from `milestone` - -**Date:** 2026-05-31 -**Status:** approved (design) -**Topic:** make `audit` unable to imply a milestone is finished; -add a milestone-wide fieldtest as the closing gate. - -## Problem - -`audit` runs at cycle close and emits a "clean" signal whose -commit body reads `cycle <X> tidy (clean)`. `audit` only proves -*drift-clean* — the code matches the design ledger. It is blind -to whether the work is *functional* from a downstream -consumer's point of view; that is exactly what `fieldtest` -measures, and `fieldtest` runs *after* `audit`. - -Two defects follow: - -1. **Conflation of `cycle` and `milestone`.** `README.md` - ("AILang calls a cycle a *milestone*") and - `templates/project-profile.yml:41` (`cycle: # what a - top-level work unit is called`) treat a cycle as the - top-level work unit. It is not. A **milestone** is a tracker - (Gitea) container that closes only when the work is - *completely implemented and functional*. A **cycle** is one - round in the pipeline graph — a step in the loop. A milestone - spans potentially many cycles. - -2. **An audit-clean signal can leak into a milestone close.** - Because `audit`'s "clean" reads like "done", an orchestrator - can be led to close a Gitea milestone on the strength of an - audit, before any fieldtest has demonstrated the work is - functional. No skill closes a milestone today, so this is a - conceptual hazard rather than a code path — but the wording - actively invites the mistake. - -The fix is **not** to swap the `audit → fieldtest` order: -`fieldtest` needs the drift-clean state to test against, so -`audit` must stay first. The fix is to **decouple the gate** — -`audit`'s "clean" never closes anything, and a separate, -explicitly defined milestone-close gate requires both -completeness and functional validation. - -## Conceptual model - -### Two distinct axes - -- **Cycle** — one round in the pipeline graph - (`brainstorm → planner → implement → audit → [per-cycle - fieldtest]`). A cycle close is an internal loop step. Many - cycles per milestone. -- **Milestone** — a tracker (Gitea) container. Closes **only** - when *complete* (every cycle drift-clean / ratified, no open - iterations) **and** *functional* (milestone fieldtest green). - -### Three disentangled "clean" terms - -| Term | Owner | Means | Closes a milestone? | -|------|-------|-------|---------------------| -| `drift-clean` | `audit` | code matches the ledger | never | -| cycle functionally validated | per-cycle `fieldtest` | cycle-local surface usable | never | -| milestone closeable | milestone-close gate | complete ∧ functional | yes (manual act) | - -### Two fieldtest scopes - -The milestone fieldtest is a **scope variant** of the existing -`fieldtest` skill — same `fieldtester` agent, a different -carrier. No new skill; keeps the surface DRY. - -- **Per-cycle fieldtest** (existing, unchanged): carrier carries - `cycle_id` / `cycle_scope`; dispatched after a - surface-touching cycle's audit; catches cycle-local friction - early; optional / orchestrator-dispatched as today. -- **Milestone fieldtest** (new variant): carrier carries - `milestone_id` and `milestone_promise` — the milestone's - stated goal / acceptance in the tracker (and its spec, if one - exists). The fieldtester derives a small set of **curated - end-to-end scenarios** that, run as a downstream consumer, - prove the shipped implementation delivers **what the milestone - as a whole promised**. Scenarios are chosen *top-down from the - milestone's promise*, not assembled bottom-up as the - mechanical union of per-cycle axes — the per-cycle fieldtests - already cover axis-local surface; the milestone fieldtest's - job is to demonstrate the promise end to end. Its green status - roll-up is the closing gate. - -## The milestone-close gate (authoritative) - -A milestone may be closed in the tracker only when **both** legs -hold: - -1. **Complete** — every cycle filed under the milestone is - `audit` drift-clean (or its drift explicitly ratified), and - the milestone container has no open iterations / issues - remaining. -2. **Functional** — the milestone fieldtest has run its curated - end-to-end scenarios against the milestone's promise and its - status roll-up is `clean`: every scenario demonstrably - delivers what the milestone promised; no open `bug` findings; - `friction` / `spec_gap` findings either resolved or - explicitly ratified into the design ledger. - -No `audit` result, and no `/boss` done-state, closes a milestone -on its own. `/boss` done-state means "this `/boss` run has -nothing left to dispatch" — it is **not** a milestone close. - -The actual close (`tea milestone close`, or the tracker -equivalent) stays a **deliberate human / orchestrator act**, -performed only after the gate reads green. This design defines -*when* a milestone is closeable; it does **not** mechanise the -close. (`issue/SKILL.md` is out of scope here.) - -### Edge cases - -- **Non-surface milestone.** A milestone whose entire scope is - internal (refactor, infra, docs) touches no user-visible - surface. The milestone fieldtest is then *not applicable* - (same skip logic as the per-cycle fieldtest, lifted to - milestone level). The "functional" leg is satisfied vacuously; - the "complete" leg (audit-clean across cycles) suffices. -- **Single-cycle milestone.** Nothing special: the milestone - fieldtest still runs (if surface-touching), proving the - milestone's promise end to end even though that promise - happened to ship in a single cycle. The per-cycle and - milestone fieldtests may coincide in surface but remain - conceptually distinct gates — axis-local validation versus - promise-level proof. -- **Ratified drift.** A cycle whose drift was ratified - (`--update-baseline` + ratify paragraph) counts as satisfying - the "complete" leg for that cycle — ratification is the - documented form of "complete". - -## Per-file changes - -Single-source discipline (consistent with the recent -carrier/handoff single-sourcing): the gate is **defined once** -in `docs/pipeline.md`; every other file **references** it rather -than restating it, so the files cannot drift. - -### `docs/pipeline.md` (single source) - -- ASCII graph: rename `audit --(clean)` to `audit - --(drift-clean)`; annotate `[cycle close]` explicitly as a - loop step, not a milestone end. -- New subsection **"Cycle vs. milestone"** — defines the two - axes authoritatively (a milestone spans many cycles; a cycle - is one loop round). -- New subsection **"Milestone-close gate"** — the authoritative - gate definition above (complete ∧ functional), names the - milestone fieldtest as a mandatory precondition for - surface-touching milestones, and states plainly that no - `audit` and no `/boss` done-state closes a milestone. - -### `audit/SKILL.md` - -- Step 2 table: "Audit can close" → drift-gate wording. `audit` - clears the *cycle drift check*; it does not close the cycle or - the milestone. -- Close-commit wording (`cycle <X> tidy (clean)`): kept, but - annotated explicitly as *drift-clean, not a milestone signal*. -- New **Red Flag**: "Declaring a milestone closeable on the - strength of an audit-clean, while the milestone fieldtest has - not run green." Cross-reference the gate in `docs/pipeline.md`. -- Overview: clarify `audit` ↔ cycle close (never milestone). - -### `fieldtest/SKILL.md` - -- Document the second trigger variant — the **milestone - fieldtest** (milestone-wide, end-to-end): carrier carries - `milestone_id` and `milestone_promise`; the fieldtester - derives curated end-to-end scenarios from the milestone's - promise (top-down, not a union of per-cycle axes) and proves - the shipped implementation delivers it; its green status - roll-up is the closing gate. Reference the gate in - `docs/pipeline.md` rather than restating it. -- The "audit first" precondition stays, for both variants. -- The milestone-fieldtest skip logic mirrors the per-cycle one, - lifted to milestone level (non-surface milestone → exempt). - -### `boss/SKILL.md` - -- Done-state: reference the `docs/pipeline.md` gate instead of - restating the formula. Clarify that a `/boss` done-state is - **not** an automatic milestone close — the milestone close - needs the milestone fieldtest green and is a manual act. - -### `README.md` - -- **Root fix**: correct the `cycle ≡ milestone` conflation - (the "AILang calls a cycle a *milestone*" lines). Cycle = a - pipeline round; milestone = a tracker container spanning many - cycles, closed only when complete ∧ functional. -- `fieldtest` row: per-cycle fieldtest stays optional; note the - milestone fieldtest as the mandatory gate before a - surface-touching milestone closes. - -### `templates/project-profile.yml` - -- Fix the `cycle:` comment ("top-level work unit" is wrong — a - cycle is the pipeline round). -- Add a `milestone:` vocabulary field for the tracker container. -- Add the milestone-fieldtest phase to the pipeline config (so a - project can name / gate it), consistent with the existing - `pipeline:` configuration model. - -### `docs/profile-schema.md` - -- Same root conflation lives here: the `vocabulary` table - (`cycle` = "top-level work unit", with `milestone` as an - example value) and the minimal-profile example (`cycle: - milestone`). Correct both — document `cycle` as the pipeline - round and add the `milestone` vocabulary field as the tracker - container. -- Document the milestone-fieldtest phase in the `pipeline` - section alongside the existing `fieldtest` phase. - -## Scope boundaries - -**In scope:** the gate definition and the wording/decoupling -across `docs/pipeline.md`, `audit`, `fieldtest`, `boss`, -`README.md`, `templates/project-profile.yml`; the milestone -fieldtest as a carrier-scope variant of the existing skill. - -**Out of scope:** mechanising the tracker close (no -`issue/SKILL.md` change, no automated `tea milestone close`); -reordering `audit → fieldtest`; any change to the per-cycle -fieldtest's existing behaviour beyond naming it "per-cycle". - -## Verification - -- Grep sweep: no remaining file equates `cycle` with - `milestone`; the only authoritative gate definition lives in - `docs/pipeline.md`, and `audit` / `fieldtest` / `boss` - reference it without restating it. -- `audit/SKILL.md` carries the new Red Flag and drift-gate - wording; its close-commit example is annotated as drift-clean. -- `fieldtest/SKILL.md` documents both carrier scopes and the - milestone-level skip rule. -- `templates/project-profile.yml` parses (YAML) with the new - `milestone:` vocabulary field and the milestone-fieldtest - phase, and `docs/profile-schema.md` stays consistent with it. diff --git a/docs/specs/2026-06-04-specify-entry-path-design.md b/docs/specs/2026-06-04-specify-entry-path-design.md deleted file mode 100644 index d305f97..0000000 --- a/docs/specs/2026-06-04-specify-entry-path-design.md +++ /dev/null @@ -1,308 +0,0 @@ -# `specify` — Spec-Production Entry Path — Design Spec - -**Date:** 2026-06-04 -**Status:** Draft — awaiting user spec review -**Authors:** orchestrator + Claude - -## Goal - -Add a third entry path into the dev cycle: a `specify` skill that -produces an approved spec from **given sources** (a long in-context -design discussion, an exhaustive tracker issue, settled design -docs) — with review, but **without an interview**. - -The driving observation: when the design is already settled, today's -`brainstorm` forces redundant work — it re-opens an interview and -re-litigates decisions the sources already made. That is friction, -and worse, the re-litigation invites reactive churn on settled -calls. But the *production* half of `brainstorm` — apply the -acceptance criterion, write the spec, parse-gate it, ground-check -it, get user sign-off — is wanted in every case. `specify` is that -production half, callable on its own. - -The split is the existing toolchain philosophy applied one level up. -`tdd → implement` and `debug → implement` split a discipline across -two dispatches so the spec stays honest (the test is written before -any implementation). `specify` does the same to design work: a -**deciding** phase (`brainstorm`) and a **producing** phase -(`specify`), split so the producing phase reads the decision as a -*source* rather than making it inline. - -## Architecture - -Three co-equal entry paths feed one production core. `specify` is -the sole home of the production gates; `brainstorm` becomes an -**optional** discovery front-end. - -``` -brainstorm ──► specify ──► planner ──► implement design open (discovery + production) - specify ──► planner ──► implement design settled in sources -tdd ─────────────────────► implement (mini) test-specifiable (test = spec) -debug ───────────────────► implement (mini) bug (RED-first) - ▲ - └── bounce ── specify / tdd unresolved design fork → discovery -``` - -**The hard-gate moves.** Today `brainstorm` itself is the "no plan -without an approved spec" gate. After this cycle, **`specify`** -carries that invariant (it produces and gets sign-off on the spec, -and gates `planner`); `brainstorm` is no longer itself a gate — it -is the optional discovery stage before `specify`. The universal -invariant — *no plan without an approved spec* — is unchanged -word-for-word; only its carrier moves from `brainstorm` to -`specify`. - -**The bounce-back symmetry.** `specify` is a fast path that is only -legitimate when its precondition holds — the sources resolve every -load-bearing design decision. The moment writing the spec would force -a choice between plausible designs the sources do not resolve, it -STOPs and bounces to `brainstorm`. This is structurally identical to -`tdd`'s bounce: `tdd` bounces when one honest assertion cannot pin -the behaviour; `specify` bounces when the sources cannot pin the -design. Both fast paths fall back to the same discovery skill. - -**Discovery vs. production, by verb.** `brainstorm` owns *deciding*: -interview, explore 2–3 approaches, ratify the chosen design with the -user. `specify` owns *producing*: render the decision into the -canonical spec artefact, run all gates, get artefact sign-off. The -two reviews are different: `brainstorm`'s per-section ratification -asks "is this design right?"; `specify`'s Step-8 review asks "is the -written spec faithful and complete?". In the direct path there is no -design ratification (no discovery happened) — only the artefact -review. That absence *is* "with review, but without interview". - -## Concrete code shapes - -The canonical authoring form for this prose-skill project is the -SKILL.md body and the cross-skill topology. The user-facing artefact -the cycle delivers is `specify/SKILL.md` and the edited dispatch -logic in `boss`. - -### `specify/SKILL.md` — the Iron Law (the load-bearing shape) - -``` -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 OR CODE WORK UNTIL THE SPEC HAS BEEN PRESENTED AND THE USER HAS APPROVED IT. -``` - -### `specify/SKILL.md` — process spine - -``` -Step 1 Explore / re-ground context - - direct entry: read the sources (issue body, in-context - discussion, design docs) + git log; this IS the design input. - - chain entry (from brainstorm): the ratified design narrative - is in-context; re-ground lightly (fresh git log, touched files). -Step 1.5 PRECONDITION GATE - - enumerate the load-bearing design decisions the spec must encode. - - for each: do the sources resolve it, or am I about to pick one? - - any unresolved fork → BOUNCE to brainstorm (see Error handling). -Step 2 Apply the feature-acceptance criterion + write the concrete code - (the worked user-facing example = the criterion's empirical evidence). -Step 3 Write the spec under paths.spec_dir (mandated structure). -Step 4 Self-review (placeholder / consistency / scope / ambiguity / - concrete-code / parse-every-block gate). -Step 5 Grounding-check (hard-gate) — dispatch read-only grounding-check. -Step 6 User-review gate — spec sits uncommitted; await approval; - on change request re-run Step 4 AND re-dispatch Step 5. -Step 7 Hand off to planner (spec path + iteration scope). -``` - -`specify` has **no interview step and no approaches step** — those -are `brainstorm`'s. It dispatches the existing `grounding-check` -agent; it introduces **no new agent**. - -### `boss` — the three-way Entry-path reflection - -``` -boss Entry-path reflection (feature work, tdd-enabled profile): - - one honest minimal assertion pins the behaviour → tdd [autonomous] - sources resolve every load-bearing decision → specify [autonomous] - writing one assertion / spec forces an unresolved - design choice → brainstorm [bounce-back] - - asymmetry: tdd and specify are bounded (no open Q&A) → dispatch autonomously. - brainstorm is high-context discovery the orchestrator cannot - compact on its own → bounce-back before dispatch. - specify in /boss still pauses internally at its Step-6 user-review gate - (problem-state notify: "spec X ready, please sign off") — that is the - final sign-off pause, NOT a pre-dispatch checkpoint. -``` - -### Implementation shape (secondary — the before → after of each edited file) - -``` -brainstorm/SKILL.md - - Step 6–9 (write spec, self-review, grounding-check, user-review, hand off - to planner) ──► REMOVED (moved to specify). - - Step 9 terminal "invoke planner" ──► "hand ratified design to specify". - - Hard-Gate block + "spec before plan" framing ──► removed / re-pointed: - brainstorm is no longer itself the gate. - - Skip rules: brainstorm gains an explicit "optional when design is settled - in sources — that is specify's direct path" clause. - -boss/SKILL.md - - Entry-path reflection: two-way ──► three-way (add the specify branch). - - Pipeline ASCII block: add specify node on the brainstorm→planner edge. - - Common Rationalisations / Red Flags: add the "route settled design to - brainstorm to be safe" anti-pattern (mirror of the existing tdd one). - -docs/pipeline.md - - ASCII graph: brainstorm ─► specify ─► plan; specify ─► plan direct edge; - specify ─(design fork)─► brainstorm bounce edge. - - Phase descriptions: new `specify` block; brainstorm block trimmed to discovery. - - Skip rules: "brainstorm is never skipped at cycle start" ──► "specify is - never skipped at cycle start; brainstorm is the optional discovery stage - before it, skipped when the design is already settled in the sources". - -docs/profile-schema.md, docs/design.md, README.md - - profile-schema pipeline: gates:[planner] moves brainstorm ──► specify; - specify documented as a CORE node (not opt-in, unlike tdd). - - design.md pipeline-form line + README skill table: add specify row, - flip brainstorm's "Mandatory?" cell to optional-discovery. - -tdd/SKILL.md - - Cross-references: name specify as the sibling fast path with the same - bounce-to-brainstorm discipline. -``` - -## Components - -- **`specify/SKILL.md` (new).** The production core. Follows the - skill template: Overview, When to Use / Skipping, the Iron Law - (precondition gate + bounce-back + non-negotiable gates), the - numbered process spine above, Handoff Contract, Common - Rationalisations, Red Flags, Cross-references. Dispatches - `grounding-check`; no new agent. - -- **`brainstorm/SKILL.md` (edited).** Shrinks to discovery: explore - context, interview, 2–3 approaches, per-section design - ratification. Terminal state changes from `planner` to `specify`. - The hard-gate language and the spec-writing / self-review / - grounding-check / user-review / planner-handoff steps are removed - (they now live in `specify`). brainstorm no longer writes a spec - file; it hands a ratified design narrative to `specify` in-context. - -- **`boss/SKILL.md` (edited).** Entry-path reflection becomes - three-way. `specify` direct-entry is autonomously dispatchable - (bounded, like `tdd`/`debug`), pausing only at its internal - user-review gate. The pre-dispatch bounce-back stays reserved for - a fresh `brainstorm` cycle (high-context) and for a surfaced fork. - -- **`tdd/SKILL.md` (edited).** Cross-references gain `specify` as the - sibling fast path sharing the bounce-to-`brainstorm` discipline. - -- **`docs/pipeline.md`, `docs/design.md`, `README.md`, - `docs/profile-schema.md` (edited).** Pipeline graph, phase - descriptions, skip rules, skill table, and the profile pipeline - block updated so all four renderings of the pipeline agree on the - three-path shape and on `specify` as the new production gate. - -## Data flow - -Carrier contracts (the in-context narrative is the carrier where two -skills run in the same orchestrator context — no intermediate -artefact, exactly as `tdd → implement` carries the chat history plus -the RED-test path): - -| 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` — same carrier brainstorm uses today | -| `specify` → `planner` (Step 7, on PASS or overridden BLOCK) | path to spec + iteration scope | -| `specify` → `brainstorm` (precondition bounce, or no-override BLOCK route) | the unresolved design question as a cycle request | -| `boss` Entry-path reflection | dispatches `tdd` / `specify` autonomously, or bounces back a fresh `brainstorm` cycle | - -## Error handling - -- **Precondition fails (Step 1.5).** `specify` finds, while - enumerating the load-bearing decisions, a fork the sources do not - resolve. It STOPs *before writing the spec* and bounces to - `brainstorm` with the design question as a cycle request. The - working tree is clean — nothing was written. This is the cheap, - early bounce (cheaper than `tdd`'s, which may discard a written - test). - -- **grounding-check `BLOCK` (Step 5).** Identical failure-mode - procedure to today's `brainstorm`: present the report; on no - override, delete the just-written spec from the working tree, file - a forward backlog issue (or milestone container) naming the - unratified dependency, tell the user, end the session. - -- **grounding-check `INFRA_ERROR`.** Abort; spec stays on disk; - debug the workspace out-of-band; re-dispatch. - -- **Step-6 change request.** Edit the spec in place (still - uncommitted), re-run Step 4 (self-review) AND re-dispatch Step 5 - (grounding-check) — the previous PASS no longer covers the edited - bytes — then return to the review gate. - -- **`specify` in `/boss`.** Dispatched autonomously; runs criterion, - parse-gate, and grounding-check without a checkpoint; **pauses at - the Step-6 user-review gate** as a problem-state notify ("spec X - ready, please sign off"). The distinction from `brainstorm`: no - *pre-dispatch* checkpoint (specify is bounded, no interview), only - the final artefact sign-off. - -## Testing strategy - -This is a prose / Markdown skill repo with no executable test suite -and (currently) no `dev-cycle-profile.yml`. "Tests" are -**internal-consistency** properties, verified by `audit` / -architect drift-review at cycle close: - -1. **No path-count drift.** No skill or doc still asserts the - two-path model. Every mention of the entry paths names three. -2. **Pipeline renderings agree.** The pipeline graph in - `docs/pipeline.md`, `README.md`, `docs/design.md`, and `boss` - are mutually consistent on the three-path shape and on `specify` - as the production gate. -3. **`specify/SKILL.md` follows the template.** Iron Law, numbered - process, Handoff Contract, Common Rationalisations, Red Flags, - Cross-references all present. -4. **No orphaned gate language in `brainstorm`.** No leftover - hard-gate / spec-writing / planner-handoff prose; its terminal - state names `specify`. -5. **Carrier contracts close.** Every `specify` carrier has a named - counterpart skill, and every skill that hands to `specify` (user, - brainstorm, boss reflection) is reflected in `specify`'s own - Handoff Contract. - -**Note on the Step-5 grounding-check during this very cycle.** Because -this repo has no test suite and no profile, the `grounding-check` -hard-gate is degenerate here — there is nothing green to ratify and -the agent is under-configured. The spec's load-bearing assumptions are -plain SKILL.md content facts (brainstorm's current terminal is planner; -tdd is opt-in; boss has a two-way reflection), read and verified -directly during exploration. The agent is therefore **not dispatched -into the void**; this paragraph is the visible trace that the gate was -consciously skipped for a degenerate setup, not silently bypassed. - -## Acceptance criteria - -Default criterion (no project CLAUDE.md): solves a real user-facing -problem; contradicts no stated design commitment. - -- **Real problem solved.** When the design is settled in the - sources, the orchestrator reaches `planner` through `specify` - with no interview and no re-litigation of settled decisions — - while still passing every production gate. -- **Anti-deference preserved (the load-bearing one).** `specify` - cannot become the lazy "sources look exhaustive, skip the - interview" path: the Step-1.5 precondition gate forces an honest - fork check, an unresolved fork bounces to `brainstorm`, and the - grounding-check and user-review gates are retained unchanged. The - reactive-deference failure class `brainstorm` exists to prevent is - not reintroduced. -- **Consistent with the toolchain's deepest commitment.** The - deciding→producing split mirrors the RED→GREEN split that keeps - `tdd`/`debug` honest; `specify` is a co-equal third entry path, - chosen by reflection, never a default. -- **No drift.** All four pipeline renderings and every cross- - reference agree on the three-path shape (verified by audit).