specky-sdd 3.11.0 → 3.12.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 (478) hide show
  1. package/.apm/agents/specky-design-architect.agent.md +7 -27
  2. package/.apm/agents/specky-implementer.agent.md +14 -26
  3. package/.apm/agents/specky-onboarding.agent.md +8 -49
  4. package/.apm/agents/specky-orchestrator.agent.md +11 -36
  5. package/.apm/agents/specky-quality-reviewer.agent.md +8 -29
  6. package/.apm/agents/specky-release-engineer.agent.md +7 -30
  7. package/.apm/agents/specky-sdd-init.agent.md +7 -18
  8. package/.apm/agents/specky-spec-engineer.agent.md +8 -30
  9. package/.apm/agents/specky-task-planner.agent.md +6 -25
  10. package/.apm/agents/specky-test-verifier.agent.md +6 -17
  11. package/.apm/hooks/scripts/specky-artifact-validator.sh +14 -10
  12. package/.apm/hooks/scripts/specky-auto-checkpoint.sh +9 -4
  13. package/.apm/hooks/scripts/specky-branch-validator.sh +29 -116
  14. package/.apm/hooks/scripts/specky-cognitive-debt-alert.sh +6 -3
  15. package/.apm/hooks/scripts/specky-contract-context.bash +24 -0
  16. package/.apm/hooks/scripts/specky-contract-context.mjs +235 -0
  17. package/.apm/hooks/scripts/specky-drift-monitor.sh +6 -3
  18. package/.apm/hooks/scripts/specky-ears-validator.sh +5 -2
  19. package/.apm/hooks/scripts/specky-lgtm-gate.sh +12 -10
  20. package/.apm/hooks/scripts/specky-metrics-dashboard.sh +5 -2
  21. package/.apm/hooks/scripts/specky-phase-gate.sh +18 -9
  22. package/.apm/hooks/scripts/specky-pipeline-guard.sh +19 -26
  23. package/.apm/hooks/scripts/specky-release-gate.sh +38 -46
  24. package/.apm/hooks/scripts/specky-security-scan.sh +53 -36
  25. package/.apm/hooks/scripts/specky-session-banner.sh +22 -74
  26. package/.apm/hooks/scripts/specky-spec-quality.sh +7 -4
  27. package/.apm/hooks/scripts/specky-spec-sync.sh +12 -11
  28. package/.apm/hooks/scripts/specky-task-tracer.sh +5 -2
  29. package/.apm/hooks/specky-run.sh +3 -0
  30. package/.apm/instructions/claude-instructions.instructions.md +3 -3
  31. package/.apm/instructions/copilot-instructions.instructions.md +3 -3
  32. package/.apm/instructions/cursor-instructions.instructions.md +3 -3
  33. package/.apm/instructions/opencode-instructions.instructions.md +2 -2
  34. package/.apm/prompts/specky-brownfield.prompt.md +8 -5
  35. package/.apm/prompts/specky-greenfield.prompt.md +7 -5
  36. package/.apm/prompts/specky-implement.prompt.md +1 -1
  37. package/.apm/prompts/specky-orchestrate.prompt.md +1 -1
  38. package/.apm/skills/specky-design-architect/SKILL.md +39 -16
  39. package/.apm/skills/specky-implementer/SKILL.md +46 -158
  40. package/.apm/skills/specky-onboarding/SKILL.md +50 -156
  41. package/.apm/skills/specky-orchestrator/SKILL.md +28 -26
  42. package/.apm/skills/specky-quality-reviewer/SKILL.md +38 -23
  43. package/.apm/skills/specky-release-engineer/SKILL.md +38 -270
  44. package/.apm/skills/specky-research-analyst/SKILL.md +1 -1
  45. package/.apm/skills/specky-sdd-init/SKILL.md +61 -23
  46. package/.apm/skills/specky-sdd-pipeline/SKILL.md +36 -216
  47. package/.apm/skills/specky-spec-engineer/SKILL.md +40 -17
  48. package/.apm/skills/specky-task-planner/SKILL.md +31 -12
  49. package/.apm/skills/specky-test-verifier/SKILL.md +23 -202
  50. package/CHANGELOG.md +54 -0
  51. package/README.md +55 -46
  52. package/apm.lock.yaml +51 -49
  53. package/apm.yml +3 -3
  54. package/config.yml +32 -56
  55. package/dist/cli/commands/apm.d.ts +11 -0
  56. package/dist/cli/commands/apm.d.ts.map +1 -1
  57. package/dist/cli/commands/apm.js +4 -4
  58. package/dist/cli/commands/apm.js.map +1 -1
  59. package/dist/cli/commands/compile.d.ts.map +1 -1
  60. package/dist/cli/commands/compile.js +33 -10
  61. package/dist/cli/commands/compile.js.map +1 -1
  62. package/dist/cli/commands/doctor.d.ts.map +1 -1
  63. package/dist/cli/commands/doctor.js +74 -9
  64. package/dist/cli/commands/doctor.js.map +1 -1
  65. package/dist/cli/commands/hooks.d.ts.map +1 -1
  66. package/dist/cli/commands/hooks.js +3 -1
  67. package/dist/cli/commands/hooks.js.map +1 -1
  68. package/dist/cli/commands/init.d.ts.map +1 -1
  69. package/dist/cli/commands/init.js +28 -17
  70. package/dist/cli/commands/init.js.map +1 -1
  71. package/dist/cli/commands/migrate-contracts.d.ts +15 -0
  72. package/dist/cli/commands/migrate-contracts.d.ts.map +1 -0
  73. package/dist/cli/commands/migrate-contracts.js +317 -0
  74. package/dist/cli/commands/migrate-contracts.js.map +1 -0
  75. package/dist/cli/commands/status.d.ts.map +1 -1
  76. package/dist/cli/commands/status.js +68 -52
  77. package/dist/cli/commands/status.js.map +1 -1
  78. package/dist/cli/index.js +98 -33
  79. package/dist/cli/index.js.map +1 -1
  80. package/dist/cli/lib/apm/lock.d.ts.map +1 -1
  81. package/dist/cli/lib/apm/lock.js +1 -1
  82. package/dist/cli/lib/apm/lock.js.map +1 -1
  83. package/dist/cli/lib/apm/manifest.d.ts.map +1 -1
  84. package/dist/cli/lib/apm/manifest.js +1 -1
  85. package/dist/cli/lib/apm/manifest.js.map +1 -1
  86. package/dist/cli/lib/apm/policy.d.ts.map +1 -1
  87. package/dist/cli/lib/apm/policy.js +2 -2
  88. package/dist/cli/lib/apm/policy.js.map +1 -1
  89. package/dist/cli/lib/asset-copier.d.ts.map +1 -1
  90. package/dist/cli/lib/asset-copier.js +25 -10
  91. package/dist/cli/lib/asset-copier.js.map +1 -1
  92. package/dist/cli/lib/cursor-plugin-writer.d.ts.map +1 -1
  93. package/dist/cli/lib/cursor-plugin-writer.js +36 -9
  94. package/dist/cli/lib/cursor-plugin-writer.js.map +1 -1
  95. package/dist/cli/lib/gitignore-writer.d.ts.map +1 -1
  96. package/dist/cli/lib/gitignore-writer.js.map +1 -1
  97. package/dist/cli/lib/harness/compilers/agent-skills.js.map +1 -1
  98. package/dist/cli/lib/harness/compilers/claude.d.ts.map +1 -1
  99. package/dist/cli/lib/harness/compilers/claude.js +2 -4
  100. package/dist/cli/lib/harness/compilers/claude.js.map +1 -1
  101. package/dist/cli/lib/harness/compilers/common.d.ts.map +1 -1
  102. package/dist/cli/lib/harness/compilers/common.js +2 -6
  103. package/dist/cli/lib/harness/compilers/common.js.map +1 -1
  104. package/dist/cli/lib/harness/compilers/copilot.js.map +1 -1
  105. package/dist/cli/lib/harness/compilers/cursor.d.ts.map +1 -1
  106. package/dist/cli/lib/harness/compilers/cursor.js +2 -4
  107. package/dist/cli/lib/harness/compilers/cursor.js.map +1 -1
  108. package/dist/cli/lib/harness/compilers/opencode.d.ts.map +1 -1
  109. package/dist/cli/lib/harness/compilers/opencode.js +1 -3
  110. package/dist/cli/lib/harness/compilers/opencode.js.map +1 -1
  111. package/dist/cli/lib/harness/index.d.ts +1 -1
  112. package/dist/cli/lib/harness/index.d.ts.map +1 -1
  113. package/dist/cli/lib/harness/index.js +3 -3
  114. package/dist/cli/lib/harness/index.js.map +1 -1
  115. package/dist/cli/lib/harness/tool-map.d.ts.map +1 -1
  116. package/dist/cli/lib/harness/tool-map.js +1 -2
  117. package/dist/cli/lib/harness/tool-map.js.map +1 -1
  118. package/dist/cli/lib/harness/types.d.ts.map +1 -1
  119. package/dist/cli/lib/ide-detect.d.ts.map +1 -1
  120. package/dist/cli/lib/ide-detect.js +1 -5
  121. package/dist/cli/lib/ide-detect.js.map +1 -1
  122. package/dist/cli/lib/paths.d.ts +10 -0
  123. package/dist/cli/lib/paths.d.ts.map +1 -1
  124. package/dist/cli/lib/paths.js +1 -1
  125. package/dist/cli/lib/paths.js.map +1 -1
  126. package/dist/cli/lib/settings-merger.d.ts.map +1 -1
  127. package/dist/cli/lib/settings-merger.js +2 -3
  128. package/dist/cli/lib/settings-merger.js.map +1 -1
  129. package/dist/cli/lib/update-check.js +5 -2
  130. package/dist/cli/lib/update-check.js.map +1 -1
  131. package/dist/cli/lib/vscode-settings-writer.d.ts.map +1 -1
  132. package/dist/cli/lib/vscode-settings-writer.js +1 -1
  133. package/dist/cli/lib/vscode-settings-writer.js.map +1 -1
  134. package/dist/config.d.ts +119 -47
  135. package/dist/config.d.ts.map +1 -1
  136. package/dist/config.js +164 -130
  137. package/dist/config.js.map +1 -1
  138. package/dist/constants.d.ts +1 -1
  139. package/dist/constants.d.ts.map +1 -1
  140. package/dist/constants.js +6 -1
  141. package/dist/constants.js.map +1 -1
  142. package/dist/contracts/pipeline-profiles.d.ts +61 -0
  143. package/dist/contracts/pipeline-profiles.d.ts.map +1 -0
  144. package/dist/contracts/pipeline-profiles.js +315 -0
  145. package/dist/contracts/pipeline-profiles.js.map +1 -0
  146. package/dist/contracts/tool-contracts.d.ts +449 -0
  147. package/dist/contracts/tool-contracts.d.ts.map +1 -0
  148. package/dist/contracts/tool-contracts.js +456 -0
  149. package/dist/contracts/tool-contracts.js.map +1 -0
  150. package/dist/contracts/use-case.d.ts +736 -0
  151. package/dist/contracts/use-case.d.ts.map +1 -0
  152. package/dist/contracts/use-case.js +533 -0
  153. package/dist/contracts/use-case.js.map +1 -0
  154. package/dist/index.d.ts.map +1 -1
  155. package/dist/index.js +56 -50
  156. package/dist/index.js.map +1 -1
  157. package/dist/schemas/common.d.ts +3 -3
  158. package/dist/schemas/common.d.ts.map +1 -1
  159. package/dist/schemas/common.js +1 -6
  160. package/dist/schemas/common.js.map +1 -1
  161. package/dist/schemas/context.d.ts +2 -2
  162. package/dist/schemas/context.d.ts.map +1 -1
  163. package/dist/schemas/context.js +6 -3
  164. package/dist/schemas/context.js.map +1 -1
  165. package/dist/schemas/environment.d.ts +6 -17
  166. package/dist/schemas/environment.d.ts.map +1 -1
  167. package/dist/schemas/environment.js +16 -34
  168. package/dist/schemas/environment.js.map +1 -1
  169. package/dist/schemas/feature-content.d.ts +116 -0
  170. package/dist/schemas/feature-content.d.ts.map +1 -0
  171. package/dist/schemas/feature-content.js +92 -0
  172. package/dist/schemas/feature-content.js.map +1 -0
  173. package/dist/schemas/infrastructure.d.ts +6 -28
  174. package/dist/schemas/infrastructure.d.ts.map +1 -1
  175. package/dist/schemas/infrastructure.js +16 -36
  176. package/dist/schemas/infrastructure.js.map +1 -1
  177. package/dist/schemas/input.d.ts +412 -8
  178. package/dist/schemas/input.d.ts.map +1 -1
  179. package/dist/schemas/input.js +22 -17
  180. package/dist/schemas/input.js.map +1 -1
  181. package/dist/schemas/integration.d.ts +22 -28
  182. package/dist/schemas/integration.d.ts.map +1 -1
  183. package/dist/schemas/integration.js +37 -67
  184. package/dist/schemas/integration.js.map +1 -1
  185. package/dist/schemas/metrics.d.ts +3 -2
  186. package/dist/schemas/metrics.d.ts.map +1 -1
  187. package/dist/schemas/metrics.js +7 -3
  188. package/dist/schemas/metrics.js.map +1 -1
  189. package/dist/schemas/pbt.d.ts +2 -7
  190. package/dist/schemas/pbt.d.ts.map +1 -1
  191. package/dist/schemas/pbt.js +6 -11
  192. package/dist/schemas/pbt.js.map +1 -1
  193. package/dist/schemas/pipeline.d.ts +282 -35
  194. package/dist/schemas/pipeline.d.ts.map +1 -1
  195. package/dist/schemas/pipeline.js +95 -68
  196. package/dist/schemas/pipeline.js.map +1 -1
  197. package/dist/schemas/quality.d.ts +15 -19
  198. package/dist/schemas/quality.d.ts.map +1 -1
  199. package/dist/schemas/quality.js +41 -15
  200. package/dist/schemas/quality.js.map +1 -1
  201. package/dist/schemas/routing.d.ts +2 -2
  202. package/dist/schemas/routing.d.ts.map +1 -1
  203. package/dist/schemas/routing.js +7 -6
  204. package/dist/schemas/routing.js.map +1 -1
  205. package/dist/schemas/testing.d.ts +4 -13
  206. package/dist/schemas/testing.d.ts.map +1 -1
  207. package/dist/schemas/testing.js +11 -13
  208. package/dist/schemas/testing.js.map +1 -1
  209. package/dist/schemas/transcript.d.ts +648 -10
  210. package/dist/schemas/transcript.d.ts.map +1 -1
  211. package/dist/schemas/transcript.js +42 -25
  212. package/dist/schemas/transcript.js.map +1 -1
  213. package/dist/schemas/utility.d.ts +28 -15
  214. package/dist/schemas/utility.d.ts.map +1 -1
  215. package/dist/schemas/utility.js +52 -60
  216. package/dist/schemas/utility.js.map +1 -1
  217. package/dist/schemas/visualization.d.ts +74 -15
  218. package/dist/schemas/visualization.d.ts.map +1 -1
  219. package/dist/schemas/visualization.js +155 -27
  220. package/dist/schemas/visualization.js.map +1 -1
  221. package/dist/services/analysis-engine.d.ts.map +1 -1
  222. package/dist/services/analysis-engine.js +7 -3
  223. package/dist/services/analysis-engine.js.map +1 -1
  224. package/dist/services/audit-logger.d.ts +18 -0
  225. package/dist/services/audit-logger.d.ts.map +1 -1
  226. package/dist/services/audit-logger.js +75 -37
  227. package/dist/services/audit-logger.js.map +1 -1
  228. package/dist/services/codebase-scanner.d.ts +1 -1
  229. package/dist/services/codebase-scanner.d.ts.map +1 -1
  230. package/dist/services/codebase-scanner.js +3 -6
  231. package/dist/services/codebase-scanner.js.map +1 -1
  232. package/dist/services/cognitive-debt-engine.d.ts.map +1 -1
  233. package/dist/services/cognitive-debt-engine.js +1 -1
  234. package/dist/services/cognitive-debt-engine.js.map +1 -1
  235. package/dist/services/compliance-engine.d.ts +4 -3
  236. package/dist/services/compliance-engine.d.ts.map +1 -1
  237. package/dist/services/compliance-engine.js +244 -51
  238. package/dist/services/compliance-engine.js.map +1 -1
  239. package/dist/services/content-diagram-generator.d.ts +96 -0
  240. package/dist/services/content-diagram-generator.d.ts.map +1 -0
  241. package/dist/services/content-diagram-generator.js +372 -0
  242. package/dist/services/content-diagram-generator.js.map +1 -0
  243. package/dist/services/context-tiering-engine.d.ts +1 -1
  244. package/dist/services/context-tiering-engine.d.ts.map +1 -1
  245. package/dist/services/context-tiering-engine.js +2 -4
  246. package/dist/services/context-tiering-engine.js.map +1 -1
  247. package/dist/services/cross-analyzer.d.ts +1 -3
  248. package/dist/services/cross-analyzer.d.ts.map +1 -1
  249. package/dist/services/cross-analyzer.js +28 -28
  250. package/dist/services/cross-analyzer.js.map +1 -1
  251. package/dist/services/dependency-graph.d.ts.map +1 -1
  252. package/dist/services/dependency-graph.js +148 -28
  253. package/dist/services/dependency-graph.js.map +1 -1
  254. package/dist/services/design-completeness.d.ts +19 -0
  255. package/dist/services/design-completeness.d.ts.map +1 -0
  256. package/dist/services/design-completeness.js +58 -0
  257. package/dist/services/design-completeness.js.map +1 -0
  258. package/dist/services/diagram-generator.d.ts +4 -96
  259. package/dist/services/diagram-generator.d.ts.map +1 -1
  260. package/dist/services/diagram-generator.js +18 -1051
  261. package/dist/services/diagram-generator.js.map +1 -1
  262. package/dist/services/doc-generator.d.ts +19 -52
  263. package/dist/services/doc-generator.d.ts.map +1 -1
  264. package/dist/services/doc-generator.js +420 -524
  265. package/dist/services/doc-generator.js.map +1 -1
  266. package/dist/services/document-converter.d.ts +1 -1
  267. package/dist/services/document-converter.d.ts.map +1 -1
  268. package/dist/services/document-converter.js +35 -21
  269. package/dist/services/document-converter.js.map +1 -1
  270. package/dist/services/ears-validator.d.ts +1 -1
  271. package/dist/services/ears-validator.d.ts.map +1 -1
  272. package/dist/services/ears-validator.js +36 -11
  273. package/dist/services/ears-validator.js.map +1 -1
  274. package/dist/services/execution-context.d.ts +45 -0
  275. package/dist/services/execution-context.d.ts.map +1 -0
  276. package/dist/services/execution-context.js +160 -0
  277. package/dist/services/execution-context.js.map +1 -0
  278. package/dist/services/feature-package-generator.d.ts.map +1 -1
  279. package/dist/services/feature-package-generator.js +43 -15
  280. package/dist/services/feature-package-generator.js.map +1 -1
  281. package/dist/services/file-manager.d.ts +16 -4
  282. package/dist/services/file-manager.d.ts.map +1 -1
  283. package/dist/services/file-manager.js +98 -8
  284. package/dist/services/file-manager.js.map +1 -1
  285. package/dist/services/git-manager.d.ts +1 -1
  286. package/dist/services/git-manager.d.ts.map +1 -1
  287. package/dist/services/git-manager.js +18 -7
  288. package/dist/services/git-manager.js.map +1 -1
  289. package/dist/services/iac-generator.d.ts +57 -11
  290. package/dist/services/iac-generator.d.ts.map +1 -1
  291. package/dist/services/iac-generator.js +690 -175
  292. package/dist/services/iac-generator.js.map +1 -1
  293. package/dist/services/intent-drift-engine.d.ts.map +1 -1
  294. package/dist/services/intent-drift-engine.js +19 -2
  295. package/dist/services/intent-drift-engine.js.map +1 -1
  296. package/dist/services/methodology.d.ts.map +1 -1
  297. package/dist/services/methodology.js +86 -22
  298. package/dist/services/methodology.js.map +1 -1
  299. package/dist/services/metrics-generator.d.ts +1 -2
  300. package/dist/services/metrics-generator.d.ts.map +1 -1
  301. package/dist/services/metrics-generator.js +30 -21
  302. package/dist/services/metrics-generator.js.map +1 -1
  303. package/dist/services/model-routing-engine.d.ts +4 -4
  304. package/dist/services/model-routing-engine.d.ts.map +1 -1
  305. package/dist/services/model-routing-engine.js +73 -72
  306. package/dist/services/model-routing-engine.js.map +1 -1
  307. package/dist/services/pbt-generator.d.ts +10 -31
  308. package/dist/services/pbt-generator.d.ts.map +1 -1
  309. package/dist/services/pbt-generator.js +44 -515
  310. package/dist/services/pbt-generator.js.map +1 -1
  311. package/dist/services/rate-limiter.d.ts +8 -0
  312. package/dist/services/rate-limiter.d.ts.map +1 -1
  313. package/dist/services/rate-limiter.js +18 -0
  314. package/dist/services/rate-limiter.js.map +1 -1
  315. package/dist/services/rbac-engine.d.ts.map +1 -1
  316. package/dist/services/rbac-engine.js +1 -3
  317. package/dist/services/rbac-engine.js.map +1 -1
  318. package/dist/services/state-machine.d.ts +37 -16
  319. package/dist/services/state-machine.d.ts.map +1 -1
  320. package/dist/services/state-machine.js +265 -233
  321. package/dist/services/state-machine.js.map +1 -1
  322. package/dist/services/template-engine.d.ts +11 -5
  323. package/dist/services/template-engine.d.ts.map +1 -1
  324. package/dist/services/template-engine.js +51 -23
  325. package/dist/services/template-engine.js.map +1 -1
  326. package/dist/services/test-generator.d.ts +11 -9
  327. package/dist/services/test-generator.d.ts.map +1 -1
  328. package/dist/services/test-generator.js +104 -94
  329. package/dist/services/test-generator.js.map +1 -1
  330. package/dist/services/test-result-parser.d.ts.map +1 -1
  331. package/dist/services/test-result-parser.js +5 -4
  332. package/dist/services/test-result-parser.js.map +1 -1
  333. package/dist/services/test-traceability-mapper.d.ts.map +1 -1
  334. package/dist/services/test-traceability-mapper.js +16 -4
  335. package/dist/services/test-traceability-mapper.js.map +1 -1
  336. package/dist/services/transcript-parser.d.ts +1 -1
  337. package/dist/services/transcript-parser.d.ts.map +1 -1
  338. package/dist/services/transcript-parser.js +61 -27
  339. package/dist/services/transcript-parser.js.map +1 -1
  340. package/dist/services/work-item-exporter.d.ts +1 -1
  341. package/dist/services/work-item-exporter.d.ts.map +1 -1
  342. package/dist/services/work-item-exporter.js +14 -2
  343. package/dist/services/work-item-exporter.js.map +1 -1
  344. package/dist/templates/design.md +6 -0
  345. package/dist/tools/analysis.d.ts +1 -1
  346. package/dist/tools/analysis.d.ts.map +1 -1
  347. package/dist/tools/analysis.js +29 -25
  348. package/dist/tools/analysis.js.map +1 -1
  349. package/dist/tools/audit.d.ts.map +1 -1
  350. package/dist/tools/audit.js +4 -2
  351. package/dist/tools/audit.js.map +1 -1
  352. package/dist/tools/checkpoint.d.ts.map +1 -1
  353. package/dist/tools/checkpoint.js +88 -77
  354. package/dist/tools/checkpoint.js.map +1 -1
  355. package/dist/tools/context.d.ts +1 -1
  356. package/dist/tools/context.d.ts.map +1 -1
  357. package/dist/tools/context.js +8 -15
  358. package/dist/tools/context.js.map +1 -1
  359. package/dist/tools/documentation.d.ts +1 -4
  360. package/dist/tools/documentation.d.ts.map +1 -1
  361. package/dist/tools/documentation.js +115 -159
  362. package/dist/tools/documentation.js.map +1 -1
  363. package/dist/tools/environment.d.ts +3 -3
  364. package/dist/tools/environment.d.ts.map +1 -1
  365. package/dist/tools/environment.js +76 -116
  366. package/dist/tools/environment.js.map +1 -1
  367. package/dist/tools/infrastructure.d.ts +1 -1
  368. package/dist/tools/infrastructure.d.ts.map +1 -1
  369. package/dist/tools/infrastructure.js +50 -53
  370. package/dist/tools/infrastructure.js.map +1 -1
  371. package/dist/tools/input.d.ts +1 -1
  372. package/dist/tools/input.d.ts.map +1 -1
  373. package/dist/tools/input.js +46 -37
  374. package/dist/tools/input.js.map +1 -1
  375. package/dist/tools/integration.d.ts +1 -1
  376. package/dist/tools/integration.d.ts.map +1 -1
  377. package/dist/tools/integration.js +86 -98
  378. package/dist/tools/integration.js.map +1 -1
  379. package/dist/tools/metrics.d.ts +4 -4
  380. package/dist/tools/metrics.d.ts.map +1 -1
  381. package/dist/tools/metrics.js +22 -44
  382. package/dist/tools/metrics.js.map +1 -1
  383. package/dist/tools/pbt.d.ts +1 -1
  384. package/dist/tools/pbt.d.ts.map +1 -1
  385. package/dist/tools/pbt.js +13 -25
  386. package/dist/tools/pbt.js.map +1 -1
  387. package/dist/tools/pipeline-writers.d.ts +193 -0
  388. package/dist/tools/pipeline-writers.d.ts.map +1 -0
  389. package/dist/tools/pipeline-writers.js +203 -0
  390. package/dist/tools/pipeline-writers.js.map +1 -0
  391. package/dist/tools/pipeline.d.ts +1 -1
  392. package/dist/tools/pipeline.d.ts.map +1 -1
  393. package/dist/tools/pipeline.js +261 -431
  394. package/dist/tools/pipeline.js.map +1 -1
  395. package/dist/tools/quality.d.ts +3 -3
  396. package/dist/tools/quality.d.ts.map +1 -1
  397. package/dist/tools/quality.js +401 -129
  398. package/dist/tools/quality.js.map +1 -1
  399. package/dist/tools/rbac.d.ts.map +1 -1
  400. package/dist/tools/rbac.js +7 -4
  401. package/dist/tools/rbac.js.map +1 -1
  402. package/dist/tools/response-builder.d.ts +1 -1
  403. package/dist/tools/response-builder.d.ts.map +1 -1
  404. package/dist/tools/response-builder.js +12 -13
  405. package/dist/tools/response-builder.js.map +1 -1
  406. package/dist/tools/routing.d.ts.map +1 -1
  407. package/dist/tools/routing.js +3 -9
  408. package/dist/tools/routing.js.map +1 -1
  409. package/dist/tools/testing.d.ts.map +1 -1
  410. package/dist/tools/testing.js +59 -56
  411. package/dist/tools/testing.js.map +1 -1
  412. package/dist/tools/tool-enforcement.d.ts +3 -1
  413. package/dist/tools/tool-enforcement.d.ts.map +1 -1
  414. package/dist/tools/tool-enforcement.js +85 -59
  415. package/dist/tools/tool-enforcement.js.map +1 -1
  416. package/dist/tools/tool-result.d.ts +1 -0
  417. package/dist/tools/tool-result.d.ts.map +1 -1
  418. package/dist/tools/tool-result.js.map +1 -1
  419. package/dist/tools/transcript.d.ts +1 -1
  420. package/dist/tools/transcript.d.ts.map +1 -1
  421. package/dist/tools/transcript.js +357 -506
  422. package/dist/tools/transcript.js.map +1 -1
  423. package/dist/tools/turnkey.d.ts +1 -31
  424. package/dist/tools/turnkey.d.ts.map +1 -1
  425. package/dist/tools/turnkey.js +124 -484
  426. package/dist/tools/turnkey.js.map +1 -1
  427. package/dist/tools/utility.d.ts +2 -2
  428. package/dist/tools/utility.d.ts.map +1 -1
  429. package/dist/tools/utility.js +156 -164
  430. package/dist/tools/utility.js.map +1 -1
  431. package/dist/tools/visualization.d.ts +1 -25
  432. package/dist/tools/visualization.d.ts.map +1 -1
  433. package/dist/tools/visualization.js +250 -527
  434. package/dist/tools/visualization.js.map +1 -1
  435. package/dist/types.d.ts +39 -13
  436. package/dist/types.d.ts.map +1 -1
  437. package/dist/utils/artifact-metadata.d.ts +8 -0
  438. package/dist/utils/artifact-metadata.d.ts.map +1 -0
  439. package/dist/utils/artifact-metadata.js +10 -0
  440. package/dist/utils/artifact-metadata.js.map +1 -0
  441. package/dist/utils/context-helper.d.ts +1 -1
  442. package/dist/utils/context-helper.d.ts.map +1 -1
  443. package/dist/utils/context-helper.js.map +1 -1
  444. package/dist/utils/http-auth.d.ts.map +1 -1
  445. package/dist/utils/http-auth.js +1 -1
  446. package/dist/utils/http-auth.js.map +1 -1
  447. package/dist/utils/id-contracts.d.ts +21 -0
  448. package/dist/utils/id-contracts.d.ts.map +1 -1
  449. package/dist/utils/id-contracts.js +60 -1
  450. package/dist/utils/id-contracts.js.map +1 -1
  451. package/dist/utils/requirement-partition.d.ts +8 -0
  452. package/dist/utils/requirement-partition.d.ts.map +1 -0
  453. package/dist/utils/requirement-partition.js +15 -0
  454. package/dist/utils/requirement-partition.js.map +1 -0
  455. package/dist/utils/routing-helper.d.ts +1 -1
  456. package/dist/utils/routing-helper.d.ts.map +1 -1
  457. package/dist/utils/routing-helper.js.map +1 -1
  458. package/dist/utils/safe-read.d.ts +10 -0
  459. package/dist/utils/safe-read.d.ts.map +1 -0
  460. package/dist/utils/safe-read.js +10 -0
  461. package/dist/utils/safe-read.js.map +1 -0
  462. package/dist/utils/task-parser.d.ts.map +1 -1
  463. package/dist/utils/task-parser.js +1 -1
  464. package/dist/utils/task-parser.js.map +1 -1
  465. package/dist/utils/test-quality.d.ts +10 -0
  466. package/dist/utils/test-quality.d.ts.map +1 -0
  467. package/dist/utils/test-quality.js +10 -0
  468. package/dist/utils/test-quality.js.map +1 -0
  469. package/dist/utils/token-table.d.ts +20 -0
  470. package/dist/utils/token-table.d.ts.map +1 -1
  471. package/dist/utils/token-table.js +2 -2
  472. package/dist/utils/token-table.js.map +1 -1
  473. package/package.json +7 -3
  474. package/templates/design.md +6 -0
  475. package/dist/utils/design-stubs.d.ts +0 -32
  476. package/dist/utils/design-stubs.d.ts.map +0 -1
  477. package/dist/utils/design-stubs.js +0 -103
  478. package/dist/utils/design-stubs.js.map +0 -1
@@ -1,131 +1,44 @@
1
- #!/bin/bash
2
- # specky-branch-validator.sh — Validate git branch matches expected pattern for current tool.
3
- #
4
- # Type: Mixed (see below) | Trigger: PreToolUse | All phases
5
- # • Advisory (exit 0, warn) for sdd_* pipeline tools (always).
6
- # • For native edit tools (Write|Edit|MultiEdit) on a wrong branch during
7
- # an active pipeline:
8
- # - default (SPECKY_GUARD unset OR "off"/"advisory") → warn, exit 0
9
- # - SPECKY_GUARD=strict → exit 2 (BLOCK)
10
- #
11
- # Rationale (rc.13): rc.10-rc.12 defaulted Write|Edit|MultiEdit to BLOCKING,
12
- # which burned pilots who run `specky init` and then edit anything from
13
- # develop/main. Enforcement is now explicit opt-in.
1
+ #!/usr/bin/env bash
2
+ # specky-branch-validator.sh — Validate persisted release branch policy.
3
+ # Type: advisory by default; strict for native edits when SPECKY_GUARD=strict.
14
4
 
15
5
  set -euo pipefail
6
+ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
7
+ source "$SCRIPT_DIR/specky-contract-context.bash"
16
8
 
17
9
  TOOL="${SDD_TOOL_NAME:-unknown}"
18
10
  CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr -d '\n' || true)
19
11
  [ -z "$CURRENT_BRANCH" ] && CURRENT_BRANCH="unknown"
20
12
 
21
- # Mode selection (rc.13): strict = block, anything else = advisory.
22
- SPECKY_GUARD_MODE="${SPECKY_GUARD:-advisory}"
23
- if [ "$SPECKY_GUARD_MODE" = "off" ]; then
24
- SPECKY_GUARD_MODE="advisory"
13
+ specky_load_contract_context || exit $?
14
+ if [ "${SPECKY_CONTEXT_ACTIVE:-0}" != "1" ]; then
15
+ echo "ℹ️ Branch Validator no explicit feature context; no branch inferred."
16
+ exit 0
25
17
  fi
26
-
27
- # ── Branch enforcement for native edit tools when pipeline is active ──
28
- if [[ "$TOOL" == "Write" || "$TOOL" == "Edit" || "$TOOL" == "MultiEdit" ]]; then
29
- LATEST=$(ls -td .specs/*/ 2>/dev/null | head -1 || true)
30
- if [ -z "$LATEST" ]; then exit 0; fi
31
- STATE="$LATEST/.sdd-state.json"
32
- if [ ! -f "$STATE" ]; then exit 0; fi
33
-
34
- PHASE="?"
35
- if command -v jq >/dev/null 2>&1; then
36
- PHASE=$(jq -r '.current_phase // "?"' "$STATE" 2>/dev/null || echo "?")
37
- fi
38
-
39
- FEATURE=$(basename "$LATEST")
40
-
41
- emit_violation() {
42
- local expected="$1"
43
- if [ "$SPECKY_GUARD_MODE" = "strict" ]; then
44
- echo "" >&2
45
- echo "🚫 [specky-branch-validator] BLOCKED — $TOOL on '$CURRENT_BRANCH' (phase $PHASE expects $expected) [SPECKY_GUARD=strict]" >&2
46
- echo " Feature: $FEATURE" >&2
47
- echo " Fix: git checkout $expected (or: git checkout -b spec/$FEATURE)" >&2
48
- echo " Disable: unset SPECKY_GUARD" >&2
49
- exit 2
50
- fi
51
- echo "⚠️ [specky-branch-validator] $TOOL on '$CURRENT_BRANCH' during phase $PHASE (expected $expected). Enforce with: export SPECKY_GUARD=strict" >&2
52
- }
53
-
54
- case "$PHASE" in
55
- init|discover|specify|clarify|design|tasks|analyze|implement)
56
- if [[ "$CURRENT_BRANCH" != spec/* ]]; then
57
- emit_violation "spec/$FEATURE"
58
- fi
59
- ;;
60
- verify)
61
- if [[ "$CURRENT_BRANCH" != "develop" ]]; then
62
- emit_violation "develop"
63
- fi
64
- ;;
65
- release)
66
- if [[ "$CURRENT_BRANCH" != "stage" ]]; then
67
- emit_violation "stage"
68
- fi
69
- ;;
70
- esac
18
+ if [ "${SPECKY_RELEASE_ENABLED:-0}" != "1" ]; then
19
+ echo "ℹ️ Branch Validator release capability disabled by $SPECKY_CONTRACT_ID."
71
20
  exit 0
72
21
  fi
73
22
 
74
- echo "🔀 Branch Validator — $CURRENT_BRANCH — before $TOOL"
23
+ EXPECTED_FEATURE_BRANCH="${SPECKY_BRANCH_PREFIX}${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME}"
24
+ EXPECTED="$EXPECTED_FEATURE_BRANCH"
25
+ if [ "$TOOL" = "sdd_create_branch" ]; then
26
+ EXPECTED="$SPECKY_BASE_BRANCH"
27
+ fi
75
28
 
76
- warn() {
77
- echo "⚠️ $1"
78
- echo " Expected: $2"
79
- }
29
+ if [ "$CURRENT_BRANCH" = "$EXPECTED" ]; then
30
+ echo "✅ Branch Validator — $CURRENT_BRANCH matches persisted release policy."
31
+ exit 0
32
+ fi
80
33
 
81
- case "$TOOL" in
82
- sdd_init|sdd_create_branch)
83
- # Init should happen on develop (about to create spec branch)
84
- if [[ "$CURRENT_BRANCH" != "develop" ]] && [[ "$CURRENT_BRANCH" != spec/* ]]; then
85
- warn "sdd_init typically runs on 'develop' before creating a spec branch" "develop"
86
- fi
87
- ;;
88
- sdd_write_spec|sdd_turnkey_spec|sdd_figma_to_spec|sdd_write_design|sdd_write_tasks|sdd_implement|sdd_generate_tests|sdd_generate_pbt|sdd_generate_iac|sdd_generate_dockerfile)
89
- # Spec work must be on spec/* branch
90
- if [[ "$CURRENT_BRANCH" != spec/* ]]; then
91
- warn "Spec work should be on a spec/NNN-* branch, not '$CURRENT_BRANCH'" "spec/NNN-feature-name"
92
- echo " Flow: spec/NNN-* → develop → stage → main"
93
- fi
94
- ;;
95
- sdd_discover|sdd_research|sdd_import_document|sdd_import_transcript|sdd_clarify|sdd_validate_ears)
96
- # Research/clarify on spec branch
97
- if [[ "$CURRENT_BRANCH" != spec/* ]]; then
98
- warn "Research and clarification should be on a spec/NNN-* branch" "spec/NNN-feature-name"
99
- fi
100
- ;;
101
- sdd_verify_tests|sdd_verify_tasks|sdd_check_sync)
102
- # Verification on spec branch
103
- if [[ "$CURRENT_BRANCH" != spec/* ]]; then
104
- warn "Verification should be on a spec/NNN-* branch" "spec/NNN-feature-name"
105
- fi
106
- ;;
107
- sdd_run_analysis|sdd_cross_analyze|sdd_compliance_check)
108
- # Review on develop (after merge from spec)
109
- if [[ "$CURRENT_BRANCH" != "develop" ]] && [[ "$CURRENT_BRANCH" != spec/* ]]; then
110
- warn "Review tools typically run on 'develop' after merge from spec" "develop"
111
- fi
112
- ;;
113
- sdd_create_pr)
114
- # PR: branch determines target
115
- if [[ "$CURRENT_BRANCH" == spec/* ]]; then
116
- echo " ℹ️ spec branch → PR will target develop"
117
- elif [[ "$CURRENT_BRANCH" == "develop" ]]; then
118
- echo " ℹ️ develop → PR will target stage"
119
- elif [[ "$CURRENT_BRANCH" == "stage" ]]; then
120
- echo " ℹ️ stage → PR will target main"
121
- elif [[ "$CURRENT_BRANCH" == "main" ]]; then
122
- warn "Cannot create PR from main — nothing to merge" "spec/*, develop, or stage"
123
- fi
124
- ;;
125
- *)
126
- echo " ✅ No branch requirement for $TOOL"
127
- ;;
128
- esac
34
+ MESSAGE="branch '$CURRENT_BRANCH' does not match persisted release policy '$EXPECTED' for $TOOL"
35
+ if [[ "$TOOL" == "Write" || "$TOOL" == "Edit" || "$TOOL" == "MultiEdit" ]] && [ "${SPECKY_GUARD:-advisory}" = "strict" ]; then
36
+ echo "🚫 [specky-branch-validator] BLOCKED $MESSAGE" >&2
37
+ exit 2
38
+ fi
129
39
 
130
- # Always exit 0 — advisory only
40
+ echo "⚠️ [specky-branch-validator] $MESSAGE" >&2
41
+ echo " Contract: $SPECKY_CONTRACT_ID" >&2
42
+ echo " Base: $SPECKY_BASE_BRANCH | Prefix: $SPECKY_BRANCH_PREFIX" >&2
43
+ echo " Enforce native edits with: export SPECKY_GUARD=strict" >&2
131
44
  exit 0
@@ -5,14 +5,17 @@
5
5
  # Paper: arXiv:2603.22106 — cognitive surrender measurement
6
6
 
7
7
  set -euo pipefail
8
+ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
9
+ . "$SCRIPT_DIR/specky-contract-context.bash"
10
+ specky_load_contract_context || exit $?
11
+ [ "${SPECKY_CONTEXT_ACTIVE:-0}" = "1" ] || exit 0
8
12
 
9
- STATE=$(find . -name ".sdd-state.json" -maxdepth 2 2>/dev/null | head -1)
10
- [ -z "$STATE" ] || [ ! -f "$STATE" ] && exit 0
13
+ STATE="$SPECKY_STATE_FILE"
11
14
 
12
15
  # Check if gate history exists in state
13
16
  if command -v jq &>/dev/null && [ -f "$STATE" ]; then
14
17
  GATES=$(jq -r '.gate_history // [] | length' "$STATE" 2>/dev/null || echo "0")
15
- LGTM_NO_MOD=$(jq -r '[.gate_history // [] | .[] | select(.modified == false)] | length' "$STATE" 2>/dev/null || echo "0")
18
+ LGTM_NO_MOD=$(jq -r '[.gate_history // [] | .[] | select(.was_modified == false)] | length' "$STATE" 2>/dev/null || echo "0")
16
19
 
17
20
  if [ "$GATES" -gt 0 ]; then
18
21
  RATE=$((LGTM_NO_MOD * 100 / GATES))
@@ -0,0 +1,24 @@
1
+ # Shared explicit feature-contract context for Specky hooks.
2
+
3
+ specky_load_contract_context() {
4
+ local context_dir context_exports
5
+ context_dir=$(cd "$(dirname "$0")" && pwd)
6
+ context_exports=$(node "$context_dir/specky-contract-context.mjs" shell) || return $?
7
+ eval "$context_exports"
8
+ }
9
+
10
+ specky_has_capability() {
11
+ local capability=",${SPECKY_CAPABILITIES:-},"
12
+ case "$capability" in
13
+ *",$1,"*) return 0 ;;
14
+ *) return 1 ;;
15
+ esac
16
+ }
17
+
18
+ specky_require_feature_context() {
19
+ specky_load_contract_context || return $?
20
+ if [ "${SPECKY_CONTEXT_ACTIVE:-0}" != "1" ]; then
21
+ echo "[specky] Explicit feature context required: ${SPECKY_CONTEXT_REASON:-missing context}." >&2
22
+ return 2
23
+ fi
24
+ }
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env node
2
+ import { createHash, createHmac, timingSafeEqual } from "node:crypto";
3
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
4
+ import { relative, resolve, sep } from "node:path";
5
+
6
+ function fail(message) {
7
+ console.error(`[specky-contract-context] ${message}`);
8
+ process.exit(2);
9
+ }
10
+
11
+ function readHookInput() {
12
+ const fromEnvironment = process.env.SDD_HOOK_INPUT;
13
+ if (fromEnvironment?.trim()) return fromEnvironment;
14
+ if (process.stdin.isTTY) return "";
15
+ try {
16
+ return readFileSync(0, "utf8");
17
+ } catch {
18
+ return "";
19
+ }
20
+ }
21
+
22
+ function parseInput(raw) {
23
+ if (!raw.trim()) return {};
24
+ try {
25
+ return JSON.parse(raw);
26
+ } catch {
27
+ return {};
28
+ }
29
+ }
30
+
31
+ function objects(value) {
32
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return [];
33
+ const record = value;
34
+ return [
35
+ record,
36
+ record.tool_input,
37
+ record.toolInput,
38
+ record.arguments,
39
+ record.input,
40
+ record.params,
41
+ record.params?.arguments,
42
+ record.request?.params?.arguments,
43
+ ].filter(
44
+ (candidate) => typeof candidate === "object" && candidate !== null && !Array.isArray(candidate),
45
+ );
46
+ }
47
+
48
+ function findString(input, keys) {
49
+ for (const candidate of objects(input)) {
50
+ for (const key of keys) {
51
+ const value = candidate[key];
52
+ if (typeof value === "string" && value.trim()) return value.trim();
53
+ }
54
+ }
55
+ return undefined;
56
+ }
57
+
58
+ function safeRelativePath(value, label) {
59
+ if (!value || value.startsWith("/") || value.startsWith("\\") || /^[A-Za-z]:/.test(value)) {
60
+ fail(`${label} must be a workspace-relative path.`);
61
+ }
62
+ const segments = value.split(/[\\/]/);
63
+ if (segments.includes("..") || value.includes("\0")) fail(`${label} contains unsafe traversal.`);
64
+ return segments.filter((segment) => segment && segment !== ".").join("/");
65
+ }
66
+
67
+ function canonicalize(value) {
68
+ if (Array.isArray(value)) return value.map(canonicalize);
69
+ if (typeof value !== "object" || value === null) return value;
70
+ return Object.keys(value)
71
+ .sort((left, right) => left.localeCompare(right))
72
+ .reduce((result, key) => {
73
+ result[key] = canonicalize(value[key]);
74
+ return result;
75
+ }, {});
76
+ }
77
+
78
+ function fingerprintContract(contract) {
79
+ const { fingerprint: _fingerprint, ...snapshot } = contract;
80
+ return createHash("sha256")
81
+ .update(JSON.stringify(canonicalize(snapshot)))
82
+ .digest("hex");
83
+ }
84
+
85
+ function safeEqualHex(left, right) {
86
+ if (!/^[a-f0-9]{64}$/.test(left) || !/^[a-f0-9]{64}$/.test(right)) return false;
87
+ return timingSafeEqual(Buffer.from(left, "hex"), Buffer.from(right, "hex"));
88
+ }
89
+
90
+ function shellQuote(value) {
91
+ return `'${String(value).replaceAll("'", `'"'"'`)}'`;
92
+ }
93
+
94
+ function resolveContext() {
95
+ const workspace = resolve(process.env.SPECKY_HOOK_WORKSPACE ?? process.cwd());
96
+ const input = parseInput(readHookInput());
97
+ const requestedSpecDir = process.env.SDD_SPEC_DIR ?? findString(input, ["spec_dir", "specDir"]);
98
+ const requestedFeatureNumber =
99
+ process.env.SDD_FEATURE_NUMBER ?? findString(input, ["feature_number", "featureNumber"]);
100
+
101
+ if (!requestedSpecDir || !requestedFeatureNumber) {
102
+ return { active: false, reason: "missing explicit SDD_SPEC_DIR/SDD_FEATURE_NUMBER context" };
103
+ }
104
+ const specDir = safeRelativePath(requestedSpecDir, "spec_dir");
105
+ if (!/^\d{3}$/.test(requestedFeatureNumber)) fail("feature_number must be exactly three digits.");
106
+
107
+ const specRoot = resolve(workspace, specDir);
108
+ if (!existsSync(specRoot)) fail(`spec root does not exist: ${specDir}`);
109
+ const matches = readdirSync(specRoot, { withFileTypes: true }).filter(
110
+ (entry) => entry.isDirectory() && entry.name.startsWith(`${requestedFeatureNumber}-`),
111
+ );
112
+ if (matches.length !== 1) {
113
+ fail(
114
+ `feature ${requestedFeatureNumber} must resolve to exactly one directory in ${specDir}; found ${matches.length}.`,
115
+ );
116
+ }
117
+
118
+ const featureName = matches[0].name.slice(4);
119
+ const featureDirectory = `${specDir}/${matches[0].name}`;
120
+ const statePath = resolve(workspace, featureDirectory, ".sdd-state.json");
121
+ const signaturePath = `${statePath}.sig`;
122
+ if (!existsSync(statePath) || !existsSync(signaturePath)) {
123
+ fail(
124
+ `feature ${requestedFeatureNumber} requires signed v5 state at ${featureDirectory}/.sdd-state.json.`,
125
+ );
126
+ }
127
+
128
+ const raw = readFileSync(statePath, "utf8");
129
+ let state;
130
+ try {
131
+ state = JSON.parse(raw);
132
+ } catch {
133
+ fail(`state is not valid JSON: ${relative(workspace, statePath)}`);
134
+ }
135
+ if (state.version !== "5.0.0") fail(`state version ${String(state.version)} requires migration.`);
136
+
137
+ const key =
138
+ process.env.SDD_STATE_KEY ??
139
+ createHash("sha256").update(`specky-state-v1:${workspace}`).digest("hex");
140
+ const expectedSignature = createHmac("sha256", key).update(raw).digest("hex");
141
+ const storedSignature = readFileSync(signaturePath, "utf8").trim();
142
+ if (!safeEqualHex(storedSignature, expectedSignature))
143
+ fail("feature state signature verification failed.");
144
+
145
+ if (
146
+ state.feature?.number !== requestedFeatureNumber ||
147
+ state.feature?.name !== featureName ||
148
+ state.feature?.directory !== featureDirectory
149
+ ) {
150
+ fail(`feature state identity does not match ${featureDirectory}.`);
151
+ }
152
+ if (!state.contract || fingerprintContract(state.contract) !== state.contract.fingerprint) {
153
+ fail("feature contract fingerprint verification failed.");
154
+ }
155
+ if (
156
+ !Array.isArray(state.contract.phases) ||
157
+ !state.contract.phases.includes(state.current_phase)
158
+ ) {
159
+ fail(`current phase ${String(state.current_phase)} is not enabled by the feature contract.`);
160
+ }
161
+
162
+ const capabilities = Array.isArray(state.contract.capabilities)
163
+ ? state.contract.capabilities
164
+ : [];
165
+ const capabilityConfig = state.contract.capability_config ?? {};
166
+ const configuredCapabilities = Object.keys(capabilityConfig).sort();
167
+ const declaredCapabilities = [...new Set(capabilities)].sort();
168
+ if (JSON.stringify(configuredCapabilities) !== JSON.stringify(declaredCapabilities)) {
169
+ fail("capabilities and capability_config keys do not match.");
170
+ }
171
+
172
+ return {
173
+ active: true,
174
+ workspace,
175
+ specDir,
176
+ featureNumber: requestedFeatureNumber,
177
+ featureName,
178
+ featureDirectory,
179
+ statePath: relative(workspace, statePath).split(sep).join("/"),
180
+ phase: state.current_phase,
181
+ contract: state.contract,
182
+ gateDecision: state.gate_decision?.decision ?? "",
183
+ };
184
+ }
185
+
186
+ function printShell(context) {
187
+ const contract = context.contract ?? {};
188
+ const capabilities = Array.isArray(contract.capabilities) ? contract.capabilities : [];
189
+ const release = contract.capability_config?.release;
190
+ const tdd = contract.capability_config?.tdd;
191
+ const compliance = contract.capability_config?.compliance;
192
+ const development = contract.capability_config?.["dev-environment"];
193
+ const iac = contract.capability_config?.iac;
194
+ const values = {
195
+ SPECKY_CONTEXT_ACTIVE: context.active ? "1" : "0",
196
+ SPECKY_CONTEXT_REASON: context.reason ?? "",
197
+ SPECKY_SPEC_DIR: context.specDir ?? "",
198
+ SPECKY_FEATURE_NUMBER: context.featureNumber ?? "",
199
+ SPECKY_FEATURE_NAME: context.featureName ?? "",
200
+ SPECKY_FEATURE_DIR: context.featureDirectory ?? "",
201
+ SPECKY_STATE_FILE: context.statePath ?? "",
202
+ SPECKY_PHASE: context.phase ?? "",
203
+ SPECKY_CONTRACT_ID: contract.id ?? "",
204
+ SPECKY_CONTRACT_FINGERPRINT: contract.fingerprint ?? "",
205
+ SPECKY_LIFECYCLE: contract.lifecycle ?? "",
206
+ SPECKY_WORKLOAD: contract.workload ?? "",
207
+ SPECKY_EXECUTION_MODE: contract.execution_mode ?? "",
208
+ SPECKY_CAPABILITIES: capabilities.join(","),
209
+ SPECKY_GATE_DECISION: context.gateDecision ?? "",
210
+ SPECKY_RELEASE_ENABLED: release ? "1" : "0",
211
+ SPECKY_BRANCH_PREFIX: release?.branch_prefix ?? "",
212
+ SPECKY_BASE_BRANCH: release?.base_branch ?? "",
213
+ SPECKY_CHECKPOINTS_REQUIRED: release?.checkpoints ? "1" : "0",
214
+ SPECKY_TDD_ENABLED: tdd ? "1" : "0",
215
+ SPECKY_TDD_THRESHOLD: tdd ? String(tdd.coverage_threshold) : "",
216
+ SPECKY_COMPLIANCE_ENABLED: compliance ? "1" : "0",
217
+ SPECKY_COMPLIANCE_FRAMEWORKS: compliance?.frameworks?.join(",") ?? "",
218
+ SPECKY_DEV_ENV_ENABLED: development ? "1" : "0",
219
+ SPECKY_DEV_LANGUAGE: development?.language ?? "",
220
+ SPECKY_IAC_ENABLED: iac ? "1" : "0",
221
+ SPECKY_IAC_PROVIDER: iac?.provider ?? "",
222
+ SPECKY_IAC_CLOUD: iac?.cloud ?? "",
223
+ };
224
+ for (const [key, value] of Object.entries(values)) console.log(`${key}=${shellQuote(value)}`);
225
+ }
226
+
227
+ const command = process.argv[2] ?? "shell";
228
+ const context = resolveContext();
229
+ if (command === "json") {
230
+ console.log(JSON.stringify(context));
231
+ } else if (command === "shell") {
232
+ printShell(context);
233
+ } else {
234
+ fail(`unknown command ${command}`);
235
+ }
@@ -5,14 +5,17 @@
5
5
  # Paper: arXiv:2602.20478, arXiv:2603.22106
6
6
 
7
7
  set -euo pipefail
8
+ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
9
+ . "$SCRIPT_DIR/specky-contract-context.bash"
10
+ specky_load_contract_context || exit $?
11
+ [ "${SPECKY_CONTEXT_ACTIVE:-0}" = "1" ] || exit 0
8
12
 
9
- LATEST=$(ls -td .specs/*/ 2>/dev/null | head -1 || true)
10
- [ -z "$LATEST" ] && exit 0
13
+ LATEST="$SPECKY_FEATURE_DIR"
11
14
  CONST="$LATEST/CONSTITUTION.md"
12
15
  SPEC="$LATEST/SPECIFICATION.md"
13
16
  [ -f "$CONST" ] && [ -f "$SPEC" ] || exit 0
14
17
 
15
- echo "🧭 Drift Monitor: $(basename "$LATEST")"
18
+ echo "🧭 Drift Monitor: ${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME} ($SPECKY_CONTRACT_ID)"
16
19
 
17
20
  # Simple drift: compare key terms in constitution vs spec (POSIX ERE for portability)
18
21
  CONST_TERMS=$(grep -oE '[A-Z][a-z]+([[:space:]][A-Z][a-z]+)+' "$CONST" 2>/dev/null | sort -u | wc -l)
@@ -10,9 +10,12 @@
10
10
  # plain `set -eu` instead of bash-only `set -o pipefail`.
11
11
 
12
12
  set -eu
13
+ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
14
+ . "$SCRIPT_DIR/specky-contract-context.bash"
15
+ specky_load_contract_context || exit $?
16
+ [ "${SPECKY_CONTEXT_ACTIVE:-0}" = "1" ] || exit 0
13
17
 
14
- LATEST=$(ls -td .specs/*/ 2>/dev/null | head -1 || true)
15
- [ -z "$LATEST" ] && exit 0
18
+ LATEST="$SPECKY_FEATURE_DIR"
16
19
  SPEC="$LATEST/SPECIFICATION.md"
17
20
 
18
21
  if [ ! -f "$SPEC" ] || [ ! -r "$SPEC" ]; then
@@ -4,13 +4,15 @@
4
4
  # Summarizes artifact and prompts for LGTM before phase advancement
5
5
 
6
6
  set -euo pipefail
7
+ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
8
+ . "$SCRIPT_DIR/specky-contract-context.bash"
9
+ specky_load_contract_context || exit $?
10
+ [ "${SPECKY_CONTEXT_ACTIVE:-0}" = "1" ] || exit 0
7
11
 
8
12
  TOOL="${SDD_TOOL_NAME:-unknown}"
9
- LATEST=$(ls -td .specs/*/ 2>/dev/null | head -1 || true)
13
+ LATEST="$SPECKY_FEATURE_DIR"
10
14
 
11
- [ -z "$LATEST" ] && exit 0
12
-
13
- FEATURE=$(basename "$LATEST")
15
+ FEATURE="${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME}"
14
16
 
15
17
  print_summary() {
16
18
  local file="$1" label="$2"
@@ -29,25 +31,25 @@ case "$TOOL" in
29
31
  sdd_write_spec|sdd_turnkey_spec|sdd_figma_to_spec)
30
32
  print_summary "SPECIFICATION.md" "SPECIFICATION.md"
31
33
  echo ""
32
- echo "⏸ LGTM GATEPhase 3 (Specify)"
34
+ echo "⏸ LGTM REVIEWSpecify ($SPECKY_CONTRACT_ID)"
33
35
  echo " Review SPECIFICATION.md above. Are the requirements correct?"
34
- echo " Reply 'LGTM' to proceed to Phase 4 (Design)."
36
+ echo " If workspace policy requires LGTM, pass lgtm:true to sdd_advance_phase."
35
37
  echo " Reply with feedback to revise."
36
38
  ;;
37
39
  sdd_write_design)
38
40
  print_summary "DESIGN.md" "DESIGN.md"
39
41
  echo ""
40
- echo "⏸ LGTM GATEPhase 4 (Design)"
42
+ echo "⏸ LGTM REVIEWDesign ($SPECKY_CONTRACT_ID)"
41
43
  echo " Review DESIGN.md above. Is the architecture sound?"
42
- echo " Reply 'LGTM' to proceed to Phase 5 (Tasks)."
44
+ echo " If workspace policy requires LGTM, pass lgtm:true to sdd_advance_phase."
43
45
  echo " Reply with feedback to revise."
44
46
  ;;
45
47
  sdd_write_tasks)
46
48
  print_summary "TASKS.md" "TASKS.md"
47
49
  echo ""
48
- echo "⏸ LGTM GATEPhase 5 (Tasks)"
50
+ echo "⏸ LGTM REVIEWTasks ($SPECKY_CONTRACT_ID)"
49
51
  echo " Review TASKS.md above. Is the task breakdown complete?"
50
- echo " Reply 'LGTM' to proceed to Phase 6 (Implement)."
52
+ echo " If workspace policy requires LGTM, pass lgtm:true to sdd_advance_phase."
51
53
  echo " Reply with feedback to revise."
52
54
  ;;
53
55
  *)
@@ -5,9 +5,12 @@
5
5
  # Paper: arXiv:2507.09089 — AI productivity paradox
6
6
 
7
7
  set -euo pipefail
8
+ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
9
+ . "$SCRIPT_DIR/specky-contract-context.bash"
10
+ specky_load_contract_context || exit $?
11
+ [ "${SPECKY_CONTEXT_ACTIVE:-0}" = "1" ] || exit 0
8
12
 
9
- LATEST=$(ls -td .specs/*/ 2>/dev/null | head -1 || true)
10
- [ -z "$LATEST" ] && exit 0
13
+ LATEST="$SPECKY_FEATURE_DIR"
11
14
 
12
15
  # Check if analysis is done but metrics not generated
13
16
  if [ -f "$LATEST/ANALYSIS.md" ] && [ ! -f "$LATEST/specky-metrics-dashboard.html" ]; then
@@ -4,14 +4,16 @@
4
4
  # Ensures phase artifacts exist and meet minimum quality after creation
5
5
 
6
6
  set -euo pipefail
7
+ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
8
+ source "$SCRIPT_DIR/specky-contract-context.bash"
7
9
 
8
10
  TOOL="${SDD_TOOL_NAME:-unknown}"
9
- LATEST=$(ls -td .specs/*/ 2>/dev/null | head -1 || true)
10
11
  FAILS=0
11
12
 
12
- [ -z "$LATEST" ] && exit 0
13
+ specky_require_feature_context || exit $?
14
+ LATEST="$SPECKY_FEATURE_DIR"
13
15
 
14
- FEATURE=$(basename "$LATEST")
16
+ FEATURE="${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME}"
15
17
  echo "🚦 Phase Gate — $FEATURE — after $TOOL"
16
18
 
17
19
  check_created() {
@@ -43,28 +45,35 @@ case "$TOOL" in
43
45
  sdd_init)
44
46
  check_created "CONSTITUTION.md" "CONSTITUTION.md"
45
47
  check_created ".sdd-state.json" ".sdd-state.json"
48
+ check_created ".sdd-state.json.sig" ".sdd-state.json.sig"
46
49
  ;;
47
50
  sdd_write_spec|sdd_turnkey_spec|sdd_figma_to_spec)
48
51
  check_created "SPECIFICATION.md" "SPECIFICATION.md"
49
- check_has_content "SPECIFICATION.md" "REQ-[A-Z]+-[0-9]+" "REQ-IDs" 3
50
- check_has_content "SPECIFICATION.md" "(shall|When .* shall|While .* shall|Where .* shall|If .* then)" "EARS patterns" 3
52
+ check_has_content "SPECIFICATION.md" "REQ-[A-Z]+-[0-9]+" "REQ-IDs" 1
53
+ check_has_content "SPECIFICATION.md" "(shall|When .* shall|While .* shall|Where .* shall|If .* then)" "EARS patterns" 1
51
54
  ;;
52
55
  sdd_write_design)
53
56
  check_created "DESIGN.md" "DESIGN.md"
54
- check_has_content "DESIGN.md" "##" "Sections" 3
57
+ check_has_content "DESIGN.md" "## 13\. Workload-Specific Design Contract" "Workload design contract" 1
58
+ check_has_content "DESIGN.md" "REQ-[A-Z]+-[0-9]+" "REQ-ID traceability" 1
59
+ ;;
60
+ sdd_generate_all_diagrams)
61
+ check_created "DIAGRAMS.md" "DIAGRAMS.md"
62
+ REQUIRED_DIAGRAMS=$(node -e 'const s=JSON.parse(require("fs").readFileSync(process.argv[1],"utf8")); console.log(s.contract.required_diagrams.length)' "$SPECKY_STATE_FILE")
63
+ check_has_content "DIAGRAMS.md" '^```mermaid' "Contracted Mermaid diagrams" "$REQUIRED_DIAGRAMS"
55
64
  ;;
56
65
  sdd_write_tasks)
57
66
  check_created "TASKS.md" "TASKS.md"
58
67
  check_has_content "TASKS.md" "REQ-[A-Z]+-[0-9]+" "REQ-ID traceability" 1
59
- check_has_content "TASKS.md" "T-?[0-9]{3}" "Task IDs" 3
68
+ check_has_content "TASKS.md" "T-[0-9]{3}" "Task IDs" 1
60
69
  ;;
61
70
  sdd_verify_tests|sdd_verify_tasks)
62
71
  check_created "VERIFICATION.md" "VERIFICATION.md"
63
- check_has_content "VERIFICATION.md" "pass_rate" "Pass rate metric" 1
72
+ check_has_content "VERIFICATION.md" "Pass Rate|pass_rate" "Pass rate metric" 1
64
73
  ;;
65
74
  sdd_run_analysis)
66
75
  check_created "ANALYSIS.md" "ANALYSIS.md"
67
- check_has_content "ANALYSIS.md" "gate_decision" "Gate decision" 1
76
+ check_has_content "ANALYSIS.md" "APPROVE|CHANGES_NEEDED|BLOCK" "Gate decision" 1
68
77
  ;;
69
78
  sdd_cross_analyze)
70
79
  check_created "CROSS_ANALYSIS.md" "CROSS_ANALYSIS.md"