cyber-sdd 0.7.0 → 0.7.1

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 (149) hide show
  1. package/.claude-plugin/plugin.json +1 -2
  2. package/.codex-plugin/plugin.json +1 -2
  3. package/agents/sdd-scanner.md +1 -1
  4. package/package.json +11 -13
  5. package/plugin.json +55 -0
  6. package/skills/align-spec/SKILL.md +1 -1
  7. package/skills/align-spec/scripts/align-spec.mjs +6755 -12
  8. package/skills/blast-estimate/README.md +3 -3
  9. package/skills/blast-estimate/scripts/blast-estimate.mjs +601 -12
  10. package/skills/check-field-mandates/scripts/check-field-mandates.mjs +253 -12
  11. package/skills/check-partition-quality/scripts/check-partition-quality.mjs +235 -12
  12. package/skills/check-plan-safety/SKILL.md +2 -3
  13. package/skills/check-plan-safety/scripts/check-plan-safety.mjs +109 -12
  14. package/skills/check-plugin-manifests/scripts/check-plugin-manifests.mjs +250 -12
  15. package/skills/check-project-specs/SKILL.md +1 -1
  16. package/skills/check-project-specs/scripts/check-project-specs.mjs +593 -12
  17. package/skills/check-retired-terms/SKILL.md +2 -3
  18. package/skills/check-retired-terms/scripts/check-retired-terms.mjs +186 -12
  19. package/skills/check-scenario-overlap/SKILL.md +1 -2
  20. package/skills/check-scenario-overlap/scripts/check-scenario-overlap.mjs +177 -12
  21. package/skills/check-spec-references/SKILL.md +2 -2
  22. package/skills/check-spec-references/scripts/check-spec-references.mjs +287 -12
  23. package/skills/check-spec-structure/SKILL.md +1 -2
  24. package/skills/check-spec-structure/scripts/check-spec-structure.mjs +243 -12
  25. package/skills/collision-ladder/README.md +2 -2
  26. package/skills/collision-ladder/scripts/collision-ladder.mjs +7047 -12
  27. package/skills/combat-log-governance/SKILL.md +1 -1
  28. package/skills/concept-index/SKILL.md +1 -1
  29. package/skills/concept-index/scripts/concept-index.mjs +183 -12
  30. package/skills/discover-plans/README.md +3 -3
  31. package/skills/discover-plans/SKILL.md +1 -1
  32. package/skills/discover-plans/scripts/discover-plans.mjs +137 -12
  33. package/skills/discover-specs/README.md +3 -3
  34. package/skills/discover-specs/SKILL.md +1 -1
  35. package/skills/discover-specs/scripts/discover-specs.mjs +321 -12
  36. package/skills/doctrine-loop/SKILL.md +1 -1
  37. package/skills/gate-validation-governance/SKILL.md +1 -1
  38. package/skills/init/README.md +2 -2
  39. package/skills/init/scripts/wire-statusline.mjs +168 -12
  40. package/skills/manage-ignore/README.md +3 -3
  41. package/skills/manage-ignore/SKILL.md +1 -2
  42. package/skills/manage-ignore/scripts/manage-ignore.mjs +285 -12
  43. package/skills/manage-scenario-bridge/README.md +3 -3
  44. package/skills/manage-scenario-bridge/SKILL.md +1 -1
  45. package/skills/manage-scenario-bridge/scripts/manage-scenario-bridge.mjs +239 -12
  46. package/skills/manage-spec-anchors/README.md +3 -3
  47. package/skills/manage-spec-anchors/SKILL.md +1 -1
  48. package/skills/manage-spec-anchors/scripts/manage-spec-anchors.mjs +310 -12
  49. package/skills/mission-graph/README.md +2 -2
  50. package/skills/mission-graph/SKILL.md +1 -1
  51. package/skills/mission-graph/scripts/mission-graph.mjs +1040 -12
  52. package/skills/pause-mission/SKILL.md +1 -1
  53. package/skills/place-node/SKILL.md +2 -2
  54. package/skills/place-node/scripts/place-node.mjs +117 -12
  55. package/skills/plan-retirement/README.md +2 -2
  56. package/skills/plan-retirement/scripts/retire-plans.mjs +123 -12
  57. package/skills/resolve-governances/README.md +3 -3
  58. package/skills/resolve-governances/SKILL.md +1 -1
  59. package/skills/resolve-governances/scripts/resolve-governances.mjs +352 -12
  60. package/skills/resolve-tracking/SKILL.md +1 -1
  61. package/skills/resolve-tracking/scripts/resolve-tracking.mjs +152 -12
  62. package/skills/scaffold-project-spec/SKILL.md +1 -1
  63. package/skills/spec-gate/README.md +12 -9
  64. package/skills/spec-gate/SKILL.md +2 -2
  65. package/skills/spec-gate/scripts/check-spec-state.mjs +422 -12
  66. package/skills/spec-gate/scripts/check-suite.mjs +6500 -12
  67. package/skills/spec-gate/scripts/classify-edit-class.mjs +6579 -12
  68. package/skills/spec-producer-governance/SKILL.md +2 -2
  69. package/skills/start-mission/SKILL.md +1 -1
  70. package/skills/suite-format-governance/README.md +1 -1
  71. package/skills/suite-format-governance/SKILL.md +1 -1
  72. package/skills/touch-set-correction/README.md +5 -5
  73. package/skills/touch-set-correction/SKILL.md +1 -1
  74. package/skills/touch-set-correction/scripts/touch-set-correction.mjs +6663 -12
  75. package/skills/verify-scenarios/README.md +6 -6
  76. package/skills/verify-scenarios/scripts/verify-scenarios.mjs +6539 -12
  77. package/.plugin/pins.json +0 -3
  78. package/.plugin/plugin.json +0 -19
  79. package/dist/align-spec/scripts/align-spec.js +0 -102
  80. package/dist/check-project-specs/scripts/check-project-specs.js +0 -312
  81. package/dist/check-scenario-overlap/scripts/check-scenario-overlap.js +0 -175
  82. package/dist/check-spec-references/scripts/check-spec-references.js +0 -285
  83. package/dist/check-spec-structure/scripts/check-spec-structure.js +0 -241
  84. package/dist/concept-index/scripts/concept-index.js +0 -181
  85. package/dist/discover-specs/scripts/discover-specs.js +0 -318
  86. package/dist/spec-gate/scripts/check-spec-state.js +0 -420
  87. package/dist/spec-gate/scripts/check-suite.js +0 -317
  88. package/dist/spec-gate/scripts/classify-edit-class.js +0 -263
  89. package/dist/spec-gate/vendor/gherkin-cli.js +0 -6369
  90. package/skills/align-spec/scripts/align-spec.bundle.mjs +0 -6753
  91. package/skills/align-spec/scripts/align-spec.mts +0 -188
  92. package/skills/blast-estimate/scripts/blast-estimate.bundle.mjs +0 -593
  93. package/skills/blast-estimate/scripts/blast-estimate.mts +0 -586
  94. package/skills/check-field-mandates/scripts/check-field-mandates.bundle.mjs +0 -251
  95. package/skills/check-field-mandates/scripts/check-field-mandates.mts +0 -337
  96. package/skills/check-partition-quality/scripts/check-partition-quality.bundle.mjs +0 -233
  97. package/skills/check-partition-quality/scripts/check-partition-quality.mts +0 -338
  98. package/skills/check-plan-safety/scripts/check-plan-safety.bundle.mjs +0 -107
  99. package/skills/check-plan-safety/scripts/check-plan-safety.mts +0 -148
  100. package/skills/check-plugin-manifests/scripts/check-plugin-manifests.bundle.mjs +0 -248
  101. package/skills/check-plugin-manifests/scripts/check-plugin-manifests.mts +0 -303
  102. package/skills/check-project-specs/scripts/check-project-specs.bundle.mjs +0 -584
  103. package/skills/check-project-specs/scripts/check-project-specs.mts +0 -370
  104. package/skills/check-retired-terms/scripts/check-retired-terms.bundle.mjs +0 -184
  105. package/skills/check-retired-terms/scripts/check-retired-terms.mts +0 -293
  106. package/skills/check-scenario-overlap/scripts/check-scenario-overlap.bundle.mjs +0 -175
  107. package/skills/check-scenario-overlap/scripts/check-scenario-overlap.mts +0 -250
  108. package/skills/check-spec-references/scripts/check-spec-references.bundle.mjs +0 -285
  109. package/skills/check-spec-references/scripts/check-spec-references.mts +0 -422
  110. package/skills/check-spec-structure/scripts/check-spec-structure.bundle.mjs +0 -241
  111. package/skills/check-spec-structure/scripts/check-spec-structure.mts +0 -347
  112. package/skills/collision-ladder/scripts/collision-ladder.bundle.mjs +0 -7041
  113. package/skills/collision-ladder/scripts/collision-ladder.mts +0 -662
  114. package/skills/concept-index/scripts/concept-index.bundle.mjs +0 -181
  115. package/skills/concept-index/scripts/concept-index.mts +0 -246
  116. package/skills/discover-plans/scripts/discover-plans.bundle.mjs +0 -135
  117. package/skills/discover-plans/scripts/discover-plans.mts +0 -215
  118. package/skills/discover-specs/scripts/discover-specs.bundle.mjs +0 -319
  119. package/skills/discover-specs/scripts/discover-specs.mts +0 -420
  120. package/skills/init/scripts/wire-statusline.bundle.mjs +0 -166
  121. package/skills/init/scripts/wire-statusline.mts +0 -279
  122. package/skills/manage-ignore/scripts/manage-ignore.bundle.mjs +0 -244
  123. package/skills/manage-ignore/scripts/manage-ignore.mts +0 -297
  124. package/skills/manage-scenario-bridge/scripts/manage-scenario-bridge.bundle.mjs +0 -237
  125. package/skills/manage-scenario-bridge/scripts/manage-scenario-bridge.mts +0 -159
  126. package/skills/manage-spec-anchors/scripts/manage-spec-anchors.bundle.mjs +0 -308
  127. package/skills/manage-spec-anchors/scripts/manage-spec-anchors.mts +0 -331
  128. package/skills/mission-graph/scripts/mission-graph.bundle.mjs +0 -1038
  129. package/skills/mission-graph/scripts/mission-graph.mts +0 -1333
  130. package/skills/place-node/scripts/place-node.bundle.mjs +0 -115
  131. package/skills/place-node/scripts/place-node.mts +0 -158
  132. package/skills/plan-retirement/scripts/retire-plans.bundle.mjs +0 -121
  133. package/skills/plan-retirement/scripts/retire-plans.mts +0 -205
  134. package/skills/resolve-governances/scripts/resolve-governances.bundle.mjs +0 -350
  135. package/skills/resolve-governances/scripts/resolve-governances.mts +0 -518
  136. package/skills/resolve-tracking/scripts/resolve-tracking.bundle.mjs +0 -150
  137. package/skills/resolve-tracking/scripts/resolve-tracking.mts +0 -214
  138. package/skills/spec-gate/scripts/check-spec-state.bundle.mjs +0 -420
  139. package/skills/spec-gate/scripts/check-spec-state.mts +0 -637
  140. package/skills/spec-gate/scripts/check-suite.bundle.mjs +0 -6498
  141. package/skills/spec-gate/scripts/check-suite.mts +0 -538
  142. package/skills/spec-gate/scripts/classify-edit-class.bundle.mjs +0 -6577
  143. package/skills/spec-gate/scripts/classify-edit-class.mts +0 -414
  144. package/skills/spec-gate/vendor/gherkin-cli.d.mts +0 -2
  145. package/skills/spec-gate/vendor/gherkin-cli.mjs +0 -6545
  146. package/skills/touch-set-correction/scripts/touch-set-correction.bundle.mjs +0 -6655
  147. package/skills/touch-set-correction/scripts/touch-set-correction.mts +0 -429
  148. package/skills/verify-scenarios/scripts/verify-scenarios.bundle.mjs +0 -6537
  149. package/skills/verify-scenarios/scripts/verify-scenarios.mts +0 -470
@@ -1,188 +0,0 @@
1
- #!/usr/bin/env node
2
- // align-spec — project-spec/align-spec's concrete engine. Detects prose↔suite drift across the
3
- // project spec's nodes and, on request, applies the mechanical write primitives a judge-directed
4
- // reconcile step uses (see this skill's README.md / SKILL.md).
5
- //
6
- // The 12 frozen scenarios split two ways (align-spec.feature):
7
- // - Mechanical (this engine ships code + a test for each):
8
- // * a scenario-diff flags a narrowing of the frozen suite → Clearance
9
- // * check mode exits non-zero on drift and writes nothing
10
- // * check mode exits zero when there is no drift
11
- // * detect runs over every node of the project spec (a chosen set)
12
- // * reconcile never writes lifecycle state (writes only prose or scenarios)
13
- // - Judge-orchestrated (SKILL.md documents the procedure; no engine code):
14
- // coverage-gap detection, prose/scenario contradiction detection, the aligned-report-no-
15
- // drift aggregate, and every reconcile *decision* (add a scenario / trim prose / align the
16
- // losing side / escalate a Clearance) — there are no scenario IDs in prose, so prose↔suite
17
- // alignment is judge-only. This engine feeds that judge the mechanical scan (node
18
- // iteration + scenario-diff); it never itself judges coverage or contradiction.
19
- //
20
- // Node iteration and the scenario-diff reuse the existing engines rather than re-implementing
21
- // them: check-spec-structure's scanProjectSpec (node discovery) and spec-gate's classify-edit-
22
- // class (the gherkin-cli-backed structural diff against a frozen baseline).
23
- //
24
- // No dependencies (the repo's node-≥23.6 / no-deps convention). Pure functions are exported for
25
- // node:test; running the file directly drives the CLI.
26
-
27
- import { existsSync, readdirSync, realpathSync } from 'node:fs'
28
- import { isAbsolute, join, relative } from 'node:path'
29
- import { pathToFileURL } from 'node:url'
30
- import { type NodeRecord, scanProjectSpec } from '../../check-spec-structure/scripts/check-spec-structure.mts'
31
- import { classifyFile } from '../../spec-gate/scripts/classify-edit-class.mts'
32
-
33
- export const DEFAULT_BASE = 'HEAD'
34
-
35
- export type DriftKind = 'narrowing'
36
- export type DriftSeverity = 'clearance'
37
-
38
- export interface DriftFinding {
39
- kind: DriftKind
40
- severity: DriftSeverity
41
- /** The node's display path (a folder for a README-rooted node). */
42
- node: string
43
- detail: string
44
- }
45
-
46
- // ── Node selection — the "chosen set" a detect run scopes to ──
47
- // No `--nodes` arg selects every node scanProjectSpec finds; an explicit list scopes the sweep
48
- // to exactly those nodes (matched by display path or the README's relative path).
49
- export function selectNodes(records: NodeRecord[], only?: string[]): NodeRecord[] {
50
- if (!only || only.length === 0) return records
51
- const wanted = new Set(only.map(normalizeNodeRef))
52
- return records.filter((r) => wanted.has(normalizeNodeRef(r.display)) || wanted.has(normalizeNodeRef(r.relPath)))
53
- }
54
-
55
- function normalizeNodeRef(ref: string): string {
56
- return ref
57
- .replace(/\\/g, '/')
58
- .replace(/\/README\.md$/, '')
59
- .replace(/\/+$/, '')
60
- }
61
-
62
- // ── Locate a node's sibling `.feature` file (same convention check-spec-structure scans by) ──
63
- export function findFeaturePath(specDir: string, node: NodeRecord): string | null {
64
- const nodeDir = join(specDir, node.relPath.replace(/README\.md$/, ''))
65
- if (!existsSync(nodeDir)) return null
66
- const entries = readdirSync(nodeDir, { withFileTypes: true })
67
- const feature = entries.find((e) => e.isFile() && e.name.endsWith('.feature'))
68
- return feature ? join(nodeDir, feature.name) : null
69
- }
70
-
71
- // ── Mechanical scenario-diff: a modified/removed baseline scenario is a narrowing → Clearance ──
72
- // Reuses spec-gate's classify-edit-class rather than hand-rolling a line-diff (a line-diff is
73
- // fooled by a step reassigned off a frozen scenario onto a newly-added adjacent one).
74
- export function detectNarrowing(node: NodeRecord, specDir: string, base: string, cwd = '.'): DriftFinding[] {
75
- const featurePath = findFeaturePath(specDir, node)
76
- if (!featurePath) return []
77
- // classifyFile (and the `git show <base>:<path>` it drives) needs a path relative to cwd
78
- // (the git repo root) — resolve it, since specDir/featurePath may already be absolute.
79
- const relFeaturePath = isAbsolute(featurePath) ? relative(cwd, featurePath) : featurePath
80
- const result = classifyFile(relFeaturePath, base, cwd)
81
- if (result.classification !== 'narrowing' && result.classification !== 'mixed') return []
82
- const narrowed = result.scenarios.filter((s) => s.change === 'modified' || s.change === 'removed')
83
- return [
84
- {
85
- kind: 'narrowing',
86
- severity: 'clearance',
87
- node: node.display,
88
- detail: `scenario-diff vs ${base} narrows: ${narrowed.map((s) => s.name).join(', ')} — escalate a Clearance CR, do not silently rewrite`,
89
- },
90
- ]
91
- }
92
-
93
- // Runs the mechanical scan over exactly the chosen node set — reports drift per node.
94
- export function detect(records: NodeRecord[], specDir: string, base: string, cwd = '.'): DriftFinding[] {
95
- return records.flatMap((node) => detectNarrowing(node, specDir, base, cwd))
96
- }
97
-
98
- export function hasDrift(findings: DriftFinding[]): boolean {
99
- return findings.length > 0
100
- }
101
-
102
- // ── The write boundary ──
103
- // Reconcile decisions (add/trim/align/escalate) are judge-orchestrated (SKILL.md), but the
104
- // mechanical write primitives the judge's verdict drives are engine code, and they are built to
105
- // make writing lifecycle state structurally impossible: a README write splits frontmatter from
106
- // body and only ever touches the body; a .feature write only ever appends a whole scenario block.
107
- export interface SplitDocument {
108
- frontmatter: string
109
- body: string
110
- }
111
-
112
- export function splitFrontmatter(text: string): SplitDocument {
113
- const m = /^(---\r?\n[\s\S]*?\r?\n---\s*(?:\r?\n|$))([\s\S]*)$/.exec(text)
114
- if (!m) return { frontmatter: '', body: text }
115
- return { frontmatter: m[1], body: m[2] }
116
- }
117
-
118
- // Trims prose out of a node's README body — the frontmatter (and any status/approval/freeze
119
- // field it carries) passes through byte-for-byte untouched.
120
- export function trimProse(readmeText: string, proseToRemove: string): string {
121
- const { frontmatter, body } = splitFrontmatter(readmeText)
122
- return frontmatter + body.split(proseToRemove).join('')
123
- }
124
-
125
- // Appends a whole scenario block to a `.feature` file. `.feature` files carry no frontmatter /
126
- // lifecycle fields to begin with — this only ever appends, never rewrites an existing scenario
127
- // (a rewrite of an existing frozen scenario is the narrowing path above, which escalates instead).
128
- export function appendScenario(featureText: string, scenarioBlock: string): string {
129
- const trimmed = featureText.replace(/\s+$/, '')
130
- return `${trimmed}\n\n${scenarioBlock.trim()}\n`
131
- }
132
-
133
- // ── Render ──
134
- export function renderFindings(findings: DriftFinding[], specDir: string): string {
135
- const lines: string[] = [`align-spec: spec-dir=${specDir}`, `drift[${findings.length}]:`]
136
- for (const f of findings) lines.push(` ${f.node} — ${f.kind} (${f.severity}): ${f.detail}`)
137
- if (findings.length === 0) lines.push(' (none — mechanical scenario-diff found no narrowing)')
138
- lines.push(
139
- 'note: coverage gaps and prose/scenario contradictions are judge-only (no scenario IDs in prose) — this engine reports only the mechanical scenario-diff',
140
- )
141
- return lines.join('\n')
142
- }
143
-
144
- // ── CLI ──
145
- function parseNodesArg(value: string | undefined): string[] | undefined {
146
- if (!value) return undefined
147
- const parts = value
148
- .split(',')
149
- .map((s) => s.trim())
150
- .filter(Boolean)
151
- return parts.length > 0 ? parts : undefined
152
- }
153
-
154
- export function main(argv: string[]): number {
155
- let specDir = '.'
156
- let base = DEFAULT_BASE
157
- let mode: 'detect' | 'check' = 'detect'
158
- let format: 'toon' | 'json' = 'toon'
159
- let only: string[] | undefined
160
- for (let i = 0; i < argv.length; i++) {
161
- const a = argv[i]
162
- if (a === '--spec-dir') specDir = argv[++i] ?? '.'
163
- else if (a === '--check') mode = 'check'
164
- else if (a === '--base') base = argv[++i] ?? DEFAULT_BASE
165
- else if (a === '--format') format = (argv[++i] as 'toon' | 'json') ?? 'toon'
166
- else if (a === '--nodes') only = parseNodesArg(argv[++i])
167
- }
168
-
169
- const records = selectNodes(scanProjectSpec(specDir), only)
170
- const findings = detect(records, specDir, base)
171
-
172
- if (mode === 'check') {
173
- if (hasDrift(findings)) {
174
- process.stderr.write(`align-spec: ${findings.length} drift finding(s) (mechanical scenario-diff)\n`)
175
- return 1
176
- }
177
- process.stdout.write('align-spec: no mechanical drift\n')
178
- return 0
179
- }
180
-
181
- if (format === 'json') process.stdout.write(`${JSON.stringify(findings)}\n`)
182
- else process.stdout.write(`${renderFindings(findings, specDir)}\n`)
183
- return 0
184
- }
185
-
186
- if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href) {
187
- process.exit(main(process.argv.slice(2)))
188
- }