sdd-agent-platform 0.4.2 → 0.5.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 (834) hide show
  1. package/README.md +34 -41
  2. package/node_modules/@sdd-agent-platform/core/dist/ai-tools.js +56 -73
  3. package/node_modules/@sdd-agent-platform/core/dist/ai-tools.js.map +1 -1
  4. package/node_modules/@sdd-agent-platform/core/dist/artifacts/ingestion.js +9 -64
  5. package/node_modules/@sdd-agent-platform/core/dist/artifacts/ingestion.js.map +1 -1
  6. package/node_modules/@sdd-agent-platform/core/dist/artifacts/sdd-evidence.js +1 -1
  7. package/node_modules/@sdd-agent-platform/core/dist/artifacts/sdd-evidence.js.map +1 -1
  8. package/node_modules/@sdd-agent-platform/core/dist/artifacts/sdd-result.js +17 -26
  9. package/node_modules/@sdd-agent-platform/core/dist/artifacts/sdd-result.js.map +1 -1
  10. package/node_modules/@sdd-agent-platform/core/dist/config/init-project.d.ts +8 -7
  11. package/node_modules/@sdd-agent-platform/core/dist/config/init-project.js +8 -12
  12. package/node_modules/@sdd-agent-platform/core/dist/config/init-project.js.map +1 -1
  13. package/node_modules/@sdd-agent-platform/core/dist/config/project-config.d.ts +1 -1
  14. package/node_modules/@sdd-agent-platform/core/dist/config/project-config.js +1 -1
  15. package/node_modules/@sdd-agent-platform/core/dist/config/project-config.js.map +1 -1
  16. package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.d.ts +3 -4
  17. package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.js +377 -411
  18. package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.js.map +1 -1
  19. package/node_modules/@sdd-agent-platform/core/dist/context/build-package.d.ts +1 -1
  20. package/node_modules/@sdd-agent-platform/core/dist/context/build-package.js +18 -25
  21. package/node_modules/@sdd-agent-platform/core/dist/context/build-package.js.map +1 -1
  22. package/node_modules/@sdd-agent-platform/core/dist/context/evidence-summary.js +8 -26
  23. package/node_modules/@sdd-agent-platform/core/dist/context/evidence-summary.js.map +1 -1
  24. package/node_modules/@sdd-agent-platform/core/dist/context/log-worker.js +2 -2
  25. package/node_modules/@sdd-agent-platform/core/dist/context/log-worker.js.map +1 -1
  26. package/node_modules/@sdd-agent-platform/core/dist/context-offload/contracts.d.ts +1 -1
  27. package/node_modules/@sdd-agent-platform/core/dist/contracts.d.ts +6 -1
  28. package/node_modules/@sdd-agent-platform/core/dist/contracts.js +5 -0
  29. package/node_modules/@sdd-agent-platform/core/dist/contracts.js.map +1 -1
  30. package/node_modules/@sdd-agent-platform/core/dist/delegation/model.d.ts +0 -3
  31. package/node_modules/@sdd-agent-platform/core/dist/delegation/validation.d.ts +0 -3
  32. package/node_modules/@sdd-agent-platform/core/dist/delegation/validation.js +4 -7
  33. package/node_modules/@sdd-agent-platform/core/dist/delegation/validation.js.map +1 -1
  34. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/document-chain.js +3 -13
  35. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/document-chain.js.map +1 -1
  36. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/local-run-index.js +1 -9
  37. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/local-run-index.js.map +1 -1
  38. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/project.js +9 -9
  39. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/project.js.map +1 -1
  40. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/registries.js +1 -0
  41. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/registries.js.map +1 -1
  42. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js +4 -4
  43. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js.map +1 -1
  44. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-trust.js +24 -0
  45. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-trust.js.map +1 -1
  46. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/runtime-contracts.js +2 -2
  47. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/runtime-contracts.js.map +1 -1
  48. package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js +43 -180
  49. package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js.map +1 -1
  50. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.d.ts +1 -1
  51. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js +7 -14
  52. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js.map +1 -1
  53. package/node_modules/@sdd-agent-platform/core/dist/evidence-runtime/coordination.js +110 -0
  54. package/node_modules/@sdd-agent-platform/core/dist/evidence-runtime/coordination.js.map +1 -0
  55. package/node_modules/@sdd-agent-platform/core/dist/execution/background-executor.js +4 -4
  56. package/node_modules/@sdd-agent-platform/core/dist/execution/background-executor.js.map +1 -1
  57. package/node_modules/@sdd-agent-platform/core/dist/execution/foreground-subagents.js +3 -3
  58. package/node_modules/@sdd-agent-platform/core/dist/execution/foreground-subagents.js.map +1 -1
  59. package/node_modules/@sdd-agent-platform/core/dist/execution/host-invocation.js +85 -86
  60. package/node_modules/@sdd-agent-platform/core/dist/execution/host-invocation.js.map +1 -1
  61. package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js +2 -3
  62. package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js.map +1 -1
  63. package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js +2 -2
  64. package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js.map +1 -1
  65. package/node_modules/@sdd-agent-platform/core/dist/governance/policy.d.ts +1 -1
  66. package/node_modules/@sdd-agent-platform/core/dist/governance/policy.js +1 -1
  67. package/node_modules/@sdd-agent-platform/core/dist/governance/policy.js.map +1 -1
  68. package/node_modules/@sdd-agent-platform/core/dist/instructions.d.ts +1 -1
  69. package/node_modules/@sdd-agent-platform/core/dist/instructions.js +31 -67
  70. package/node_modules/@sdd-agent-platform/core/dist/instructions.js.map +1 -1
  71. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/decision-gate.js +1 -1
  72. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/decision-gate.js.map +1 -1
  73. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.d.ts +0 -1
  74. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js +59 -85
  75. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js.map +1 -1
  76. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/contracts.d.ts +159 -0
  77. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/contracts.js +7 -0
  78. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/contracts.js.map +1 -0
  79. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/kernel.d.ts +16 -0
  80. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/kernel.js +461 -0
  81. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/kernel.js.map +1 -0
  82. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph.d.ts +2 -0
  83. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph.js +3 -0
  84. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph.js.map +1 -0
  85. package/node_modules/@sdd-agent-platform/core/dist/orchestration/contracts.d.ts +1 -1
  86. package/node_modules/@sdd-agent-platform/core/dist/orchestration/runtime.d.ts +2 -12
  87. package/node_modules/@sdd-agent-platform/core/dist/orchestration/runtime.js +32 -80
  88. package/node_modules/@sdd-agent-platform/core/dist/orchestration/runtime.js.map +1 -1
  89. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.d.ts +2 -5
  90. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js +27 -69
  91. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js.map +1 -1
  92. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js +118 -34
  93. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js.map +1 -1
  94. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js +1 -1
  95. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js.map +1 -1
  96. package/node_modules/@sdd-agent-platform/core/dist/registries/capability-sources.js +1 -1
  97. package/node_modules/@sdd-agent-platform/core/dist/registries/command-team-runtime.d.ts +1 -1
  98. package/node_modules/@sdd-agent-platform/core/dist/registries/command-team-runtime.js +8 -15
  99. package/node_modules/@sdd-agent-platform/core/dist/registries/command-team-runtime.js.map +1 -1
  100. package/node_modules/@sdd-agent-platform/core/dist/registries/eval-learning-context.js +4 -4
  101. package/node_modules/@sdd-agent-platform/core/dist/registries/eval-learning-context.js.map +1 -1
  102. package/node_modules/@sdd-agent-platform/core/dist/registries/plan-scout-domains.d.ts +13 -0
  103. package/node_modules/@sdd-agent-platform/core/dist/registries/plan-scout-domains.js +76 -0
  104. package/node_modules/@sdd-agent-platform/core/dist/registries/plan-scout-domains.js.map +1 -0
  105. package/node_modules/@sdd-agent-platform/core/dist/registries/query-status.js +2 -2
  106. package/node_modules/@sdd-agent-platform/core/dist/registries/query-status.js.map +1 -1
  107. package/node_modules/@sdd-agent-platform/core/dist/registries/skill-capabilities.js +7 -7
  108. package/node_modules/@sdd-agent-platform/core/dist/registries/skill-capabilities.js.map +1 -1
  109. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-capabilities.js +4 -4
  110. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-capabilities.js.map +1 -1
  111. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-plugins.js +2 -2
  112. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-plugins.js.map +1 -1
  113. package/node_modules/@sdd-agent-platform/core/dist/registries/worker-adapters.js +11 -11
  114. package/node_modules/@sdd-agent-platform/core/dist/registries/worker-adapters.js.map +1 -1
  115. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.d.ts +1 -1
  116. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js +21 -21
  117. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js.map +1 -1
  118. package/node_modules/@sdd-agent-platform/core/dist/risk/consumer-diagnostics.js +2 -1
  119. package/node_modules/@sdd-agent-platform/core/dist/risk/consumer-diagnostics.js.map +1 -1
  120. package/node_modules/@sdd-agent-platform/core/dist/risk/kernel.js +6 -6
  121. package/node_modules/@sdd-agent-platform/core/dist/risk/kernel.js.map +1 -1
  122. package/node_modules/@sdd-agent-platform/core/dist/risk/legacy-adapters.js +11 -23
  123. package/node_modules/@sdd-agent-platform/core/dist/risk/legacy-adapters.js.map +1 -1
  124. package/node_modules/@sdd-agent-platform/core/dist/risk/workflow-gates.d.ts +2 -2
  125. package/node_modules/@sdd-agent-platform/core/dist/risk/workflow-gates.js +18 -20
  126. package/node_modules/@sdd-agent-platform/core/dist/risk/workflow-gates.js.map +1 -1
  127. package/node_modules/@sdd-agent-platform/core/dist/router/agent-runtime.d.ts +0 -2
  128. package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js +1 -1
  129. package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js.map +1 -1
  130. package/node_modules/@sdd-agent-platform/core/dist/router/routing.js +16 -48
  131. package/node_modules/@sdd-agent-platform/core/dist/router/routing.js.map +1 -1
  132. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-import.js +11 -1
  133. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-import.js.map +1 -1
  134. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js +2 -2
  135. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js.map +1 -1
  136. package/node_modules/@sdd-agent-platform/core/dist/router/stage-route-binding.d.ts +2 -2
  137. package/node_modules/@sdd-agent-platform/core/dist/router/stage-route-binding.js +20 -28
  138. package/node_modules/@sdd-agent-platform/core/dist/router/stage-route-binding.js.map +1 -1
  139. package/node_modules/@sdd-agent-platform/core/dist/router.d.ts +0 -1
  140. package/node_modules/@sdd-agent-platform/core/dist/router.js +0 -1
  141. package/node_modules/@sdd-agent-platform/core/dist/router.js.map +1 -1
  142. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.d.ts +6 -6
  143. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js +13 -124
  144. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js.map +1 -1
  145. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.d.ts +2 -0
  146. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js +5 -7
  147. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js.map +1 -1
  148. package/node_modules/@sdd-agent-platform/core/dist/run-state/model.d.ts +28 -28
  149. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-index.d.ts +3 -2
  150. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-index.js +15 -66
  151. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-index.js.map +1 -1
  152. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js +26 -36
  153. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js.map +1 -1
  154. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.d.ts +0 -4
  155. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js +5 -51
  156. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js.map +1 -1
  157. package/node_modules/@sdd-agent-platform/core/dist/run-state.d.ts +0 -1
  158. package/node_modules/@sdd-agent-platform/core/dist/run-state.js +0 -1
  159. package/node_modules/@sdd-agent-platform/core/dist/run-state.js.map +1 -1
  160. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/build.js +1 -1
  161. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/build.js.map +1 -1
  162. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/findings.js +7 -16
  163. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/findings.js.map +1 -1
  164. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/model.d.ts +1 -2
  165. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.d.ts +0 -1
  166. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js +1 -4
  167. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js.map +1 -1
  168. package/node_modules/@sdd-agent-platform/core/dist/runtime-projection-p0.d.ts +2 -2
  169. package/node_modules/@sdd-agent-platform/core/dist/runtime-projection-p0.js +11 -0
  170. package/node_modules/@sdd-agent-platform/core/dist/runtime-projection-p0.js.map +1 -1
  171. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/artifact-depth.d.ts +14 -0
  172. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/artifact-depth.js +179 -0
  173. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/artifact-depth.js.map +1 -0
  174. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.d.ts +0 -2
  175. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js +10 -97
  176. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js.map +1 -1
  177. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.d.ts +1 -1
  178. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js +6 -8
  179. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js.map +1 -1
  180. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.d.ts +5 -2
  181. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js +85 -68
  182. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js.map +1 -1
  183. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-rendering.js +2 -2
  184. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-rendering.js.map +1 -1
  185. package/node_modules/@sdd-agent-platform/core/dist/spec-entry.js +40 -0
  186. package/node_modules/@sdd-agent-platform/core/dist/spec-entry.js.map +1 -0
  187. package/node_modules/@sdd-agent-platform/core/dist/spec-manager-contracts.d.ts +12 -0
  188. package/node_modules/@sdd-agent-platform/core/dist/spec-manager-contracts.js +2 -0
  189. package/node_modules/@sdd-agent-platform/core/dist/spec-manager-contracts.js.map +1 -0
  190. package/node_modules/@sdd-agent-platform/core/dist/stage-artifacts.d.ts +2 -2
  191. package/node_modules/@sdd-agent-platform/core/dist/stage-artifacts.js +19 -26
  192. package/node_modules/@sdd-agent-platform/core/dist/stage-artifacts.js.map +1 -1
  193. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration-contracts.d.ts +1 -1
  194. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration-contracts.js +3 -6
  195. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration-contracts.js.map +1 -1
  196. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration.d.ts +111 -263
  197. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration.js +1272 -1124
  198. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration.js.map +1 -1
  199. package/node_modules/@sdd-agent-platform/core/dist/stage-runtime/runtime.js +5 -5
  200. package/node_modules/@sdd-agent-platform/core/dist/stage-runtime/runtime.js.map +1 -1
  201. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.d.ts +1 -44
  202. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js +47 -170
  203. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js.map +1 -1
  204. package/node_modules/@sdd-agent-platform/core/dist/storage/runtime-store.js +73 -73
  205. package/node_modules/@sdd-agent-platform/core/dist/subagents/contracts.d.ts +1 -1
  206. package/node_modules/@sdd-agent-platform/core/dist/subagents/runtime.js +7 -7
  207. package/node_modules/@sdd-agent-platform/core/dist/subagents/runtime.js.map +1 -1
  208. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.d.ts +1 -0
  209. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js +2 -0
  210. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js.map +1 -0
  211. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.d.ts +1 -0
  212. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js +2 -0
  213. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js.map +1 -0
  214. package/node_modules/@sdd-agent-platform/core/dist/sync-back.d.ts +1 -0
  215. package/node_modules/@sdd-agent-platform/core/dist/sync-back.js +2 -0
  216. package/node_modules/@sdd-agent-platform/core/dist/sync-back.js.map +1 -0
  217. package/node_modules/@sdd-agent-platform/core/dist/task-execution-contract.d.ts +167 -0
  218. package/node_modules/@sdd-agent-platform/core/dist/task-execution-contract.js +377 -0
  219. package/node_modules/@sdd-agent-platform/core/dist/task-execution-contract.js.map +1 -0
  220. package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js +329 -314
  221. package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js.map +1 -1
  222. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.d.ts +1 -0
  223. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js +53 -7
  224. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js.map +1 -1
  225. package/node_modules/@sdd-agent-platform/core/dist/truth-reconciliation.js +9 -12
  226. package/node_modules/@sdd-agent-platform/core/dist/truth-reconciliation.js.map +1 -1
  227. package/node_modules/@sdd-agent-platform/core/dist/tsconfig.tsbuildinfo +1 -1
  228. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.d.ts +0 -48
  229. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js +1 -520
  230. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js.map +1 -1
  231. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.d.ts +5 -5
  232. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js +14 -14
  233. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js.map +1 -1
  234. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.d.ts +1 -0
  235. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js +111 -159
  236. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js.map +1 -1
  237. package/node_modules/@sdd-agent-platform/core/dist/verification/task-evidence-judgment.d.ts +49 -0
  238. package/node_modules/@sdd-agent-platform/core/dist/verification/task-evidence-judgment.js +521 -0
  239. package/node_modules/@sdd-agent-platform/core/dist/verification/task-evidence-judgment.js.map +1 -0
  240. package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js +21 -21
  241. package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js.map +1 -1
  242. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.d.ts +0 -18
  243. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js +5 -27
  244. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js.map +1 -1
  245. package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js +45 -45
  246. package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js.map +1 -1
  247. package/node_modules/@sdd-agent-platform/core/dist/verification.d.ts +3 -3
  248. package/node_modules/@sdd-agent-platform/core/dist/verification.js +2 -2
  249. package/node_modules/@sdd-agent-platform/core/dist/verification.js.map +1 -1
  250. package/node_modules/@sdd-agent-platform/core/dist/work-units/contracts.d.ts +1 -1
  251. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js +9 -227
  252. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js.map +1 -1
  253. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js +9 -50
  254. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js.map +1 -1
  255. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js +4 -42
  256. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js.map +1 -1
  257. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/types.d.ts +2 -3
  258. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
  259. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js +2 -1
  260. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
  261. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/dependencies.js +1 -1
  262. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.d.ts +1 -0
  263. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js +23 -63
  264. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js.map +1 -1
  265. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.d.ts +2 -2
  266. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js +43 -65
  267. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js.map +1 -1
  268. package/node_modules/@sdd-agent-platform/core/package.json +5 -2
  269. package/node_modules/@sdd-agent-platform/core/src/ai-tools.test.ts +238 -185
  270. package/node_modules/@sdd-agent-platform/core/src/ai-tools.ts +56 -73
  271. package/node_modules/@sdd-agent-platform/core/src/artifacts/ingestion.test.ts +189 -227
  272. package/node_modules/@sdd-agent-platform/core/src/artifacts/ingestion.ts +222 -278
  273. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-evidence.test.ts +28 -28
  274. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-evidence.ts +301 -301
  275. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-result.test.ts +181 -181
  276. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-result.ts +231 -240
  277. package/node_modules/@sdd-agent-platform/core/src/artifacts/templates.ts +99 -99
  278. package/node_modules/@sdd-agent-platform/core/src/artifacts.ts +4 -4
  279. package/node_modules/@sdd-agent-platform/core/src/coding-facts/contracts.ts +79 -79
  280. package/node_modules/@sdd-agent-platform/core/src/coding-facts.ts +1 -1
  281. package/node_modules/@sdd-agent-platform/core/src/config/init-project.test.ts +314 -318
  282. package/node_modules/@sdd-agent-platform/core/src/config/init-project.ts +128 -123
  283. package/node_modules/@sdd-agent-platform/core/src/config/project-config.ts +265 -265
  284. package/node_modules/@sdd-agent-platform/core/src/config/project-detection.ts +147 -147
  285. package/node_modules/@sdd-agent-platform/core/src/config/starter-documents.ts +400 -432
  286. package/node_modules/@sdd-agent-platform/core/src/context/budget.ts +30 -30
  287. package/node_modules/@sdd-agent-platform/core/src/context/build-package.ts +304 -311
  288. package/node_modules/@sdd-agent-platform/core/src/context/command-summary.ts +45 -45
  289. package/node_modules/@sdd-agent-platform/core/src/context/context-build.test.ts +188 -189
  290. package/node_modules/@sdd-agent-platform/core/src/context/evidence-summary.ts +144 -163
  291. package/node_modules/@sdd-agent-platform/core/src/context/log-worker.ts +48 -48
  292. package/node_modules/@sdd-agent-platform/core/src/context/source-refs.ts +41 -41
  293. package/node_modules/@sdd-agent-platform/core/src/context-offload/contracts.ts +47 -47
  294. package/node_modules/@sdd-agent-platform/core/src/context-offload/runtime.test.ts +71 -71
  295. package/node_modules/@sdd-agent-platform/core/src/context-offload/runtime.ts +178 -178
  296. package/node_modules/@sdd-agent-platform/core/src/context-offload.ts +2 -2
  297. package/node_modules/@sdd-agent-platform/core/src/context.ts +6 -6
  298. package/node_modules/@sdd-agent-platform/core/src/contracts/issues.ts +13 -13
  299. package/node_modules/@sdd-agent-platform/core/src/contracts.test.ts +9 -9
  300. package/node_modules/@sdd-agent-platform/core/src/contracts.ts +121 -116
  301. package/node_modules/@sdd-agent-platform/core/src/delegation/delegation.test.ts +183 -183
  302. package/node_modules/@sdd-agent-platform/core/src/delegation/model.ts +23 -26
  303. package/node_modules/@sdd-agent-platform/core/src/delegation/queue.ts +58 -58
  304. package/node_modules/@sdd-agent-platform/core/src/delegation/run-state.ts +14 -14
  305. package/node_modules/@sdd-agent-platform/core/src/delegation/state-machine.ts +90 -90
  306. package/node_modules/@sdd-agent-platform/core/src/delegation/validation.ts +124 -127
  307. package/node_modules/@sdd-agent-platform/core/src/delegation.ts +26 -26
  308. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/ai-entries.ts +28 -28
  309. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/document-chain.ts +104 -112
  310. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/local-run-index.ts +19 -27
  311. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/project.ts +84 -84
  312. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/registries.ts +252 -251
  313. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-evidence.ts +330 -330
  314. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-records.ts +79 -79
  315. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-trust.ts +128 -107
  316. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/runtime-contracts.ts +300 -300
  317. package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.test.ts +628 -755
  318. package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.ts +301 -453
  319. package/node_modules/@sdd-agent-platform/core/src/doctor/model.ts +13 -13
  320. package/node_modules/@sdd-agent-platform/core/src/doctor/summary.ts +11 -11
  321. package/node_modules/@sdd-agent-platform/core/src/doctor.ts +2 -2
  322. package/node_modules/@sdd-agent-platform/core/src/evidence/lookup.ts +80 -88
  323. package/node_modules/@sdd-agent-platform/core/src/evidence-runtime/contracts.ts +48 -48
  324. package/node_modules/@sdd-agent-platform/core/src/evidence-runtime.ts +1 -1
  325. package/node_modules/@sdd-agent-platform/core/src/execution/agent-execution-records.ts +195 -195
  326. package/node_modules/@sdd-agent-platform/core/src/execution/background-executor.test.ts +187 -235
  327. package/node_modules/@sdd-agent-platform/core/src/execution/background-executor.ts +305 -305
  328. package/node_modules/@sdd-agent-platform/core/src/execution/foreground-subagents.test.ts +97 -106
  329. package/node_modules/@sdd-agent-platform/core/src/execution/foreground-subagents.ts +453 -453
  330. package/node_modules/@sdd-agent-platform/core/src/execution/host-invocation.ts +225 -226
  331. package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.test.ts +132 -143
  332. package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.ts +436 -437
  333. package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.test.ts +102 -102
  334. package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.ts +271 -271
  335. package/node_modules/@sdd-agent-platform/core/src/execution/wave-executor.test.ts +111 -121
  336. package/node_modules/@sdd-agent-platform/core/src/execution/wave-executor.ts +231 -231
  337. package/node_modules/@sdd-agent-platform/core/src/execution.ts +5 -5
  338. package/node_modules/@sdd-agent-platform/core/src/governance/policy.test.ts +57 -65
  339. package/node_modules/@sdd-agent-platform/core/src/governance/policy.ts +175 -175
  340. package/node_modules/@sdd-agent-platform/core/src/governance.ts +1 -1
  341. package/node_modules/@sdd-agent-platform/core/src/instructions.test.ts +80 -64
  342. package/node_modules/@sdd-agent-platform/core/src/instructions.ts +32 -68
  343. package/node_modules/@sdd-agent-platform/core/src/lifecycle/decision-gate.test.ts +174 -174
  344. package/node_modules/@sdd-agent-platform/core/src/lifecycle/decision-gate.ts +373 -373
  345. package/node_modules/@sdd-agent-platform/core/src/lifecycle/rendering.ts +29 -29
  346. package/node_modules/@sdd-agent-platform/core/src/lifecycle/risk-signals.ts +146 -146
  347. package/node_modules/@sdd-agent-platform/core/src/lifecycle/ship.test.ts +47 -47
  348. package/node_modules/@sdd-agent-platform/core/src/lifecycle/ship.ts +255 -280
  349. package/node_modules/@sdd-agent-platform/core/src/lifecycle-graph/contracts.ts +179 -0
  350. package/node_modules/@sdd-agent-platform/core/src/lifecycle-graph/kernel.ts +522 -0
  351. package/node_modules/@sdd-agent-platform/core/src/lifecycle-graph.ts +2 -0
  352. package/node_modules/@sdd-agent-platform/core/src/lifecycle.ts +4 -4
  353. package/node_modules/@sdd-agent-platform/core/src/orchestration/contracts.ts +50 -50
  354. package/node_modules/@sdd-agent-platform/core/src/orchestration/index.ts +2 -2
  355. package/node_modules/@sdd-agent-platform/core/src/orchestration/runtime.ts +331 -394
  356. package/node_modules/@sdd-agent-platform/core/src/path-safety.test.ts +22 -22
  357. package/node_modules/@sdd-agent-platform/core/src/phase8-contracts.test.ts +243 -242
  358. package/node_modules/@sdd-agent-platform/core/src/phase8-projection-compat.test.ts +152 -153
  359. package/node_modules/@sdd-agent-platform/core/src/phase8-risk-kernel.test.ts +277 -277
  360. package/node_modules/@sdd-agent-platform/core/src/phase9-lifecycle-graph.test.ts +103 -0
  361. package/node_modules/@sdd-agent-platform/core/src/planning/task-graph.test.ts +88 -88
  362. package/node_modules/@sdd-agent-platform/core/src/planning/task-graph.ts +222 -222
  363. package/node_modules/@sdd-agent-platform/core/src/planning/wave-plan.test.ts +79 -79
  364. package/node_modules/@sdd-agent-platform/core/src/planning/wave-plan.ts +160 -160
  365. package/node_modules/@sdd-agent-platform/core/src/planning.ts +2 -2
  366. package/node_modules/@sdd-agent-platform/core/src/registries/agent-capability-catalog.ts +426 -473
  367. package/node_modules/@sdd-agent-platform/core/src/registries/agent-registry.ts +230 -146
  368. package/node_modules/@sdd-agent-platform/core/src/registries/agent-runtime-static.ts +142 -142
  369. package/node_modules/@sdd-agent-platform/core/src/registries/capability-sources.ts +253 -253
  370. package/node_modules/@sdd-agent-platform/core/src/registries/command-team-runtime.ts +302 -309
  371. package/node_modules/@sdd-agent-platform/core/src/registries/eval-learning-context.ts +246 -246
  372. package/node_modules/@sdd-agent-platform/core/src/registries/plan-scout-domains.ts +89 -0
  373. package/node_modules/@sdd-agent-platform/core/src/registries/query-status.ts +119 -119
  374. package/node_modules/@sdd-agent-platform/core/src/registries/registries.test.ts +454 -445
  375. package/node_modules/@sdd-agent-platform/core/src/registries/skill-capabilities.ts +37 -37
  376. package/node_modules/@sdd-agent-platform/core/src/registries/tool-capabilities.ts +135 -135
  377. package/node_modules/@sdd-agent-platform/core/src/registries/tool-plugins.ts +132 -132
  378. package/node_modules/@sdd-agent-platform/core/src/registries/worker-adapters.ts +144 -144
  379. package/node_modules/@sdd-agent-platform/core/src/registries/workflow-gates.ts +111 -111
  380. package/node_modules/@sdd-agent-platform/core/src/registries.ts +42 -42
  381. package/node_modules/@sdd-agent-platform/core/src/risk/consumer-diagnostics.ts +98 -97
  382. package/node_modules/@sdd-agent-platform/core/src/risk/contracts.ts +63 -63
  383. package/node_modules/@sdd-agent-platform/core/src/risk/kernel.ts +233 -233
  384. package/node_modules/@sdd-agent-platform/core/src/risk/legacy-adapters.ts +251 -263
  385. package/node_modules/@sdd-agent-platform/core/src/risk/workflow-gates.ts +203 -205
  386. package/node_modules/@sdd-agent-platform/core/src/risk.ts +5 -5
  387. package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime-config.ts +327 -327
  388. package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime.ts +388 -390
  389. package/node_modules/@sdd-agent-platform/core/src/router/profile-resolution.ts +154 -154
  390. package/node_modules/@sdd-agent-platform/core/src/router/risk-policy.ts +33 -33
  391. package/node_modules/@sdd-agent-platform/core/src/router/route-cache.ts +100 -100
  392. package/node_modules/@sdd-agent-platform/core/src/router/route-projection.ts +356 -356
  393. package/node_modules/@sdd-agent-platform/core/src/router/route-sdd-task.test.ts +428 -665
  394. package/node_modules/@sdd-agent-platform/core/src/router/route-sdd-task.ts +2 -2
  395. package/node_modules/@sdd-agent-platform/core/src/router/routing-rules.ts +73 -73
  396. package/node_modules/@sdd-agent-platform/core/src/router/routing.ts +189 -223
  397. package/node_modules/@sdd-agent-platform/core/src/router/runtime-import.ts +464 -453
  398. package/node_modules/@sdd-agent-platform/core/src/router/runtime-inspection.ts +124 -124
  399. package/node_modules/@sdd-agent-platform/core/src/router/runtime-registry.ts +123 -123
  400. package/node_modules/@sdd-agent-platform/core/src/router/runtime-validation.ts +277 -277
  401. package/node_modules/@sdd-agent-platform/core/src/router/stage-route-binding.ts +273 -279
  402. package/node_modules/@sdd-agent-platform/core/src/router/team-mode.ts +170 -170
  403. package/node_modules/@sdd-agent-platform/core/src/router.ts +5 -6
  404. package/node_modules/@sdd-agent-platform/core/src/run-state/artifacts.ts +126 -240
  405. package/node_modules/@sdd-agent-platform/core/src/run-state/events.ts +27 -27
  406. package/node_modules/@sdd-agent-platform/core/src/run-state/inspect-run.ts +172 -172
  407. package/node_modules/@sdd-agent-platform/core/src/run-state/invocation-ledger.ts +109 -109
  408. package/node_modules/@sdd-agent-platform/core/src/run-state/model.ts +252 -253
  409. package/node_modules/@sdd-agent-platform/core/src/run-state/run-index.test.ts +80 -52
  410. package/node_modules/@sdd-agent-platform/core/src/run-state/run-index.ts +301 -352
  411. package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.test.ts +70 -118
  412. package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.ts +406 -416
  413. package/node_modules/@sdd-agent-platform/core/src/run-state/task-evidence.ts +198 -252
  414. package/node_modules/@sdd-agent-platform/core/src/run-state/timing.ts +146 -146
  415. package/node_modules/@sdd-agent-platform/core/src/run-state.ts +8 -9
  416. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis/build.ts +60 -60
  417. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis/findings.ts +249 -256
  418. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis/model.ts +139 -140
  419. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis.test.ts +65 -66
  420. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis.ts +2 -2
  421. package/node_modules/@sdd-agent-platform/core/src/runtime-paths.ts +249 -253
  422. package/node_modules/@sdd-agent-platform/core/src/runtime-projection-p0.test.ts +101 -96
  423. package/node_modules/@sdd-agent-platform/core/src/runtime-projection-p0.ts +314 -292
  424. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/artifact-depth.test.ts +380 -0
  425. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/artifact-depth.ts +207 -0
  426. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/context.ts +111 -111
  427. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/document-hashes.ts +207 -306
  428. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/run-binding.ts +95 -97
  429. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-inspection.ts +39 -39
  430. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.test.ts +467 -523
  431. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.ts +738 -709
  432. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-rendering.ts +81 -81
  433. package/node_modules/@sdd-agent-platform/core/src/sdd-docs.ts +5 -5
  434. package/node_modules/@sdd-agent-platform/core/src/spec-manager-contracts.ts +13 -0
  435. package/node_modules/@sdd-agent-platform/core/src/stage-artifacts.ts +435 -450
  436. package/node_modules/@sdd-agent-platform/core/src/stage-collaboration-contracts.ts +316 -322
  437. package/node_modules/@sdd-agent-platform/core/src/stage-collaboration.test.ts +2963 -2902
  438. package/node_modules/@sdd-agent-platform/core/src/stage-collaboration.ts +5856 -5831
  439. package/node_modules/@sdd-agent-platform/core/src/stage-runtime/contracts.ts +40 -40
  440. package/node_modules/@sdd-agent-platform/core/src/stage-runtime/runtime.test.ts +209 -209
  441. package/node_modules/@sdd-agent-platform/core/src/stage-runtime/runtime.ts +360 -360
  442. package/node_modules/@sdd-agent-platform/core/src/stage-runtime.ts +2 -2
  443. package/node_modules/@sdd-agent-platform/core/src/status/project-status.test.ts +288 -511
  444. package/node_modules/@sdd-agent-platform/core/src/status/project-status.ts +651 -851
  445. package/node_modules/@sdd-agent-platform/core/src/status.ts +2 -2
  446. package/node_modules/@sdd-agent-platform/core/src/storage/json-io.ts +10 -10
  447. package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.test.ts +489 -681
  448. package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.ts +1981 -1981
  449. package/node_modules/@sdd-agent-platform/core/src/subagents/contracts.ts +45 -45
  450. package/node_modules/@sdd-agent-platform/core/src/subagents/runtime.test.ts +232 -232
  451. package/node_modules/@sdd-agent-platform/core/src/subagents/runtime.ts +307 -307
  452. package/node_modules/@sdd-agent-platform/core/src/subagents.ts +2 -2
  453. package/node_modules/@sdd-agent-platform/core/src/task-execution-contract.test.ts +141 -0
  454. package/node_modules/@sdd-agent-platform/core/src/task-execution-contract.ts +566 -0
  455. package/node_modules/@sdd-agent-platform/core/src/task-risk-profile.ts +193 -193
  456. package/node_modules/@sdd-agent-platform/core/src/test-support/fixtures.ts +413 -398
  457. package/node_modules/@sdd-agent-platform/core/src/test-support/run-state.ts +102 -56
  458. package/node_modules/@sdd-agent-platform/core/src/test-support.ts +2 -2
  459. package/node_modules/@sdd-agent-platform/core/src/truth-reconciliation.test.ts +72 -72
  460. package/node_modules/@sdd-agent-platform/core/src/truth-reconciliation.ts +9 -12
  461. package/node_modules/@sdd-agent-platform/core/src/verification/rendering.ts +137 -137
  462. package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.test.ts +77 -84
  463. package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.ts +77 -77
  464. package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.ts +455 -506
  465. package/node_modules/@sdd-agent-platform/core/src/verification/{goal-verify.test.ts → task-evidence-judgment.test.ts} +261 -261
  466. package/node_modules/@sdd-agent-platform/core/src/verification/{goal-verify.ts → task-evidence-judgment.ts} +619 -619
  467. package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.ts +1190 -1190
  468. package/node_modules/@sdd-agent-platform/core/src/verification/validation-cache.ts +106 -106
  469. package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.ts +513 -556
  470. package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.ts +334 -334
  471. package/node_modules/@sdd-agent-platform/core/src/verification.ts +8 -8
  472. package/node_modules/@sdd-agent-platform/core/src/work-units/contracts.ts +26 -26
  473. package/node_modules/@sdd-agent-platform/core/src/work-units/runtime.test.ts +88 -88
  474. package/node_modules/@sdd-agent-platform/core/src/work-units/runtime.ts +112 -112
  475. package/node_modules/@sdd-agent-platform/core/src/work-units.ts +2 -2
  476. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/evidence-packet.ts +190 -425
  477. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.test.ts +169 -507
  478. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.ts +136 -182
  479. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.test.ts +135 -174
  480. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.ts +153 -194
  481. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/types.ts +111 -115
  482. package/node_modules/@sdd-agent-platform/core/src/workflow-state/affected-file-conflicts.ts +95 -93
  483. package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.test.ts +32 -32
  484. package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.ts +114 -114
  485. package/node_modules/@sdd-agent-platform/core/src/workflow-state/latest-eligible-run.ts +184 -224
  486. package/node_modules/@sdd-agent-platform/core/src/workflow-state/migration-recovery.ts +158 -158
  487. package/node_modules/@sdd-agent-platform/core/src/workflow-state/repair-contract.ts +77 -77
  488. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve-task-run.ts +114 -114
  489. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.test.ts +969 -956
  490. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.ts +967 -992
  491. package/node_modules/@sdd-agent-platform/core/src/workflow-state/runtime-projections.ts +712 -712
  492. package/node_modules/@sdd-agent-platform/core/src/workflow-state.ts +2 -2
  493. package/node_modules/@sdd-agent-platform/core/src/worktree/isolation.ts +130 -130
  494. package/node_modules/@sdd-agent-platform/core/src/worktree/lifecycle.ts +269 -269
  495. package/node_modules/@sdd-agent-platform/core/src/worktree/worktree.test.ts +150 -150
  496. package/node_modules/@sdd-agent-platform/core/src/worktree.ts +2 -2
  497. package/node_modules/@sdd-agent-platform/core/tsconfig.json +15 -15
  498. package/package.json +2 -2
  499. package/packages/cli/dist/args.js +2 -2
  500. package/packages/cli/dist/args.js.map +1 -1
  501. package/packages/cli/dist/commands/ai-tools.js +2 -13
  502. package/packages/cli/dist/commands/ai-tools.js.map +1 -1
  503. package/packages/cli/dist/commands/{verifies.d.ts → artifact.d.ts} +1 -1
  504. package/packages/cli/dist/commands/artifact.js +168 -0
  505. package/packages/cli/dist/commands/artifact.js.map +1 -0
  506. package/packages/cli/dist/commands/context.js +1 -1
  507. package/packages/cli/dist/commands/context.js.map +1 -1
  508. package/packages/cli/dist/commands/evidence.js.map +1 -0
  509. package/packages/cli/dist/commands/execution.js +127 -49
  510. package/packages/cli/dist/commands/execution.js.map +1 -1
  511. package/packages/cli/dist/commands/governance.js +1 -1
  512. package/packages/cli/dist/commands/governance.js.map +1 -1
  513. package/packages/cli/dist/commands/init.js +1 -6
  514. package/packages/cli/dist/commands/init.js.map +1 -1
  515. package/packages/cli/dist/commands/instructions.d.ts +1 -1
  516. package/packages/cli/dist/commands/instructions.js +15 -1
  517. package/packages/cli/dist/commands/instructions.js.map +1 -1
  518. package/packages/cli/dist/commands/registry/runtime.js +63 -40
  519. package/packages/cli/dist/commands/registry/runtime.js.map +1 -1
  520. package/packages/cli/dist/commands/run.js +13 -52
  521. package/packages/cli/dist/commands/run.js.map +1 -1
  522. package/packages/cli/dist/commands/stage-close.d.ts +60 -0
  523. package/packages/cli/dist/commands/stage-close.js +270 -41
  524. package/packages/cli/dist/commands/stage-close.js.map +1 -1
  525. package/packages/cli/dist/commands/status.js +9 -68
  526. package/packages/cli/dist/commands/status.js.map +1 -1
  527. package/packages/cli/dist/commands/tasks.js.map +1 -1
  528. package/packages/cli/dist/dispatch.js +6 -26
  529. package/packages/cli/dist/dispatch.js.map +1 -1
  530. package/packages/cli/dist/help.js +153 -159
  531. package/packages/cli/dist/help.js.map +1 -1
  532. package/packages/cli/dist/renderers/artifacts.d.ts +5 -0
  533. package/packages/cli/dist/renderers/artifacts.js +43 -0
  534. package/packages/cli/dist/renderers/artifacts.js.map +1 -0
  535. package/packages/cli/dist/renderers/doctor.js +1 -2
  536. package/packages/cli/dist/renderers/doctor.js.map +1 -1
  537. package/packages/cli/dist/renderers/execution.js +1 -1
  538. package/packages/cli/dist/renderers/execution.js.map +1 -1
  539. package/packages/cli/dist/renderers/json.d.ts +0 -1
  540. package/packages/cli/dist/renderers/json.js +0 -3
  541. package/packages/cli/dist/renderers/json.js.map +1 -1
  542. package/packages/cli/dist/renderers/registry-runtime.d.ts +1 -2
  543. package/packages/cli/dist/renderers/registry-runtime.js +0 -20
  544. package/packages/cli/dist/renderers/registry-runtime.js.map +1 -1
  545. package/packages/cli/dist/renderers/router.js +1 -1
  546. package/packages/cli/dist/renderers/router.js.map +1 -1
  547. package/packages/cli/dist/renderers/workflow.d.ts +53 -0
  548. package/packages/cli/dist/renderers/workflow.js +93 -34
  549. package/packages/cli/dist/renderers/workflow.js.map +1 -1
  550. package/packages/cli/dist/tsconfig.tsbuildinfo +1 -1
  551. package/packages/cli/package.json +2 -2
  552. package/packages/core/dist/ai-tools.js +56 -73
  553. package/packages/core/dist/ai-tools.js.map +1 -1
  554. package/packages/core/dist/artifacts/ingestion.js +9 -64
  555. package/packages/core/dist/artifacts/ingestion.js.map +1 -1
  556. package/packages/core/dist/artifacts/sdd-evidence.js +1 -1
  557. package/packages/core/dist/artifacts/sdd-evidence.js.map +1 -1
  558. package/packages/core/dist/artifacts/sdd-result.js +17 -26
  559. package/packages/core/dist/artifacts/sdd-result.js.map +1 -1
  560. package/packages/core/dist/config/init-project.d.ts +8 -7
  561. package/packages/core/dist/config/init-project.js +8 -12
  562. package/packages/core/dist/config/init-project.js.map +1 -1
  563. package/packages/core/dist/config/project-config.d.ts +1 -1
  564. package/packages/core/dist/config/project-config.js +1 -1
  565. package/packages/core/dist/config/project-config.js.map +1 -1
  566. package/packages/core/dist/config/starter-documents.d.ts +3 -4
  567. package/packages/core/dist/config/starter-documents.js +377 -411
  568. package/packages/core/dist/config/starter-documents.js.map +1 -1
  569. package/packages/core/dist/context/build-package.d.ts +1 -1
  570. package/packages/core/dist/context/build-package.js +18 -25
  571. package/packages/core/dist/context/build-package.js.map +1 -1
  572. package/packages/core/dist/context/evidence-summary.js +8 -26
  573. package/packages/core/dist/context/evidence-summary.js.map +1 -1
  574. package/packages/core/dist/context/log-worker.js +2 -2
  575. package/packages/core/dist/context/log-worker.js.map +1 -1
  576. package/packages/core/dist/context-offload/contracts.d.ts +1 -1
  577. package/packages/core/dist/contracts.d.ts +6 -1
  578. package/packages/core/dist/contracts.js +5 -0
  579. package/packages/core/dist/contracts.js.map +1 -1
  580. package/packages/core/dist/delegation/model.d.ts +0 -3
  581. package/packages/core/dist/delegation/validation.d.ts +0 -3
  582. package/packages/core/dist/delegation/validation.js +4 -7
  583. package/packages/core/dist/delegation/validation.js.map +1 -1
  584. package/packages/core/dist/doctor/checks/document-chain.js +3 -13
  585. package/packages/core/dist/doctor/checks/document-chain.js.map +1 -1
  586. package/packages/core/dist/doctor/checks/local-run-index.js +1 -9
  587. package/packages/core/dist/doctor/checks/local-run-index.js.map +1 -1
  588. package/packages/core/dist/doctor/checks/project.js +9 -9
  589. package/packages/core/dist/doctor/checks/project.js.map +1 -1
  590. package/packages/core/dist/doctor/checks/registries.js +1 -0
  591. package/packages/core/dist/doctor/checks/registries.js.map +1 -1
  592. package/packages/core/dist/doctor/checks/run-evidence.js +4 -4
  593. package/packages/core/dist/doctor/checks/run-evidence.js.map +1 -1
  594. package/packages/core/dist/doctor/checks/run-trust.js +24 -0
  595. package/packages/core/dist/doctor/checks/run-trust.js.map +1 -1
  596. package/packages/core/dist/doctor/checks/runtime-contracts.js +2 -2
  597. package/packages/core/dist/doctor/checks/runtime-contracts.js.map +1 -1
  598. package/packages/core/dist/doctor/doctor.js +43 -180
  599. package/packages/core/dist/doctor/doctor.js.map +1 -1
  600. package/packages/core/dist/evidence/lookup.d.ts +1 -1
  601. package/packages/core/dist/evidence/lookup.js +7 -14
  602. package/packages/core/dist/evidence/lookup.js.map +1 -1
  603. package/packages/core/dist/evidence-runtime/coordination.js +110 -0
  604. package/packages/core/dist/evidence-runtime/coordination.js.map +1 -0
  605. package/packages/core/dist/execution/background-executor.js +4 -4
  606. package/packages/core/dist/execution/background-executor.js.map +1 -1
  607. package/packages/core/dist/execution/foreground-subagents.js +3 -3
  608. package/packages/core/dist/execution/foreground-subagents.js.map +1 -1
  609. package/packages/core/dist/execution/host-invocation.js +85 -86
  610. package/packages/core/dist/execution/host-invocation.js.map +1 -1
  611. package/packages/core/dist/execution/resident-worker.js +2 -3
  612. package/packages/core/dist/execution/resident-worker.js.map +1 -1
  613. package/packages/core/dist/execution/stage-team-runtime.js +2 -2
  614. package/packages/core/dist/execution/stage-team-runtime.js.map +1 -1
  615. package/packages/core/dist/governance/policy.d.ts +1 -1
  616. package/packages/core/dist/governance/policy.js +1 -1
  617. package/packages/core/dist/governance/policy.js.map +1 -1
  618. package/packages/core/dist/instructions.d.ts +1 -1
  619. package/packages/core/dist/instructions.js +31 -67
  620. package/packages/core/dist/instructions.js.map +1 -1
  621. package/packages/core/dist/lifecycle/decision-gate.js +1 -1
  622. package/packages/core/dist/lifecycle/decision-gate.js.map +1 -1
  623. package/packages/core/dist/lifecycle/ship.d.ts +0 -1
  624. package/packages/core/dist/lifecycle/ship.js +59 -85
  625. package/packages/core/dist/lifecycle/ship.js.map +1 -1
  626. package/packages/core/dist/lifecycle-graph/contracts.d.ts +159 -0
  627. package/packages/core/dist/lifecycle-graph/contracts.js +7 -0
  628. package/packages/core/dist/lifecycle-graph/contracts.js.map +1 -0
  629. package/packages/core/dist/lifecycle-graph/kernel.d.ts +16 -0
  630. package/packages/core/dist/lifecycle-graph/kernel.js +461 -0
  631. package/packages/core/dist/lifecycle-graph/kernel.js.map +1 -0
  632. package/packages/core/dist/lifecycle-graph.d.ts +2 -0
  633. package/packages/core/dist/lifecycle-graph.js +3 -0
  634. package/packages/core/dist/lifecycle-graph.js.map +1 -0
  635. package/packages/core/dist/orchestration/contracts.d.ts +1 -1
  636. package/packages/core/dist/orchestration/runtime.d.ts +2 -12
  637. package/packages/core/dist/orchestration/runtime.js +32 -80
  638. package/packages/core/dist/orchestration/runtime.js.map +1 -1
  639. package/packages/core/dist/registries/agent-capability-catalog.d.ts +2 -5
  640. package/packages/core/dist/registries/agent-capability-catalog.js +27 -69
  641. package/packages/core/dist/registries/agent-capability-catalog.js.map +1 -1
  642. package/packages/core/dist/registries/agent-registry.js +118 -34
  643. package/packages/core/dist/registries/agent-registry.js.map +1 -1
  644. package/packages/core/dist/registries/agent-runtime-static.js +1 -1
  645. package/packages/core/dist/registries/agent-runtime-static.js.map +1 -1
  646. package/packages/core/dist/registries/capability-sources.js +1 -1
  647. package/packages/core/dist/registries/command-team-runtime.d.ts +1 -1
  648. package/packages/core/dist/registries/command-team-runtime.js +8 -15
  649. package/packages/core/dist/registries/command-team-runtime.js.map +1 -1
  650. package/packages/core/dist/registries/eval-learning-context.js +4 -4
  651. package/packages/core/dist/registries/eval-learning-context.js.map +1 -1
  652. package/packages/core/dist/registries/plan-scout-domains.d.ts +13 -0
  653. package/packages/core/dist/registries/plan-scout-domains.js +76 -0
  654. package/packages/core/dist/registries/plan-scout-domains.js.map +1 -0
  655. package/packages/core/dist/registries/query-status.js +2 -2
  656. package/packages/core/dist/registries/query-status.js.map +1 -1
  657. package/packages/core/dist/registries/skill-capabilities.js +7 -7
  658. package/packages/core/dist/registries/skill-capabilities.js.map +1 -1
  659. package/packages/core/dist/registries/tool-capabilities.js +4 -4
  660. package/packages/core/dist/registries/tool-capabilities.js.map +1 -1
  661. package/packages/core/dist/registries/tool-plugins.js +2 -2
  662. package/packages/core/dist/registries/tool-plugins.js.map +1 -1
  663. package/packages/core/dist/registries/worker-adapters.js +11 -11
  664. package/packages/core/dist/registries/worker-adapters.js.map +1 -1
  665. package/packages/core/dist/registries/workflow-gates.d.ts +1 -1
  666. package/packages/core/dist/registries/workflow-gates.js +21 -21
  667. package/packages/core/dist/registries/workflow-gates.js.map +1 -1
  668. package/packages/core/dist/risk/consumer-diagnostics.js +2 -1
  669. package/packages/core/dist/risk/consumer-diagnostics.js.map +1 -1
  670. package/packages/core/dist/risk/kernel.js +6 -6
  671. package/packages/core/dist/risk/kernel.js.map +1 -1
  672. package/packages/core/dist/risk/legacy-adapters.js +11 -23
  673. package/packages/core/dist/risk/legacy-adapters.js.map +1 -1
  674. package/packages/core/dist/risk/workflow-gates.d.ts +2 -2
  675. package/packages/core/dist/risk/workflow-gates.js +18 -20
  676. package/packages/core/dist/risk/workflow-gates.js.map +1 -1
  677. package/packages/core/dist/router/agent-runtime.d.ts +0 -2
  678. package/packages/core/dist/router/route-projection.js +1 -1
  679. package/packages/core/dist/router/route-projection.js.map +1 -1
  680. package/packages/core/dist/router/routing.js +16 -48
  681. package/packages/core/dist/router/routing.js.map +1 -1
  682. package/packages/core/dist/router/runtime-import.js +11 -1
  683. package/packages/core/dist/router/runtime-import.js.map +1 -1
  684. package/packages/core/dist/router/runtime-validation.js +2 -2
  685. package/packages/core/dist/router/runtime-validation.js.map +1 -1
  686. package/packages/core/dist/router/stage-route-binding.d.ts +2 -2
  687. package/packages/core/dist/router/stage-route-binding.js +20 -28
  688. package/packages/core/dist/router/stage-route-binding.js.map +1 -1
  689. package/packages/core/dist/router.d.ts +0 -1
  690. package/packages/core/dist/router.js +0 -1
  691. package/packages/core/dist/router.js.map +1 -1
  692. package/packages/core/dist/run-state/artifacts.d.ts +6 -6
  693. package/packages/core/dist/run-state/artifacts.js +13 -124
  694. package/packages/core/dist/run-state/artifacts.js.map +1 -1
  695. package/packages/core/dist/run-state/inspect-run.d.ts +2 -0
  696. package/packages/core/dist/run-state/inspect-run.js +5 -7
  697. package/packages/core/dist/run-state/inspect-run.js.map +1 -1
  698. package/packages/core/dist/run-state/model.d.ts +28 -28
  699. package/packages/core/dist/run-state/run-index.d.ts +3 -2
  700. package/packages/core/dist/run-state/run-index.js +15 -66
  701. package/packages/core/dist/run-state/run-index.js.map +1 -1
  702. package/packages/core/dist/run-state/run-state.js +26 -36
  703. package/packages/core/dist/run-state/run-state.js.map +1 -1
  704. package/packages/core/dist/run-state/task-evidence.d.ts +0 -4
  705. package/packages/core/dist/run-state/task-evidence.js +5 -51
  706. package/packages/core/dist/run-state/task-evidence.js.map +1 -1
  707. package/packages/core/dist/run-state.d.ts +0 -1
  708. package/packages/core/dist/run-state.js +0 -1
  709. package/packages/core/dist/run-state.js.map +1 -1
  710. package/packages/core/dist/runtime-analysis/build.js +1 -1
  711. package/packages/core/dist/runtime-analysis/build.js.map +1 -1
  712. package/packages/core/dist/runtime-analysis/findings.js +7 -16
  713. package/packages/core/dist/runtime-analysis/findings.js.map +1 -1
  714. package/packages/core/dist/runtime-analysis/model.d.ts +1 -2
  715. package/packages/core/dist/runtime-paths.d.ts +0 -1
  716. package/packages/core/dist/runtime-paths.js +1 -4
  717. package/packages/core/dist/runtime-paths.js.map +1 -1
  718. package/packages/core/dist/runtime-projection-p0.d.ts +2 -2
  719. package/packages/core/dist/runtime-projection-p0.js +11 -0
  720. package/packages/core/dist/runtime-projection-p0.js.map +1 -1
  721. package/packages/core/dist/sdd-docs/artifact-depth.d.ts +14 -0
  722. package/packages/core/dist/sdd-docs/artifact-depth.js +179 -0
  723. package/packages/core/dist/sdd-docs/artifact-depth.js.map +1 -0
  724. package/packages/core/dist/sdd-docs/document-hashes.d.ts +0 -2
  725. package/packages/core/dist/sdd-docs/document-hashes.js +10 -97
  726. package/packages/core/dist/sdd-docs/document-hashes.js.map +1 -1
  727. package/packages/core/dist/sdd-docs/run-binding.d.ts +1 -1
  728. package/packages/core/dist/sdd-docs/run-binding.js +6 -8
  729. package/packages/core/dist/sdd-docs/run-binding.js.map +1 -1
  730. package/packages/core/dist/sdd-docs/task-parser.d.ts +5 -2
  731. package/packages/core/dist/sdd-docs/task-parser.js +85 -68
  732. package/packages/core/dist/sdd-docs/task-parser.js.map +1 -1
  733. package/packages/core/dist/sdd-docs/task-rendering.js +2 -2
  734. package/packages/core/dist/sdd-docs/task-rendering.js.map +1 -1
  735. package/packages/core/dist/spec-entry.js +40 -0
  736. package/packages/core/dist/spec-entry.js.map +1 -0
  737. package/packages/core/dist/spec-manager-contracts.d.ts +12 -0
  738. package/packages/core/dist/spec-manager-contracts.js +2 -0
  739. package/packages/core/dist/spec-manager-contracts.js.map +1 -0
  740. package/packages/core/dist/stage-artifacts.d.ts +2 -2
  741. package/packages/core/dist/stage-artifacts.js +19 -26
  742. package/packages/core/dist/stage-artifacts.js.map +1 -1
  743. package/packages/core/dist/stage-collaboration-contracts.d.ts +1 -1
  744. package/packages/core/dist/stage-collaboration-contracts.js +3 -6
  745. package/packages/core/dist/stage-collaboration-contracts.js.map +1 -1
  746. package/packages/core/dist/stage-collaboration.d.ts +111 -263
  747. package/packages/core/dist/stage-collaboration.js +1272 -1124
  748. package/packages/core/dist/stage-collaboration.js.map +1 -1
  749. package/packages/core/dist/stage-runtime/runtime.js +5 -5
  750. package/packages/core/dist/stage-runtime/runtime.js.map +1 -1
  751. package/packages/core/dist/status/project-status.d.ts +1 -44
  752. package/packages/core/dist/status/project-status.js +47 -170
  753. package/packages/core/dist/status/project-status.js.map +1 -1
  754. package/packages/core/dist/storage/runtime-store.js +73 -73
  755. package/packages/core/dist/subagents/contracts.d.ts +1 -1
  756. package/packages/core/dist/subagents/runtime.js +7 -7
  757. package/packages/core/dist/subagents/runtime.js.map +1 -1
  758. package/packages/core/dist/sync-back/apply.d.ts +1 -0
  759. package/packages/core/dist/sync-back/apply.js +2 -0
  760. package/packages/core/dist/sync-back/apply.js.map +1 -0
  761. package/packages/core/dist/sync-back/inspect.d.ts +1 -0
  762. package/packages/core/dist/sync-back/inspect.js +2 -0
  763. package/packages/core/dist/sync-back/inspect.js.map +1 -0
  764. package/packages/core/dist/sync-back.d.ts +1 -0
  765. package/packages/core/dist/sync-back.js +2 -0
  766. package/packages/core/dist/sync-back.js.map +1 -0
  767. package/packages/core/dist/task-execution-contract.d.ts +167 -0
  768. package/packages/core/dist/task-execution-contract.js +377 -0
  769. package/packages/core/dist/task-execution-contract.js.map +1 -0
  770. package/packages/core/dist/test-support/fixtures.js +329 -314
  771. package/packages/core/dist/test-support/fixtures.js.map +1 -1
  772. package/packages/core/dist/test-support/run-state.d.ts +1 -0
  773. package/packages/core/dist/test-support/run-state.js +53 -7
  774. package/packages/core/dist/test-support/run-state.js.map +1 -1
  775. package/packages/core/dist/truth-reconciliation.js +9 -12
  776. package/packages/core/dist/truth-reconciliation.js.map +1 -1
  777. package/packages/core/dist/tsconfig.tsbuildinfo +1 -1
  778. package/packages/core/dist/verification/goal-verify.d.ts +0 -48
  779. package/packages/core/dist/verification/goal-verify.js +1 -520
  780. package/packages/core/dist/verification/goal-verify.js.map +1 -1
  781. package/packages/core/dist/verification/rendering.d.ts +5 -5
  782. package/packages/core/dist/verification/rendering.js +14 -14
  783. package/packages/core/dist/verification/rendering.js.map +1 -1
  784. package/packages/core/dist/verification/single-task-loop.d.ts +1 -0
  785. package/packages/core/dist/verification/single-task-loop.js +111 -159
  786. package/packages/core/dist/verification/single-task-loop.js.map +1 -1
  787. package/packages/core/dist/verification/task-evidence-judgment.d.ts +49 -0
  788. package/packages/core/dist/verification/task-evidence-judgment.js +521 -0
  789. package/packages/core/dist/verification/task-evidence-judgment.js.map +1 -0
  790. package/packages/core/dist/verification/test-runtime.js +21 -21
  791. package/packages/core/dist/verification/test-runtime.js.map +1 -1
  792. package/packages/core/dist/verification/validation-wave.d.ts +0 -18
  793. package/packages/core/dist/verification/validation-wave.js +5 -27
  794. package/packages/core/dist/verification/validation-wave.js.map +1 -1
  795. package/packages/core/dist/verification/verify-contract.js +45 -45
  796. package/packages/core/dist/verification/verify-contract.js.map +1 -1
  797. package/packages/core/dist/verification.d.ts +3 -3
  798. package/packages/core/dist/verification.js +2 -2
  799. package/packages/core/dist/verification.js.map +1 -1
  800. package/packages/core/dist/work-units/contracts.d.ts +1 -1
  801. package/packages/core/dist/workflow-gate/evidence-packet.js +9 -227
  802. package/packages/core/dist/workflow-gate/evidence-packet.js.map +1 -1
  803. package/packages/core/dist/workflow-gate/hard-checks.js +9 -50
  804. package/packages/core/dist/workflow-gate/hard-checks.js.map +1 -1
  805. package/packages/core/dist/workflow-gate/policy.js +4 -42
  806. package/packages/core/dist/workflow-gate/policy.js.map +1 -1
  807. package/packages/core/dist/workflow-gate/types.d.ts +2 -3
  808. package/packages/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
  809. package/packages/core/dist/workflow-state/affected-file-conflicts.js +2 -1
  810. package/packages/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
  811. package/packages/core/dist/workflow-state/dependencies.js +1 -1
  812. package/packages/core/dist/workflow-state/latest-eligible-run.d.ts +1 -0
  813. package/packages/core/dist/workflow-state/latest-eligible-run.js +23 -63
  814. package/packages/core/dist/workflow-state/latest-eligible-run.js.map +1 -1
  815. package/packages/core/dist/workflow-state/resolve.d.ts +2 -2
  816. package/packages/core/dist/workflow-state/resolve.js +43 -65
  817. package/packages/core/dist/workflow-state/resolve.js.map +1 -1
  818. package/packages/core/package.json +5 -2
  819. package/tsconfig.build.json +6 -7
  820. package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.test.ts +0 -269
  821. package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.test.ts +0 -492
  822. package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.test.ts +0 -383
  823. package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.test.ts +0 -188
  824. package/packages/cli/dist/commands/lifecycle.d.ts +0 -6
  825. package/packages/cli/dist/commands/lifecycle.js +0 -125
  826. package/packages/cli/dist/commands/lifecycle.js.map +0 -1
  827. package/packages/cli/dist/commands/test.d.ts +0 -6
  828. package/packages/cli/dist/commands/test.js +0 -373
  829. package/packages/cli/dist/commands/test.js.map +0 -1
  830. package/packages/cli/dist/commands/verifies.js +0 -87
  831. package/packages/cli/dist/commands/verifies.js.map +0 -1
  832. package/packages/cli/dist/commands/verify.d.ts +0 -6
  833. package/packages/cli/dist/commands/verify.js +0 -330
  834. package/packages/cli/dist/commands/verify.js.map +0 -1
@@ -1,709 +1,738 @@
1
- import { hashDocumentContent, hashNormalizedMarkdownContent, hashSemanticDocument, hashTasksContract } from './document-hashes.js';
2
- import { readdir, readFile } from 'node:fs/promises';
3
- import path from 'node:path';
4
- import { assertSafePathSegment } from '../path-safety.js';
5
- import { exists } from '../storage/json-io.js';
6
-
7
- export type SddTaskStatus = 'pending' | 'in_progress' | 'completed' | 'blocked' | 'deferred' | 'unknown';
8
- export type SddChangeSurface = 'frontend_only' | 'backend_only' | 'full_stack' | 'docs_only' | 'config_only' | 'unknown';
9
- export type SddValidationTiming = 'task_end' | 'batch_end' | 'wave_end';
10
- export type SddGapSeverity = 'blocking' | 'warning';
11
- export type SddGapType = 'Document Gap' | 'Task Gap' | 'Dependency Gap';
12
-
13
- export interface SddTaskSourceLocation {
14
- filePath: string;
15
- heading: string | null;
16
- lineStart: number;
17
- lineEnd: number;
18
- }
19
-
20
- export interface SddValidationCommand {
21
- command: string;
22
- acceptanceRefs: string[];
23
- raw: string;
24
- }
25
-
26
- export interface SddTask {
27
- id: string;
28
- contractHash: string;
29
- title: string | null;
30
- status: SddTaskStatus;
31
- wave: number | null;
32
- implementationWave: string | null;
33
- validationBatch: string | null;
34
- validationTiming: SddValidationTiming;
35
- requiresVerifyBeforeNext: boolean;
36
- changeSurface: SddChangeSurface;
37
- dependsOn: string[];
38
- affectedFiles: string[];
39
- validation: string[];
40
- validationCommands: SddValidationCommand[];
41
- risk: string[];
42
- acceptanceRefs: string[];
43
- planRefs: string[];
44
- fileOwnership: string[];
45
- agentFit: string[];
46
- verificationAvailability: string[];
47
- autonomy: string | null;
48
- allowedAgents: string[];
49
- requiredArtifacts: string[];
50
- gapState: string | null;
51
- boundary: string | null;
52
- acceptance: string[];
53
- implementationNotes: string | null;
54
- rawMetadata: Record<string, string | string[]>;
55
- source: SddTaskSourceLocation;
56
- }
57
-
58
- export interface SddTaskGap {
59
- type: SddGapType;
60
- severity: SddGapSeverity;
61
- taskId: string | null;
62
- field: string;
63
- message: string;
64
- recommendation: string;
65
- }
66
-
67
- export interface SddTaskModel {
68
- branch: string;
69
- specPath: string;
70
- planPath: string;
71
- tasksPath: string;
72
- verifyPath: string;
73
- documents: {
74
- specExists: boolean;
75
- planExists: boolean;
76
- tasksExists: boolean;
77
- verifyExists: boolean;
78
- specHash?: string | null;
79
- planHash?: string | null;
80
- tasksHash?: string | null;
81
- verifyHash?: string | null;
82
- specDocHash?: string | null;
83
- planDocHash?: string | null;
84
- tasksDocHash?: string | null;
85
- verifyDocHash?: string | null;
86
- specContractHash?: string | null;
87
- planContractHash?: string | null;
88
- tasksContractHash?: string | null;
89
- verifyContractHash?: string | null;
90
- planBasedOnSpecHash?: string | null;
91
- tasksBasedOnPlanHash?: string | null;
92
- verifyBasedOnTasksHash?: string | null;
93
- planBasedOnSpecContractHash?: string | null;
94
- tasksBasedOnPlanContractHash?: string | null;
95
- verifyBasedOnTasksContractHash?: string | null;
96
- planStale?: boolean;
97
- tasksStale?: boolean;
98
- verifyStale?: boolean;
99
- };
100
- tasks: SddTask[];
101
- gaps: SddTaskGap[];
102
- }
103
-
104
- export async function parseSddBranch(projectRoot: string, branch = 'master'): Promise<SddTaskModel> {
105
- assertSafePathSegment(branch, 'branch');
106
- const specPath = path.join(projectRoot, 'specs', branch, 'spec.md');
107
- const planPath = path.join(projectRoot, 'specs', branch, 'plan.md');
108
- const tasksPath = path.join(projectRoot, 'specs', branch, 'tasks.md');
109
- const verifyPath = path.join(projectRoot, 'specs', branch, 'verify.md');
110
- const [specExists, planExists, tasksExists, verifyExists] = await Promise.all([exists(specPath), exists(planPath), exists(tasksPath), exists(verifyPath)]);
111
- const [rawSpec, rawPlan, rawTasks, rawVerify] = await Promise.all([
112
- specExists ? readFile(specPath, 'utf8') : Promise.resolve(null),
113
- planExists ? readFile(planPath, 'utf8') : Promise.resolve(null),
114
- tasksExists ? readFile(tasksPath, 'utf8') : Promise.resolve(null),
115
- verifyExists ? readFile(verifyPath, 'utf8') : Promise.resolve(null)
116
- ]);
117
- const documents = buildDocumentChainState({ specExists, planExists, tasksExists, verifyExists, rawSpec, rawPlan, rawTasks, rawVerify });
118
- const gaps: SddTaskGap[] = [];
119
-
120
- if (!specExists) {
121
- gaps.push(documentGap('spec.md', 'Spec document is missing.', 'Create or restore specs/<branch>/spec.md before full SDD execution.'));
122
- }
123
- if (!planExists) {
124
- gaps.push(documentGap('plan.md', 'Plan document is missing.', 'Create or restore specs/<branch>/plan.md before task execution.'));
125
- }
126
- if (!tasksExists || rawTasks === null) {
127
- gaps.push(documentGap('tasks.md', 'Tasks document is missing.', 'Create specs/<branch>/tasks.md with sdd-task fenced blocks.'));
128
- return {
129
- branch,
130
- specPath,
131
- planPath,
132
- tasksPath,
133
- verifyPath,
134
- documents,
135
- tasks: [],
136
- gaps
137
- };
138
- }
139
-
140
- const taskModel = parseSddTasksMarkdown(rawTasks, { tasksPath });
141
- if (taskModel.tasks.length === 0 && !path.basename(tasksPath).startsWith('phase')) {
142
- const retainedModel = await parseRetainedPhaseTasks(path.dirname(tasksPath));
143
- if (retainedModel.tasks.length > 0) {
144
- return {
145
- branch,
146
- specPath,
147
- planPath,
148
- tasksPath,
149
- verifyPath,
150
- documents,
151
- tasks: retainedModel.tasks,
152
- gaps: [...gaps, ...retainedModel.gaps]
153
- };
154
- }
155
- }
156
- return {
157
- branch,
158
- specPath,
159
- planPath,
160
- tasksPath,
161
- verifyPath,
162
- documents,
163
- tasks: taskModel.tasks,
164
- gaps: [...gaps, ...taskModel.gaps]
165
- };
166
- }
167
-
168
- export function parseSddTasksMarkdown(raw: string, options: { branch?: string; tasksPath?: string; validateDependencies?: boolean } = {}): Pick<SddTaskModel, 'tasks' | 'gaps'> {
169
- const tasksPath = options.tasksPath ?? 'tasks.md';
170
- const fencedBlocks = Array.from(raw.matchAll(/^\s*```sdd-task\s*\r?\n([\s\S]*?)\r?^\s*```\s*$/gm));
171
- const tasks: SddTask[] = [];
172
- const gaps: SddTaskGap[] = [];
173
-
174
- if (fencedBlocks.length === 0) {
175
- gaps.push({
176
- type: 'Task Gap',
177
- severity: 'blocking',
178
- taskId: null,
179
- field: 'sdd-task',
180
- message: 'No sdd-task fenced blocks found in tasks.md.',
181
- recommendation: 'Add one sdd-task fenced block per executable task.'
182
- });
183
- return { tasks, gaps };
184
- }
185
-
186
- const seenIds = new Map<string, SddTaskSourceLocation>();
187
- for (let blockIndex = 0; blockIndex < fencedBlocks.length; blockIndex += 1) {
188
- const blockMatch = fencedBlocks[blockIndex];
189
- const block = blockMatch[1] ?? '';
190
- const blockStart = blockMatch.index ?? 0;
191
- const blockEnd = blockStart + blockMatch[0].length;
192
- const nextBlockStart = fencedBlocks[blockIndex + 1]?.index ?? raw.length;
193
- const lineStart = lineNumberAt(raw, blockStart);
194
- const lineEnd = lineNumberAt(raw, blockEnd);
195
- const heading = nearestTaskHeading(raw.slice(0, blockStart));
196
- const metadata = parseSimpleYamlBlock(block);
197
- const id = scalarValue(metadata.id);
198
- const taskId = id || heading?.id || null;
199
- const section = raw.slice(blockEnd, nextTaskStart(raw, blockEnd, nextBlockStart));
200
- const parsedSections = parseTaskCompanionSections(section);
201
- if (!taskId) {
202
- gaps.push({
203
- type: 'Task Gap',
204
- severity: 'blocking',
205
- taskId: null,
206
- field: 'id',
207
- message: `sdd-task block starting at line ${lineStart} is missing id.`,
208
- recommendation: 'Add a stable id field such as id: T1.'
209
- });
210
- continue;
211
- }
212
-
213
- const source: SddTaskSourceLocation = {
214
- filePath: tasksPath,
215
- heading: heading?.raw ?? null,
216
- lineStart,
217
- lineEnd
218
- };
219
- const priorSource = seenIds.get(taskId);
220
- if (priorSource) {
221
- gaps.push({
222
- type: 'Task Gap',
223
- severity: 'blocking',
224
- taskId,
225
- field: 'id',
226
- message: `Duplicate task id ${taskId} in ${taskSourceEvidence({ id: taskId, source })} and ${sourceLocationEvidence(priorSource)}.`,
227
- recommendation: 'Keep task ids unique within a spec branch.'
228
- });
229
- }
230
- seenIds.set(taskId, source);
231
-
232
- const contractHash = hashTaskContract({ taskId, headingTitle: heading?.title ?? null, metadata, parsedSections });
233
- const task: SddTask = {
234
- id: taskId,
235
- contractHash,
236
- title: heading?.title ?? null,
237
- status: parseTaskStatus(scalarValue(metadata.status)),
238
- wave: parseWave(scalarValue(metadata.wave)),
239
- implementationWave: scalarValue(metadata.implementation_wave),
240
- validationBatch: scalarValue(metadata.validation_batch),
241
- validationTiming: parseValidationTiming(scalarValue(metadata.validation_timing)),
242
- requiresVerifyBeforeNext: parseRequiresVerifyBeforeNext(scalarValue(metadata.requires_verify_before_next)),
243
- changeSurface: parseChangeSurface(scalarValue(metadata.change_surface)),
244
- dependsOn: listValue(metadata.depends_on),
245
- affectedFiles: listValue(metadata.affected_files),
246
- validation: parseValidationCommands(metadata.validation).map((command) => command.command),
247
- validationCommands: parseValidationCommands(metadata.validation),
248
- risk: listValue(metadata.risk),
249
- acceptanceRefs: listValue(metadata.acceptance_refs),
250
- planRefs: listValue(metadata.plan_refs),
251
- fileOwnership: listValue(metadata.file_ownership),
252
- agentFit: listValue(metadata.agent_fit),
253
- verificationAvailability: listValue(metadata.verification_availability),
254
- autonomy: scalarValue(metadata.autonomy),
255
- allowedAgents: listValue(metadata.allowed_agents),
256
- requiredArtifacts: listValue(metadata.required_artifacts),
257
- gapState: scalarValue(metadata.gap_state),
258
- boundary: parsedSections.boundary,
259
- acceptance: parsedSections.acceptance,
260
- implementationNotes: parsedSections.implementationNotes,
261
- rawMetadata: metadata,
262
- source
263
- };
264
- tasks.push(task);
265
- gaps.push(...validateTask(task));
266
- }
267
-
268
- if (options.validateDependencies !== false) {
269
- gaps.push(...validateAggregateTaskSet(tasks));
270
- }
271
-
272
- return { tasks, gaps };
273
- }
274
-
275
- function buildDocumentChainState(input: { specExists: boolean; planExists: boolean; tasksExists: boolean; verifyExists: boolean; rawSpec: string | null; rawPlan: string | null; rawTasks: string | null; rawVerify: string | null }): SddTaskModel['documents'] {
276
- const specDocHash = input.rawSpec === null ? null : hashDocumentContent(input.rawSpec);
277
- const planDocHash = input.rawPlan === null ? null : hashDocumentContent(input.rawPlan);
278
- const tasksDocHash = input.rawTasks === null ? null : hashDocumentContent(input.rawTasks);
279
- const verifyDocHash = input.rawVerify === null ? null : hashDocumentContent(input.rawVerify);
280
- const specContractHash = hashNormalizedMarkdownContent(input.rawSpec);
281
- const planContractHash = hashNormalizedMarkdownContent(input.rawPlan);
282
- const tasksContractHash = hashTasksContract(input.rawTasks);
283
- const verifyContractHash = hashSemanticDocument(input.rawVerify);
284
- const planBasedOnSpecHash = null;
285
- const tasksBasedOnPlanHash = null;
286
- const verifyBasedOnTasksHash = null;
287
- const planBasedOnSpecContractHash = null;
288
- const tasksBasedOnPlanContractHash = null;
289
- const verifyBasedOnTasksContractHash = null;
290
- const planStale = false;
291
- const tasksHashMismatch = false;
292
- const verifyHashMismatch = false;
293
-
294
- return {
295
- specExists: input.specExists,
296
- planExists: input.planExists,
297
- tasksExists: input.tasksExists,
298
- verifyExists: input.verifyExists,
299
- specHash: specDocHash,
300
- planHash: planDocHash,
301
- tasksHash: tasksDocHash,
302
- verifyHash: verifyDocHash,
303
- specDocHash,
304
- planDocHash,
305
- tasksDocHash,
306
- verifyDocHash,
307
- specContractHash,
308
- planContractHash,
309
- tasksContractHash,
310
- verifyContractHash,
311
- planBasedOnSpecHash,
312
- tasksBasedOnPlanHash,
313
- verifyBasedOnTasksHash,
314
- planBasedOnSpecContractHash,
315
- tasksBasedOnPlanContractHash,
316
- verifyBasedOnTasksContractHash,
317
- planStale,
318
- tasksStale: planStale || tasksHashMismatch,
319
- verifyStale: planStale || tasksHashMismatch || verifyHashMismatch
320
- };
321
- }
322
-
323
-
324
- async function parseRetainedPhaseTasks(specBranchDir: string): Promise<Pick<SddTaskModel, 'tasks' | 'gaps'>> {
325
- const entries = await readdir(specBranchDir, { withFileTypes: true });
326
- const taskFiles = entries
327
- .filter((entry) => entry.isFile() && /^phase\d+\.\d+-tasks\.md$/.test(entry.name))
328
- .map((entry) => path.join(specBranchDir, entry.name))
329
- .sort();
330
- const tasks: SddTask[] = [];
331
- const gaps: SddTaskGap[] = [];
332
- for (const taskFile of taskFiles) {
333
- const raw = await readFile(taskFile, 'utf8');
334
- const parsed = parseSddTasksMarkdown(raw, { tasksPath: taskFile, validateDependencies: false });
335
- tasks.push(...parsed.tasks);
336
- gaps.push(...parsed.gaps);
337
- }
338
- gaps.push(...validateAggregateTaskSet(tasks));
339
- return { tasks, gaps };
340
- }
341
-
342
- function documentGap(field: string, message: string, recommendation: string): SddTaskGap {
343
- return {
344
- type: 'Document Gap',
345
- severity: 'blocking',
346
- taskId: null,
347
- field,
348
- message,
349
- recommendation
350
- };
351
- }
352
-
353
- function parseTaskStatus(value: string | null): SddTaskStatus {
354
- if (value === 'pending' || value === 'in_progress' || value === 'completed' || value === 'blocked' || value === 'deferred') {
355
- return value;
356
- }
357
- return 'unknown';
358
- }
359
-
360
- function parseWave(value: string | null): number | null {
361
- if (!value) {
362
- return null;
363
- }
364
- const parsed = Number(value);
365
- return Number.isInteger(parsed) && parsed > 0 ? parsed : null;
366
- }
367
-
368
- function parseChangeSurface(value: string | null): SddChangeSurface {
369
- if (value === 'frontend_only' || value === 'backend_only' || value === 'full_stack' || value === 'docs_only' || value === 'config_only' || value === 'unknown') {
370
- return value;
371
- }
372
- return 'unknown';
373
- }
374
-
375
- function parseValidationTiming(value: string | null): SddValidationTiming {
376
- if (value === 'batch_end' || value === 'wave_end') {
377
- return value;
378
- }
379
- return 'task_end';
380
- }
381
-
382
- function parseRequiresVerifyBeforeNext(value: string | null): boolean {
383
- return value === 'false' ? false : true;
384
- }
385
-
386
- function isValidChangeSurface(value: string | null): boolean {
387
- return value === null || value === 'frontend_only' || value === 'backend_only' || value === 'full_stack' || value === 'docs_only' || value === 'config_only' || value === 'unknown';
388
- }
389
-
390
- function isValidValidationTiming(value: string | null): boolean {
391
- return value === null || value === 'task_end' || value === 'batch_end' || value === 'wave_end';
392
- }
393
-
394
- function isValidBooleanScalar(value: string | null): boolean {
395
- return value === null || value === 'true' || value === 'false';
396
- }
397
-
398
- function parseSimpleYamlBlock(raw: string): Record<string, string | string[]> {
399
- const result: Record<string, string | string[]> = {};
400
- const lines = raw.split(/\r?\n/);
401
- let currentListKey: string | null = null;
402
-
403
- for (const line of lines) {
404
- const trimmed = line.trim();
405
- if (!trimmed || trimmed.startsWith('#')) {
406
- continue;
407
- }
408
- if (currentListKey && /^-\s+/.test(trimmed)) {
409
- const current = result[currentListKey];
410
- const items = Array.isArray(current) ? current : [];
411
- items.push(unquoteSimpleYamlValue(trimmed.slice(2).trim()));
412
- result[currentListKey] = items;
413
- continue;
414
- }
415
-
416
- const scalarMatch = trimmed.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
417
- if (!scalarMatch) {
418
- currentListKey = null;
419
- continue;
420
- }
421
- const key = scalarMatch[1];
422
- const value = scalarMatch[2].trim();
423
- if (value === '') {
424
- result[key] = [];
425
- currentListKey = key;
426
- } else if (value === '[]') {
427
- result[key] = [];
428
- currentListKey = null;
429
- } else if (value.startsWith('[') && value.endsWith(']')) {
430
- result[key] = value.slice(1, -1).split(',').map((item) => unquoteSimpleYamlValue(item.trim())).filter(Boolean);
431
- currentListKey = null;
432
- } else {
433
- result[key] = unquoteSimpleYamlValue(value);
434
- currentListKey = null;
435
- }
436
- }
437
-
438
- return result;
439
- }
440
-
441
- function unquoteSimpleYamlValue(value: string): string {
442
- if (value.length >= 2) {
443
- const first = value[0];
444
- const last = value[value.length - 1];
445
- if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
446
- return value.slice(1, -1);
447
- }
448
- }
449
- return value;
450
- }
451
-
452
- function scalarValue(value: string | string[] | undefined): string | null {
453
- return typeof value === 'string' && value.length > 0 ? value : null;
454
- }
455
-
456
- function listValue(value: string | string[] | undefined): string[] {
457
- if (Array.isArray(value)) {
458
- return value.filter(Boolean);
459
- }
460
- if (!value || value === '[]') {
461
- return [];
462
- }
463
- return [value];
464
- }
465
-
466
- function parseValidationCommands(value: string | string[] | undefined): SddValidationCommand[] {
467
- return listValue(value).map(parseValidationCommand);
468
- }
469
-
470
- function parseValidationCommand(raw: string): SddValidationCommand {
471
- const separator = raw.match(/\s=>\s/);
472
- if (!separator || separator.index === undefined) {
473
- return { command: raw, acceptanceRefs: [], raw };
474
- }
475
- const command = raw.slice(0, separator.index).trim();
476
- const refsRaw = raw.slice(separator.index + separator[0].length).trim();
477
- return {
478
- command: command || raw,
479
- acceptanceRefs: parseAcceptanceRefList(refsRaw),
480
- raw
481
- };
482
- }
483
-
484
- function parseAcceptanceRefList(raw: string): string[] {
485
- const trimmed = raw.replace(/^\[/, '').replace(/\]$/, '').trim();
486
- if (!trimmed) {
487
- return [];
488
- }
489
- return trimmed.split(',').map((item) => unquoteSimpleYamlValue(item.trim())).filter(Boolean);
490
- }
491
-
492
- function lineNumberAt(raw: string, offset: number): number {
493
- return raw.slice(0, offset).split(/\r?\n/).length;
494
- }
495
-
496
- function nearestTaskHeading(prefix: string): { raw: string; id: string | null; title: string | null } | null {
497
- const matches = Array.from(prefix.matchAll(/^\s*#{2,3}\s+(.+)$/gm));
498
- const last = matches.at(-1);
499
- if (!last) {
500
- return null;
501
- }
502
- const raw = last[1].trim();
503
- const parsed = raw.match(/^([^::\s]+)\s*[::]\s*(.+)$/);
504
- return {
505
- raw,
506
- id: parsed?.[1]?.trim() ?? null,
507
- title: parsed?.[2]?.trim() ?? raw
508
- };
509
- }
510
-
511
- function nextTaskStart(raw: string, offset: number, limit = raw.length): number {
512
- const next = raw.slice(offset, limit).search(/^\s*#{2,3}\s+/m);
513
- return next < 0 ? limit : offset + next;
514
- }
515
-
516
- function parseTaskCompanionSections(raw: string): { boundary: string | null; acceptance: string[]; implementationNotes: string | null } {
517
- return {
518
- boundary: sectionText(raw, 'Boundary'),
519
- acceptance: sectionBullets(raw, 'Acceptance'),
520
- implementationNotes: sectionText(raw, 'Implementation Notes')
521
- };
522
- }
523
-
524
- function hashTaskContract(input: { taskId: string; headingTitle: string | null; metadata: Record<string, string | string[]>; parsedSections: { boundary: string | null; acceptance: string[]; implementationNotes: string | null } }): string {
525
- return hashDocumentContent(JSON.stringify({
526
- id: input.taskId,
527
- title: input.headingTitle,
528
- metadata: {
529
- id: normalizedTaskContractValue(input.metadata.id),
530
- wave: normalizedTaskContractValue(input.metadata.wave),
531
- depends_on: normalizedTaskContractValue(input.metadata.depends_on),
532
- acceptance_refs: normalizedTaskContractValue(input.metadata.acceptance_refs),
533
- plan_refs: normalizedTaskContractValue(input.metadata.plan_refs),
534
- affected_files: normalizedTaskContractValue(input.metadata.affected_files),
535
- change_surface: normalizedTaskContractValue(input.metadata.change_surface),
536
- implementation_wave: normalizedTaskContractValue(input.metadata.implementation_wave),
537
- validation_batch: normalizedTaskContractValue(input.metadata.validation_batch),
538
- validation_timing: normalizedTaskContractValue(input.metadata.validation_timing),
539
- requires_verify_before_next: normalizedTaskContractValue(input.metadata.requires_verify_before_next),
540
- validation: normalizedTaskContractValue(input.metadata.validation),
541
- risk: normalizedTaskContractValue(input.metadata.risk),
542
- required_artifacts: normalizedTaskContractValue(input.metadata.required_artifacts),
543
- allowed_agents: normalizedTaskContractValue(input.metadata.allowed_agents),
544
- verification_availability: normalizedTaskContractValue(input.metadata.verification_availability),
545
- autonomy: normalizedTaskContractValue(input.metadata.autonomy),
546
- validation_wave: normalizedTaskContractValue(input.metadata.validation_wave),
547
- review_gate: normalizedTaskContractValue(input.metadata.review_gate)
548
- },
549
- sections: input.parsedSections
550
- }));
551
- }
552
-
553
- function normalizedTaskContractValue(value: string | string[] | undefined): string | string[] | null {
554
- if (Array.isArray(value)) {
555
- return value.map((item) => item.trim()).filter(Boolean);
556
- }
557
- if (typeof value === 'string') {
558
- const trimmed = value.trim();
559
- return trimmed ? trimmed : null;
560
- }
561
- return null;
562
- }
563
-
564
- function sectionText(raw: string, title: string): string | null {
565
- const escaped = title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
566
- const sectionPattern = `^\\s*####\\s+${escaped}\\s*$([\\s\\S]*?)(?=^\\s*####\\s+|^\\s*#{2,3}\\s+|$(?![\\s\\S]))`;
567
- const match = raw.match(new RegExp(sectionPattern, 'im'));
568
- const text = match?.[1]?.trim() ?? '';
569
- return text.length > 0 ? text : null;
570
- }
571
-
572
- function sectionBullets(raw: string, title: string): string[] {
573
- const text = sectionText(raw, title);
574
- if (!text) {
575
- return [];
576
- }
577
- return text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.startsWith('- ')).map((line) => line.slice(2).trim()).filter(Boolean);
578
- }
579
-
580
- function validateTask(task: SddTask): SddTaskGap[] {
581
- const gaps: SddTaskGap[] = [];
582
- const requiredLists: Array<[keyof SddTask, string]> = [
583
- ['affectedFiles', 'affected_files'],
584
- ['validation', 'validation']
585
- ];
586
-
587
- if (task.status === 'unknown') {
588
- gaps.push(taskGap(task.id, 'status', 'Task status is missing or unsupported.', 'Use one of pending, in_progress, completed, blocked, deferred.'));
589
- }
590
- if (task.wave === null) {
591
- gaps.push(taskGap(task.id, 'wave', 'Task wave is missing or invalid.', 'Add a positive integer wave value.'));
592
- }
593
- if (!isValidChangeSurface(scalarValue(task.rawMetadata.change_surface))) {
594
- gaps.push(taskGap(task.id, 'change_surface', `Task ${task.id} has invalid change_surface.`, 'Use one of frontend_only, backend_only, full_stack, docs_only, config_only, unknown.'));
595
- }
596
- if (!isValidValidationTiming(scalarValue(task.rawMetadata.validation_timing))) {
597
- gaps.push(taskGap(task.id, 'validation_timing', `Task ${task.id} has invalid validation_timing.`, 'Use one of task_end, batch_end, wave_end.'));
598
- }
599
- if (!isValidBooleanScalar(scalarValue(task.rawMetadata.requires_verify_before_next))) {
600
- gaps.push(taskGap(task.id, 'requires_verify_before_next', `Task ${task.id} has invalid requires_verify_before_next.`, 'Use true or false.'));
601
- }
602
- if ((task.validationTiming === 'batch_end' || task.validationTiming === 'wave_end') && !task.validationBatch) {
603
- gaps.push(taskGap(task.id, 'validation_batch', `Task ${task.id} uses ${task.validationTiming} but has no validation_batch.`, 'Declare validation_batch so batch/wave validation can group implementation evidence before /sdd:test.'));
604
- }
605
- if ((task.validationTiming === 'batch_end' || task.validationTiming === 'wave_end') && task.requiresVerifyBeforeNext) {
606
- gaps.push(taskGap(task.id, 'requires_verify_before_next', `Task ${task.id} uses ${task.validationTiming} but requires verify before next.`, 'Set requires_verify_before_next: false for batch/wave validation, or use validation_timing: task_end for strict validation.'));
607
- }
608
- for (const [property, field] of requiredLists) {
609
- if ((task[property] as unknown[]).length === 0) {
610
- gaps.push(taskGap(task.id, field, `Task ${task.id} has no ${field}.`, `Declare ${field} in the sdd-task block before implementation.`));
611
- }
612
- }
613
- if ((task.changeSurface === 'frontend_only' || isFrontendOnlyTask(task)) && task.validation.some(isBackendBuildValidationCommand)) {
614
- gaps.push(taskGap(task.id, 'validation', `Task ${task.id} is frontend-only but declares backend build validation.`, 'For JSP/static frontend-only changes, replace Maven/Gradle validation with frontend-appropriate checks, dev-server/manual page evidence, lint/typecheck, or an explicit unavailable reason.'));
615
- }
616
- if (!task.boundary) {
617
- gaps.push(taskGap(task.id, 'Boundary', `Task ${task.id} has no Boundary section.`, 'Add a #### Boundary section describing allowed and forbidden scope.'));
618
- }
619
- if (task.acceptance.length === 0) {
620
- gaps.push(taskGap(task.id, 'Acceptance', `Task ${task.id} has no acceptance items.`, 'Add verifiable bullets under #### Acceptance.'));
621
- }
622
- return gaps;
623
- }
624
-
625
- export function isFrontendOnlyTask(task: SddTask): boolean {
626
- return task.affectedFiles.length > 0 && task.affectedFiles.every(isFrontendOnlyPath);
627
- }
628
-
629
- function isFrontendOnlyPath(filePath: string): boolean {
630
- const normalized = filePath.toLowerCase().replace(/\\/g, '/');
631
- return /\.(jsp|html|htm|css|scss|sass|less|js|jsx|ts|tsx|vue|svelte|png|jpg|jpeg|gif|svg|webp|ico)$/.test(normalized)
632
- && !normalized.includes('/src/main/java/')
633
- && !normalized.includes('/src/test/java/')
634
- && !normalized.includes('/pom.xml')
635
- && !normalized.endsWith('pom.xml')
636
- && !normalized.endsWith('build.gradle')
637
- && !normalized.endsWith('build.gradle.kts');
638
- }
639
-
640
- export function isBackendBuildValidationCommand(command: string): boolean {
641
- return /(^|\s)(mvn|maven|mvnw|\.\/mvnw|gradle|gradlew|\.\/gradlew)(\s|$)|\b(maven_compile|gradle_build)\b/i.test(command);
642
- }
643
-
644
- function taskGap(taskId: string, field: string, message: string, recommendation: string): SddTaskGap {
645
- return {
646
- type: 'Task Gap',
647
- severity: 'blocking',
648
- taskId,
649
- field,
650
- message,
651
- recommendation
652
- };
653
- }
654
-
655
- function validateAggregateTaskSet(tasks: SddTask[]): SddTaskGap[] {
656
- const gaps: SddTaskGap[] = [];
657
- const tasksById = new Map<string, SddTask[]>();
658
- for (const task of tasks) {
659
- const matchingTasks = tasksById.get(task.id) ?? [];
660
- matchingTasks.push(task);
661
- tasksById.set(task.id, matchingTasks);
662
- }
663
-
664
- for (const [taskId, matchingTasks] of tasksById) {
665
- if (matchingTasks.length > 1) {
666
- gaps.push(taskGap(
667
- taskId,
668
- 'id',
669
- `Duplicate task id ${taskId} across parsed task files: ${matchingTasks.map(taskSourceEvidence).join('; ')}.`,
670
- 'Rename duplicate task ids or add deterministic source disambiguation before implementation.'
671
- ));
672
- }
673
- }
674
-
675
- for (const task of tasks) {
676
- for (const dependency of task.dependsOn) {
677
- const matchingDependencies = tasksById.get(dependency) ?? [];
678
- if (matchingDependencies.length === 0) {
679
- gaps.push({
680
- type: 'Dependency Gap',
681
- severity: 'blocking',
682
- taskId: task.id,
683
- field: 'depends_on',
684
- message: `Task ${task.id} depends on unknown task ${dependency}.`,
685
- recommendation: 'Fix depends_on to reference an existing task id, or add the missing task.'
686
- });
687
- } else if (matchingDependencies.length > 1) {
688
- gaps.push({
689
- type: 'Dependency Gap',
690
- severity: 'blocking',
691
- taskId: task.id,
692
- field: 'depends_on',
693
- message: `Task ${task.id} depends on ambiguous duplicate task id ${dependency}: ${matchingDependencies.map(taskSourceEvidence).join('; ')}.`,
694
- recommendation: 'Rename duplicate task ids so dependencies resolve to one task.'
695
- });
696
- }
697
- }
698
- }
699
-
700
- return gaps;
701
- }
702
-
703
- function taskSourceEvidence(task: Pick<SddTask, 'id' | 'source'>): string {
704
- return `${task.id} at ${sourceLocationEvidence(task.source)}`;
705
- }
706
-
707
- function sourceLocationEvidence(source: SddTaskSourceLocation): string {
708
- return `${source.filePath}:${source.lineStart}-${source.lineEnd}`;
709
- }
1
+ import { hashDocumentContent, hashSemanticDocument, hashTasksContract, documentHashMatches } from './document-hashes.js';
2
+ import { readdir, readFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { assertSafePathSegment } from '../path-safety.js';
5
+ import { exists } from '../storage/json-io.js';
6
+
7
+ export type SddTaskStatus = 'pending' | 'in_progress' | 'completed' | 'blocked' | 'deferred' | 'unknown';
8
+ export type SddChangeSurface = 'frontend_only' | 'backend_only' | 'full_stack' | 'docs_only' | 'config_only' | 'cli_only' | 'unknown';
9
+ export type SddValidationTiming = 'task_end' | 'batch_end' | 'wave_end';
10
+ export type SddGapSeverity = 'blocking' | 'warning';
11
+ export type SddGapType = 'Document Gap' | 'Task Gap' | 'Dependency Gap';
12
+
13
+ export type SddTaskClass = 'implementation' | 'validation';
14
+ export interface SddTaskSourceLocation {
15
+ filePath: string;
16
+ heading: string | null;
17
+ lineStart: number;
18
+ lineEnd: number;
19
+ }
20
+
21
+ export interface SddValidationCommand {
22
+ command: string;
23
+ acceptanceRefs: string[];
24
+ raw: string;
25
+ }
26
+
27
+ export interface SddTask {
28
+ id: string;
29
+ title: string | null;
30
+ status: SddTaskStatus;
31
+ wave: number | null;
32
+ taskClass: SddTaskClass | null;
33
+ unitType: string | null;
34
+ implementationWave: string | null;
35
+ validationBatch: string | null;
36
+ validationTiming: SddValidationTiming;
37
+ requiresVerifyBeforeNext: boolean;
38
+ changeSurface: SddChangeSurface;
39
+ dependsOn: string[];
40
+ validationHandoff: string[];
41
+ affectedFiles: string[];
42
+ validation: string[];
43
+ validationCommands: SddValidationCommand[];
44
+ risk: string[];
45
+ acceptanceRefs: string[];
46
+ planRefs: string[];
47
+ fileOwnership: string[];
48
+ agentFit: string[];
49
+ verificationAvailability: string[];
50
+ autonomy: string | null;
51
+ allowedAgents: string[];
52
+ requiredArtifacts: string[];
53
+ gapState: string | null;
54
+ boundary: string | null;
55
+ acceptance: string[];
56
+ implementationNotes: string | null;
57
+ rawMetadata: Record<string, string | string[]>;
58
+ source: SddTaskSourceLocation;
59
+ }
60
+
61
+ export interface SddTaskGap {
62
+ type: SddGapType;
63
+ severity: SddGapSeverity;
64
+ taskId: string | null;
65
+ field: string;
66
+ message: string;
67
+ recommendation: string;
68
+ }
69
+
70
+ export interface SddTaskModel {
71
+ branch: string;
72
+ specPath: string;
73
+ planPath: string;
74
+ tasksPath: string;
75
+ verifyPath: string;
76
+ documents: {
77
+ specExists: boolean;
78
+ planExists: boolean;
79
+ tasksExists: boolean;
80
+ verifyExists: boolean;
81
+ specHash?: string | null;
82
+ planHash?: string | null;
83
+ tasksHash?: string | null;
84
+ verifyHash?: string | null;
85
+ specDocHash?: string | null;
86
+ planDocHash?: string | null;
87
+ tasksDocHash?: string | null;
88
+ verifyDocHash?: string | null;
89
+ specContractHash?: string | null;
90
+ planContractHash?: string | null;
91
+ tasksContractHash?: string | null;
92
+ verifyContractHash?: string | null;
93
+ planBasedOnSpecHash?: string | null;
94
+ tasksBasedOnPlanHash?: string | null;
95
+ verifyBasedOnTasksHash?: string | null;
96
+ planBasedOnSpecContractHash?: string | null;
97
+ tasksBasedOnPlanContractHash?: string | null;
98
+ verifyBasedOnTasksContractHash?: string | null;
99
+ planStale?: boolean;
100
+ tasksStale?: boolean;
101
+ verifyStale?: boolean;
102
+ };
103
+ tasks: SddTask[];
104
+ gaps: SddTaskGap[];
105
+ }
106
+
107
+ export async function parseSddBranch(projectRoot: string, branch = 'master'): Promise<SddTaskModel> {
108
+ assertSafePathSegment(branch, 'branch');
109
+ const specPath = path.join(projectRoot, 'specs', branch, 'spec.md');
110
+ const planPath = path.join(projectRoot, 'specs', branch, 'plan.md');
111
+ const tasksPath = path.join(projectRoot, 'specs', branch, 'tasks.md');
112
+ const verifyPath = path.join(projectRoot, 'specs', branch, 'verify.md');
113
+ const [specExists, planExists, tasksExists, verifyExists] = await Promise.all([exists(specPath), exists(planPath), exists(tasksPath), exists(verifyPath)]);
114
+ const [rawSpec, rawPlan, rawTasks, rawVerify] = await Promise.all([
115
+ specExists ? readFile(specPath, 'utf8') : Promise.resolve(null),
116
+ planExists ? readFile(planPath, 'utf8') : Promise.resolve(null),
117
+ tasksExists ? readFile(tasksPath, 'utf8') : Promise.resolve(null),
118
+ verifyExists ? readFile(verifyPath, 'utf8') : Promise.resolve(null)
119
+ ]);
120
+ const documents = buildDocumentChainState({ specExists, planExists, tasksExists, verifyExists, rawSpec, rawPlan, rawTasks, rawVerify });
121
+ const gaps: SddTaskGap[] = [];
122
+
123
+ if (documents.planStale) {
124
+ gaps.push(documentGap('plan.md', `Plan document is stale because based_on_spec_hash ${documents.planBasedOnSpecHash} no longer matches current spec hash ${documents.specHash}.`, 'Refresh the plan stage for this partition before updating tasks or executing implementation.'));
125
+ }
126
+ if (documents.tasksStale) {
127
+ gaps.push(documentGap('tasks.md', `Tasks document is stale because based_on_plan_hash ${documents.tasksBasedOnPlanHash} no longer matches current plan hash ${documents.planHash}.`, 'Refresh the tasks stage for this partition before executing implementation.'));
128
+ }
129
+
130
+ if (!specExists) {
131
+ gaps.push(documentGap('spec.md', 'Spec document is missing.', 'Create or restore specs/<branch>/spec.md before full SDD execution.'));
132
+ }
133
+ if (!planExists) {
134
+ gaps.push(documentGap('plan.md', 'Plan document is missing.', 'Create or restore specs/<branch>/plan.md before task execution.'));
135
+ }
136
+ if (!tasksExists || rawTasks === null) {
137
+ gaps.push(documentGap('tasks.md', 'Tasks document is missing.', 'Create specs/<branch>/tasks.md with sdd-task fenced blocks.'));
138
+ return {
139
+ branch,
140
+ specPath,
141
+ planPath,
142
+ tasksPath,
143
+ verifyPath,
144
+ documents,
145
+ tasks: [],
146
+ gaps
147
+ };
148
+ }
149
+
150
+ const taskModel = parseSddTasksMarkdown(rawTasks, { tasksPath });
151
+ if (taskModel.tasks.length === 0 && !path.basename(tasksPath).startsWith('phase')) {
152
+ const retainedModel = await parseRetainedPhaseTasks(path.dirname(tasksPath));
153
+ if (retainedModel.tasks.length > 0) {
154
+ return {
155
+ branch,
156
+ specPath,
157
+ planPath,
158
+ tasksPath,
159
+ verifyPath,
160
+ documents,
161
+ tasks: retainedModel.tasks,
162
+ gaps: [...gaps, ...retainedModel.gaps]
163
+ };
164
+ }
165
+ }
166
+ return {
167
+ branch,
168
+ specPath,
169
+ planPath,
170
+ tasksPath,
171
+ verifyPath,
172
+ documents,
173
+ tasks: taskModel.tasks,
174
+ gaps: [...gaps, ...taskModel.gaps]
175
+ };
176
+ }
177
+
178
+ export function parseSddTasksMarkdown(raw: string, options: { branch?: string; tasksPath?: string; validateDependencies?: boolean } = {}): Pick<SddTaskModel, 'tasks' | 'gaps'> {
179
+ const tasksPath = options.tasksPath ?? 'tasks.md';
180
+ const fencedBlocks = Array.from(raw.matchAll(/^\s*```sdd-task\s*\r?\n([\s\S]*?)\r?^\s*```\s*$/gm));
181
+ const tasks: SddTask[] = [];
182
+ const gaps: SddTaskGap[] = [];
183
+
184
+ if (fencedBlocks.length === 0) {
185
+ gaps.push({
186
+ type: 'Task Gap',
187
+ severity: 'blocking',
188
+ taskId: null,
189
+ field: 'sdd-task',
190
+ message: 'No sdd-task fenced blocks found in tasks.md.',
191
+ recommendation: 'Add one sdd-task fenced block per executable task.'
192
+ });
193
+ return { tasks, gaps };
194
+ }
195
+
196
+ const seenIds = new Map<string, SddTaskSourceLocation>();
197
+ for (let blockIndex = 0; blockIndex < fencedBlocks.length; blockIndex += 1) {
198
+ const blockMatch = fencedBlocks[blockIndex];
199
+ const block = blockMatch[1] ?? '';
200
+ const blockStart = blockMatch.index ?? 0;
201
+ const blockEnd = blockStart + blockMatch[0].length;
202
+ const nextBlockStart = fencedBlocks[blockIndex + 1]?.index ?? raw.length;
203
+ const lineStart = lineNumberAt(raw, blockStart);
204
+ const lineEnd = lineNumberAt(raw, blockEnd);
205
+ const heading = nearestTaskHeading(raw.slice(0, blockStart));
206
+ const metadata = parseSimpleYamlBlock(block);
207
+ const id = scalarValue(metadata.id);
208
+ const taskId = id || heading?.id || null;
209
+ const section = raw.slice(blockEnd, nextTaskStart(raw, blockEnd, nextBlockStart));
210
+ const parsedSections = parseTaskCompanionSections(section);
211
+ if (!taskId) {
212
+ gaps.push({
213
+ type: 'Task Gap',
214
+ severity: 'blocking',
215
+ taskId: null,
216
+ field: 'id',
217
+ message: `sdd-task block starting at line ${lineStart} is missing id.`,
218
+ recommendation: 'Add a stable id field such as id: T1.'
219
+ });
220
+ continue;
221
+ }
222
+
223
+ const source: SddTaskSourceLocation = {
224
+ filePath: tasksPath,
225
+ heading: heading?.raw ?? null,
226
+ lineStart,
227
+ lineEnd
228
+ };
229
+ const priorSource = seenIds.get(taskId);
230
+ if (priorSource) {
231
+ gaps.push({
232
+ type: 'Task Gap',
233
+ severity: 'blocking',
234
+ taskId,
235
+ field: 'id',
236
+ message: `Duplicate task id ${taskId} in ${taskSourceEvidence({ id: taskId, source })} and ${sourceLocationEvidence(priorSource)}.`,
237
+ recommendation: 'Keep task ids unique within a spec branch.'
238
+ });
239
+ }
240
+ seenIds.set(taskId, source);
241
+
242
+ const task: SddTask = {
243
+ id: taskId,
244
+ title: heading?.title ?? null,
245
+ status: parseTaskStatus(scalarValue(metadata.status)),
246
+ wave: parseWave(scalarValue(metadata.wave)),
247
+ taskClass: parseTaskClass(scalarByNames(metadata, ['taskClass', 'task_class'])),
248
+ unitType: scalarByNames(metadata, ['unitType', 'unit_type']),
249
+ implementationWave: scalarValue(metadata.implementation_wave),
250
+ validationBatch: scalarValue(metadata.validation_batch),
251
+ validationTiming: parseValidationTiming(scalarValue(metadata.validation_timing)),
252
+ requiresVerifyBeforeNext: parseRequiresVerifyBeforeNext(scalarValue(metadata.requires_verify_before_next)),
253
+ changeSurface: parseChangeSurface(scalarValue(metadata.change_surface)),
254
+ dependsOn: listByNames(metadata, ['depends_on', 'dependencies', 'dependsOn']),
255
+ validationHandoff: listByNames(metadata, ['validationHandoff', 'validation_handoff', 'validationTasks', 'validation_tasks']),
256
+ affectedFiles: listByNames(metadata, ['affected_files', 'touches', 'affectedFiles']),
257
+ validation: parseValidationCommands(metadata.validation ?? metadata.completionEvidence ?? metadata.completion_evidence).map((command) => command.command),
258
+ validationCommands: parseValidationCommands(metadata.validation ?? metadata.completionEvidence ?? metadata.completion_evidence),
259
+ risk: listValue(metadata.risk),
260
+ acceptanceRefs: listByNames(metadata, ['acceptance_refs', 'sourceAcceptanceCriteria', 'source_acceptance_criteria']),
261
+ planRefs: listByNames(metadata, ['plan_refs', 'planRefs']),
262
+ fileOwnership: listByNames(metadata, ['file_ownership', 'primaryWritableOwnership', 'primary_writable_ownership']),
263
+ agentFit: listValue(metadata.agent_fit),
264
+ verificationAvailability: listValue(metadata.verification_availability),
265
+ autonomy: scalarValue(metadata.autonomy),
266
+ allowedAgents: listValue(metadata.allowed_agents),
267
+ requiredArtifacts: listValue(metadata.required_artifacts),
268
+ gapState: scalarValue(metadata.gap_state),
269
+ boundary: parsedSections.boundary,
270
+ acceptance: parsedSections.acceptance,
271
+ implementationNotes: parsedSections.implementationNotes,
272
+ rawMetadata: metadata,
273
+ source
274
+ };
275
+ tasks.push(task);
276
+ gaps.push(...validateTask(task));
277
+ }
278
+
279
+ if (options.validateDependencies !== false) {
280
+ gaps.push(...validateAggregateTaskSet(tasks));
281
+ }
282
+
283
+ return { tasks, gaps };
284
+ }
285
+
286
+ function buildDocumentChainState(input: { specExists: boolean; planExists: boolean; tasksExists: boolean; verifyExists: boolean; rawSpec: string | null; rawPlan: string | null; rawTasks: string | null; rawVerify: string | null }): SddTaskModel['documents'] {
287
+ const specDocHash = input.rawSpec === null ? null : hashDocumentContent(input.rawSpec);
288
+ const planDocHash = input.rawPlan === null ? null : hashDocumentContent(input.rawPlan);
289
+ const tasksDocHash = input.rawTasks === null ? null : hashDocumentContent(input.rawTasks);
290
+ const verifyDocHash = input.rawVerify === null ? null : hashDocumentContent(input.rawVerify);
291
+ const specContractHash = hashSemanticDocument(input.rawSpec);
292
+ const planContractHash = hashSemanticDocument(input.rawPlan);
293
+ const tasksContractHash = hashTasksContract(input.rawTasks);
294
+ const verifyContractHash = hashSemanticDocument(input.rawVerify);
295
+ const planBasedOnSpecHash = input.rawPlan === null ? null : readDocumentScalar(input.rawPlan, 'based_on_spec_hash');
296
+ const tasksBasedOnPlanHash = input.rawTasks === null ? null : readDocumentScalar(input.rawTasks, 'based_on_plan_hash');
297
+ const verifyBasedOnTasksHash = input.rawVerify === null ? null : readDocumentScalar(input.rawVerify, 'based_on_tasks_hash');
298
+ const planBasedOnSpecContractHash = input.rawPlan === null ? null : readDocumentScalar(input.rawPlan, 'based_on_spec_contract_hash');
299
+ const tasksBasedOnPlanContractHash = input.rawTasks === null ? null : readDocumentScalar(input.rawTasks, 'based_on_plan_contract_hash');
300
+ const verifyBasedOnTasksContractHash = input.rawVerify === null ? null : readDocumentScalar(input.rawVerify, 'based_on_tasks_contract_hash');
301
+
302
+ const planStale = Boolean(
303
+ (planBasedOnSpecContractHash && specContractHash && !documentHashMatches(planBasedOnSpecContractHash, specContractHash))
304
+ || (!planBasedOnSpecContractHash && planBasedOnSpecHash && specDocHash && !documentHashMatches(planBasedOnSpecHash, specDocHash))
305
+ );
306
+ const tasksHashMismatch = Boolean(
307
+ (tasksBasedOnPlanContractHash && planContractHash && !documentHashMatches(tasksBasedOnPlanContractHash, planContractHash))
308
+ || (!tasksBasedOnPlanContractHash && tasksBasedOnPlanHash && planDocHash && !documentHashMatches(tasksBasedOnPlanHash, planDocHash))
309
+ );
310
+ const verifyHashMismatch = false;
311
+
312
+ return {
313
+ specExists: input.specExists,
314
+ planExists: input.planExists,
315
+ tasksExists: input.tasksExists,
316
+ verifyExists: input.verifyExists,
317
+ specHash: specDocHash,
318
+ planHash: planDocHash,
319
+ tasksHash: tasksDocHash,
320
+ verifyHash: verifyDocHash,
321
+ specDocHash,
322
+ planDocHash,
323
+ tasksDocHash,
324
+ verifyDocHash,
325
+ specContractHash,
326
+ planContractHash,
327
+ tasksContractHash,
328
+ verifyContractHash,
329
+ planBasedOnSpecHash,
330
+ tasksBasedOnPlanHash,
331
+ verifyBasedOnTasksHash,
332
+ planBasedOnSpecContractHash,
333
+ tasksBasedOnPlanContractHash,
334
+ verifyBasedOnTasksContractHash,
335
+ planStale,
336
+ tasksStale: planStale || tasksHashMismatch,
337
+ verifyStale: planStale || tasksHashMismatch || verifyHashMismatch
338
+ };
339
+ }
340
+
341
+ function readDocumentScalar(raw: string, key: string): string | null {
342
+ const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
343
+ const match = raw.match(new RegExp(`^\\s*(?:-\\s*)?${escapedKey}:\\s*(.+?)\\s*$`, 'm'));
344
+ return match?.[1]?.trim().replace(/^["'`]|["'`]$/g, '') ?? null;
345
+ }
346
+
347
+ async function parseRetainedPhaseTasks(specBranchDir: string): Promise<Pick<SddTaskModel, 'tasks' | 'gaps'>> {
348
+ const entries = await readdir(specBranchDir, { withFileTypes: true });
349
+ const taskFiles = entries
350
+ .filter((entry) => entry.isFile() && /^phase\d+\.\d+-tasks\.md$/.test(entry.name))
351
+ .map((entry) => path.join(specBranchDir, entry.name))
352
+ .sort();
353
+ const tasks: SddTask[] = [];
354
+ const gaps: SddTaskGap[] = [];
355
+ for (const taskFile of taskFiles) {
356
+ const raw = await readFile(taskFile, 'utf8');
357
+ const parsed = parseSddTasksMarkdown(raw, { tasksPath: taskFile, validateDependencies: false });
358
+ tasks.push(...parsed.tasks);
359
+ gaps.push(...parsed.gaps);
360
+ }
361
+ gaps.push(...validateAggregateTaskSet(tasks));
362
+ return { tasks, gaps };
363
+ }
364
+
365
+ function documentGap(field: string, message: string, recommendation: string): SddTaskGap {
366
+ return {
367
+ type: 'Document Gap',
368
+ severity: 'blocking',
369
+ taskId: null,
370
+ field,
371
+ message,
372
+ recommendation
373
+ };
374
+ }
375
+
376
+ function parseTaskStatus(value: string | null): SddTaskStatus {
377
+ if (value === 'pending' || value === 'in_progress' || value === 'completed' || value === 'blocked' || value === 'deferred') {
378
+ return value;
379
+ }
380
+ return 'unknown';
381
+ }
382
+
383
+ function parseWave(value: string | null): number | null {
384
+ if (!value) {
385
+ return null;
386
+ }
387
+ const parsed = Number(value);
388
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : null;
389
+ }
390
+
391
+ function parseChangeSurface(value: string | null): SddChangeSurface {
392
+ if (value === 'frontend_only' || value === 'backend_only' || value === 'full_stack' || value === 'docs_only' || value === 'config_only' || value === 'cli_only' || value === 'unknown') {
393
+ return value;
394
+ }
395
+ return 'unknown';
396
+ }
397
+ function parseTaskClass(value: string | null): SddTaskClass | null {
398
+ return value === 'implementation' || value === 'validation' ? value : null;
399
+ }
400
+
401
+ function parseValidationTiming(value: string | null): SddValidationTiming {
402
+ if (value === 'batch_end' || value === 'wave_end') {
403
+ return value;
404
+ }
405
+ return 'task_end';
406
+ }
407
+
408
+ function parseRequiresVerifyBeforeNext(value: string | null): boolean {
409
+ return value === 'false' ? false : true;
410
+ }
411
+
412
+ function isValidChangeSurface(value: string | null): boolean {
413
+ return value === null || value === 'frontend_only' || value === 'backend_only' || value === 'full_stack' || value === 'docs_only' || value === 'config_only' || value === 'cli_only' || value === 'unknown';
414
+ }
415
+
416
+ function isValidValidationTiming(value: string | null): boolean {
417
+ return value === null || value === 'task_end' || value === 'batch_end' || value === 'wave_end';
418
+ }
419
+
420
+ function isValidBooleanScalar(value: string | null): boolean {
421
+ return value === null || value === 'true' || value === 'false';
422
+ }
423
+
424
+ function parseSimpleYamlBlock(raw: string): Record<string, string | string[]> {
425
+ const result: Record<string, string | string[]> = {};
426
+ const lines = raw.split(/\r?\n/);
427
+ let currentListKey: string | null = null;
428
+
429
+ for (const line of lines) {
430
+ const trimmed = line.trim();
431
+ if (!trimmed || trimmed.startsWith('#')) {
432
+ continue;
433
+ }
434
+ if (currentListKey && /^-\s+/.test(trimmed)) {
435
+ const current = result[currentListKey];
436
+ const items = Array.isArray(current) ? current : [];
437
+ items.push(unquoteSimpleYamlValue(trimmed.slice(2).trim()));
438
+ result[currentListKey] = items;
439
+ continue;
440
+ }
441
+
442
+ const scalarMatch = trimmed.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
443
+ if (!scalarMatch) {
444
+ currentListKey = null;
445
+ continue;
446
+ }
447
+ const key = scalarMatch[1];
448
+ const value = scalarMatch[2].trim();
449
+ if (value === '') {
450
+ result[key] = [];
451
+ currentListKey = key;
452
+ } else if (value === '[]') {
453
+ result[key] = [];
454
+ currentListKey = null;
455
+ } else if (value.startsWith('[') && value.endsWith(']')) {
456
+ result[key] = value.slice(1, -1).split(',').map((item) => unquoteSimpleYamlValue(item.trim())).filter(Boolean);
457
+ currentListKey = null;
458
+ } else {
459
+ result[key] = unquoteSimpleYamlValue(value);
460
+ currentListKey = null;
461
+ }
462
+ }
463
+
464
+ return result;
465
+ }
466
+
467
+ function unquoteSimpleYamlValue(value: string): string {
468
+ if (value.length >= 2) {
469
+ const first = value[0];
470
+ const last = value[value.length - 1];
471
+ if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
472
+ return value.slice(1, -1);
473
+ }
474
+ }
475
+ return value;
476
+ }
477
+
478
+ function scalarValue(value: string | string[] | undefined): string | null {
479
+ return typeof value === 'string' && value.length > 0 ? value : null;
480
+ }
481
+
482
+ function listValue(value: string | string[] | undefined): string[] {
483
+ if (Array.isArray(value)) {
484
+ return value.filter(Boolean);
485
+ }
486
+ if (!value || value === '[]') {
487
+ return [];
488
+ }
489
+ return [value];
490
+ }
491
+
492
+ function scalarByNames(metadata: Record<string, string | string[]>, names: string[]): string | null {
493
+ for (const name of names) {
494
+ const value = scalarValue(metadata[name]);
495
+ if (value) {
496
+ return value;
497
+ }
498
+ }
499
+ return null;
500
+ }
501
+
502
+ function listByNames(metadata: Record<string, string | string[]>, names: string[]): string[] {
503
+ for (const name of names) {
504
+ const value = listValue(metadata[name]);
505
+ if (value.length > 0) {
506
+ return value;
507
+ }
508
+ }
509
+ return [];
510
+ }
511
+
512
+ function parseValidationCommands(value: string | string[] | undefined): SddValidationCommand[] {
513
+ return listValue(value).map(parseValidationCommand);
514
+ }
515
+
516
+ function parseValidationCommand(raw: string): SddValidationCommand {
517
+ const separator = raw.match(/\s=>\s/);
518
+ if (!separator || separator.index === undefined) {
519
+ return { command: raw, acceptanceRefs: [], raw };
520
+ }
521
+ const command = raw.slice(0, separator.index).trim();
522
+ const refsRaw = raw.slice(separator.index + separator[0].length).trim();
523
+ return {
524
+ command: command || raw,
525
+ acceptanceRefs: parseAcceptanceRefList(refsRaw),
526
+ raw
527
+ };
528
+ }
529
+
530
+ function parseAcceptanceRefList(raw: string): string[] {
531
+ const trimmed = raw.replace(/^\[/, '').replace(/\]$/, '').trim();
532
+ if (!trimmed) {
533
+ return [];
534
+ }
535
+ return trimmed.split(',').map((item) => unquoteSimpleYamlValue(item.trim())).filter(Boolean);
536
+ }
537
+
538
+ function lineNumberAt(raw: string, offset: number): number {
539
+ return raw.slice(0, offset).split(/\r?\n/).length;
540
+ }
541
+
542
+ function nearestTaskHeading(prefix: string): { raw: string; id: string | null; title: string | null } | null {
543
+ const matches = Array.from(prefix.matchAll(/^\s*###\s+(.+)$/gm));
544
+ const last = matches.at(-1);
545
+ if (!last) {
546
+ return null;
547
+ }
548
+ const raw = last[1].trim();
549
+ const parsed = raw.match(/^([^::\s]+)\s*[::]\s*(.+)$/);
550
+ return {
551
+ raw,
552
+ id: parsed?.[1]?.trim() ?? null,
553
+ title: parsed?.[2]?.trim() ?? raw
554
+ };
555
+ }
556
+
557
+ function nextTaskStart(raw: string, offset: number, limit = raw.length): number {
558
+ const next = raw.slice(offset, limit).search(/^\s*###\s+/m);
559
+ return next < 0 ? limit : offset + next;
560
+ }
561
+
562
+ function parseTaskCompanionSections(raw: string): { boundary: string | null; acceptance: string[]; implementationNotes: string | null } {
563
+ return {
564
+ boundary: sectionText(raw, 'Boundary'),
565
+ acceptance: sectionBullets(raw, 'Acceptance'),
566
+ implementationNotes: sectionText(raw, 'Implementation Notes')
567
+ };
568
+ }
569
+
570
+ function sectionText(raw: string, title: string): string | null {
571
+ const escaped = title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
572
+ const sectionPattern = `^\\s*####\\s+${escaped}\\s*$([\\s\\S]*?)(?=^\\s*####\\s+|^\\s*###\\s+|^\\s*##\\s+|$(?![\\s\\S]))`;
573
+ const match = raw.match(new RegExp(sectionPattern, 'im'));
574
+ const text = match?.[1]?.trim() ?? '';
575
+ return text.length > 0 ? text : null;
576
+ }
577
+
578
+ function sectionBullets(raw: string, title: string): string[] {
579
+ const text = sectionText(raw, title);
580
+ if (!text) {
581
+ return [];
582
+ }
583
+ return text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.startsWith('- ')).map((line) => line.slice(2).trim()).filter(Boolean);
584
+ }
585
+
586
+ function validateTask(task: SddTask): SddTaskGap[] {
587
+ const gaps: SddTaskGap[] = [];
588
+ const isV3Task = Boolean(scalarValue(task.rawMetadata.workType) || scalarValue(task.rawMetadata.work_type));
589
+
590
+ if (task.status === 'unknown') {
591
+ gaps.push(taskGap(task.id, 'status', 'Task status is missing or unsupported.', 'Use one of pending, in_progress, completed, blocked, deferred.'));
592
+ }
593
+ if (task.wave === null) {
594
+ gaps.push(taskGap(task.id, 'wave', 'Task wave is missing or invalid.', 'Add a positive integer wave value.'));
595
+ }
596
+
597
+ if (isV3Task) {
598
+ const requiredV3Lists: Array<[string[], string]> = [
599
+ [['primaryWritableOwnership', 'primary_writable_ownership'], 'primaryWritableOwnership'],
600
+ [['touches', 'affectedFiles', 'affected_files'], 'touches'],
601
+ [['completionEvidence', 'completion_evidence'], 'completionEvidence']
602
+ ];
603
+ for (const [names, field] of requiredV3Lists) {
604
+ if (listByNames(task.rawMetadata, names).length === 0) {
605
+ gaps.push(taskGap(task.id, field, `Task ${task.id} has no ${field}.`, `Declare ${field} in the sdd-task block before execute.`));
606
+ }
607
+ }
608
+ if (!scalarByNames(task.rawMetadata, ['executionLane', 'execution_lane'])) {
609
+ gaps.push(taskGap(task.id, 'executionLane', `Task ${task.id} has no executionLane.`, 'Declare executionLane in the sdd-task block before execute.'));
610
+ }
611
+ if (!scalarByNames(task.rawMetadata, ['failureRoute', 'failure_route'])) {
612
+ gaps.push(taskGap(task.id, 'failureRoute', `Task ${task.id} has no failureRoute.`, 'Declare failureRoute in the sdd-task block before execute.'));
613
+ }
614
+ return gaps;
615
+ }
616
+
617
+ const requiredLists: Array<[keyof SddTask, string]> = [
618
+ ['affectedFiles', 'affected_files'],
619
+ ['validation', 'validation']
620
+ ];
621
+
622
+ if (!isValidChangeSurface(scalarValue(task.rawMetadata.change_surface))) {
623
+ gaps.push(taskGap(task.id, 'change_surface', `Task ${task.id} has invalid change_surface.`, 'Use one of frontend_only, backend_only, full_stack, docs_only, config_only, cli_only, unknown.'));
624
+ }
625
+ if (!isValidValidationTiming(scalarValue(task.rawMetadata.validation_timing))) {
626
+ gaps.push(taskGap(task.id, 'validation_timing', `Task ${task.id} has invalid validation_timing.`, 'Use one of task_end, batch_end, wave_end.'));
627
+ }
628
+ if (!isValidBooleanScalar(scalarValue(task.rawMetadata.requires_verify_before_next))) {
629
+ gaps.push(taskGap(task.id, 'requires_verify_before_next', `Task ${task.id} has invalid requires_verify_before_next.`, 'Use true or false.'));
630
+ }
631
+ if ((task.validationTiming === 'batch_end' || task.validationTiming === 'wave_end') && !task.validationBatch) {
632
+ gaps.push(taskGap(task.id, 'validation_batch', `Task ${task.id} uses ${task.validationTiming} but has no validation_batch.`, 'Declare validation_batch so batch/wave validation can group implementation evidence before /sdd:test.'));
633
+ }
634
+ if ((task.validationTiming === 'batch_end' || task.validationTiming === 'wave_end') && task.requiresVerifyBeforeNext) {
635
+ gaps.push(taskGap(task.id, 'requires_verify_before_next', `Task ${task.id} uses ${task.validationTiming} but requires verify before next.`, 'Set requires_verify_before_next: false for batch/wave validation, or use validation_timing: task_end for strict validation.'));
636
+ }
637
+ for (const [property, field] of requiredLists) {
638
+ if ((task[property] as unknown[]).length === 0) {
639
+ gaps.push(taskGap(task.id, field, `Task ${task.id} has no ${field}.`, `Declare ${field} in the sdd-task block before implementation.`));
640
+ }
641
+ }
642
+ if ((task.changeSurface === 'frontend_only' || isFrontendOnlyTask(task)) && task.validation.some(isBackendBuildValidationCommand)) {
643
+ gaps.push(taskGap(task.id, 'validation', `Task ${task.id} is frontend-only but declares backend build validation.`, 'For JSP/static frontend-only changes, replace Maven/Gradle validation with frontend-appropriate checks, dev-server/manual page evidence, lint/typecheck, or an explicit unavailable reason.'));
644
+ }
645
+ if (!task.boundary) {
646
+ gaps.push(taskGap(task.id, 'Boundary', `Task ${task.id} has no Boundary section.`, 'Add a #### Boundary section describing allowed and forbidden scope.'));
647
+ }
648
+ if (task.acceptance.length === 0) {
649
+ gaps.push(taskGap(task.id, 'Acceptance', `Task ${task.id} has no acceptance items.`, 'Add verifiable bullets under #### Acceptance.'));
650
+ }
651
+ return gaps;
652
+ }
653
+
654
+ export function isFrontendOnlyTask(task: SddTask): boolean {
655
+ return task.affectedFiles.length > 0 && task.affectedFiles.every(isFrontendOnlyPath);
656
+ }
657
+
658
+ function isFrontendOnlyPath(filePath: string): boolean {
659
+ const normalized = filePath.toLowerCase().replace(/\\/g, '/');
660
+ return /\.(jsp|html|htm|css|scss|sass|less|js|jsx|ts|tsx|vue|svelte|png|jpg|jpeg|gif|svg|webp|ico)$/.test(normalized)
661
+ && !normalized.includes('/src/main/java/')
662
+ && !normalized.includes('/src/test/java/')
663
+ && !normalized.includes('/pom.xml')
664
+ && !normalized.endsWith('pom.xml')
665
+ && !normalized.endsWith('build.gradle')
666
+ && !normalized.endsWith('build.gradle.kts');
667
+ }
668
+
669
+ export function isBackendBuildValidationCommand(command: string): boolean {
670
+ return /(^|\s)(mvn|maven|mvnw|\.\/mvnw|gradle|gradlew|\.\/gradlew)(\s|$)|\b(maven_compile|gradle_build)\b/i.test(command);
671
+ }
672
+
673
+ function taskGap(taskId: string, field: string, message: string, recommendation: string): SddTaskGap {
674
+ return {
675
+ type: 'Task Gap',
676
+ severity: 'blocking',
677
+ taskId,
678
+ field,
679
+ message,
680
+ recommendation
681
+ };
682
+ }
683
+
684
+ function validateAggregateTaskSet(tasks: SddTask[]): SddTaskGap[] {
685
+ const gaps: SddTaskGap[] = [];
686
+ const tasksById = new Map<string, SddTask[]>();
687
+ for (const task of tasks) {
688
+ const matchingTasks = tasksById.get(task.id) ?? [];
689
+ matchingTasks.push(task);
690
+ tasksById.set(task.id, matchingTasks);
691
+ }
692
+
693
+ for (const [taskId, matchingTasks] of tasksById) {
694
+ if (matchingTasks.length > 1) {
695
+ gaps.push(taskGap(
696
+ taskId,
697
+ 'id',
698
+ `Duplicate task id ${taskId} across parsed task files: ${matchingTasks.map(taskSourceEvidence).join('; ')}.`,
699
+ 'Rename duplicate task ids or add deterministic source disambiguation before implementation.'
700
+ ));
701
+ }
702
+ }
703
+
704
+ for (const task of tasks) {
705
+ for (const dependency of task.dependsOn) {
706
+ const matchingDependencies = tasksById.get(dependency) ?? [];
707
+ if (matchingDependencies.length === 0) {
708
+ gaps.push({
709
+ type: 'Dependency Gap',
710
+ severity: 'blocking',
711
+ taskId: task.id,
712
+ field: 'depends_on',
713
+ message: `Task ${task.id} depends on unknown task ${dependency}.`,
714
+ recommendation: 'Fix depends_on to reference an existing task id, or add the missing task.'
715
+ });
716
+ } else if (matchingDependencies.length > 1) {
717
+ gaps.push({
718
+ type: 'Dependency Gap',
719
+ severity: 'blocking',
720
+ taskId: task.id,
721
+ field: 'depends_on',
722
+ message: `Task ${task.id} depends on ambiguous duplicate task id ${dependency}: ${matchingDependencies.map(taskSourceEvidence).join('; ')}.`,
723
+ recommendation: 'Rename duplicate task ids so dependencies resolve to one task.'
724
+ });
725
+ }
726
+ }
727
+ }
728
+
729
+ return gaps;
730
+ }
731
+
732
+ function taskSourceEvidence(task: Pick<SddTask, 'id' | 'source'>): string {
733
+ return `${task.id} at ${sourceLocationEvidence(task.source)}`;
734
+ }
735
+
736
+ function sourceLocationEvidence(source: SddTaskSourceLocation): string {
737
+ return `${source.filePath}:${source.lineStart}-${source.lineEnd}`;
738
+ }