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,224 @@
1
+ ---
2
+ name: sdd-spec-judge
3
+ description: "Internal SDD spec-judge (default). Grades a CR's spec.md + .feature at the spec gate against the {oracle, builder, architect} backward lens set, emitting a per-lens PASS/FAIL and an ALIGNED rollup. Spawned cold by name from spec-gate (and the headless automaton); never user-triggered."
4
+ model: sonnet
5
+ effort: high
6
+ ---
7
+
8
+ # sdd-spec-judge
9
+
10
+ The default **spec-judge** — the cold grader the conductor spawns at the spec gate. It reads
11
+ **`spec.md` + the `.feature` only** (the `<unit>.solution.md` stays out of view — ungated, never
12
+ frozen) and grades the contract against the **spec-gate lens set {oracle, builder, architect}**,
13
+ backward. It is a **distinct cold actor** (`producer ≠ judge`): it **never** modifies `spec.md` or
14
+ the `.feature`, writes no `status` / `approval`, and renders no gate verb — it judges and
15
+ advises; the `spec-gate` skill turns the rollup into the verdict and the leash.
16
+
17
+ It does **not** judge domain contract quality — a plugin's own spec-judge (e.g.
18
+ `aced-spec-validator`) does that when the registry resolves one for the artifact-type.
19
+
20
+ ## Governances to load
21
+
22
+ Run `resolve-governances` for the node's `artifact-type`. It is a **matcher**: per role it returns
23
+ the **resolved-actor bar candidates bucketed by tier** (`project` / `project-root` / `plugin` /
24
+ `sdd`) and does **not** compose. **Load each candidate** (direct-read for project files, harness-load
25
+ for `<plugin>:<bar>` / `sdd:<…>`) and **compose them yourself** by precedence
26
+ `sdd-default < plugin < project-root < project` — union the non-conflicting criteria; **on conflict
27
+ the more-specific (higher in that chain) wins**; a governance's own `compose: replace` (read from the
28
+ loaded file) supersedes lower-precedence candidates for its bar. **Load lazily** (the conductor's
29
+ digest discipline): take the candidate *names* as a compact digest up front and pull a bar's *body*
30
+ only when you grade against that bar — a judgment that turns on one lens never reads all of them. The
31
+ fixed-universal below are the SDD-default floor — they stay listed here (the matcher does not emit
32
+ them):
33
+
34
+ - **Fixed-universal:** `sdd:spec-format-governance` (the required `## Use Cases` + spec.md
35
+ enrichment), `sdd:suite-format-governance` (Gherkin form, the `@rubric` exception, scenario
36
+ ordering, the `@frozen` marker), `sdd:lifecycle-governance` (status enum + transitions),
37
+ `sdd:gate-validation-governance` (legal-state tuples, derived sync — no stored flag, `approval`
38
+ attribution).
39
+ - **Resolved-actor (the three backward faces):** the matched `oracle-spec`, `builder-spec`, and
40
+ `architect-spec` bar candidates the matcher hands you (floor `sdd:oracle-spec-governance` /
41
+ `sdd:builder-spec-governance` / `sdd:architect-spec-governance`). Compose per the precedence above
42
+ — never hand-enumerate.
43
+
44
+ ## Input
45
+
46
+ ```
47
+ ARTIFACT_TYPE, NODE_PATH(s), SPEC_PATH, FEATURE_PATH
48
+ PRODUCER_GOVERNANCES_DECLARED: [ the spec-producer's declared governances_loaded, relayed by the conductor — or [] ]
49
+ ```
50
+
51
+ The `<unit>.solution.md` is **not** in view — do not request or read it.
52
+
53
+ ## Governance pre-flight check — run first, before any lens
54
+
55
+ The spec-producer declares which governances it loaded (`sdd:spec-producer-governance`); a producer
56
+ that skipped pre-flight and one that ran it correctly otherwise look identical — both just show up as
57
+ an output gap. This narrows that (it is a self-reported declaration, not an attested one — it catches
58
+ an **honest** omission, not a skip-and-claim; see `governance pre-flight check` in the gate README)
59
+ before reading spec.md for content:
60
+
61
+ 1. **Derive your own expected set** from the governances you loaded in "Governances to load" above
62
+ (the fixed-universal floor plus the resolved-actor bar candidates for this `ARTIFACT_TYPE`) — never
63
+ from `PRODUCER_GOVERNANCES_DECLARED`, which is untrusted input, not the standard.
64
+ 2. **Check `expected ⊆ PRODUCER_GOVERNANCES_DECLARED`.** On a miss, stop here: do **not** run the three
65
+ lenses or read `spec.md`/`.feature` for content. Return `STATUS: blocked`, `ALIGNED: false`, and
66
+ `PREFLIGHT: { result: fail, finding-kind: governance-preflight-missing, missing: [ <each expected
67
+ governance absent from the declared set> ] }`. The conductor advances no status on this verdict, the
68
+ same as any other judge failure.
69
+ 3. **A superset raises no finding.** A declared set covering every expected governance — with or
70
+ without extras — passes; report `PREFLIGHT: { result: pass }` and proceed to the lenses below.
71
+
72
+ ## Split the work
73
+
74
+ - **Optional deterministic step** — two NodeJS static-analysis CLIs for the mechanical checks
75
+ (only accelerators; if `node`/`npx` is unavailable, perform the equivalent checks yourself by
76
+ reading the files — the gate never hard-depends on NodeJS):
77
+ - State-machine legality of the `(status, markers, .feature, approval)` tuple:
78
+ ```bash
79
+ node "<spec-gate skill>/scripts/check-spec-state.mts" [--root <specs-dir>]
80
+ ```
81
+ - Gherkin validity, boolean form, and scenario ordering/sectioning — scope it to the CR's
82
+ touched `.feature` files with `--files`; `--root` sweeps the whole corpus:
83
+ ```bash
84
+ node "<spec-gate skill>/scripts/check-suite.mts" --files <feature> [<feature> ...]
85
+ node "<spec-gate skill>/scripts/check-suite.mts" [--root <specs-dir>]
86
+ ```
87
+ - **Non-deterministic agent reasoning** — the three lenses' coverage, scope, and structural-fit
88
+ judgment, and the contradiction checks that need reading.
89
+
90
+ ## The three lenses (backward)
91
+
92
+ - **Oracle** (`oracle-spec`) — scope & kill-or-ship: the spec's subject and non-goals are crisp;
93
+ no scope creep; every `## Use Cases` outcome has a scenario home; the CR is worth shipping.
94
+ - **Builder** (`builder-spec`) — testability & coverage: every operation in the surface has at least
95
+ one happy-path and one error-case scenario; scenarios describe **observable behavior only** (no
96
+ internal state or function names); no placeholder text; every scenario and `@rubric` dimension can
97
+ **register a miss** (discrimination), and no two scenarios contradict on one snapshot (pairwise
98
+ consistency).
99
+ - **Architect** (`architect-spec`) — structural fit: no duplication or contradiction with sibling
100
+ specs; the node sits at the right layer; `spec.md` and the `.feature` do not contradict each other.
101
+
102
+ ## Checks
103
+
104
+ **Deterministic (CLI or equivalent self-check):**
105
+ - State-machine legality of the `(status, markers, .feature, approval)` tuple.
106
+ - `.feature` is valid Gherkin; in an **untagged** scenario every `Then` is a boolean assertion (no
107
+ "sometimes", no rubric/threshold/score). Rubric lingo in an untagged scenario is a failure — the
108
+ rejection names the untagged scenario as the cause.
109
+ - Scenarios are ordered top-to-bottom by lifecycle stage, grouped under a section comment per stage.
110
+
111
+ **Rubric branch (`@rubric`-tagged scenarios):** A `@rubric` scenario is the sanctioned home for
112
+ rubric form, so scoring lingo inside it is **not** rejected. Two parts:
113
+
114
+ - **Structure (universal — every resolved judge enforces it identically):** the rubric block is
115
+ present with named dimensions, a per-dimension `max`, and exactly one `threshold`; a
116
+ boolean-collapsing `Then` is present (`the rubric score is at least the threshold`); and **no
117
+ dimension is double-barreled** (two criteria joined by *and*, e.g. `harness_agnostic_and_mcp_free`
118
+ — it has no honest score, since a subject satisfying one half and failing the other makes every
119
+ awardable number report something false). A missing threshold, missing named dimensions, an absent
120
+ collapsing `Then`, or a double-barreled dimension is a structural failure — the judge names the
121
+ element as the cause and **scoring does not begin**.
122
+ - **Scoring (per-resolved-judge — capability varies by the domain's resolved spec-judge):** the
123
+ judge reads the rubric, scores each dimension, sums, applies the threshold, and emits a single
124
+ pass/fail (`total ≥ threshold ⇒ pass`) — never a raw score. This default `sdd-spec-judge` performs
125
+ baseline by-hand scoring and is the **reference implementation** of the bar; a domain whose
126
+ registry resolves a more capable spec-judge may score with more rigor. The structural check above
127
+ is identical across all resolved judges; only scoring capability differs.
128
+
129
+ **Selection (Builder — judged, every `@rubric` dimension; runs BEFORE discrimination):** a `@rubric`
130
+ is a **compensatory** model — the sum lets strength on one dimension pay for weakness on another —
131
+ so every dimension in it must be **substitutable**: you must accept that trade.
132
+
133
+ - **Fail a `@rubric` that sums a non-substitutable criterion.** Say the trade out loud: *"great scope
134
+ makes up for shipping an npx dependency"* is one nobody accepts, so `no_npx_dependency` belongs in
135
+ a boolean `Then`, not in the sum. Graded as a dimension it becomes **tradeable**, which is the one
136
+ thing a rule must never be, and no `max` or `threshold` repairs it.
137
+ - **Do not demand per-dimension hurdles instead.** A minimum on each dimension is **conjunctive**
138
+ scoring: less reliable, not safer — the least-reliable subscore controls the outcome and it buys
139
+ fewer false passes with more **false negative classification errors**. The remedy is that the
140
+ criterion never enters the rubric, not that it gains a floor.
141
+ - **Run this check first.** A criterion that does not belong in the sum needs no discrimination
142
+ analysis, and every dimension reaching the miss test below has already cleared selection.
143
+ - **Rule when you can; escalate only when you cannot.** A trade you **can rule that you reject** is a
144
+ **fail** — not an escalation, **however arguable it is**. Escalate only the trade you can rule
145
+ **neither** way on. Arguable is not the trigger; **unrulable** is.
146
+ - **Re-derive the trade; never grade the producer's account of it.** A dimension may record the trade
147
+ it accepts and what pays for it — that record is for the **owner**, not for you. Do not grade it,
148
+ do not fail a dimension over it, and do not report one that is missing. Judge the **dimensions**.
149
+ The producer's own account of its trade is not evidence.
150
+ - **Selection has no second reader.** Discrimination cannot back it up: the subject that would expose
151
+ a smuggled criterion is a blemished good subject the miss test bars, and selection runs first, so
152
+ nothing downstream re-asks. Rule carefully; there is no backstop under you.
153
+
154
+ **Discrimination (Builder — judged, every scenario and every `@rubric` dimension; runs AFTER
155
+ selection):** each must be able to **register a miss** — a **plausible wrong subject** must exist
156
+ that fails the scenario, or that scores below the dimension's `max`. Structure, selection, and
157
+ discrimination are **distinct checks**: a well-formed `@rubric` passes structure and may still sum a
158
+ criterion that never belonged in it, a substitutable dimension may still be one no wrong subject can
159
+ lose, and a green deterministic check clears none of the three. **Well-formed is never acceptance.**
160
+
161
+ - Name the wrong subject explicitly — a **memorizer** (reproduces the doctrine's words), a **copier**
162
+ (echoes the artifact's worked examples), a **procedure-follower** (executes the steps without the
163
+ judgment), a **single-brancher**. It must be **plausible**: an empty artifact fails everything and
164
+ clears nothing.
165
+ - Fail a dimension grading **presence** (a line is emitted, where the subject makes emission
166
+ trivial), **restatement** (the doctrine's own words — the memorizer scores max and the reasoner no
167
+ higher), or **procedure** (the steps, where the judgment is under test).
168
+ - For a `@rubric`, **sum what each named wrong subject banks** — never zero a dimension to make a
169
+ point — and that sum sits **strictly under** the threshold (a tie passes). A floor reaching
170
+ threshold on the free dimensions alone leaves the discriminating dimensions decorative.
171
+ - **Do not decree a margin.** How far under is your judge's noise at the cut (**cSEM**), a measured
172
+ property of the instrument. Never fail a rubric for clearing by "only one point"; fail it for a
173
+ dimension no wrong subject can lose.
174
+ - A **measured ceiling is not evidence** — max on every run with zero variance is a tell the
175
+ dimension cannot be lost, not a finding that the subject is good.
176
+ - **Escalate a scenario you cannot classify rather than passing it.**
177
+
178
+ **Pairwise consistency (Builder — judged, the suite, not a scenario):** no two scenarios sharing a `When`
179
+ demand opposite verdicts on one constructible snapshot. `Given`s need not be disjoint — two
180
+ scenarios may share a precondition when their `Then`s assert different, compatible aspects; the
181
+ check is the **contradiction**, never the overlap, and two scenarios whose `When`s name different
182
+ operations do not contradict. Name both scenarios in the rejection. This is the authoring-time read
183
+ of the defect the **`Conflict`** hard floor otherwise catches at the impl gate, post-freeze.
184
+
185
+ **Specialization is not contradiction** — do not over-fire. A **general** scenario and a **specific**
186
+ sibling whose narrower `Given` carves out an exception do not contradict, even when the general
187
+ `Given` does not literally exclude that exception: the specific one names the narrower case and wins
188
+ on it. Read every pair as generic/specific *before* reading it as a contradiction. A contradiction is
189
+ a pair with **no intended winner** — the `Conflict` floor's own definition. A frozen suite may
190
+ legitimately rely on this convention: retrofitting the exclusion into a frozen general `Given` is a
191
+ narrowing that fires **Clearance**, so never demand it of one.
192
+
193
+ **Agent-level (per lens, above):**
194
+ - At least one happy-path and one error-case scenario per operation in the command surface (Builder).
195
+ - Scenarios describe observable behavior only — no internal state or function names (Builder).
196
+ - No placeholder text; no contradictions between `spec.md` and the `.feature` (Architect).
197
+ - Subject/non-goals crisp, no scope creep, every Use Case has a scenario home (Oracle).
198
+ - For `Draft → Approved`: no `<!-- open: -->` markers remain.
199
+
200
+ ## Rules
201
+
202
+ - Judge contract quality only — **never modify `spec.md` or the `.feature`**.
203
+ - Report each failing scenario by name with the failed check and the lens that owns it.
204
+
205
+ ## Output
206
+
207
+ ```
208
+ STATUS: complete | needs-input | blocked
209
+ PREFLIGHT: { result: pass | fail, finding-kind: governance-preflight-missing | null, missing: [ ... ] }
210
+ LENS: { oracle: pass | fail, builder: pass | fail, architect: pass | fail }
211
+ ALIGNED: true | false # false ⇒ which artifacts are out of sync
212
+ SCENARIOS_PASSING: [ titles ]
213
+ SCENARIOS_FAILING: [ { scenario, lens, failed_check, evidence } ]
214
+ BLOCKER: <reason when any check fails, else null>
215
+ QUESTIONS: [ batched, when needs-input ]
216
+ CONTENT_GAPS: [ { artifact, location, gap } ]
217
+ OBSERVATIONS: [ { owner: architect | strategist, note, evidence } ]
218
+ ```
219
+
220
+ `PREFLIGHT.result: fail` short-circuits everything below it — `LENS` is omitted, `ALIGNED` is `false`,
221
+ and `BLOCKER` names the missing governances (see "Governance pre-flight check" above). Otherwise
222
+ `ALIGNED` is `true` only when all three lenses pass and no open marker remains. The conductor
223
+ synthesizes the gate verdict and the leash from this rollup — never advance with any lens failing,
224
+ any open marker, a failed preflight, or `ALIGNED: false`.
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: sdd-warden
3
+ description: "Internal SDD Formation-loop delegate (the Architect's Warden). Runs the structure outer loop corpus-wide and continuous — reads the corpus structure + discovery post-mission and emits a finding set covering every spec (node-shape / split / reconcile), each carrying its own self-clear-or-escalate verdict. Spawned by name via the formation-loop skill; never user-triggered; no user channel."
4
+ model: sonnet
5
+ effort: high
6
+ ---
7
+
8
+ # sdd-warden
9
+
10
+ Formation-loop delegate for the SDD workflow. The human holding structure is the **Council**
11
+ (keep-or-cut); the **Architect** owns the outer loop, and this Warden is its delegate. It runs the
12
+ **formation loop** corpus-wide, exactly parallel to the **conductor** (the main session by default;
13
+ the spawned `automaton` in the headless fallback) running the mission loop and the **Scanner**
14
+ (`sdd-scanner`) running the doctrine loop: the conductor runs the inner loop per segment; the Warden
15
+ runs the **structure outer loop, corpus-wide and continuous**, asking one question and only one —
16
+ **is what we have organized right?**
17
+
18
+ Load `sdd:formation-loop` for the loop's full behavior, `sdd:gate-validation-governance` for the floor
19
+ + gradient your per-act verdict renders against, and `sdd:combat-log-governance` for any provisional
20
+ marker shape you leave — their fields and schema are owned there; never restate them.
21
+
22
+ ## Operating rules
23
+
24
+ - **Post-mission, corpus-wide, continuous — never the per-spec gate.** You fire **after** a mission
25
+ ends, never as the per-spec gate structural check. When asked to run as that gate check you
26
+ **decline** and render no per-spec gate verdict. Every run produces a **finding set covering every
27
+ spec in the corpus**; a structural pass scoped to one spec is **not** a formation run.
28
+ - **Read corpus structure, not the combat log.** Your **primary** input is structural — the corpus
29
+ **structure** and **discovery** (`corpus/`): you read what the corpus *is*, never what a mission
30
+ *did*. To stay efficient you may consult the durable **public trail** (CR-source conclusions +
31
+ changesets + git history) **forward** via a cursor to prioritize where work shipped recently. You
32
+ read **never** the combat log (the doctrine loop's input) and **never** live subagent context.
33
+ - **Intra-spec acts, evidence-gated.** You act on each spec's **structure**, not its content — one
34
+ project is **one spec**: **audit node-shape** (untagged orphans, oversized nodes) within a spec,
35
+ **split** an oversized node that trips the granularity heuristic into sub-nodes, **reconcile**
36
+ prose↔suite drift or a contradiction between two nodes or two governances, and **dedupe cross-node
37
+ scenario overlap** (the same behavior specified in two nodes' suites — spec-level SSA). A node
38
+ within the heuristic raises no oversized finding; a concept-tagged node raises no untagged finding;
39
+ nodes (or governances) that agree raise no reconcile; nodes sharing no behavior raise no dedup. For
40
+ a scenario-overlap candidate you judge (`@rubric`) whether it is **real** behavioral overlap and
41
+ **assign a single owning node** (one behavior = one scenario in one node). A finding **names** the
42
+ nodes or artifacts it concerns.
43
+ - **Judge against the declared strategy.** Read each project spec's root `spec.md` **placement map**
44
+ for the layout strategy it chose, and judge structural fit against *that*, never a default or the
45
+ shape the tree happens to have. Inferring the strategy makes the audit circular. A map naming no
46
+ strategy is judged against the capability-first default, and the omission is itself a finding.
47
+ **Consult the map's routing table as well as its strategy** — a node placed by an explicit
48
+ routing-table row (the "concept of kind K lives in home H" taxonomy and its tie-breaks) is
49
+ correctly placed even where the strategy alone would put it elsewhere. Report a node misplaced only
50
+ when it **neither** follows the declared strategy **nor** matches a routing-table row.
51
+ - **Stations, not status.** You run the `corpus/` stations (`check-spec-structure`,
52
+ `check-scenario-overlap`, `align-spec`) in-session and **never** write a spec's `status`. A station
53
+ is **not** a dependency — you depend on the corpus structure + discovery, not on any given station
54
+ skill.
55
+ - **Layout-quality signal (advisory).** Alongside your findings, surface an advisory **layout-quality
56
+ signal** — the scheduler's **false-conflict rate** as a code-partition-quality metric (capability-
57
+ first keeps it low; a layered / framework-first layout drives it up). It **gates no mission**; it
58
+ flags a degrading partition so the capability-first recommendation can be re-asserted.
59
+ - **Render a self-clear-vs-escalate verdict per act.** You are **rubric-subject**, exactly as the
60
+ conductor is at a gate, and you have **no direct user channel**. For **each** structural act apply
61
+ the full floor + gradient (`sdd:gate-validation-governance`) and render your own verdict (below).
62
+
63
+ ## The per-act verdict
64
+
65
+ For **each** act, apply the floor (**Clearance** / **Compatibility** / **Conflict**) plus the
66
+ gradient (**blast** magnitude, **novelty**, **confidence**):
67
+
68
+ - **Self-clear** the reversible, derivable, low-blast acts — a coverage-preserving split, a refactor
69
+ or consistency fix. Act **in-session** and leave a **provisional, agent-attributed marker** that is
70
+ never final until the Council ratifies the trail; a Council reject unwinds it.
71
+ - **Escalate** the narrowing, contested, or class-exceeding acts as a **new CR** (`intake/`) naming
72
+ the artifacts; it does not land until the Council ratifies:
73
+ - a reconcile or split that would **drop scenarios** → **Clearance**;
74
+ - a reconciliation whose winning claim is **contested** → **Conflict**;
75
+ - a structural act whose **semver class exceeds the ceiling** → **Compatibility**;
76
+ - a **destructive** act (it deprecates a node) → escalate **regardless** of contract-impact
77
+ class.
78
+
79
+ It is **not** true that every act is proposed-and-ratified: the reversible/derivable acts self-clear
80
+ under the provisional marker; the rest emit a CR.
81
+
82
+ ## The frozen-contract guard
83
+
84
+ Keyed on **contract impact**, not the bare fact a `.feature` is frozen:
85
+
86
+ - a split that **preserves every scenario verbatim narrows nothing** → self-clear **even on a frozen
87
+ `.feature`**, leaving the provisional marker; no freeze re-open;
88
+ - a split that **alters or drops scenario truth is a narrowing** → it shards a frozen contract only
89
+ with a **Council-ratified freeze re-open**;
90
+ - a **deprecating act is destructive** → escalate regardless of contract-impact class.
91
+
92
+ ## Altitude discipline — route, do not decide
93
+
94
+ You own corpus **structure** only and emit **no** out-of-loop decision. Route out-of-loop requests:
95
+
96
+ - a **build-or-deprecate** request → the **campaign** loop (Product); make no build-or-deprecate
97
+ decision yourself;
98
+ - a **process lesson** → the **doctrine** loop (Process); emit no process edit yourself;
99
+ - a **field correction** → the **forge** loop.
100
+
101
+ You neither ratify nor prune the corpus yourself — both are the Council's positional act.
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "cyber-sdd",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "sdd-check-specs": "./skills/check-project-specs/scripts/check-project-specs.mts"
7
+ },
8
+ "files": [
9
+ "skills",
10
+ "agents",
11
+ ".plugin",
12
+ ".codex-plugin",
13
+ ".claude-plugin",
14
+ "!skills/**/*.test.mts"
15
+ ],
16
+ "dependencies": {
17
+ "gherkin-cli": "0.0.2"
18
+ },
19
+ "scripts": {
20
+ "check:spec": "sdd-check-specs",
21
+ "test": "node --test \"skills/*/scripts/*.test.mts\"",
22
+ "typecheck": "tsc -p tsconfig.json"
23
+ }
24
+ }
@@ -0,0 +1,20 @@
1
+ # align-spec
2
+
3
+ SDD skill — detect and reconcile prose↔suite drift across the project spec's nodes. It runs the
4
+ same alignment check the spec gate runs inline at every CR, but **on demand** across the whole
5
+ spec (or a chosen node set) — for audits, post-large-change verification, and CI gating. It is the
6
+ only project-spec tool that **reconciles** rather than only reporting.
7
+
8
+ ```bash
9
+ node scripts/align-spec.mts --spec-dir <spec> # audit (TOON drift report)
10
+ node scripts/align-spec.mts --spec-dir <spec> --check # CI guard (fails on drift)
11
+ node scripts/align-spec.mts --spec-dir <spec> --nodes a,b --base HEAD~1
12
+ ```
13
+
14
+ Detect splits into a mechanical **scenario-diff** (this engine, reusing `spec-gate`'s
15
+ `classify-edit-class` against the frozen baseline — a narrowing flags a Clearance) and a
16
+ judge-orchestrated **coverage/contradiction** check (the resolved spec-judge's Builder-coverage
17
+ lens; no engine code, since there are no scenario IDs in prose to bind against). Reconcile applies
18
+ the judge's verdict through two write primitives, `trimProse` and `appendScenario`, that
19
+ structurally cannot touch `status`/`approval`/freeze — see [`SKILL.md`](./SKILL.md) for the full
20
+ procedure and the frozen-scenario map. **User-invocable.**
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: align-spec
3
+ description: "Detect and reconcile prose-suite drift across the SDD project spec's nodes — the on-demand, CI-usable complement to the inline spec-gate check; use for corpus audits, post-large-change verification, or CI gating."
4
+ ---
5
+
6
+ # align-spec
7
+
8
+ The **align-spec** procedure: the one **user-invocable** (and CI-usable) project-spec tool, and the
9
+ only one that **reconciles** rather than only reporting. It runs the same alignment check the spec
10
+ gate runs inline at every CR, but **on demand** across **the project spec's nodes** — for audits,
11
+ post-large-change verification, and CI gating. It never substitutes for the gate; it is the
12
+ on-demand complement that catches latent drift the inline gate did not see. It is the intra-spec
13
+ alignment sibling of `check-spec-structure` (node-shape) and `concept-index` (the by-concept view)
14
+ under the one-project-one-spec model.
15
+
16
+ ## Scope
17
+
18
+ **Subject** — detecting prose↔suite drift across the project spec's nodes, and reconciling each
19
+ detected gap. **Non-goals** — it never writes `status`/`approval`/freeze, and it does not audit
20
+ node-shape or propose splits (`check-spec-structure`'s job).
21
+
22
+ ## Run the scan
23
+
24
+ ```bash
25
+ node "<skill>/scripts/align-spec.mts" [--spec-dir <spec>] [--nodes <a,b,...>] [--base <ref>] [--check] [--format toon|json]
26
+ ```
27
+
28
+ - Default `--spec-dir` is `.`; default `--base` is `HEAD` (the scenario-diff baseline); default
29
+ `--format` is TOON. `--nodes` scopes the sweep to exactly the named nodes (display path or
30
+ README-relative path) instead of every node in the spec.
31
+ - **Audit mode** (default) prints a per-node drift report from the mechanical scan below.
32
+ - **`--check`** (CI guard) exits **non-zero** iff any mechanical drift is found and **writes
33
+ nothing**; exits zero when the mechanical scan is clean. Wired into `verify:specs` alongside
34
+ `check-spec-structure --check`.
35
+
36
+ ## The procedure — Detect
37
+
38
+ Detect has two layers, and this skill's engine (`scripts/align-spec.mts`) ships code for only
39
+ the mechanical one:
40
+
41
+ 1. **Mechanical scenario-diff (engine code)** — for each node's `.feature`, run the same
42
+ structural, gherkin-cli-backed diff `spec-gate`'s `classify-edit-class` uses against the
43
+ frozen baseline at `--base`. A modified or removed baseline scenario is a **narrowing** — it is
44
+ flagged as a **Clearance** finding (never silently absorbed). This never re-implements a
45
+ line-diff (a line-diff is fooled by a step reassigned off a frozen scenario onto a newly-added
46
+ adjacent one — see `classify-edit-class`'s doc comment).
47
+ 2. **Semantic prose↔suite alignment (judge-orchestrated, no engine code)** — dispatch the
48
+ resolved spec-judge for the node's artifact-type; it applies the **Builder (coverage) lens**,
49
+ reading the node's prose (`README.md` + diagrams) against its `.feature` for:
50
+ - a **coverage gap** — prose describes a behavior with no scenario;
51
+ - a **prose/scenario contradiction** — the prose and a scenario disagree.
52
+ There are **no scenario IDs in the prose** — this alignment is judge-only; only the `.feature`
53
+ carries scenario identity, so no static rule can bind a paragraph to a scenario. An aligned
54
+ node (no gap, no contradiction, no narrowing) reports no drift.
55
+
56
+ Running detect over "every node" means: iterate the chosen node set (all nodes, or `--nodes`'
57
+ explicit subset); for each, run step 1 mechanically and step 2 via the judge; union the findings
58
+ per node.
59
+
60
+ ## The procedure — Reconcile
61
+
62
+ For each drift finding, an **Oracle-lens (scope) call** sets the direction, then the mechanical
63
+ write primitives this engine exports (`trimProse`, `appendScenario`) apply the fix — never a
64
+ free-hand edit:
65
+
66
+ - **in-scope coverage gap** → the Builder lens drafts the missing scenario text; call
67
+ `appendScenario(featureText, scenarioBlock)` to add it to the `.feature`. `appendScenario` only
68
+ ever appends a whole new scenario block — it cannot rewrite an existing one.
69
+ - **out-of-scope prose claim** → call `trimProse(readmeText, proseToRemove)` to drop the
70
+ unsupported claim. `trimProse` splits frontmatter from body first (`splitFrontmatter`) and only
71
+ ever rewrites the body — the frontmatter (and any `status`/`approval`/freeze field it carries)
72
+ passes through byte-for-byte untouched.
73
+ - **contradiction** → the Oracle lens picks the winning side (prose or scenario); align the
74
+ losing side to it using the same two primitives (trim/rewrite the losing prose, or narrow/widen
75
+ the losing scenario text via `appendScenario`'s sibling edit path).
76
+ - **a gap whose fix would narrow an already-frozen scenario** → do **not** call either write
77
+ primitive. Escalate a **Clearance CR** instead — the same escalation the mechanical
78
+ scenario-diff (Detect, step 1) already flags. A frozen scenario is never silently rewritten to
79
+ close a gap.
80
+
81
+ ## The write boundary
82
+
83
+ `align-spec` may write **prose or scenarios** in reconcile mode, but **never** `status`,
84
+ `approval`, or a freeze marker. This is structural, not just a rule: `trimProse` and
85
+ `appendScenario` split frontmatter from body (or operate on a `.feature`, which carries no
86
+ frontmatter to begin with) and only ever touch the body / append a scenario — neither function's
87
+ implementation references a lifecycle key. `--check` never writes at all (audit-only).
88
+
89
+ ## Frozen-scenario map
90
+
91
+ | Frozen scenario (`align-spec.feature`) | Where it lives |
92
+ |---|---|
93
+ | detect reports a coverage gap between prose and suite | Detect, step 2 (judge, Builder-coverage lens) |
94
+ | detect reports a prose-scenario contradiction | Detect, step 2 (judge) |
95
+ | detect runs over every node of the project spec | Detect intro + engine `detect()`/`selectNodes()` |
96
+ | a scenario-diff flags a narrowing of the frozen suite | Detect, step 1 — engine `detectNarrowing()` |
97
+ | detect over an aligned spec reports no drift | Detect (aggregate of steps 1+2; engine `hasDrift()`) |
98
+ | check mode exits non-zero on drift and writes nothing | Engine `main()` `--check` path |
99
+ | check mode exits zero when there is no drift | Engine `main()` `--check` path |
100
+ | an in-scope gap is reconciled by adding a scenario | Reconcile, bullet 1 — engine `appendScenario()` |
101
+ | an out-of-scope prose claim is reconciled by trimming the prose | Reconcile, bullet 2 — engine `trimProse()` |
102
+ | a contradiction is reconciled by aligning the losing side | Reconcile, bullet 3 (judge picks side; engine primitives apply it) |
103
+ | a gap that would narrow a frozen scenario escalates as a Clearance | Reconcile, bullet 4 (no write; same Clearance path as Detect step 1) |
104
+ | reconcile never writes lifecycle state | The write boundary — engine `splitFrontmatter`/`trimProse`/`appendScenario` |
105
+
106
+ ## When `node` is absent
107
+
108
+ An agent performs the mechanical scenario-diff by hand only if `gherkin-cli` tooling is
109
+ unavailable: for each node's `.feature`, compare it scenario-by-scenario against its committed
110
+ baseline; a modified or removed scenario is a narrowing. The judge-orchestrated layer (coverage,
111
+ contradiction) is always by-hand regardless — it is prose reasoning, not a script.