79d269463d
Adds a new utility skill `glossary` (invoked on demand like `issue`, not a pipeline phase) carrying two procedures over a project's glossary: - maintain: guided add / change / remove of one entry with a local conformance check (three-field shape, <=2-sentence definition, collision scan against existing entries) plus a stale-usage sweep on change/rename. A non-conforming entry is rejected with the named rule, not written. - bootstrap (user-only): a fan-out of read-only glossary-extractor agents over the project's prose surface, merged and clustered into conforming entries; clear winners auto-included, contested clusters surfaced to the user, unresolved clusters left out (never coined). Single-sources against docs/glossary-convention.md (the skill executes the rules, restates none). Authority unchanged: maintain keeps the existing user-any-time / boss-record-reality rule; bootstrap is user-only with boss allowed to recommend it via bounce-back. Grounding-check PASS (9/9 assumptions ratified against live repo bytes; parse-gate a documented no-op, no spec_validation configured). The fresh-context pass also surfaced that README's "Eight skills" framing is already stale (omits the existing `issue` utility skill); the spec's README edit reconciles that rather than assuming a non-existent agent-roster note. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
300 lines
13 KiB
Markdown
300 lines
13 KiB
Markdown
# 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).
|