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.
Files changed (133) hide show
  1. package/.claude-plugin/plugin.json +17 -0
  2. package/.codex-plugin/plugin.json +17 -0
  3. package/.plugin/plugin.json +17 -0
  4. package/README.md +159 -0
  5. package/agents/sdd-automaton.md +97 -0
  6. package/agents/sdd-impl-judge.md +214 -0
  7. package/agents/sdd-scanner.md +120 -0
  8. package/agents/sdd-spec-judge.md +224 -0
  9. package/agents/sdd-warden.md +101 -0
  10. package/package.json +24 -0
  11. package/skills/align-spec/README.md +20 -0
  12. package/skills/align-spec/SKILL.md +111 -0
  13. package/skills/align-spec/scripts/align-spec.mts +187 -0
  14. package/skills/architect-impl-governance/README.md +46 -0
  15. package/skills/architect-impl-governance/SKILL.md +45 -0
  16. package/skills/architect-spec-governance/README.md +48 -0
  17. package/skills/architect-spec-governance/SKILL.md +59 -0
  18. package/skills/blast-estimate/README.md +47 -0
  19. package/skills/blast-estimate/SKILL.md +133 -0
  20. package/skills/blast-estimate/scripts/blast-estimate.mts +583 -0
  21. package/skills/builder-impl-governance/README.md +47 -0
  22. package/skills/builder-impl-governance/SKILL.md +47 -0
  23. package/skills/builder-spec-governance/README.md +49 -0
  24. package/skills/builder-spec-governance/SKILL.md +36 -0
  25. package/skills/check-partition-quality/README.md +22 -0
  26. package/skills/check-partition-quality/SKILL.md +51 -0
  27. package/skills/check-partition-quality/scripts/check-partition-quality.mts +336 -0
  28. package/skills/check-plan-safety/README.md +17 -0
  29. package/skills/check-plan-safety/SKILL.md +60 -0
  30. package/skills/check-plan-safety/scripts/check-plan-safety.mts +145 -0
  31. package/skills/check-project-specs/README.md +19 -0
  32. package/skills/check-project-specs/SKILL.md +69 -0
  33. package/skills/check-project-specs/scripts/check-project-specs.mts +217 -0
  34. package/skills/check-scenario-overlap/README.md +19 -0
  35. package/skills/check-scenario-overlap/SKILL.md +74 -0
  36. package/skills/check-scenario-overlap/scripts/check-scenario-overlap.mts +249 -0
  37. package/skills/check-spec-structure/README.md +17 -0
  38. package/skills/check-spec-structure/SKILL.md +66 -0
  39. package/skills/check-spec-structure/scripts/check-spec-structure.mts +346 -0
  40. package/skills/collision-ladder/README.md +18 -0
  41. package/skills/collision-ladder/SKILL.md +83 -0
  42. package/skills/collision-ladder/scripts/collision-ladder.mts +657 -0
  43. package/skills/combat-log-governance/README.md +13 -0
  44. package/skills/combat-log-governance/SKILL.md +257 -0
  45. package/skills/concept-index/README.md +13 -0
  46. package/skills/concept-index/SKILL.md +38 -0
  47. package/skills/concept-index/scripts/concept-index.mts +245 -0
  48. package/skills/discover-plans/README.md +16 -0
  49. package/skills/discover-plans/SKILL.md +74 -0
  50. package/skills/discover-plans/scripts/discover-plans.mts +212 -0
  51. package/skills/discover-specs/README.md +15 -0
  52. package/skills/discover-specs/SKILL.md +76 -0
  53. package/skills/discover-specs/scripts/discover-specs.mts +396 -0
  54. package/skills/doctrine-loop/README.md +15 -0
  55. package/skills/doctrine-loop/SKILL.md +97 -0
  56. package/skills/formation-loop/README.md +17 -0
  57. package/skills/formation-loop/SKILL.md +140 -0
  58. package/skills/gate-validation-governance/README.md +12 -0
  59. package/skills/gate-validation-governance/SKILL.md +87 -0
  60. package/skills/impl-producer-governance/README.md +48 -0
  61. package/skills/impl-producer-governance/SKILL.md +85 -0
  62. package/skills/init/README.md +27 -0
  63. package/skills/init/SKILL.md +68 -0
  64. package/skills/init/scripts/wire-statusline.mts +276 -0
  65. package/skills/lifecycle-governance/README.md +11 -0
  66. package/skills/lifecycle-governance/SKILL.md +168 -0
  67. package/skills/manage/README.md +9 -0
  68. package/skills/manage/SKILL.md +62 -0
  69. package/skills/manage-ignore/README.md +19 -0
  70. package/skills/manage-ignore/SKILL.md +52 -0
  71. package/skills/manage-ignore/scripts/manage-ignore.mts +294 -0
  72. package/skills/manage-scenario-bridge/README.md +20 -0
  73. package/skills/manage-scenario-bridge/SKILL.md +60 -0
  74. package/skills/manage-scenario-bridge/scripts/manage-scenario-bridge.mts +156 -0
  75. package/skills/manage-spec-anchors/README.md +18 -0
  76. package/skills/manage-spec-anchors/SKILL.md +56 -0
  77. package/skills/manage-spec-anchors/scripts/manage-spec-anchors.mts +328 -0
  78. package/skills/mission-graph/README.md +15 -0
  79. package/skills/mission-graph/SKILL.md +67 -0
  80. package/skills/mission-graph/scripts/mission-graph.mts +844 -0
  81. package/skills/oracle-spec-governance/README.md +45 -0
  82. package/skills/oracle-spec-governance/SKILL.md +45 -0
  83. package/skills/ownership-governance/README.md +65 -0
  84. package/skills/ownership-governance/SKILL.md +104 -0
  85. package/skills/pause-mission/README.md +18 -0
  86. package/skills/pause-mission/SKILL.md +112 -0
  87. package/skills/place-node/README.md +12 -0
  88. package/skills/place-node/SKILL.md +47 -0
  89. package/skills/place-node/scripts/place-node.mts +157 -0
  90. package/skills/plan-retirement/README.md +32 -0
  91. package/skills/plan-retirement/SKILL.md +90 -0
  92. package/skills/plan-retirement/scripts/retire-plans.mts +196 -0
  93. package/skills/plugin-contract-governance/README.md +12 -0
  94. package/skills/plugin-contract-governance/SKILL.md +112 -0
  95. package/skills/remediation-governance/README.md +46 -0
  96. package/skills/remediation-governance/SKILL.md +78 -0
  97. package/skills/resolve-governances/README.md +18 -0
  98. package/skills/resolve-governances/SKILL.md +50 -0
  99. package/skills/resolve-governances/scripts/resolve-governances.mts +515 -0
  100. package/skills/resolve-tracking/SKILL.md +64 -0
  101. package/skills/resolve-tracking/scripts/resolve-tracking.mts +213 -0
  102. package/skills/resume-mission/README.md +12 -0
  103. package/skills/resume-mission/SKILL.md +53 -0
  104. package/skills/scaffold-project-spec/README.md +7 -0
  105. package/skills/scaffold-project-spec/SKILL.md +192 -0
  106. package/skills/sdd/README.md +7 -0
  107. package/skills/sdd/SKILL.md +92 -0
  108. package/skills/solution-producer-governance/README.md +9 -0
  109. package/skills/solution-producer-governance/SKILL.md +44 -0
  110. package/skills/spec-format-governance/README.md +73 -0
  111. package/skills/spec-format-governance/SKILL.md +114 -0
  112. package/skills/spec-gate/README.md +26 -0
  113. package/skills/spec-gate/SKILL.md +201 -0
  114. package/skills/spec-gate/scripts/check-spec-state.mts +601 -0
  115. package/skills/spec-gate/scripts/check-suite.mts +501 -0
  116. package/skills/spec-gate/scripts/classify-edit-class.mts +411 -0
  117. package/skills/spec-producer-governance/README.md +7 -0
  118. package/skills/spec-producer-governance/SKILL.md +86 -0
  119. package/skills/spec-structure-governance/README.md +40 -0
  120. package/skills/spec-structure-governance/SKILL.md +169 -0
  121. package/skills/ssa-lowering/README.md +26 -0
  122. package/skills/ssa-lowering/SKILL.md +181 -0
  123. package/skills/start-mission/README.md +7 -0
  124. package/skills/start-mission/SKILL.md +115 -0
  125. package/skills/suite-format-governance/README.md +75 -0
  126. package/skills/suite-format-governance/SKILL.md +299 -0
  127. package/skills/suite-format-governance/references/rubric.md +313 -0
  128. package/skills/touch-set-correction/README.md +16 -0
  129. package/skills/touch-set-correction/SKILL.md +67 -0
  130. package/skills/touch-set-correction/scripts/touch-set-correction.mts +418 -0
  131. package/skills/verify-scenarios/README.md +17 -0
  132. package/skills/verify-scenarios/SKILL.md +109 -0
  133. package/skills/verify-scenarios/scripts/verify-scenarios.mts +386 -0
@@ -0,0 +1,75 @@
1
+ # suite-format-governance
2
+
3
+ This is an internal SDD governance about the acceptance behavior suite.
4
+
5
+ It describes how a capability's `.feature` suite — the executable scenarios that sit beside its
6
+ `spec.md` — is written and judged.
7
+
8
+ Every behavioral spec carries such a suite, and every scenario in it collapses to one pass/fail at
9
+ the point of verification — never a score. The core idea: the suite **is** the capability's
10
+ **control-flow graph (CFG)**. Each scenario pins one branch the capability takes; the suite as a
11
+ whole covers every branch, and nothing that is not a branch.
12
+
13
+ ## What it requires
14
+
15
+ | Rule | What it means |
16
+ | --- | --- |
17
+ | **Acceptance only, strict** | A scenario tests a **decision** — a branch you can name. A statement with no nameable branch ("output is valid JSON", "idempotent") is an invariant: not specified here, covered by the implementation's own tests. Properties another capability co-owns are out of scope too. |
18
+ | **One scenario per (path class, edge)** | The `Given` is the path taken to a decision, the `When` is the decision under test, the `Then` is the branch taken. Paths that reconverge with the same outcome collapse into one scenario — that is what keeps the suite finite. An over-specific `Given` is a defect: it manufactures a false permutation. |
19
+ | **Every guard gets a positive companion** | A reject/kill/guard scenario is paired with a scenario driving the same path in its firing direction. A lone negative is inert — a do-nothing subject passes it. |
20
+ | **Scenario map, 1:1** | The spec's `## Scenario map` table and the suite bind one-to-one: every scenario has a row, every row names a real scenario, each row names both the edge and the path class. An unmapped scenario is an orphan; an unmapped edge is a coverage hole. |
21
+ | **Boolean Gherkin by default** | Every `Then` is an observable, deterministic boolean. The test is the **trace, not the verb**: name the artifact a verifier would read to settle it — an output, an exit code, a written file, a returned field. Asserting an *act* is fine when the act leaves a trace; if nothing records it, either add the record or do not assert it. Never assert how the artifact was authored, nor internal state. |
22
+ | **`@rubric` for graded judgment** | When a branch's correctness is a gradient no single boolean captures: named dimensions, a threshold, and a collapsing `Then` — still one boolean per scenario at the verification point. |
23
+ | **A `Given` is a test vector** | The implementation owes conformance to the `Then` only. A `Given`'s domain and framing are apparatus (the swap test tells them apart from the binding precondition), and neither side may absorb the other's examples. |
24
+ | **A `Given` is a scaffoldable state** | Declarative, observable, present-tense, one condition per step. The build test: could two people, given only this line, construct the same fixture? |
25
+ | **Pairwise consistency** | No two scenarios demand opposite verdicts on one constructible state. A narrower `Given` that carves an exception is specialization, not contradiction. |
26
+ | **Dead edges measure nothing** | The miss test: name a plausible wrong subject and check it takes the wrong branch. If none can, the edge is inert. |
27
+
28
+ Scenarios are grouped under section comments mirroring the spec's use-case groups, in the same
29
+ order, stepping down from the happy path to its branches and errors.
30
+
31
+ ## Two special markers
32
+
33
+ - **`@pinned`** — a **user-owned** seed scenario. Only the user applies it; the agent may propose a
34
+ change or removal but never executes one without in-session user authorization. A pin marks a
35
+ behavior the CFG did not reach, and the agent grows the CFG around it. It is the one
36
+ override to strict.
37
+ - **`@frozen`** — freeze is per `.feature` file. Adding a scenario folds in and self-clears; a pure
38
+ move preserves the freeze; a narrowing or rewrite unfreezes and fires Clearance at the gate.
39
+
40
+ ## The executable check — `check-suite`
41
+
42
+ The mechanical rules — Gherkin validity, boolean `Then`s, section comments, Outline coverage, and
43
+ the scenario-map binding — are linted by `check-suite` (`spec-gate/scripts/check-suite.mts`). The
44
+ spec-producer self-runs it before returning, and the spec gate runs it fail-closed before the cold
45
+ judge. It checks **form only**: whether the map's rows actually cover the drawn CFG — coverage,
46
+ discrimination, consistency — is judged, never linted, so a green check clears no coverage
47
+ question.
48
+
49
+ ## Usage
50
+
51
+ - **spec-producer:** self-aligns to this bar before writing the suite, and self-runs `check-suite`
52
+ before returning.
53
+ - **spec-judge** and the actor bars (**oracle** / **architect** / **builder**): judge their slices
54
+ of it backward at the **spec-gate**.
55
+ - **spec-gate:** runs `check-suite` fail-closed before spawning the cold judge.
56
+
57
+ ## Related governances
58
+
59
+ This bar owns how the **`.feature` suite** is written. Its neighbors own everything around that:
60
+
61
+ - **`spec-format-governance`** — how the `spec.md` is written: the use-case groups, the drawn
62
+ CFG, and the `## Scenario map` table this suite binds to. Spec-format owns the `spec.md`;
63
+ suite-format owns the `.feature` that mirrors it.
64
+ - **`lifecycle-governance`** — the freeze/unfreeze *model* and its risk trigger; this bar carries
65
+ only the `@frozen` marker's mechanics.
66
+ - **`ownership-governance`** — who may write a frozen `.feature` (no one), and the user's ownership
67
+ of `@pinned` scenarios.
68
+ - **The impl actor bars** (`builder-impl-governance`, `architect-impl-governance`) — the
69
+ **verification level**. This bar is deliberately **silent** on it, and that silence is the point:
70
+ what a suite specifies (acceptance) and how high a test runs to verify it (e2e down to unit) are
71
+ two independent axes. A suite that names a level has leaked the second axis into the first —
72
+ "boundary" is a level, not a category of scenario. The level is chosen per scenario by whoever
73
+ implements the test.
74
+
75
+ Internal SDD governance (`user-invocable: false`). Not triggered by users directly.
@@ -0,0 +1,299 @@
1
+ ---
2
+ name: suite-format-governance
3
+ description: "Partial Skill: invoke by name only"
4
+ user-invocable: false
5
+ ---
6
+
7
+ # Suite-Format Governance — the acceptance behavior-suite bar
8
+
9
+ Form authority for a behavior suite: how it is written and judged. Fixed-universal SDD
10
+ governance — the spec-producer self-aligns to it, and each actor bar (`oracle` / `architect` /
11
+ `builder`) judges its slice of it backward at the gates. Governs the suite of a **behavioral**
12
+ spec only; descriptive and reference nodes carry no suite. Every scenario collapses to **one
13
+ pass/fail** at the verification point — never a score.
14
+
15
+ ## The suite specifies acceptance only — strict
16
+
17
+ A suite specifies **acceptance** — the observable **decisions** the node owns — and nothing else.
18
+
19
+ - **Decisions only — and the map is the test.** A scenario tests a **decision** — a branch the
20
+ capability takes. The mechanical filter is **can you name the edge it sits on?** A scenario with no
21
+ nameable edge is a non-branch **invariant** ("output is valid JSON", "idempotent"): not acceptance,
22
+ not specified here, covered by the implementation's own tests.
23
+ Do **not** cut a scenario merely because it reads like a property. A constraint that holds across
24
+ every path *still sits on an edge* — "the envelope is the same for every strategy" is the
25
+ **convergence** shape at that edge (below), asserting the outcome does not vary, which is a design
26
+ decision. Unmappable is the cut; property-sounding is not.
27
+ - **The node's own decisions.** A property **co-owned** across a seam — activation/routing (does this
28
+ config fire?), a sibling's behavior, harness wiring — is not this node's to freeze; it is **out of
29
+ scope** (Oracle relocates or kills it).
30
+ - The only escape from strict is a user **pin** (below).
31
+
32
+ ## The suite is the capability's control-flow graph
33
+
34
+ The suite **is** the node's **control-flow graph (CFG)** at acceptance level. Author it as one:
35
+
36
+ - **One scenario = one (path class, edge) pair.** The `Given` is the **path** — the decisions already
37
+ made on the way here; the `When` is the **edge under test**; the `Then` is the **branch taken**. The
38
+ unit is not the edge alone: one edge needs several scenarios when its outcome differs by the path
39
+ reaching it.
40
+ - **State the least specific `Given` that determines the outcome.** Paths that **reconverge** and leave
41
+ no distinguishing state **collapse into one scenario** — `a→b→d` and `a→c→d` are the same scenario
42
+ when the outcome at `d` does not depend on whether `b` or `c` was taken. Name the reconvergence
43
+ point, never the route. This is what keeps the suite finite: without it, every upstream branch
44
+ multiplies every downstream one.
45
+ - **Add a permutation only when the outcome differs.** Same outcome under two prefixes ⇒ one scenario.
46
+ - **An over-specific `Given` is a defect.** Naming state the outcome does *not* depend on
47
+ **manufactures a false permutation** — it implies a sibling scenario for the other value and invites
48
+ exactly the explosion the collapse rule prevents.
49
+ - **Cover every branch.** A decision whose only covered edges are its "no" branches is incomplete: a
50
+ **kill / reject / guard edge is paired with a positive companion** driving the same path in its
51
+ firing direction. A lone negative is passed by a do-nothing subject (the sorted list that "stays
52
+ sorted" under `sort = identity`).
53
+ - **Each edge isolates a specific condition** — the `Given` sets up the exact state forcing *this*
54
+ branch and not its sibling, and hands over **no** part of the verdict. A scenario asserting a finding
55
+ asserts its **binding consequence** (withholds the pass, blocks the gate), never just its emission.
56
+
57
+ A **dead edge** — one no plausible wrong subject takes the wrong way — measures nothing: a missing
58
+ guard, an orphaned negative, or a `Given` that states its own answer. The **miss test** settles it:
59
+ *name a plausible wrong subject and check it takes the wrong branch; if none can, the edge is
60
+ inert.* Plausible, not strawman — a memorizer, a copier, a single-brancher, never an empty artifact.
61
+ Discrimination is **judged, not linted**; a **measured ceiling is a tell an edge cannot be lost**,
62
+ not evidence it works. Rubric-dimension discrimination detail: `references/rubric.md`.
63
+
64
+ **Backfilling from existing code — derive, don't patch.** When the implementation already exists,
65
+ draw the CFG from the code (`sdd:spec-format-governance` owns the `## Control Flow` + `## Scenario
66
+ map` sections) and **re-derive the whole scenario set from its edges** — one scenario per `(path
67
+ class, edge)` pair, every guard paired with a positive companion. Any pre-existing `.feature` or
68
+ legacy corpus (a retired golden set) is **reference only**: each entry is a **claim to verify against
69
+ the current code**, never the baseline to patch. Reading the standing suite and filling only the gaps
70
+ a diff notices is not this procedure — it leaves stale scenarios in place and misses edges the CFG
71
+ mandates (ADR-0029).
72
+
73
+ ## Sections mirror the spec's use-case groups; every scenario binds to a map edge
74
+
75
+ `spec.md` sections the node by **use-case group**, each carrying a drawn **CFG** and an
76
+ explicit **scenario-map** table (`sdd:spec-format-governance`). The suite **mirrors** it:
77
+
78
+ - Group scenarios under `# ── <use-case group> ──` comments — same groups, same order — screaming
79
+ the intents; never sectioned by layer, output format, or "misc rules".
80
+ - **The map is 1:1 scenario↔row**, and each row names **both** the edge and the path class
81
+ (`| Edge | Path (Given) | Scenario |`). A scenario off the map is an orphan; an edge with **no** row
82
+ is a coverage hole. An edge with **several** rows is **not** a duplicate — it is permutation
83
+ coverage, and legitimate exactly when each row's path class yields a different outcome. Two rows
84
+ with the same edge *and* the same path class **is** a duplicate. `check-suite` lints orphans,
85
+ uncovered edges, and same-edge-same-path duplicates.
86
+
87
+ **Three shapes sit on the map**, all of them acceptance:
88
+
89
+ - **branch** — the `Given` pins one path class; the `Then` names the branch taken.
90
+ - **convergence** — the `Given` deliberately **spans** classes ("for every strategy"); the `Then`
91
+ asserts the outcome **does not vary**. One scenario legitimately covers many permutations, and that
92
+ non-variance is a design decision, not an invariant.
93
+ - **barred** — the `Then` asserts an edge that must **not** exist (an option never offered).
94
+
95
+ ## The tag set — every tag a `.feature` may carry
96
+
97
+ This bar defines the tag **vocabulary** — what each tag *means*. It does **not** define how a judge
98
+ measures the tagged scenario: run counts, thresholds, corpora and pass bars are the resolved
99
+ plugin's (ACED, for agent-config domains). Tag = interface, plugin = implementation. A governance
100
+ that mentions a tag is a consumer. The rules live in the sections named below; this table is the index.
101
+
102
+ | Tag | Names | Scope | Applied by | Means |
103
+ | --- | --- | --- | --- | --- |
104
+ | `@trigger` | the engage decision | scenario | producer | Does the subject **engage** when it should, and stay out when it should not? |
105
+ | `@behavior` | conduct once engaged | scenario | producer | Having engaged, does it take the right steps and honor its rules? |
106
+ | `@quality` | the result | scenario | producer | Is what it produced good? |
107
+ | `@rubric` | the assertion form | scenario | producer | Graded against an inline rubric (named dimensions + threshold) rather than a boolean `Then` — see *Form 2*. Independent of the tags above; a scenario may carry both. |
108
+ | `@pinned` | ownership | scenario | **user only** | A user-owned seed scenario the agent may propose against but never change unilaterally — see *`@pinned`*. |
109
+ | `@frozen` | lifecycle state | **file** | the gate | The suite is the agreed contract; narrowing it needs Clearance — see *The `@frozen` marker*. |
110
+
111
+ **`@trigger` vs `@behavior` is a per-node question, judged — never linted.** `@trigger` is legal
112
+ only *where the node genuinely owns the routing decision*, and two different deciders qualify:
113
+
114
+ - the **harness** — a model matching this config's `description` against a user query. Here the
115
+ decision is **co-owned** (description prose × harness × sibling set) and the node holds one of the
116
+ three, so freezing it on the node is the seam issue #304 raises.
117
+ - **an agent applying the node's own doctrine** — e.g. a coordinator reading this doctrine to decide
118
+ whether it governs the situation at hand. No harness is in the loop and the deciding input is the
119
+ node's own content, so **the node owns it outright**.
120
+
121
+ The two look alike in shape and differ only in who decides, so **step form does not classify them**
122
+ and no mechanical check should try (see `.agents/specs/sdd/ssa-lowering/ssa-lowering.feature`, where
123
+ a deletion that read the second case as the first was blocked at the gate and reverted). A
124
+ deterministic, fully-owned decision table that selects *what an already-invoked subject does* is
125
+ conduct, not engagement — it wants `@behavior`.
126
+
127
+ **`@frozen` is the only file-level tag** — it sits on the `Feature`, not a scenario.
128
+
129
+ `check-suite` ignores tags it does not recognize, so an unknown tag fails silently rather than
130
+ loudly — spell them exactly as written above.
131
+
132
+ ## `@pinned` — user-owned seed scenarios
133
+
134
+ A **user** may mark a scenario `@pinned`. It is **user-owned** (`sdd:ownership-governance`) — the one
135
+ scenario class the agent does not own:
136
+
137
+ - **Agent proposes, user disposes.** The agent may propose changing or removing a `@pinned` scenario;
138
+ it may **not execute** the change without in-session user authorization — the authority of a human
139
+ ratification (positional, not relayable, not self-assertable within leash). Ownership is
140
+ lifecycle-independent: the pin holds in `draft` and survives a re-open; freeze does not enter.
141
+ - **Only the user pins.** The agent never applies `@pinned`.
142
+ - **A pin is a seed.** It marks a behavior the CFG did not reach; the agent **grows the
143
+ CFG around it** — proposing the sibling branches, guards, and companions the pinned behavior
144
+ implies (agent-owned; only the seed stays pinned).
145
+ - It is the **override to strict** — kept whatever strict would prune.
146
+
147
+ ## One behavior per scenario — SRP and dedup
148
+
149
+ One (path class, edge) per scenario; one canonical scenario per pair. A scenario with several unrelated `Then`s
150
+ churns and its name lies — split it. Two scenarios sharing a `When`+`Then` core are a duplicate —
151
+ dedup to the canonical (never dedup away a `@pinned` scenario without consent).
152
+
153
+ ## Form 1 — pure-boolean Gherkin (default)
154
+
155
+ `Given / When / Then` whose every `Then` is an **observable, deterministic boolean**. Use whenever the
156
+ branch is directly checkable.
157
+
158
+ **The test is the trace, not the verb.** A `Then` is legal when you can name the artifact a verifier
159
+ reads to settle it — an output, an exit code, a written file, an emitted event, a returned field.
160
+ Asserting an *act* is not the defect; asserting an act that records nothing is. Follow these:
161
+
162
+ - **Name the artifact before writing the `Then`. If nothing records it, do not assert it.**
163
+ - **Assert an act only when the act leaves a trace.** `Then it reads the role-to-agent map from the
164
+ registry` is legal — the resolved squad is checkable against the registry. `Then it sweeps the
165
+ corpus` is not: no artifact records a sweep.
166
+ - **When an act matters but records nothing, add the record — do not delete the act.** Give the role
167
+ an `Output` field, a written report, or a ledger line, then assert *that*.
168
+ - **Never assert how the artifact came to be authored** — "co-developed", "written test-first",
169
+ "authored in this order". Nothing in the artifact or a run reveals authoring sequence. Assert the
170
+ end state instead, and keep production discipline in governance prose.
171
+ - **Never assert internal state or a function name.** Neither is readable at the verification point.
172
+
173
+ ## Form 2 — rubric Gherkin (`@rubric`, judged by hand)
174
+
175
+ For a branch whose correctness is a **gradient judgment** across dimensions no single boolean
176
+ captures. Structure: a rubric block with named dimensions, per-dimension `max`, exactly one
177
+ `threshold`, a collapsing `Then`, **no double-barreled dimension**. Selection (is a dimension
178
+ substitutable), threshold policy, and cSEM: load `references/rubric.md` before authoring or judging
179
+ one. Collapses to one boolean per scenario at the verification point, like every other scenario.
180
+
181
+ ## A `Given` is a test vector, not specification
182
+
183
+ The implementation owes conformance to the `Then`, nothing to the `Given`'s apparatus. A `Given`
184
+ carries a **precondition** (the state the `Then` is asserted under — contract, the impl handles it)
185
+ and **apparatus** (domain, names, framing — a test vector, binds nothing). **Swap test:** substitute
186
+ the domain for an unrelated one; if the `Then` still holds, what was swapped is apparatus. **No
187
+ absorption** — no producer lifts a `Given`'s apparatus into the artifact as a worked example, and no
188
+ artifact illustration is lifted into a `Given`; each draws from a domain the other does not probe.
189
+ Judged semantically, not lexically.
190
+
191
+ ### A `Given` must be a **scaffoldable state**
192
+
193
+ The `Given` is what the impl-producer **builds** and the impl-judge **checks it built**. If the two
194
+ can read it and picture different fixtures, the gate churns — the producer writes a defensive step
195
+ carrying flags and branches, and the judge disagrees about what was even set up. A step definition
196
+ that needs conditionals is the tell that the step is wrong **upstream**, not that the automation is
197
+ hard.
198
+
199
+ - **A state, not a procedure.** Declarative: *what holds*, never the keystrokes that got there.
200
+ - **Observable, not evaluative.** Bar judgment words — *discernible, valid, appropriate, clear,
201
+ proper, reasonable*. They read as precision and carry none: each reader supplies their own
202
+ threshold. Name the fact instead.
203
+ - **Present, not absent.** A state defined by what is *missing* ("no X and no Y") is unbuildable —
204
+ absence has infinitely many fixtures. Name the concrete shape that *has* the property.
205
+ - **One condition per step.** Split a conjunction into `Given` + `And`. Each step then stands alone
206
+ and is reusable across scenarios, which is what makes a step library accumulate instead of
207
+ fragment.
208
+ - **The build test:** *could two people, given only this line, construct the same fixture?* If no, it
209
+ is not yet a `Given`.
210
+
211
+ **Worked correction.** `Given a project with no discernible capability decomposition and no
212
+ feature-first source layout` fails three ways at once — *discernible* is evaluative, the state is
213
+ doubly absent, and it is a conjunction. It becomes:
214
+
215
+ ```gherkin
216
+ Given a project in detection mode
217
+ And its src/ is organized by layer rather than by feature
218
+ ```
219
+
220
+ Two buildable steps, no judgment words, and the path class is named outright.
221
+
222
+ ## Pairwise consistency — no two scenarios contradict on one snapshot
223
+
224
+ Within one suite, no two scenarios may demand **opposite verdicts** on a single constructible state.
225
+ A contradiction needs a shared `When` **and** an overlapping `Given`; different `When`s over one
226
+ state do not contradict. **Specialization is not contradiction** — a specific scenario whose narrower
227
+ `Given` carves an exception wins on it; read a pair as generic/specific before reading it as a
228
+ conflict. The remedy is a `Given` narrowing. Judged, not linted; the `Conflict` hard floor is the
229
+ post-freeze backstop.
230
+
231
+ ## Optional conventions — scenario tagging and enumerated cases
232
+
233
+ Additive and plugin-facing (e.g. ACED); untagged plain suites are unaffected and the structural
234
+ check ignores unrecognized tags.
235
+
236
+ - **`@trigger`, `@behavior` and `@quality`** are defined in *The tag set* above. There is no
237
+ collective noun for them and none is wanted: they are three separate tags, not a stack or a
238
+ pipeline, and naming them as a group invites generalizations that do not hold. Apply `@trigger`
239
+ only where the node genuinely owns the routing decision, and read that section's two-deciders test
240
+ before choosing between `@trigger` and `@behavior` — the classification is judged per node, never
241
+ linted.
242
+ - **`Scenario Outline` is a rare exception, not a default** (DAMP over DRY) — legitimate only for a
243
+ genuinely uniform enumerated set (one varying token, every row the same `Then` shape). Two rows
244
+ wanting different `Then`s are two scenarios, not one Outline. Requires a non-empty `Examples:` table
245
+ covering every `<placeholder>`.
246
+
247
+ ## The `@frozen` marker
248
+
249
+ Freeze is **per `.feature` file** (a feature-level `@frozen` tag; metadata, excluded from the
250
+ protected content). An **additive** scenario folds in and **self-clears**; a **pure move/rename**
251
+ (`git mv`, zero content delta) **preserves** the freeze; a **narrowing or rewrite** unfreezes and
252
+ fires **Clearance** at the gate. Vocabulary is **freeze / unfreeze**. The model and its risk trigger
253
+ are `sdd:lifecycle-governance`; the write constraint is `sdd:ownership-governance`.
254
+
255
+ ## Scenario ordering (step-down)
256
+
257
+ Trace the workflow top-to-bottom: each use-case group in sequence; within a group, the happy path
258
+ first, then its branches and errors; a `@rubric` scenario sorts into its group like any other.
259
+
260
+ ## The executable form — `check-suite`
261
+
262
+ The mechanical rules — Gherkin validity, every untagged `Then` a boolean, no leaked rubric lingo,
263
+ `Scenario Outline` Examples coverage, `# ── ── ` section comments, and **scenario-map binding** —
264
+ every scenario carries a map row, every row names a real scenario, and no two rows share an edge
265
+ *and* a path class. Whether the rows **cover the CFG** is judged, not linted: that needs the drawn
266
+ CFG's semantics, so a green check clears no coverage question. A spec with no `## Scenario map`
267
+ section is skipped, not failed — run as `check-suite`
268
+ (`spec-gate/scripts/check-suite.mts`): the spec-producer self-runs it before returning, and the spec
269
+ gate runs it fail-closed before the cold judge.
270
+
271
+ **Form only** — coverage adequacy, discrimination,
272
+ selection, pairwise consistency, and apparatus independence are **judged**, never linted, and a green
273
+ `check-suite` clears none of them.
274
+
275
+ ## Key points (read-check)
276
+
277
+ The load-bearing directives below are the ones whose misreading is expensive — read them as the
278
+ compressed form of this bar, not as a summary that replaces it:
279
+
280
+ 1. **Acceptance only, strict** — a suite specifies the decisions the node owns; invariants and
281
+ co-owned seams are out of scope.
282
+ 2. **The suite is the CFG** — one scenario per **(path class, edge)** pair, cover every
283
+ branch, collapse reconverged paths whose outcome does not differ, and pair every guard/negative
284
+ edge with a positive companion on the same path (a lone negative is inert).
285
+ 3. **Each edge isolates a specific condition** — the `Given` hands over no part of the verdict, and a
286
+ scenario asserting a finding asserts its binding consequence, not just its emission.
287
+ 4. **A dead edge measures nothing** — run the miss test (a plausible wrong subject takes the wrong
288
+ branch); a measured ceiling is a tell it cannot be lost, not evidence.
289
+ 5. **The scenario map is 1:1 scenario<->row**, each row naming both the **edge** and the **path
290
+ class**; an edge may carry several rows (permutation coverage) — a duplicate is same edge *and*
291
+ same path. Sections mirror the spec's use-case groups.
292
+ 6. **`@pinned` is user-owned** — the agent proposes but never executes a change or removal without
293
+ user authorization; only the user pins; a pin seeds CFG growth.
294
+ 7. **A `Given` is a test vector** — the precondition binds, the apparatus binds nothing (swap test);
295
+ no absorption.
296
+ 8. **A `Then` is legal when you can name the artifact that settles it** — the test is the **trace,
297
+ not the verb**. Asserting an *act* is fine when the act leaves a trace; where it records nothing,
298
+ **add the record and assert that**, rather than dropping the act. Never assert how the artifact
299
+ was authored, nor internal state.