sdd-agent-platform 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (826) hide show
  1. package/README.md +33 -39
  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 -0
  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 +7 -13
  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/project.js +8 -8
  37. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/project.js.map +1 -1
  38. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/registries.js +1 -0
  39. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/registries.js.map +1 -1
  40. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js +4 -4
  41. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js.map +1 -1
  42. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-trust.js +24 -0
  43. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-trust.js.map +1 -1
  44. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/runtime-contracts.js +1 -1
  45. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/runtime-contracts.js.map +1 -1
  46. package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js +43 -180
  47. package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js.map +1 -1
  48. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.d.ts +1 -1
  49. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js +7 -14
  50. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js.map +1 -1
  51. package/node_modules/@sdd-agent-platform/core/dist/evidence-runtime/coordination.js +110 -0
  52. package/node_modules/@sdd-agent-platform/core/dist/evidence-runtime/coordination.js.map +1 -0
  53. package/node_modules/@sdd-agent-platform/core/dist/execution/background-executor.js +4 -4
  54. package/node_modules/@sdd-agent-platform/core/dist/execution/background-executor.js.map +1 -1
  55. package/node_modules/@sdd-agent-platform/core/dist/execution/foreground-subagents.js +3 -3
  56. package/node_modules/@sdd-agent-platform/core/dist/execution/foreground-subagents.js.map +1 -1
  57. package/node_modules/@sdd-agent-platform/core/dist/execution/host-invocation.js +85 -86
  58. package/node_modules/@sdd-agent-platform/core/dist/execution/host-invocation.js.map +1 -1
  59. package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js +2 -3
  60. package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js.map +1 -1
  61. package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js +2 -2
  62. package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js.map +1 -1
  63. package/node_modules/@sdd-agent-platform/core/dist/governance/policy.d.ts +1 -1
  64. package/node_modules/@sdd-agent-platform/core/dist/governance/policy.js +1 -1
  65. package/node_modules/@sdd-agent-platform/core/dist/governance/policy.js.map +1 -1
  66. package/node_modules/@sdd-agent-platform/core/dist/instructions.d.ts +1 -1
  67. package/node_modules/@sdd-agent-platform/core/dist/instructions.js +31 -67
  68. package/node_modules/@sdd-agent-platform/core/dist/instructions.js.map +1 -1
  69. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/decision-gate.js +1 -1
  70. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/decision-gate.js.map +1 -1
  71. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.d.ts +0 -1
  72. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js +59 -85
  73. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js.map +1 -1
  74. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/contracts.d.ts +159 -0
  75. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/contracts.js +7 -0
  76. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/contracts.js.map +1 -0
  77. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/kernel.d.ts +16 -0
  78. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/kernel.js +461 -0
  79. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/kernel.js.map +1 -0
  80. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph.d.ts +2 -0
  81. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph.js +3 -0
  82. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph.js.map +1 -0
  83. package/node_modules/@sdd-agent-platform/core/dist/orchestration/contracts.d.ts +1 -1
  84. package/node_modules/@sdd-agent-platform/core/dist/orchestration/runtime.d.ts +2 -12
  85. package/node_modules/@sdd-agent-platform/core/dist/orchestration/runtime.js +32 -80
  86. package/node_modules/@sdd-agent-platform/core/dist/orchestration/runtime.js.map +1 -1
  87. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.d.ts +2 -5
  88. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js +27 -69
  89. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js.map +1 -1
  90. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js +118 -34
  91. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js.map +1 -1
  92. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js +1 -1
  93. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js.map +1 -1
  94. package/node_modules/@sdd-agent-platform/core/dist/registries/capability-sources.js +1 -1
  95. package/node_modules/@sdd-agent-platform/core/dist/registries/command-team-runtime.d.ts +1 -1
  96. package/node_modules/@sdd-agent-platform/core/dist/registries/command-team-runtime.js +8 -15
  97. package/node_modules/@sdd-agent-platform/core/dist/registries/command-team-runtime.js.map +1 -1
  98. package/node_modules/@sdd-agent-platform/core/dist/registries/eval-learning-context.js +4 -4
  99. package/node_modules/@sdd-agent-platform/core/dist/registries/eval-learning-context.js.map +1 -1
  100. package/node_modules/@sdd-agent-platform/core/dist/registries/plan-scout-domains.d.ts +13 -0
  101. package/node_modules/@sdd-agent-platform/core/dist/registries/plan-scout-domains.js +76 -0
  102. package/node_modules/@sdd-agent-platform/core/dist/registries/plan-scout-domains.js.map +1 -0
  103. package/node_modules/@sdd-agent-platform/core/dist/registries/query-status.js +2 -2
  104. package/node_modules/@sdd-agent-platform/core/dist/registries/query-status.js.map +1 -1
  105. package/node_modules/@sdd-agent-platform/core/dist/registries/skill-capabilities.js +7 -7
  106. package/node_modules/@sdd-agent-platform/core/dist/registries/skill-capabilities.js.map +1 -1
  107. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-capabilities.js +4 -4
  108. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-capabilities.js.map +1 -1
  109. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-plugins.js +2 -2
  110. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-plugins.js.map +1 -1
  111. package/node_modules/@sdd-agent-platform/core/dist/registries/worker-adapters.js +11 -11
  112. package/node_modules/@sdd-agent-platform/core/dist/registries/worker-adapters.js.map +1 -1
  113. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.d.ts +1 -1
  114. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js +21 -21
  115. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js.map +1 -1
  116. package/node_modules/@sdd-agent-platform/core/dist/risk/consumer-diagnostics.js +2 -1
  117. package/node_modules/@sdd-agent-platform/core/dist/risk/consumer-diagnostics.js.map +1 -1
  118. package/node_modules/@sdd-agent-platform/core/dist/risk/kernel.js +6 -6
  119. package/node_modules/@sdd-agent-platform/core/dist/risk/kernel.js.map +1 -1
  120. package/node_modules/@sdd-agent-platform/core/dist/risk/legacy-adapters.js +11 -23
  121. package/node_modules/@sdd-agent-platform/core/dist/risk/legacy-adapters.js.map +1 -1
  122. package/node_modules/@sdd-agent-platform/core/dist/risk/workflow-gates.d.ts +2 -2
  123. package/node_modules/@sdd-agent-platform/core/dist/risk/workflow-gates.js +18 -20
  124. package/node_modules/@sdd-agent-platform/core/dist/risk/workflow-gates.js.map +1 -1
  125. package/node_modules/@sdd-agent-platform/core/dist/router/agent-runtime.d.ts +0 -2
  126. package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js +1 -1
  127. package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js.map +1 -1
  128. package/node_modules/@sdd-agent-platform/core/dist/router/routing.js +16 -48
  129. package/node_modules/@sdd-agent-platform/core/dist/router/routing.js.map +1 -1
  130. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-import.js +11 -1
  131. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-import.js.map +1 -1
  132. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js +2 -2
  133. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js.map +1 -1
  134. package/node_modules/@sdd-agent-platform/core/dist/router/stage-route-binding.d.ts +2 -2
  135. package/node_modules/@sdd-agent-platform/core/dist/router/stage-route-binding.js +20 -28
  136. package/node_modules/@sdd-agent-platform/core/dist/router/stage-route-binding.js.map +1 -1
  137. package/node_modules/@sdd-agent-platform/core/dist/router.d.ts +0 -1
  138. package/node_modules/@sdd-agent-platform/core/dist/router.js +0 -1
  139. package/node_modules/@sdd-agent-platform/core/dist/router.js.map +1 -1
  140. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.d.ts +6 -6
  141. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js +13 -124
  142. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js.map +1 -1
  143. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.d.ts +2 -0
  144. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js +5 -7
  145. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js.map +1 -1
  146. package/node_modules/@sdd-agent-platform/core/dist/run-state/model.d.ts +28 -28
  147. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-index.d.ts +2 -0
  148. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-index.js +3 -1
  149. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-index.js.map +1 -1
  150. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js +26 -36
  151. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js.map +1 -1
  152. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.d.ts +0 -4
  153. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js +5 -51
  154. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js.map +1 -1
  155. package/node_modules/@sdd-agent-platform/core/dist/run-state.d.ts +0 -1
  156. package/node_modules/@sdd-agent-platform/core/dist/run-state.js +0 -1
  157. package/node_modules/@sdd-agent-platform/core/dist/run-state.js.map +1 -1
  158. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/build.js +1 -1
  159. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/build.js.map +1 -1
  160. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/findings.js +5 -5
  161. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/findings.js.map +1 -1
  162. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js +1 -1
  163. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js.map +1 -1
  164. package/node_modules/@sdd-agent-platform/core/dist/runtime-projection-p0.d.ts +2 -2
  165. package/node_modules/@sdd-agent-platform/core/dist/runtime-projection-p0.js +11 -0
  166. package/node_modules/@sdd-agent-platform/core/dist/runtime-projection-p0.js.map +1 -1
  167. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/artifact-depth.d.ts +14 -0
  168. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/artifact-depth.js +179 -0
  169. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/artifact-depth.js.map +1 -0
  170. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.d.ts +0 -2
  171. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js +10 -97
  172. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js.map +1 -1
  173. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.d.ts +1 -1
  174. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js +6 -8
  175. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js.map +1 -1
  176. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.d.ts +5 -2
  177. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js +85 -68
  178. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js.map +1 -1
  179. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-rendering.js +2 -2
  180. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-rendering.js.map +1 -1
  181. package/node_modules/@sdd-agent-platform/core/dist/spec-entry.js +40 -0
  182. package/node_modules/@sdd-agent-platform/core/dist/spec-entry.js.map +1 -0
  183. package/node_modules/@sdd-agent-platform/core/dist/spec-manager-contracts.d.ts +12 -0
  184. package/node_modules/@sdd-agent-platform/core/dist/spec-manager-contracts.js +2 -0
  185. package/node_modules/@sdd-agent-platform/core/dist/spec-manager-contracts.js.map +1 -0
  186. package/node_modules/@sdd-agent-platform/core/dist/stage-artifacts.d.ts +2 -2
  187. package/node_modules/@sdd-agent-platform/core/dist/stage-artifacts.js +19 -26
  188. package/node_modules/@sdd-agent-platform/core/dist/stage-artifacts.js.map +1 -1
  189. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration-contracts.d.ts +1 -1
  190. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration-contracts.js +3 -6
  191. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration-contracts.js.map +1 -1
  192. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration.d.ts +111 -263
  193. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration.js +1272 -1124
  194. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration.js.map +1 -1
  195. package/node_modules/@sdd-agent-platform/core/dist/stage-runtime/runtime.js +5 -5
  196. package/node_modules/@sdd-agent-platform/core/dist/stage-runtime/runtime.js.map +1 -1
  197. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.d.ts +1 -44
  198. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js +47 -170
  199. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js.map +1 -1
  200. package/node_modules/@sdd-agent-platform/core/dist/storage/runtime-store.js +73 -73
  201. package/node_modules/@sdd-agent-platform/core/dist/subagents/contracts.d.ts +1 -1
  202. package/node_modules/@sdd-agent-platform/core/dist/subagents/runtime.js +7 -7
  203. package/node_modules/@sdd-agent-platform/core/dist/subagents/runtime.js.map +1 -1
  204. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.d.ts +1 -0
  205. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js +2 -0
  206. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js.map +1 -0
  207. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.d.ts +1 -0
  208. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js +2 -0
  209. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js.map +1 -0
  210. package/node_modules/@sdd-agent-platform/core/dist/sync-back.d.ts +1 -0
  211. package/node_modules/@sdd-agent-platform/core/dist/sync-back.js +2 -0
  212. package/node_modules/@sdd-agent-platform/core/dist/sync-back.js.map +1 -0
  213. package/node_modules/@sdd-agent-platform/core/dist/task-execution-contract.d.ts +167 -0
  214. package/node_modules/@sdd-agent-platform/core/dist/task-execution-contract.js +377 -0
  215. package/node_modules/@sdd-agent-platform/core/dist/task-execution-contract.js.map +1 -0
  216. package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js +329 -314
  217. package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js.map +1 -1
  218. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.d.ts +1 -0
  219. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js +53 -7
  220. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js.map +1 -1
  221. package/node_modules/@sdd-agent-platform/core/dist/truth-reconciliation.js +9 -12
  222. package/node_modules/@sdd-agent-platform/core/dist/truth-reconciliation.js.map +1 -1
  223. package/node_modules/@sdd-agent-platform/core/dist/tsconfig.tsbuildinfo +1 -1
  224. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.d.ts +0 -48
  225. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js +1 -520
  226. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js.map +1 -1
  227. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.d.ts +5 -5
  228. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js +14 -14
  229. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js.map +1 -1
  230. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.d.ts +1 -0
  231. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js +111 -159
  232. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js.map +1 -1
  233. package/node_modules/@sdd-agent-platform/core/dist/verification/task-evidence-judgment.d.ts +49 -0
  234. package/node_modules/@sdd-agent-platform/core/dist/verification/task-evidence-judgment.js +521 -0
  235. package/node_modules/@sdd-agent-platform/core/dist/verification/task-evidence-judgment.js.map +1 -0
  236. package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js +21 -21
  237. package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js.map +1 -1
  238. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.d.ts +0 -18
  239. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js +5 -27
  240. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js.map +1 -1
  241. package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js +45 -45
  242. package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js.map +1 -1
  243. package/node_modules/@sdd-agent-platform/core/dist/verification.d.ts +3 -3
  244. package/node_modules/@sdd-agent-platform/core/dist/verification.js +2 -2
  245. package/node_modules/@sdd-agent-platform/core/dist/verification.js.map +1 -1
  246. package/node_modules/@sdd-agent-platform/core/dist/work-units/contracts.d.ts +1 -1
  247. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js +9 -227
  248. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js.map +1 -1
  249. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js +9 -50
  250. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js.map +1 -1
  251. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js +4 -42
  252. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js.map +1 -1
  253. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/types.d.ts +2 -3
  254. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
  255. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js +2 -1
  256. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
  257. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/dependencies.js +1 -1
  258. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.d.ts +1 -0
  259. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js +23 -63
  260. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js.map +1 -1
  261. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.d.ts +2 -2
  262. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js +43 -65
  263. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js.map +1 -1
  264. package/node_modules/@sdd-agent-platform/core/package.json +5 -2
  265. package/node_modules/@sdd-agent-platform/core/src/ai-tools.test.ts +238 -185
  266. package/node_modules/@sdd-agent-platform/core/src/ai-tools.ts +56 -73
  267. package/node_modules/@sdd-agent-platform/core/src/artifacts/ingestion.test.ts +189 -227
  268. package/node_modules/@sdd-agent-platform/core/src/artifacts/ingestion.ts +222 -278
  269. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-evidence.test.ts +28 -28
  270. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-evidence.ts +302 -301
  271. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-result.test.ts +181 -181
  272. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-result.ts +231 -240
  273. package/node_modules/@sdd-agent-platform/core/src/artifacts/templates.ts +99 -99
  274. package/node_modules/@sdd-agent-platform/core/src/artifacts.ts +4 -4
  275. package/node_modules/@sdd-agent-platform/core/src/coding-facts/contracts.ts +79 -79
  276. package/node_modules/@sdd-agent-platform/core/src/coding-facts.ts +1 -1
  277. package/node_modules/@sdd-agent-platform/core/src/config/init-project.test.ts +314 -318
  278. package/node_modules/@sdd-agent-platform/core/src/config/init-project.ts +128 -123
  279. package/node_modules/@sdd-agent-platform/core/src/config/project-config.ts +265 -265
  280. package/node_modules/@sdd-agent-platform/core/src/config/project-detection.ts +147 -147
  281. package/node_modules/@sdd-agent-platform/core/src/config/starter-documents.ts +400 -432
  282. package/node_modules/@sdd-agent-platform/core/src/context/budget.ts +30 -30
  283. package/node_modules/@sdd-agent-platform/core/src/context/build-package.ts +305 -311
  284. package/node_modules/@sdd-agent-platform/core/src/context/command-summary.ts +45 -45
  285. package/node_modules/@sdd-agent-platform/core/src/context/context-build.test.ts +188 -189
  286. package/node_modules/@sdd-agent-platform/core/src/context/evidence-summary.ts +144 -163
  287. package/node_modules/@sdd-agent-platform/core/src/context/log-worker.ts +48 -48
  288. package/node_modules/@sdd-agent-platform/core/src/context/source-refs.ts +41 -41
  289. package/node_modules/@sdd-agent-platform/core/src/context-offload/contracts.ts +47 -47
  290. package/node_modules/@sdd-agent-platform/core/src/context-offload/runtime.test.ts +71 -71
  291. package/node_modules/@sdd-agent-platform/core/src/context-offload/runtime.ts +178 -178
  292. package/node_modules/@sdd-agent-platform/core/src/context-offload.ts +2 -2
  293. package/node_modules/@sdd-agent-platform/core/src/context.ts +6 -6
  294. package/node_modules/@sdd-agent-platform/core/src/contracts/issues.ts +13 -13
  295. package/node_modules/@sdd-agent-platform/core/src/contracts.test.ts +9 -9
  296. package/node_modules/@sdd-agent-platform/core/src/contracts.ts +121 -116
  297. package/node_modules/@sdd-agent-platform/core/src/delegation/delegation.test.ts +183 -183
  298. package/node_modules/@sdd-agent-platform/core/src/delegation/model.ts +23 -26
  299. package/node_modules/@sdd-agent-platform/core/src/delegation/queue.ts +58 -58
  300. package/node_modules/@sdd-agent-platform/core/src/delegation/run-state.ts +14 -14
  301. package/node_modules/@sdd-agent-platform/core/src/delegation/state-machine.ts +90 -90
  302. package/node_modules/@sdd-agent-platform/core/src/delegation/validation.ts +124 -127
  303. package/node_modules/@sdd-agent-platform/core/src/delegation.ts +26 -26
  304. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/ai-entries.ts +28 -28
  305. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/document-chain.ts +104 -112
  306. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/local-run-index.ts +27 -27
  307. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/project.ts +84 -84
  308. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/registries.ts +252 -251
  309. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-evidence.ts +330 -330
  310. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-records.ts +79 -79
  311. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-trust.ts +128 -107
  312. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/runtime-contracts.ts +300 -300
  313. package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.test.ts +627 -755
  314. package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.ts +301 -453
  315. package/node_modules/@sdd-agent-platform/core/src/doctor/model.ts +13 -13
  316. package/node_modules/@sdd-agent-platform/core/src/doctor/summary.ts +11 -11
  317. package/node_modules/@sdd-agent-platform/core/src/doctor.ts +2 -2
  318. package/node_modules/@sdd-agent-platform/core/src/evidence/lookup.ts +80 -88
  319. package/node_modules/@sdd-agent-platform/core/src/evidence-runtime/contracts.ts +48 -48
  320. package/node_modules/@sdd-agent-platform/core/src/evidence-runtime.ts +1 -1
  321. package/node_modules/@sdd-agent-platform/core/src/execution/agent-execution-records.ts +195 -195
  322. package/node_modules/@sdd-agent-platform/core/src/execution/background-executor.test.ts +187 -235
  323. package/node_modules/@sdd-agent-platform/core/src/execution/background-executor.ts +305 -305
  324. package/node_modules/@sdd-agent-platform/core/src/execution/foreground-subagents.test.ts +97 -106
  325. package/node_modules/@sdd-agent-platform/core/src/execution/foreground-subagents.ts +453 -453
  326. package/node_modules/@sdd-agent-platform/core/src/execution/host-invocation.ts +225 -226
  327. package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.test.ts +132 -143
  328. package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.ts +436 -437
  329. package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.test.ts +102 -102
  330. package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.ts +271 -271
  331. package/node_modules/@sdd-agent-platform/core/src/execution/wave-executor.test.ts +111 -121
  332. package/node_modules/@sdd-agent-platform/core/src/execution/wave-executor.ts +231 -231
  333. package/node_modules/@sdd-agent-platform/core/src/execution.ts +5 -5
  334. package/node_modules/@sdd-agent-platform/core/src/governance/policy.test.ts +57 -65
  335. package/node_modules/@sdd-agent-platform/core/src/governance/policy.ts +175 -175
  336. package/node_modules/@sdd-agent-platform/core/src/governance.ts +1 -1
  337. package/node_modules/@sdd-agent-platform/core/src/instructions.test.ts +80 -64
  338. package/node_modules/@sdd-agent-platform/core/src/instructions.ts +32 -68
  339. package/node_modules/@sdd-agent-platform/core/src/lifecycle/decision-gate.test.ts +174 -174
  340. package/node_modules/@sdd-agent-platform/core/src/lifecycle/decision-gate.ts +373 -373
  341. package/node_modules/@sdd-agent-platform/core/src/lifecycle/rendering.ts +29 -29
  342. package/node_modules/@sdd-agent-platform/core/src/lifecycle/risk-signals.ts +146 -146
  343. package/node_modules/@sdd-agent-platform/core/src/lifecycle/ship.test.ts +47 -47
  344. package/node_modules/@sdd-agent-platform/core/src/lifecycle/ship.ts +255 -280
  345. package/node_modules/@sdd-agent-platform/core/src/lifecycle-graph/contracts.ts +179 -0
  346. package/node_modules/@sdd-agent-platform/core/src/lifecycle-graph/kernel.ts +522 -0
  347. package/node_modules/@sdd-agent-platform/core/src/lifecycle-graph.ts +2 -0
  348. package/node_modules/@sdd-agent-platform/core/src/lifecycle.ts +4 -4
  349. package/node_modules/@sdd-agent-platform/core/src/orchestration/contracts.ts +50 -50
  350. package/node_modules/@sdd-agent-platform/core/src/orchestration/index.ts +2 -2
  351. package/node_modules/@sdd-agent-platform/core/src/orchestration/runtime.ts +331 -394
  352. package/node_modules/@sdd-agent-platform/core/src/path-safety.test.ts +22 -22
  353. package/node_modules/@sdd-agent-platform/core/src/phase8-contracts.test.ts +243 -242
  354. package/node_modules/@sdd-agent-platform/core/src/phase8-projection-compat.test.ts +152 -153
  355. package/node_modules/@sdd-agent-platform/core/src/phase8-risk-kernel.test.ts +277 -277
  356. package/node_modules/@sdd-agent-platform/core/src/phase9-lifecycle-graph.test.ts +103 -0
  357. package/node_modules/@sdd-agent-platform/core/src/planning/task-graph.test.ts +88 -88
  358. package/node_modules/@sdd-agent-platform/core/src/planning/task-graph.ts +222 -222
  359. package/node_modules/@sdd-agent-platform/core/src/planning/wave-plan.test.ts +79 -79
  360. package/node_modules/@sdd-agent-platform/core/src/planning/wave-plan.ts +160 -160
  361. package/node_modules/@sdd-agent-platform/core/src/planning.ts +2 -2
  362. package/node_modules/@sdd-agent-platform/core/src/registries/agent-capability-catalog.ts +426 -473
  363. package/node_modules/@sdd-agent-platform/core/src/registries/agent-registry.ts +230 -146
  364. package/node_modules/@sdd-agent-platform/core/src/registries/agent-runtime-static.ts +142 -142
  365. package/node_modules/@sdd-agent-platform/core/src/registries/capability-sources.ts +253 -253
  366. package/node_modules/@sdd-agent-platform/core/src/registries/command-team-runtime.ts +302 -309
  367. package/node_modules/@sdd-agent-platform/core/src/registries/eval-learning-context.ts +246 -246
  368. package/node_modules/@sdd-agent-platform/core/src/registries/plan-scout-domains.ts +89 -0
  369. package/node_modules/@sdd-agent-platform/core/src/registries/query-status.ts +119 -119
  370. package/node_modules/@sdd-agent-platform/core/src/registries/registries.test.ts +454 -445
  371. package/node_modules/@sdd-agent-platform/core/src/registries/skill-capabilities.ts +37 -37
  372. package/node_modules/@sdd-agent-platform/core/src/registries/tool-capabilities.ts +135 -135
  373. package/node_modules/@sdd-agent-platform/core/src/registries/tool-plugins.ts +132 -132
  374. package/node_modules/@sdd-agent-platform/core/src/registries/worker-adapters.ts +144 -144
  375. package/node_modules/@sdd-agent-platform/core/src/registries/workflow-gates.ts +111 -111
  376. package/node_modules/@sdd-agent-platform/core/src/registries.ts +42 -42
  377. package/node_modules/@sdd-agent-platform/core/src/risk/consumer-diagnostics.ts +98 -97
  378. package/node_modules/@sdd-agent-platform/core/src/risk/contracts.ts +63 -63
  379. package/node_modules/@sdd-agent-platform/core/src/risk/kernel.ts +233 -233
  380. package/node_modules/@sdd-agent-platform/core/src/risk/legacy-adapters.ts +251 -263
  381. package/node_modules/@sdd-agent-platform/core/src/risk/workflow-gates.ts +203 -205
  382. package/node_modules/@sdd-agent-platform/core/src/risk.ts +5 -5
  383. package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime-config.ts +327 -327
  384. package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime.ts +388 -390
  385. package/node_modules/@sdd-agent-platform/core/src/router/profile-resolution.ts +154 -154
  386. package/node_modules/@sdd-agent-platform/core/src/router/risk-policy.ts +33 -33
  387. package/node_modules/@sdd-agent-platform/core/src/router/route-cache.ts +100 -100
  388. package/node_modules/@sdd-agent-platform/core/src/router/route-projection.ts +356 -356
  389. package/node_modules/@sdd-agent-platform/core/src/router/route-sdd-task.test.ts +428 -665
  390. package/node_modules/@sdd-agent-platform/core/src/router/route-sdd-task.ts +2 -2
  391. package/node_modules/@sdd-agent-platform/core/src/router/routing-rules.ts +73 -73
  392. package/node_modules/@sdd-agent-platform/core/src/router/routing.ts +189 -223
  393. package/node_modules/@sdd-agent-platform/core/src/router/runtime-import.ts +464 -453
  394. package/node_modules/@sdd-agent-platform/core/src/router/runtime-inspection.ts +124 -124
  395. package/node_modules/@sdd-agent-platform/core/src/router/runtime-registry.ts +123 -123
  396. package/node_modules/@sdd-agent-platform/core/src/router/runtime-validation.ts +277 -277
  397. package/node_modules/@sdd-agent-platform/core/src/router/stage-route-binding.ts +273 -279
  398. package/node_modules/@sdd-agent-platform/core/src/router/team-mode.ts +170 -170
  399. package/node_modules/@sdd-agent-platform/core/src/router.ts +5 -6
  400. package/node_modules/@sdd-agent-platform/core/src/run-state/artifacts.ts +126 -240
  401. package/node_modules/@sdd-agent-platform/core/src/run-state/events.ts +27 -27
  402. package/node_modules/@sdd-agent-platform/core/src/run-state/inspect-run.ts +172 -172
  403. package/node_modules/@sdd-agent-platform/core/src/run-state/invocation-ledger.ts +109 -109
  404. package/node_modules/@sdd-agent-platform/core/src/run-state/model.ts +252 -253
  405. package/node_modules/@sdd-agent-platform/core/src/run-state/run-index.test.ts +52 -52
  406. package/node_modules/@sdd-agent-platform/core/src/run-state/run-index.ts +356 -352
  407. package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.test.ts +70 -118
  408. package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.ts +406 -416
  409. package/node_modules/@sdd-agent-platform/core/src/run-state/task-evidence.ts +198 -252
  410. package/node_modules/@sdd-agent-platform/core/src/run-state/timing.ts +146 -146
  411. package/node_modules/@sdd-agent-platform/core/src/run-state.ts +8 -9
  412. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis/build.ts +60 -60
  413. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis/findings.ts +257 -256
  414. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis/model.ts +140 -140
  415. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis.test.ts +66 -66
  416. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis.ts +2 -2
  417. package/node_modules/@sdd-agent-platform/core/src/runtime-paths.ts +253 -253
  418. package/node_modules/@sdd-agent-platform/core/src/runtime-projection-p0.test.ts +101 -96
  419. package/node_modules/@sdd-agent-platform/core/src/runtime-projection-p0.ts +314 -292
  420. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/artifact-depth.test.ts +380 -0
  421. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/artifact-depth.ts +207 -0
  422. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/context.ts +111 -111
  423. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/document-hashes.ts +207 -306
  424. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/run-binding.ts +95 -97
  425. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-inspection.ts +39 -39
  426. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.test.ts +467 -523
  427. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.ts +738 -709
  428. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-rendering.ts +81 -81
  429. package/node_modules/@sdd-agent-platform/core/src/sdd-docs.ts +5 -5
  430. package/node_modules/@sdd-agent-platform/core/src/spec-manager-contracts.ts +13 -0
  431. package/node_modules/@sdd-agent-platform/core/src/stage-artifacts.ts +435 -450
  432. package/node_modules/@sdd-agent-platform/core/src/stage-collaboration-contracts.ts +316 -322
  433. package/node_modules/@sdd-agent-platform/core/src/stage-collaboration.test.ts +2963 -2902
  434. package/node_modules/@sdd-agent-platform/core/src/stage-collaboration.ts +5856 -5831
  435. package/node_modules/@sdd-agent-platform/core/src/stage-runtime/contracts.ts +40 -40
  436. package/node_modules/@sdd-agent-platform/core/src/stage-runtime/runtime.test.ts +209 -209
  437. package/node_modules/@sdd-agent-platform/core/src/stage-runtime/runtime.ts +360 -360
  438. package/node_modules/@sdd-agent-platform/core/src/stage-runtime.ts +2 -2
  439. package/node_modules/@sdd-agent-platform/core/src/status/project-status.test.ts +288 -511
  440. package/node_modules/@sdd-agent-platform/core/src/status/project-status.ts +651 -851
  441. package/node_modules/@sdd-agent-platform/core/src/status.ts +2 -2
  442. package/node_modules/@sdd-agent-platform/core/src/storage/json-io.ts +10 -10
  443. package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.test.ts +489 -681
  444. package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.ts +1981 -1981
  445. package/node_modules/@sdd-agent-platform/core/src/subagents/contracts.ts +45 -45
  446. package/node_modules/@sdd-agent-platform/core/src/subagents/runtime.test.ts +232 -232
  447. package/node_modules/@sdd-agent-platform/core/src/subagents/runtime.ts +307 -307
  448. package/node_modules/@sdd-agent-platform/core/src/subagents.ts +2 -2
  449. package/node_modules/@sdd-agent-platform/core/src/task-execution-contract.test.ts +141 -0
  450. package/node_modules/@sdd-agent-platform/core/src/task-execution-contract.ts +566 -0
  451. package/node_modules/@sdd-agent-platform/core/src/task-risk-profile.ts +193 -193
  452. package/node_modules/@sdd-agent-platform/core/src/test-support/fixtures.ts +413 -398
  453. package/node_modules/@sdd-agent-platform/core/src/test-support/run-state.ts +102 -56
  454. package/node_modules/@sdd-agent-platform/core/src/test-support.ts +2 -2
  455. package/node_modules/@sdd-agent-platform/core/src/truth-reconciliation.test.ts +72 -72
  456. package/node_modules/@sdd-agent-platform/core/src/truth-reconciliation.ts +9 -12
  457. package/node_modules/@sdd-agent-platform/core/src/verification/rendering.ts +137 -137
  458. package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.test.ts +77 -84
  459. package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.ts +77 -77
  460. package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.ts +455 -506
  461. package/node_modules/@sdd-agent-platform/core/src/verification/{goal-verify.test.ts → task-evidence-judgment.test.ts} +261 -261
  462. package/node_modules/@sdd-agent-platform/core/src/verification/{goal-verify.ts → task-evidence-judgment.ts} +619 -619
  463. package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.ts +1190 -1190
  464. package/node_modules/@sdd-agent-platform/core/src/verification/validation-cache.ts +106 -106
  465. package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.ts +513 -556
  466. package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.ts +334 -334
  467. package/node_modules/@sdd-agent-platform/core/src/verification.ts +8 -8
  468. package/node_modules/@sdd-agent-platform/core/src/work-units/contracts.ts +26 -26
  469. package/node_modules/@sdd-agent-platform/core/src/work-units/runtime.test.ts +88 -88
  470. package/node_modules/@sdd-agent-platform/core/src/work-units/runtime.ts +112 -112
  471. package/node_modules/@sdd-agent-platform/core/src/work-units.ts +2 -2
  472. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/evidence-packet.ts +190 -425
  473. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.test.ts +169 -507
  474. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.ts +136 -182
  475. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.test.ts +135 -174
  476. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.ts +153 -194
  477. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/types.ts +111 -115
  478. package/node_modules/@sdd-agent-platform/core/src/workflow-state/affected-file-conflicts.ts +95 -93
  479. package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.test.ts +32 -32
  480. package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.ts +114 -114
  481. package/node_modules/@sdd-agent-platform/core/src/workflow-state/latest-eligible-run.ts +184 -224
  482. package/node_modules/@sdd-agent-platform/core/src/workflow-state/migration-recovery.ts +158 -158
  483. package/node_modules/@sdd-agent-platform/core/src/workflow-state/repair-contract.ts +77 -77
  484. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve-task-run.ts +114 -114
  485. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.test.ts +969 -956
  486. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.ts +967 -992
  487. package/node_modules/@sdd-agent-platform/core/src/workflow-state/runtime-projections.ts +712 -712
  488. package/node_modules/@sdd-agent-platform/core/src/workflow-state.ts +2 -2
  489. package/node_modules/@sdd-agent-platform/core/src/worktree/isolation.ts +130 -130
  490. package/node_modules/@sdd-agent-platform/core/src/worktree/lifecycle.ts +269 -269
  491. package/node_modules/@sdd-agent-platform/core/src/worktree/worktree.test.ts +150 -150
  492. package/node_modules/@sdd-agent-platform/core/src/worktree.ts +2 -2
  493. package/node_modules/@sdd-agent-platform/core/tsconfig.json +15 -15
  494. package/package.json +2 -2
  495. package/packages/cli/dist/args.js +2 -2
  496. package/packages/cli/dist/args.js.map +1 -1
  497. package/packages/cli/dist/commands/ai-tools.js +2 -13
  498. package/packages/cli/dist/commands/ai-tools.js.map +1 -1
  499. package/packages/cli/dist/commands/{verifies.d.ts → artifact.d.ts} +1 -1
  500. package/packages/cli/dist/commands/artifact.js +168 -0
  501. package/packages/cli/dist/commands/artifact.js.map +1 -0
  502. package/packages/cli/dist/commands/context.js +1 -1
  503. package/packages/cli/dist/commands/context.js.map +1 -1
  504. package/packages/cli/dist/commands/evidence.js.map +1 -0
  505. package/packages/cli/dist/commands/execution.js +127 -49
  506. package/packages/cli/dist/commands/execution.js.map +1 -1
  507. package/packages/cli/dist/commands/governance.js +1 -1
  508. package/packages/cli/dist/commands/governance.js.map +1 -1
  509. package/packages/cli/dist/commands/init.js +1 -6
  510. package/packages/cli/dist/commands/init.js.map +1 -1
  511. package/packages/cli/dist/commands/instructions.d.ts +1 -1
  512. package/packages/cli/dist/commands/instructions.js +15 -1
  513. package/packages/cli/dist/commands/instructions.js.map +1 -1
  514. package/packages/cli/dist/commands/registry/runtime.js +63 -40
  515. package/packages/cli/dist/commands/registry/runtime.js.map +1 -1
  516. package/packages/cli/dist/commands/run.js +13 -52
  517. package/packages/cli/dist/commands/run.js.map +1 -1
  518. package/packages/cli/dist/commands/stage-close.d.ts +60 -0
  519. package/packages/cli/dist/commands/stage-close.js +270 -41
  520. package/packages/cli/dist/commands/stage-close.js.map +1 -1
  521. package/packages/cli/dist/commands/status.js +9 -68
  522. package/packages/cli/dist/commands/status.js.map +1 -1
  523. package/packages/cli/dist/commands/tasks.js.map +1 -1
  524. package/packages/cli/dist/dispatch.js +6 -26
  525. package/packages/cli/dist/dispatch.js.map +1 -1
  526. package/packages/cli/dist/help.js +153 -159
  527. package/packages/cli/dist/help.js.map +1 -1
  528. package/packages/cli/dist/renderers/artifacts.d.ts +5 -0
  529. package/packages/cli/dist/renderers/artifacts.js +43 -0
  530. package/packages/cli/dist/renderers/artifacts.js.map +1 -0
  531. package/packages/cli/dist/renderers/doctor.js +1 -1
  532. package/packages/cli/dist/renderers/doctor.js.map +1 -1
  533. package/packages/cli/dist/renderers/execution.js +1 -1
  534. package/packages/cli/dist/renderers/execution.js.map +1 -1
  535. package/packages/cli/dist/renderers/json.d.ts +0 -1
  536. package/packages/cli/dist/renderers/json.js +0 -3
  537. package/packages/cli/dist/renderers/json.js.map +1 -1
  538. package/packages/cli/dist/renderers/registry-runtime.d.ts +1 -2
  539. package/packages/cli/dist/renderers/registry-runtime.js +0 -20
  540. package/packages/cli/dist/renderers/registry-runtime.js.map +1 -1
  541. package/packages/cli/dist/renderers/router.js +1 -1
  542. package/packages/cli/dist/renderers/router.js.map +1 -1
  543. package/packages/cli/dist/renderers/workflow.d.ts +53 -0
  544. package/packages/cli/dist/renderers/workflow.js +89 -30
  545. package/packages/cli/dist/renderers/workflow.js.map +1 -1
  546. package/packages/cli/dist/tsconfig.tsbuildinfo +1 -1
  547. package/packages/cli/package.json +2 -2
  548. package/packages/core/dist/ai-tools.js +56 -73
  549. package/packages/core/dist/ai-tools.js.map +1 -1
  550. package/packages/core/dist/artifacts/ingestion.js +9 -64
  551. package/packages/core/dist/artifacts/ingestion.js.map +1 -1
  552. package/packages/core/dist/artifacts/sdd-evidence.js +1 -0
  553. package/packages/core/dist/artifacts/sdd-evidence.js.map +1 -1
  554. package/packages/core/dist/artifacts/sdd-result.js +17 -26
  555. package/packages/core/dist/artifacts/sdd-result.js.map +1 -1
  556. package/packages/core/dist/config/init-project.d.ts +8 -7
  557. package/packages/core/dist/config/init-project.js +8 -12
  558. package/packages/core/dist/config/init-project.js.map +1 -1
  559. package/packages/core/dist/config/project-config.d.ts +1 -1
  560. package/packages/core/dist/config/project-config.js +1 -1
  561. package/packages/core/dist/config/project-config.js.map +1 -1
  562. package/packages/core/dist/config/starter-documents.d.ts +3 -4
  563. package/packages/core/dist/config/starter-documents.js +377 -411
  564. package/packages/core/dist/config/starter-documents.js.map +1 -1
  565. package/packages/core/dist/context/build-package.d.ts +1 -1
  566. package/packages/core/dist/context/build-package.js +7 -13
  567. package/packages/core/dist/context/build-package.js.map +1 -1
  568. package/packages/core/dist/context/evidence-summary.js +8 -26
  569. package/packages/core/dist/context/evidence-summary.js.map +1 -1
  570. package/packages/core/dist/context/log-worker.js +2 -2
  571. package/packages/core/dist/context/log-worker.js.map +1 -1
  572. package/packages/core/dist/context-offload/contracts.d.ts +1 -1
  573. package/packages/core/dist/contracts.d.ts +6 -1
  574. package/packages/core/dist/contracts.js +5 -0
  575. package/packages/core/dist/contracts.js.map +1 -1
  576. package/packages/core/dist/delegation/model.d.ts +0 -3
  577. package/packages/core/dist/delegation/validation.d.ts +0 -3
  578. package/packages/core/dist/delegation/validation.js +4 -7
  579. package/packages/core/dist/delegation/validation.js.map +1 -1
  580. package/packages/core/dist/doctor/checks/document-chain.js +3 -13
  581. package/packages/core/dist/doctor/checks/document-chain.js.map +1 -1
  582. package/packages/core/dist/doctor/checks/project.js +8 -8
  583. package/packages/core/dist/doctor/checks/project.js.map +1 -1
  584. package/packages/core/dist/doctor/checks/registries.js +1 -0
  585. package/packages/core/dist/doctor/checks/registries.js.map +1 -1
  586. package/packages/core/dist/doctor/checks/run-evidence.js +4 -4
  587. package/packages/core/dist/doctor/checks/run-evidence.js.map +1 -1
  588. package/packages/core/dist/doctor/checks/run-trust.js +24 -0
  589. package/packages/core/dist/doctor/checks/run-trust.js.map +1 -1
  590. package/packages/core/dist/doctor/checks/runtime-contracts.js +1 -1
  591. package/packages/core/dist/doctor/checks/runtime-contracts.js.map +1 -1
  592. package/packages/core/dist/doctor/doctor.js +43 -180
  593. package/packages/core/dist/doctor/doctor.js.map +1 -1
  594. package/packages/core/dist/evidence/lookup.d.ts +1 -1
  595. package/packages/core/dist/evidence/lookup.js +7 -14
  596. package/packages/core/dist/evidence/lookup.js.map +1 -1
  597. package/packages/core/dist/evidence-runtime/coordination.js +110 -0
  598. package/packages/core/dist/evidence-runtime/coordination.js.map +1 -0
  599. package/packages/core/dist/execution/background-executor.js +4 -4
  600. package/packages/core/dist/execution/background-executor.js.map +1 -1
  601. package/packages/core/dist/execution/foreground-subagents.js +3 -3
  602. package/packages/core/dist/execution/foreground-subagents.js.map +1 -1
  603. package/packages/core/dist/execution/host-invocation.js +85 -86
  604. package/packages/core/dist/execution/host-invocation.js.map +1 -1
  605. package/packages/core/dist/execution/resident-worker.js +2 -3
  606. package/packages/core/dist/execution/resident-worker.js.map +1 -1
  607. package/packages/core/dist/execution/stage-team-runtime.js +2 -2
  608. package/packages/core/dist/execution/stage-team-runtime.js.map +1 -1
  609. package/packages/core/dist/governance/policy.d.ts +1 -1
  610. package/packages/core/dist/governance/policy.js +1 -1
  611. package/packages/core/dist/governance/policy.js.map +1 -1
  612. package/packages/core/dist/instructions.d.ts +1 -1
  613. package/packages/core/dist/instructions.js +31 -67
  614. package/packages/core/dist/instructions.js.map +1 -1
  615. package/packages/core/dist/lifecycle/decision-gate.js +1 -1
  616. package/packages/core/dist/lifecycle/decision-gate.js.map +1 -1
  617. package/packages/core/dist/lifecycle/ship.d.ts +0 -1
  618. package/packages/core/dist/lifecycle/ship.js +59 -85
  619. package/packages/core/dist/lifecycle/ship.js.map +1 -1
  620. package/packages/core/dist/lifecycle-graph/contracts.d.ts +159 -0
  621. package/packages/core/dist/lifecycle-graph/contracts.js +7 -0
  622. package/packages/core/dist/lifecycle-graph/contracts.js.map +1 -0
  623. package/packages/core/dist/lifecycle-graph/kernel.d.ts +16 -0
  624. package/packages/core/dist/lifecycle-graph/kernel.js +461 -0
  625. package/packages/core/dist/lifecycle-graph/kernel.js.map +1 -0
  626. package/packages/core/dist/lifecycle-graph.d.ts +2 -0
  627. package/packages/core/dist/lifecycle-graph.js +3 -0
  628. package/packages/core/dist/lifecycle-graph.js.map +1 -0
  629. package/packages/core/dist/orchestration/contracts.d.ts +1 -1
  630. package/packages/core/dist/orchestration/runtime.d.ts +2 -12
  631. package/packages/core/dist/orchestration/runtime.js +32 -80
  632. package/packages/core/dist/orchestration/runtime.js.map +1 -1
  633. package/packages/core/dist/registries/agent-capability-catalog.d.ts +2 -5
  634. package/packages/core/dist/registries/agent-capability-catalog.js +27 -69
  635. package/packages/core/dist/registries/agent-capability-catalog.js.map +1 -1
  636. package/packages/core/dist/registries/agent-registry.js +118 -34
  637. package/packages/core/dist/registries/agent-registry.js.map +1 -1
  638. package/packages/core/dist/registries/agent-runtime-static.js +1 -1
  639. package/packages/core/dist/registries/agent-runtime-static.js.map +1 -1
  640. package/packages/core/dist/registries/capability-sources.js +1 -1
  641. package/packages/core/dist/registries/command-team-runtime.d.ts +1 -1
  642. package/packages/core/dist/registries/command-team-runtime.js +8 -15
  643. package/packages/core/dist/registries/command-team-runtime.js.map +1 -1
  644. package/packages/core/dist/registries/eval-learning-context.js +4 -4
  645. package/packages/core/dist/registries/eval-learning-context.js.map +1 -1
  646. package/packages/core/dist/registries/plan-scout-domains.d.ts +13 -0
  647. package/packages/core/dist/registries/plan-scout-domains.js +76 -0
  648. package/packages/core/dist/registries/plan-scout-domains.js.map +1 -0
  649. package/packages/core/dist/registries/query-status.js +2 -2
  650. package/packages/core/dist/registries/query-status.js.map +1 -1
  651. package/packages/core/dist/registries/skill-capabilities.js +7 -7
  652. package/packages/core/dist/registries/skill-capabilities.js.map +1 -1
  653. package/packages/core/dist/registries/tool-capabilities.js +4 -4
  654. package/packages/core/dist/registries/tool-capabilities.js.map +1 -1
  655. package/packages/core/dist/registries/tool-plugins.js +2 -2
  656. package/packages/core/dist/registries/tool-plugins.js.map +1 -1
  657. package/packages/core/dist/registries/worker-adapters.js +11 -11
  658. package/packages/core/dist/registries/worker-adapters.js.map +1 -1
  659. package/packages/core/dist/registries/workflow-gates.d.ts +1 -1
  660. package/packages/core/dist/registries/workflow-gates.js +21 -21
  661. package/packages/core/dist/registries/workflow-gates.js.map +1 -1
  662. package/packages/core/dist/risk/consumer-diagnostics.js +2 -1
  663. package/packages/core/dist/risk/consumer-diagnostics.js.map +1 -1
  664. package/packages/core/dist/risk/kernel.js +6 -6
  665. package/packages/core/dist/risk/kernel.js.map +1 -1
  666. package/packages/core/dist/risk/legacy-adapters.js +11 -23
  667. package/packages/core/dist/risk/legacy-adapters.js.map +1 -1
  668. package/packages/core/dist/risk/workflow-gates.d.ts +2 -2
  669. package/packages/core/dist/risk/workflow-gates.js +18 -20
  670. package/packages/core/dist/risk/workflow-gates.js.map +1 -1
  671. package/packages/core/dist/router/agent-runtime.d.ts +0 -2
  672. package/packages/core/dist/router/route-projection.js +1 -1
  673. package/packages/core/dist/router/route-projection.js.map +1 -1
  674. package/packages/core/dist/router/routing.js +16 -48
  675. package/packages/core/dist/router/routing.js.map +1 -1
  676. package/packages/core/dist/router/runtime-import.js +11 -1
  677. package/packages/core/dist/router/runtime-import.js.map +1 -1
  678. package/packages/core/dist/router/runtime-validation.js +2 -2
  679. package/packages/core/dist/router/runtime-validation.js.map +1 -1
  680. package/packages/core/dist/router/stage-route-binding.d.ts +2 -2
  681. package/packages/core/dist/router/stage-route-binding.js +20 -28
  682. package/packages/core/dist/router/stage-route-binding.js.map +1 -1
  683. package/packages/core/dist/router.d.ts +0 -1
  684. package/packages/core/dist/router.js +0 -1
  685. package/packages/core/dist/router.js.map +1 -1
  686. package/packages/core/dist/run-state/artifacts.d.ts +6 -6
  687. package/packages/core/dist/run-state/artifacts.js +13 -124
  688. package/packages/core/dist/run-state/artifacts.js.map +1 -1
  689. package/packages/core/dist/run-state/inspect-run.d.ts +2 -0
  690. package/packages/core/dist/run-state/inspect-run.js +5 -7
  691. package/packages/core/dist/run-state/inspect-run.js.map +1 -1
  692. package/packages/core/dist/run-state/model.d.ts +28 -28
  693. package/packages/core/dist/run-state/run-index.d.ts +2 -0
  694. package/packages/core/dist/run-state/run-index.js +3 -1
  695. package/packages/core/dist/run-state/run-index.js.map +1 -1
  696. package/packages/core/dist/run-state/run-state.js +26 -36
  697. package/packages/core/dist/run-state/run-state.js.map +1 -1
  698. package/packages/core/dist/run-state/task-evidence.d.ts +0 -4
  699. package/packages/core/dist/run-state/task-evidence.js +5 -51
  700. package/packages/core/dist/run-state/task-evidence.js.map +1 -1
  701. package/packages/core/dist/run-state.d.ts +0 -1
  702. package/packages/core/dist/run-state.js +0 -1
  703. package/packages/core/dist/run-state.js.map +1 -1
  704. package/packages/core/dist/runtime-analysis/build.js +1 -1
  705. package/packages/core/dist/runtime-analysis/build.js.map +1 -1
  706. package/packages/core/dist/runtime-analysis/findings.js +5 -5
  707. package/packages/core/dist/runtime-analysis/findings.js.map +1 -1
  708. package/packages/core/dist/runtime-paths.js +1 -1
  709. package/packages/core/dist/runtime-paths.js.map +1 -1
  710. package/packages/core/dist/runtime-projection-p0.d.ts +2 -2
  711. package/packages/core/dist/runtime-projection-p0.js +11 -0
  712. package/packages/core/dist/runtime-projection-p0.js.map +1 -1
  713. package/packages/core/dist/sdd-docs/artifact-depth.d.ts +14 -0
  714. package/packages/core/dist/sdd-docs/artifact-depth.js +179 -0
  715. package/packages/core/dist/sdd-docs/artifact-depth.js.map +1 -0
  716. package/packages/core/dist/sdd-docs/document-hashes.d.ts +0 -2
  717. package/packages/core/dist/sdd-docs/document-hashes.js +10 -97
  718. package/packages/core/dist/sdd-docs/document-hashes.js.map +1 -1
  719. package/packages/core/dist/sdd-docs/run-binding.d.ts +1 -1
  720. package/packages/core/dist/sdd-docs/run-binding.js +6 -8
  721. package/packages/core/dist/sdd-docs/run-binding.js.map +1 -1
  722. package/packages/core/dist/sdd-docs/task-parser.d.ts +5 -2
  723. package/packages/core/dist/sdd-docs/task-parser.js +85 -68
  724. package/packages/core/dist/sdd-docs/task-parser.js.map +1 -1
  725. package/packages/core/dist/sdd-docs/task-rendering.js +2 -2
  726. package/packages/core/dist/sdd-docs/task-rendering.js.map +1 -1
  727. package/packages/core/dist/spec-entry.js +40 -0
  728. package/packages/core/dist/spec-entry.js.map +1 -0
  729. package/packages/core/dist/spec-manager-contracts.d.ts +12 -0
  730. package/packages/core/dist/spec-manager-contracts.js +2 -0
  731. package/packages/core/dist/spec-manager-contracts.js.map +1 -0
  732. package/packages/core/dist/stage-artifacts.d.ts +2 -2
  733. package/packages/core/dist/stage-artifacts.js +19 -26
  734. package/packages/core/dist/stage-artifacts.js.map +1 -1
  735. package/packages/core/dist/stage-collaboration-contracts.d.ts +1 -1
  736. package/packages/core/dist/stage-collaboration-contracts.js +3 -6
  737. package/packages/core/dist/stage-collaboration-contracts.js.map +1 -1
  738. package/packages/core/dist/stage-collaboration.d.ts +111 -263
  739. package/packages/core/dist/stage-collaboration.js +1272 -1124
  740. package/packages/core/dist/stage-collaboration.js.map +1 -1
  741. package/packages/core/dist/stage-runtime/runtime.js +5 -5
  742. package/packages/core/dist/stage-runtime/runtime.js.map +1 -1
  743. package/packages/core/dist/status/project-status.d.ts +1 -44
  744. package/packages/core/dist/status/project-status.js +47 -170
  745. package/packages/core/dist/status/project-status.js.map +1 -1
  746. package/packages/core/dist/storage/runtime-store.js +73 -73
  747. package/packages/core/dist/subagents/contracts.d.ts +1 -1
  748. package/packages/core/dist/subagents/runtime.js +7 -7
  749. package/packages/core/dist/subagents/runtime.js.map +1 -1
  750. package/packages/core/dist/sync-back/apply.d.ts +1 -0
  751. package/packages/core/dist/sync-back/apply.js +2 -0
  752. package/packages/core/dist/sync-back/apply.js.map +1 -0
  753. package/packages/core/dist/sync-back/inspect.d.ts +1 -0
  754. package/packages/core/dist/sync-back/inspect.js +2 -0
  755. package/packages/core/dist/sync-back/inspect.js.map +1 -0
  756. package/packages/core/dist/sync-back.d.ts +1 -0
  757. package/packages/core/dist/sync-back.js +2 -0
  758. package/packages/core/dist/sync-back.js.map +1 -0
  759. package/packages/core/dist/task-execution-contract.d.ts +167 -0
  760. package/packages/core/dist/task-execution-contract.js +377 -0
  761. package/packages/core/dist/task-execution-contract.js.map +1 -0
  762. package/packages/core/dist/test-support/fixtures.js +329 -314
  763. package/packages/core/dist/test-support/fixtures.js.map +1 -1
  764. package/packages/core/dist/test-support/run-state.d.ts +1 -0
  765. package/packages/core/dist/test-support/run-state.js +53 -7
  766. package/packages/core/dist/test-support/run-state.js.map +1 -1
  767. package/packages/core/dist/truth-reconciliation.js +9 -12
  768. package/packages/core/dist/truth-reconciliation.js.map +1 -1
  769. package/packages/core/dist/tsconfig.tsbuildinfo +1 -1
  770. package/packages/core/dist/verification/goal-verify.d.ts +0 -48
  771. package/packages/core/dist/verification/goal-verify.js +1 -520
  772. package/packages/core/dist/verification/goal-verify.js.map +1 -1
  773. package/packages/core/dist/verification/rendering.d.ts +5 -5
  774. package/packages/core/dist/verification/rendering.js +14 -14
  775. package/packages/core/dist/verification/rendering.js.map +1 -1
  776. package/packages/core/dist/verification/single-task-loop.d.ts +1 -0
  777. package/packages/core/dist/verification/single-task-loop.js +111 -159
  778. package/packages/core/dist/verification/single-task-loop.js.map +1 -1
  779. package/packages/core/dist/verification/task-evidence-judgment.d.ts +49 -0
  780. package/packages/core/dist/verification/task-evidence-judgment.js +521 -0
  781. package/packages/core/dist/verification/task-evidence-judgment.js.map +1 -0
  782. package/packages/core/dist/verification/test-runtime.js +21 -21
  783. package/packages/core/dist/verification/test-runtime.js.map +1 -1
  784. package/packages/core/dist/verification/validation-wave.d.ts +0 -18
  785. package/packages/core/dist/verification/validation-wave.js +5 -27
  786. package/packages/core/dist/verification/validation-wave.js.map +1 -1
  787. package/packages/core/dist/verification/verify-contract.js +45 -45
  788. package/packages/core/dist/verification/verify-contract.js.map +1 -1
  789. package/packages/core/dist/verification.d.ts +3 -3
  790. package/packages/core/dist/verification.js +2 -2
  791. package/packages/core/dist/verification.js.map +1 -1
  792. package/packages/core/dist/work-units/contracts.d.ts +1 -1
  793. package/packages/core/dist/workflow-gate/evidence-packet.js +9 -227
  794. package/packages/core/dist/workflow-gate/evidence-packet.js.map +1 -1
  795. package/packages/core/dist/workflow-gate/hard-checks.js +9 -50
  796. package/packages/core/dist/workflow-gate/hard-checks.js.map +1 -1
  797. package/packages/core/dist/workflow-gate/policy.js +4 -42
  798. package/packages/core/dist/workflow-gate/policy.js.map +1 -1
  799. package/packages/core/dist/workflow-gate/types.d.ts +2 -3
  800. package/packages/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
  801. package/packages/core/dist/workflow-state/affected-file-conflicts.js +2 -1
  802. package/packages/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
  803. package/packages/core/dist/workflow-state/dependencies.js +1 -1
  804. package/packages/core/dist/workflow-state/latest-eligible-run.d.ts +1 -0
  805. package/packages/core/dist/workflow-state/latest-eligible-run.js +23 -63
  806. package/packages/core/dist/workflow-state/latest-eligible-run.js.map +1 -1
  807. package/packages/core/dist/workflow-state/resolve.d.ts +2 -2
  808. package/packages/core/dist/workflow-state/resolve.js +43 -65
  809. package/packages/core/dist/workflow-state/resolve.js.map +1 -1
  810. package/packages/core/package.json +5 -2
  811. package/tsconfig.build.json +6 -7
  812. package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.test.ts +0 -269
  813. package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.test.ts +0 -492
  814. package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.test.ts +0 -383
  815. package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.test.ts +0 -188
  816. package/packages/cli/dist/commands/lifecycle.d.ts +0 -6
  817. package/packages/cli/dist/commands/lifecycle.js +0 -125
  818. package/packages/cli/dist/commands/lifecycle.js.map +0 -1
  819. package/packages/cli/dist/commands/test.d.ts +0 -6
  820. package/packages/cli/dist/commands/test.js +0 -373
  821. package/packages/cli/dist/commands/test.js.map +0 -1
  822. package/packages/cli/dist/commands/verifies.js +0 -87
  823. package/packages/cli/dist/commands/verifies.js.map +0 -1
  824. package/packages/cli/dist/commands/verify.d.ts +0 -6
  825. package/packages/cli/dist/commands/verify.js +0 -330
  826. 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
+ }