@mlmcps/ml-specs 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +15 -0
- package/LICENSE +21 -0
- package/README.md +106 -0
- package/ml-specs/.claude-plugin/plugin.json +11 -0
- package/ml-specs/.mcp.json +17 -0
- package/ml-specs/CHANGELOG.md +860 -0
- package/ml-specs/LICENSE +21 -0
- package/ml-specs/README.md +347 -0
- package/ml-specs/agents/coder.md +76 -0
- package/ml-specs/agents/developer.md +78 -0
- package/ml-specs/agents/pr-author.md +36 -0
- package/ml-specs/agents/reviewer.md +65 -0
- package/ml-specs/agents/scanner.md +66 -0
- package/ml-specs/agents/spec-author.md +91 -0
- package/ml-specs/agents/spec-reviewer.md +59 -0
- package/ml-specs/commands/code.md +29 -0
- package/ml-specs/commands/fix.md +67 -0
- package/ml-specs/commands/nfr.md +114 -0
- package/ml-specs/commands/pr.md +32 -0
- package/ml-specs/commands/repo-adopt.md +86 -0
- package/ml-specs/commands/repo-doctor.md +57 -0
- package/ml-specs/commands/repo-estate.md +79 -0
- package/ml-specs/commands/repo-impact.md +77 -0
- package/ml-specs/commands/repo-init.md +155 -0
- package/ml-specs/commands/repo-refresh.md +58 -0
- package/ml-specs/commands/repo-rollout.md +84 -0
- package/ml-specs/commands/repo-status.md +59 -0
- package/ml-specs/commands/spec-advance.md +81 -0
- package/ml-specs/commands/spec-build.md +66 -0
- package/ml-specs/commands/spec-fanout.md +64 -0
- package/ml-specs/commands/spec-review.md +24 -0
- package/ml-specs/commands/spec-verify.md +55 -0
- package/ml-specs/commands/spec.md +73 -0
- package/ml-specs/hooks/hooks.json +23 -0
- package/ml-specs/hooks/knowledge-drift.sh +43 -0
- package/ml-specs/hooks/secret-scan.sh +56 -0
- package/ml-specs/mcp/README.md +173 -0
- package/ml-specs/mcp/ml-specs-server.mjs +708 -0
- package/ml-specs/mcp/ml-specs-server.test.mjs +225 -0
- package/ml-specs/package.json +44 -0
- package/ml-specs/scripts/branch-policy.mjs +71 -0
- package/ml-specs/scripts/fix-specs.mjs +289 -0
- package/ml-specs/scripts/lib/cli.mjs +43 -0
- package/ml-specs/scripts/lib/estate.mjs +108 -0
- package/ml-specs/scripts/lib/http.mjs +73 -0
- package/ml-specs/scripts/lib/knowledge.mjs +91 -0
- package/ml-specs/scripts/lib/knowledge.test.mjs +70 -0
- package/ml-specs/scripts/lib/nfr.mjs +119 -0
- package/ml-specs/scripts/lib/nfr.test.mjs +89 -0
- package/ml-specs/scripts/lib/policy.mjs +114 -0
- package/ml-specs/scripts/lib/policy.test.mjs +139 -0
- package/ml-specs/scripts/lib/scm.mjs +189 -0
- package/ml-specs/scripts/lib/scm.test.mjs +155 -0
- package/ml-specs/scripts/lib/specs.mjs +192 -0
- package/ml-specs/scripts/lib/specs.test.mjs +69 -0
- package/ml-specs/scripts/lib/trace.mjs +90 -0
- package/ml-specs/scripts/lib/trace.test.mjs +110 -0
- package/ml-specs/scripts/lib/tracker.mjs +257 -0
- package/ml-specs/scripts/lib/tracker.test.mjs +177 -0
- package/ml-specs/scripts/nfr-compile.mjs +120 -0
- package/ml-specs/scripts/scripts.test.mjs +182 -0
- package/ml-specs/scripts/spec-brief.mjs +127 -0
- package/ml-specs/scripts/spec-dashboard.mjs +331 -0
- package/ml-specs/scripts/spec-fanout.mjs +120 -0
- package/ml-specs/scripts/spec-gate.mjs +329 -0
- package/ml-specs/scripts/spec-trace.mjs +91 -0
- package/ml-specs/scripts/survey-estate.mjs +230 -0
- package/ml-specs/scripts/tracker-sync.mjs +91 -0
- package/ml-specs/skills/knowledge-retrieval/SKILL.md +75 -0
- package/ml-specs/templates/CLAUDE.fragment.md +87 -0
- package/ml-specs/templates/ci/azure-pipelines-spec-gate.yml +64 -0
- package/ml-specs/templates/ci/knowledge-check.mjs +176 -0
- package/ml-specs/templates/ci/knowledge-layer.yml +35 -0
- package/ml-specs/templates/ci/spec-gate.yml +69 -0
- package/ml-specs/templates/docs/ARCHITECTURE.template.md +110 -0
- package/ml-specs/templates/docs/ESTATE.template.md +55 -0
- package/ml-specs/templates/docs/PATTERNS.template.md +80 -0
- package/ml-specs/templates/gitattributes +18 -0
- package/ml-specs/templates/hooks/settings.hooks.example.json +32 -0
- package/ml-specs/templates/mcp/.mcp.json +34 -0
- package/ml-specs/templates/settings.json +18 -0
- package/ml-specs/templates/specs/AGENTS.md +57 -0
- package/ml-specs/templates/specs/README.md +104 -0
- package/ml-specs/templates/specs/TEMPLATE.md +114 -0
- package/ml-specs/templates/standards/.mlskills.json +24 -0
- package/package.json +36 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate or refresh docs/ESTATE.md — the cross-service contract index (who calls, publishes, and consumes what) for a multi-service estate
|
|
3
|
+
argument-hint: (no args) to scan sibling repos, or paths/globs to the peer repos — e.g. ../user-service ../payments-service
|
|
4
|
+
model: sonnet
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are building this repo's **estate index**: the map of the services around it and the contracts
|
|
8
|
+
between them. It is what lets a change that crosses a service boundary be designed against both
|
|
9
|
+
sides without cloning and grepping the whole estate.
|
|
10
|
+
|
|
11
|
+
Peer repos to scan: **$ARGUMENTS**
|
|
12
|
+
|
|
13
|
+
The template lives at `${CLAUDE_PLUGIN_ROOT}/templates/docs/ESTATE.template.md`.
|
|
14
|
+
|
|
15
|
+
## Phase 1 — scope it
|
|
16
|
+
|
|
17
|
+
1. **Does this repo need an estate index at all?** If it's a standalone app with no outbound
|
|
18
|
+
service calls and no event producers/consumers, say so and **stop** — do not create the file. A
|
|
19
|
+
monorepo's internal modules are `docs/ARCHITECTURE.md` shards, not estate peers.
|
|
20
|
+
|
|
21
|
+
2. **Locate the peers.** In order: the paths given in `$ARGUMENTS`; else sibling directories of this
|
|
22
|
+
repo's parent that are git repos; else the other working directories available in this session.
|
|
23
|
+
List what you found and how many you'll scan. If the set is ambiguous or large (>~12 repos), put
|
|
24
|
+
it to the user with AskUserQuestion — scan the ones they name rather than guessing.
|
|
25
|
+
|
|
26
|
+
3. **Read-only outside this repo.** You may read peer repos; you may not write to them.
|
|
27
|
+
|
|
28
|
+
## Phase 2 — learn the edges (not the peers)
|
|
29
|
+
|
|
30
|
+
You are indexing contracts, not learning each service — that's `/repo-init` inside that repo. Stay
|
|
31
|
+
shallow and cheap: for each peer, the manifest for its stack, its README/`docs/ARCHITECTURE.md` for
|
|
32
|
+
what it owns, and then only the files that carry an edge.
|
|
33
|
+
|
|
34
|
+
**Delegate the peer reading, one agent per repo.** Spawn **scanner** once per peer repo with
|
|
35
|
+
the `edges` brief, all **in a single message** so they run concurrently — N peers cost about one
|
|
36
|
+
peer's wall-clock instead of N, and their file reads never enter this context. Give each the peer's
|
|
37
|
+
path and the specific contracts you're trying to resolve (step 5), so it looks for counterparts
|
|
38
|
+
rather than surveying the service. Scan this repo's own edges (step 4) inline — you need that
|
|
39
|
+
detail first-hand to brief the peer scanners.
|
|
40
|
+
|
|
41
|
+
4. **This repo's outbound edges** (highest confidence — you can read the real code):
|
|
42
|
+
- Synchronous: HTTP/RPC/gRPC clients, `@FeignClient`, generated SDK clients, base URLs from config.
|
|
43
|
+
- Asynchronous: published events/topics, and the listeners/consumers it subscribes to.
|
|
44
|
+
- Shared data: tables/collections/schemas or published packages/types shared with a peer.
|
|
45
|
+
Cite `file:line` for each.
|
|
46
|
+
|
|
47
|
+
5. **The other side of each edge.** In the peer repo, find the counterpart — the controller/route
|
|
48
|
+
that serves the call, the producer of the event this repo consumes, the consumer of the event it
|
|
49
|
+
publishes. Confirmed from real code → cite `file:line`. Not confirmed → write the row anyway and
|
|
50
|
+
mark it **`(inferred)`** or `_TBD_`. Never invent a peer-side handler to make a table look complete.
|
|
51
|
+
|
|
52
|
+
6. **Note what the names resolve from.** Queue/topic names and service URLs usually come from config
|
|
53
|
+
(env, a config server, service discovery), not literals — record where, so the next reader can
|
|
54
|
+
resolve them.
|
|
55
|
+
|
|
56
|
+
## Phase 3 — write it
|
|
57
|
+
|
|
58
|
+
7. Fill the template into `docs/ESTATE.md`. If the file already exists, **merge**: keep human-edited
|
|
59
|
+
rows and notes, correct what's now wrong, add new edges, and delete edges whose code is gone.
|
|
60
|
+
Refreshing is also pruning — keep it under ~200 lines. It is an index that links out, not
|
|
61
|
+
documentation that inlines.
|
|
62
|
+
|
|
63
|
+
8. Make sure `CLAUDE.md`'s knowledge-layer section points at `docs/ESTATE.md` for cross-service work
|
|
64
|
+
(add the line if missing). Don't inline any of it into `CLAUDE.md`.
|
|
65
|
+
|
|
66
|
+
9. **Other repos:** if the user wants the same index in the peer repos, offer it as an explicit
|
|
67
|
+
follow-up and write it only on their say-so. Never write into another repo unasked.
|
|
68
|
+
|
|
69
|
+
## Phase 4 — report
|
|
70
|
+
|
|
71
|
+
10. Report: peers scanned, edges found (sync / async / shared data), how many are confirmed vs
|
|
72
|
+
`(inferred)`, and the edges you could **not** resolve — those are the real output, because an
|
|
73
|
+
unresolved edge is where a cross-service change will break. Do NOT commit.
|
|
74
|
+
|
|
75
|
+
Re-run this after adding a listener, a published topic, or a new cross-service client. Related:
|
|
76
|
+
`/repo-refresh` (this repo's own docs) and `/repo-doctor` (drift check).
|
|
77
|
+
|
|
78
|
+
The index exists to be *used*: `/repo-impact` reads it to answer "who breaks if this ships?" — which
|
|
79
|
+
is why an unresolved edge here becomes a blind spot there, and why `_TBD_` is better than a guess.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Find which other services a change breaks — detects modified published contracts and looks up their consumers in docs/ESTATE.md
|
|
3
|
+
argument-hint: <spec file> to check a spec's ripple, or (no args) to analyse the current branch diff
|
|
4
|
+
model: sonnet
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Target: **$ARGUMENTS** (a spec file, or the current branch diff if empty).
|
|
8
|
+
|
|
9
|
+
You are answering one question: **who else breaks if this ships?** Read-only — report, don't fix.
|
|
10
|
+
|
|
11
|
+
This is the failure an estate actually dies of. A change that is correct inside its own repo and
|
|
12
|
+
still takes down a consumer is not caught by tests, `/code-review`, or `/spec-verify`, because every
|
|
13
|
+
one of those looks only at this repo.
|
|
14
|
+
|
|
15
|
+
## Step 0 — establish whether you can answer at all
|
|
16
|
+
|
|
17
|
+
Read `docs/ESTATE.md`. **If it's missing, or its contract index is mostly `_TBD_`, stop and say so
|
|
18
|
+
plainly**: you cannot distinguish "no consumers" from "no index". Recommend `/repo-estate`, and do
|
|
19
|
+
not produce a clean bill of health — a false "nothing affected" here is worse than no answer,
|
|
20
|
+
because it gets believed.
|
|
21
|
+
|
|
22
|
+
Note which rows are marked `(inferred)`: those were never confirmed against the peer's real code, so
|
|
23
|
+
any conclusion resting on them is a hypothesis, and must be labelled as one in your report.
|
|
24
|
+
|
|
25
|
+
If this repo has the toolkit's MCP server wired up, `estate_lookup` answers step 2 directly and
|
|
26
|
+
returns which rows are unconfirmed — use it rather than re-parsing the tables by hand.
|
|
27
|
+
|
|
28
|
+
## Step 1 — find the contracts this change touches
|
|
29
|
+
|
|
30
|
+
From the diff (`git diff "$(git merge-base HEAD @{u} 2>/dev/null || echo HEAD~1)"...HEAD`) or from
|
|
31
|
+
the spec's §4, identify changes to anything **someone else can observe**:
|
|
32
|
+
|
|
33
|
+
- **Published event / message payloads** — a field removed or renamed, a type narrowed, a new
|
|
34
|
+
required field, a changed routing/topic name, changed ordering or idempotency assumptions.
|
|
35
|
+
- **API responses and requests** — a field removed or renamed, a type change, a new required
|
|
36
|
+
request field, a changed status code, a changed error shape, a new auth requirement.
|
|
37
|
+
- **Shared data** — a table/collection another service reads, a column dropped or renamed, a
|
|
38
|
+
changed constraint or index another service's queries depend on.
|
|
39
|
+
- **Published packages/types** — a shared library's exported signature.
|
|
40
|
+
|
|
41
|
+
Purely internal changes (private helpers, tests, this service's own storage that nobody else reads)
|
|
42
|
+
have no ripple. Say that and stop — most changes are this, and inventing ripple is its own failure.
|
|
43
|
+
|
|
44
|
+
## Step 2 — resolve the consumers
|
|
45
|
+
|
|
46
|
+
For each touched contract, find it in the `docs/ESTATE.md` contract index and list the services on
|
|
47
|
+
the other side. For each consumer, classify the change:
|
|
48
|
+
|
|
49
|
+
| Class | Meaning | What it forces |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **Additive** | New optional field, new endpoint, new event type | Nothing — deploy in any order |
|
|
52
|
+
| **Compatible-with-sequence** | Consumer must handle both shapes first | A deploy order, and a spec that names it |
|
|
53
|
+
| **Breaking** | Consumer breaks the moment this ships | A migration path: dual-write/dual-read, version the contract, or coordinate a release |
|
|
54
|
+
|
|
55
|
+
Assume **something you don't control is already calling this**. In-flight messages and old clients
|
|
56
|
+
outlive a deploy; a change that is safe only if every consumer upgrades simultaneously is breaking.
|
|
57
|
+
|
|
58
|
+
## Step 3 — check the spec covers it (when given a spec)
|
|
59
|
+
|
|
60
|
+
The spec's **§7 Rollout & risks** must name each affected consumer and the deploy order, and §4.3 /
|
|
61
|
+
§4.4 must describe the contract on both sides. If it doesn't, that's the finding: the ripple was
|
|
62
|
+
designed but not written down, and the person deploying won't know.
|
|
63
|
+
|
|
64
|
+
## Report
|
|
65
|
+
|
|
66
|
+
- **Contracts touched** — each with `file:line` and its class (additive / sequenced / breaking).
|
|
67
|
+
- **Consumers affected** — service, what it consumes, and whether the estate row was confirmed or
|
|
68
|
+
`(inferred)`.
|
|
69
|
+
- **Required deploy order** — as a numbered sequence that is safe at every intermediate step
|
|
70
|
+
(usually: consumers accept both shapes → producer changes → old path removed later).
|
|
71
|
+
- **Unresolvable** — contracts you could not find a consumer for, and whether that means "nobody
|
|
72
|
+
consumes it" or "the index doesn't know". Never merge those two.
|
|
73
|
+
- **Spec gaps** — what §7 needs to say and doesn't.
|
|
74
|
+
|
|
75
|
+
Next: put any breaking finding into the spec (§4 contracts, §7 rollout) via a **Revisions** row
|
|
76
|
+
before building, or — if the code is already written — treat it as a spec gap in `/spec-verify` and
|
|
77
|
+
resolve it with the user before `/pr`.
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Learn the existing project, then scaffold spec-driven development + all Claude knowledge files (CLAUDE.md, docs/, specs/, CI gate)
|
|
3
|
+
argument-hint: (no args) — run from the root of the repo to learn it and set up
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are bootstrapping the **ml-specs** into the current repository. This is a **learn-first**
|
|
7
|
+
command: study the real codebase, extract how it actually works, then generate every Claude
|
|
8
|
+
knowledge file with those findings baked in. Do not produce generic boilerplate — everything you
|
|
9
|
+
write must reflect THIS project and cite real `file:line`.
|
|
10
|
+
|
|
11
|
+
**First, check this is the right command.** If the repo already has a hand-written `CLAUDE.md`,
|
|
12
|
+
`docs/`, or an existing spec/RFC/ADR practice, stop and recommend **`/repo-adopt`** instead — it
|
|
13
|
+
merges into what's there rather than assuming a blank slate. Only continue here if the knowledge
|
|
14
|
+
layer is genuinely absent or was generated by this toolkit.
|
|
15
|
+
|
|
16
|
+
The plugin's templates live under `${CLAUDE_PLUGIN_ROOT}/templates/`.
|
|
17
|
+
|
|
18
|
+
## Phase 1 — LEARN the project (do this before writing anything)
|
|
19
|
+
|
|
20
|
+
**Delegate the reading.** This is the most expensive phase in the toolkit, and every file read
|
|
21
|
+
here would otherwise sit in your context for the rest of the run — while you are writing docs, not
|
|
22
|
+
reading code. So spawn **scanner** three times **in a single message**, so the three run
|
|
23
|
+
concurrently, one per brief:
|
|
24
|
+
|
|
25
|
+
1. `stack` — language, package manager, framework, data layer, test layout, and the repo's real
|
|
26
|
+
build/test/lint/typecheck commands. Tell it to flag whether this is a monorepo/workspace (npm
|
|
27
|
+
workspaces, pnpm, Nx/Turborepo/Lerna, Maven multi-module, Gradle subprojects, Go workspaces) and,
|
|
28
|
+
if so, each package's own stack and commands — packages differ, and one root summary hides that.
|
|
29
|
+
2. `structure` — directory layout, entry points, data layer + migrations, config/env handling, test
|
|
30
|
+
layout, and the bounded contexts/packages with their dependencies.
|
|
31
|
+
3. `patterns` — the actual house style: naming; end-to-end feature layering; data access &
|
|
32
|
+
migrations; API/DTO contracts and status codes; error handling; validation, config & secrets;
|
|
33
|
+
logging; testing shape; and inferable anti-patterns.
|
|
34
|
+
|
|
35
|
+
Each returns a capped findings block of `file:line` citations, not source. Work from those three
|
|
36
|
+
blocks for the rest of this command.
|
|
37
|
+
|
|
38
|
+
**If a scanner returns thin or contradictory findings**, re-brief that one scanner with a narrower
|
|
39
|
+
scope rather than reading the codebase yourself — the point is that raw file contents never enter
|
|
40
|
+
this context. Reading a *specific* file yourself is fine when a scanner's `NOTES` asks you to
|
|
41
|
+
adjudicate something; re-doing a whole brief inline is not.
|
|
42
|
+
|
|
43
|
+
Carry every `(inferred)` marker through to Phase 4 — those are what the human must confirm.
|
|
44
|
+
|
|
45
|
+
## Phase 2 — GENERATE the Claude knowledge files (memory)
|
|
46
|
+
|
|
47
|
+
Write these so the agents (`coder`, `developer`, `reviewer`, `spec-author`) have durable project memory. Cite real `file:line`;
|
|
48
|
+
do not overwrite a maintained file without saying so — if one exists, merge, and report what changed.
|
|
49
|
+
|
|
50
|
+
**Token discipline (these files load into context on every task):** be terse and high-signal.
|
|
51
|
+
Reference `file:line` instead of pasting code. Keep `docs/PATTERNS.md` and `docs/ARCHITECTURE.md`
|
|
52
|
+
under ~200 lines each; keep `CLAUDE.md` a thin index (~150 lines) that LINKS to those docs rather
|
|
53
|
+
than inlining them. In a monorepo, prefer per-package sections/files over one fat document.
|
|
54
|
+
|
|
55
|
+
4. **`docs/PATTERNS.md` — the learned house style (the key new artifact).** Create `docs/` if
|
|
56
|
+
missing and fill `${CLAUDE_PLUGIN_ROOT}/templates/docs/PATTERNS.template.md` from your Phase 1
|
|
57
|
+
findings. Keep only sections that apply; every pattern cites a real example. This is the
|
|
58
|
+
"code patterns" memory new code must match.
|
|
59
|
+
|
|
60
|
+
5. **`docs/ARCHITECTURE.md` — the structural map.** Fill
|
|
61
|
+
`${CLAUDE_PLUGIN_ROOT}/templates/docs/ARCHITECTURE.template.md` with this project's real
|
|
62
|
+
structure, data/persistence, events, external calls, and cross-cutting concerns — per the
|
|
63
|
+
detected stack (Java/Spring: controllers, `@SqsListener`, `@FeignClient`, repo flavor; Node:
|
|
64
|
+
routers/modules, services, ORM models & migrations, DB engine; React: routes/pages, components,
|
|
65
|
+
state, data-fetching). Don't copy the example verbatim.
|
|
66
|
+
- **Large application (many modules/contexts, or a monorepo)? Shard it.** Don't write one huge
|
|
67
|
+
file. Make `docs/ARCHITECTURE.md` a small **router** (blurb + a Structure table whose rows link
|
|
68
|
+
to per-module shards), and generate one `docs/architecture/<module>.md` (≤~150 lines) per
|
|
69
|
+
bounded context / package. Add `docs/patterns/<module>.md` only where conventions differ by
|
|
70
|
+
module. This keeps each task's context to the router + the one relevant shard.
|
|
71
|
+
- **Map the edges, not just the nodes (essential when modules are interlinked).** Give each shard
|
|
72
|
+
a `## Depends on / Used by` header listing the modules it calls / is called by, each as a
|
|
73
|
+
one-line contract pointer (event/API/shared type/table → `file:line`). Fill the router's
|
|
74
|
+
**module contract index** with the shared contracts and their producers/consumers. If the code
|
|
75
|
+
is heavily coupled, also generate `docs/architecture/_core.md` for the truly shared contracts.
|
|
76
|
+
Determine edges from real imports/calls/events/shared schemas — don't guess.
|
|
77
|
+
|
|
78
|
+
6. **`docs/ESTATE.md` — only for a multi-service estate.** If this repo is part of a larger estate
|
|
79
|
+
(it calls other services, or produces/consumes events), don't hand-write it here — recommend
|
|
80
|
+
**`/repo-estate`**, which scans the peer repos and fills
|
|
81
|
+
`${CLAUDE_PLUGIN_ROOT}/templates/docs/ESTATE.template.md` with the real contract index. For a
|
|
82
|
+
standalone app, SKIP it entirely.
|
|
83
|
+
|
|
84
|
+
7. **`CLAUDE.md` — the primary project memory.** If absent, run `/init` first for a base. Then
|
|
85
|
+
ensure it contains the shared sections from `${CLAUDE_PLUGIN_ROOT}/templates/CLAUDE.fragment.md`
|
|
86
|
+
("Knowledge layer", "Working agreement", "Spec-driven development", "Quality gates"), AND a
|
|
87
|
+
concise **"Code patterns & conventions"** section that summarizes `docs/PATTERNS.md` in a few
|
|
88
|
+
lines and **links** to it (don't inline it), plus the accurate stack / build / run / test
|
|
89
|
+
commands for THIS repo. Keep CLAUDE.md a thin index — the agents read it first on every task, so
|
|
90
|
+
the learned patterns must be *discoverable* from it, not *embedded* in it.
|
|
91
|
+
|
|
92
|
+
## Phase 3 — SCAFFOLD the spec workflow
|
|
93
|
+
|
|
94
|
+
8. **Spec workflow:** create `specs/` if missing and copy in `README.md`, `TEMPLATE.md`, and
|
|
95
|
+
`AGENTS.md` from `${CLAUDE_PLUGIN_ROOT}/templates/specs/`. Do not overwrite existing specs.
|
|
96
|
+
`specs/archive/` is created on demand by `/spec-advance` — don't create it empty here.
|
|
97
|
+
|
|
98
|
+
9. **Line endings:** if the repo has no `.gitattributes`, copy
|
|
99
|
+
`${CLAUDE_PLUGIN_ROOT}/templates/gitattributes` to `./.gitattributes`, then run
|
|
100
|
+
`git add --renormalize .` to clear any CRLF/LF phantom diff. Report how many files normalized.
|
|
101
|
+
|
|
102
|
+
10. **Commit attribution:** merge `${CLAUDE_PLUGIN_ROOT}/templates/settings.json` into
|
|
103
|
+
`.claude/settings.json` (create it if absent; if it exists, add the `attribution` key and leave
|
|
104
|
+
every other key alone). Commit it — that is the point: it applies to every teammate who clones
|
|
105
|
+
the repo, with no per-machine configuration. It makes commits and PRs name the humans who own
|
|
106
|
+
the change, which `CLAUDE.md` also states, but here it is enforced by Claude Code rather than
|
|
107
|
+
being an instruction a model has to remember. If the repo already sets `attribution`, leave the
|
|
108
|
+
existing value and say so.
|
|
109
|
+
|
|
110
|
+
11. **Architecture standards (optional):** if `ml-skills` is available — the MCP server, or
|
|
111
|
+
`npx @mlmcps/ml-skills` — copy `${CLAUDE_PLUGIN_ROOT}/templates/standards/.mlskills.json` to the
|
|
112
|
+
repo root and run `npx @mlmcps/ml-skills check .` once.
|
|
113
|
+
|
|
114
|
+
Report the finding count, and report it as a **baseline, not a failure**. Every standard is
|
|
115
|
+
seeded `proposed`, which means it can only warn and cannot fail anything — that is deliberate.
|
|
116
|
+
A gate that fails on day one gets disabled on day two, and a repo that has never been checked
|
|
117
|
+
will have a backlog. Say what the backlog is, say that nothing is enforced yet, and point at
|
|
118
|
+
the ratification decision as a separate, human step: `npx @mlmcps/ml-skills ratify`.
|
|
119
|
+
|
|
120
|
+
Do **not** ratify a standard here. That means someone read the decisions, agreed to them, and
|
|
121
|
+
accepted that they can now break the build — none of which an init command can do on a team's
|
|
122
|
+
behalf.
|
|
123
|
+
|
|
124
|
+
If ml-skills is not installed, skip this and say so in one line. It is genuinely optional; the
|
|
125
|
+
rest of the toolkit works without it.
|
|
126
|
+
|
|
127
|
+
12. **Knowledge-layer CI gate:** copy `${CLAUDE_PLUGIN_ROOT}/templates/ci/knowledge-check.mjs` to
|
|
128
|
+
`.github/scripts/` and `${CLAUDE_PLUGIN_ROOT}/templates/ci/knowledge-layer.yml` to
|
|
129
|
+
`.github/workflows/`. It fails a PR when a doc's `file:line` reference points at code that no
|
|
130
|
+
longer exists — the mechanical half of `/repo-doctor`, which is the half worth automating.
|
|
131
|
+
Run it once now and report the result. If the repo isn't on GitHub Actions, say so and give the
|
|
132
|
+
command to wire into whatever CI it does use.
|
|
133
|
+
|
|
134
|
+
13. **Optional MCP server:** mention that `${CLAUDE_PLUGIN_ROOT}/templates/mcp/.mcp.json` wires this
|
|
135
|
+
repo to the toolkit's read-only MCP tools (`estate_lookup`, `knowledge_check`, `spec_list`,
|
|
136
|
+
`spec_next_number`), which non-Claude tools can use too. Do NOT install it automatically — it
|
|
137
|
+
needs an absolute path to the plugin checkout. Offer it, and only wire it if the user says yes.
|
|
138
|
+
|
|
139
|
+
14. **Optional hooks:** mention that `${CLAUDE_PLUGIN_ROOT}/templates/hooks/settings.hooks.example.json`
|
|
140
|
+
has opt-in automation (post-edit format/lint, a pre-PR test reminder). Do NOT install hooks
|
|
141
|
+
automatically — the commands are project-specific. If the user wants them, copy the chosen hooks
|
|
142
|
+
into `.claude/settings.json` and replace the commands with this project's real ones. The
|
|
143
|
+
plugin's own hooks (knowledge-drift warning, secret scan) are already active on install and
|
|
144
|
+
need nothing here.
|
|
145
|
+
|
|
146
|
+
## Phase 4 — REPORT
|
|
147
|
+
|
|
148
|
+
15. Report what was created/skipped/merged, and what the human should review — especially
|
|
149
|
+
`docs/PATTERNS.md` and `docs/ARCHITECTURE.md` (verify the learned patterns match intent, and
|
|
150
|
+
correct anything you marked *inferred*). Do NOT commit — leave changes staged/untracked for review.
|
|
151
|
+
|
|
152
|
+
The agents (`coder`, `spec-author`, `spec-reviewer`, `developer`, `reviewer`,
|
|
153
|
+
`pr-author`) and commands (`/spec` → `/spec-review` → `/spec-build` → `/spec-verify` →
|
|
154
|
+
`/spec-advance` → `/pr`) come from the plugin itself and need no per-repo files — they read the
|
|
155
|
+
generated `CLAUDE.md` + `docs/` to learn this project.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Re-learn what changed since the last refresh and update the Claude knowledge files (docs/, CLAUDE.md) so the agent's memory matches reality
|
|
3
|
+
argument-hint: (no args) — run from the repo root after the codebase has drifted
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The project has evolved since `/repo-init` (or the last refresh). Re-learn it and update the
|
|
7
|
+
generated knowledge files so the coding agents' memory stays accurate. The code is the source of
|
|
8
|
+
truth — a stale summary is worse than none.
|
|
9
|
+
|
|
10
|
+
This is the LEARN + UPDATE half of `/repo-init` (it does NOT re-scaffold `specs/` or
|
|
11
|
+
`.gitattributes`). The plugin's templates live under `${CLAUDE_PLUGIN_ROOT}/templates/`.
|
|
12
|
+
|
|
13
|
+
Steps:
|
|
14
|
+
|
|
15
|
+
1. **Scope the re-learn to what actually moved.** A refresh is not a re-init: most of the repo is
|
|
16
|
+
unchanged, and re-learning all of it is the single most wasteful path in this toolkit. Find the
|
|
17
|
+
changed surface first — it's cheap and mechanical:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
git log -1 --format=%H -- CLAUDE.md docs/ # when the knowledge layer was last updated
|
|
21
|
+
git diff --name-only <that-sha>..HEAD -- . ':(exclude)docs/*' ':(exclude)*.md'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If that returns nothing, the docs are current — say so and stop. If it returns more than roughly
|
|
25
|
+
half the repo's source files (or the last-doc commit is unreachable), fall back to a full
|
|
26
|
+
re-learn and say that you did.
|
|
27
|
+
|
|
28
|
+
2. **Re-learn, in parallel, scoped to those paths.** Spawn **scanner** agents **in a single
|
|
29
|
+
message** — one `patterns` and one `structure` brief, each scoped to the changed paths, plus a
|
|
30
|
+
`stack` brief **only if** the manifest/build file or lockfile is among them (otherwise the stack
|
|
31
|
+
hasn't moved and re-detecting it is pure cost). Each returns `file:line` findings, not source, so
|
|
32
|
+
the changed code never lands in this context.
|
|
33
|
+
|
|
34
|
+
3. **Diff against the existing docs.** Read the current `docs/PATTERNS.md`, `docs/ARCHITECTURE.md`,
|
|
35
|
+
and the "Code patterns & conventions" section of `CLAUDE.md`. Identify what changed: new
|
|
36
|
+
modules/endpoints/components, new or changed data models & migrations, new conventions, removed
|
|
37
|
+
patterns, new dependencies, changed commands.
|
|
38
|
+
|
|
39
|
+
4. **Update the files in place** (don't blow away human edits — merge and preserve hand-written
|
|
40
|
+
notes; only correct what's now wrong or missing). Refreshing is also pruning: **delete stale
|
|
41
|
+
patterns and trim bloat** so each doc stays under its ~200-line budget and `CLAUDE.md` stays a
|
|
42
|
+
thin index — replace drifted sections, don't just append. Smaller, current memory = fewer tokens
|
|
43
|
+
every task.
|
|
44
|
+
- `docs/PATTERNS.md` — refresh the house style from current code.
|
|
45
|
+
- `docs/ARCHITECTURE.md` — refresh structure, data/persistence, events, external calls.
|
|
46
|
+
- `CLAUDE.md` — fix the stack/build/run/test commands and the "Code patterns & conventions"
|
|
47
|
+
summary if they've drifted.
|
|
48
|
+
- `docs/ESTATE.md` — do NOT rewrite it here. If this repo's cross-service contracts changed
|
|
49
|
+
(a new client, listener, or published topic), say so and recommend `/repo-estate`, which reads
|
|
50
|
+
the peer repos to resolve both sides of each edge.
|
|
51
|
+
- **Sharded (large app):** update ONLY the `docs/architecture/<module>.md` (and
|
|
52
|
+
`docs/patterns/<module>.md`) shards for modules that changed; add a shard + router row for a
|
|
53
|
+
new module; remove the row + shard for a deleted one. Don't rewrite untouched shards.
|
|
54
|
+
|
|
55
|
+
5. **Report a concise changelog** of what you updated (and what you intentionally left), and what
|
|
56
|
+
the human should review. Do NOT commit — leave changes staged/untracked for review.
|
|
57
|
+
|
|
58
|
+
If no knowledge files exist yet, tell the user to run `/repo-init` first.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Onboard the toolkit across an estate — survey the repos cheaply, then init/adopt them in reviewed waves rather than all at once
|
|
3
|
+
argument-hint: <parent dir containing the repos, or an explicit list> — e.g. ~/work or ../svc-a ../svc-b
|
|
4
|
+
model: sonnet
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Target repos: **$ARGUMENTS**
|
|
8
|
+
|
|
9
|
+
You are rolling the toolkit out across many repos. The whole job is **aiming the expensive part**.
|
|
10
|
+
|
|
11
|
+
`/repo-init` is the most costly operation in this toolkit — a full codebase scan. Running it across
|
|
12
|
+
an estate unattended produces a large bill and, worse, a pile of knowledge layers nobody reviewed,
|
|
13
|
+
which is the exact failure the toolkit exists to prevent. So: survey cheaply, onboard deliberately,
|
|
14
|
+
and let the first repo teach you what the rest need.
|
|
15
|
+
|
|
16
|
+
**Never commit in another repo. Never onboard more than one repo before a human has seen the first
|
|
17
|
+
one's output.**
|
|
18
|
+
|
|
19
|
+
## Phase 1 — survey (cheap, mechanical, read-only)
|
|
20
|
+
|
|
21
|
+
1. Run the survey script — no model needed, so this costs almost nothing:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/survey-estate.mjs <parent-or-repos>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
It classifies each repo as **init** (no knowledge layer, active), **adopt** (has hand-written
|
|
28
|
+
docs or another tool's agent instructions — `/repo-init` would clobber them), **refresh** (already
|
|
29
|
+
onboarded), **review** (dormant, or no recognisable manifest), or **skip**. It also counts
|
|
30
|
+
cross-service edge signals.
|
|
31
|
+
|
|
32
|
+
2. Relay the table and the per-repo reasons. Flag anything with uncommitted changes — onboard on a
|
|
33
|
+
clean tree, or the toolkit's diff is tangled with someone's work in progress.
|
|
34
|
+
|
|
35
|
+
## Phase 2 — agree the order with the human
|
|
36
|
+
|
|
37
|
+
3. Order by **what onboarding unlocks**, not alphabetically. Repos with the most cross-service edge
|
|
38
|
+
signals come first: their `docs/ARCHITECTURE.md` is what `/repo-estate` needs to resolve the *other*
|
|
39
|
+
side of a contract, so onboarding them makes `/repo-impact` answerable for their peers too. A leaf
|
|
40
|
+
service with no edges can wait.
|
|
41
|
+
|
|
42
|
+
4. Put the plan to the user with AskUserQuestion: which repos are in the first wave (recommend 1–3),
|
|
43
|
+
and confirm the **review** ones — dormant or unrecognised repos are a human call, not yours. State
|
|
44
|
+
the rough cost: one `/repo-init` per repo, larger repos costing more.
|
|
45
|
+
|
|
46
|
+
## Phase 3 — onboard, one repo at a time
|
|
47
|
+
|
|
48
|
+
5. **The first repo is a calibration run.** Onboard exactly one, then **stop** and have the human read
|
|
49
|
+
its generated `CLAUDE.md`, `docs/PATTERNS.md`, and `docs/ARCHITECTURE.md`. Almost always something
|
|
50
|
+
is systematically off — a convention mislabelled, the wrong build command, too much detail in the
|
|
51
|
+
thin index. Fixing that once, before repo two, is the difference between 17 good knowledge layers
|
|
52
|
+
and 17 copies of the same mistake.
|
|
53
|
+
|
|
54
|
+
6. For each repo in the wave, in its own directory:
|
|
55
|
+
- `action: init` → run `/repo-init`'s procedure there.
|
|
56
|
+
- `action: adopt` → run `/repo-adopt`'s procedure instead. **Never `/repo-init` a repo with existing
|
|
57
|
+
docs** — clobbering documentation a team wrote is how a tool gets banned.
|
|
58
|
+
- Leave every change **uncommitted**. Report the file list per repo. The human commits.
|
|
59
|
+
- If a repo turns out to be something other than a service (a library, a config repo, an
|
|
60
|
+
archive), stop and say so rather than generating a knowledge layer for it.
|
|
61
|
+
|
|
62
|
+
7. Between repos, carry forward what you learned: if repo one's `PATTERNS.md` needed the same
|
|
63
|
+
correction twice, apply it from the start in repo three.
|
|
64
|
+
|
|
65
|
+
## Phase 4 — make the estate index real
|
|
66
|
+
|
|
67
|
+
8. Once **two or more** repos are onboarded, run `/repo-estate` from one of them. Before this, the
|
|
68
|
+
contract index is mostly `_TBD_` and `/repo-impact` correctly refuses to answer; after it, both
|
|
69
|
+
start returning real consumers. This is the payoff for the whole rollout — don't skip it because
|
|
70
|
+
the individual repos "look done".
|
|
71
|
+
|
|
72
|
+
## Phase 5 — report
|
|
73
|
+
|
|
74
|
+
9. Report: repos onboarded, repos deliberately skipped **and why**, repos still pending, what the
|
|
75
|
+
human must review first (the `(inferred)` patterns), and the next wave. Be explicit about what
|
|
76
|
+
was NOT done — a rollout that silently stops at 4 of 17 and reads as finished is worse than one
|
|
77
|
+
that says "13 remain".
|
|
78
|
+
|
|
79
|
+
10. Re-running this command is how you resume: the survey re-derives every repo's state from what's
|
|
80
|
+
on disk, so onboarded repos show as `refresh` and drop out of the queue. There is no ledger to
|
|
81
|
+
go stale.
|
|
82
|
+
|
|
83
|
+
Related: `/repo-init` (one repo, greenfield) · `/repo-adopt` (one repo, existing docs) ·
|
|
84
|
+
`/repo-estate` (the contract index) · `/repo-doctor` (drift, per repo).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Dashboard of the specs under specs/ — lifecycle status, acceptance-criteria progress, and branch — read-only, summarizes rather than dumping
|
|
3
|
+
argument-hint: (no args) for the default view · `all` for every row · a status (e.g. `Draft`) to filter
|
|
4
|
+
model: haiku
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Give the user a read-only view of **what's in flight**. Do NOT edit anything.
|
|
8
|
+
|
|
9
|
+
Filter/mode: **$ARGUMENTS**
|
|
10
|
+
|
|
11
|
+
## Get the data cheaply
|
|
12
|
+
|
|
13
|
+
If this repo has the toolkit's MCP server wired up, call **`spec_list`** — it parses every spec
|
|
14
|
+
locally and returns structured data, which is far cheaper than reading the files into context.
|
|
15
|
+
Otherwise read `specs/NNNN-*.md` headers yourself (ignore `README.md`, `TEMPLATE.md`, `AGENTS.md`;
|
|
16
|
+
`specs/archive/` is a count, not rows).
|
|
17
|
+
|
|
18
|
+
Per spec: number & slug, Status, acceptance criteria checked/total, and Branch — the header's
|
|
19
|
+
**Branch** row if present, else a best-effort match against `git branch --all` shown with `?` to
|
|
20
|
+
mark it a guess.
|
|
21
|
+
|
|
22
|
+
## Choose the view by size — this matters
|
|
23
|
+
|
|
24
|
+
A mature repo can hold **hundreds** of specs. Rendering every row is unreadable and expensive, and
|
|
25
|
+
it buries the handful of things that actually need a decision.
|
|
26
|
+
|
|
27
|
+
- **≤ 25 specs, or the user asked for `all`** → the full table, sorted by number:
|
|
28
|
+
|
|
29
|
+
| Spec | Status | AC | Branch |
|
|
30
|
+
|------|--------|----|--------|
|
|
31
|
+
| 0001-add-coupon-expiry | Implemented | 4/4 | feat/0001-coupon-expiry |
|
|
32
|
+
|
|
33
|
+
- **More than that** → **summarize, don't dump.** Lead with counts by status and overall
|
|
34
|
+
acceptance-criteria completion, then table **only the specs that need attention** (below).
|
|
35
|
+
Say how many rows you're not showing and how to see them (`/repo-status all`, or
|
|
36
|
+
`/repo-status Draft` to filter).
|
|
37
|
+
|
|
38
|
+
## Needs attention
|
|
39
|
+
|
|
40
|
+
This is the actual output — the rest is context. Table only these:
|
|
41
|
+
|
|
42
|
+
- `Implemented` with unchecked criteria, or a §6 test named that doesn't exist on disk.
|
|
43
|
+
- `Draft`/`Approved` with no branch (nothing started), or a branch with `Draft` status (work
|
|
44
|
+
started before the contract was agreed).
|
|
45
|
+
- `Verified` whose branch is already merged → should be `/spec-advance … Archived`.
|
|
46
|
+
- **A Status that isn't one of `Draft`/`Approved`/`Implemented`/`Verified`/`Archived`** — free-text
|
|
47
|
+
prose in that field means `/spec-advance` and `spec_list` can't read it. Report the count; if it's
|
|
48
|
+
more than a few, point at `scripts/fix-specs.mjs`, which normalizes them in one pass and preserves
|
|
49
|
+
the prose.
|
|
50
|
+
- **Duplicate spec numbers** — two files sharing an id is a merge hazard. Same script repairs it.
|
|
51
|
+
|
|
52
|
+
## Close
|
|
53
|
+
|
|
54
|
+
End with the single most useful next action for whatever is most in-flight — `/spec-review` a draft,
|
|
55
|
+
`/spec-advance` an approved-in-conversation one, `/spec-build` an `Approved` one, `/spec-verify` an
|
|
56
|
+
`Implemented` one, `/pr` a `Verified` one, `/spec-advance … Archived` a merged one. One line, not a
|
|
57
|
+
menu.
|
|
58
|
+
|
|
59
|
+
Read-only. Every status *write* goes through `/spec-advance`, never this command.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Advance a spec's lifecycle status (Draft → Approved → Implemented → Verified → Archived) — each transition gated on real evidence, archives merged specs
|
|
3
|
+
argument-hint: <path to spec file> [target status] — e.g. specs/0001-foo.md Verified
|
|
4
|
+
model: sonnet
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Spec: **$ARGUMENTS** (path, then optionally the target status — if no status is given, advance to
|
|
8
|
+
the next one in the lifecycle).
|
|
9
|
+
|
|
10
|
+
This is the **only** command that writes a spec's Status. It exists because a status is a claim
|
|
11
|
+
about reality, and a claim nobody checks is worth nothing: `Verified` must mean the suite actually
|
|
12
|
+
ran green, not that an agent felt done.
|
|
13
|
+
|
|
14
|
+
## What you may edit
|
|
15
|
+
|
|
16
|
+
The spec's **header table** (Status, Branch, Date), its **Revisions** table, and its
|
|
17
|
+
**acceptance-criteria checkboxes** — nothing else. Never touch code, never commit, never edit
|
|
18
|
+
another spec.
|
|
19
|
+
|
|
20
|
+
## Procedure
|
|
21
|
+
|
|
22
|
+
1. Read the spec. Record its current Status and the current branch
|
|
23
|
+
(`git rev-parse --abbrev-ref HEAD`). Determine the target status: the argument if given,
|
|
24
|
+
otherwise the next one in `Draft → Approved → Implemented → Verified → Archived`.
|
|
25
|
+
|
|
26
|
+
2. **Run the mechanical half of the gate first:**
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
node ${CLAUDE_PLUGIN_ROOT}/scripts/spec-gate.mjs <spec-file> --to <target>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
It checks exactly what a script can check exactly: lifecycle ordering, leftover `<placeholder>`
|
|
33
|
+
text, whether every acceptance criterion is ticked, whether **every test file named in the §6
|
|
34
|
+
table actually exists on disk**, and whether the recorded branch is merged. It prints `PASS` /
|
|
35
|
+
`FAIL` / `MANUAL` per gate and exits non-zero on any `FAIL`. Trust its `FAIL`s — do not re-derive
|
|
36
|
+
them by hand, and do not argue with them.
|
|
37
|
+
|
|
38
|
+
3. **Then judge the `MANUAL` gates yourself — below. Gather that evidence yourself; do not take the
|
|
39
|
+
user's or another agent's word for it.** These are the ones no script can settle: whether the
|
|
40
|
+
human approved in this conversation, whether a §8 question is blocking, whether `/spec-verify`
|
|
41
|
+
was clean, and whether the §6.1 suite actually ran green.
|
|
42
|
+
|
|
43
|
+
For the `Verified` gate, one of those is now mechanical too — call **`verify_evidence`** on the
|
|
44
|
+
`ml-skills` MCP server with `base` set to the branch this work forked from, and read its
|
|
45
|
+
`verdict` rather than re-deriving one. It already draws the distinction this transition turns
|
|
46
|
+
on: `fail` blocks, `pass` clears, `partial` means a requested checker never ran, and
|
|
47
|
+
**`inconclusive` means clean but nothing was ratified, so nothing could have failed**. Only
|
|
48
|
+
`pass` clears this gate on its own; on `partial` or `inconclusive`, record the transition only
|
|
49
|
+
with the gap stated in the same breath. Fall back to `npx @mlmcps/ml-skills check . --json` (or
|
|
50
|
+
`check_repo`) if the tool is unavailable: there, `summary.errors` must be 0 and
|
|
51
|
+
`summary.proposedSkills` names the standards that were **incapable** of failing. If most
|
|
52
|
+
standards are unratified, say so when you record the
|
|
53
|
+
the person reading the status later deserves to know which one they are getting.
|
|
54
|
+
|
|
55
|
+
If ml-skills is not installed, that gate is **unavailable**, not passed. Record it as such.
|
|
56
|
+
|
|
57
|
+
4. **If the evidence isn't there, do not write the status.** Report exactly which gate failed, what
|
|
58
|
+
is missing, and the one command that produces it. A refused transition is a successful run of
|
|
59
|
+
this command.
|
|
60
|
+
|
|
61
|
+
5. If it passes: update Status, set/refresh the **Branch** row from the current branch, update the
|
|
62
|
+
**Date**, and tick any acceptance criteria you confirmed. Report the transition in one line.
|
|
63
|
+
|
|
64
|
+
## The gates
|
|
65
|
+
|
|
66
|
+
| Transition | Required evidence |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `Draft` → `Approved` | The human approves **in this conversation** — ask if they haven't. Section 8 holds no blocking questions (an answer that would change an API shape, data model, error code, scope boundary, or compatibility). No `<placeholder>` text left in filled sections. If the spec hasn't had an adversarial pass, run `/spec-review` first. |
|
|
69
|
+
| `Approved` → `Implemented` | Every acceptance criterion is checked, and each row of the §6 test-plan table names a test file/method that **exists on disk** — `spec-gate.mjs` checks both; a named-but-missing test is the most common lie here. Normally `/spec-build` makes this transition itself. |
|
|
70
|
+
| `Implemented` → `Verified` | A clean **`/spec-verify`** — the `reviewer` agent marked every criterion satisfied, with a functional/E2E test for each user-facing or contract-level one — **and** the §6.1 full suite green end to end, **and** no new error-severity finding from the architecture standards (`ml-skills check`, if the repo has a `.mlskills.json`). If any of those did not happen in this session, run them now; if a suite or the standards check can't be run here, say so and refuse the transition. Never set `Verified` on assertion. |
|
|
71
|
+
| `Verified` → `Archived` | The spec's branch is merged into the default branch — `spec-gate.mjs` checks `git branch --merged`; if the PR merged but the local branch is behind, fetch first rather than overriding it. Then `git mv` the file to `specs/archive/NNNN-slug.md` — keep the number, create `specs/archive/` if absent — and fix any relative links that pointed at it. Numbers are never reused. |
|
|
72
|
+
|
|
73
|
+
**Moving backwards** (e.g. `Implemented` → `Draft` because the contract changed) is allowed and
|
|
74
|
+
sometimes correct. It needs no evidence gate, but it **must** add a **Revisions** row saying what
|
|
75
|
+
changed and why, and it un-ticks the acceptance criteria that no longer hold.
|
|
76
|
+
|
|
77
|
+
**Skipping a status** is not allowed — run the gates in order. If the user asks to jump straight to
|
|
78
|
+
`Verified`, walk each intervening gate and report the first one that fails.
|
|
79
|
+
|
|
80
|
+
Next step after a successful transition: `Approved` → `/spec-build <spec-file>` ·
|
|
81
|
+
`Implemented` → `/spec-verify <spec-file>` · `Verified` → `/pr <spec-file>` · `Archived` → done.
|