specky-sdd 3.10.2 → 3.11.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 (322) hide show
  1. package/.apm/agents/specky-design-architect.agent.md +8 -28
  2. package/.apm/agents/specky-implementer.agent.md +15 -27
  3. package/.apm/agents/specky-onboarding.agent.md +8 -49
  4. package/.apm/agents/specky-orchestrator.agent.md +12 -37
  5. package/.apm/agents/specky-quality-reviewer.agent.md +9 -30
  6. package/.apm/agents/specky-release-engineer.agent.md +8 -30
  7. package/.apm/agents/specky-requirements-engineer.agent.md +1 -1
  8. package/.apm/agents/specky-research-analyst.agent.md +1 -1
  9. package/.apm/agents/specky-sdd-clarify.agent.md +1 -1
  10. package/.apm/agents/specky-sdd-init.agent.md +8 -19
  11. package/.apm/agents/specky-spec-engineer.agent.md +8 -30
  12. package/.apm/agents/specky-task-planner.agent.md +7 -26
  13. package/.apm/agents/specky-test-verifier.agent.md +7 -17
  14. package/.apm/hooks/scripts/specky-artifact-validator.sh +14 -10
  15. package/.apm/hooks/scripts/specky-auto-checkpoint.sh +9 -4
  16. package/.apm/hooks/scripts/specky-branch-validator.sh +29 -116
  17. package/.apm/hooks/scripts/specky-cognitive-debt-alert.sh +6 -3
  18. package/.apm/hooks/scripts/specky-contract-context.bash +24 -0
  19. package/.apm/hooks/scripts/specky-contract-context.mjs +219 -0
  20. package/.apm/hooks/scripts/specky-drift-monitor.sh +6 -3
  21. package/.apm/hooks/scripts/specky-ears-validator.sh +5 -2
  22. package/.apm/hooks/scripts/specky-lgtm-gate.sh +12 -10
  23. package/.apm/hooks/scripts/specky-metrics-dashboard.sh +5 -2
  24. package/.apm/hooks/scripts/specky-phase-gate.sh +18 -9
  25. package/.apm/hooks/scripts/specky-pipeline-guard.sh +19 -26
  26. package/.apm/hooks/scripts/specky-release-gate.sh +38 -46
  27. package/.apm/hooks/scripts/specky-security-scan.sh +53 -36
  28. package/.apm/hooks/scripts/specky-session-banner.sh +22 -74
  29. package/.apm/hooks/scripts/specky-spec-quality.sh +7 -4
  30. package/.apm/hooks/scripts/specky-spec-sync.sh +12 -11
  31. package/.apm/hooks/scripts/specky-task-tracer.sh +5 -2
  32. package/.apm/hooks/specky-run.sh +3 -0
  33. package/.apm/instructions/claude-instructions.instructions.md +3 -3
  34. package/.apm/instructions/copilot-instructions.instructions.md +3 -3
  35. package/.apm/instructions/cursor-instructions.instructions.md +3 -3
  36. package/.apm/instructions/opencode-instructions.instructions.md +2 -2
  37. package/.apm/prompts/specky-brownfield.prompt.md +8 -5
  38. package/.apm/prompts/specky-greenfield.prompt.md +7 -5
  39. package/.apm/prompts/specky-implement.prompt.md +1 -1
  40. package/.apm/prompts/specky-orchestrate.prompt.md +1 -1
  41. package/.apm/skills/specky-design-architect/SKILL.md +39 -16
  42. package/.apm/skills/specky-implementer/SKILL.md +46 -158
  43. package/.apm/skills/specky-onboarding/SKILL.md +50 -156
  44. package/.apm/skills/specky-orchestrator/SKILL.md +28 -26
  45. package/.apm/skills/specky-quality-reviewer/SKILL.md +38 -23
  46. package/.apm/skills/specky-release-engineer/SKILL.md +38 -270
  47. package/.apm/skills/specky-research-analyst/SKILL.md +1 -1
  48. package/.apm/skills/specky-sdd-init/SKILL.md +61 -23
  49. package/.apm/skills/specky-sdd-pipeline/SKILL.md +36 -216
  50. package/.apm/skills/specky-spec-engineer/SKILL.md +40 -17
  51. package/.apm/skills/specky-task-planner/SKILL.md +31 -12
  52. package/.apm/skills/specky-test-verifier/SKILL.md +23 -202
  53. package/CHANGELOG.md +39 -0
  54. package/README.md +49 -47
  55. package/SECURITY.md +5 -1
  56. package/apm-policy.yml +2 -0
  57. package/apm.lock.yaml +55 -53
  58. package/apm.yml +3 -3
  59. package/config.yml +32 -53
  60. package/dist/cli/commands/doctor.d.ts.map +1 -1
  61. package/dist/cli/commands/doctor.js +106 -20
  62. package/dist/cli/commands/doctor.js.map +1 -1
  63. package/dist/cli/commands/init.d.ts +2 -0
  64. package/dist/cli/commands/init.d.ts.map +1 -1
  65. package/dist/cli/commands/init.js +105 -7
  66. package/dist/cli/commands/init.js.map +1 -1
  67. package/dist/cli/commands/migrate-contracts.d.ts +15 -0
  68. package/dist/cli/commands/migrate-contracts.d.ts.map +1 -0
  69. package/dist/cli/commands/migrate-contracts.js +311 -0
  70. package/dist/cli/commands/migrate-contracts.js.map +1 -0
  71. package/dist/cli/commands/status.d.ts.map +1 -1
  72. package/dist/cli/commands/status.js +63 -48
  73. package/dist/cli/commands/status.js.map +1 -1
  74. package/dist/cli/index.js +82 -27
  75. package/dist/cli/index.js.map +1 -1
  76. package/dist/cli/lib/apm/policy.d.ts +1 -0
  77. package/dist/cli/lib/apm/policy.d.ts.map +1 -1
  78. package/dist/cli/lib/apm/policy.js +15 -0
  79. package/dist/cli/lib/apm/policy.js.map +1 -1
  80. package/dist/cli/lib/asset-copier.d.ts +1 -0
  81. package/dist/cli/lib/asset-copier.d.ts.map +1 -1
  82. package/dist/cli/lib/asset-copier.js +4 -4
  83. package/dist/cli/lib/asset-copier.js.map +1 -1
  84. package/dist/cli/lib/cursor-plugin-writer.d.ts.map +1 -1
  85. package/dist/cli/lib/cursor-plugin-writer.js +34 -9
  86. package/dist/cli/lib/cursor-plugin-writer.js.map +1 -1
  87. package/dist/cli/lib/harness/compilers/claude.js +3 -3
  88. package/dist/cli/lib/harness/compilers/claude.js.map +1 -1
  89. package/dist/cli/lib/harness/compilers/common.d.ts +10 -1
  90. package/dist/cli/lib/harness/compilers/common.d.ts.map +1 -1
  91. package/dist/cli/lib/harness/compilers/common.js +71 -8
  92. package/dist/cli/lib/harness/compilers/common.js.map +1 -1
  93. package/dist/cli/lib/harness/compilers/copilot.js +3 -3
  94. package/dist/cli/lib/harness/compilers/copilot.js.map +1 -1
  95. package/dist/cli/lib/harness/compilers/cursor.js +3 -3
  96. package/dist/cli/lib/harness/compilers/cursor.js.map +1 -1
  97. package/dist/cli/lib/harness/compilers/opencode.js +3 -3
  98. package/dist/cli/lib/harness/compilers/opencode.js.map +1 -1
  99. package/dist/cli/lib/harness/tool-map.d.ts +8 -1
  100. package/dist/cli/lib/harness/tool-map.d.ts.map +1 -1
  101. package/dist/cli/lib/harness/tool-map.js +74 -0
  102. package/dist/cli/lib/harness/tool-map.js.map +1 -1
  103. package/dist/cli/lib/harness/types.d.ts +11 -1
  104. package/dist/cli/lib/harness/types.d.ts.map +1 -1
  105. package/dist/cli/lib/mcp-writer.d.ts +2 -1
  106. package/dist/cli/lib/mcp-writer.d.ts.map +1 -1
  107. package/dist/cli/lib/mcp-writer.js +13 -5
  108. package/dist/cli/lib/mcp-writer.js.map +1 -1
  109. package/dist/cli/lib/settings-merger.d.ts +15 -0
  110. package/dist/cli/lib/settings-merger.d.ts.map +1 -1
  111. package/dist/cli/lib/settings-merger.js +66 -1
  112. package/dist/cli/lib/settings-merger.js.map +1 -1
  113. package/dist/config.d.ts +110 -42
  114. package/dist/config.d.ts.map +1 -1
  115. package/dist/config.js +129 -140
  116. package/dist/config.js.map +1 -1
  117. package/dist/constants.d.ts +1 -1
  118. package/dist/constants.d.ts.map +1 -1
  119. package/dist/contracts/pipeline-profiles.d.ts +61 -0
  120. package/dist/contracts/pipeline-profiles.d.ts.map +1 -0
  121. package/dist/contracts/pipeline-profiles.js +303 -0
  122. package/dist/contracts/pipeline-profiles.js.map +1 -0
  123. package/dist/contracts/tool-contracts.d.ts +449 -0
  124. package/dist/contracts/tool-contracts.d.ts.map +1 -0
  125. package/dist/contracts/tool-contracts.js +83 -0
  126. package/dist/contracts/tool-contracts.js.map +1 -0
  127. package/dist/contracts/use-case.d.ts +736 -0
  128. package/dist/contracts/use-case.d.ts.map +1 -0
  129. package/dist/contracts/use-case.js +352 -0
  130. package/dist/contracts/use-case.js.map +1 -0
  131. package/dist/index.js +7 -4
  132. package/dist/index.js.map +1 -1
  133. package/dist/schemas/common.d.ts +3 -3
  134. package/dist/schemas/common.d.ts.map +1 -1
  135. package/dist/schemas/common.js +1 -4
  136. package/dist/schemas/common.js.map +1 -1
  137. package/dist/schemas/context.d.ts +2 -2
  138. package/dist/schemas/environment.d.ts +6 -17
  139. package/dist/schemas/environment.d.ts.map +1 -1
  140. package/dist/schemas/environment.js +1 -28
  141. package/dist/schemas/environment.js.map +1 -1
  142. package/dist/schemas/feature-content.d.ts +116 -0
  143. package/dist/schemas/feature-content.d.ts.map +1 -0
  144. package/dist/schemas/feature-content.js +65 -0
  145. package/dist/schemas/feature-content.js.map +1 -0
  146. package/dist/schemas/infrastructure.d.ts +6 -28
  147. package/dist/schemas/infrastructure.d.ts.map +1 -1
  148. package/dist/schemas/infrastructure.js +1 -30
  149. package/dist/schemas/infrastructure.js.map +1 -1
  150. package/dist/schemas/input.d.ts +412 -8
  151. package/dist/schemas/input.d.ts.map +1 -1
  152. package/dist/schemas/input.js +6 -7
  153. package/dist/schemas/input.js.map +1 -1
  154. package/dist/schemas/integration.d.ts +22 -28
  155. package/dist/schemas/integration.d.ts.map +1 -1
  156. package/dist/schemas/integration.js +11 -47
  157. package/dist/schemas/integration.js.map +1 -1
  158. package/dist/schemas/metrics.d.ts +3 -2
  159. package/dist/schemas/metrics.d.ts.map +1 -1
  160. package/dist/schemas/metrics.js +2 -1
  161. package/dist/schemas/metrics.js.map +1 -1
  162. package/dist/schemas/pbt.d.ts +2 -7
  163. package/dist/schemas/pbt.d.ts.map +1 -1
  164. package/dist/schemas/pbt.js +1 -9
  165. package/dist/schemas/pbt.js.map +1 -1
  166. package/dist/schemas/pipeline.d.ts +282 -35
  167. package/dist/schemas/pipeline.d.ts.map +1 -1
  168. package/dist/schemas/pipeline.js +29 -15
  169. package/dist/schemas/pipeline.js.map +1 -1
  170. package/dist/schemas/quality.d.ts +15 -19
  171. package/dist/schemas/quality.d.ts.map +1 -1
  172. package/dist/schemas/quality.js +6 -3
  173. package/dist/schemas/quality.js.map +1 -1
  174. package/dist/schemas/routing.d.ts +2 -2
  175. package/dist/schemas/routing.d.ts.map +1 -1
  176. package/dist/schemas/routing.js +2 -4
  177. package/dist/schemas/routing.js.map +1 -1
  178. package/dist/schemas/testing.d.ts +4 -13
  179. package/dist/schemas/testing.d.ts.map +1 -1
  180. package/dist/schemas/testing.js +2 -10
  181. package/dist/schemas/testing.js.map +1 -1
  182. package/dist/schemas/transcript.d.ts +648 -10
  183. package/dist/schemas/transcript.d.ts.map +1 -1
  184. package/dist/schemas/transcript.js +25 -12
  185. package/dist/schemas/transcript.js.map +1 -1
  186. package/dist/schemas/utility.d.ts +28 -15
  187. package/dist/schemas/utility.d.ts.map +1 -1
  188. package/dist/schemas/utility.js +23 -14
  189. package/dist/schemas/utility.js.map +1 -1
  190. package/dist/schemas/visualization.d.ts +66 -15
  191. package/dist/schemas/visualization.d.ts.map +1 -1
  192. package/dist/schemas/visualization.js +36 -12
  193. package/dist/schemas/visualization.js.map +1 -1
  194. package/dist/services/codebase-scanner.d.ts +1 -1
  195. package/dist/services/codebase-scanner.d.ts.map +1 -1
  196. package/dist/services/codebase-scanner.js +2 -2
  197. package/dist/services/codebase-scanner.js.map +1 -1
  198. package/dist/services/compliance-engine.d.ts +3 -2
  199. package/dist/services/compliance-engine.d.ts.map +1 -1
  200. package/dist/services/compliance-engine.js +34 -21
  201. package/dist/services/compliance-engine.js.map +1 -1
  202. package/dist/services/diagram-generator.d.ts +4 -96
  203. package/dist/services/diagram-generator.d.ts.map +1 -1
  204. package/dist/services/diagram-generator.js +18 -1051
  205. package/dist/services/diagram-generator.js.map +1 -1
  206. package/dist/services/doc-generator.d.ts +19 -52
  207. package/dist/services/doc-generator.d.ts.map +1 -1
  208. package/dist/services/doc-generator.js +389 -524
  209. package/dist/services/doc-generator.js.map +1 -1
  210. package/dist/services/execution-context.d.ts +32 -0
  211. package/dist/services/execution-context.d.ts.map +1 -0
  212. package/dist/services/execution-context.js +120 -0
  213. package/dist/services/execution-context.js.map +1 -0
  214. package/dist/services/file-manager.d.ts +16 -4
  215. package/dist/services/file-manager.d.ts.map +1 -1
  216. package/dist/services/file-manager.js +81 -5
  217. package/dist/services/file-manager.js.map +1 -1
  218. package/dist/services/iac-generator.d.ts +9 -10
  219. package/dist/services/iac-generator.d.ts.map +1 -1
  220. package/dist/services/iac-generator.js +36 -99
  221. package/dist/services/iac-generator.js.map +1 -1
  222. package/dist/services/methodology.js +1 -1
  223. package/dist/services/methodology.js.map +1 -1
  224. package/dist/services/metrics-generator.d.ts +1 -1
  225. package/dist/services/metrics-generator.d.ts.map +1 -1
  226. package/dist/services/metrics-generator.js +2 -2
  227. package/dist/services/metrics-generator.js.map +1 -1
  228. package/dist/services/pbt-generator.d.ts +10 -31
  229. package/dist/services/pbt-generator.d.ts.map +1 -1
  230. package/dist/services/pbt-generator.js +43 -515
  231. package/dist/services/pbt-generator.js.map +1 -1
  232. package/dist/services/state-machine.d.ts +22 -16
  233. package/dist/services/state-machine.d.ts.map +1 -1
  234. package/dist/services/state-machine.js +176 -179
  235. package/dist/services/state-machine.js.map +1 -1
  236. package/dist/services/template-engine.d.ts +11 -5
  237. package/dist/services/template-engine.d.ts.map +1 -1
  238. package/dist/services/template-engine.js +48 -21
  239. package/dist/services/template-engine.js.map +1 -1
  240. package/dist/services/test-generator.d.ts +11 -7
  241. package/dist/services/test-generator.d.ts.map +1 -1
  242. package/dist/services/test-generator.js +45 -54
  243. package/dist/services/test-generator.js.map +1 -1
  244. package/dist/templates/design.md +6 -0
  245. package/dist/tools/analysis.d.ts.map +1 -1
  246. package/dist/tools/analysis.js +8 -9
  247. package/dist/tools/analysis.js.map +1 -1
  248. package/dist/tools/checkpoint.d.ts.map +1 -1
  249. package/dist/tools/checkpoint.js +43 -46
  250. package/dist/tools/checkpoint.js.map +1 -1
  251. package/dist/tools/context.d.ts.map +1 -1
  252. package/dist/tools/context.js +5 -7
  253. package/dist/tools/context.js.map +1 -1
  254. package/dist/tools/documentation.d.ts +1 -4
  255. package/dist/tools/documentation.d.ts.map +1 -1
  256. package/dist/tools/documentation.js +112 -193
  257. package/dist/tools/documentation.js.map +1 -1
  258. package/dist/tools/environment.d.ts +1 -1
  259. package/dist/tools/environment.d.ts.map +1 -1
  260. package/dist/tools/environment.js +58 -99
  261. package/dist/tools/environment.js.map +1 -1
  262. package/dist/tools/infrastructure.d.ts.map +1 -1
  263. package/dist/tools/infrastructure.js +36 -38
  264. package/dist/tools/infrastructure.js.map +1 -1
  265. package/dist/tools/input.d.ts.map +1 -1
  266. package/dist/tools/input.js +18 -11
  267. package/dist/tools/input.js.map +1 -1
  268. package/dist/tools/integration.d.ts.map +1 -1
  269. package/dist/tools/integration.js +64 -65
  270. package/dist/tools/integration.js.map +1 -1
  271. package/dist/tools/metrics.d.ts.map +1 -1
  272. package/dist/tools/metrics.js +18 -30
  273. package/dist/tools/metrics.js.map +1 -1
  274. package/dist/tools/pbt.d.ts.map +1 -1
  275. package/dist/tools/pbt.js +10 -12
  276. package/dist/tools/pbt.js.map +1 -1
  277. package/dist/tools/pipeline.d.ts.map +1 -1
  278. package/dist/tools/pipeline.js +156 -274
  279. package/dist/tools/pipeline.js.map +1 -1
  280. package/dist/tools/quality.d.ts.map +1 -1
  281. package/dist/tools/quality.js +58 -45
  282. package/dist/tools/quality.js.map +1 -1
  283. package/dist/tools/response-builder.d.ts.map +1 -1
  284. package/dist/tools/response-builder.js +12 -10
  285. package/dist/tools/response-builder.js.map +1 -1
  286. package/dist/tools/testing.d.ts.map +1 -1
  287. package/dist/tools/testing.js +28 -29
  288. package/dist/tools/testing.js.map +1 -1
  289. package/dist/tools/tool-enforcement.d.ts +2 -0
  290. package/dist/tools/tool-enforcement.d.ts.map +1 -1
  291. package/dist/tools/tool-enforcement.js +84 -59
  292. package/dist/tools/tool-enforcement.js.map +1 -1
  293. package/dist/tools/transcript.d.ts.map +1 -1
  294. package/dist/tools/transcript.js +304 -374
  295. package/dist/tools/transcript.js.map +1 -1
  296. package/dist/tools/turnkey.d.ts +1 -31
  297. package/dist/tools/turnkey.d.ts.map +1 -1
  298. package/dist/tools/turnkey.js +104 -488
  299. package/dist/tools/turnkey.js.map +1 -1
  300. package/dist/tools/utility.d.ts.map +1 -1
  301. package/dist/tools/utility.js +115 -134
  302. package/dist/tools/utility.js.map +1 -1
  303. package/dist/tools/visualization.d.ts +1 -25
  304. package/dist/tools/visualization.d.ts.map +1 -1
  305. package/dist/tools/visualization.js +187 -562
  306. package/dist/tools/visualization.js.map +1 -1
  307. package/dist/types.d.ts +21 -11
  308. package/dist/types.d.ts.map +1 -1
  309. package/dist/utils/artifact-metadata.d.ts +8 -0
  310. package/dist/utils/artifact-metadata.d.ts.map +1 -0
  311. package/dist/utils/artifact-metadata.js +10 -0
  312. package/dist/utils/artifact-metadata.js.map +1 -0
  313. package/dist/utils/requirement-partition.d.ts +8 -0
  314. package/dist/utils/requirement-partition.d.ts.map +1 -0
  315. package/dist/utils/requirement-partition.js +15 -0
  316. package/dist/utils/requirement-partition.js.map +1 -0
  317. package/package.json +11 -2
  318. package/templates/design.md +6 -0
  319. package/dist/utils/design-stubs.d.ts +0 -32
  320. package/dist/utils/design-stubs.d.ts.map +0 -1
  321. package/dist/utils/design-stubs.js +0 -103
  322. package/dist/utils/design-stubs.js.map +0 -1
@@ -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"
@@ -22,6 +22,8 @@
22
22
  # ALL work MUST flow through @specky-orchestrator.
23
23
 
24
24
  set -euo pipefail
25
+ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
26
+ source "$SCRIPT_DIR/specky-contract-context.bash"
25
27
 
26
28
  # ── rc.14: Copilot compatibility guard ───────────────────
27
29
  # VS Code Copilot reads .claude/settings.json hooks and treats SessionStart/
@@ -51,40 +53,31 @@ if [ "$SPECKY_GUARD_MODE" = "off" ]; then
51
53
  SPECKY_GUARD_MODE="advisory"
52
54
  fi
53
55
 
54
- # ── Check if pipeline is active ──────────────────────────
55
- LATEST=$(ls -td .specs/*/ 2>/dev/null | head -1 || true)
56
- if [ -z "$LATEST" ]; then
57
- exit 0
58
- fi
59
-
60
- STATE="$LATEST/.sdd-state.json"
61
- if [ ! -f "$STATE" ]; then
62
- exit 0
63
- fi
64
-
65
- FEATURE=$(basename "$LATEST")
66
-
67
- # Try to read current phase (optional — requires jq)
68
- PHASE="?"
69
- if command -v jq >/dev/null 2>&1; then
70
- PHASE=$(jq -r '.current_phase // "?"' "$STATE" 2>/dev/null || echo "?")
56
+ # Buffer stdin once; both the context resolver and prompt parser consume this JSON.
57
+ if [ -z "${SDD_HOOK_INPUT:-}" ] && [ ! -t 0 ]; then
58
+ SDD_HOOK_INPUT=$(cat 2>/dev/null || true)
59
+ export SDD_HOOK_INPUT
71
60
  fi
72
61
 
73
62
  # ── Extract user prompt ──────────────────────────────────
74
- # Claude Code sends the prompt as JSON on stdin: {"prompt": "..."}
75
- # Copilot uses $CLAUDE_USER_PROMPT. Fall back to empty.
76
- PROMPT=""
77
- if [ -n "${CLAUDE_USER_PROMPT:-}" ]; then
78
- PROMPT="$CLAUDE_USER_PROMPT"
79
- elif [ ! -t 0 ]; then
80
- # Read from stdin non-blocking
63
+ PROMPT="${CLAUDE_USER_PROMPT:-}"
64
+ if [ -z "$PROMPT" ] && [ -n "${SDD_HOOK_INPUT:-}" ]; then
81
65
  if command -v jq >/dev/null 2>&1; then
82
- PROMPT=$(jq -r '.prompt // .user_prompt // ""' 2>/dev/null || cat || true)
66
+ PROMPT=$(printf '%s' "$SDD_HOOK_INPUT" | jq -r '.prompt // .user_prompt // ""' 2>/dev/null || true)
83
67
  else
84
- PROMPT=$(cat 2>/dev/null || true)
68
+ PROMPT="$SDD_HOOK_INPUT"
85
69
  fi
86
70
  fi
87
71
 
72
+ # ── Resolve explicit pipeline context ───────────────────
73
+ specky_load_contract_context || exit $?
74
+ if [ "${SPECKY_CONTEXT_ACTIVE:-0}" != "1" ]; then
75
+ exit 0
76
+ fi
77
+ FEATURE="${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME}"
78
+ PHASE="$SPECKY_PHASE"
79
+ STATE="$SPECKY_STATE_FILE"
80
+
88
81
  # Lowercase for matching
89
82
  PROMPT_LC=$(echo "$PROMPT" | tr '[:upper:]' '[:lower:]' 2>/dev/null || true)
90
83
 
@@ -1,62 +1,54 @@
1
- #!/bin/bash
2
- # specky-release-gate.sh — Verify VERIFICATION.md + 90% pass rate before PR
3
- # Target: Claude Code (.claude/hooks/)
4
- # Type: BLOCKING (exit 2) | Trigger: before sdd_create_pr | Phase: 9
5
- # Paper: arXiv:2601.03878 — human-in-loop gate
1
+ #!/usr/bin/env bash
2
+ # specky-release-gate.sh — Verify persisted release and TDD policy before PR payload generation.
3
+ # Type: BLOCKING (exit 2) | Trigger: before release operations.
6
4
 
7
5
  set -euo pipefail
8
- FAILS=0
6
+ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
7
+ source "$SCRIPT_DIR/specky-contract-context.bash"
8
+ specky_require_feature_context || exit $?
9
9
 
10
- echo "🚦 Release Gate Check"
10
+ FAILS=0
11
+ echo "🚦 Release Gate — ${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME}"
11
12
 
12
- # Branch validation (advisory warning only)
13
- CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
14
- if [[ "$CURRENT_BRANCH" == "main" ]]; then
15
- echo "⚠️ WARNING: You are on 'main'. Spec work should be on spec/NNN-* branches."
16
- echo " Expected flow: spec/NNN-* → develop → stage → main"
17
- elif [[ "$CURRENT_BRANCH" == "develop" ]] || [[ "$CURRENT_BRANCH" == "stage" ]]; then
18
- echo "ℹ️ Branch: $CURRENT_BRANCH (integration/release branch)"
19
- elif [[ "$CURRENT_BRANCH" == spec/* ]]; then
20
- echo "ℹ️ Branch: $CURRENT_BRANCH (spec branch → PR targets develop)"
21
- else
22
- echo "⚠️ WARNING: Branch '$CURRENT_BRANCH' does not follow naming convention."
23
- echo " Expected: spec/NNN-feature-name, develop, stage, or main"
13
+ if [ "${SPECKY_RELEASE_ENABLED:-0}" != "1" ]; then
14
+ echo "🚫 Release capability is not enabled by $SPECKY_CONTRACT_ID"
15
+ FAILS=$((FAILS+1))
24
16
  fi
25
- echo ""
26
-
27
- # Find active feature
28
- LATEST=$(ls -td .specs/*/ 2>/dev/null | head -1 || true)
29
- [ -z "$LATEST" ] && { echo "❌ No .specs/ directory found"; exit 2; }
30
-
31
- # VERIFICATION.md must exist
32
- if [ ! -f "$LATEST/VERIFICATION.md" ]; then
33
- echo "🚫 Missing VERIFICATION.md in $LATEST — run /sdd:test first"
17
+ if [ "${SPECKY_GATE_DECISION:-}" != "APPROVE" ]; then
18
+ echo "🚫 Analysis gate is '${SPECKY_GATE_DECISION:-none}', expected APPROVE"
34
19
  FAILS=$((FAILS+1))
35
20
  fi
36
-
37
- # CHECKLIST.md must exist
38
- if [ ! -f "$LATEST/CHECKLIST.md" ]; then
39
- echo "🚫 Missing CHECKLIST.md in $LATEST — run /sdd:implement first"
21
+ if [ ! -f "$SPECKY_FEATURE_DIR/ANALYSIS.md" ]; then
22
+ echo "🚫 Missing ANALYSIS.md"
23
+ FAILS=$((FAILS+1))
24
+ fi
25
+ if [ ! -f "$SPECKY_FEATURE_DIR/VERIFICATION.md" ]; then
26
+ echo "🚫 Missing VERIFICATION.md"
40
27
  FAILS=$((FAILS+1))
41
28
  fi
42
29
 
43
- # Pass rate >= 90%
44
- if [ -f "$LATEST/VERIFICATION.md" ]; then
45
- RATE=$(grep -oE 'pass_rate:[[:space:]]*"?([0-9]+(\.[0-9]+)?)"?' "$LATEST/VERIFICATION.md" | grep -oE '[0-9.]+' | head -1 || echo "0")
46
- if [ -n "$RATE" ]; then
47
- PASS=$(echo "$RATE >= 90" | bc -l 2>/dev/null || echo "0")
48
- if [ "$PASS" -eq 0 ]; then
49
- echo "🚫 Test pass rate ${RATE}% < 90% fix failing tests"
50
- FAILS=$((FAILS+1))
51
- fi
30
+ if [ "${SPECKY_TDD_ENABLED:-0}" = "1" ] && [ -f "$SPECKY_FEATURE_DIR/VERIFICATION.md" ]; then
31
+ RATE=$(grep -m1 -oE '\*\*Pass Rate\*\*:[[:space:]]*[0-9]+([.][0-9]+)?%' "$SPECKY_FEATURE_DIR/VERIFICATION.md" | grep -oE '[0-9]+([.][0-9]+)?' || true)
32
+ if [ -z "$RATE" ]; then
33
+ echo "🚫 VERIFICATION.md does not contain a parseable Pass Rate"
34
+ FAILS=$((FAILS+1))
35
+ elif ! node -e 'process.exit(Number(process.argv[1]) >= Number(process.argv[2]) ? 0 : 1)' "$RATE" "$SPECKY_TDD_THRESHOLD"; then
36
+ echo "🚫 Verification pass rate ${RATE}% is below contracted threshold ${SPECKY_TDD_THRESHOLD}%"
37
+ FAILS=$((FAILS+1))
38
+ else
39
+ echo " ✅ Verification pass rate ${RATE}% meets ${SPECKY_TDD_THRESHOLD}%"
52
40
  fi
53
41
  fi
54
42
 
43
+ EXPECTED_BRANCH="${SPECKY_BRANCH_PREFIX}${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME}"
44
+ CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)
45
+ if [ -n "$CURRENT_BRANCH" ] && [ "$CURRENT_BRANCH" != "$EXPECTED_BRANCH" ]; then
46
+ echo "⚠️ Current branch '$CURRENT_BRANCH' differs from persisted release head '$EXPECTED_BRANCH'"
47
+ fi
48
+
55
49
  if [ "$FAILS" -gt 0 ]; then
56
- echo ""
57
- echo "❌ Release gate FAILED ($FAILS issues). Cannot create PR."
58
- exit 2 # BLOCKING
50
+ echo "❌ Release gate failed with $FAILS issue(s)."
51
+ exit 2
59
52
  fi
60
53
 
61
- echo "✅ Release gate passed."
62
- exit 0
54
+ echo "✅ Release gate passed for base '$SPECKY_BASE_BRANCH'."
@@ -1,55 +1,72 @@
1
- #!/bin/bash
2
- # specky-security-scan.sh — OWASP + secrets scan
3
- # Target: Claude Code (.claude/hooks/)
4
- # Type: BLOCKING (exit 2) | Trigger: Stop | Phase: 9
5
- # Paper: arXiv:2503.23278 — security enforcement
6
- #
7
- # Claude Code settings.json:
8
- # "hooks": { "Stop": ["bash .claude/hooks/specky-security-scan.sh"] }
1
+ #!/usr/bin/env bash
2
+ # specky-security-scan.sh — Contract-aware release security checks.
3
+ # Type: BLOCKING (exit 2) | Trigger: before release operations.
9
4
 
10
5
  set -euo pipefail
11
- FAILS=0
6
+ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
7
+ source "$SCRIPT_DIR/specky-contract-context.bash"
8
+ specky_require_feature_context || exit $?
9
+
10
+ if [ "${SPECKY_RELEASE_ENABLED:-0}" != "1" ]; then
11
+ echo "🚫 Security scan requires the release capability." >&2
12
+ exit 2
13
+ fi
12
14
 
13
- echo "🔒 Security Scan"
15
+ FAILS=0
16
+ echo "🔒 Security Scan — ${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME} ($SPECKY_CONTRACT_ID)"
14
17
 
15
- # Hardcoded secrets
16
18
  PATTERNS='AKIA[0-9A-Z]{16}|sk-[a-zA-Z0-9]{48}|sk-ant-[a-zA-Z0-9-]{90}|ghp_[a-zA-Z0-9]{36}|gho_[a-zA-Z0-9]{36}|xox[bpors]-[a-zA-Z0-9-]+|sk_live_[a-zA-Z0-9]{24}'
17
- FOUND=$(grep -rnE "$PATTERNS" src/ tests/ test/ --include="*.ts" --include="*.js" --include="*.py" --include="*.json" --include="*.yml" --include="*.env" 2>/dev/null || true)
19
+ FOUND=$(git grep -nE "$PATTERNS" -- ':!*.lock' ':!.specs/**' 2>/dev/null || true)
18
20
  if [ -n "$FOUND" ]; then
19
- echo "🚫 HARDCODED SECRETS FOUND:"
21
+ echo "🚫 Hardcoded credential patterns found in tracked files:"
20
22
  echo "$FOUND" | head -10
21
23
  FAILS=$((FAILS+1))
22
24
  fi
23
25
 
24
- # .env in tracked files
25
- if git ls-files --error-unmatch .env .env.local .env.production 2>/dev/null; then
26
- echo "🚫 .env file tracked in git — add to .gitignore"
26
+ TRACKED_ENV=$(git ls-files '.env' '.env.*' 2>/dev/null || true)
27
+ if [ -n "$TRACKED_ENV" ]; then
28
+ echo "🚫 Environment secret files are tracked:"
29
+ echo "$TRACKED_ENV"
27
30
  FAILS=$((FAILS+1))
28
31
  fi
29
32
 
30
- # npm audit (if package.json exists)
31
- if [ -f "package.json" ] && command -v npm &>/dev/null; then
32
- AUDIT=$(npm audit --json 2>/dev/null | grep -o '"critical":[0-9]*' | head -1 || true)
33
- CRITICAL=$(echo "$AUDIT" | grep -oE '[0-9]+' || echo "0")
34
- if [ "$CRITICAL" -gt 0 ]; then
35
- echo "🚫 npm audit: $CRITICAL critical vulnerabilities"
36
- FAILS=$((FAILS+1))
37
- fi
38
- fi
33
+ case "${SPECKY_DEV_LANGUAGE:-}" in
34
+ TypeScript|JavaScript)
35
+ if [ -f package-lock.json ] && command -v npm >/dev/null 2>&1; then
36
+ AUDIT=$(npm audit --json 2>/dev/null || true)
37
+ CRITICAL=$(printf '%s' "$AUDIT" | node -e 'let x="";process.stdin.on("data",d=>x+=d).on("end",()=>{try{const j=JSON.parse(x);console.log(j.metadata?.vulnerabilities?.critical??0)}catch{console.log(0)}})')
38
+ if [ "$CRITICAL" -gt 0 ]; then
39
+ echo "🚫 npm audit reports $CRITICAL critical vulnerabilities"
40
+ FAILS=$((FAILS+1))
41
+ fi
42
+ fi
43
+ ;;
44
+ Python)
45
+ if [ -f requirements.txt ] && command -v pip-audit >/dev/null 2>&1; then
46
+ if ! pip-audit -r requirements.txt --strict; then
47
+ echo "🚫 pip-audit reports vulnerabilities"
48
+ FAILS=$((FAILS+1))
49
+ fi
50
+ fi
51
+ ;;
52
+ Go)
53
+ if [ -f go.mod ] && command -v govulncheck >/dev/null 2>&1; then
54
+ if ! govulncheck ./...; then
55
+ echo "🚫 govulncheck reports reachable vulnerabilities"
56
+ FAILS=$((FAILS+1))
57
+ fi
58
+ fi
59
+ ;;
60
+ esac
39
61
 
40
- # pip audit (if requirements.txt exists)
41
- if [ -f "requirements.txt" ] && command -v pip-audit &>/dev/null; then
42
- if ! pip-audit -r requirements.txt --strict 2>/dev/null; then
43
- echo "🚫 pip-audit: vulnerabilities found"
44
- FAILS=$((FAILS+1))
45
- fi
62
+ if [ "${SPECKY_COMPLIANCE_ENABLED:-0}" = "1" ] && [ ! -f "$SPECKY_FEATURE_DIR/COMPLIANCE.md" ]; then
63
+ echo "🚫 Configured compliance frameworks lack COMPLIANCE.md evidence: $SPECKY_COMPLIANCE_FRAMEWORKS"
64
+ FAILS=$((FAILS+1))
46
65
  fi
47
66
 
48
67
  if [ "$FAILS" -gt 0 ]; then
49
- echo ""
50
- echo "❌ Security scan FAILED ($FAILS issues). Fix before release."
51
- exit 2 # BLOCKING
68
+ echo "❌ Security scan failed with $FAILS issue(s)."
69
+ exit 2
52
70
  fi
53
71
 
54
- echo "✅ Security scan passed."
55
- exit 0
72
+ echo "✅ Contract-aware security scan passed."
@@ -1,82 +1,30 @@
1
- #!/bin/bash
2
- # specky-session-banner.sh — Show Specky pipeline status at session start.
3
- # Target: Claude Code + GitHub Copilot
4
- # Type: Advisory (exit 0 always) | Trigger: SessionStart
5
- #
6
- # Prints a one-screen banner whenever the user opens a new session so they
7
- # immediately see which feature and phase are active. Helps avoid the SIFAP
8
- # incident where a user bypassed the pipeline because they didn't realize
9
- # one was running.
1
+ #!/usr/bin/env bash
2
+ # specky-session-banner.sh — Show explicit feature context or workspace-level status guidance.
3
+ # Type: Advisory | Trigger: SessionStart.
10
4
 
11
5
  set -euo pipefail
12
-
13
- # ── rc.14: Copilot compatibility guard ───────────────────
14
- # VS Code Copilot reads .claude/settings.json hooks and treats SessionStart as
15
- # PreToolUse. This script is advisory-only but Copilot surfaces any output from
16
- # a hook as a block warning. Skip entirely when not in Claude Code context.
17
- if [ -z "${CLAUDE_PROJECT_DIR:-}" ]; then
18
- exit 0
19
- fi
20
-
21
- SPECS_DIR=".specs"
22
- [ -d "$SPECS_DIR" ] || exit 0
23
-
24
- # Find most recently touched feature
25
- LATEST=$(ls -td "$SPECS_DIR"/*/ 2>/dev/null | head -1 || true)
26
- if [ -z "$LATEST" ]; then
27
- exit 0
28
- fi
29
-
30
- STATE="$LATEST/.sdd-state.json"
31
- if [ ! -f "$STATE" ]; then
6
+ [ -n "${CLAUDE_PROJECT_DIR:-}" ] || exit 0
7
+ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
8
+ . "$SCRIPT_DIR/specky-contract-context.bash"
9
+ specky_load_contract_context || exit $?
10
+
11
+ if [ "${SPECKY_CONTEXT_ACTIVE:-0}" != "1" ]; then
12
+ if [ -d .specs ]; then
13
+ echo "🧭 Specky workspace detected. No feature selected; run 'specky status' and resume with explicit spec_dir + feature_number."
14
+ fi
32
15
  exit 0
33
16
  fi
34
17
 
35
- FEATURE=$(basename "$LATEST")
36
- PHASE="?"
37
- if command -v jq >/dev/null 2>&1; then
38
- PHASE=$(jq -r '.current_phase // "?"' "$STATE" 2>/dev/null || echo "?")
39
- fi
40
-
41
18
  BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr -d '\n' || true)
42
- [ -z "$BRANCH" ] && BRANCH="unknown"
19
+ [ -n "$BRANCH" ] || BRANCH="unknown"
43
20
 
44
21
  echo ""
45
- echo "╭─────────────────────────────────────────────────────────────╮"
46
- echo "│ 🧭 Specky Pipeline Active │"
47
- echo "├─────────────────────────────────────────────────────────────┤"
48
- printf "│ Feature: %-50s│\n" "$FEATURE"
49
- printf "│ Phase: %-50s│\n" "$PHASE"
50
- printf "│ Branch: %-50s│\n" "$BRANCH"
51
- echo "├─────────────────────────────────────────────────────────────┤"
52
- echo "│ Resume: @specky-orchestrator (Copilot) │"
53
- echo "│ /specky-orchestrate (Claude Code) │"
54
- echo "│ Status: specky status (or npx specky status) │"
55
- echo "│ New work: @specky-onboarding │"
56
- echo "╰─────────────────────────────────────────────────────────────╯"
57
- echo ""
58
-
59
- # Validate branch matches expected for phase (advisory warning only)
60
- case "$PHASE" in
61
- init|discover|specify|clarify|design|tasks|analyze|implement)
62
- if [[ ! "$BRANCH" =~ ^spec/ ]]; then
63
- echo "⚠️ [specky-session-banner] Phase $PHASE expects branch spec/NNN-* — you are on '$BRANCH'"
64
- echo " Consider: git checkout -b spec/$FEATURE (or let @specky-orchestrator handle it)"
65
- echo ""
66
- fi
67
- ;;
68
- verify)
69
- if [ "$BRANCH" != "develop" ]; then
70
- echo "⚠️ [specky-session-banner] Phase 'verify' expects branch 'develop' — you are on '$BRANCH'"
71
- echo ""
72
- fi
73
- ;;
74
- release)
75
- if [ "$BRANCH" != "stage" ]; then
76
- echo "⚠️ [specky-session-banner] Phase 'release' expects branch 'stage' — you are on '$BRANCH'"
77
- echo ""
78
- fi
79
- ;;
80
- esac
81
-
82
- exit 0
22
+ echo "🧭 Specky Feature Context"
23
+ echo " Feature: ${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME}"
24
+ echo " Contract: $SPECKY_CONTRACT_ID"
25
+ echo " Phase: $SPECKY_PHASE"
26
+ echo " Branch: $BRANCH"
27
+ echo " Resume: @specky-orchestrator or /specky-orchestrate"
28
+ if [ "${SPECKY_RELEASE_ENABLED:-0}" = "1" ]; then
29
+ echo " Release: head=${SPECKY_BRANCH_PREFIX}${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME} base=$SPECKY_BASE_BRANCH"
30
+ fi
@@ -5,9 +5,12 @@
5
5
  # Paper: arXiv:2601.03878 — EARS quality
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
  SPEC="$LATEST/SPECIFICATION.md"
12
15
  [ -f "$SPEC" ] || exit 0
13
16
 
@@ -15,8 +18,8 @@ echo "📋 Spec Quality Check: $SPEC"
15
18
 
16
19
  # Count requirements (POSIX ERE for macOS/Linux portability)
17
20
  REQ_COUNT=$(grep -cE 'REQ-[A-Z]+-[0-9]+' "$SPEC" 2>/dev/null || echo "0")
18
- if [ "$REQ_COUNT" -lt 5 ]; then
19
- echo "⚠️ Only $REQ_COUNT requirements found (minimum 5)."
21
+ if [ "$REQ_COUNT" -lt 1 ]; then
22
+ echo "⚠️ No requirements found. The contract requires source-backed requirements, not a fixed generic count."
20
23
  fi
21
24
 
22
25
  # Check REQ-ID format consistency
@@ -8,19 +8,20 @@
8
8
  # "hooks": { "PostToolUse": ["bash .claude/hooks/specky-spec-sync.sh"] }
9
9
 
10
10
  set -euo pipefail
11
- SPECS_DIR=".specs"
12
- [ -d "$SPECS_DIR" ] || exit 0
11
+ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
12
+ . "$SCRIPT_DIR/specky-contract-context.bash"
13
+ specky_load_contract_context || exit $?
14
+ [ "${SPECKY_CONTEXT_ACTIVE:-0}" = "1" ] || exit 0
13
15
 
14
16
  DRIFT=0
15
- for dir in "$SPECS_DIR"/*/; do
16
- [ -f "$dir/SPECIFICATION.md" ] || continue
17
- REQS=$(grep -oE 'REQ-[A-Z]+-[0-9]+' "$dir/SPECIFICATION.md" 2>/dev/null | sort -u)
18
- for req in $REQS; do
19
- if ! grep -rq "$req" src/ tests/ test/ __tests__/ 2>/dev/null; then
20
- echo "⚠️ DRIFT: $req ($(basename "$dir")) — not found in code or tests"
21
- DRIFT=1
22
- fi
23
- done
17
+ dir="$SPECKY_FEATURE_DIR"
18
+ [ -f "$dir/SPECIFICATION.md" ] || exit 0
19
+ REQS=$(grep -oE 'REQ-[A-Z]+-[0-9]+' "$dir/SPECIFICATION.md" 2>/dev/null | sort -u)
20
+ for req in $REQS; do
21
+ if ! grep -rq "$req" src/ tests/ test/ __tests__/ 2>/dev/null; then
22
+ echo "⚠️ DRIFT: $req (${SPECKY_FEATURE_NUMBER}-${SPECKY_FEATURE_NAME}) — not found in code or tests"
23
+ DRIFT=1
24
+ fi
24
25
  done
25
26
 
26
27
  [ "$DRIFT" -eq 1 ] && echo "📋 Run sdd_check_sync for details. If intentional, run sdd_amend."
@@ -5,9 +5,12 @@
5
5
  # Paper: arXiv:2602.00180 — SDD traceability
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
  TASKS="$LATEST/TASKS.md"
12
15
  [ -f "$TASKS" ] || exit 0
13
16
 
@@ -6,6 +6,7 @@ SCRIPT="${1:?usage: specky-run.sh <script-name> [--blocking]}"
6
6
  BLOCKING="${2:-}"
7
7
  HOOK=".cursor/hooks/scripts/${SCRIPT}"
8
8
  INPUT=$(cat || true)
9
+ [ -n "$INPUT" ] && export SDD_HOOK_INPUT="$INPUT"
9
10
 
10
11
  if command -v jq >/dev/null 2>&1 && [ -n "$INPUT" ]; then
11
12
  RAW=$(echo "$INPUT" | jq -r '
@@ -19,6 +20,8 @@ if command -v jq >/dev/null 2>&1 && [ -n "$INPUT" ]; then
19
20
 
20
21
  PROMPT=$(echo "$INPUT" | jq -r '.prompt // .user_prompt // .text // empty' 2>/dev/null || true)
21
22
  [ -n "$PROMPT" ] && export CLAUDE_USER_PROMPT="$PROMPT"
23
+ WORKSPACE=$(echo "$INPUT" | jq -r '.workspace // .workspace_path // .cwd // .project_dir // empty' 2>/dev/null || true)
24
+ [ -n "$WORKSPACE" ] && export SPECKY_HOOK_WORKSPACE="$WORKSPACE"
22
25
  fi
23
26
 
24
27
  set +e
@@ -13,14 +13,14 @@ This project uses Spec-Driven Development (SDD) via the Specky pipeline.
13
13
  3. **Model routing matters.** Use a fast model class for lightweight scaffolding (Phase 0, 9), a balanced model class for iterative delivery (Phase 1, 5-7), and a reasoning-focused model class for complex analysis and design (Phase 2-4, 8). The user chooses any available model.
14
14
  4. **Never skip hooks.** Blocking hooks (specky-security-scan, specky-release-gate) must pass before release.
15
15
  5. **Artifacts live in `.specs/NNN-feature/`.** CONSTITUTION.md, RESEARCH.md, SPECIFICATION.md, DESIGN.md, TASKS.md, VERIFICATION.md, ANALYSIS.md.
16
- 6. **One branch per spec.** Create `spec/NNN-feature-name` from `develop` for all pipeline work (Phases 0-7). All `.specs/` artifacts are created on this branch. Merge to `develop` after verification, then `stage` for QA and release gates, then `main` for production. Never commit spec work directly to develop, stage, or main.
16
+ 6. **Branch policy is explicit.** Use `capability_config.release.branch_prefix` and `base_branch` when release capability is enabled. Do not invent Gitflow branches or create a branch during Init.
17
17
  7. **Load companion SKILL.md first.** Every agent reads its companion skill file (`.claude/skills/{skill-name}/SKILL.md`) as the first workflow step. Phase agents have dedicated skills (specky-sdd-init, specky-spec-engineer, specky-sdd-clarify, specky-design-architect, specky-task-planner, specky-quality-reviewer); shared pipeline context lives in specky-sdd-pipeline.
18
- 8. **Orchestrator is the single entry point.** When `.specs/` exists with an active pipeline (`.sdd-state.json` present), ALL work code, branches, commits, PRs — MUST flow through `@specky-orchestrator`. Direct calls to phase agents, manual branch creation outside `spec/NNN-*`, or free-form edits bypass the quality gates and are pipeline violations. If unsure where to start, invoke `@specky-onboarding`. Starting in v3.5, `specky-pipeline-guard` hook enforces this automatically.
18
+ 8. **Orchestrator is the single entry point.** When a feature directory contains signed `.sdd-state.json`, work flows through `@specky-orchestrator` and the persisted contract. Calls that omit feature identity, capability policy, or phase gates are pipeline violations. If unsure where to start, invoke `@specky-onboarding`.
19
19
 
20
20
  ## Available Agents
21
21
 
22
22
  - @specky-onboarding — Interactive wizard and default entry point
23
- - @specky-orchestrator — Full pipeline coordinator (all 10 phases)
23
+ - @specky-orchestrator — Contracted phase-graph coordinator
24
24
  - @specky-sdd-init — Initialize pipeline (Phase 0)
25
25
  - @specky-requirements-engineer — Produce FRD + NFRD
26
26
  - @specky-research-analyst — Technical research (Phase 1)
@@ -13,14 +13,14 @@ This project uses Spec-Driven Development (SDD) via the Specky pipeline.
13
13
  3. **Model routing matters.** Use a fast model class for lightweight scaffolding (Phase 0, 9), a balanced model class for iterative delivery (Phase 1, 5-7), and a reasoning-focused model class for complex analysis and design (Phase 2-4, 8). The user chooses any available model.
14
14
  4. **Never skip hooks.** Blocking hooks (specky-security-scan, specky-release-gate) must pass before release.
15
15
  5. **Artifacts live in `.specs/NNN-feature/`.** CONSTITUTION.md, RESEARCH.md, SPECIFICATION.md, DESIGN.md, TASKS.md, VERIFICATION.md, ANALYSIS.md.
16
- 6. **One branch per spec.** Create `spec/NNN-feature-name` from `develop` for all pipeline work (Phases 0-7). All `.specs/` artifacts are created on this branch. Merge to `develop` after verification, then `stage` for QA and release gates, then `main` for production. Never commit spec work directly to develop, stage, or main.
16
+ 6. **Branch policy is explicit.** Use `capability_config.release.branch_prefix` and `base_branch` when release capability is enabled. Do not invent Gitflow branches or create a branch during Init.
17
17
  7. **Load companion SKILL.md first.** Every agent reads its companion skill file (`.github/skills/{skill-name}/SKILL.md`) as the first workflow step. Phase agents have dedicated skills (specky-sdd-init, specky-spec-engineer, specky-sdd-clarify, specky-design-architect, specky-task-planner, specky-quality-reviewer); shared pipeline context lives in specky-sdd-pipeline.
18
- 8. **Orchestrator is the single entry point.** When `.specs/` exists with an active pipeline (`.sdd-state.json` present), ALL work code, branches, commits, PRs — MUST flow through `@specky-orchestrator`. Direct calls to phase agents, manual branch creation outside `spec/NNN-*`, or free-form edits bypass the quality gates and are pipeline violations. If unsure where to start, invoke `@specky-onboarding`. Starting in v3.5, `specky-pipeline-guard` hook enforces this automatically.
18
+ 8. **Orchestrator is the single entry point.** When a feature directory contains signed `.sdd-state.json`, work flows through `@specky-orchestrator` and the persisted contract. Calls that omit feature identity, capability policy, or phase gates are pipeline violations. If unsure where to start, invoke `@specky-onboarding`.
19
19
 
20
20
  ## Available Agents
21
21
 
22
22
  - @specky-onboarding — Interactive wizard and default entry point
23
- - @specky-orchestrator — Full pipeline coordinator (all 10 phases)
23
+ - @specky-orchestrator — Contracted phase-graph coordinator
24
24
  - @specky-sdd-init — Initialize pipeline (Phase 0)
25
25
  - @specky-requirements-engineer — Produce FRD + NFRD
26
26
  - @specky-research-analyst — Technical research (Phase 1)
@@ -13,14 +13,14 @@ This project uses Spec-Driven Development (SDD) via the Specky pipeline.
13
13
  3. **Model routing matters.** Use a fast model class for lightweight scaffolding (Phase 0, 9), a balanced model class for iterative delivery (Phase 1, 5-7), and a reasoning-focused model class for complex analysis and design (Phase 2-4, 8).
14
14
  4. **Never skip hooks.** Blocking hooks (specky-security-scan, specky-release-gate, specky-artifact-validator, specky-phase-gate) must pass before release.
15
15
  5. **Artifacts live in `.specs/NNN-feature/`.** CONSTITUTION.md, RESEARCH.md, SPECIFICATION.md, DESIGN.md, TASKS.md, VERIFICATION.md, ANALYSIS.md.
16
- 6. **One branch per spec.** Create `spec/NNN-feature-name` from `develop` for all pipeline work (Phases 0-7). Merge to `develop` after verification, then `stage` for QA, then `main` for production.
16
+ 6. **Branch policy is explicit.** Use the persisted release branch prefix and base branch. Do not invent Gitflow branches or create a branch during Init.
17
17
  7. **Load companion SKILL.md first.** Every agent reads `.agents/skills/{skill-name}/SKILL.md` as the first workflow step. Phase agents have dedicated skills (specky-sdd-init, specky-spec-engineer, specky-sdd-clarify, specky-design-architect, specky-task-planner, specky-quality-reviewer); shared pipeline context lives in specky-sdd-pipeline.
18
- 8. **Orchestrator is the single entry point.** When `.specs/` exists with an active pipeline (`.sdd-state.json` present), ALL work MUST flow through `@specky-orchestrator`. If unsure where to start, invoke `@specky-onboarding`.
18
+ 8. **Orchestrator is the single entry point.** When a feature directory contains signed `.sdd-state.json`, work follows its persisted contract through `@specky-orchestrator`. If unsure where to start, invoke `@specky-onboarding`.
19
19
 
20
20
  ## Available Agents
21
21
 
22
22
  - @specky-onboarding — Interactive wizard and default entry point
23
- - @specky-orchestrator — Full pipeline coordinator (all 10 phases)
23
+ - @specky-orchestrator — Contracted phase-graph coordinator
24
24
  - @specky-sdd-init — Initialize pipeline (Phase 0)
25
25
  - @specky-requirements-engineer — Produce FRD + NFRD
26
26
  - @specky-research-analyst — Technical research (Phase 1)
@@ -18,9 +18,9 @@ OpenCode requires two steps after install:
18
18
  1. **EARS notation is mandatory.** Every requirement must follow one of the 6 EARS patterns.
19
19
  2. **REQ-ID traceability is non-negotiable.** Every test, task, and design decision traces to a REQ-ID.
20
20
  3. **Artifacts live in `.specs/NNN-feature/`.** CONSTITUTION.md, SPECIFICATION.md, DESIGN.md, TASKS.md, ANALYSIS.md, VERIFICATION.md.
21
- 4. **One branch per spec.** Create `spec/NNN-feature-name` from `develop` for pipeline work (Phases 0-7).
21
+ 4. **Branch policy is explicit.** Use the persisted release branch prefix and base branch. Do not invent Gitflow branches or create a branch during Init.
22
22
  5. **Load companion SKILL.md first.** Read `.agents/skills/{skill-name}/SKILL.md` before phase work.
23
- 6. **Orchestrator is the single entry point.** When `.specs/` has an active pipeline, route work through `@specky-orchestrator` or `/specky-orchestrate`.
23
+ 6. **Orchestrator is the single entry point.** When a feature directory has signed state, route work through `@specky-orchestrator` or `/specky-orchestrate` and follow its persisted contract.
24
24
 
25
25
  ## Available Agents
26
26