chore: remove this repo's own committed specs/plans
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.
This commit is contained in:
@@ -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`.
|
||||
@@ -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: <short concept label>
|
||||
variants: [<variant> (<count>x), <variant> (<count>x), ...]
|
||||
locations: [<path:line>, <path:line>, ...]
|
||||
```
|
||||
|
||||
End with a one-line `Swept: <n> files in <slice>` summary. On an empty
|
||||
slice, emit `No recurring concept terms found in <slice>.`
|
||||
|
||||
## 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.
|
||||
@@ -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` | `<milestone-start>..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 <X> 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 <X> 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.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
@@ -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).
|
||||
@@ -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.
|
||||
@@ -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).
|
||||
Reference in New Issue
Block a user