cyber-sdd 0.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/plugin.json +17 -0
- package/.codex-plugin/plugin.json +17 -0
- package/.plugin/plugin.json +17 -0
- package/README.md +159 -0
- package/agents/sdd-automaton.md +97 -0
- package/agents/sdd-impl-judge.md +214 -0
- package/agents/sdd-scanner.md +120 -0
- package/agents/sdd-spec-judge.md +224 -0
- package/agents/sdd-warden.md +101 -0
- package/package.json +24 -0
- package/skills/align-spec/README.md +20 -0
- package/skills/align-spec/SKILL.md +111 -0
- package/skills/align-spec/scripts/align-spec.mts +187 -0
- package/skills/architect-impl-governance/README.md +46 -0
- package/skills/architect-impl-governance/SKILL.md +45 -0
- package/skills/architect-spec-governance/README.md +48 -0
- package/skills/architect-spec-governance/SKILL.md +59 -0
- package/skills/blast-estimate/README.md +47 -0
- package/skills/blast-estimate/SKILL.md +133 -0
- package/skills/blast-estimate/scripts/blast-estimate.mts +583 -0
- package/skills/builder-impl-governance/README.md +47 -0
- package/skills/builder-impl-governance/SKILL.md +47 -0
- package/skills/builder-spec-governance/README.md +49 -0
- package/skills/builder-spec-governance/SKILL.md +36 -0
- package/skills/check-partition-quality/README.md +22 -0
- package/skills/check-partition-quality/SKILL.md +51 -0
- package/skills/check-partition-quality/scripts/check-partition-quality.mts +336 -0
- package/skills/check-plan-safety/README.md +17 -0
- package/skills/check-plan-safety/SKILL.md +60 -0
- package/skills/check-plan-safety/scripts/check-plan-safety.mts +145 -0
- package/skills/check-project-specs/README.md +19 -0
- package/skills/check-project-specs/SKILL.md +69 -0
- package/skills/check-project-specs/scripts/check-project-specs.mts +217 -0
- package/skills/check-scenario-overlap/README.md +19 -0
- package/skills/check-scenario-overlap/SKILL.md +74 -0
- package/skills/check-scenario-overlap/scripts/check-scenario-overlap.mts +249 -0
- package/skills/check-spec-structure/README.md +17 -0
- package/skills/check-spec-structure/SKILL.md +66 -0
- package/skills/check-spec-structure/scripts/check-spec-structure.mts +346 -0
- package/skills/collision-ladder/README.md +18 -0
- package/skills/collision-ladder/SKILL.md +83 -0
- package/skills/collision-ladder/scripts/collision-ladder.mts +657 -0
- package/skills/combat-log-governance/README.md +13 -0
- package/skills/combat-log-governance/SKILL.md +257 -0
- package/skills/concept-index/README.md +13 -0
- package/skills/concept-index/SKILL.md +38 -0
- package/skills/concept-index/scripts/concept-index.mts +245 -0
- package/skills/discover-plans/README.md +16 -0
- package/skills/discover-plans/SKILL.md +74 -0
- package/skills/discover-plans/scripts/discover-plans.mts +212 -0
- package/skills/discover-specs/README.md +15 -0
- package/skills/discover-specs/SKILL.md +76 -0
- package/skills/discover-specs/scripts/discover-specs.mts +396 -0
- package/skills/doctrine-loop/README.md +15 -0
- package/skills/doctrine-loop/SKILL.md +97 -0
- package/skills/formation-loop/README.md +17 -0
- package/skills/formation-loop/SKILL.md +140 -0
- package/skills/gate-validation-governance/README.md +12 -0
- package/skills/gate-validation-governance/SKILL.md +87 -0
- package/skills/impl-producer-governance/README.md +48 -0
- package/skills/impl-producer-governance/SKILL.md +85 -0
- package/skills/init/README.md +27 -0
- package/skills/init/SKILL.md +68 -0
- package/skills/init/scripts/wire-statusline.mts +276 -0
- package/skills/lifecycle-governance/README.md +11 -0
- package/skills/lifecycle-governance/SKILL.md +168 -0
- package/skills/manage/README.md +9 -0
- package/skills/manage/SKILL.md +62 -0
- package/skills/manage-ignore/README.md +19 -0
- package/skills/manage-ignore/SKILL.md +52 -0
- package/skills/manage-ignore/scripts/manage-ignore.mts +294 -0
- package/skills/manage-scenario-bridge/README.md +20 -0
- package/skills/manage-scenario-bridge/SKILL.md +60 -0
- package/skills/manage-scenario-bridge/scripts/manage-scenario-bridge.mts +156 -0
- package/skills/manage-spec-anchors/README.md +18 -0
- package/skills/manage-spec-anchors/SKILL.md +56 -0
- package/skills/manage-spec-anchors/scripts/manage-spec-anchors.mts +328 -0
- package/skills/mission-graph/README.md +15 -0
- package/skills/mission-graph/SKILL.md +67 -0
- package/skills/mission-graph/scripts/mission-graph.mts +844 -0
- package/skills/oracle-spec-governance/README.md +45 -0
- package/skills/oracle-spec-governance/SKILL.md +45 -0
- package/skills/ownership-governance/README.md +65 -0
- package/skills/ownership-governance/SKILL.md +104 -0
- package/skills/pause-mission/README.md +18 -0
- package/skills/pause-mission/SKILL.md +112 -0
- package/skills/place-node/README.md +12 -0
- package/skills/place-node/SKILL.md +47 -0
- package/skills/place-node/scripts/place-node.mts +157 -0
- package/skills/plan-retirement/README.md +32 -0
- package/skills/plan-retirement/SKILL.md +90 -0
- package/skills/plan-retirement/scripts/retire-plans.mts +196 -0
- package/skills/plugin-contract-governance/README.md +12 -0
- package/skills/plugin-contract-governance/SKILL.md +112 -0
- package/skills/remediation-governance/README.md +46 -0
- package/skills/remediation-governance/SKILL.md +78 -0
- package/skills/resolve-governances/README.md +18 -0
- package/skills/resolve-governances/SKILL.md +50 -0
- package/skills/resolve-governances/scripts/resolve-governances.mts +515 -0
- package/skills/resolve-tracking/SKILL.md +64 -0
- package/skills/resolve-tracking/scripts/resolve-tracking.mts +213 -0
- package/skills/resume-mission/README.md +12 -0
- package/skills/resume-mission/SKILL.md +53 -0
- package/skills/scaffold-project-spec/README.md +7 -0
- package/skills/scaffold-project-spec/SKILL.md +192 -0
- package/skills/sdd/README.md +7 -0
- package/skills/sdd/SKILL.md +92 -0
- package/skills/solution-producer-governance/README.md +9 -0
- package/skills/solution-producer-governance/SKILL.md +44 -0
- package/skills/spec-format-governance/README.md +73 -0
- package/skills/spec-format-governance/SKILL.md +114 -0
- package/skills/spec-gate/README.md +26 -0
- package/skills/spec-gate/SKILL.md +201 -0
- package/skills/spec-gate/scripts/check-spec-state.mts +601 -0
- package/skills/spec-gate/scripts/check-suite.mts +501 -0
- package/skills/spec-gate/scripts/classify-edit-class.mts +411 -0
- package/skills/spec-producer-governance/README.md +7 -0
- package/skills/spec-producer-governance/SKILL.md +86 -0
- package/skills/spec-structure-governance/README.md +40 -0
- package/skills/spec-structure-governance/SKILL.md +169 -0
- package/skills/ssa-lowering/README.md +26 -0
- package/skills/ssa-lowering/SKILL.md +181 -0
- package/skills/start-mission/README.md +7 -0
- package/skills/start-mission/SKILL.md +115 -0
- package/skills/suite-format-governance/README.md +75 -0
- package/skills/suite-format-governance/SKILL.md +299 -0
- package/skills/suite-format-governance/references/rubric.md +313 -0
- package/skills/touch-set-correction/README.md +16 -0
- package/skills/touch-set-correction/SKILL.md +67 -0
- package/skills/touch-set-correction/scripts/touch-set-correction.mts +418 -0
- package/skills/verify-scenarios/README.md +17 -0
- package/skills/verify-scenarios/SKILL.md +109 -0
- package/skills/verify-scenarios/scripts/verify-scenarios.mts +386 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: solution-producer-governance
|
|
3
|
+
description: "Partial Skill: invoke by name only — the SDD default solution-producer procedure. Loaded in-session by the conductor when it runs the solution-producer role inline, not user-triggered."
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Solution-Producer Governance — the default solution-recording procedure
|
|
8
|
+
|
|
9
|
+
The procedure the **conductor** follows when it runs the **solution-producer** role from the SDD default — no plugin covers the domain and no model-tuned producer agent is named for the slot, so the conductor **loads this governance and authors inline** in its own warm context (recorded `produced-by.solution-producer: sdd:automaton`). This is the relocation of the former `plan-producer` role's *functional-spec* half: the solution is the chosen approach + rejected alternatives, now recorded **per unit** as `<unit>.solution.md` rather than as a `plan.md`. The task DAG that `plan-producer` also wrote is **not** this role's output — it is the conductor's transient execution `.plan.md` `todos`.
|
|
10
|
+
|
|
11
|
+
The solution is the unit's **third facet** (spec = *what*, suite = *proof*, solution = *why this shape*). It is **optional** and **ungated**: it gets no judge of its own, stays out of the spec-judge's view, and is never frozen. The implementation's frozen-scenario result validates it transitively.
|
|
12
|
+
|
|
13
|
+
Load alongside this governance: the resolved **architect** actor bar (structural fit — no duplication or conflict with existing code/conventions) to self-align before writing, and `sdd:ownership-governance` for the write-ownership matrix — the solution-producer must **not** modify `spec.md`, the `.feature`, or any control frontmatter; a behavior gap discovered while recording the solution is a `CONTENT_GAP` / `OBSERVATIONS`, never an in-place edit.
|
|
14
|
+
|
|
15
|
+
## Inputs (folded in by the conductor)
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
DOMAIN, DOMAIN_PATH, SPEC_PATH, FEATURE_PATH, SOLUTION_PATH
|
|
19
|
+
MODE: explore | implement
|
|
20
|
+
EXISTING_SOLUTION: <the current <unit>.solution.md, on a revise — or null>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Procedure
|
|
24
|
+
|
|
25
|
+
1. **Decide whether a solution is warranted at all.** Read `spec.md` and the `.feature`. Write a solution **only** when the unit has a **real design fork** — a non-obvious approach chosen over plausible alternatives that a later reader could not reconstruct from the spec alone. If the unit's shape follows directly from its spec, **write no file** and return `STATUS: complete` with `SOLUTION_WRITTEN: none`. A solution that would only paraphrase the spec's *what* or the suite's *proof* is noise — do not write it.
|
|
26
|
+
|
|
27
|
+
2. **Record the solution at the design boundary, not per scenario.** Write `<SOLUTION_PATH>` (`<unit>.solution.md`, beside the unit's `README.md` + `.feature`) capturing: the **chosen approach**, the **rejected alternatives with why each lost**, and the trade-offs that decided it. Map to the **decision**, not one entry per scenario — the suite already covers scenarios. Apply the **architect** bar (does this shape fit existing code/conventions without duplication or conflict?).
|
|
28
|
+
|
|
29
|
+
3. **Never restate the contract.** Do not paraphrase `spec.md` or the `.feature`. The solution adds *why this shape*; it carries no *what* the spec already states and no *proof* the suite already encodes.
|
|
30
|
+
|
|
31
|
+
4. **On a revise, tighten in place.** When `EXISTING_SOLUTION` is non-null, sharpen the existing record rather than rewriting from scratch; if the design fork it documented no longer exists, remove the file (the optional facet returns to absent).
|
|
32
|
+
|
|
33
|
+
5. **Never modify `spec.md` or the `.feature`** — four-eyes (the producer does not set its own bar). The solution is co-delivered with the other producers' artifacts, not in a separate gated phase.
|
|
34
|
+
|
|
35
|
+
## Output (the conductor collects)
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
STATUS: complete | needs-input | blocked
|
|
39
|
+
SOLUTION_WRITTEN: written | tightened | removed | none
|
|
40
|
+
NOTES: <the fork recorded, or why none was warranted>
|
|
41
|
+
QUESTIONS: [ batched, when needs-input ]
|
|
42
|
+
CONTENT_GAPS: [ { artifact, location, gap } ]
|
|
43
|
+
OBSERVATIONS: [ { owner: architect | strategist, note, evidence } ]
|
|
44
|
+
```
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# spec-format-governance
|
|
2
|
+
|
|
3
|
+
This is an internal SDD governance about the project specification.
|
|
4
|
+
|
|
5
|
+
It describes how one capability's `spec.md` is structured and what it should contain.
|
|
6
|
+
|
|
7
|
+
Every behavioral spec in the project is written to the same shape, so a reader who has read one
|
|
8
|
+
knows where to look in any other. This governance is that shape.
|
|
9
|
+
|
|
10
|
+
## Where a spec lives — the folder structure
|
|
11
|
+
|
|
12
|
+
A `spec.md` never sits on its own. The project spec is a folder tree organized by **capability** —
|
|
13
|
+
the top-level folder names say what the project *does* (`gateway/`, `intake/`, `mission/`) — with
|
|
14
|
+
three folders that are deliberately not capabilities:
|
|
15
|
+
|
|
16
|
+
| Folder | Holds | Why it is not a capability |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| `design/` | The **rules** — the model, and the *why*. | Describes the system rather than doing something in it. |
|
|
19
|
+
| `workflows/` | The **usage** — how the capabilities compose into whole flows. | Cuts across every capability instead of being one. |
|
|
20
|
+
| `ledger/` | The **provenance** — durable audit records. | Data, not a spec at all. |
|
|
21
|
+
|
|
22
|
+
Two rules shape the tree:
|
|
23
|
+
|
|
24
|
+
- **Two levels, never three.** A capability folder holds leaf units (`<capability>/<unit>/`), and
|
|
25
|
+
that is as deep as it goes. When something inside a capability wants its own sub-grouping — a
|
|
26
|
+
phase, a producer/judge pair — that grouping is a *cross-cutting concern*, so it is tagged with
|
|
27
|
+
`concept:` frontmatter and recovered through the by-concept index rather than given a third
|
|
28
|
+
folder level.
|
|
29
|
+
- **Rules in `design/`, behavior in the capability folder.** The rule a thing follows and the
|
|
30
|
+
scenarios that enact that rule live apart, which keeps `design/` readable as a model while the
|
|
31
|
+
capabilities stay testable as behavior.
|
|
32
|
+
|
|
33
|
+
Each leaf unit folder holds the `spec.md` this governance describes, its `.feature` suite alongside
|
|
34
|
+
it, and optionally a `.solution.md`.
|
|
35
|
+
|
|
36
|
+
The folder law itself — spec types, the folder kinds, screaming architecture, the depth cap — is
|
|
37
|
+
owned by **`spec-structure-governance`**, not by this bar. It is summarized here so the file
|
|
38
|
+
structure below has somewhere to sit.
|
|
39
|
+
|
|
40
|
+
## What it requires — the file structure
|
|
41
|
+
|
|
42
|
+
A `spec.md` has **four sections, in this order**:
|
|
43
|
+
|
|
44
|
+
| Section | What goes in it |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| `## What` | What the capability is, the problem it solves, who has that problem, and what it deliberately does not do (non-goals). |
|
|
47
|
+
| `## Use Cases` | Every distinct way the capability is invoked — one row each, as trigger / inputs / outcome. Each is named after the thing you actually call: a CLI verb, a function, an endpoint. |
|
|
48
|
+
| `## Control Flow` | The decisions the capability makes once invoked, taken as one **control-flow graph (CFG)** and **drawn** as a diagram rather than described in prose. Use cases feed into one CFG; several usually share it. |
|
|
49
|
+
| `## Scenario map` | A table pairing each branch in that diagram with the one test scenario covering it, grouped by use case. One-to-one, both directions — so a gap in coverage is visible instead of buried in prose. |
|
|
50
|
+
|
|
51
|
+
It also sets a **plain-language bar**: a smart reader with no background in the domain should follow
|
|
52
|
+
the spec on the first read. Simplify the writing, never the domain — define the domain terms in
|
|
53
|
+
plain words instead of dropping them. This is a gate requirement, not a style preference, because
|
|
54
|
+
`spec.md` is what gets reviewed.
|
|
55
|
+
|
|
56
|
+
Descriptive indexes and reference documents are exempt — they carry none of these sections.
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
- **spec-producer:** how to write the spec
|
|
61
|
+
- **spec-judge:** grade the spec structure and content at the **spec-gate**
|
|
62
|
+
|
|
63
|
+
## Related governances
|
|
64
|
+
|
|
65
|
+
This bar owns the layout of a **single** `spec.md`. Its neighbors own everything around that:
|
|
66
|
+
|
|
67
|
+
- **`spec-structure-governance`** — the layout law this sits inside, and the owner of the folder
|
|
68
|
+
structure summarized above: spec types, the folder kinds, screaming architecture, the depth cap.
|
|
69
|
+
- **`suite-format-governance`** — how the `.feature` suite itself is written (Gherkin form, rubrics,
|
|
70
|
+
scenario ordering).
|
|
71
|
+
- The **corpus-organization** bar — how big a spec should be in the first place.
|
|
72
|
+
|
|
73
|
+
Internal SDD governance (`user-invocable: false`). Not triggered by users directly.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-format-governance
|
|
3
|
+
description: "Partial Skill: invoke by name only"
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Spec-Format Governance — the spec.md structure bar
|
|
8
|
+
|
|
9
|
+
Universal bar for how a **behavioral** node's `spec.md` is structured. The spec-producer self-aligns
|
|
10
|
+
to it before writing; the spec-judge grades structure backward at the spec gate. The layout law it
|
|
11
|
+
sits inside — spec types, the four folder kinds, screaming architecture — is
|
|
12
|
+
`sdd:spec-structure-governance`; this bar owns one node's `spec.md`. A descriptive index or reference
|
|
13
|
+
artifact carries none of the sections below.
|
|
14
|
+
|
|
15
|
+
## The four sections, in order (plus one optional)
|
|
16
|
+
|
|
17
|
+
### `## What`
|
|
18
|
+
The overview: what the capability is, the problem it solves, who has it — plus **Non-goals** (what it
|
|
19
|
+
deliberately excludes). One or two short paragraphs; add a **Key terms** glossary when it leans on
|
|
20
|
+
jargon. Legible to a non-engineer.
|
|
21
|
+
|
|
22
|
+
### `## Use Cases`
|
|
23
|
+
The **entry points** — one row per distinct way the capability is invoked, each **named to its
|
|
24
|
+
implementation surface** (a CLI verb, a public function, an endpoint), given as
|
|
25
|
+
**trigger / inputs / outcome**. A use case answers *"when, and with what, is this invoked?"* — never
|
|
26
|
+
*"given this state, does it do that?"* (that is a scenario). Naming the impl surface keeps the spec,
|
|
27
|
+
the suite, and the code on **one screaming structure**: the builder gives each use case its own
|
|
28
|
+
module, so each change stays local.
|
|
29
|
+
|
|
30
|
+
### `## Control Flow`
|
|
31
|
+
The **control-flow graph (CFG)** the capability runs once invoked, **drawn** as a fenced Mermaid
|
|
32
|
+
graph — nodes are decisions, edges are branches. Use cases **enter** the CFG, and several usually
|
|
33
|
+
share one (many-to-one). When use cases run genuinely distinct decision logic (common for CLI verbs),
|
|
34
|
+
section `## Control Flow` by sub-graph and have each use case name the one it enters. A single-branch
|
|
35
|
+
capability may state its decision in a line.
|
|
36
|
+
|
|
37
|
+
### `## Scenario map`
|
|
38
|
+
The **explicit maintained table** binding the CFG to the suite, **grouped by use case**, with three
|
|
39
|
+
columns — **`| Edge | Path (Given) | Scenario |`**. The unit is the **(path class, edge)** pair, not
|
|
40
|
+
the edge alone: a scenario's `Given` is the path reaching the edge, its `When` is the edge under test
|
|
41
|
+
(`sdd:suite-format-governance`).
|
|
42
|
+
|
|
43
|
+
- **1:1 scenario↔row** — every scenario has exactly one row, every row one scenario.
|
|
44
|
+
- **An edge may carry several rows.** That is **permutation coverage**, not duplication — legitimate
|
|
45
|
+
when each row's path class yields a *different* outcome. Same edge *and* same path class twice is a
|
|
46
|
+
duplicate.
|
|
47
|
+
- **Collapse reconverged paths.** Where the outcome does not depend on which upstream branch was
|
|
48
|
+
taken, one row covers them all; write the path as the reconvergence point (or `any`), never the
|
|
49
|
+
route. Naming state the outcome does not depend on manufactures a false permutation.
|
|
50
|
+
- An edge with **no** row is a coverage hole; a scenario with **no nameable edge** is not acceptance
|
|
51
|
+
and does not belong in the suite.
|
|
52
|
+
|
|
53
|
+
Three columns make the shape legible at a glance: a `Path` column reading `any` is a **convergence**
|
|
54
|
+
claim (the outcome does not vary), and an edge repeated with different paths shows exactly which
|
|
55
|
+
distinctions the contract cares about. The grouping keeps coverage **visible per use case** — an
|
|
56
|
+
uncovered surface is a hole, not a silent gap in prose. `check-suite` lints it. A `@pinned` behavior
|
|
57
|
+
the CFG did not reach enters as a **seed** the agent grows the CFG around, adding the discovered
|
|
58
|
+
edges to the map.
|
|
59
|
+
|
|
60
|
+
### On backfill — draw the CFG and the scenario map, don't stop at Use Cases
|
|
61
|
+
When the implementation already exists (a **backfill**), the four sections are **still mandatory**.
|
|
62
|
+
Read the source, then **draw the `## Control Flow` CFG from the code** and its 1:1 `## Scenario map` —
|
|
63
|
+
a spec that stops at `## Use Cases` has named its entry points but neither the decisions the
|
|
64
|
+
capability takes nor their coverage. The suite is **re-derived from that CFG**, not patched from the
|
|
65
|
+
standing one (`sdd:suite-format-governance`). `check-spec-structure`'s `incomplete-node` flags a
|
|
66
|
+
behavioral leaf that skips a required section.
|
|
67
|
+
|
|
68
|
+
### `## References` *(optional — any spec-type)*
|
|
69
|
+
Where a decision in this node rests on **research or an external standard**, cite it here: the source
|
|
70
|
+
and **what it backs**. Not a bibliography — a line earns its place only by carrying a decision that
|
|
71
|
+
would otherwise read as taste.
|
|
72
|
+
|
|
73
|
+
- **Cite the claim, not the topic.** "Vague steps produce defensive step definitions carrying flags,
|
|
74
|
+
so a `Given` must be buildable — [source]" beats "see [source] on BDD".
|
|
75
|
+
- **External sources only.** A sibling spec, a `design/` model doc, or a governance is a normal
|
|
76
|
+
in-body reference, not a research citation.
|
|
77
|
+
- **Optional and rare.** Most nodes decide from the domain and cite nothing. An empty section is
|
|
78
|
+
omitted, never stubbed.
|
|
79
|
+
- **Not the design record.** A chosen-vs-rejected design fork belongs in the unit's
|
|
80
|
+
`<unit>.solution.md`; `## References` records the *evidence consulted*, which outlives the fork.
|
|
81
|
+
|
|
82
|
+
It is the last section, after `## Scenario map` (or after `## Subject` on a reference artifact).
|
|
83
|
+
Reason: a reader wants the contract first and the provenance only when they question it.
|
|
84
|
+
|
|
85
|
+
## Plain language — a gate requirement, not a nicety
|
|
86
|
+
|
|
87
|
+
`spec.md` is reviewed at the gate, so plain language is a bar it must clear. Write so a **smart
|
|
88
|
+
reader with no domain context follows it on the first read**:
|
|
89
|
+
|
|
90
|
+
- **Simplify the writing, never the domain.** Domain concepts are essential — define each in plain
|
|
91
|
+
words, never drop one to sound simpler. Jargon, long sentences, and unexplained acronyms are
|
|
92
|
+
accidental — drive them to zero.
|
|
93
|
+
- **Lead with the plain word**, keep the specialized term as a parenthetical ("**safe to repeat**
|
|
94
|
+
(idempotent)"); carry a **Key terms** glossary when the spec leans on several.
|
|
95
|
+
- **Short sentences, concrete over abstract.** Draw a diagram wherever it beats prose; format with
|
|
96
|
+
headings, tables, and callouts for the load-bearing decisions.
|
|
97
|
+
|
|
98
|
+
The same bar binds the **suite**'s scenarios — plain `Given/When/Then` the same reader can follow.
|
|
99
|
+
Enrichment (diagrams, formatting) is `spec.md` only; the suite stays plain Gherkin.
|
|
100
|
+
|
|
101
|
+
## Key points (read-check)
|
|
102
|
+
|
|
103
|
+
1. **Four sections in order** — `## What` (overview + non-goals), `## Use Cases`, `## Control Flow`,
|
|
104
|
+
`## Scenario map` — plus an optional `## References` last, citing research that backs a decision
|
|
105
|
+
(the claim it supports, not the topic).
|
|
106
|
+
2. **A use case is an entry point named to its impl surface** (CLI verb / function / endpoint) — spec,
|
|
107
|
+
suite, and code share one screaming structure.
|
|
108
|
+
3. **The CFG is shared** — use cases enter it (many-to-one); section by sub-graph only when the
|
|
109
|
+
decision logic genuinely differs.
|
|
110
|
+
4. **The scenario map is 1:1 and grouped by use case** — coverage visible per use case; `check-suite`
|
|
111
|
+
lints it.
|
|
112
|
+
5. **A `@pinned` behavior enters as a seed** the agent grows the CFG around.
|
|
113
|
+
6. **Plain language is a gate bar** — a reader with no domain context follows the spec (and its
|
|
114
|
+
suite) on first read; define every term, simplify the writing not the domain.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# spec-gate
|
|
2
|
+
|
|
3
|
+
Internal SDD skill that runs the **spec gate** (Draft → Approved) over a CR's spec + suite
|
|
4
|
+
**diff**. It runs the deterministic structural checks (`scripts/check-spec-state.mts` — the root
|
|
5
|
+
lifecycle tuple + the per-node `spec-type` reconcile) and the provenance structural checks first
|
|
6
|
+
(fail-closed on malformed `produced-by` / no resolvable producer; flag-only on uninstalled
|
|
7
|
+
producers), then — running **in-session** as the conductor at the gate — **spawns a distinct cold
|
|
8
|
+
spec-judge** over `spec.md` + the `.feature` (the **{oracle, builder, architect}** lens set; the
|
|
9
|
+
solution stays out of its view) and derives the leash, then takes the verdict — self-asserting into
|
|
10
|
+
the async review queue when in leash, else showing the in-session digest and taking the human
|
|
11
|
+
verdict directly (it holds the user channel).
|
|
12
|
+
|
|
13
|
+
On **approve** it freezes each touched `.feature` per-file (`@frozen`), appends a per-CR `gate`
|
|
14
|
+
line to the mission's own `ledger/` shard, and writes `status: approved`; `spec.md`/READMEs stay aligned, never frozen.
|
|
15
|
+
The **impl gate** is the mission's, not here. The gate is verdict-only — it writes no setup
|
|
16
|
+
frontmatter and never fixes issues automatically.
|
|
17
|
+
|
|
18
|
+
References `sdd:lifecycle-governance`, `sdd:ownership-governance`, `sdd:gate-validation-governance`,
|
|
19
|
+
`sdd:combat-log-governance` (provenance/freeze shapes), and the conductor's autonomy bar.
|
|
20
|
+
|
|
21
|
+
## scripts/
|
|
22
|
+
|
|
23
|
+
- `check-spec-state.mts` — deterministic state validator (root tuple + per-node spec-type
|
|
24
|
+
reconcile); run via `pnpm verify:specs-new`. Tested by `check-spec-state.test.mts`.
|
|
25
|
+
- `check-suite.mts` — deterministic `.feature`-form validator (Gherkin validity, boolean-`Then`
|
|
26
|
+
form, scenario ordering); run via `pnpm verify:specs-new`. Tested by `check-suite.test.mts`.
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-gate
|
|
3
|
+
description: "Partial Skill: invoke by name only — the SDD spec gate (Draft → Approved), the verdict on a CR's spec + suite diff — run by the conductor inside the mission loop, not triggered by users directly."
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# spec-gate
|
|
8
|
+
|
|
9
|
+
Run the SDD **spec gate**: the verdict on a CR's spec + suite **diff** before it becomes the
|
|
10
|
+
contract. This is an **internal step the conductor runs inside the mission loop** (loaded by
|
|
11
|
+
`start-mission` at the end of explore), **not** a user-invocable skill. It **spawns a distinct
|
|
12
|
+
cold spec-judge**, derives the **leash**, takes the verdict (the in-session conductor holds the user
|
|
13
|
+
channel, so it is the positional ratifier), and on approval **freezes** each touched `.feature` file
|
|
14
|
+
and records a durable per-CR `gate` line. The impl gate (Approved → Implemented) is **not** here — it
|
|
15
|
+
is the mission's. This skill never collapses producing and judging into one voice.
|
|
16
|
+
|
|
17
|
+
Load `sdd:lifecycle-governance` (status enum, transitions, the freeze state-transition),
|
|
18
|
+
`sdd:ownership-governance` (who may write `status` / `approval`),
|
|
19
|
+
`sdd:gate-validation-governance` (legal-state tuples, per-node spec-type checks, derived sync —
|
|
20
|
+
no stored flag, `approval` attribution). The `produced-by` and sharded-ledger shapes the gate checks are in
|
|
21
|
+
`sdd:combat-log-governance`; the freeze model in `sdd:lifecycle-governance`; the
|
|
22
|
+
self-clear-vs-escalate bar and the four-C floor are the conductor's autonomy bar (`start-mission`).
|
|
23
|
+
|
|
24
|
+
## 1. Structural checks (deterministic, run first)
|
|
25
|
+
|
|
26
|
+
Run before any verdict work; structural validity **fails closed**, availability only **flags**:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
node "<skill>/scripts/check-spec-state.mts" [--root <specs-dir>]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Exit `0` = legal; exit `1` prints each violation as `✗ <slug>: <reason>` — fix before continuing.
|
|
33
|
+
It checks the root lifecycle tuple **and** the per-node `spec-type` reconcile: a `reference` node
|
|
34
|
+
carrying a `.feature` or missing its `## Subject`, and a `behavioral` node missing `## Use Cases`,
|
|
35
|
+
**fail closed**; a descriptive node (no marker) raises no violation. If `node` is unavailable,
|
|
36
|
+
perform the same checks by reading each README's frontmatter yourself.
|
|
37
|
+
|
|
38
|
+
The sibling `scripts/check-suite.mts` is the **`.feature`-form** authority — Gherkin validity,
|
|
39
|
+
boolean-`Then` form (hedge-word + leaked-rubric detection), and scenario ordering/sectioning. When
|
|
40
|
+
the CR touches any `.feature`, run it here **fail-closed, before spawning the cold judge**, scoped to
|
|
41
|
+
the CR's touched files:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
node "<skill>/scripts/check-suite.mts" --files <the CR's touched .feature files>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Exit `0` = form clean; exit `1` prints each `✗ <file>: <reason>` — **advance nothing and do not
|
|
48
|
+
spawn the judge; report the violations for the producer to fix.** Scoping to `--files` keeps the gate
|
|
49
|
+
on the CR's delta; the tree-wide `--root` sweep stays the `verify:specs-new` CI backstop. The cold
|
|
50
|
+
spec-judge grades form qualitatively; this engine catches it mechanically, so the judge only ever
|
|
51
|
+
sees a well-formed suite.
|
|
52
|
+
|
|
53
|
+
The same `check-spec-state.mts` also carries **referenced-artifact-exists** — a backtick-wrapped
|
|
54
|
+
path any touched **prose `.md` under the spec tree** names (not just `spec.md`/`README.md` — a
|
|
55
|
+
`design/*.md` or nested node doc too; a relative `./`/`../` reference or a repo-root-relative one
|
|
56
|
+
under `.agents/`, `plugins/`, `packages/`, `apps/`, `docs/`, `.claude/`) must resolve to a real
|
|
57
|
+
file or dir; a template placeholder (`<project>`) or glob (`*.plan.md`) is exempt. **Diff-scoped +
|
|
58
|
+
surface-for-judgment, not fail-closed:** the check gates only paths the CR **introduces** against
|
|
59
|
+
the file's committed baseline (`--base <baseref>`, absent ⇒ every ref counts as introduced) — a
|
|
60
|
+
pre-existing reference a touched file already carried is never gated. An unresolved *introduced*
|
|
61
|
+
ref is printed as a `⚠` finding for the cold judge to weigh, but never blocks the gate on its own;
|
|
62
|
+
the judge still runs. Referenced ≠ must-exist. Never the `--root` sweep, since the existing
|
|
63
|
+
corpus's accumulated prose legitimately names example/convention paths a blind tree-wide scan
|
|
64
|
+
cannot distinguish from a real broken reference. Pass every touched `.md` path (the engine filters
|
|
65
|
+
internally to prose `.md` files that lie under the spec tree — `.agents/spec/`, `.agents/specs/`,
|
|
66
|
+
or a nested `<project-path>/.agents/spec/` — so a touched `.md` outside the spec tree is never
|
|
67
|
+
swept):
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
node "<skill>/scripts/check-spec-state.mts" --files <the CR's touched .md files> [--base <baseref>]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Exit `0` prints each `⚠ <file>: introduces unresolved reference ...` finding (if any) plus the
|
|
74
|
+
summary line — **surface the findings for the judge's read, never a hard block by themselves.**
|
|
75
|
+
An unreadable touched file still **fails closed** (`✗ <file>: cannot read file`, exit `1`) — that
|
|
76
|
+
is a real error, not a can-exist judgment call.
|
|
77
|
+
|
|
78
|
+
Also carried in the same `--files` pass: the **use-case-coverage** pre-filter. For each touched
|
|
79
|
+
file whose `## Use Cases` section is written as a **table** with a `Scenario` column, every row's
|
|
80
|
+
backtick-wrapped `Scenario:` title (or shared `@tag`) must resolve to a real `Scenario:` in the
|
|
81
|
+
sibling `.feature` (same directory). Unresolved → **fail closed**, judge not spawned. Non-mandating:
|
|
82
|
+
no `## Use Cases` section, or a table with no `Scenario` column, or prose/EARS use cases, raise no
|
|
83
|
+
violation and stay the spec-judge's coverage backstop. Exit `1` prints each `✗ <file>: Use Cases
|
|
84
|
+
table names scenario ... that does not resolve in the sibling .feature`.
|
|
85
|
+
|
|
86
|
+
**Provenance structural checks** (`sdd:combat-log-governance`). Read the touched files'
|
|
87
|
+
`produced-by` frontmatter and the root's `ledger/` shards (globbed; a legacy `ledger.jsonl` still counts):
|
|
88
|
+
|
|
89
|
+
- **Malformed `produced-by` entry** — a value that is not a well-formed plugin-qualified name
|
|
90
|
+
(`<plugin>:<agent>`) → **flag and fail closed**.
|
|
91
|
+
- **Uninstalled-but-valid recorded producer** — an entry whose plugin is not installed is valid
|
|
92
|
+
history → **flag only** (annotate `[unavailable]`), do not block.
|
|
93
|
+
- **No resolvable producer** — a required production role that resolves to neither a plugin agent
|
|
94
|
+
nor an SDD default → **fail closed**.
|
|
95
|
+
|
|
96
|
+
The gate stays verdict-only — it writes **no** setup frontmatter to resolve any of these.
|
|
97
|
+
|
|
98
|
+
## 2. Identify the CR's diff footprint
|
|
99
|
+
|
|
100
|
+
The gate decides a **CR**, not a single folder: resolve the set of files this CR **touched**
|
|
101
|
+
(the spec READMEs + `.feature` files in its delta). The digest and freeze both operate over this
|
|
102
|
+
footprint, never the whole tree and never one fleet-era folder.
|
|
103
|
+
|
|
104
|
+
## 3. Judge and derive the leash
|
|
105
|
+
|
|
106
|
+
Resolve the **spec-judge** for each `artifact-types` (a plugin judge or the SDD default
|
|
107
|
+
`sdd-spec-judge`) and **spawn it cold** over the touched node(s) — pass it `spec.md` + the
|
|
108
|
+
`.feature` only (the solution stays out of its view). It grades against the spec-gate lens set
|
|
109
|
+
**{oracle, builder, architect}**. Then take the judge's **contract-sync verdict** (derived at this
|
|
110
|
+
gate, never stored) and **derive the leash** (the conductor's autonomy bar,
|
|
111
|
+
baked into `start-mission`) in-session. Collect the judge's `STATUS`,
|
|
112
|
+
`ALIGNED`, failing scenarios, remaining `<!-- open: -->` markers, `OBSERVATIONS`, and the gate
|
|
113
|
+
report. The judge is a **distinct cold actor** and never edits the artifact it grades.
|
|
114
|
+
|
|
115
|
+
**Never advance** — by self-assertion or human verdict — with judge failures, any remaining open
|
|
116
|
+
markers, or a misaligned suite. They fail the confidence dimension, so they forbid self-assertion
|
|
117
|
+
too; report the blockers for the user to fix (surface `OBSERVATIONS`; on accept they become a new
|
|
118
|
+
node, never a marker grown into this spec).
|
|
119
|
+
|
|
120
|
+
## 4. Take the verdict — self-assert within leash, else the human
|
|
121
|
+
|
|
122
|
+
- **In leash** (every dimension reads safe): the conductor **self-asserts** — writes
|
|
123
|
+
`approval.spec: { verdict: approve, by: agent, why }`. The diff lands
|
|
124
|
+
**provisionally** into the asynchronous review queue. Still emit the digest + gate report,
|
|
125
|
+
flagged **"agent-asserted — ratify or kick back."**
|
|
126
|
+
- **Gated** (the leash stops, or the hard floor fires): present the **digest** above the gate
|
|
127
|
+
report so the human sees what they are deciding, then take the human verdict
|
|
128
|
+
(`approve` / `change` / `reject`).
|
|
129
|
+
|
|
130
|
+
**Hard-floor escalations at this gate** (the conductor's autonomy bar): **Clearance** — a
|
|
131
|
+
narrowing (weakening or deleting an e2e scenario), escalated unless the CR pre-authorized it; and
|
|
132
|
+
**Compatibility** — the change's semver class exceeds the authorized change-class ceiling.
|
|
133
|
+
**Conflict resolution** cases (a contradiction inside the suite) are surfaced here but formally
|
|
134
|
+
fire at the impl gate; **Consent** never fires at authoring. Everything additive / internal / minor
|
|
135
|
+
self-clears.
|
|
136
|
+
|
|
137
|
+
## 5. Apply the verb + freeze
|
|
138
|
+
|
|
139
|
+
| Verb | Action |
|
|
140
|
+
|---|---|
|
|
141
|
+
| **approve** | land the diff; **freeze** each touched `.feature` (set its own `@frozen` tag); append a per-CR `gate` line to the mission's **own shard** in the `ledger/` directory sibling to `spec.md` (`verdict: approve`, `frozen[]`, keyed by `cr`, no `ts`); write `status: approved` |
|
|
142
|
+
| **change** | revise the diff; **nothing freezes**; stays `draft`. The findings are **evidence, not a work order** — the producer substantiates each before acting, states the **rule** each instantiates and sweeps for its other instances, re-derives every correction against the rule **governing the artifact**, and accounts for each finding's **provenance**: a finding naming an artifact the previous round's commits changed is a **regression**, which stops the loop for a re-plan (`sdd:remediation-governance`) |
|
|
143
|
+
| **reject** | scope-kill — drop the delta; nothing freezes |
|
|
144
|
+
|
|
145
|
+
**Freeze is per `.feature` file.** Each touched file hard-freezes via its `@frozen` tag; untouched
|
|
146
|
+
files keep their state. An **additive** scenario folds into a frozen file without unfreezing it
|
|
147
|
+
(self-clears) — the `addOnly` result of the mechanical diff above (`gherkin-cli diff`) confirms a
|
|
148
|
+
change is purely additive with no judge round; a **narrowing/rewriting** edit (a `modified`/`removed`
|
|
149
|
+
scenario) unfreezes its file and fires **Clearance** once the narrowing is confirmed semantically.
|
|
150
|
+
The edit-class classification itself — additive / no-content-change / narrowing / mixed — comes from
|
|
151
|
+
`scripts/classify-edit-class.mts` (`--files <paths> [--base <ref>]`): a **structural** per-named-`Scenario`
|
|
152
|
+
diff via the pinned `gherkin-cli@0.0.2 diff`, plus git rename detection for a pure `git mv`, **never a raw
|
|
153
|
+
line diff** (a step orphaned off a frozen scenario onto a new adjacent scenario shows no `-` line and
|
|
154
|
+
would read as additive to a line-diff; the structural diff correctly reports the losing scenario as
|
|
155
|
+
`modified`). It only classifies — additive / no-content-change self-clear, narrowing / mixed take the
|
|
156
|
+
Clearance path above; it fires no verdict itself. Run it over the CR's touched frozen `.feature` files
|
|
157
|
+
to read the edit class before applying the verb:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
node "<skill>/scripts/classify-edit-class.mts" --files <the CR's touched .feature files> [--base <baseref>]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
A `narrowing`/`mixed` result on a still-`@frozen` file routes to **Clearance** (escalated unless the CR
|
|
164
|
+
pre-authorized it); `additive`/`no-content-change` self-clears; `unfrozen-skip` needs no edit-class gate.
|
|
165
|
+
`spec.md`
|
|
166
|
+
/ the node READMEs are **kept aligned, never frozen** — editable, but may not contradict a frozen
|
|
167
|
+
scenario (enforced by the alignment check and the judge, not a flat freeze). Vocabulary is
|
|
168
|
+
**freeze/unfreeze**; "lock" is the concurrency layer.
|
|
169
|
+
|
|
170
|
+
**Attribution.** A **human verdict** writes `approval.spec: { verdict: approve, by: <name> }` (no
|
|
171
|
+
`why`) — only the in-session position may write this. A **self-assertion** already wrote
|
|
172
|
+
`by: agent, why`; this skill only writes the matching `status`. **Ratifying** a queued
|
|
173
|
+
self-assertion rewrites `by: agent` → `by: <name>` and drops it from the queue. Re-run the state
|
|
174
|
+
check after any write to confirm the tuple is legal.
|
|
175
|
+
|
|
176
|
+
## The gate digest (folded in-session)
|
|
177
|
+
|
|
178
|
+
Assemble the **digest** inline (no spawned skill) — a read-only, decision-free summary so a
|
|
179
|
+
ratifier sees *what* they are approving. It covers **only the CR's touched files**, aggregated;
|
|
180
|
+
a touched area with **no** `.feature` reports **zero scenarios, not an error**. It **writes
|
|
181
|
+
nothing, advances no status, renders no verdict**. Fixed sections:
|
|
182
|
+
|
|
183
|
+
| Section | Source |
|
|
184
|
+
|---|---|
|
|
185
|
+
| **CR** | the `cr` id + its what/why |
|
|
186
|
+
| **What** | the `## What` line of each touched capability's README |
|
|
187
|
+
| **Status** | the spec's `status` |
|
|
188
|
+
| **Scenarios** | the **added / modified / removed** `Scenario:` names across the touched `.feature` files, from a **mechanical diff** against the committed baseline — `npx gherkin-cli@0.0.2 diff --base <baseref> <file> --format json` (its `addOnly` confirms a purely additive change; a `modified`/`removed` scenario is flagged for **semantic** narrowing review — narrowing-vs-widening within a modified scenario stays a judgment). A **brand-new** suite with no committed baseline is listed with `npx gherkin-cli@0.0.2 parse <file>` (compact names / tags / counts) rather than re-tokenizing the raw file by hand |
|
|
189
|
+
| **Key decisions** | the `### ` headings under `## Design decisions` in the touched prose |
|
|
190
|
+
| **Open items** | every `<!-- open: ... -->` marker in the touched files |
|
|
191
|
+
|
|
192
|
+
## Report
|
|
193
|
+
|
|
194
|
+
- PASS / FAIL per lens, relayed from the judge
|
|
195
|
+
- `ALIGNED: true | false`; if false, which artifacts are out of sync
|
|
196
|
+
- Open markers / failing scenarios still blocking, if any
|
|
197
|
+
- The leash derivation and the effective leash for this gate
|
|
198
|
+
- On success: the new `status`, the approver (`agent` = provisional, in the review queue; `<name>` =
|
|
199
|
+
ratified), and which `.feature` files were frozen
|
|
200
|
+
|
|
201
|
+
Do not fix issues automatically — report them for the user to address or confirm intent.
|