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
@@ -7,18 +7,18 @@ import { createRun } from './run-state/run-state.js';
7
7
  import { normalizePortablePath } from './path-safety.js';
8
8
  import { getBranchStageEvidenceDir, normalizeBranchStageEvidenceRef, toBranchStageEvidenceRef } from './runtime-paths.js';
9
9
  import { resolveSddContext } from './sdd-docs/context.js';
10
+ import { evaluatePlanArtifactDepth, evaluateSpecArtifactDepth, formatArtifactDepthBlockingIssues } from './sdd-docs/artifact-depth.js';
10
11
  import { hashDocumentContent, hashSemanticDocument, hashTasksContract } from './sdd-docs/document-hashes.js';
11
12
  import { parseSddTasksMarkdown } from './sdd-docs/task-parser.js';
13
+ import { EXECUTION_LANE_PROJECTION_TYPE, TASK_DEPENDENCY_GRAPH_PROJECTION_TYPE, TASK_UNIT_PROJECTION_TYPE, executionLaneScopeKey, readTaskDependencyGraphProjection, taskDependencyGraphScopeKey } from './task-execution-contract.js';
12
14
  import { readWorkflowHandoffProjection, recordStageRunProjection, recordWorkflowHandoffProjection, STAGE_RUN_PROJECTION_TYPE, stageRunScopeKey, WORKFLOW_HANDOFF_PROJECTION_TYPE, workflowHandoffScopeKey } from './stage-runtime/runtime.js';
13
15
  import { listRuntimeProjections, recordRuntimeArtifactPayload, recordRuntimeProjectionEnvelope, recordRuntimeStageArtifact, recordRuntimeStageCollaborationContract, runtimeScopedId } from './storage/runtime-store.js';
14
16
  import { readMarkdownArtifact, validateStageArtifactFrontmatter } from './stage-artifacts.js';
15
17
  import { readStageCollaborationContract, validateStageCollaborationContractFrontmatter } from './stage-collaboration-contracts.js';
16
- import { inspectVerifyContract } from './verification/verify-contract.js';
17
18
  export const SPEC_STAGE_MANAGER = 'spec-manager';
18
- export const SPEC_STAGE_DRAFTER_AGENT = 'spec-drafter';
19
19
  export const SPEC_STAGE_REVIEW_AGENT = 'spec-reviewer';
20
20
  export const SPEC_STAGE_SCOUT_AGENT = 'scout';
21
- export const SPEC_STAGE_AGENT_TEAM = [SPEC_STAGE_DRAFTER_AGENT, SPEC_STAGE_REVIEW_AGENT, SPEC_STAGE_SCOUT_AGENT];
21
+ export const SPEC_STAGE_AGENT_TEAM = [SPEC_STAGE_SCOUT_AGENT, SPEC_STAGE_REVIEW_AGENT];
22
22
  export const SPEC_STAGE_REQUIRED_CAPABILITIES = ['norm_discovery', 'uncertainty_resolution'];
23
23
  export const SPEC_STAGE_OPTIONAL_CAPABILITIES = ['context_curation', 'solution-design', 'frontend-engineering', 'security-engineering', 'ui-ux-product-design'];
24
24
  export const SPEC_STAGE_MATERIAL_PACKS = ['project-norms', 'uncertainty-map', 'baseline-solution-design', 'baseline-frontend-engineering', 'baseline-security-engineering', 'baseline-ui-ux-product-design'];
@@ -26,32 +26,26 @@ export const STAGE_COLLABORATION_RUNTIME_PRODUCER_VERSION = 'phase9.1-stage-coll
26
26
  export const SPEC_COLLABORATION_ADJUDICATION_PROJECTION_TYPE = 'phase9_1_spec_collaboration_adjudication';
27
27
  export const PLAN_COLLABORATION_ADJUDICATION_PROJECTION_TYPE = 'phase9_2_plan_collaboration_adjudication';
28
28
  export const PLAN_STAGE_MANAGER = 'plan-manager';
29
- export const PLAN_STAGE_DRAFTER_AGENT = 'plan-drafter';
30
- export const PLAN_STAGE_REVIEW_AGENT = 'plan-reviewer';
29
+ export const PLAN_STAGE_SCOUT_AGENT = 'plan-scout';
30
+ export const PLAN_STAGE_REVIEW_AGENT = 'plan-review-agent';
31
+ export const PLAN_STAGE_AGENT_TEAM = [PLAN_STAGE_SCOUT_AGENT, PLAN_STAGE_REVIEW_AGENT];
32
+ export const PLAN_SCOUT_DOMAINS = ['architecture-runtime', 'backend-api', 'frontend-ui', 'database-migration', 'security', 'performance', 'testing-validation'];
33
+ export const PLAN_STAGE_REQUIRED_CAPABILITIES = ['plan-strategy', 'plan-pressure-review'];
34
+ export const PLAN_STAGE_OPTIONAL_CAPABILITIES = [...PLAN_SCOUT_DOMAINS];
35
+ export const PLAN_STAGE_MATERIAL_PACKS = ['project-norms', 'plan-section-rubric', 'plan-scout-domain-packs'];
31
36
  export const TASKS_COLLABORATION_ADJUDICATION_PROJECTION_TYPE = 'phase9_3_tasks_collaboration_adjudication';
32
37
  export const TASKS_STAGE_MANAGER = 'tasks-manager';
33
- export const TASKS_STAGE_DRAFTER_AGENT = 'tasks-drafter';
34
- export const TASKS_STAGE_REVIEW_AGENT = 'tasks-reviewer';
38
+ export const TASKS_STAGE_REVIEW_AGENT = 'task-review-agent';
35
39
  export const TASKS_STAGE_SLICER_AGENT = 'task-slicer';
36
- export const VERIFIES_COLLABORATION_ADJUDICATION_PROJECTION_TYPE = 'phase9_4_verifies_collaboration_adjudication';
37
- export const VERIFIES_STAGE_MANAGER = 'verifies-manager';
38
- export const VERIFIES_STAGE_DRAFTER_AGENT = 'verifies-drafter';
39
- export const VERIFIES_STAGE_REVIEW_AGENT = 'verifies-reviewer';
40
- export const VERIFIES_STAGE_VERIFICATION_AGENT = 'verification-agent';
41
- export const DO_COLLABORATION_ADJUDICATION_PROJECTION_TYPE = 'phase9_5_do_collaboration_adjudication';
42
- export const DO_STAGE_MANAGER = 'do-manager';
43
- export const DO_STAGE_IMPLEMENTER_AGENT = 'implementer';
44
- export const DO_STAGE_CODE_REVIEW_AGENT = 'code-reviewer';
45
- export const DO_STAGE_DEBUGGER_AGENT = 'debugger';
46
- export const TEST_COLLABORATION_ADJUDICATION_PROJECTION_TYPE = 'phase9_6_test_collaboration_adjudication';
47
- export const TEST_STAGE_MANAGER = 'test-manager';
48
- export const TEST_STAGE_RUNNER_AGENT = 'test-runner';
49
- export const TEST_STAGE_VALIDATOR_AGENT = 'validator';
50
- export const TEST_STAGE_REVIEW_AGENT = 'test-reviewer';
51
- export const GOAL_VERIFY_COLLABORATION_ADJUDICATION_PROJECTION_TYPE = 'phase9_7_goal_verify_collaboration_adjudication';
52
- export const GOAL_VERIFY_STAGE_MANAGER = 'goal-verify-manager';
53
- export const GOAL_VERIFY_STAGE_VALIDATOR_AGENT = 'goal-validator';
54
- export const GOAL_VERIFY_STAGE_REVIEW_AGENT = 'goal-reviewer';
40
+ export const EXECUTE_IMPLEMENTER_AGENT = 'implementer';
41
+ export const EXECUTE_CODE_REVIEW_AGENT = 'code-reviewer';
42
+ export const EXECUTE_DEBUGGER_AGENT = 'debugger';
43
+ export const EXECUTE_TEST_RUNNER_AGENT = 'test-runner';
44
+ export const EXECUTE_VALIDATOR_AGENT = 'validator';
45
+ export const EXECUTE_TEST_REVIEW_AGENT = 'test-reviewer';
46
+ export const EXECUTE_COLLABORATION_ADJUDICATION_PROJECTION_TYPE = 'phase10_execute_collaboration_adjudication';
47
+ export const EXECUTE_EVIDENCE_JUDGMENT_VALIDATOR_AGENT = 'evidence-validator';
48
+ export const EXECUTE_EVIDENCE_JUDGMENT_REVIEW_AGENT = 'evidence-reviewer';
55
49
  export const TRUTH_ALIGNMENT_PROJECTION_TYPE = 'phase9_12_truth_alignment';
56
50
  export const TRUTH_ALIGNMENT_CONTRACT = 'sdd-truth-alignment-v1';
57
51
  export const SHIP_COLLABORATION_ADJUDICATION_PROJECTION_TYPE = 'phase9_9_ship_collaboration_adjudication';
@@ -60,7 +54,7 @@ export const SHIP_STAGE_VALIDATOR_AGENT = 'ship-validator';
60
54
  export const SHIP_STAGE_REVIEW_AGENT = 'release-reviewer';
61
55
  const TRUTH_ALIGNMENT_STATUSES = ['aligned', 'drift_detected', 'update_required', 'blocked'];
62
56
  const TRUTH_ALIGNMENT_SEMANTIC_IMPACTS = ['none', 'bounded', 'material'];
63
- const TRUTH_ALIGNMENT_OWNER_STAGES = ['spec', 'plan', 'tasks', 'verifies', 'do', 'test', 'goal-verify', 'ship'];
57
+ const TRUTH_ALIGNMENT_OWNER_STAGES = ['spec', 'plan', 'tasks', 'execute', 'ship'];
64
58
  export function deriveSpecCollaborationProfile(decision, generatedAt = new Date().toISOString()) {
65
59
  const required = decision.requiredStages.includes('spec');
66
60
  const intensity = specIntensity(decision, required);
@@ -92,9 +86,7 @@ export function buildSpecStageWorkOrder(profile, profileRef, generatedAt = new D
92
86
  scope: profile.scope,
93
87
  profileRef,
94
88
  authorityCeiling: 'proposal_input',
95
- requiredOutputKinds: profile.agentTeam.includes(SPEC_STAGE_SCOUT_AGENT)
96
- ? ['scout_context', 'spec_review', 'manager_closure_request']
97
- : ['spec_review', 'manager_closure_request'],
89
+ requiredOutputKinds: specRequiredOutputKinds(profile.intensity),
98
90
  forbiddenActions: ['stage_pass', 'risk_decision', 'gate_pass', 'ship_ready', 'truth_alignment_approved'],
99
91
  stageManager: SPEC_STAGE_MANAGER,
100
92
  agentTeam: profile.agentTeam,
@@ -109,7 +101,8 @@ export function buildSpecStageWorkOrder(profile, profileRef, generatedAt = new D
109
101
  export function planCollaborationScopeKey(scope) {
110
102
  return [scope.branch, scope.taskId ?? 'all', scope.runId ?? 'none', scope.changeRef ?? 'none', 'plan'].join(':');
111
103
  }
112
- export function buildPlanStageWorkOrder(scope, profileRef, inputRefs, generatedAt = new Date().toISOString()) {
104
+ export function buildPlanStageWorkOrder(scope, profileRef, inputRefs, generatedAt = new Date().toISOString(), intensity = 'scout-first') {
105
+ const collaborationPlan = planCollaborationPlan(intensity);
113
106
  return {
114
107
  contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
115
108
  workOrderId: stableId('plan-work-order', scope),
@@ -117,14 +110,16 @@ export function buildPlanStageWorkOrder(scope, profileRef, inputRefs, generatedA
117
110
  scope,
118
111
  profileRef,
119
112
  authorityCeiling: 'proposal_input',
120
- requiredOutputKinds: ['plan_context', 'plan_review', 'manager_closure_request'],
113
+ requiredOutputKinds: planRequiredOutputKinds(intensity),
121
114
  forbiddenActions: ['stage_pass', 'risk_decision', 'gate_pass', 'ship_ready', 'truth_alignment_approved'],
122
115
  inputRefs,
123
116
  stageManager: PLAN_STAGE_MANAGER,
124
- agentTeam: ['plan-scout', PLAN_STAGE_DRAFTER_AGENT, PLAN_STAGE_REVIEW_AGENT],
125
- requiredCapabilities: ['solution-design', 'verification-design'],
126
- optionalCapabilities: ['performance-planning', 'security-engineering', 'frontend-engineering'],
127
- materialPackIds: ['project-norms', 'baseline-solution-design', 'baseline-verification-design'],
117
+ agentTeam: planMemberAgents(intensity),
118
+ planScoutDomains: planScoutDomains(intensity),
119
+ requiredCapabilities: planRequiredCapabilities(intensity),
120
+ optionalCapabilities: planOptionalCapabilities(intensity),
121
+ materialPackIds: planMaterialPackIds(intensity),
122
+ collaborationPlan,
128
123
  generatedAt
129
124
  };
130
125
  }
@@ -143,98 +138,32 @@ export function buildTasksStageWorkOrder(scope, profileRef, inputRefs, generated
143
138
  forbiddenActions: ['stage_pass', 'risk_decision', 'gate_pass', 'ship_ready', 'truth_alignment_approved'],
144
139
  inputRefs,
145
140
  stageManager: TASKS_STAGE_MANAGER,
146
- agentTeam: [TASKS_STAGE_SLICER_AGENT, TASKS_STAGE_DRAFTER_AGENT, TASKS_STAGE_REVIEW_AGENT],
141
+ agentTeam: [TASKS_STAGE_SLICER_AGENT, TASKS_STAGE_REVIEW_AGENT],
147
142
  requiredCapabilities: ['task-decomposition', 'acceptance-mapping'],
148
143
  optionalCapabilities: ['dependency-analysis', 'parallelization-planning'],
149
144
  materialPackIds: ['project-norms', 'baseline-task-slicing', 'baseline-acceptance-mapping'],
150
145
  generatedAt
151
146
  };
152
147
  }
153
- export function verifiesCollaborationScopeKey(scope) {
154
- return [scope.branch, scope.taskId ?? 'all', scope.runId ?? 'none', scope.changeRef ?? 'none', 'verifies'].join(':');
148
+ export function executeCollaborationScopeKey(scope) {
149
+ return [scope.branch, scope.taskId ?? 'all', scope.runId ?? 'none', scope.changeRef ?? 'none', 'execute'].join(':');
155
150
  }
156
- export function buildVerifiesStageWorkOrder(scope, profileRef, inputRefs, generatedAt = new Date().toISOString()) {
151
+ export function buildExecuteStageWorkOrder(scope, profileRef, inputRefs, generatedAt = new Date().toISOString()) {
157
152
  return {
158
153
  contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
159
- workOrderId: stableId('verifies-work-order', scope),
160
- stage: 'verifies',
154
+ workOrderId: stableId('execute-work-order', scope),
155
+ stage: 'execute',
161
156
  scope,
162
157
  profileRef,
163
158
  authorityCeiling: 'proposal_input',
164
- requiredOutputKinds: ['verifies_context', 'verifies_review', 'manager_closure_request'],
159
+ requiredOutputKinds: ['implementation_evidence', 'code_review', 'validation_evidence', 'checkpoint_decision', 'evidence_judgment', 'manager_closure_request'],
165
160
  forbiddenActions: ['stage_pass', 'risk_decision', 'gate_pass', 'ship_ready', 'truth_alignment_approved'],
166
161
  inputRefs,
167
- stageManager: VERIFIES_STAGE_MANAGER,
168
- agentTeam: [VERIFIES_STAGE_VERIFICATION_AGENT, VERIFIES_STAGE_DRAFTER_AGENT, VERIFIES_STAGE_REVIEW_AGENT],
169
- requiredCapabilities: ['verification-design', 'acceptance-coverage'],
170
- optionalCapabilities: ['security-testing', 'performance-testing', 'frontend-validation'],
171
- materialPackIds: ['project-norms', 'baseline-verification-design', 'baseline-acceptance-coverage'],
172
- generatedAt
173
- };
174
- }
175
- export function doCollaborationScopeKey(scope) {
176
- return [scope.branch, scope.taskId ?? 'all', scope.runId ?? 'none', scope.changeRef ?? 'none', 'do'].join(':');
177
- }
178
- export function buildDoStageWorkOrder(scope, profileRef, inputRefs, generatedAt = new Date().toISOString()) {
179
- return {
180
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
181
- workOrderId: stableId('do-work-order', scope),
182
- stage: 'do',
183
- scope,
184
- profileRef,
185
- authorityCeiling: 'proposal_input',
186
- requiredOutputKinds: ['implementation_evidence', 'code_review', 'manager_closure_request'],
187
- forbiddenActions: ['stage_pass', 'risk_decision', 'gate_pass', 'ship_ready', 'truth_alignment_approved'],
188
- inputRefs,
189
- stageManager: DO_STAGE_MANAGER,
190
- agentTeam: [DO_STAGE_IMPLEMENTER_AGENT, DO_STAGE_CODE_REVIEW_AGENT, DO_STAGE_DEBUGGER_AGENT],
191
- requiredCapabilities: ['implementation', 'code-review'],
192
- optionalCapabilities: ['debugging', 'security-engineering', 'frontend-engineering'],
193
- materialPackIds: ['project-norms', 'baseline-implementation', 'baseline-code-review'],
194
- generatedAt
195
- };
196
- }
197
- export function testCollaborationScopeKey(scope) {
198
- return [scope.branch, scope.taskId ?? 'all', scope.runId ?? 'none', scope.changeRef ?? 'none', 'test'].join(':');
199
- }
200
- export function buildTestStageWorkOrder(scope, profileRef, inputRefs, generatedAt = new Date().toISOString()) {
201
- return {
202
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
203
- workOrderId: stableId('test-work-order', scope),
204
- stage: 'test',
205
- scope,
206
- profileRef,
207
- authorityCeiling: 'proposal_input',
208
- requiredOutputKinds: ['test_execution', 'validation_evidence', 'test_review', 'manager_closure_request'],
209
- forbiddenActions: ['stage_pass', 'risk_decision', 'gate_pass', 'ship_ready', 'truth_alignment_approved'],
210
- inputRefs,
211
- stageManager: TEST_STAGE_MANAGER,
212
- agentTeam: [TEST_STAGE_RUNNER_AGENT, TEST_STAGE_VALIDATOR_AGENT, TEST_STAGE_REVIEW_AGENT],
213
- requiredCapabilities: ['test-execution', 'validation-evidence'],
214
- optionalCapabilities: ['flaky-test-analysis', 'frontend-validation', 'security-testing'],
215
- materialPackIds: ['project-norms', 'baseline-test-execution', 'baseline-validation-evidence'],
216
- generatedAt
217
- };
218
- }
219
- export function goalVerifyCollaborationScopeKey(scope) {
220
- return [scope.branch, scope.taskId ?? 'all', scope.runId ?? 'none', scope.changeRef ?? 'none', 'goal-verify'].join(':');
221
- }
222
- export function buildGoalVerifyStageWorkOrder(scope, profileRef, inputRefs, generatedAt = new Date().toISOString()) {
223
- return {
224
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
225
- workOrderId: stableId('goal-verify-work-order', scope),
226
- stage: 'goal-verify',
227
- scope,
228
- profileRef,
229
- authorityCeiling: 'proposal_input',
230
- requiredOutputKinds: ['goal_verification', 'goal_review', 'manager_closure_request'],
231
- forbiddenActions: ['stage_pass', 'risk_decision', 'gate_pass', 'ship_ready', 'truth_alignment_approved'],
232
- inputRefs,
233
- stageManager: GOAL_VERIFY_STAGE_MANAGER,
234
- agentTeam: [GOAL_VERIFY_STAGE_VALIDATOR_AGENT, GOAL_VERIFY_STAGE_REVIEW_AGENT],
235
- requiredCapabilities: ['goal-verification', 'acceptance-coverage'],
236
- optionalCapabilities: ['gap-analysis', 'regression-risk-review'],
237
- materialPackIds: ['project-norms', 'baseline-goal-verification', 'baseline-acceptance-coverage'],
162
+ stageManager: 'execute-manager',
163
+ agentTeam: [EXECUTE_IMPLEMENTER_AGENT, EXECUTE_CODE_REVIEW_AGENT, EXECUTE_DEBUGGER_AGENT, EXECUTE_TEST_RUNNER_AGENT, EXECUTE_VALIDATOR_AGENT, EXECUTE_TEST_REVIEW_AGENT, EXECUTE_EVIDENCE_JUDGMENT_VALIDATOR_AGENT, EXECUTE_EVIDENCE_JUDGMENT_REVIEW_AGENT],
164
+ requiredCapabilities: ['implementation', 'code-review', 'validation', 'evidence-judgment'],
165
+ optionalCapabilities: ['debugging', 'checkpoint-review', 'frontend-engineering', 'security-engineering'],
166
+ materialPackIds: ['accepted-task-contract', 'execute-lane-contract', 'validation-contract', 'checkpoint-policy', 'evidence-judgment-policy'],
238
167
  generatedAt
239
168
  };
240
169
  }
@@ -242,11 +171,11 @@ export function truthAlignmentScopeKey(scope) {
242
171
  return [scope.branch, scope.taskId ?? 'all', scope.runId ?? 'none', scope.changeRef ?? 'none', 'truth-alignment'].join(':');
243
172
  }
244
173
  function buildTruthAlignmentProjection(scope, input) {
245
- const acceptedRealityRefs = uniqueRuntimeRefs([input.acceptedGoalVerificationRef, ...input.artifactRefs].filter((ref) => ref !== null));
174
+ const acceptedRealityRefs = uniqueRuntimeRefs([input.acceptedEvidenceJudgmentRef, ...input.artifactRefs].filter((ref) => ref !== null));
246
175
  return {
247
176
  contract: TRUTH_ALIGNMENT_CONTRACT,
248
177
  branch: scope.branch,
249
- sourceStage: 'goal-verify',
178
+ sourceStage: 'execute',
250
179
  declaredTruthRefs: uniqueRuntimeRefs(input.declaredTruthRefs),
251
180
  acceptedRealityRefs,
252
181
  status: input.status,
@@ -316,46 +245,13 @@ export async function recordTasksCollaborationAdjudicationProjection(projectRoot
316
245
  payload: result
317
246
  });
318
247
  }
319
- export async function recordVerifiesCollaborationAdjudicationProjection(projectRoot, result) {
320
- return recordRuntimeProjectionEnvelope(projectRoot, {
321
- projectionType: VERIFIES_COLLABORATION_ADJUDICATION_PROJECTION_TYPE,
322
- scopeKey: verifiesCollaborationScopeKey(result.scope),
323
- inputHash: stableHash(JSON.stringify(result)),
324
- producer: 'phase9.4-verifies-stage-collaboration-runtime',
325
- producerVersion: 'phase9.4-verifies-stage-collaboration-runtime-v1',
326
- generatedAt: result.createdAt,
327
- payload: result
328
- });
329
- }
330
- export async function recordDoCollaborationAdjudicationProjection(projectRoot, result) {
248
+ export async function recordExecuteCollaborationAdjudicationProjection(projectRoot, result) {
331
249
  return recordRuntimeProjectionEnvelope(projectRoot, {
332
- projectionType: DO_COLLABORATION_ADJUDICATION_PROJECTION_TYPE,
333
- scopeKey: doCollaborationScopeKey(result.scope),
250
+ projectionType: EXECUTE_COLLABORATION_ADJUDICATION_PROJECTION_TYPE,
251
+ scopeKey: executeCollaborationScopeKey(result.scope),
334
252
  inputHash: stableHash(JSON.stringify(result)),
335
- producer: 'phase9.5-do-stage-collaboration-runtime',
336
- producerVersion: 'phase9.5-do-stage-collaboration-runtime-v1',
337
- generatedAt: result.createdAt,
338
- payload: result
339
- });
340
- }
341
- export async function recordTestCollaborationAdjudicationProjection(projectRoot, result) {
342
- return recordRuntimeProjectionEnvelope(projectRoot, {
343
- projectionType: TEST_COLLABORATION_ADJUDICATION_PROJECTION_TYPE,
344
- scopeKey: testCollaborationScopeKey(result.scope),
345
- inputHash: stableHash(JSON.stringify(result)),
346
- producer: 'phase9.6-test-stage-collaboration-runtime',
347
- producerVersion: 'phase9.6-test-stage-collaboration-runtime-v1',
348
- generatedAt: result.createdAt,
349
- payload: result
350
- });
351
- }
352
- export async function recordGoalVerifyCollaborationAdjudicationProjection(projectRoot, result) {
353
- return recordRuntimeProjectionEnvelope(projectRoot, {
354
- projectionType: GOAL_VERIFY_COLLABORATION_ADJUDICATION_PROJECTION_TYPE,
355
- scopeKey: goalVerifyCollaborationScopeKey(result.scope),
356
- inputHash: stableHash(JSON.stringify(result)),
357
- producer: 'phase9.7-goal-verify-stage-collaboration-runtime',
358
- producerVersion: 'phase9.7-goal-verify-stage-collaboration-runtime-v1',
253
+ producer: 'phase10-execute-stage-collaboration-runtime',
254
+ producerVersion: 'phase10-execute-stage-collaboration-runtime-v1',
359
255
  generatedAt: result.createdAt,
360
256
  payload: result
361
257
  });
@@ -406,13 +302,15 @@ export async function reconcileSpecCollaborationClosure(projectRoot, input) {
406
302
  const profile = deriveSpecCollaborationProfile(decision, generatedAt);
407
303
  const profileRef = { kind: 'projection', ref: `${SPEC_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${specCollaborationScopeKey(profile.scope)}:profile` };
408
304
  const workOrder = profile.stageManager ? buildSpecStageWorkOrder(profile, profileRef, generatedAt) : null;
409
- const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'spec', workOrder, input.collaborationContractRefs, generatedAt);
305
+ const registeredCollaborationContracts = input.collaborationContractRefs && input.collaborationContractRefs.length > 0
306
+ ? await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'spec', workOrder, input.collaborationContractRefs, generatedAt)
307
+ : [];
410
308
  const validatedCollaborationContract = latestValidatedStageCollaborationContract(registeredCollaborationContracts);
411
309
  const collaborationContractRef = validatedCollaborationContract ? runtimeRefForStageCollaborationContract(validatedCollaborationContract) : null;
412
310
  const registeredArtifacts = await registerSpecStageArtifacts(projectRoot, context.rawBranch, profile, input.artifactRefs, run.runId, generatedAt);
413
311
  const artifactRefs = registeredArtifacts.map(runtimeRefForStageArtifact);
414
- const derivedClosure = deriveRegisteredStageClosureRequest(profile, workOrder, registeredArtifacts, context.partition, generatedAt);
415
- const closureRequest = input.closureRequest ?? derivedClosure;
312
+ const outputClosure = await buildOutputCenteredSpecClosureRequest(projectRoot, profile, workOrder, context.partition, input.outputCloseRequest, generatedAt);
313
+ const closureRequest = input.closureRequest ?? outputClosure;
416
314
  const coordination = input.coordination ?? deriveRegisteredSpecManagerCoordination(profile, workOrder, registeredArtifacts, generatedAt);
417
315
  const candidate = closureRequest?.candidate ?? null;
418
316
  const reviews = closureRequest?.reviewResults ?? [];
@@ -519,10 +417,11 @@ export async function reconcilePlanCollaborationClosure(projectRoot, input) {
519
417
  const workOrderInputRefs = acceptedSpecHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs;
520
418
  const profileRef = { kind: 'projection', ref: `${PLAN_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${planCollaborationScopeKey(decision.scope)}:profile` };
521
419
  const workOrder = planRequired && !blocked ? buildPlanStageWorkOrder(decision.scope, profileRef, workOrderInputRefs, generatedAt) : null;
522
- const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'plan', workOrder, input.collaborationContractRefs, generatedAt);
420
+ const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'plan', null, input.collaborationContractRefs, generatedAt);
523
421
  const validatedCollaborationContract = latestValidatedStageCollaborationContract(registeredCollaborationContracts);
524
422
  const collaborationContractRef = validatedCollaborationContract ? runtimeRefForStageCollaborationContract(validatedCollaborationContract) : null;
525
- const registeredArtifacts = await registerBranchStageArtifacts(projectRoot, context.rawBranch, 'plan', input.artifactRefs, Boolean(workOrder), run.runId, generatedAt);
423
+ const registeredArtifacts = await registerBranchStageArtifacts(projectRoot, context.rawBranch, 'plan', input.artifactRefs, false, run.runId, generatedAt);
424
+ const closureRequest = await buildOutputCenteredPlanClosureRequest(projectRoot, decision.scope, workOrder, context.partition, acceptedSpecHandoffEnvelope?.payload ?? null, input.outputCloseRequest, generatedAt);
526
425
  const artifactRefs = registeredArtifacts.map(runtimeRefForStageArtifact);
527
426
  const lifecycleRiskProjectionRef = {
528
427
  kind: 'projection',
@@ -535,7 +434,8 @@ export async function reconcilePlanCollaborationClosure(projectRoot, input) {
535
434
  blocked,
536
435
  registeredArtifacts,
537
436
  registeredCollaborationContracts,
538
- acceptedSpecHandoff: acceptedSpecHandoffEnvelope?.payload ?? null
437
+ acceptedSpecHandoff: acceptedSpecHandoffEnvelope?.payload ?? null,
438
+ closureRequest,
539
439
  });
540
440
  const health = planAcceptance.planAcceptanceStatus === 'accepted'
541
441
  ? 'ready_for_tasks'
@@ -556,11 +456,14 @@ export async function reconcilePlanCollaborationClosure(projectRoot, input) {
556
456
  kind: 'projection',
557
457
  ref: `${STAGE_RUN_PROJECTION_TYPE}:${stageRunScopeKey(stageRun.scope, stageRun.stage)}`
558
458
  };
459
+ const acceptedSpecRef = acceptedSpecRefFromHandoff(context.partition, acceptedSpecHandoffEnvelope?.payload ?? null);
460
+ const handoffOutputRefs = [planAcceptance.acceptedPlanRef].filter((ref) => ref !== null);
461
+ const handoffRequiredInputRefs = [acceptedSpecRef, planAcceptance.acceptedPlanRef].filter((ref) => ref !== null);
559
462
  const handoff = planAcceptance.planAcceptanceStatus === 'accepted'
560
463
  ? buildPlanWorkflowHandoff(decision.scope, decision, {
561
- outputRefs,
562
- requiredInputRefs: planAcceptance.acceptedPlanRef ? [planAcceptance.acceptedPlanRef] : [],
563
- evidenceRefs: artifactRefs,
464
+ outputRefs: handoffOutputRefs,
465
+ requiredInputRefs: handoffRequiredInputRefs,
466
+ evidenceRefs: [],
564
467
  riskDecisionRef: lifecycleRiskProjectionRef,
565
468
  generatedAt
566
469
  })
@@ -599,7 +502,7 @@ export async function reconcilePlanCollaborationClosure(projectRoot, input) {
599
502
  scope: decision.scope,
600
503
  status: health === 'ready_for_tasks' ? 'completed' : health === 'no-op' ? 'skipped' : health === 'blocked' ? 'blocked' : 'rejected',
601
504
  health,
602
- acceptedDecisionRefs: outputRefs,
505
+ acceptedDecisionRefs: [planAcceptance.acceptedPlanRef, adjudicationProjectionRef].filter((ref) => ref !== null),
603
506
  advisoryRefs: [],
604
507
  capabilityRefs: artifactRefs.filter((ref) => ref.ref.includes('context') || ref.ref.includes('capability')),
605
508
  blockingReasons: health === 'ready_for_tasks' || health === 'no-op' ? [] : planAcceptance.reasons,
@@ -648,10 +551,11 @@ export async function reconcileTasksCollaborationClosure(projectRoot, input) {
648
551
  const workOrderInputRefs = acceptedPlanHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs;
649
552
  const profileRef = { kind: 'projection', ref: `${TASKS_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${tasksCollaborationScopeKey(decision.scope)}:profile` };
650
553
  const workOrder = tasksRequired && !blocked ? buildTasksStageWorkOrder(decision.scope, profileRef, workOrderInputRefs, generatedAt) : null;
651
- const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'tasks', workOrder, input.collaborationContractRefs, generatedAt);
554
+ const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'tasks', null, input.collaborationContractRefs, generatedAt);
652
555
  const validatedCollaborationContract = latestValidatedStageCollaborationContract(registeredCollaborationContracts);
653
556
  const collaborationContractRef = validatedCollaborationContract ? runtimeRefForStageCollaborationContract(validatedCollaborationContract) : null;
654
- const registeredArtifacts = await registerBranchStageArtifacts(projectRoot, context.rawBranch, 'tasks', input.artifactRefs, Boolean(workOrder), run.runId, generatedAt);
557
+ const registeredArtifacts = await registerBranchStageArtifacts(projectRoot, context.rawBranch, 'tasks', input.artifactRefs, false, run.runId, generatedAt);
558
+ const closureRequest = await buildOutputCenteredTasksClosureRequest(projectRoot, decision.scope, workOrder, context.partition, acceptedPlanHandoffEnvelope?.payload ?? null, input.outputCloseRequest, generatedAt);
655
559
  const artifactRefs = registeredArtifacts.map(runtimeRefForStageArtifact);
656
560
  const lifecycleRiskProjectionRef = {
657
561
  kind: 'projection',
@@ -664,10 +568,11 @@ export async function reconcileTasksCollaborationClosure(projectRoot, input) {
664
568
  blocked,
665
569
  registeredArtifacts,
666
570
  registeredCollaborationContracts,
667
- acceptedPlanHandoff: acceptedPlanHandoffEnvelope?.payload ?? null
571
+ acceptedPlanHandoff: acceptedPlanHandoffEnvelope?.payload ?? null,
572
+ closureRequest
668
573
  });
669
574
  const health = tasksAcceptance.tasksAcceptanceStatus === 'accepted'
670
- ? 'ready_for_verifies'
575
+ ? 'ready_for_execute'
671
576
  : !tasksRequired
672
577
  ? 'no-op'
673
578
  : blocked
@@ -726,17 +631,17 @@ export async function reconcileTasksCollaborationClosure(projectRoot, input) {
726
631
  decisionId: stableId('tasks-stage-decision', decision.scope, run.runId, generatedAt),
727
632
  stage: 'tasks',
728
633
  scope: decision.scope,
729
- status: health === 'ready_for_verifies' ? 'completed' : health === 'no-op' ? 'skipped' : health === 'blocked' ? 'blocked' : 'rejected',
634
+ status: health === 'ready_for_execute' ? 'completed' : health === 'no-op' ? 'skipped' : health === 'blocked' ? 'blocked' : 'rejected',
730
635
  health,
731
636
  acceptedDecisionRefs: outputRefs,
732
637
  advisoryRefs: [],
733
638
  capabilityRefs: artifactRefs.filter((ref) => ref.ref.includes('context') || ref.ref.includes('capability')),
734
- blockingReasons: health === 'ready_for_verifies' || health === 'no-op' ? [] : tasksAcceptance.reasons,
639
+ blockingReasons: health === 'ready_for_execute' || health === 'no-op' ? [] : tasksAcceptance.reasons,
735
640
  createdAt: generatedAt
736
641
  },
737
642
  handoffPacket: handoff,
738
643
  rejection,
739
- nextActions: buildStageRuntimeNextActions('tasks', decision.scope, generatedAt, health === 'ready_for_verifies' ? ['stage_ready', 'handoff_ready'] : rejection ? [rejectionReasonToNextActionReason(rejection.reasonCode)] : ['report_only']),
644
+ nextActions: buildStageRuntimeNextActions('tasks', decision.scope, generatedAt, health === 'ready_for_execute' ? ['stage_ready', 'handoff_ready'] : rejection ? [rejectionReasonToNextActionReason(rejection.reasonCode)] : ['report_only']),
740
645
  closureRefs,
741
646
  createdAt: generatedAt
742
647
  };
@@ -758,7 +663,7 @@ export async function reconcileTasksCollaborationClosure(projectRoot, input) {
758
663
  acceptedTasksRef: tasksAcceptance.acceptedTasksRef
759
664
  };
760
665
  }
761
- export async function reconcileVerifiesCollaborationClosure(projectRoot, input) {
666
+ export async function reconcileExecuteCollaborationClosure(projectRoot, input) {
762
667
  const generatedAt = input.generatedAt ?? new Date().toISOString();
763
668
  const context = await resolveSddContext(projectRoot, { branch: input.decision.scope.branch, branchSource: 'cli_option' });
764
669
  const decision = {
@@ -771,504 +676,122 @@ export async function reconcileVerifiesCollaborationClosure(projectRoot, input)
771
676
  lifecycleDecision: runLifecycleDecisionRecord(decision)
772
677
  });
773
678
  const runRef = { kind: 'run', ref: run.runId };
774
- const verifiesRequired = decision.requiredStages.includes('verifies');
775
- const blocked = decision.profile === 'blocked' || decision.approvalPolicy === 'blocked' || decision.blockedStages.includes('verifies');
776
- const acceptedTasksHandoffEnvelope = await readWorkflowHandoffProjection(projectRoot, decision.scope, 'tasks', 'verifies');
679
+ const executeRequired = decision.requiredStages.includes('execute');
680
+ const blocked = decision.profile === 'blocked' || decision.approvalPolicy === 'blocked' || decision.blockedStages.includes('execute');
681
+ const acceptedTasksHandoffEnvelope = await readWorkflowHandoffProjection(projectRoot, decision.scope, 'tasks', 'execute');
777
682
  const workOrderInputRefs = acceptedTasksHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs;
778
- const profileRef = { kind: 'projection', ref: `${VERIFIES_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${verifiesCollaborationScopeKey(decision.scope)}:profile` };
779
- const workOrder = verifiesRequired && !blocked ? buildVerifiesStageWorkOrder(decision.scope, profileRef, workOrderInputRefs, generatedAt) : null;
780
- const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'verifies', workOrder, input.collaborationContractRefs, generatedAt);
683
+ const profileRef = { kind: 'projection', ref: `${EXECUTE_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${executeCollaborationScopeKey(decision.scope)}:profile` };
684
+ const workOrder = executeRequired && !blocked ? buildExecuteStageWorkOrder(decision.scope, profileRef, workOrderInputRefs, generatedAt) : null;
685
+ const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'execute', workOrder, input.collaborationContractRefs, generatedAt);
781
686
  const validatedCollaborationContract = latestValidatedStageCollaborationContract(registeredCollaborationContracts);
782
687
  const collaborationContractRef = validatedCollaborationContract ? runtimeRefForStageCollaborationContract(validatedCollaborationContract) : null;
783
- const registeredArtifacts = await registerBranchStageArtifacts(projectRoot, context.rawBranch, 'verifies', input.artifactRefs, Boolean(workOrder), run.runId, generatedAt);
688
+ const registeredArtifacts = await registerBranchStageArtifacts(projectRoot, context.rawBranch, 'execute', input.artifactRefs, Boolean(workOrder), run.runId, generatedAt);
784
689
  const artifactRefs = registeredArtifacts.map(runtimeRefForStageArtifact);
785
690
  const lifecycleRiskProjectionRef = {
786
691
  kind: 'projection',
787
692
  ref: `${LIFECYCLE_RISK_DECISION_PROJECTION_TYPE}:${lifecycleRiskDecisionScopeKey(decision.scope)}`
788
693
  };
789
- const adjudicationProjectionRef = verifiesAdjudicationProjectionRef(decision.scope);
790
- const verifyAcceptance = await validateAcceptedVerifyArtifact(projectRoot, {
694
+ const adjudicationProjectionRef = executeAdjudicationProjectionRef(decision.scope);
695
+ const executeAcceptance = await validateAcceptedExecuteArtifact(projectRoot, {
791
696
  partition: context.partition,
792
- required: verifiesRequired,
697
+ required: executeRequired,
793
698
  blocked,
794
699
  registeredArtifacts,
795
700
  registeredCollaborationContracts,
796
701
  acceptedTasksHandoff: acceptedTasksHandoffEnvelope?.payload ?? null
797
702
  });
798
- const health = verifyAcceptance.verifyAcceptanceStatus === 'accepted'
799
- ? 'ready_for_do'
800
- : !verifiesRequired
801
- ? 'no-op'
802
- : blocked
803
- ? 'blocked'
804
- : 'rejected';
805
- const outputRefs = [verifyAcceptance.acceptedVerifyRef, adjudicationProjectionRef, collaborationContractRef, ...artifactRefs].filter((ref) => ref !== null);
806
- const stageRun = buildVerifiesClosureStageRun(decision.scope, run.runId, workOrder, health, {
807
- outputRefs,
808
- decisionRefs: [lifecycleRiskProjectionRef, adjudicationProjectionRef],
809
- inputRefs: acceptedTasksHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs,
810
- generatedAt,
811
- rejectionReason: verifyAcceptance.rejectionIssue?.explanation ?? null
812
- });
813
- const stageRunProjectionRef = {
814
- kind: 'projection',
815
- ref: `${STAGE_RUN_PROJECTION_TYPE}:${stageRunScopeKey(stageRun.scope, stageRun.stage)}`
816
- };
817
- const handoff = verifyAcceptance.verifyAcceptanceStatus === 'accepted'
818
- ? buildVerifiesWorkflowHandoff(decision.scope, decision, {
819
- outputRefs,
820
- requiredInputRefs: verifyAcceptance.acceptedVerifyRef ? [verifyAcceptance.acceptedVerifyRef] : [],
821
- evidenceRefs: artifactRefs,
822
- riskDecisionRef: lifecycleRiskProjectionRef,
823
- generatedAt
824
- })
825
- : null;
826
- const workflowHandoffProjectionRef = handoff
827
- ? { kind: 'projection', ref: `${WORKFLOW_HANDOFF_PROJECTION_TYPE}:${workflowHandoffScopeKey(handoff.scope, handoff.fromStage, handoff.toStage)}` }
828
- : undefined;
829
- const rejection = verifyAcceptance.rejectionIssue
830
- ? buildStageRejection('verifies', decision.scope, null, verifyAcceptance.rejectionIssue.reasonCode, verifyAcceptance.rejectionIssue.explanation, verifyAcceptance.rejectionIssue.requiredNextAction, verifyAcceptance.rejectionIssue.fallbackRoute, generatedAt, true)
831
- : null;
832
- const closureRefs = {
833
- runRef,
834
- acceptedVerifyRef: verifyAcceptance.acceptedVerifyRef,
835
- verifyAcceptanceStatus: verifyAcceptance.verifyAcceptanceStatus,
836
- verifyHash: verifyAcceptance.verifyHash,
837
- verifyContractHash: verifyAcceptance.verifyContractHash,
838
- acceptedTasksHandoffRef: acceptedTasksHandoffEnvelope ? { kind: 'projection', ref: `${WORKFLOW_HANDOFF_PROJECTION_TYPE}:${workflowHandoffScopeKey(decision.scope, 'tasks', 'verifies')}` } : null,
839
- artifactRefs,
840
- collaborationContractRef,
841
- lifecycleRiskProjectionRef,
842
- adjudicationProjectionRef,
843
- stageRunProjectionRef,
844
- workflowHandoffProjectionRef,
845
- reasons: verifyAcceptance.reasons
846
- };
847
- const adjudication = {
848
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
849
- adjudicationId: stableId('verifies-adjudication', decision.scope, health, generatedAt),
850
- stage: 'verifies',
851
- scope: decision.scope,
852
- health,
853
- stageDecision: {
854
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
855
- decisionId: stableId('verifies-stage-decision', decision.scope, run.runId, generatedAt),
856
- stage: 'verifies',
857
- scope: decision.scope,
858
- status: health === 'ready_for_do' ? 'completed' : health === 'no-op' ? 'skipped' : health === 'blocked' ? 'blocked' : 'rejected',
859
- health,
860
- acceptedDecisionRefs: outputRefs,
861
- advisoryRefs: [],
862
- capabilityRefs: artifactRefs.filter((ref) => ref.ref.includes('context') || ref.ref.includes('capability')),
863
- blockingReasons: health === 'ready_for_do' || health === 'no-op' ? [] : verifyAcceptance.reasons,
864
- createdAt: generatedAt
865
- },
866
- handoffPacket: handoff,
867
- rejection,
868
- nextActions: buildStageRuntimeNextActions('verifies', decision.scope, generatedAt, health === 'ready_for_do' ? ['stage_ready', 'handoff_ready'] : rejection ? [rejectionReasonToNextActionReason(rejection.reasonCode)] : ['report_only']),
869
- closureRefs,
870
- createdAt: generatedAt
871
- };
872
- await recordLifecycleRiskDecisionProjection(projectRoot, decision);
873
- await recordStageRunProjection(projectRoot, stageRun);
874
- if (handoff) {
875
- await recordWorkflowHandoffProjection(projectRoot, handoff);
876
- }
877
- const projection = await recordVerifiesCollaborationAdjudicationProjection(projectRoot, adjudication);
878
- return {
879
- runId: run.runId,
880
- branch: context.rawBranch,
881
- workOrder,
882
- adjudication,
883
- projectionRef: { kind: 'projection', ref: `${projection.envelope.projectionType}:${projection.envelope.scopeKey}` },
884
- artifactRefs,
885
- registeredArtifacts,
886
- registeredCollaborationContracts,
887
- acceptedVerifyRef: verifyAcceptance.acceptedVerifyRef
888
- };
889
- }
890
- export async function reconcileDoCollaborationClosure(projectRoot, input) {
891
- const generatedAt = input.generatedAt ?? new Date().toISOString();
892
- const context = await resolveSddContext(projectRoot, { branch: input.decision.scope.branch, branchSource: 'cli_option' });
893
- const decision = {
894
- ...input.decision,
895
- scope: { ...input.decision.scope, branch: context.rawBranch }
896
- };
897
- const run = await createRun(projectRoot, {
898
- runId: input.runId,
899
- branch: context.rawBranch,
900
- lifecycleDecision: runLifecycleDecisionRecord(decision)
901
- });
902
- const runRef = { kind: 'run', ref: run.runId };
903
- const doRequired = decision.requiredStages.includes('do');
904
- const blocked = decision.profile === 'blocked' || decision.approvalPolicy === 'blocked' || decision.blockedStages.includes('do');
905
- const acceptedVerifyHandoffEnvelope = await readWorkflowHandoffProjection(projectRoot, decision.scope, 'verifies', 'do');
906
- const workOrderInputRefs = acceptedVerifyHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs;
907
- const profileRef = { kind: 'projection', ref: `${DO_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${doCollaborationScopeKey(decision.scope)}:profile` };
908
- const workOrder = doRequired && !blocked ? buildDoStageWorkOrder(decision.scope, profileRef, workOrderInputRefs, generatedAt) : null;
909
- const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'do', workOrder, input.collaborationContractRefs, generatedAt);
910
- const validatedCollaborationContract = latestValidatedStageCollaborationContract(registeredCollaborationContracts);
911
- const collaborationContractRef = validatedCollaborationContract ? runtimeRefForStageCollaborationContract(validatedCollaborationContract) : null;
912
- const registeredArtifacts = await registerBranchStageArtifacts(projectRoot, context.rawBranch, 'do', input.artifactRefs, Boolean(workOrder), run.runId, generatedAt);
913
- const artifactRefs = registeredArtifacts.map(runtimeRefForStageArtifact);
914
- const lifecycleRiskProjectionRef = {
915
- kind: 'projection',
916
- ref: `${LIFECYCLE_RISK_DECISION_PROJECTION_TYPE}:${lifecycleRiskDecisionScopeKey(decision.scope)}`
917
- };
918
- const adjudicationProjectionRef = doAdjudicationProjectionRef(decision.scope);
919
- const implementationAcceptance = await validateAcceptedDoArtifact(projectRoot, {
920
- partition: context.partition,
921
- required: doRequired,
922
- blocked,
923
- registeredArtifacts,
924
- registeredCollaborationContracts,
925
- acceptedVerifyHandoff: acceptedVerifyHandoffEnvelope?.payload ?? null,
926
- allowedChangedFileRefs: input.allowedChangedFileRefs
927
- });
928
- const health = implementationAcceptance.implementationAcceptanceStatus === 'accepted'
929
- ? 'ready_for_test'
930
- : !doRequired
703
+ const health = executeAcceptance.executeAcceptanceStatus === 'accepted'
704
+ ? 'ready_for_ship'
705
+ : !executeRequired
931
706
  ? 'no-op'
932
707
  : blocked
933
708
  ? 'blocked'
934
709
  : 'rejected';
935
- const outputRefs = [implementationAcceptance.acceptedImplementationRef, adjudicationProjectionRef, collaborationContractRef, ...implementationAcceptance.changedFileRefs, ...artifactRefs].filter((ref) => ref !== null);
936
- const stageRun = buildDoClosureStageRun(decision.scope, run.runId, workOrder, health, {
937
- outputRefs,
938
- decisionRefs: [lifecycleRiskProjectionRef, adjudicationProjectionRef],
939
- inputRefs: acceptedVerifyHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs,
940
- generatedAt,
941
- rejectionReason: implementationAcceptance.rejectionIssue?.explanation ?? null
942
- });
943
- const stageRunProjectionRef = {
944
- kind: 'projection',
945
- ref: `${STAGE_RUN_PROJECTION_TYPE}:${stageRunScopeKey(stageRun.scope, stageRun.stage)}`
946
- };
947
- const handoff = implementationAcceptance.implementationAcceptanceStatus === 'accepted'
948
- ? buildDoWorkflowHandoff(decision.scope, decision, {
949
- outputRefs,
950
- requiredInputRefs: [implementationAcceptance.acceptedImplementationRef, ...implementationAcceptance.changedFileRefs].filter((ref) => ref !== null),
951
- evidenceRefs: artifactRefs,
952
- riskDecisionRef: lifecycleRiskProjectionRef,
953
- generatedAt
954
- })
710
+ const acceptedEvidenceJudgmentArtifact = latestStageArtifact(registeredArtifacts, 'evidence_judgment');
711
+ const acceptedEvidenceJudgmentRef = executeAcceptance.executeAcceptanceStatus === 'accepted' && acceptedEvidenceJudgmentArtifact
712
+ ? { kind: 'artifact', ref: acceptedEvidenceJudgmentArtifact.ref, hash: acceptedEvidenceJudgmentArtifact.hash }
955
713
  : null;
956
- const workflowHandoffProjectionRef = handoff
957
- ? { kind: 'projection', ref: `${WORKFLOW_HANDOFF_PROJECTION_TYPE}:${workflowHandoffScopeKey(handoff.scope, handoff.fromStage, handoff.toStage)}` }
958
- : undefined;
959
- const rejection = implementationAcceptance.rejectionIssue
960
- ? buildStageRejection('do', decision.scope, null, implementationAcceptance.rejectionIssue.reasonCode, implementationAcceptance.rejectionIssue.explanation, implementationAcceptance.rejectionIssue.requiredNextAction, implementationAcceptance.rejectionIssue.fallbackRoute, generatedAt, true)
961
- : null;
962
- const closureRefs = {
963
- runRef,
964
- acceptedImplementationRef: implementationAcceptance.acceptedImplementationRef,
965
- implementationAcceptanceStatus: implementationAcceptance.implementationAcceptanceStatus,
966
- implementationHash: implementationAcceptance.implementationHash,
967
- changedFileRefs: implementationAcceptance.changedFileRefs,
968
- acceptedVerifyHandoffRef: acceptedVerifyHandoffEnvelope ? { kind: 'projection', ref: `${WORKFLOW_HANDOFF_PROJECTION_TYPE}:${workflowHandoffScopeKey(decision.scope, 'verifies', 'do')}` } : null,
969
- artifactRefs,
970
- collaborationContractRef,
971
- lifecycleRiskProjectionRef,
972
- adjudicationProjectionRef,
973
- stageRunProjectionRef,
974
- workflowHandoffProjectionRef,
975
- reasons: implementationAcceptance.reasons
976
- };
977
- const adjudication = {
978
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
979
- adjudicationId: stableId('do-adjudication', decision.scope, health, generatedAt),
980
- stage: 'do',
981
- scope: decision.scope,
982
- health,
983
- stageDecision: {
984
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
985
- decisionId: stableId('do-stage-decision', decision.scope, run.runId, generatedAt),
986
- stage: 'do',
987
- scope: decision.scope,
988
- status: health === 'ready_for_test' ? 'completed' : health === 'no-op' ? 'skipped' : health === 'blocked' ? 'blocked' : 'rejected',
989
- health,
990
- acceptedDecisionRefs: outputRefs,
991
- advisoryRefs: [],
992
- capabilityRefs: artifactRefs.filter((ref) => ref.ref.includes('debug') || ref.ref.includes('capability')),
993
- blockingReasons: health === 'ready_for_test' || health === 'no-op' ? [] : implementationAcceptance.reasons,
994
- createdAt: generatedAt
995
- },
996
- handoffPacket: handoff,
997
- rejection,
998
- nextActions: buildStageRuntimeNextActions('do', decision.scope, generatedAt, health === 'ready_for_test' ? ['stage_ready', 'handoff_ready'] : rejection ? [rejectionReasonToNextActionReason(rejection.reasonCode)] : ['report_only']),
999
- closureRefs,
1000
- createdAt: generatedAt
1001
- };
1002
- await recordLifecycleRiskDecisionProjection(projectRoot, decision);
1003
- await recordStageRunProjection(projectRoot, stageRun);
1004
- if (handoff) {
1005
- await recordWorkflowHandoffProjection(projectRoot, handoff);
1006
- }
1007
- const projection = await recordDoCollaborationAdjudicationProjection(projectRoot, adjudication);
1008
- return {
1009
- runId: run.runId,
1010
- branch: context.rawBranch,
1011
- workOrder,
1012
- adjudication,
1013
- projectionRef: { kind: 'projection', ref: `${projection.envelope.projectionType}:${projection.envelope.scopeKey}` },
1014
- artifactRefs,
1015
- registeredArtifacts,
1016
- registeredCollaborationContracts,
1017
- acceptedImplementationRef: implementationAcceptance.acceptedImplementationRef,
1018
- changedFileRefs: implementationAcceptance.changedFileRefs
1019
- };
1020
- }
1021
- export async function reconcileTestCollaborationClosure(projectRoot, input) {
1022
- const generatedAt = input.generatedAt ?? new Date().toISOString();
1023
- const context = await resolveSddContext(projectRoot, { branch: input.decision.scope.branch, branchSource: 'cli_option' });
1024
- const decision = {
1025
- ...input.decision,
1026
- scope: { ...input.decision.scope, branch: context.rawBranch }
1027
- };
1028
- const run = await createRun(projectRoot, {
1029
- runId: input.runId,
1030
- branch: context.rawBranch,
1031
- lifecycleDecision: runLifecycleDecisionRecord(decision)
1032
- });
1033
- const runRef = { kind: 'run', ref: run.runId };
1034
- const testRequired = decision.requiredStages.includes('test');
1035
- const blocked = decision.profile === 'blocked' || decision.approvalPolicy === 'blocked' || decision.blockedStages.includes('test');
1036
- const acceptedDoHandoffEnvelope = await readWorkflowHandoffProjection(projectRoot, decision.scope, 'do', 'test');
1037
- const workOrderInputRefs = acceptedDoHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs;
1038
- const profileRef = { kind: 'projection', ref: `${TEST_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${testCollaborationScopeKey(decision.scope)}:profile` };
1039
- const workOrder = testRequired && !blocked ? buildTestStageWorkOrder(decision.scope, profileRef, workOrderInputRefs, generatedAt) : null;
1040
- const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'test', workOrder, input.collaborationContractRefs, generatedAt);
1041
- const validatedCollaborationContract = latestValidatedStageCollaborationContract(registeredCollaborationContracts);
1042
- const collaborationContractRef = validatedCollaborationContract ? runtimeRefForStageCollaborationContract(validatedCollaborationContract) : null;
1043
- const registeredArtifacts = await registerBranchStageArtifacts(projectRoot, context.rawBranch, 'test', input.artifactRefs, Boolean(workOrder), run.runId, generatedAt);
1044
- const artifactRefs = registeredArtifacts.map(runtimeRefForStageArtifact);
1045
- const lifecycleRiskProjectionRef = {
1046
- kind: 'projection',
1047
- ref: `${LIFECYCLE_RISK_DECISION_PROJECTION_TYPE}:${lifecycleRiskDecisionScopeKey(decision.scope)}`
1048
- };
1049
- const adjudicationProjectionRef = testAdjudicationProjectionRef(decision.scope);
1050
- const testAcceptance = await validateAcceptedTestArtifact(projectRoot, {
1051
- partition: context.partition,
1052
- required: testRequired,
1053
- blocked,
1054
- registeredArtifacts,
1055
- registeredCollaborationContracts,
1056
- acceptedDoHandoff: acceptedDoHandoffEnvelope?.payload ?? null
1057
- });
1058
- const health = testAcceptance.testAcceptanceStatus === 'accepted'
1059
- ? 'ready_for_goal_verify'
1060
- : !testRequired
1061
- ? 'no-op'
1062
- : blocked
1063
- ? 'blocked'
1064
- : 'rejected';
1065
- const outputRefs = [testAcceptance.acceptedTestEvidenceRef, adjudicationProjectionRef, collaborationContractRef, ...artifactRefs].filter((ref) => ref !== null);
1066
- const stageRun = buildTestClosureStageRun(decision.scope, run.runId, workOrder, health, {
1067
- outputRefs,
1068
- decisionRefs: [lifecycleRiskProjectionRef, adjudicationProjectionRef],
1069
- inputRefs: acceptedDoHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs,
1070
- generatedAt,
1071
- rejectionReason: testAcceptance.rejectionIssue?.explanation ?? null
1072
- });
1073
- const stageRunProjectionRef = {
1074
- kind: 'projection',
1075
- ref: `${STAGE_RUN_PROJECTION_TYPE}:${stageRunScopeKey(stageRun.scope, stageRun.stage)}`
1076
- };
1077
- const handoff = testAcceptance.testAcceptanceStatus === 'accepted'
1078
- ? buildTestWorkflowHandoff(decision.scope, decision, {
1079
- outputRefs,
1080
- requiredInputRefs: testAcceptance.acceptedTestEvidenceRef ? [testAcceptance.acceptedTestEvidenceRef] : [],
1081
- evidenceRefs: artifactRefs,
1082
- riskDecisionRef: lifecycleRiskProjectionRef,
1083
- generatedAt
1084
- })
1085
- : null;
1086
- const workflowHandoffProjectionRef = handoff
1087
- ? { kind: 'projection', ref: `${WORKFLOW_HANDOFF_PROJECTION_TYPE}:${workflowHandoffScopeKey(handoff.scope, handoff.fromStage, handoff.toStage)}` }
1088
- : undefined;
1089
- const rejection = testAcceptance.rejectionIssue
1090
- ? buildStageRejection('test', decision.scope, null, testAcceptance.rejectionIssue.reasonCode, testAcceptance.rejectionIssue.explanation, testAcceptance.rejectionIssue.requiredNextAction, testAcceptance.rejectionIssue.fallbackRoute, generatedAt, true)
1091
- : null;
1092
- const closureRefs = {
1093
- runRef,
1094
- acceptedTestEvidenceRef: testAcceptance.acceptedTestEvidenceRef,
1095
- testAcceptanceStatus: testAcceptance.testAcceptanceStatus,
1096
- testEvidenceHash: testAcceptance.testEvidenceHash,
1097
- acceptedDoHandoffRef: acceptedDoHandoffEnvelope ? { kind: 'projection', ref: `${WORKFLOW_HANDOFF_PROJECTION_TYPE}:${workflowHandoffScopeKey(decision.scope, 'do', 'test')}` } : null,
1098
- artifactRefs,
1099
- collaborationContractRef,
1100
- lifecycleRiskProjectionRef,
1101
- adjudicationProjectionRef,
1102
- stageRunProjectionRef,
1103
- workflowHandoffProjectionRef,
1104
- reasons: testAcceptance.reasons
1105
- };
1106
- const adjudication = {
1107
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
1108
- adjudicationId: stableId('test-adjudication', decision.scope, health, generatedAt),
1109
- stage: 'test',
1110
- scope: decision.scope,
1111
- health,
1112
- stageDecision: {
1113
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
1114
- decisionId: stableId('test-stage-decision', decision.scope, run.runId, generatedAt),
1115
- stage: 'test',
1116
- scope: decision.scope,
1117
- status: health === 'ready_for_goal_verify' ? 'completed' : health === 'no-op' ? 'skipped' : health === 'blocked' ? 'blocked' : 'rejected',
1118
- health,
1119
- acceptedDecisionRefs: outputRefs,
1120
- advisoryRefs: [],
1121
- capabilityRefs: artifactRefs.filter((ref) => ref.ref.includes('validation') || ref.ref.includes('capability')),
1122
- blockingReasons: health === 'ready_for_goal_verify' || health === 'no-op' ? [] : testAcceptance.reasons,
1123
- createdAt: generatedAt
1124
- },
1125
- handoffPacket: handoff,
1126
- rejection,
1127
- nextActions: buildStageRuntimeNextActions('test', decision.scope, generatedAt, health === 'ready_for_goal_verify' ? ['stage_ready', 'handoff_ready'] : rejection ? [rejectionReasonToNextActionReason(rejection.reasonCode)] : ['report_only']),
1128
- closureRefs,
1129
- createdAt: generatedAt
1130
- };
1131
- await recordLifecycleRiskDecisionProjection(projectRoot, decision);
1132
- await recordStageRunProjection(projectRoot, stageRun);
1133
- if (handoff) {
1134
- await recordWorkflowHandoffProjection(projectRoot, handoff);
1135
- }
1136
- const projection = await recordTestCollaborationAdjudicationProjection(projectRoot, adjudication);
1137
- return {
1138
- runId: run.runId,
1139
- branch: context.rawBranch,
1140
- workOrder,
1141
- adjudication,
1142
- projectionRef: { kind: 'projection', ref: `${projection.envelope.projectionType}:${projection.envelope.scopeKey}` },
1143
- artifactRefs,
1144
- registeredArtifacts,
1145
- registeredCollaborationContracts,
1146
- acceptedTestEvidenceRef: testAcceptance.acceptedTestEvidenceRef
1147
- };
1148
- }
1149
- export async function reconcileGoalVerifyCollaborationClosure(projectRoot, input) {
1150
- const generatedAt = input.generatedAt ?? new Date().toISOString();
1151
- const context = await resolveSddContext(projectRoot, { branch: input.decision.scope.branch, branchSource: 'cli_option' });
1152
- const decision = {
1153
- ...input.decision,
1154
- scope: { ...input.decision.scope, branch: context.rawBranch }
1155
- };
1156
- const run = await createRun(projectRoot, {
1157
- runId: input.runId,
1158
- branch: context.rawBranch,
1159
- lifecycleDecision: runLifecycleDecisionRecord(decision)
1160
- });
1161
- const runRef = { kind: 'run', ref: run.runId };
1162
- const goalVerifyRequired = decision.requiredStages.includes('goal-verify');
1163
- const blocked = decision.profile === 'blocked' || decision.approvalPolicy === 'blocked' || decision.blockedStages.includes('goal-verify');
1164
- const acceptedTestHandoffEnvelope = await readWorkflowHandoffProjection(projectRoot, decision.scope, 'test', 'goal-verify');
1165
- const workOrderInputRefs = acceptedTestHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs;
1166
- const profileRef = { kind: 'projection', ref: `${GOAL_VERIFY_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${goalVerifyCollaborationScopeKey(decision.scope)}:profile` };
1167
- const workOrder = goalVerifyRequired && !blocked ? buildGoalVerifyStageWorkOrder(decision.scope, profileRef, workOrderInputRefs, generatedAt) : null;
1168
- const registeredCollaborationContracts = await registerStageCollaborationContracts(projectRoot, context.rawBranch, 'goal-verify', workOrder, input.collaborationContractRefs, generatedAt);
1169
- const validatedCollaborationContract = latestValidatedStageCollaborationContract(registeredCollaborationContracts);
1170
- const collaborationContractRef = validatedCollaborationContract ? runtimeRefForStageCollaborationContract(validatedCollaborationContract) : null;
1171
- const registeredArtifacts = await registerBranchStageArtifacts(projectRoot, context.rawBranch, 'goal-verify', input.artifactRefs, Boolean(workOrder), run.runId, generatedAt);
1172
- const artifactRefs = registeredArtifacts.map(runtimeRefForStageArtifact);
1173
- const lifecycleRiskProjectionRef = {
1174
- kind: 'projection',
1175
- ref: `${LIFECYCLE_RISK_DECISION_PROJECTION_TYPE}:${lifecycleRiskDecisionScopeKey(decision.scope)}`
1176
- };
1177
- const adjudicationProjectionRef = goalVerifyAdjudicationProjectionRef(decision.scope);
1178
- const goalVerifyAcceptance = await validateAcceptedGoalVerifyArtifact(projectRoot, {
1179
- partition: context.partition,
1180
- required: goalVerifyRequired,
1181
- blocked,
1182
- registeredArtifacts,
1183
- registeredCollaborationContracts,
1184
- acceptedTestHandoff: acceptedTestHandoffEnvelope?.payload ?? null
1185
- });
1186
- const truthAlignmentObservation = goalVerifyAcceptance.truthAlignment;
1187
- const truthAlignmentStatus = goalVerifyAcceptance.goalVerifyAcceptanceStatus === 'accepted'
1188
- ? truthAlignmentObservation?.status ?? 'aligned'
1189
- : 'blocked';
1190
- const declaredTruthRefs = await collectTruthAlignmentDeclaredTruthRefs(projectRoot, context.rawBranch, acceptedTestHandoffEnvelope?.payload ?? null);
1191
- const truthAlignmentProjection = goalVerifyRequired
714
+ const truthAlignmentProjection = acceptedEvidenceJudgmentRef
1192
715
  ? buildTruthAlignmentProjection(decision.scope, {
1193
- acceptedGoalVerificationRef: goalVerifyAcceptance.acceptedGoalVerificationRef,
1194
- declaredTruthRefs,
716
+ acceptedEvidenceJudgmentRef: acceptedEvidenceJudgmentRef,
717
+ declaredTruthRefs: await collectTruthAlignmentDeclaredTruthRefs(projectRoot, context.rawBranch, acceptedTasksHandoffEnvelope?.payload ?? null),
1195
718
  artifactRefs,
1196
- status: truthAlignmentStatus,
1197
- ownerStage: truthAlignmentObservation?.ownerStage ?? null,
1198
- semanticImpact: truthAlignmentObservation?.semanticImpact ?? (truthAlignmentStatus === 'aligned' ? 'none' : 'material'),
1199
- staleRefs: truthAlignmentObservation?.staleRefs ?? [],
1200
- invalidatesStages: truthAlignmentObservation?.invalidatesStages ?? (truthAlignmentStatus === 'aligned' ? [] : ['ship']),
1201
- reasons: truthAlignmentObservation?.reasons.length ? truthAlignmentObservation.reasons : goalVerifyAcceptance.goalVerifyAcceptanceStatus === 'accepted'
1202
- ? ['Accepted goal verification is structurally aligned with declared upstream truth refs.']
1203
- : goalVerifyAcceptance.reasons,
719
+ status: 'aligned',
720
+ ownerStage: null,
721
+ semanticImpact: 'none',
722
+ staleRefs: [],
723
+ invalidatesStages: [],
724
+ reasons: ['Accepted execute evidence judgment is structurally aligned with declared upstream truth refs.'],
1204
725
  generatedAt
1205
726
  })
1206
727
  : null;
1207
- const goalVerifyClosureReasons = truthAlignmentProjection?.status !== 'aligned' && truthAlignmentProjection?.reasons.length ? truthAlignmentProjection.reasons : goalVerifyAcceptance.reasons;
1208
728
  const truthAlignmentProjectionRef = truthAlignmentProjection
1209
- ? { kind: 'projection', ref: `${TRUTH_ALIGNMENT_PROJECTION_TYPE}:${truthAlignmentScopeKey({ branch: decision.scope.branch })}` }
1210
- : undefined;
1211
- const health = goalVerifyAcceptance.goalVerifyAcceptanceStatus === 'accepted'
1212
- ? truthAlignmentStatus === 'aligned' ? 'ready_for_ship' : 'blocked'
1213
- : !goalVerifyRequired
1214
- ? 'no-op'
1215
- : blocked
1216
- ? 'blocked'
1217
- : 'rejected';
1218
- const outputRefs = [goalVerifyAcceptance.acceptedGoalVerificationRef, truthAlignmentProjectionRef, adjudicationProjectionRef, collaborationContractRef, ...artifactRefs].filter((ref) => ref !== null && ref !== undefined);
1219
- const stageRun = buildGoalVerifyClosureStageRun(decision.scope, run.runId, workOrder, health, {
729
+ ? { kind: 'projection', ref: `${TRUTH_ALIGNMENT_PROJECTION_TYPE}:${truthAlignmentScopeKey({ branch: decision.scope.branch })}` }
730
+ : null;
731
+ const outputRefs = [executeAcceptance.acceptedExecuteRef, truthAlignmentProjectionRef, adjudicationProjectionRef, collaborationContractRef, ...executeAcceptance.laneEvidenceRefs, ...artifactRefs].filter((ref) => ref !== null);
732
+ const stageRun = buildExecuteClosureStageRun(decision.scope, run.runId, workOrder, health, {
1220
733
  outputRefs,
1221
734
  decisionRefs: [lifecycleRiskProjectionRef, adjudicationProjectionRef],
1222
- inputRefs: acceptedTestHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs,
735
+ inputRefs: acceptedTasksHandoffEnvelope?.payload.requiredInputRefs ?? decision.inputRefs,
1223
736
  generatedAt,
1224
- rejectionReason: goalVerifyAcceptance.rejectionIssue?.explanation ?? null
737
+ rejectionReason: executeAcceptance.rejectionIssue?.explanation ?? null
1225
738
  });
1226
739
  const stageRunProjectionRef = {
1227
740
  kind: 'projection',
1228
741
  ref: `${STAGE_RUN_PROJECTION_TYPE}:${stageRunScopeKey(stageRun.scope, stageRun.stage)}`
1229
742
  };
1230
- const handoff = null;
1231
- const workflowHandoffProjectionRef = undefined;
1232
- const rejection = goalVerifyAcceptance.rejectionIssue
1233
- ? buildStageRejection('goal-verify', decision.scope, null, goalVerifyAcceptance.rejectionIssue.reasonCode, goalVerifyAcceptance.rejectionIssue.explanation, goalVerifyAcceptance.rejectionIssue.requiredNextAction, goalVerifyAcceptance.rejectionIssue.fallbackRoute, generatedAt, true)
743
+ const handoff = executeAcceptance.executeAcceptanceStatus === 'accepted'
744
+ ? buildExecuteWorkflowHandoff(decision.scope, decision, {
745
+ outputRefs,
746
+ requiredInputRefs: executeAcceptance.acceptedExecuteRef ? [executeAcceptance.acceptedExecuteRef, ...executeAcceptance.laneEvidenceRefs] : executeAcceptance.laneEvidenceRefs,
747
+ evidenceRefs: artifactRefs,
748
+ riskDecisionRef: lifecycleRiskProjectionRef,
749
+ generatedAt
750
+ })
751
+ : null;
752
+ const workflowHandoffProjectionRef = handoff
753
+ ? { kind: 'projection', ref: `${WORKFLOW_HANDOFF_PROJECTION_TYPE}:${workflowHandoffScopeKey(handoff.scope, handoff.fromStage, handoff.toStage)}` }
754
+ : undefined;
755
+ const rejection = executeAcceptance.rejectionIssue
756
+ ? buildStageRejection('execute', decision.scope, null, executeAcceptance.rejectionIssue.reasonCode, executeAcceptance.rejectionIssue.explanation, executeAcceptance.rejectionIssue.requiredNextAction, executeAcceptance.rejectionIssue.fallbackRoute, generatedAt, true)
1234
757
  : null;
1235
758
  const closureRefs = {
1236
759
  runRef,
1237
- acceptedGoalVerificationRef: goalVerifyAcceptance.acceptedGoalVerificationRef,
1238
- goalVerifyAcceptanceStatus: goalVerifyAcceptance.goalVerifyAcceptanceStatus,
1239
- goalVerificationHash: goalVerifyAcceptance.goalVerificationHash,
1240
- acceptedTestHandoffRef: acceptedTestHandoffEnvelope ? { kind: 'projection', ref: `${WORKFLOW_HANDOFF_PROJECTION_TYPE}:${workflowHandoffScopeKey(decision.scope, 'test', 'goal-verify')}` } : null,
760
+ acceptedExecuteRef: executeAcceptance.acceptedExecuteRef,
761
+ executeAcceptanceStatus: executeAcceptance.executeAcceptanceStatus,
762
+ acceptedTasksHandoffRef: acceptedTasksHandoffEnvelope ? { kind: 'projection', ref: `${WORKFLOW_HANDOFF_PROJECTION_TYPE}:${workflowHandoffScopeKey(decision.scope, 'tasks', 'execute')}` } : null,
763
+ truthAlignmentProjectionRef,
764
+ laneEvidenceRefs: executeAcceptance.laneEvidenceRefs,
1241
765
  artifactRefs,
1242
766
  collaborationContractRef,
1243
767
  lifecycleRiskProjectionRef,
1244
768
  adjudicationProjectionRef,
1245
769
  stageRunProjectionRef,
1246
770
  workflowHandoffProjectionRef,
1247
- truthAlignmentProjectionRef,
1248
- reasons: goalVerifyClosureReasons
771
+ reasons: executeAcceptance.reasons
1249
772
  };
1250
773
  const adjudication = {
1251
774
  contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
1252
- adjudicationId: stableId('goal-verify-adjudication', decision.scope, health, generatedAt),
1253
- stage: 'goal-verify',
775
+ adjudicationId: stableId('execute-adjudication', decision.scope, health, generatedAt),
776
+ stage: 'execute',
1254
777
  scope: decision.scope,
1255
778
  health,
1256
779
  stageDecision: {
1257
780
  contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
1258
- decisionId: stableId('goal-verify-stage-decision', decision.scope, run.runId, generatedAt),
1259
- stage: 'goal-verify',
781
+ decisionId: stableId('execute-stage-decision', decision.scope, run.runId, generatedAt),
782
+ stage: 'execute',
1260
783
  scope: decision.scope,
1261
784
  status: health === 'ready_for_ship' ? 'completed' : health === 'no-op' ? 'skipped' : health === 'blocked' ? 'blocked' : 'rejected',
1262
785
  health,
1263
786
  acceptedDecisionRefs: outputRefs,
1264
787
  advisoryRefs: [],
1265
- capabilityRefs: artifactRefs.filter((ref) => ref.ref.includes('goal-verification') || ref.ref.includes('capability')),
1266
- blockingReasons: health === 'ready_for_ship' || health === 'no-op' ? [] : goalVerifyClosureReasons,
788
+ capabilityRefs: executeAcceptance.laneEvidenceRefs,
789
+ blockingReasons: health === 'ready_for_ship' || health === 'no-op' ? [] : executeAcceptance.reasons,
1267
790
  createdAt: generatedAt
1268
791
  },
1269
792
  handoffPacket: handoff,
1270
793
  rejection,
1271
- nextActions: buildStageRuntimeNextActions('goal-verify', decision.scope, generatedAt, health === 'ready_for_ship' ? ['stage_ready'] : rejection ? [rejectionReasonToNextActionReason(rejection.reasonCode)] : ['report_only']),
794
+ nextActions: buildStageRuntimeNextActions('execute', decision.scope, generatedAt, health === 'ready_for_ship' ? ['stage_ready', 'handoff_ready'] : rejection ? [rejectionReasonToNextActionReason(rejection.reasonCode)] : ['report_only']),
1272
795
  closureRefs,
1273
796
  createdAt: generatedAt
1274
797
  };
@@ -1277,7 +800,10 @@ export async function reconcileGoalVerifyCollaborationClosure(projectRoot, input
1277
800
  if (truthAlignmentProjection) {
1278
801
  await recordTruthAlignmentProjection(projectRoot, truthAlignmentProjection);
1279
802
  }
1280
- const projection = await recordGoalVerifyCollaborationAdjudicationProjection(projectRoot, adjudication);
803
+ if (handoff) {
804
+ await recordWorkflowHandoffProjection(projectRoot, handoff);
805
+ }
806
+ const projection = await recordExecuteCollaborationAdjudicationProjection(projectRoot, adjudication);
1281
807
  return {
1282
808
  runId: run.runId,
1283
809
  branch: context.rawBranch,
@@ -1287,7 +813,7 @@ export async function reconcileGoalVerifyCollaborationClosure(projectRoot, input
1287
813
  artifactRefs,
1288
814
  registeredArtifacts,
1289
815
  registeredCollaborationContracts,
1290
- acceptedGoalVerificationRef: goalVerifyAcceptance.acceptedGoalVerificationRef
816
+ acceptedExecuteRef: executeAcceptance.acceptedExecuteRef
1291
817
  };
1292
818
  }
1293
819
  export async function reconcileShipCollaborationClosure(projectRoot, input) {
@@ -1413,11 +939,8 @@ export async function reconcileShipCollaborationClosure(projectRoot, input) {
1413
939
  const FULL_STAGE_CHAIN = [
1414
940
  { stage: 'spec', expectedHealth: 'ready_for_plan', projectionType: SPEC_COLLABORATION_ADJUDICATION_PROJECTION_TYPE },
1415
941
  { stage: 'plan', expectedHealth: 'ready_for_tasks', projectionType: PLAN_COLLABORATION_ADJUDICATION_PROJECTION_TYPE },
1416
- { stage: 'tasks', expectedHealth: 'ready_for_verifies', projectionType: TASKS_COLLABORATION_ADJUDICATION_PROJECTION_TYPE },
1417
- { stage: 'verifies', expectedHealth: 'ready_for_do', projectionType: VERIFIES_COLLABORATION_ADJUDICATION_PROJECTION_TYPE },
1418
- { stage: 'do', expectedHealth: 'ready_for_test', projectionType: DO_COLLABORATION_ADJUDICATION_PROJECTION_TYPE },
1419
- { stage: 'test', expectedHealth: 'ready_for_goal_verify', projectionType: TEST_COLLABORATION_ADJUDICATION_PROJECTION_TYPE },
1420
- { stage: 'goal-verify', expectedHealth: 'ready_for_ship', projectionType: GOAL_VERIFY_COLLABORATION_ADJUDICATION_PROJECTION_TYPE },
942
+ { stage: 'tasks', expectedHealth: 'ready_for_execute', projectionType: TASKS_COLLABORATION_ADJUDICATION_PROJECTION_TYPE },
943
+ { stage: 'execute', expectedHealth: 'ready_for_ship', projectionType: EXECUTE_COLLABORATION_ADJUDICATION_PROJECTION_TYPE },
1421
944
  { stage: 'ship', expectedHealth: 'ship_ready', projectionType: SHIP_COLLABORATION_ADJUDICATION_PROJECTION_TYPE }
1422
945
  ];
1423
946
  export async function inspectFullStageChain(projectRoot, branch) {
@@ -1447,14 +970,14 @@ export async function inspectFullStageChain(projectRoot, branch) {
1447
970
  }
1448
971
  async function collectTruthAlignmentDeclaredTruthRefs(projectRoot, branch, testHandoff) {
1449
972
  const projectionTypes = FULL_STAGE_CHAIN
1450
- .filter((item) => item.stage !== 'goal-verify' && item.stage !== 'ship')
973
+ .filter((item) => item.stage !== 'ship')
1451
974
  .map((item) => item.projectionType);
1452
975
  const projections = await listRuntimeProjections(projectRoot, projectionTypes);
1453
976
  const envelopes = projections
1454
977
  .map((projection) => projection.payload)
1455
978
  .filter((envelope) => envelope?.payload?.scope?.branch === branch);
1456
979
  const acceptedRefs = FULL_STAGE_CHAIN
1457
- .filter((item) => item.stage !== 'goal-verify' && item.stage !== 'ship')
980
+ .filter((item) => item.stage !== 'ship')
1458
981
  .map((item) => latestStageChainEnvelope(envelopes, item.projectionType, item.stage))
1459
982
  .map((envelope) => envelope ? acceptedRefFromAdjudication(envelope.payload.stage, envelope.payload) : null)
1460
983
  .filter((ref) => ref !== null);
@@ -1497,10 +1020,7 @@ function acceptedRefFromAdjudication(stage, adjudication) {
1497
1020
  spec: 'acceptedSpecRef',
1498
1021
  plan: 'acceptedPlanRef',
1499
1022
  tasks: 'acceptedTasksRef',
1500
- verifies: 'acceptedVerifyRef',
1501
- do: 'acceptedImplementationRef',
1502
- test: 'acceptedTestEvidenceRef',
1503
- 'goal-verify': 'acceptedGoalVerificationRef',
1023
+ execute: 'acceptedExecuteRef',
1504
1024
  ship: 'acceptedShipReadinessRef'
1505
1025
  };
1506
1026
  return runtimeRefValue(closureRefs[keyByStage[stage]]) ?? adjudication.stageDecision?.acceptedDecisionRefs[0] ?? null;
@@ -1639,6 +1159,105 @@ export function adjudicateSpecStageClosureRequest(input) {
1639
1159
  nextActions: buildRuntimeNextActions(input.profile, generatedAt, ['stage_ready', 'handoff_ready'])
1640
1160
  });
1641
1161
  }
1162
+ function planMemberAgents(intensity) {
1163
+ if (intensity === 'noop' || intensity === 'blocked') {
1164
+ return [];
1165
+ }
1166
+ if (intensity === 'lightweight') {
1167
+ return [PLAN_STAGE_REVIEW_AGENT];
1168
+ }
1169
+ return [PLAN_STAGE_SCOUT_AGENT, PLAN_STAGE_REVIEW_AGENT];
1170
+ }
1171
+ function planScoutDomains(intensity) {
1172
+ if (intensity === 'noop' || intensity === 'blocked' || intensity === 'lightweight') {
1173
+ return [];
1174
+ }
1175
+ if (intensity === 'scout-first') {
1176
+ return ['architecture-runtime', 'testing-validation'];
1177
+ }
1178
+ return ['architecture-runtime', 'backend-api', 'database-migration', 'security', 'testing-validation'];
1179
+ }
1180
+ function planRequiredOutputKinds(intensity) {
1181
+ if (intensity === 'noop' || intensity === 'blocked') {
1182
+ return [];
1183
+ }
1184
+ if (intensity === 'lightweight') {
1185
+ return ['plan_review', 'manager_closure_request'];
1186
+ }
1187
+ return ['plan_context', 'plan_review', 'manager_closure_request'];
1188
+ }
1189
+ function planRequiredCapabilities(intensity) {
1190
+ if (intensity === 'noop' || intensity === 'blocked') {
1191
+ return [];
1192
+ }
1193
+ if (intensity === 'lightweight') {
1194
+ return ['plan-strategy', 'plan-pressure-review'];
1195
+ }
1196
+ return ['plan-strategy', 'plan-pressure-review', ...planScoutDomains(intensity)];
1197
+ }
1198
+ function planOptionalCapabilities(intensity) {
1199
+ if (intensity === 'noop' || intensity === 'blocked') {
1200
+ return [];
1201
+ }
1202
+ return PLAN_SCOUT_DOMAINS.filter((domain) => !planScoutDomains(intensity).includes(domain));
1203
+ }
1204
+ function planMaterialPackIds(intensity) {
1205
+ if (intensity === 'noop' || intensity === 'blocked') {
1206
+ return [];
1207
+ }
1208
+ if (intensity === 'lightweight') {
1209
+ return ['project-norms', 'plan-section-rubric'];
1210
+ }
1211
+ return [...PLAN_STAGE_MATERIAL_PACKS];
1212
+ }
1213
+ function planCollaborationPlan(intensity) {
1214
+ if (intensity === 'noop' || intensity === 'blocked') {
1215
+ return { topology: 'none', participants: [], maxParallelism: 0, fanIn: 'runtime_adjudication' };
1216
+ }
1217
+ const requiredCapabilities = planRequiredCapabilities(intensity);
1218
+ const optionalCapabilities = planOptionalCapabilities(intensity);
1219
+ const materialPackIds = planMaterialPackIds(intensity);
1220
+ const participants = [
1221
+ { id: PLAN_STAGE_MANAGER, kind: 'agent', role: 'plan-stage-manager', required: true, capabilityDomain: 'plan-strategy', parallelGroup: null },
1222
+ ...planMemberAgents(intensity).map((agent) => ({
1223
+ id: agent,
1224
+ kind: 'subagent',
1225
+ role: planAgentRole(agent),
1226
+ required: agent === PLAN_STAGE_REVIEW_AGENT,
1227
+ capabilityDomain: planAgentCapability(agent),
1228
+ parallelGroup: planAgentParallelGroup(agent)
1229
+ })),
1230
+ ...requiredCapabilities.map((capability) => ({ id: `cap.${capability}`, kind: 'skill', role: 'required-capability-review', required: true, capabilityDomain: capability, parallelGroup: 'capability-review' })),
1231
+ ...optionalCapabilities.map((capability) => ({ id: `cap.${capability}`, kind: 'skill', role: 'optional-capability-review', required: false, capabilityDomain: capability, parallelGroup: 'capability-review' })),
1232
+ ...materialPackIds.map((packId) => ({ id: packId, kind: 'material-pack', role: 'capability-material', required: false, parallelGroup: 'material-pack' }))
1233
+ ];
1234
+ const topology = intensity === 'lightweight' ? 'team-lite' : intensity === 'scout-first' ? 'parallel-research' : 'team-required';
1235
+ return { topology, participants, maxParallelism: topology === 'team-lite' ? 2 : 3, fanIn: 'runtime_adjudication' };
1236
+ }
1237
+ function planAgentRole(agent) {
1238
+ switch (agent) {
1239
+ case PLAN_STAGE_SCOUT_AGENT:
1240
+ return 'domain-evidence-scout';
1241
+ case PLAN_STAGE_REVIEW_AGENT:
1242
+ return 'plan-pressure-reviewer';
1243
+ }
1244
+ }
1245
+ function planAgentCapability(agent) {
1246
+ switch (agent) {
1247
+ case PLAN_STAGE_SCOUT_AGENT:
1248
+ return 'architecture-runtime';
1249
+ case PLAN_STAGE_REVIEW_AGENT:
1250
+ return 'plan-pressure-review';
1251
+ }
1252
+ }
1253
+ function planAgentParallelGroup(agent) {
1254
+ switch (agent) {
1255
+ case PLAN_STAGE_SCOUT_AGENT:
1256
+ return 'domain-scouting';
1257
+ case PLAN_STAGE_REVIEW_AGENT:
1258
+ return 'review';
1259
+ }
1260
+ }
1642
1261
  function specIntensity(decision, required) {
1643
1262
  if (decision.profile === 'blocked' || decision.blockedStages.includes('spec')) {
1644
1263
  return 'blocked';
@@ -1674,9 +1293,18 @@ function specMemberAgents(intensity) {
1674
1293
  return [];
1675
1294
  }
1676
1295
  if (intensity === 'lightweight') {
1677
- return [SPEC_STAGE_DRAFTER_AGENT, SPEC_STAGE_REVIEW_AGENT];
1296
+ return [SPEC_STAGE_REVIEW_AGENT];
1297
+ }
1298
+ return [SPEC_STAGE_SCOUT_AGENT, SPEC_STAGE_REVIEW_AGENT];
1299
+ }
1300
+ function specRequiredOutputKinds(intensity) {
1301
+ if (intensity === 'noop' || intensity === 'blocked') {
1302
+ return [];
1303
+ }
1304
+ if (intensity === 'lightweight') {
1305
+ return ['spec_review', 'manager_closure_request'];
1678
1306
  }
1679
- return [SPEC_STAGE_SCOUT_AGENT, SPEC_STAGE_DRAFTER_AGENT, SPEC_STAGE_REVIEW_AGENT];
1307
+ return ['scout_context', 'spec_review', 'manager_closure_request'];
1680
1308
  }
1681
1309
  function specRequiredCapabilities(intensity) {
1682
1310
  if (intensity === 'noop' || intensity === 'blocked') {
@@ -1717,10 +1345,10 @@ function specCollaborationPlan(intensity) {
1717
1345
  ...specMemberAgents(intensity).map((agent) => ({
1718
1346
  id: agent,
1719
1347
  kind: 'subagent',
1720
- role: agent === SPEC_STAGE_SCOUT_AGENT ? 'bounded-context-scout' : agent === SPEC_STAGE_DRAFTER_AGENT ? 'spec-document-candidate-author' : 'spec-document-reviewer',
1348
+ role: agent === SPEC_STAGE_SCOUT_AGENT ? 'bounded-context-scout' : 'spec-document-reviewer',
1721
1349
  required: true,
1722
- capabilityDomain: agent === SPEC_STAGE_SCOUT_AGENT ? 'context_curation' : agent === SPEC_STAGE_DRAFTER_AGENT ? 'norm_discovery' : 'uncertainty_resolution',
1723
- parallelGroup: agent === SPEC_STAGE_SCOUT_AGENT ? 'discovery' : agent === SPEC_STAGE_DRAFTER_AGENT ? 'authoring' : 'review'
1350
+ capabilityDomain: agent === SPEC_STAGE_SCOUT_AGENT ? 'context_curation' : 'uncertainty_resolution',
1351
+ parallelGroup: agent === SPEC_STAGE_SCOUT_AGENT ? 'discovery' : 'review'
1724
1352
  })),
1725
1353
  ...requiredCapabilities.map((capability) => ({ id: `cap.${capability}`, kind: 'skill', role: 'required-capability-review', required: true, capabilityDomain: capability, parallelGroup: 'capability-review' })),
1726
1354
  ...optionalCapabilities.map((capability) => ({ id: `cap.${capability}`, kind: 'skill', role: 'optional-capability-review', required: false, capabilityDomain: capability, parallelGroup: 'capability-review' })),
@@ -1732,7 +1360,7 @@ function specCollaborationPlan(intensity) {
1732
1360
  function validateStageClosureRequest(input) {
1733
1361
  const request = input.closureRequest;
1734
1362
  if (!request) {
1735
- return { reasonCode: 'invalid_proposal', explanation: 'Spec stage closure requires a StageClosureRequest from spec-manager.', requiredNextAction: 'Submit spec-manager closure request with candidate, review, and evidence refs.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1363
+ return { reasonCode: 'invalid_proposal', explanation: 'Spec stage closure requires a StageClosureRequest from spec-manager.', requiredNextAction: 'Submit spec-manager closure request with final spec ref/hash and runtime close boundary facts.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1736
1364
  }
1737
1365
  if (request.stage !== 'spec') {
1738
1366
  return { reasonCode: 'unsupported_stage', explanation: `Spec runtime cannot close ${request.stage} closure requests.`, requiredNextAction: 'Route the closure request to the matching stage runtime.', fallbackRoute: 'revise-proposal', retryAllowed: true };
@@ -1740,32 +1368,19 @@ function validateStageClosureRequest(input) {
1740
1368
  if (request.authorityAttempts.length > 0) {
1741
1369
  return { reasonCode: 'authority_violation', explanation: `Spec stage closure attempted workflow authority: ${request.authorityAttempts.join(', ')}.`, requiredNextAction: 'Remove workflow-authority attempts from manager and agent-team outputs.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1742
1370
  }
1743
- if (!request.candidate || !request.candidateRef) {
1744
- return { reasonCode: 'invalid_proposal', explanation: 'Spec stage closure is missing SpecDocumentCandidate.', requiredNextAction: 'Ask spec-drafter to produce a candidate and submit its ref.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1745
- }
1746
- if (request.candidate.stage !== 'spec') {
1371
+ if (request.candidate && request.candidate.stage !== 'spec') {
1747
1372
  return { reasonCode: 'unsupported_stage', explanation: `Spec runtime cannot close ${request.candidate.stage} candidates.`, requiredNextAction: 'Route the candidate to the matching stage runtime.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1748
1373
  }
1749
- if (request.candidate.inputRefs.length === 0) {
1750
- return { reasonCode: 'missing_refs', explanation: 'SpecDocumentCandidate has no input refs.', requiredNextAction: 'Attach spec request, document, or runtime projection refs before closure.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1751
- }
1752
- const unsupported = request.candidate.acceptedItems.find((item) => !input.profile.allowedProposalKinds.includes(item.kind));
1374
+ const unsupported = request.candidate?.acceptedItems.find((item) => !input.profile.allowedProposalKinds.includes(item.kind));
1753
1375
  if (unsupported) {
1754
1376
  return { reasonCode: 'invalid_proposal', explanation: `Spec candidate item ${unsupported.id} uses unsupported kind ${unsupported.kind}.`, requiredNextAction: 'Submit only allowed spec candidate item kinds for this profile.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1755
1377
  }
1756
- const missingItemRef = request.candidate.acceptedItems.find((item) => item.refs.length === 0);
1378
+ const missingItemRef = request.candidate?.acceptedItems.find((item) => item.refs.length === 0);
1757
1379
  if (missingItemRef) {
1758
1380
  return { reasonCode: 'missing_refs', explanation: `Spec candidate item ${missingItemRef.id} has no refs.`, requiredNextAction: 'Attach source refs to every candidate item.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1759
1381
  }
1760
- if (request.reviewRefs.length === 0 || request.reviewResults.length === 0) {
1761
- return { reasonCode: 'missing_required_review', explanation: 'Spec stage closure is missing spec-reviewer review evidence.', requiredNextAction: 'Ask spec-reviewer to review the candidate before closure.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1762
- }
1763
- const approvedReview = request.reviewResults.find((review) => review.reviewer === SPEC_STAGE_REVIEW_AGENT && review.verdict === 'approved');
1764
- if (!approvedReview && request.unresolvedAmbiguityIds.length === 0) {
1765
- return { reasonCode: 'missing_required_review', explanation: 'Spec stage closure has no approved spec-reviewer result.', requiredNextAction: 'Resolve review findings or submit approved spec-reviewer evidence.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1766
- }
1767
- if (request.evidenceRefs.length === 0) {
1768
- return { reasonCode: 'missing_refs', explanation: 'Spec stage closure has no evidence refs.', requiredNextAction: 'Attach work order, candidate, review, and source evidence refs.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1382
+ if (request.managerRecommendation === 'close_stage' && !request.runtimeCloseBoundaryFacts) {
1383
+ return { reasonCode: 'missing_refs', explanation: 'Spec stage close request is missing runtime close boundary facts for the final spec.md V3.', requiredNextAction: 'Ask spec-manager to submit finalSpecRef/finalSpecHash, section close declaration, review signal presence, and blockingBeforePlanCount=0.', fallbackRoute: 'revise-proposal', retryAllowed: true };
1769
1384
  }
1770
1385
  return null;
1771
1386
  }
@@ -2092,27 +1707,13 @@ async function registerSpecStageArtifacts(projectRoot, branch, profile, artifact
2092
1707
  return records;
2093
1708
  }
2094
1709
  async function collectSpecStageEvidenceRefs(projectRoot, branch, profile, artifactRefs) {
1710
+ void projectRoot;
1711
+ void branch;
1712
+ void profile;
2095
1713
  if (artifactRefs && artifactRefs.length > 0) {
2096
1714
  return [...new Set(artifactRefs.map(normalizeBranchStageEvidenceRef))];
2097
1715
  }
2098
- if (!profile.requiresStageClosure) {
2099
- return [];
2100
- }
2101
- const dir = getBranchStageEvidenceDir(projectRoot, branch, 'spec');
2102
- let files;
2103
- try {
2104
- files = await readdir(dir);
2105
- }
2106
- catch (error) {
2107
- if (error.code === 'ENOENT') {
2108
- return [];
2109
- }
2110
- throw error;
2111
- }
2112
- return files
2113
- .filter(isSpecStageEvidenceFile)
2114
- .sort(compareStageEvidenceFileNames)
2115
- .map((fileName) => toBranchStageEvidenceRef(branch, 'spec', fileName));
1716
+ return [];
2116
1717
  }
2117
1718
  async function registerBranchStageArtifacts(projectRoot, branch, stage, artifactRefs, required, runId, registeredAt) {
2118
1719
  const refs = await collectBranchStageEvidenceRefs(projectRoot, branch, stage, artifactRefs, required);
@@ -2200,95 +1801,226 @@ function runtimeRefForStageArtifact(record) {
2200
1801
  function runtimeRefForStageCollaborationContract(record) {
2201
1802
  return { kind: 'artifact', ref: record.ref, hash: record.hash };
2202
1803
  }
2203
- function latestValidatedStageCollaborationContract(records) {
2204
- return records
2205
- .filter((record) => record.status === 'validated')
2206
- .sort((left, right) => stageEvidenceVersion(right.ref) - stageEvidenceVersion(left.ref) || right.registeredAt.localeCompare(left.registeredAt))[0] ?? null;
2207
- }
2208
- function deriveRegisteredSpecManagerCoordination(profile, workOrder, records, generatedAt) {
2209
- const manager = latestStageArtifact(records, 'manager_closure_request');
2210
- if (!manager || !workOrder) {
1804
+ async function buildOutputCenteredSpecClosureRequest(projectRoot, profile, workOrder, partition, request, generatedAt) {
1805
+ if (!request) {
2211
1806
  return null;
2212
1807
  }
2213
- return {
2214
- contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
2215
- coordinationId: stableId('spec-manager-coordination', profile.scope, manager.ref, manager.hash, generatedAt),
2216
- stage: 'spec',
2217
- scope: profile.scope,
2218
- stageManager: SPEC_STAGE_MANAGER,
2219
- workOrderRef: { kind: 'projection', ref: `spec-work-order:${workOrder.workOrderId}` },
2220
- agentTeamRefs: records.filter((record) => record.ref !== manager.ref).map(runtimeRefForStageArtifact),
2221
- recommendation: manager.recommendation ?? 'blocked',
2222
- generatedAt
2223
- };
2224
- }
2225
- function deriveRegisteredStageClosureRequest(profile, workOrder, records, branchPartition, generatedAt) {
2226
- const manager = latestStageArtifact(records, 'manager_closure_request');
2227
- if (!manager) {
1808
+ const expectedSpecRef = `specs/${partition}/spec.md`;
1809
+ if (request.finalSpecRef && request.finalSpecRef !== expectedSpecRef) {
2228
1810
  return null;
2229
1811
  }
2230
- const review = findReviewForManager(records, manager);
2231
- const expectedSpecRef = `specs/${branchPartition}/spec.md`;
2232
- const candidateRef = manager.targetRef ?? review?.targetRef ?? { kind: 'document', ref: expectedSpecRef };
2233
- const evidenceRefs = records.map(runtimeRefForStageArtifact);
2234
- const blockingItem = manager.recommendation === 'request_clarification' || review?.verdict === 'blocked'
2235
- ? [{ id: 'blocking-ambiguity', kind: 'blocking_ambiguity', summary: 'Spec closure needs clarification before plan handoff.', refs: evidenceRefs }]
2236
- : [];
2237
- const handoffItem = manager.recommendation === 'close_stage'
2238
- ? [{ id: 'accepted-spec', kind: 'handoff_proposal', summary: 'Spec manager requested plan handoff for the reviewed canonical spec.', refs: [candidateRef, ...evidenceRefs] }]
2239
- : [];
2240
- const acceptedItems = [...blockingItem, ...handoffItem];
1812
+ if (request.sectionCloseDeclaration !== 'present' || request.reviewSignal !== 'present' || request.blockingBeforePlanCount !== 0) {
1813
+ return null;
1814
+ }
1815
+ const content = await readOptionalText(path.join(projectRoot, 'specs', partition, 'spec.md'));
1816
+ if (content === null) {
1817
+ return null;
1818
+ }
1819
+ const specHash = hashDocumentContent(content);
1820
+ const finalSpecRef = { kind: 'document', ref: expectedSpecRef, hash: specHash };
1821
+ const facts = {
1822
+ contract: 'sdd-spec-runtime-close-boundary-facts-v1',
1823
+ scope: profile.scope,
1824
+ finalSpecRef,
1825
+ finalSpecHash: specHash,
1826
+ templateContract: 'sdd-spec-doc-v3',
1827
+ blockingBeforePlanCount: 0,
1828
+ sectionCloseDeclaration: 'present',
1829
+ reviewSignal: 'present',
1830
+ runtimeTruthOwner: 'Runtime Kernel'
1831
+ };
1832
+ const acceptedItems = [{
1833
+ id: 'accepted-spec',
1834
+ kind: 'handoff_proposal',
1835
+ summary: 'Spec-manager submitted final spec.md V3 for runtime ref/hash acceptance.',
1836
+ refs: [finalSpecRef]
1837
+ }];
2241
1838
  const candidate = {
2242
1839
  contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
2243
- candidateId: stableId('spec-document-candidate', profile.scope, manager.ref, manager.hash, generatedAt),
1840
+ candidateId: stableId('spec-document-candidate', profile.scope, expectedSpecRef, specHash, generatedAt),
2244
1841
  stage: 'spec',
2245
1842
  scope: profile.scope,
2246
- producedBy: SPEC_STAGE_DRAFTER_AGENT,
2247
- inputRefs: profile.inputRefs.length > 0 ? profile.inputRefs : evidenceRefs,
2248
- evidenceRefs,
1843
+ producedBy: SPEC_STAGE_MANAGER,
1844
+ inputRefs: profile.inputRefs,
1845
+ evidenceRefs: [],
2249
1846
  acceptedItems,
2250
1847
  generatedAt
2251
1848
  };
2252
1849
  return {
2253
1850
  contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
2254
- closureRequestId: stableId('spec-closure-request', profile.scope, manager.ref, manager.hash, generatedAt),
1851
+ closureRequestId: stableId('spec-closure-request', profile.scope, expectedSpecRef, specHash, generatedAt),
2255
1852
  stage: 'spec',
2256
1853
  scope: profile.scope,
2257
- submittedBy: SPEC_STAGE_MANAGER,
1854
+ submittedBy: 'host-adapter',
2258
1855
  workOrderRef: workOrder ? { kind: 'projection', ref: `spec-work-order:${workOrder.workOrderId}` } : { kind: 'projection', ref: `spec-work-order:${specCollaborationScopeKey(profile.scope)}` },
2259
- coordinationRef: runtimeRefForStageArtifact(manager),
2260
- candidateRef,
2261
- reviewRefs: review ? [runtimeRefForStageArtifact(review)] : [],
1856
+ coordinationRef: null,
1857
+ candidateRef: finalSpecRef,
1858
+ reviewRefs: [],
2262
1859
  capabilityFindingRefs: [],
2263
- evidenceRefs,
1860
+ evidenceRefs: [],
2264
1861
  candidate,
2265
- reviewResults: review ? [registeredReviewResult(profile, review, generatedAt)] : [],
1862
+ reviewResults: [],
2266
1863
  capabilityFindings: [],
2267
- unresolvedAmbiguityIds: blockingItem.map((item) => item.id),
1864
+ unresolvedAmbiguityIds: [],
2268
1865
  authorityAttempts: [],
2269
- managerRecommendation: manager.recommendation ?? 'blocked',
1866
+ managerRecommendation: 'close_stage',
1867
+ runtimeCloseBoundaryFacts: facts,
2270
1868
  generatedAt
2271
1869
  };
2272
1870
  }
2273
- function registeredReviewResult(profile, review, generatedAt) {
1871
+ async function buildOutputCenteredPlanClosureRequest(projectRoot, scope, workOrder, partition, acceptedSpecHandoff, request, generatedAt) {
1872
+ if (!request) {
1873
+ return null;
1874
+ }
1875
+ const expectedPlanRef = `specs/${partition}/plan.md`;
1876
+ if (request.finalPlanRef && request.finalPlanRef !== expectedPlanRef) {
1877
+ return null;
1878
+ }
1879
+ if (request.planCloseQualityEvidence !== 'present' || request.reviewSignal !== 'present' || request.blockingBeforeTasksCount !== 0) {
1880
+ return null;
1881
+ }
1882
+ const acceptedSpecRef = acceptedSpecRefFromHandoff(partition, acceptedSpecHandoff);
1883
+ if (!acceptedSpecRef) {
1884
+ return null;
1885
+ }
1886
+ const content = await readOptionalText(path.join(projectRoot, 'specs', partition, 'plan.md'));
1887
+ if (content === null) {
1888
+ return null;
1889
+ }
1890
+ const planHash = hashDocumentContent(content);
1891
+ const finalPlanRef = { kind: 'document', ref: expectedPlanRef, hash: planHash };
1892
+ const facts = {
1893
+ contract: 'sdd-plan-runtime-close-boundary-facts-v1',
1894
+ scope,
1895
+ acceptedSpecRef,
1896
+ finalPlanRef,
1897
+ finalPlanHash: planHash,
1898
+ templateContract: 'sdd-plan-doc-v3',
1899
+ blockingBeforeTasksCount: 0,
1900
+ planCloseQualityEvidence: 'present',
1901
+ reviewSignal: 'present',
1902
+ runtimeTruthOwner: 'Runtime Kernel'
1903
+ };
2274
1904
  return {
2275
1905
  contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
2276
- reviewId: review.artifactId,
2277
- stage: 'spec',
2278
- scope: profile.scope,
2279
- reviewer: SPEC_STAGE_REVIEW_AGENT,
2280
- candidateRef: review.targetRef,
2281
- verdict: review.verdict ?? 'blocked',
2282
- findings: [`findingCount=${review.findingCount ?? 0}`, `blockingCount=${review.blockingCount ?? 0}`],
2283
- evidenceRefs: [runtimeRefForStageArtifact(review)],
1906
+ closureRequestId: stableId('plan-closure-request', scope, expectedPlanRef, planHash, generatedAt),
1907
+ stage: 'plan',
1908
+ scope,
1909
+ submittedBy: 'host-adapter',
1910
+ workOrderRef: workOrder ? { kind: 'projection', ref: `plan-work-order:${workOrder.workOrderId}` } : { kind: 'projection', ref: `plan-work-order:${planCollaborationScopeKey(scope)}` },
1911
+ coordinationRef: null,
1912
+ candidateRef: finalPlanRef,
1913
+ reviewRefs: [],
1914
+ capabilityFindingRefs: [],
1915
+ evidenceRefs: [],
1916
+ candidate: null,
1917
+ reviewResults: [],
1918
+ capabilityFindings: [],
1919
+ unresolvedAmbiguityIds: [],
1920
+ authorityAttempts: [],
1921
+ managerRecommendation: 'close_stage',
1922
+ runtimeCloseBoundaryFacts: facts,
2284
1923
  generatedAt
2285
1924
  };
2286
1925
  }
2287
- function findReviewForManager(records, manager) {
2288
- if (manager.reviewRef) {
2289
- return records.find((record) => record.kind === 'spec_review' && record.ref === manager.reviewRef?.ref && record.hash === manager.reviewHash) ?? null;
1926
+ async function buildOutputCenteredTasksClosureRequest(projectRoot, scope, workOrder, partition, acceptedPlanHandoff, request, generatedAt) {
1927
+ if (!request) {
1928
+ return null;
1929
+ }
1930
+ const expectedTasksRef = `specs/${partition}/tasks.md`;
1931
+ if (request.finalTasksRef && request.finalTasksRef !== expectedTasksRef) {
1932
+ return null;
1933
+ }
1934
+ if (request.dependencyGraphStatus !== 'present' || request.validationSignalsStatus !== 'present' || request.reviewSignal !== 'present' || request.blockingBeforeExecuteCount !== 0) {
1935
+ return null;
1936
+ }
1937
+ const acceptedPlanRef = acceptedPlanRefFromHandoff(partition, acceptedPlanHandoff);
1938
+ const acceptedSpecRef = acceptedSpecRefFromPlanHandoff(acceptedPlanHandoff);
1939
+ if (!acceptedPlanRef || !acceptedSpecRef) {
1940
+ return null;
1941
+ }
1942
+ const content = await readOptionalText(path.join(projectRoot, 'specs', partition, 'tasks.md'));
1943
+ if (content === null) {
1944
+ return null;
1945
+ }
1946
+ const taskModel = parseSddTasksMarkdown(content, { tasksPath: expectedTasksRef });
1947
+ const tasksHash = hashDocumentContent(content);
1948
+ const finalTasksRef = { kind: 'document', ref: expectedTasksRef, hash: tasksHash };
1949
+ const facts = {
1950
+ contract: 'sdd-tasks-runtime-close-boundary-facts-v1',
1951
+ scope,
1952
+ acceptedSpecRef,
1953
+ acceptedPlanRef,
1954
+ finalTasksRef,
1955
+ finalTasksHash: tasksHash,
1956
+ templateContract: 'sdd-tasks-doc-v2',
1957
+ taskUnitCount: taskModel.tasks.length,
1958
+ blockingBeforeExecuteCount: 0,
1959
+ dependencyGraphStatus: 'present',
1960
+ validationSignalsStatus: 'present',
1961
+ reviewSignal: 'present',
1962
+ runtimeTruthOwner: 'Runtime Kernel'
1963
+ };
1964
+ return {
1965
+ contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
1966
+ closureRequestId: stableId('tasks-closure-request', scope, expectedTasksRef, tasksHash, generatedAt),
1967
+ stage: 'tasks',
1968
+ scope,
1969
+ submittedBy: 'host-adapter',
1970
+ workOrderRef: workOrder ? { kind: 'projection', ref: `tasks-work-order:${workOrder.workOrderId}` } : { kind: 'projection', ref: `tasks-work-order:${tasksCollaborationScopeKey(scope)}` },
1971
+ coordinationRef: null,
1972
+ candidateRef: finalTasksRef,
1973
+ reviewRefs: [],
1974
+ capabilityFindingRefs: [],
1975
+ evidenceRefs: [],
1976
+ candidate: null,
1977
+ reviewResults: [],
1978
+ capabilityFindings: [],
1979
+ unresolvedAmbiguityIds: [],
1980
+ authorityAttempts: [],
1981
+ managerRecommendation: 'close_stage',
1982
+ runtimeCloseBoundaryFacts: facts,
1983
+ generatedAt
1984
+ };
1985
+ }
1986
+ function acceptedSpecRefFromHandoff(partition, handoff) {
1987
+ const expectedSpecRef = `specs/${partition}/spec.md`;
1988
+ return handoff?.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref === expectedSpecRef)
1989
+ ?? handoff?.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref === expectedSpecRef)
1990
+ ?? null;
1991
+ }
1992
+ function acceptedPlanRefFromHandoff(partition, handoff) {
1993
+ const expectedPlanRef = `specs/${partition}/plan.md`;
1994
+ return handoff?.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref === expectedPlanRef)
1995
+ ?? handoff?.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref === expectedPlanRef)
1996
+ ?? null;
1997
+ }
1998
+ function acceptedSpecRefFromPlanHandoff(handoff) {
1999
+ return handoff?.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref.endsWith('/spec.md'))
2000
+ ?? handoff?.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref.endsWith('/spec.md'))
2001
+ ?? null;
2002
+ }
2003
+ function latestValidatedStageCollaborationContract(records) {
2004
+ return records
2005
+ .filter((record) => record.status === 'validated')
2006
+ .sort((left, right) => stageEvidenceVersion(right.ref) - stageEvidenceVersion(left.ref) || right.registeredAt.localeCompare(left.registeredAt))[0] ?? null;
2007
+ }
2008
+ function deriveRegisteredSpecManagerCoordination(profile, workOrder, records, generatedAt) {
2009
+ const manager = latestStageArtifact(records, 'manager_closure_request');
2010
+ if (!manager || !workOrder) {
2011
+ return null;
2290
2012
  }
2291
- return latestStageArtifact(records, 'spec_review');
2013
+ return {
2014
+ contract: STAGE_COLLABORATION_RUNTIME_CONTRACT_VERSION,
2015
+ coordinationId: stableId('spec-manager-coordination', profile.scope, manager.ref, manager.hash, generatedAt),
2016
+ stage: 'spec',
2017
+ scope: profile.scope,
2018
+ stageManager: SPEC_STAGE_MANAGER,
2019
+ workOrderRef: { kind: 'projection', ref: `spec-work-order:${workOrder.workOrderId}` },
2020
+ agentTeamRefs: records.filter((record) => record.ref !== manager.ref).map(runtimeRefForStageArtifact),
2021
+ recommendation: manager.recommendation ?? 'blocked',
2022
+ generatedAt
2023
+ };
2292
2024
  }
2293
2025
  function latestStageArtifact(records, kind) {
2294
2026
  return records
@@ -2305,54 +2037,90 @@ async function validateAcceptedSpecArtifact(projectRoot, input) {
2305
2037
  reasons: [`Spec artifact was not accepted because adjudication health is ${input.adjudication.health}.`]
2306
2038
  };
2307
2039
  }
2308
- if (!input.validatedCollaborationContract) {
2309
- return rejectedSpecArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready spec closure must be backed by a validated spec StageCollaborationContract.', 'Ask spec-manager to write .sdd/runs/<branch>/spec/spec-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2310
- }
2311
2040
  const expectedRef = `specs/${input.partition}/spec.md`;
2312
- const manager = latestStageArtifact(input.registeredArtifacts, 'manager_closure_request');
2313
- if (!manager) {
2314
- return rejectedSpecArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready spec closure must be backed by a registered spec-manager closure artifact.', 'Ask spec-manager to write .sdd/runs/<branch>/spec/spec-manager-vN.md and register it before closure.');
2315
- }
2316
- if (manager.recommendation !== 'close_stage') {
2317
- return rejectedSpecArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Spec-manager recommendation ${manager.recommendation ?? 'none'} cannot accept spec for plan handoff.`, 'Ask spec-manager to submit a close_stage recommendation after review blockers are resolved.');
2041
+ const boundaryFacts = input.closureRequest?.runtimeCloseBoundaryFacts ?? null;
2042
+ if (!boundaryFacts || boundaryFacts.contract !== 'sdd-spec-runtime-close-boundary-facts-v1') {
2043
+ return rejectedSpecArtifact('not_accepted_wrong_ref', 'missing_refs', 'Ready spec closure must include runtime close boundary facts for the final spec.md V3.', 'Submit finalSpecRef/finalSpecHash, section close declaration, review signal presence, and blockingBeforePlanCount=0 before closure.');
2318
2044
  }
2319
- const reviewByRef = manager.reviewRef
2320
- ? input.registeredArtifacts.find((record) => record.kind === 'spec_review' && record.ref === manager.reviewRef?.ref) ?? null
2321
- : null;
2322
- if (reviewByRef && manager.reviewHash !== reviewByRef.hash) {
2323
- return rejectedSpecArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Spec-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh spec-manager closure artifact so reviewRef/reviewHash point at the registered review artifact.');
2324
- }
2325
- const approvedReview = findReviewForManager(input.registeredArtifacts, manager);
2326
- if (!approvedReview) {
2327
- return rejectedSpecArtifact('not_accepted_wrong_ref', 'missing_required_review', 'Ready spec closure must include a registered spec-reviewer artifact referenced by spec-manager.', 'Ask spec-reviewer to write .sdd/runs/<branch>/spec/spec-review-vN.md and ask spec-manager to reference that review hash.');
2328
- }
2329
- if (approvedReview.verdict !== 'approved' || approvedReview.blockingCount !== 0) {
2330
- return rejectedSpecArtifact('not_accepted_wrong_ref', 'missing_required_review', `Spec-reviewer verdict ${approvedReview.verdict ?? 'none'} with ${approvedReview.blockingCount ?? 0} blockers cannot accept spec.`, 'Resolve review blockers and register an approved spec-reviewer artifact before closure.');
2331
- }
2332
- if (manager.targetRef?.kind !== 'document' || manager.targetRef.ref !== expectedRef || approvedReview.targetRef?.kind !== 'document' || approvedReview.targetRef.ref !== expectedRef) {
2333
- return rejectedSpecArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready spec closure must reference reviewed ${expectedRef} as the canonical spec document.`, 'Refresh review and manager artifacts so targetRef points at specs/<branch>/spec.md.');
2045
+ if (!validSpecRuntimeCloseBoundaryFacts(boundaryFacts, input.partition, expectedRef)) {
2046
+ return rejectedSpecArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Spec runtime close boundary facts do not match the final spec.md V3 acceptance contract.', 'Refresh spec close facts so finalSpecRef/finalSpecHash, template contract, section close declaration, review signal, and blocking count match runtime requirements.');
2334
2047
  }
2335
2048
  const specPath = path.join(projectRoot, 'specs', input.partition, 'spec.md');
2336
2049
  const content = await readOptionalText(specPath);
2337
2050
  if (content === null) {
2338
- return rejectedSpecArtifact('not_accepted_missing_spec', 'missing_refs', `Reviewed canonical spec artifact is missing at ${expectedRef}.`, 'Produce and review specs/<branch>/spec.md before requesting runtime closure.');
2051
+ return rejectedSpecArtifact('not_accepted_missing_spec', 'missing_refs', `Final spec.md V3 artifact is missing at ${expectedRef}.`, 'Produce specs/<branch>/spec.md before requesting runtime closure.');
2339
2052
  }
2340
2053
  if (isManagedStarterSpec(content)) {
2341
- return rejectedSpecArtifact('not_accepted_starter_spec', 'invalid_proposal', `Canonical spec artifact at ${expectedRef} is still the managed starter spec.`, 'Replace starter spec.md with reviewed semantic spec content before closure.');
2054
+ return rejectedSpecArtifact('not_accepted_starter_spec', 'invalid_proposal', `Canonical spec artifact at ${expectedRef} is still the managed starter spec.`, 'Replace starter spec.md with final semantic spec.md V3 content before closure.');
2342
2055
  }
2343
2056
  const specHash = hashDocumentContent(content);
2344
- const expectedHashes = [manager.targetHash, approvedReview.targetHash, manager.targetRef.hash, approvedReview.targetRef.hash].filter((hash) => Boolean(hash));
2057
+ const expectedHashes = [boundaryFacts.finalSpecHash, boundaryFacts.finalSpecRef.hash].filter((hash) => Boolean(hash));
2345
2058
  const mismatchedHash = expectedHashes.find((hash) => hash !== specHash);
2346
2059
  if (mismatchedHash) {
2347
- return rejectedSpecArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed spec hash mismatch for ${expectedRef}: expected ${mismatchedHash}, actual ${specHash}.`, 'Refresh spec-reviewer and spec-manager artifacts with the current spec.md hash before closure.');
2060
+ return rejectedSpecArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Final spec.md V3 hash mismatch for ${expectedRef}: expected ${mismatchedHash}, actual ${specHash}.`, 'Refresh spec close facts with the current spec.md hash before closure.');
2061
+ }
2062
+ const specV3Errors = validateSpecDocumentV3(content);
2063
+ if (specV3Errors.length > 0) {
2064
+ return rejectedSpecArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Final spec.md does not satisfy sdd-spec-doc-v3: ${specV3Errors.join('; ')}.`, 'Rewrite specs/<branch>/spec.md as final spec.md V3 with required semantic sections before closure.');
2348
2065
  }
2349
2066
  return {
2350
2067
  acceptedSpecRef: { kind: 'document', ref: expectedRef, hash: specHash },
2351
2068
  specAcceptanceStatus: 'accepted',
2352
2069
  specHash,
2353
2070
  specContractHash: hashSemanticDocument(content),
2354
- reasons: [`Runtime accepted reviewed canonical spec artifact ${expectedRef}.`]
2355
- };
2071
+ reasons: [`Runtime accepted final spec.md V3 artifact ${expectedRef}.`]
2072
+ };
2073
+ }
2074
+ function validSpecRuntimeCloseBoundaryFacts(facts, partition, expectedSpecRef) {
2075
+ return facts.contract === 'sdd-spec-runtime-close-boundary-facts-v1'
2076
+ && facts.scope.branch === partition
2077
+ && facts.finalSpecRef.kind === 'document'
2078
+ && facts.finalSpecRef.ref === expectedSpecRef
2079
+ && Boolean(facts.finalSpecRef.hash)
2080
+ && facts.finalSpecHash === facts.finalSpecRef.hash
2081
+ && facts.templateContract === 'sdd-spec-doc-v3'
2082
+ && facts.blockingBeforePlanCount === 0
2083
+ && facts.sectionCloseDeclaration === 'present'
2084
+ && facts.reviewSignal === 'present'
2085
+ && facts.runtimeTruthOwner === 'Runtime Kernel';
2086
+ }
2087
+ function validPlanRuntimeCloseBoundaryFacts(facts, partition, expectedPlanRef, acceptedSpecRef) {
2088
+ return facts.contract === 'sdd-plan-runtime-close-boundary-facts-v1'
2089
+ && facts.scope.branch === partition
2090
+ && facts.acceptedSpecRef.kind === acceptedSpecRef.kind
2091
+ && facts.acceptedSpecRef.ref === acceptedSpecRef.ref
2092
+ && facts.acceptedSpecRef.hash === acceptedSpecRef.hash
2093
+ && facts.finalPlanRef.kind === 'document'
2094
+ && facts.finalPlanRef.ref === expectedPlanRef
2095
+ && Boolean(facts.finalPlanRef.hash)
2096
+ && facts.finalPlanHash === facts.finalPlanRef.hash
2097
+ && facts.templateContract === 'sdd-plan-doc-v3'
2098
+ && facts.blockingBeforeTasksCount === 0
2099
+ && facts.planCloseQualityEvidence === 'present'
2100
+ && facts.reviewSignal === 'present'
2101
+ && facts.runtimeTruthOwner === 'Runtime Kernel';
2102
+ }
2103
+ function validTasksRuntimeCloseBoundaryFacts(facts, partition, expectedTasksRef, acceptedSpecRef, acceptedPlanRef, taskUnitCount) {
2104
+ return facts.contract === 'sdd-tasks-runtime-close-boundary-facts-v1'
2105
+ && facts.scope.branch === partition
2106
+ && facts.acceptedSpecRef.kind === acceptedSpecRef.kind
2107
+ && facts.acceptedSpecRef.ref === acceptedSpecRef.ref
2108
+ && facts.acceptedSpecRef.hash === acceptedSpecRef.hash
2109
+ && facts.acceptedPlanRef.kind === acceptedPlanRef.kind
2110
+ && facts.acceptedPlanRef.ref === acceptedPlanRef.ref
2111
+ && facts.acceptedPlanRef.hash === acceptedPlanRef.hash
2112
+ && facts.finalTasksRef.kind === 'document'
2113
+ && facts.finalTasksRef.ref === expectedTasksRef
2114
+ && Boolean(facts.finalTasksRef.hash)
2115
+ && facts.finalTasksHash === facts.finalTasksRef.hash
2116
+ && facts.templateContract === 'sdd-tasks-doc-v2'
2117
+ && facts.taskUnitCount === taskUnitCount
2118
+ && facts.taskUnitCount > 0
2119
+ && facts.blockingBeforeExecuteCount === 0
2120
+ && facts.dependencyGraphStatus === 'present'
2121
+ && facts.validationSignalsStatus === 'present'
2122
+ && facts.reviewSignal === 'present'
2123
+ && facts.runtimeTruthOwner === 'Runtime Kernel';
2356
2124
  }
2357
2125
  function rejectedSpecArtifact(specAcceptanceStatus, reasonCode, explanation, requiredNextAction) {
2358
2126
  return {
@@ -2382,50 +2150,37 @@ async function validateAcceptedPlanArtifact(projectRoot, input) {
2382
2150
  if (input.blocked) {
2383
2151
  return rejectedPlanArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks plan closure.', 'Resolve lifecycle blockers before requesting plan-stage closure.', 'runtime-blocked');
2384
2152
  }
2385
- if (!latestValidatedStageCollaborationContract(input.registeredCollaborationContracts)) {
2386
- return rejectedPlanArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready plan closure must be backed by a validated plan StageCollaborationContract.', 'Ask plan-manager to write .sdd/runs/<branch>/plan/plan-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2387
- }
2388
2153
  const upstreamIssue = await validateAcceptedSpecHandoff(projectRoot, input.partition, input.acceptedSpecHandoff);
2389
2154
  if (upstreamIssue) {
2390
2155
  return rejectedPlanArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh spec-stage closure and provide a fresh spec -> plan handoff before plan closure.');
2391
2156
  }
2392
2157
  const expectedRef = `specs/${input.partition}/plan.md`;
2393
- const manager = latestStageArtifact(input.registeredArtifacts, 'manager_closure_request');
2394
- if (!manager) {
2395
- return rejectedPlanArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready plan closure must be backed by a registered plan-manager closure artifact.', 'Ask plan-manager to write .sdd/runs/<branch>/plan/plan-manager-vN.md and register it before closure.');
2396
- }
2397
- if (manager.recommendation !== 'close_stage') {
2398
- return rejectedPlanArtifact('not_accepted_rejected', 'invalid_proposal', `Plan-manager recommendation ${manager.recommendation ?? 'none'} cannot accept plan for tasks handoff.`, 'Ask plan-manager to submit a close_stage recommendation after review blockers are resolved.');
2399
- }
2400
- const reviewByRef = manager.reviewRef
2401
- ? input.registeredArtifacts.find((record) => record.kind === 'plan_review' && record.ref === manager.reviewRef?.ref) ?? null
2402
- : null;
2403
- if (reviewByRef && manager.reviewHash !== reviewByRef.hash) {
2404
- return rejectedPlanArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Plan-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh plan-manager closure artifact so reviewRef/reviewHash point at the registered review artifact.');
2405
- }
2406
- const approvedReview = findStageReviewForManager(input.registeredArtifacts, manager, 'plan_review');
2407
- if (!approvedReview) {
2408
- return rejectedPlanArtifact('not_accepted_missing_review', 'missing_required_review', 'Ready plan closure must include a registered plan-reviewer artifact referenced by plan-manager.', 'Ask plan-reviewer to write .sdd/runs/<branch>/plan/plan-review-vN.md and ask plan-manager to reference that review hash.');
2158
+ const acceptedSpecRef = acceptedSpecRefFromHandoff(input.partition, input.acceptedSpecHandoff);
2159
+ if (!acceptedSpecRef) {
2160
+ return rejectedPlanArtifact('not_accepted_missing_upstream', 'missing_refs', 'Plan closure requires accepted spec ref/hash from runtime handoff.', 'Refresh spec-stage closure and provide a fresh spec -> plan handoff before plan closure.');
2409
2161
  }
2410
- if (approvedReview.verdict !== 'approved' || approvedReview.blockingCount !== 0) {
2411
- return rejectedPlanArtifact('not_accepted_missing_review', 'missing_required_review', `Plan-reviewer verdict ${approvedReview.verdict ?? 'none'} with ${approvedReview.blockingCount ?? 0} blockers cannot accept plan.`, 'Resolve review blockers and register an approved plan-reviewer artifact before closure.');
2162
+ const boundaryFacts = input.closureRequest?.runtimeCloseBoundaryFacts;
2163
+ if (!boundaryFacts || boundaryFacts.contract !== 'sdd-plan-runtime-close-boundary-facts-v1') {
2164
+ return rejectedPlanArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Plan close request is missing runtime boundary facts for final plan.md V3.', 'Submit finalPlanRef/finalPlanHash, acceptedSpecRef, plan close quality evidence, review signal, and blockingBeforeTasksCount=0.');
2412
2165
  }
2413
- if (manager.targetRef?.kind !== 'document' || manager.targetRef.ref !== expectedRef || approvedReview.targetRef?.kind !== 'document' || approvedReview.targetRef.ref !== expectedRef) {
2414
- return rejectedPlanArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready plan closure must reference reviewed ${expectedRef} as the canonical plan document.`, 'Refresh review and manager artifacts so targetRef points at specs/<branch>/plan.md.');
2166
+ if (!validPlanRuntimeCloseBoundaryFacts(boundaryFacts, input.partition, expectedRef, acceptedSpecRef)) {
2167
+ return rejectedPlanArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Plan close boundary facts must reference accepted spec and final ${expectedRef}.`, 'Refresh the output close request from current runtime handoff and specs/<branch>/plan.md.');
2415
2168
  }
2416
2169
  const planPath = path.join(projectRoot, 'specs', input.partition, 'plan.md');
2417
2170
  const content = await readOptionalText(planPath);
2418
2171
  if (content === null) {
2419
- return rejectedPlanArtifact('not_accepted_missing_plan', 'missing_refs', `Reviewed canonical plan artifact is missing at ${expectedRef}.`, 'Produce and review specs/<branch>/plan.md before requesting runtime closure.');
2172
+ return rejectedPlanArtifact('not_accepted_missing_plan', 'missing_refs', `Canonical plan artifact is missing at ${expectedRef}.`, 'Produce specs/<branch>/plan.md before requesting runtime closure.');
2420
2173
  }
2421
2174
  if (isManagedStarterSpec(content)) {
2422
- return rejectedPlanArtifact('not_accepted_starter_plan', 'invalid_proposal', `Canonical plan artifact at ${expectedRef} is still the managed starter document.`, 'Replace starter plan.md with reviewed semantic plan content before closure.');
2175
+ return rejectedPlanArtifact('not_accepted_starter_plan', 'invalid_proposal', `Canonical plan artifact at ${expectedRef} is still the managed starter document.`, 'Replace starter plan.md with semantic plan content before closure.');
2176
+ }
2177
+ const documentErrors = validatePlanDocumentV3(content, boundaryFacts);
2178
+ if (documentErrors.length > 0) {
2179
+ return rejectedPlanArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Canonical plan artifact at ${expectedRef} is not a valid sdd-plan-doc-v3: ${documentErrors.join('; ')}.`, 'Rewrite specs/<branch>/plan.md as plan.md V3 before requesting runtime closure.');
2423
2180
  }
2424
2181
  const planHash = hashDocumentContent(content);
2425
- const expectedHashes = [manager.targetHash, approvedReview.targetHash, manager.targetRef.hash, approvedReview.targetRef.hash].filter((hash) => Boolean(hash));
2426
- const mismatchedHash = expectedHashes.find((hash) => hash !== planHash);
2427
- if (mismatchedHash) {
2428
- return rejectedPlanArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed plan hash mismatch for ${expectedRef}: expected ${mismatchedHash}, actual ${planHash}.`, 'Refresh plan-reviewer and plan-manager artifacts with the current plan.md hash before closure.');
2182
+ if (boundaryFacts.finalPlanHash !== planHash || boundaryFacts.finalPlanRef.hash !== planHash) {
2183
+ return rejectedPlanArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Final plan hash mismatch for ${expectedRef}: expected ${boundaryFacts.finalPlanHash}, actual ${planHash}.`, 'Refresh plan close request with the current plan.md hash before closure.');
2429
2184
  }
2430
2185
  return {
2431
2186
  acceptedPlanRef: { kind: 'document', ref: expectedRef, hash: planHash },
@@ -2448,45 +2203,37 @@ async function validateAcceptedTasksArtifact(projectRoot, input) {
2448
2203
  if (input.blocked) {
2449
2204
  return rejectedTasksArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks tasks closure.', 'Resolve lifecycle blockers before requesting tasks-stage closure.', 'runtime-blocked');
2450
2205
  }
2451
- if (!latestValidatedStageCollaborationContract(input.registeredCollaborationContracts)) {
2452
- return rejectedTasksArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready tasks closure must be backed by a validated tasks StageCollaborationContract.', 'Ask tasks-manager to write .sdd/runs/<branch>/tasks/tasks-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2453
- }
2454
2206
  const upstreamIssue = await validateAcceptedPlanHandoff(projectRoot, input.partition, input.acceptedPlanHandoff);
2455
2207
  if (upstreamIssue) {
2456
2208
  return rejectedTasksArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh plan-stage closure and provide a fresh plan -> tasks handoff before tasks closure.');
2457
2209
  }
2458
2210
  const expectedRef = `specs/${input.partition}/tasks.md`;
2459
- const manager = latestStageArtifact(input.registeredArtifacts, 'manager_closure_request');
2460
- if (!manager) {
2461
- return rejectedTasksArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready tasks closure must be backed by a registered tasks-manager closure artifact.', 'Ask tasks-manager to write .sdd/runs/<branch>/tasks/tasks-manager-vN.md and register it before closure.');
2462
- }
2463
- if (manager.recommendation !== 'close_stage') {
2464
- return rejectedTasksArtifact('not_accepted_rejected', 'invalid_proposal', `Tasks-manager recommendation ${manager.recommendation ?? 'none'} cannot accept tasks for verifies handoff.`, 'Ask tasks-manager to submit a close_stage recommendation after review blockers are resolved.');
2465
- }
2466
- const reviewByRef = manager.reviewRef
2467
- ? input.registeredArtifacts.find((record) => record.kind === 'tasks_review' && record.ref === manager.reviewRef?.ref) ?? null
2468
- : null;
2469
- if (reviewByRef && manager.reviewHash !== reviewByRef.hash) {
2470
- return rejectedTasksArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Tasks-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh tasks-manager closure artifact so reviewRef/reviewHash point at the registered review artifact.');
2471
- }
2472
- const approvedReview = findStageReviewForManager(input.registeredArtifacts, manager, 'tasks_review');
2473
- if (!approvedReview) {
2474
- return rejectedTasksArtifact('not_accepted_missing_review', 'missing_required_review', 'Ready tasks closure must include a registered tasks-reviewer artifact referenced by tasks-manager.', 'Ask tasks-reviewer to write .sdd/runs/<branch>/tasks/tasks-review-vN.md and ask tasks-manager to reference that review hash.');
2475
- }
2476
- if (approvedReview.verdict !== 'approved' || approvedReview.blockingCount !== 0) {
2477
- return rejectedTasksArtifact('not_accepted_missing_review', 'missing_required_review', `Tasks-reviewer verdict ${approvedReview.verdict ?? 'none'} with ${approvedReview.blockingCount ?? 0} blockers cannot accept tasks.`, 'Resolve review blockers and register an approved tasks-reviewer artifact before closure.');
2478
- }
2479
- if (manager.targetRef?.kind !== 'document' || manager.targetRef.ref !== expectedRef || approvedReview.targetRef?.kind !== 'document' || approvedReview.targetRef.ref !== expectedRef) {
2480
- return rejectedTasksArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready tasks closure must reference reviewed ${expectedRef} as the canonical tasks document.`, 'Refresh review and manager artifacts so targetRef points at specs/<branch>/tasks.md.');
2211
+ const acceptedPlanRef = acceptedPlanRefFromHandoff(input.partition, input.acceptedPlanHandoff);
2212
+ const acceptedSpecRef = acceptedSpecRefFromPlanHandoff(input.acceptedPlanHandoff);
2213
+ if (!acceptedPlanRef || !acceptedSpecRef) {
2214
+ return rejectedTasksArtifact('not_accepted_missing_upstream', 'missing_refs', 'Tasks closure requires accepted spec and plan ref/hash from runtime handoff.', 'Refresh plan-stage closure and provide a fresh plan -> tasks handoff before tasks closure.');
2481
2215
  }
2482
2216
  const tasksPath = path.join(projectRoot, 'specs', input.partition, 'tasks.md');
2483
2217
  const content = await readOptionalText(tasksPath);
2218
+ const boundaryFacts = input.closureRequest?.runtimeCloseBoundaryFacts;
2219
+ if (!boundaryFacts || boundaryFacts.contract !== 'sdd-tasks-runtime-close-boundary-facts-v1') {
2220
+ const closeEvidenceErrors = [];
2221
+ if (content !== null) {
2222
+ validateTasksDepthSignals(content, closeEvidenceErrors);
2223
+ }
2224
+ const closeEvidenceExplanation = closeEvidenceErrors.join('\n');
2225
+ return rejectedTasksArtifact('not_accepted_wrong_ref', 'invalid_proposal', closeEvidenceExplanation || 'Tasks close request is missing runtime boundary facts for final tasks.md V2.', 'Submit finalTasksRef/finalTasksHash, acceptedSpecRef, acceptedPlanRef, taskUnitCount, dependencyGraphStatus, validationSignalsStatus, reviewSignal, and blockingBeforeExecuteCount=0.');
2226
+ }
2484
2227
  if (content === null) {
2485
2228
  return rejectedTasksArtifact('not_accepted_missing_tasks', 'missing_refs', `Reviewed canonical tasks artifact is missing at ${expectedRef}.`, 'Produce and review specs/<branch>/tasks.md before requesting runtime closure.');
2486
2229
  }
2487
2230
  if (isManagedStarterSpec(content)) {
2488
2231
  return rejectedTasksArtifact('not_accepted_starter_tasks', 'invalid_proposal', `Canonical tasks artifact at ${expectedRef} is still the managed starter document.`, 'Replace starter tasks.md with reviewed executable task contracts before closure.');
2489
2232
  }
2233
+ const tasksV2Errors = validateTasksDocumentV2(content, expectedRef);
2234
+ if (tasksV2Errors.length > 0) {
2235
+ return rejectedTasksArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Final tasks.md does not satisfy sdd-tasks-doc-v2: ${tasksV2Errors.join('; ')}.`, 'Rewrite specs/<branch>/tasks.md as final tasks.md V2 with required execution topology sections before closure.');
2236
+ }
2490
2237
  const taskModel = parseSddTasksMarkdown(content, { tasksPath: expectedRef });
2491
2238
  const duplicateIdGap = taskModel.gaps.find((gap) => gap.field === 'id' && /Duplicate task id/i.test(gap.message));
2492
2239
  if (duplicateIdGap) {
@@ -2498,11 +2245,12 @@ async function validateAcceptedTasksArtifact(projectRoot, input) {
2498
2245
  if (blockingTaskGap) {
2499
2246
  return rejectedTasksArtifact('not_accepted_invalid_task_ids', 'invalid_proposal', blockingTaskGap.message, blockingTaskGap.recommendation);
2500
2247
  }
2501
- const tasksHash = hashDocumentContent(content);
2502
- const expectedHashes = [manager.targetHash, approvedReview.targetHash, manager.targetRef.hash, approvedReview.targetRef.hash].filter((hash) => Boolean(hash));
2503
- const mismatchedHash = expectedHashes.find((hash) => hash !== tasksHash);
2504
- if (mismatchedHash) {
2505
- return rejectedTasksArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed tasks hash mismatch for ${expectedRef}: expected ${mismatchedHash}, actual ${tasksHash}.`, 'Refresh tasks-reviewer and tasks-manager artifacts with the current tasks.md hash before closure.');
2248
+ const tasksHash = hashDocumentContent(content);
2249
+ if (!validTasksRuntimeCloseBoundaryFacts(boundaryFacts, input.partition, expectedRef, acceptedSpecRef, acceptedPlanRef, taskModel.tasks.length)) {
2250
+ return rejectedTasksArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Tasks close boundary facts must reference accepted spec, accepted plan, final ${expectedRef}, and parsed task unit count.`, 'Refresh the output close request from current runtime handoff and specs/<branch>/tasks.md.');
2251
+ }
2252
+ if (boundaryFacts.finalTasksHash !== tasksHash || boundaryFacts.finalTasksRef.hash !== tasksHash) {
2253
+ return rejectedTasksArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Final tasks hash mismatch for ${expectedRef}: expected ${boundaryFacts.finalTasksHash}, actual ${tasksHash}.`, 'Refresh tasks close request with the current tasks.md hash before closure.');
2506
2254
  }
2507
2255
  const tasksContractHash = hashTasksContract(content);
2508
2256
  if (!tasksContractHash) {
@@ -2516,76 +2264,83 @@ async function validateAcceptedTasksArtifact(projectRoot, input) {
2516
2264
  reasons: [`Runtime accepted reviewed canonical tasks artifact ${expectedRef}.`]
2517
2265
  };
2518
2266
  }
2519
- async function validateAcceptedVerifyArtifact(projectRoot, input) {
2267
+ async function validateAcceptedExecuteArtifact(projectRoot, input) {
2520
2268
  if (!input.required) {
2521
2269
  return {
2522
- acceptedVerifyRef: null,
2523
- verifyAcceptanceStatus: 'not_required_noop',
2524
- verifyHash: null,
2525
- verifyContractHash: null,
2526
- reasons: ['Verify artifact was not required by this lifecycle decision.']
2270
+ acceptedExecuteRef: null,
2271
+ executeAcceptanceStatus: 'not_required_noop',
2272
+ laneEvidenceRefs: [],
2273
+ reasons: ['Execute evidence was not required by this lifecycle decision.']
2527
2274
  };
2528
2275
  }
2529
2276
  if (input.blocked) {
2530
- return rejectedVerifyArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks verifies closure.', 'Resolve lifecycle blockers before requesting verifies-stage closure.', 'runtime-blocked');
2531
- }
2532
- if (!latestValidatedStageCollaborationContract(input.registeredCollaborationContracts)) {
2533
- return rejectedVerifyArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready verifies closure must be backed by a validated verifies StageCollaborationContract.', 'Ask verifies-manager to write .sdd/runs/<branch>/verifies/verifies-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2277
+ return rejectedExecuteArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks execute closure.', 'Resolve lifecycle blockers before requesting execute-stage closure.', 'runtime-blocked');
2534
2278
  }
2535
- const upstreamIssue = await validateAcceptedTasksHandoff(projectRoot, input.partition, input.acceptedTasksHandoff);
2279
+ const upstreamIssue = await validateAcceptedExecuteTasksHandoff(projectRoot, input.partition, input.acceptedTasksHandoff);
2536
2280
  if (upstreamIssue) {
2537
- return rejectedVerifyArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh tasks-stage closure and provide a fresh tasks -> verifies handoff before verifies closure.');
2538
- }
2539
- const expectedRef = `specs/${input.partition}/verify.md`;
2540
- const manager = latestStageArtifact(input.registeredArtifacts, 'manager_closure_request');
2541
- if (!manager) {
2542
- return rejectedVerifyArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready verifies closure must be backed by a registered verifies-manager closure artifact.', 'Ask verifies-manager to write .sdd/runs/<branch>/verifies/verifies-manager-vN.md and register it before closure.');
2543
- }
2544
- if (manager.recommendation !== 'close_stage') {
2545
- return rejectedVerifyArtifact('not_accepted_rejected', 'invalid_proposal', `Verifies-manager recommendation ${manager.recommendation ?? 'none'} cannot accept verify contract for do handoff.`, 'Ask verifies-manager to submit a close_stage recommendation after review blockers are resolved.');
2546
- }
2547
- const reviewByRef = manager.reviewRef
2548
- ? input.registeredArtifacts.find((record) => record.kind === 'verifies_review' && record.ref === manager.reviewRef?.ref) ?? null
2549
- : null;
2550
- if (reviewByRef && manager.reviewHash !== reviewByRef.hash) {
2551
- return rejectedVerifyArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Verifies-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh verifies-manager closure artifact so reviewRef/reviewHash point at the registered review artifact.');
2552
- }
2553
- const approvedReview = findStageReviewForManager(input.registeredArtifacts, manager, 'verifies_review');
2554
- if (!approvedReview) {
2555
- return rejectedVerifyArtifact('not_accepted_missing_review', 'missing_required_review', 'Ready verifies closure must include a registered verifies-reviewer artifact referenced by verifies-manager.', 'Ask verifies-reviewer to write .sdd/runs/<branch>/verifies/verifies-review-vN.md and ask verifies-manager to reference that review hash.');
2556
- }
2557
- if (approvedReview.verdict !== 'approved' || approvedReview.blockingCount !== 0) {
2558
- return rejectedVerifyArtifact('not_accepted_missing_review', 'missing_required_review', `Verifies-reviewer verdict ${approvedReview.verdict ?? 'none'} with ${approvedReview.blockingCount ?? 0} blockers cannot accept verify contract.`, 'Resolve review blockers and register an approved verifies-reviewer artifact before closure.');
2559
- }
2560
- if (manager.targetRef?.kind !== 'document' || manager.targetRef.ref !== expectedRef || approvedReview.targetRef?.kind !== 'document' || approvedReview.targetRef.ref !== expectedRef) {
2561
- return rejectedVerifyArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready verifies closure must reference reviewed ${expectedRef} as the canonical verify contract.`, 'Refresh review and manager artifacts so targetRef points at specs/<branch>/verify.md.');
2562
- }
2563
- const verifyPath = path.join(projectRoot, 'specs', input.partition, 'verify.md');
2564
- const content = await readOptionalText(verifyPath);
2565
- if (content === null) {
2566
- return rejectedVerifyArtifact('not_accepted_missing_verify', 'missing_refs', `Reviewed canonical verify artifact is missing at ${expectedRef}.`, 'Produce and review specs/<branch>/verify.md before requesting runtime closure.');
2567
- }
2568
- if (isManagedStarterSpec(content)) {
2569
- return rejectedVerifyArtifact('not_accepted_starter_verify', 'invalid_proposal', `Canonical verify artifact at ${expectedRef} is still the managed starter document.`, 'Replace starter verify.md with a reviewed verification contract before closure.');
2570
- }
2571
- const verifyHash = hashDocumentContent(content);
2572
- const expectedHashes = [manager.targetHash, approvedReview.targetHash, manager.targetRef.hash, approvedReview.targetRef.hash].filter((hash) => Boolean(hash));
2573
- const mismatchedHash = expectedHashes.find((hash) => hash !== verifyHash);
2574
- if (mismatchedHash) {
2575
- return rejectedVerifyArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed verify hash mismatch for ${expectedRef}: expected ${mismatchedHash}, actual ${verifyHash}.`, 'Refresh verifies-reviewer and verifies-manager artifacts with the current verify.md hash before closure.');
2576
- }
2577
- const inspection = await inspectVerifyContract(projectRoot, { branch: input.partition, branchSource: 'cli_option' });
2578
- const blockingIssue = inspection.issues.find((issue) => issue.level === 'FAIL')
2579
- ?? inspection.issues.find((issue) => issue.field === 'tasks');
2580
- if (blockingIssue) {
2581
- return rejectedVerifyArtifact('not_accepted_incomplete_coverage', 'invalid_proposal', blockingIssue.message, blockingIssue.action);
2281
+ return rejectedExecuteArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh tasks-stage closure and provide a fresh tasks -> execute handoff before execute closure.');
2582
2282
  }
2283
+ return validateExecuteProjectionReadiness(projectRoot, input.partition, input.acceptedTasksHandoff);
2284
+ }
2285
+ async function validateExecuteProjectionReadiness(projectRoot, partition, acceptedTasksHandoff) {
2286
+ const acceptedTasksRef = acceptedTasksRefFromExecuteHandoff(acceptedTasksHandoff);
2287
+ if (!acceptedTasksRef?.hash) {
2288
+ return rejectedExecuteArtifact('not_accepted_missing_upstream', 'missing_refs', 'Execute close requires a tasks -> execute handoff carrying accepted tasks ref/hash.', 'Refresh tasks-stage closure before requesting execute close.');
2289
+ }
2290
+ const [projectionRecords, dependencyGraphEnvelope] = await Promise.all([
2291
+ listRuntimeProjections(projectRoot, [TASK_UNIT_PROJECTION_TYPE, EXECUTION_LANE_PROJECTION_TYPE]),
2292
+ readTaskDependencyGraphProjection(projectRoot, partition)
2293
+ ]);
2294
+ if (!dependencyGraphEnvelope || dependencyGraphEnvelope.payload.tasksHash !== acceptedTasksRef.hash) {
2295
+ return rejectedExecuteArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Execute dependency graph must be derived from accepted ${acceptedTasksRef.ref}.`, 'Rebuild execute task projections from the accepted tasks ref/hash before closing execute.');
2296
+ }
2297
+ const taskUnits = projectionRecords
2298
+ .filter((record) => record.projectionType === TASK_UNIT_PROJECTION_TYPE && record.scopeKey.startsWith(`${partition}:`))
2299
+ .map((record) => runtimeProjectionPayload(record.payload))
2300
+ .filter((unit) => Boolean(unit))
2301
+ .filter((unit) => unit.sourceRef.ref === acceptedTasksRef.ref && unit.sourceRef.hash === acceptedTasksRef.hash);
2302
+ if (taskUnits.length === 0) {
2303
+ return rejectedExecuteArtifact('not_accepted_wrong_ref', 'missing_refs', `No TaskUnitProjection records match accepted ${acceptedTasksRef.ref}.`, 'Rebuild execute task projections from the accepted tasks ref/hash before closing execute.');
2304
+ }
2305
+ const executionLanes = projectionRecords
2306
+ .filter((record) => record.projectionType === EXECUTION_LANE_PROJECTION_TYPE && record.scopeKey.startsWith(`${partition}:`))
2307
+ .map((record) => runtimeProjectionPayload(record.payload))
2308
+ .filter((lane) => Boolean(lane));
2309
+ const laneEvidenceRefs = executionLanes.map((lane) => ({ kind: 'projection', ref: `${EXECUTION_LANE_PROJECTION_TYPE}:${executionLaneScopeKey(partition, lane.laneId)}` }));
2310
+ const invalidTaskIds = uniqueStrings([...dependencyGraphEnvelope.payload.invalidTaskIds, ...taskUnits.filter((unit) => unit.dependencyState === 'invalid').map((unit) => unit.taskId)]);
2311
+ if (invalidTaskIds.length > 0) {
2312
+ return rejectedExecuteArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Execute task projections contain invalid task units: ${invalidTaskIds.join(', ')}.`, 'Repair accepted tasks.md and rebuild task projections before closing execute.');
2313
+ }
2314
+ const implementationUnits = taskUnits.filter((unit) => unit.unit.agentRouting.board === 'implementation');
2315
+ const validationUnits = taskUnits.filter((unit) => unit.unit.agentRouting.board === 'validation');
2316
+ if (implementationUnits.length === 0) {
2317
+ return rejectedExecuteArtifact('not_accepted_missing_implementation', 'missing_refs', 'Execute close requires at least one implementation-board task unit from accepted tasks.md.', 'Route accepted implementation tasks before closing execute.');
2318
+ }
2319
+ if (validationUnits.length === 0) {
2320
+ return rejectedExecuteArtifact('not_accepted_missing_validation', 'missing_refs', 'Execute close requires at least one validation-board task unit from accepted tasks.md.', 'Route implementation validation and goal validation tasks before closing execute.');
2321
+ }
2322
+ const incompleteImplementation = implementationUnits.filter((unit) => !isImplementationComplete(unit)).map((unit) => unit.taskId);
2323
+ if (incompleteImplementation.length > 0) {
2324
+ return rejectedExecuteArtifact('not_accepted_missing_implementation', 'missing_refs', `Implementation board is not complete for task units: ${incompleteImplementation.join(', ')}.`, 'Run implementation/review/debug lanes until implementation task units are implemented or validated before execute close.');
2325
+ }
2326
+ const openCheckpointIds = taskUnits.filter((unit) => unit.checkpointState === 'open' || unit.checkpointState === 'locked').map((unit) => `${unit.taskId}:checkpoint`);
2327
+ if (openCheckpointIds.length > 0) {
2328
+ return rejectedExecuteArtifact('not_accepted_missing_checkpoint', 'invalid_proposal', `Execute checkpoints are still open: ${openCheckpointIds.join(', ')}.`, 'Satisfy or resolve execute checkpoints before closing execute.');
2329
+ }
2330
+ const incompleteValidation = validationUnits.filter((unit) => !isValidationComplete(unit)).map((unit) => unit.taskId);
2331
+ if (incompleteValidation.length > 0) {
2332
+ return rejectedExecuteArtifact('not_accepted_missing_validation', 'missing_refs', `Validation board is not complete for task units: ${incompleteValidation.join(', ')}.`, 'Run validation and goal-validation lanes until validation task units are validated before execute close.');
2333
+ }
2334
+ const acceptedExecuteRef = {
2335
+ kind: 'projection',
2336
+ ref: `${TASK_DEPENDENCY_GRAPH_PROJECTION_TYPE}:${taskDependencyGraphScopeKey(partition)}`,
2337
+ hash: dependencyGraphEnvelope.payload.tasksHash
2338
+ };
2583
2339
  return {
2584
- acceptedVerifyRef: { kind: 'document', ref: expectedRef, hash: verifyHash },
2585
- verifyAcceptanceStatus: 'accepted',
2586
- verifyHash,
2587
- verifyContractHash: hashSemanticDocument(content),
2588
- reasons: [`Runtime accepted reviewed canonical verify artifact ${expectedRef}.`]
2340
+ acceptedExecuteRef,
2341
+ executeAcceptanceStatus: 'accepted',
2342
+ laneEvidenceRefs,
2343
+ reasons: [`Runtime accepted execute task/lane projections for ${acceptedTasksRef.ref}.`]
2589
2344
  };
2590
2345
  }
2591
2346
  async function validateAcceptedDoArtifact(projectRoot, input) {
@@ -2599,46 +2354,46 @@ async function validateAcceptedDoArtifact(projectRoot, input) {
2599
2354
  };
2600
2355
  }
2601
2356
  if (input.blocked) {
2602
- return rejectedDoArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks do closure.', 'Resolve lifecycle blockers before requesting do-stage closure.', 'runtime-blocked');
2357
+ return rejectedDoArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks execute closure.', 'Resolve lifecycle blockers before requesting execute closure.', 'runtime-blocked');
2603
2358
  }
2604
2359
  if (!latestValidatedStageCollaborationContract(input.registeredCollaborationContracts)) {
2605
- return rejectedDoArtifact('not_accepted_wrong_ref', 'missing_refs', 'Ready do closure must be backed by a validated do StageCollaborationContract.', 'Ask do-manager to write .sdd/runs/<branch>/do/do-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2360
+ return rejectedDoArtifact('not_accepted_wrong_ref', 'missing_refs', 'Ready execute implementation closure must be backed by a validated execute StageCollaborationContract.', 'Ask execute-manager to write .sdd/runs/<branch>/execute/execute-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2606
2361
  }
2607
- const upstreamIssue = await validateAcceptedVerifyHandoff(projectRoot, input.partition, input.acceptedVerifyHandoff);
2362
+ const upstreamIssue = await validateAcceptedTasksExecuteHandoff(projectRoot, input.partition, input.acceptedTasksHandoff);
2608
2363
  if (upstreamIssue) {
2609
- return rejectedDoArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh verifies-stage closure and provide a fresh verifies -> do handoff before do closure.');
2364
+ return rejectedDoArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh tasks closure and provide a fresh tasks -> execute handoff before execute closure.');
2610
2365
  }
2611
2366
  const implementation = latestStageArtifact(input.registeredArtifacts, 'implementation_evidence');
2612
2367
  if (!implementation) {
2613
- return rejectedDoArtifact('not_accepted_missing_implementation', 'missing_refs', 'Ready do closure must be backed by a registered implementer evidence artifact.', 'Ask implementer to write .sdd/runs/<branch>/do/implementation-vN.md and register it before closure.');
2368
+ return rejectedDoArtifact('not_accepted_missing_implementation', 'missing_refs', 'Ready execute implementation closure must be backed by a registered implementer evidence artifact.', 'Ask implementer to write .sdd/runs/<branch>/execute/implementation-vN.md and register it before closure.');
2614
2369
  }
2615
2370
  const manager = latestStageArtifact(input.registeredArtifacts, 'manager_closure_request');
2616
2371
  if (!manager) {
2617
- return rejectedDoArtifact('not_accepted_wrong_ref', 'missing_refs', 'Ready do closure must be backed by a registered do-manager closure artifact.', 'Ask do-manager to write .sdd/runs/<branch>/do/do-manager-vN.md and register it before closure.');
2372
+ return rejectedDoArtifact('not_accepted_wrong_ref', 'missing_refs', 'Ready execute implementation closure must be backed by a registered execute-manager closure artifact.', 'Ask execute-manager to write .sdd/runs/<branch>/execute/execute-manager-vN.md and register it before closure.');
2618
2373
  }
2619
2374
  if (manager.recommendation !== 'close_stage') {
2620
- return rejectedDoArtifact('not_accepted_rejected', 'invalid_proposal', `Do-manager recommendation ${manager.recommendation ?? 'none'} cannot accept implementation state for test handoff.`, 'Ask do-manager to submit a close_stage recommendation after review blockers are resolved.');
2375
+ return rejectedDoArtifact('not_accepted_rejected', 'invalid_proposal', `Execute-manager recommendation ${manager.recommendation ?? 'none'} cannot accept implementation state for execute validation handoff.`, 'Ask execute-manager to submit a close_stage recommendation after review blockers are resolved.');
2621
2376
  }
2622
2377
  const reviewByRef = manager.reviewRef
2623
2378
  ? input.registeredArtifacts.find((record) => record.kind === 'code_review' && record.ref === manager.reviewRef?.ref) ?? null
2624
2379
  : null;
2625
2380
  if (reviewByRef && manager.reviewHash !== reviewByRef.hash) {
2626
- return rejectedDoArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Do-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh do-manager closure artifact so reviewRef/reviewHash point at the registered code review artifact.');
2381
+ return rejectedDoArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Execute-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh execute-manager closure artifact so reviewRef/reviewHash point at the registered code review artifact.');
2627
2382
  }
2628
2383
  const approvedReview = findStageReviewForManager(input.registeredArtifacts, manager, 'code_review');
2629
2384
  if (!approvedReview) {
2630
- return rejectedDoArtifact('not_accepted_missing_review', 'missing_required_review', 'Ready do closure must include a registered code-reviewer artifact referenced by do-manager.', 'Ask code-reviewer to write .sdd/runs/<branch>/do/code-review-vN.md and ask do-manager to reference that review hash.');
2385
+ return rejectedDoArtifact('not_accepted_missing_review', 'missing_required_review', 'Ready execute implementation closure must include a registered code-reviewer artifact referenced by execute-manager.', 'Ask code-reviewer to write .sdd/runs/<branch>/execute/code-review-vN.md and ask execute-manager to reference that review hash.');
2631
2386
  }
2632
2387
  if (approvedReview.verdict !== 'approved' || approvedReview.blockingCount !== 0) {
2633
2388
  return rejectedDoArtifact('not_accepted_missing_review', 'missing_required_review', `Code-reviewer verdict ${approvedReview.verdict ?? 'none'} with ${approvedReview.blockingCount ?? 0} blockers cannot accept implementation state.`, 'Resolve review blockers and register an approved code-reviewer artifact before closure.');
2634
2389
  }
2635
2390
  if (manager.targetRef?.kind !== 'artifact' || manager.targetRef.ref !== implementation.ref || approvedReview.targetRef?.kind !== 'artifact' || approvedReview.targetRef.ref !== implementation.ref) {
2636
- return rejectedDoArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready do closure must reference reviewed ${implementation.ref} as the implementation evidence artifact.`, 'Refresh code-reviewer and do-manager artifacts so targetRef points at the implementation evidence artifact.');
2391
+ return rejectedDoArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready execute implementation closure must reference reviewed ${implementation.ref} as the implementation evidence artifact.`, 'Refresh code-reviewer and execute-manager artifacts so targetRef points at the implementation evidence artifact.');
2637
2392
  }
2638
2393
  const expectedHashes = [manager.targetHash, approvedReview.targetHash, manager.targetRef.hash, approvedReview.targetRef.hash].filter((hash) => Boolean(hash));
2639
2394
  const mismatchedHash = expectedHashes.find((hash) => hash !== implementation.hash);
2640
2395
  if (mismatchedHash) {
2641
- return rejectedDoArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed implementation evidence hash mismatch for ${implementation.ref}: expected ${mismatchedHash}, actual ${implementation.hash}.`, 'Refresh code-reviewer and do-manager artifacts with the current implementation evidence hash before closure.');
2396
+ return rejectedDoArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed implementation evidence hash mismatch for ${implementation.ref}: expected ${mismatchedHash}, actual ${implementation.hash}.`, 'Refresh code-reviewer and execute-manager artifacts with the current implementation evidence hash before closure.');
2642
2397
  }
2643
2398
  const changedFileParse = parseImplementationChangedFileRefs(implementation);
2644
2399
  if (changedFileParse.issue) {
@@ -2647,11 +2402,11 @@ async function validateAcceptedDoArtifact(projectRoot, input) {
2647
2402
  const changedFileRefs = changedFileParse.refs;
2648
2403
  const boundaryIssue = validateAllowedChangedFileRefs(changedFileRefs, input.allowedChangedFileRefs);
2649
2404
  if (boundaryIssue) {
2650
- return rejectedDoArtifact('not_accepted_boundary_violation', 'invalid_proposal', boundaryIssue, 'Restrict do-stage implementation evidence to the task boundary or update the allowed changed-file refs.');
2405
+ return rejectedDoArtifact('not_accepted_boundary_violation', 'invalid_proposal', boundaryIssue, 'Restrict execute implementation evidence to the task boundary or update the allowed changed-file refs.');
2651
2406
  }
2652
2407
  const changedFileHashIssue = await validateChangedFileHashes(projectRoot, changedFileRefs);
2653
2408
  if (changedFileHashIssue) {
2654
- return rejectedDoArtifact('not_accepted_hash_mismatch', 'invalid_proposal', changedFileHashIssue, 'Refresh implementation, code-reviewer, and do-manager artifacts with current changed-file hashes before closure.');
2409
+ return rejectedDoArtifact('not_accepted_hash_mismatch', 'invalid_proposal', changedFileHashIssue, 'Refresh implementation, code-reviewer, and execute-manager artifacts with current changed-file hashes before closure.');
2655
2410
  }
2656
2411
  return {
2657
2412
  acceptedImplementationRef: { kind: 'artifact', ref: implementation.ref, hash: implementation.hash },
@@ -2671,146 +2426,146 @@ async function validateAcceptedTestArtifact(projectRoot, input) {
2671
2426
  };
2672
2427
  }
2673
2428
  if (input.blocked) {
2674
- return rejectedTestArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks test closure.', 'Resolve lifecycle blockers before requesting test-stage closure.', 'runtime-blocked');
2429
+ return rejectedTestArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks execute validation closure.', 'Resolve lifecycle blockers before requesting execute validation closure.', 'runtime-blocked');
2675
2430
  }
2676
2431
  if (!latestValidatedStageCollaborationContract(input.registeredCollaborationContracts)) {
2677
- return rejectedTestArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready test closure must be backed by a validated test StageCollaborationContract.', 'Ask test-manager to write .sdd/runs/<branch>/test/test-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2432
+ return rejectedTestArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready execute validation closure must be backed by a validated execute StageCollaborationContract.', 'Ask execute-manager to write .sdd/runs/<branch>/execute/validation-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2678
2433
  }
2679
2434
  const upstreamIssue = await validateAcceptedDoHandoff(projectRoot, input.partition, input.acceptedDoHandoff);
2680
2435
  if (upstreamIssue) {
2681
- return rejectedTestArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh do-stage closure and provide a fresh do -> test handoff before test closure.');
2436
+ return rejectedTestArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh execute implementation closure before execute validation closure.');
2682
2437
  }
2683
2438
  const execution = latestStageArtifact(input.registeredArtifacts, 'test_execution');
2684
2439
  if (!execution) {
2685
- return rejectedTestArtifact('not_accepted_missing_execution', 'missing_refs', 'Ready test closure must be backed by a registered test-runner execution artifact.', 'Ask test-runner to write .sdd/runs/<branch>/test/test-execution-vN.md and register it before closure.');
2440
+ return rejectedTestArtifact('not_accepted_missing_execution', 'missing_refs', 'Ready execute validation closure must be backed by a registered validation execution artifact.', 'Ask validator to write .sdd/runs/<branch>/execute/test-execution-vN.md and register it before closure.');
2686
2441
  }
2687
2442
  const validation = latestStageArtifact(input.registeredArtifacts, 'validation_evidence');
2688
2443
  if (!validation) {
2689
- return rejectedTestArtifact('not_accepted_missing_validation', 'missing_refs', 'Ready test closure must be backed by a registered validator evidence artifact.', 'Ask validator to write .sdd/runs/<branch>/test/validation-vN.md and register it before closure.');
2444
+ return rejectedTestArtifact('not_accepted_missing_validation', 'missing_refs', 'Ready execute validation closure must be backed by a registered validator evidence artifact.', 'Ask validator to write .sdd/runs/<branch>/execute/validation-vN.md and register it before closure.');
2690
2445
  }
2691
2446
  const executionStatus = execution.frontmatter.status;
2692
2447
  const executionExitCode = execution.frontmatter.exitCode;
2693
2448
  if (executionStatus !== 'passed' || executionExitCode !== 0) {
2694
- return rejectedTestArtifact('not_accepted_failed_tests', 'invalid_proposal', `Test execution ${execution.ref} status ${String(executionStatus)} with exitCode ${String(executionExitCode)} cannot close test stage.`, 'Rerun failing test commands and register passing test execution evidence before closure.');
2449
+ return rejectedTestArtifact('not_accepted_failed_tests', 'invalid_proposal', `Validation execution ${execution.ref} status ${String(executionStatus)} with exitCode ${String(executionExitCode)} cannot close execute validation.`, 'Rerun failing validation commands and register passing validation execution evidence before closure.');
2695
2450
  }
2696
2451
  const validationExecutionRef = executionRefFromValidation(validation);
2697
2452
  if (validationExecutionRef !== execution.ref) {
2698
- return rejectedTestArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Validation evidence ${validation.ref} must reference execution evidence ${execution.ref}.`, 'Refresh validation evidence so executionRef points at the registered test execution artifact.');
2453
+ return rejectedTestArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Validation evidence ${validation.ref} must reference execution evidence ${execution.ref}.`, 'Refresh validation evidence so executionRef points at the registered validation execution artifact.');
2699
2454
  }
2700
2455
  const validationExecutionHash = validation.frontmatter.executionHash;
2701
2456
  if (validationExecutionHash !== execution.hash) {
2702
- return rejectedTestArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Validation evidence execution hash mismatch for ${execution.ref}: expected ${String(validationExecutionHash)}, actual ${execution.hash}.`, 'Refresh validation evidence with the current test execution hash before closure.');
2457
+ return rejectedTestArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Validation evidence execution hash mismatch for ${execution.ref}: expected ${String(validationExecutionHash)}, actual ${execution.hash}.`, 'Refresh validation evidence with the current validation execution hash before closure.');
2703
2458
  }
2704
2459
  if (validation.frontmatter.status !== 'passed') {
2705
- return rejectedTestArtifact('not_accepted_failed_tests', 'invalid_proposal', `Validation evidence ${validation.ref} status ${String(validation.frontmatter.status)} cannot close test stage.`, 'Resolve validation failures and register passing validation evidence before closure.');
2460
+ return rejectedTestArtifact('not_accepted_failed_tests', 'invalid_proposal', `Validation evidence ${validation.ref} status ${String(validation.frontmatter.status)} cannot close execute validation.`, 'Resolve validation failures and register passing validation evidence before closure.');
2706
2461
  }
2707
2462
  if (validation.frontmatter.acceptanceMapped !== true) {
2708
- return rejectedTestArtifact('not_accepted_unmapped_acceptance', 'invalid_proposal', `Validation evidence ${validation.ref} must declare acceptanceMapped: true.`, 'Map validation evidence to accepted task/verify criteria before requesting test closure.');
2463
+ return rejectedTestArtifact('not_accepted_unmapped_acceptance', 'invalid_proposal', `Validation evidence ${validation.ref} must declare acceptanceMapped: true.`, 'Map validation evidence to accepted task/verify criteria before requesting execute validation closure.');
2709
2464
  }
2710
2465
  const manager = latestStageArtifact(input.registeredArtifacts, 'manager_closure_request');
2711
2466
  if (!manager) {
2712
- return rejectedTestArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready test closure must be backed by a registered test-manager closure artifact.', 'Ask test-manager to write .sdd/runs/<branch>/test/test-manager-vN.md and register it before closure.');
2467
+ return rejectedTestArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready execute validation closure must be backed by a registered execute-manager closure artifact.', 'Ask execute-manager to write .sdd/runs/<branch>/execute/validation-manager-vN.md and register it before closure.');
2713
2468
  }
2714
2469
  if (manager.recommendation !== 'close_stage') {
2715
- return rejectedTestArtifact('not_accepted_rejected', 'invalid_proposal', `Test-manager recommendation ${manager.recommendation ?? 'none'} cannot accept test evidence for goal-verify handoff.`, 'Ask test-manager to submit a close_stage recommendation after test blockers are resolved.');
2470
+ return rejectedTestArtifact('not_accepted_rejected', 'invalid_proposal', `Execute-manager recommendation ${manager.recommendation ?? 'none'} cannot accept validation evidence for execute evidence judgment.`, 'Ask execute-manager to submit a close_stage recommendation after validation blockers are resolved.');
2716
2471
  }
2717
2472
  const reviewByRef = manager.reviewRef
2718
2473
  ? input.registeredArtifacts.find((record) => record.kind === 'test_review' && record.ref === manager.reviewRef?.ref) ?? null
2719
2474
  : null;
2720
2475
  if (reviewByRef && manager.reviewHash !== reviewByRef.hash) {
2721
- return rejectedTestArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Test-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh test-manager closure artifact so reviewRef/reviewHash point at the registered test review artifact.');
2476
+ return rejectedTestArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Execute-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh execute-manager closure artifact so reviewRef/reviewHash point at the registered validation review artifact.');
2722
2477
  }
2723
2478
  const approvedReview = findStageReviewForManager(input.registeredArtifacts, manager, 'test_review');
2724
2479
  if (!approvedReview) {
2725
- return rejectedTestArtifact('not_accepted_missing_review', 'missing_required_review', 'Ready test closure must include a registered test-reviewer artifact referenced by test-manager.', 'Ask test-reviewer to write .sdd/runs/<branch>/test/test-review-vN.md and ask test-manager to reference that review hash.');
2480
+ return rejectedTestArtifact('not_accepted_missing_review', 'missing_required_review', 'Ready execute validation closure must include a registered validation-reviewer artifact referenced by execute-manager.', 'Ask validation-reviewer to write .sdd/runs/<branch>/execute/validation-review-vN.md and ask execute-manager to reference that review hash.');
2726
2481
  }
2727
2482
  if (approvedReview.verdict !== 'approved' || approvedReview.blockingCount !== 0) {
2728
- return rejectedTestArtifact('not_accepted_missing_review', 'missing_required_review', `Test-reviewer verdict ${approvedReview.verdict ?? 'none'} with ${approvedReview.blockingCount ?? 0} blockers cannot accept test evidence.`, 'Resolve review blockers and register an approved test-reviewer artifact before closure.');
2483
+ return rejectedTestArtifact('not_accepted_missing_review', 'missing_required_review', `Validation-reviewer verdict ${approvedReview.verdict ?? 'none'} with ${approvedReview.blockingCount ?? 0} blockers cannot accept validation evidence.`, 'Resolve review blockers and register an approved validation-reviewer artifact before closure.');
2729
2484
  }
2730
2485
  if (manager.targetRef?.kind !== 'artifact' || manager.targetRef.ref !== validation.ref || approvedReview.targetRef?.kind !== 'artifact' || approvedReview.targetRef.ref !== validation.ref) {
2731
- return rejectedTestArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready test closure must reference reviewed ${validation.ref} as the validation evidence artifact.`, 'Refresh test-reviewer and test-manager artifacts so targetRef points at the validation evidence artifact.');
2486
+ return rejectedTestArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready execute validation closure must reference reviewed ${validation.ref} as the validation evidence artifact.`, 'Refresh validation-reviewer and execute-manager artifacts so targetRef points at the validation evidence artifact.');
2732
2487
  }
2733
2488
  const expectedHashes = [manager.targetHash, approvedReview.targetHash, manager.targetRef.hash, approvedReview.targetRef.hash].filter((hash) => Boolean(hash));
2734
2489
  const mismatchedHash = expectedHashes.find((hash) => hash !== validation.hash);
2735
2490
  if (mismatchedHash) {
2736
- return rejectedTestArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed validation evidence hash mismatch for ${validation.ref}: expected ${mismatchedHash}, actual ${validation.hash}.`, 'Refresh test-reviewer and test-manager artifacts with the current validation evidence hash before closure.');
2491
+ return rejectedTestArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed validation evidence hash mismatch for ${validation.ref}: expected ${mismatchedHash}, actual ${validation.hash}.`, 'Refresh validation-reviewer and execute-manager artifacts with the current validation evidence hash before closure.');
2737
2492
  }
2738
2493
  return {
2739
2494
  acceptedTestEvidenceRef: { kind: 'artifact', ref: validation.ref, hash: validation.hash },
2740
2495
  testAcceptanceStatus: 'accepted',
2741
2496
  testEvidenceHash: validation.hash,
2742
- reasons: [`Runtime accepted reviewed test validation evidence ${validation.ref}.`]
2497
+ reasons: [`Runtime accepted reviewed execute validation evidence ${validation.ref}.`]
2743
2498
  };
2744
2499
  }
2745
- async function validateAcceptedGoalVerifyArtifact(projectRoot, input) {
2500
+ async function validateAcceptedEvidenceJudgmentArtifact(projectRoot, input) {
2746
2501
  if (!input.required) {
2747
2502
  return {
2748
- acceptedGoalVerificationRef: null,
2749
- goalVerifyAcceptanceStatus: 'not_required_noop',
2750
- goalVerificationHash: null,
2751
- reasons: ['Goal verification was not required by this lifecycle decision.'],
2503
+ acceptedEvidenceJudgmentRef: null,
2504
+ evidenceJudgmentAcceptanceStatus: 'not_required_noop',
2505
+ evidenceJudgmentHash: null,
2506
+ reasons: ['Evidence judgment was not required by this lifecycle decision.'],
2752
2507
  truthAlignment: null
2753
2508
  };
2754
2509
  }
2755
2510
  if (input.blocked) {
2756
- return rejectedGoalVerifyArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks goal-verify closure.', 'Resolve lifecycle blockers before requesting goal-verify-stage closure.', 'runtime-blocked');
2511
+ return rejectedEvidenceJudgmentArtifact('not_accepted_blocked', 'blocked_lifecycle', 'Lifecycle risk decision blocks execute evidence judgment closure.', 'Resolve lifecycle blockers before requesting execute evidence judgment closure.', 'runtime-blocked');
2757
2512
  }
2758
2513
  if (!latestValidatedStageCollaborationContract(input.registeredCollaborationContracts)) {
2759
- return rejectedGoalVerifyArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready goal-verify closure must be backed by a validated goal-verify StageCollaborationContract.', 'Ask goal-verify-manager to write .sdd/runs/<branch>/goal-verify/goal-verify-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2514
+ return rejectedEvidenceJudgmentArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready execute evidence judgment closure must be backed by a validated execute StageCollaborationContract.', 'Ask execute-manager to write .sdd/runs/<branch>/execute/evidence-judgment-collaboration-contract-vN.md within StageWorkOrder constraints before closure.');
2760
2515
  }
2761
2516
  const upstreamIssue = await validateAcceptedTestHandoff(projectRoot, input.partition, input.acceptedTestHandoff);
2762
2517
  if (upstreamIssue) {
2763
- return rejectedGoalVerifyArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh test-stage closure and provide a fresh test -> goal-verify handoff before goal-verify closure.');
2518
+ return rejectedEvidenceJudgmentArtifact('not_accepted_missing_upstream', 'missing_refs', upstreamIssue, 'Refresh execute validation closure before execute evidence judgment closure.');
2764
2519
  }
2765
- const verification = latestStageArtifact(input.registeredArtifacts, 'goal_verification');
2520
+ const verification = latestStageArtifact(input.registeredArtifacts, 'evidence_judgment');
2766
2521
  if (!verification) {
2767
- return rejectedGoalVerifyArtifact('not_accepted_missing_verification', 'missing_refs', 'Ready goal-verify closure must be backed by a registered goal-validator verification artifact.', 'Ask goal-validator to write .sdd/runs/<branch>/goal-verify/goal-verification-vN.md and register it before closure.');
2522
+ return rejectedEvidenceJudgmentArtifact('not_accepted_missing_verification', 'missing_refs', 'Ready execute evidence judgment closure must be backed by a registered evidence-judgment artifact.', 'Ask evidence-judgment agent to write .sdd/runs/<branch>/execute/evidence-judgment-vN.md and register it before closure.');
2768
2523
  }
2769
2524
  if (verification.frontmatter.status !== 'passed') {
2770
- return rejectedGoalVerifyArtifact('not_accepted_failed_verification', 'invalid_proposal', `Goal verification ${verification.ref} status ${String(verification.frontmatter.status)} cannot close goal-verify stage.`, 'Resolve goal verification failures and register passing goal verification evidence before closure.');
2525
+ return rejectedEvidenceJudgmentArtifact('not_accepted_failed_verification', 'invalid_proposal', `Evidence judgment ${verification.ref} status ${String(verification.frontmatter.status)} cannot close execute evidence judgment.`, 'Resolve evidence judgment failures and register passing evidence judgment evidence before closure.');
2771
2526
  }
2772
2527
  if (verification.frontmatter.coverageComplete !== true) {
2773
- return rejectedGoalVerifyArtifact('not_accepted_incomplete_coverage', 'invalid_proposal', `Goal verification ${verification.ref} must declare coverageComplete: true.`, 'Complete acceptance coverage before requesting goal-verify closure.');
2528
+ return rejectedEvidenceJudgmentArtifact('not_accepted_incomplete_coverage', 'invalid_proposal', `Evidence judgment ${verification.ref} must declare coverageComplete: true.`, 'Complete acceptance coverage before requesting execute evidence judgment closure.');
2774
2529
  }
2775
2530
  const durableGapCount = verification.frontmatter.durableGapCount;
2776
2531
  const openGapCount = verification.frontmatter.openGapCount;
2777
2532
  if ((typeof durableGapCount === 'number' && durableGapCount > 0) || (typeof openGapCount === 'number' && openGapCount > 0)) {
2778
- return rejectedGoalVerifyArtifact('not_accepted_open_gap', 'invalid_proposal', `Goal verification ${verification.ref} still declares open durable gaps.`, 'Resolve durable gaps before requesting goal-verify closure.');
2533
+ return rejectedEvidenceJudgmentArtifact('not_accepted_open_gap', 'invalid_proposal', `Evidence judgment ${verification.ref} still declares open durable gaps.`, 'Resolve durable gaps before requesting execute evidence judgment closure.');
2779
2534
  }
2780
2535
  const manager = latestStageArtifact(input.registeredArtifacts, 'manager_closure_request');
2781
2536
  if (!manager) {
2782
- return rejectedGoalVerifyArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready goal-verify closure must be backed by a registered goal-verify-manager closure artifact.', 'Ask goal-verify-manager to write .sdd/runs/<branch>/goal-verify/goal-verify-manager-vN.md and register it before closure.');
2537
+ return rejectedEvidenceJudgmentArtifact('not_accepted_wrong_ref', 'invalid_proposal', 'Ready execute evidence judgment closure must be backed by a registered execute-manager closure artifact.', 'Ask execute-manager to write .sdd/runs/<branch>/execute/evidence-judgment-manager-vN.md and register it before closure.');
2783
2538
  }
2784
2539
  if (manager.recommendation !== 'close_stage') {
2785
- return rejectedGoalVerifyArtifact('not_accepted_rejected', 'invalid_proposal', `Goal-verify-manager recommendation ${manager.recommendation ?? 'none'} cannot accept goal verification for truthAlignment and ship readiness.`, 'Ask goal-verify-manager to submit a close_stage recommendation after goal verification blockers are resolved.');
2540
+ return rejectedEvidenceJudgmentArtifact('not_accepted_rejected', 'invalid_proposal', `Execute-manager recommendation ${manager.recommendation ?? 'none'} cannot accept evidence judgment for truthAlignment and ship readiness.`, 'Ask execute-manager to submit a close_stage recommendation after evidence judgment blockers are resolved.');
2786
2541
  }
2787
2542
  const reviewByRef = manager.reviewRef
2788
- ? input.registeredArtifacts.find((record) => record.kind === 'goal_review' && record.ref === manager.reviewRef?.ref) ?? null
2543
+ ? input.registeredArtifacts.find((record) => record.kind === 'evidence_review' && record.ref === manager.reviewRef?.ref) ?? null
2789
2544
  : null;
2790
2545
  if (reviewByRef && manager.reviewHash !== reviewByRef.hash) {
2791
- return rejectedGoalVerifyArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Goal-verify-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh goal-verify-manager closure artifact so reviewRef/reviewHash point at the registered goal review artifact.');
2546
+ return rejectedEvidenceJudgmentArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Execute-manager review hash mismatch for ${reviewByRef.ref}: expected ${manager.reviewHash ?? 'none'}, actual ${reviewByRef.hash}.`, 'Refresh execute-manager closure artifact so reviewRef/reviewHash point at the registered evidence review artifact.');
2792
2547
  }
2793
- const approvedReview = findStageReviewForManager(input.registeredArtifacts, manager, 'goal_review');
2548
+ const approvedReview = findStageReviewForManager(input.registeredArtifacts, manager, 'evidence_review');
2794
2549
  if (!approvedReview) {
2795
- return rejectedGoalVerifyArtifact('not_accepted_missing_review', 'missing_required_review', 'Ready goal-verify closure must include a registered goal-reviewer artifact referenced by goal-verify-manager.', 'Ask goal-reviewer to write .sdd/runs/<branch>/goal-verify/goal-review-vN.md and ask goal-verify-manager to reference that review hash.');
2550
+ return rejectedEvidenceJudgmentArtifact('not_accepted_missing_review', 'missing_required_review', 'Ready execute evidence judgment closure must include a registered evidence-reviewer artifact referenced by execute-manager.', 'Ask evidence-reviewer to write .sdd/runs/<branch>/execute/evidence-review-vN.md and ask execute-manager to reference that review hash.');
2796
2551
  }
2797
2552
  if (approvedReview.verdict !== 'approved' || approvedReview.blockingCount !== 0) {
2798
- return rejectedGoalVerifyArtifact('not_accepted_missing_review', 'missing_required_review', `Goal-reviewer verdict ${approvedReview.verdict ?? 'none'} with ${approvedReview.blockingCount ?? 0} blockers cannot accept goal verification.`, 'Resolve review blockers and register an approved goal-reviewer artifact before closure.');
2553
+ return rejectedEvidenceJudgmentArtifact('not_accepted_missing_review', 'missing_required_review', `Evidence-reviewer verdict ${approvedReview.verdict ?? 'none'} with ${approvedReview.blockingCount ?? 0} blockers cannot accept evidence judgment.`, 'Resolve review blockers and register an approved evidence-reviewer artifact before closure.');
2799
2554
  }
2800
2555
  if (manager.targetRef?.kind !== 'artifact' || manager.targetRef.ref !== verification.ref || approvedReview.targetRef?.kind !== 'artifact' || approvedReview.targetRef.ref !== verification.ref) {
2801
- return rejectedGoalVerifyArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready goal-verify closure must reference reviewed ${verification.ref} as the goal verification artifact.`, 'Refresh goal-reviewer and goal-verify-manager artifacts so targetRef points at the goal verification artifact.');
2556
+ return rejectedEvidenceJudgmentArtifact('not_accepted_wrong_ref', 'invalid_proposal', `Ready execute evidence judgment closure must reference reviewed ${verification.ref} as the evidence judgment artifact.`, 'Refresh evidence-reviewer and execute-manager artifacts so targetRef points at the evidence judgment artifact.');
2802
2557
  }
2803
2558
  const expectedHashes = [manager.targetHash, approvedReview.targetHash, manager.targetRef.hash, approvedReview.targetRef.hash].filter((hash) => Boolean(hash));
2804
2559
  const mismatchedHash = expectedHashes.find((hash) => hash !== verification.hash);
2805
2560
  if (mismatchedHash) {
2806
- return rejectedGoalVerifyArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed goal verification hash mismatch for ${verification.ref}: expected ${mismatchedHash}, actual ${verification.hash}.`, 'Refresh goal-reviewer and goal-verify-manager artifacts with the current goal verification hash before closure.');
2561
+ return rejectedEvidenceJudgmentArtifact('not_accepted_hash_mismatch', 'invalid_proposal', `Reviewed evidence judgment hash mismatch for ${verification.ref}: expected ${mismatchedHash}, actual ${verification.hash}.`, 'Refresh evidence-reviewer and execute-manager artifacts with the current evidence judgment hash before closure.');
2807
2562
  }
2808
2563
  return {
2809
- acceptedGoalVerificationRef: { kind: 'artifact', ref: verification.ref, hash: verification.hash },
2810
- goalVerifyAcceptanceStatus: 'accepted',
2811
- goalVerificationHash: verification.hash,
2812
- reasons: [`Runtime accepted reviewed goal verification evidence ${verification.ref}.`],
2813
- truthAlignment: parseGoalVerifyTruthAlignment(verification)
2564
+ acceptedEvidenceJudgmentRef: { kind: 'artifact', ref: verification.ref, hash: verification.hash },
2565
+ evidenceJudgmentAcceptanceStatus: 'accepted',
2566
+ evidenceJudgmentHash: verification.hash,
2567
+ reasons: [`Runtime accepted reviewed evidence judgment evidence ${verification.ref}.`],
2568
+ truthAlignment: parseEvidenceJudgmentTruthAlignment(verification)
2814
2569
  };
2815
2570
  }
2816
2571
  async function validateAcceptedShipReadinessArtifact(projectRoot, input) {
@@ -2831,7 +2586,7 @@ async function validateAcceptedShipReadinessArtifact(projectRoot, input) {
2831
2586
  }
2832
2587
  const truthAlignmentIssue = await validateAcceptedTruthAlignment(projectRoot, input.partition, input.truthAlignment);
2833
2588
  if (truthAlignmentIssue) {
2834
- return rejectedShipReadinessArtifact('not_accepted_missing_upstream', 'missing_refs', truthAlignmentIssue, 'Refresh goal-verify closure so runtime records an aligned truthAlignment projection before ship closure.');
2589
+ return rejectedShipReadinessArtifact('not_accepted_missing_upstream', 'missing_refs', truthAlignmentIssue, 'Refresh execute evidence judgment closure so runtime records an aligned truthAlignment projection before ship closure.');
2835
2590
  }
2836
2591
  const authorityIssue = validateNoRuntimeAuthorityAttempts(input.registeredArtifacts);
2837
2592
  if (authorityIssue) {
@@ -2889,6 +2644,7 @@ async function validateAcceptedShipReadinessArtifact(projectRoot, input) {
2889
2644
  };
2890
2645
  }
2891
2646
  async function validateAcceptedPlanHandoff(projectRoot, partition, handoff) {
2647
+ const expectedSpecRef = `specs/${partition}/spec.md`;
2892
2648
  const expectedPlanRef = `specs/${partition}/plan.md`;
2893
2649
  if (!handoff) {
2894
2650
  return 'Tasks closure requires a recorded plan -> tasks handoff.';
@@ -2896,6 +2652,19 @@ async function validateAcceptedPlanHandoff(projectRoot, partition, handoff) {
2896
2652
  if (handoff.fromStage !== 'plan' || handoff.toStage !== 'tasks' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2897
2653
  return 'Tasks closure requires a non-blocking plan -> tasks handoff.';
2898
2654
  }
2655
+ const acceptedSpecRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref === expectedSpecRef)
2656
+ ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref === expectedSpecRef);
2657
+ if (!acceptedSpecRef?.hash) {
2658
+ return `Plan -> tasks handoff must carry accepted ${expectedSpecRef} with a content hash.`;
2659
+ }
2660
+ const specContent = await readOptionalText(path.join(projectRoot, 'specs', partition, 'spec.md'));
2661
+ if (specContent === null) {
2662
+ return `Accepted upstream spec artifact is missing at ${expectedSpecRef}.`;
2663
+ }
2664
+ const currentSpecHash = hashDocumentContent(specContent);
2665
+ if (acceptedSpecRef.hash !== currentSpecHash) {
2666
+ return `Accepted upstream spec hash is stale for ${expectedSpecRef}: expected ${acceptedSpecRef.hash}, actual ${currentSpecHash}.`;
2667
+ }
2899
2668
  const acceptedPlanRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref === expectedPlanRef)
2900
2669
  ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref === expectedPlanRef);
2901
2670
  if (!acceptedPlanRef?.hash) {
@@ -2911,18 +2680,55 @@ async function validateAcceptedPlanHandoff(projectRoot, partition, handoff) {
2911
2680
  }
2912
2681
  return null;
2913
2682
  }
2683
+ async function validateAcceptedExecuteTasksHandoff(projectRoot, partition, handoff) {
2684
+ const expectedTasksRef = `specs/${partition}/tasks.md`;
2685
+ if (!handoff) {
2686
+ return 'Execute closure requires a recorded tasks -> execute handoff.';
2687
+ }
2688
+ if (handoff.fromStage !== 'tasks' || handoff.toStage !== 'execute' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2689
+ return 'Execute closure requires a non-blocking tasks -> execute handoff.';
2690
+ }
2691
+ const acceptedTasksRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref === expectedTasksRef)
2692
+ ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref === expectedTasksRef);
2693
+ if (!acceptedTasksRef?.hash) {
2694
+ return `Tasks -> execute handoff must carry accepted ${expectedTasksRef} with a content hash.`;
2695
+ }
2696
+ const tasksContent = await readOptionalText(path.join(projectRoot, 'specs', partition, 'tasks.md'));
2697
+ if (tasksContent === null) {
2698
+ return `Accepted upstream tasks artifact is missing at ${expectedTasksRef}.`;
2699
+ }
2700
+ const currentTasksHash = hashDocumentContent(tasksContent);
2701
+ if (acceptedTasksRef.hash !== currentTasksHash) {
2702
+ return `Accepted upstream tasks hash is stale for ${expectedTasksRef}: expected ${acceptedTasksRef.hash}, actual ${currentTasksHash}.`;
2703
+ }
2704
+ return null;
2705
+ }
2706
+ function acceptedTasksRefFromExecuteHandoff(handoff) {
2707
+ if (!handoff) {
2708
+ return null;
2709
+ }
2710
+ return handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref.endsWith('/tasks.md'))
2711
+ ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref.endsWith('/tasks.md'))
2712
+ ?? null;
2713
+ }
2714
+ function isImplementationComplete(unit) {
2715
+ return unit.executionState === 'implemented' || unit.executionState === 'validated' || unit.evidenceState === 'accepted';
2716
+ }
2717
+ function isValidationComplete(unit) {
2718
+ return unit.executionState === 'validated' || unit.evidenceState === 'accepted';
2719
+ }
2914
2720
  async function validateAcceptedTasksHandoff(projectRoot, partition, handoff) {
2915
2721
  const expectedTasksRef = `specs/${partition}/tasks.md`;
2916
2722
  if (!handoff) {
2917
- return 'Verifies closure requires a recorded tasks -> verifies handoff.';
2723
+ return 'Verification-design closure requires a recorded plan -> tasks handoff.';
2918
2724
  }
2919
- if (handoff.fromStage !== 'tasks' || handoff.toStage !== 'verifies' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2920
- return 'Verifies closure requires a non-blocking tasks -> verifies handoff.';
2725
+ if (handoff.fromStage !== 'plan' || handoff.toStage !== 'tasks' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2726
+ return 'Verification-design closure requires a non-blocking plan -> tasks handoff.';
2921
2727
  }
2922
2728
  const acceptedTasksRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref === expectedTasksRef)
2923
2729
  ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref === expectedTasksRef);
2924
2730
  if (!acceptedTasksRef?.hash) {
2925
- return `Tasks -> verifies handoff must carry accepted ${expectedTasksRef} with a content hash.`;
2731
+ return `Plan -> tasks handoff must carry accepted ${expectedTasksRef} with a content hash.`;
2926
2732
  }
2927
2733
  const tasksContent = await readOptionalText(path.join(projectRoot, 'specs', partition, 'tasks.md'));
2928
2734
  if (tasksContent === null) {
@@ -2934,54 +2740,54 @@ async function validateAcceptedTasksHandoff(projectRoot, partition, handoff) {
2934
2740
  }
2935
2741
  return null;
2936
2742
  }
2937
- async function validateAcceptedVerifyHandoff(projectRoot, partition, handoff) {
2938
- const expectedVerifyRef = `specs/${partition}/verify.md`;
2743
+ async function validateAcceptedTasksExecuteHandoff(projectRoot, partition, handoff) {
2744
+ const expectedTasksRef = `specs/${partition}/tasks.md`;
2939
2745
  if (!handoff) {
2940
- return 'Do closure requires a recorded verifies -> do handoff.';
2746
+ return 'Execute closure requires a recorded tasks -> execute handoff.';
2941
2747
  }
2942
- if (handoff.fromStage !== 'verifies' || handoff.toStage !== 'do' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2943
- return 'Do closure requires a non-blocking verifies -> do handoff.';
2748
+ if (handoff.fromStage !== 'tasks' || handoff.toStage !== 'execute' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2749
+ return 'Execute closure requires a non-blocking tasks -> execute handoff.';
2944
2750
  }
2945
- const acceptedVerifyRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref === expectedVerifyRef)
2946
- ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref === expectedVerifyRef);
2947
- if (!acceptedVerifyRef?.hash) {
2948
- return `Verifies -> do handoff must carry accepted ${expectedVerifyRef} with a content hash.`;
2751
+ const acceptedTasksRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'document' && inputRef.ref === expectedTasksRef)
2752
+ ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'document' && outputRef.ref === expectedTasksRef);
2753
+ if (!acceptedTasksRef?.hash) {
2754
+ return `Tasks -> execute handoff must carry accepted ${expectedTasksRef} with a content hash.`;
2949
2755
  }
2950
- const verifyContent = await readOptionalText(path.join(projectRoot, 'specs', partition, 'verify.md'));
2951
- if (verifyContent === null) {
2952
- return `Accepted upstream verify artifact is missing at ${expectedVerifyRef}.`;
2756
+ const tasksContent = await readOptionalText(path.join(projectRoot, 'specs', partition, 'tasks.md'));
2757
+ if (tasksContent === null) {
2758
+ return `Accepted upstream tasks artifact is missing at ${expectedTasksRef}.`;
2953
2759
  }
2954
- const currentVerifyHash = hashDocumentContent(verifyContent);
2955
- if (acceptedVerifyRef.hash !== currentVerifyHash) {
2956
- return `Accepted upstream verify hash is stale for ${expectedVerifyRef}: expected ${acceptedVerifyRef.hash}, actual ${currentVerifyHash}.`;
2760
+ const currentTasksHash = hashDocumentContent(tasksContent);
2761
+ if (acceptedTasksRef.hash !== currentTasksHash) {
2762
+ return `Accepted upstream tasks hash is stale for ${expectedTasksRef}: expected ${acceptedTasksRef.hash}, actual ${currentTasksHash}.`;
2957
2763
  }
2958
2764
  return null;
2959
2765
  }
2960
2766
  async function validateAcceptedDoHandoff(projectRoot, partition, handoff) {
2961
2767
  if (!handoff) {
2962
- return 'Test closure requires a recorded do -> test handoff.';
2768
+ return 'Validation lane closure requires a recorded execute -> ship handoff.';
2963
2769
  }
2964
- if (handoff.fromStage !== 'do' || handoff.toStage !== 'test' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2965
- return 'Test closure requires a non-blocking do -> test handoff.';
2770
+ if (handoff.fromStage !== 'execute' || handoff.toStage !== 'ship' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2771
+ return 'Validation lane closure requires a non-blocking execute -> ship handoff.';
2966
2772
  }
2967
- const acceptedImplementationRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'artifact' && inputRef.ref.startsWith(`.sdd/runs/${partition}/do/implementation-`))
2968
- ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'artifact' && outputRef.ref.startsWith(`.sdd/runs/${partition}/do/implementation-`));
2773
+ const acceptedImplementationRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'artifact' && inputRef.ref.startsWith(`.sdd/runs/${partition}/execute/implementation-`))
2774
+ ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'artifact' && outputRef.ref.startsWith(`.sdd/runs/${partition}/execute/implementation-`));
2969
2775
  if (!acceptedImplementationRef?.hash) {
2970
- return `Do -> test handoff must carry accepted .sdd/runs/${partition}/do/implementation-vN.md with a content hash.`;
2776
+ return `Execute -> ship handoff must carry accepted .sdd/runs/${partition}/execute/implementation-vN.md with a content hash.`;
2971
2777
  }
2972
2778
  return validateHandoffInputHashes(projectRoot, handoff.requiredInputRefs);
2973
2779
  }
2974
2780
  async function validateAcceptedTestHandoff(projectRoot, partition, handoff) {
2975
2781
  if (!handoff) {
2976
- return 'Goal-verify closure requires a recorded test -> goal-verify handoff.';
2782
+ return 'Evidence-judgment lane closure requires a recorded execute -> ship handoff.';
2977
2783
  }
2978
- if (handoff.fromStage !== 'test' || handoff.toStage !== 'goal-verify' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2979
- return 'Goal-verify closure requires a non-blocking test -> goal-verify handoff.';
2784
+ if (handoff.fromStage !== 'execute' || handoff.toStage !== 'ship' || handoff.status === 'blocked' || handoff.status === 'rejected') {
2785
+ return 'Evidence-judgment lane closure requires a non-blocking execute -> ship handoff.';
2980
2786
  }
2981
- const acceptedTestRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'artifact' && inputRef.ref.startsWith(`.sdd/runs/${partition}/test/validation-`))
2982
- ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'artifact' && outputRef.ref.startsWith(`.sdd/runs/${partition}/test/validation-`));
2787
+ const acceptedTestRef = handoff.requiredInputRefs.find((inputRef) => inputRef.kind === 'artifact' && inputRef.ref.startsWith(`.sdd/runs/${partition}/execute/validation-`))
2788
+ ?? handoff.outputRefs.find((outputRef) => outputRef.kind === 'artifact' && outputRef.ref.startsWith(`.sdd/runs/${partition}/execute/validation-`));
2983
2789
  if (!acceptedTestRef?.hash) {
2984
- return `Test -> goal-verify handoff must carry accepted .sdd/runs/${partition}/test/validation-vN.md with a content hash.`;
2790
+ return `Execute -> ship handoff must carry accepted .sdd/runs/${partition}/execute/validation-vN.md with a content hash.`;
2985
2791
  }
2986
2792
  return validateHandoffInputHashes(projectRoot, handoff.requiredInputRefs);
2987
2793
  }
@@ -3038,12 +2844,11 @@ function rejectedTasksArtifact(tasksAcceptanceStatus, reasonCode, explanation, r
3038
2844
  }
3039
2845
  };
3040
2846
  }
3041
- function rejectedVerifyArtifact(verifyAcceptanceStatus, reasonCode, explanation, requiredNextAction, fallbackRoute = 'revise-proposal') {
2847
+ function rejectedExecuteArtifact(executeAcceptanceStatus, reasonCode, explanation, requiredNextAction, fallbackRoute = 'revise-proposal') {
3042
2848
  return {
3043
- acceptedVerifyRef: null,
3044
- verifyAcceptanceStatus,
3045
- verifyHash: null,
3046
- verifyContractHash: null,
2849
+ acceptedExecuteRef: null,
2850
+ executeAcceptanceStatus,
2851
+ laneEvidenceRefs: [],
3047
2852
  reasons: [explanation],
3048
2853
  rejectionIssue: {
3049
2854
  reasonCode,
@@ -3082,11 +2887,11 @@ function rejectedTestArtifact(testAcceptanceStatus, reasonCode, explanation, req
3082
2887
  }
3083
2888
  };
3084
2889
  }
3085
- function rejectedGoalVerifyArtifact(goalVerifyAcceptanceStatus, reasonCode, explanation, requiredNextAction, fallbackRoute = 'revise-proposal') {
2890
+ function rejectedEvidenceJudgmentArtifact(evidenceJudgmentAcceptanceStatus, reasonCode, explanation, requiredNextAction, fallbackRoute = 'revise-proposal') {
3086
2891
  return {
3087
- acceptedGoalVerificationRef: null,
3088
- goalVerifyAcceptanceStatus,
3089
- goalVerificationHash: null,
2892
+ acceptedEvidenceJudgmentRef: null,
2893
+ evidenceJudgmentAcceptanceStatus,
2894
+ evidenceJudgmentHash: null,
3090
2895
  reasons: [explanation],
3091
2896
  truthAlignment: null,
3092
2897
  rejectionIssue: {
@@ -3097,7 +2902,7 @@ function rejectedGoalVerifyArtifact(goalVerifyAcceptanceStatus, reasonCode, expl
3097
2902
  }
3098
2903
  };
3099
2904
  }
3100
- function parseGoalVerifyTruthAlignment(verification) {
2905
+ function parseEvidenceJudgmentTruthAlignment(verification) {
3101
2906
  const status = enumFrontmatter(verification.frontmatter, 'truthAlignmentStatus', TRUTH_ALIGNMENT_STATUSES);
3102
2907
  const semanticImpact = enumFrontmatter(verification.frontmatter, 'semanticImpact', TRUTH_ALIGNMENT_SEMANTIC_IMPACTS);
3103
2908
  const ownerStage = enumFrontmatter(verification.frontmatter, 'ownerStage', TRUTH_ALIGNMENT_OWNER_STAGES);
@@ -3135,7 +2940,7 @@ function stageListFrontmatter(frontmatter, key) {
3135
2940
  if (values.length === 0) {
3136
2941
  return null;
3137
2942
  }
3138
- const allowed = new Set(['spec', 'plan', 'tasks', 'verifies', 'do', 'test', 'goal-verify', 'ship']);
2943
+ const allowed = new Set(['spec', 'plan', 'tasks', 'execute', 'ship']);
3139
2944
  return values.filter((value) => allowed.has(value));
3140
2945
  }
3141
2946
  function runtimeRefListFrontmatter(frontmatter, key) {
@@ -3202,10 +3007,10 @@ async function parseShipReleaseDocumentRef(projectRoot, partition, readiness) {
3202
3007
  }
3203
3008
  async function validateAcceptedTruthAlignment(projectRoot, partition, truthAlignment) {
3204
3009
  if (!truthAlignment) {
3205
- return 'Ship closure requires a recorded aligned truthAlignment projection from goal-verify.';
3010
+ return 'Ship closure requires a recorded aligned truthAlignment projection from execute.';
3206
3011
  }
3207
- if (truthAlignment.contract !== TRUTH_ALIGNMENT_CONTRACT || truthAlignment.sourceStage !== 'goal-verify') {
3208
- return 'Ship closure requires a valid goal-verify truthAlignment projection.';
3012
+ if (truthAlignment.contract !== TRUTH_ALIGNMENT_CONTRACT || truthAlignment.sourceStage !== 'execute') {
3013
+ return 'Ship closure requires a valid execute truthAlignment projection.';
3209
3014
  }
3210
3015
  if (truthAlignment.status !== 'aligned') {
3211
3016
  const reasons = truthAlignment.reasons.length > 0 ? `: ${truthAlignment.reasons.join('; ')}` : '';
@@ -3220,9 +3025,9 @@ async function validateAcceptedTruthAlignment(projectRoot, partition, truthAlign
3220
3025
  if (truthAlignment.invalidatesStages.includes('ship')) {
3221
3026
  return 'Ship closure requires truthAlignment that does not invalidate ship.';
3222
3027
  }
3223
- const acceptedGoalVerifyRef = truthAlignment.acceptedRealityRefs.find((ref) => ref.kind === 'artifact' && ref.ref.startsWith(`.sdd/runs/${partition}/goal-verify/goal-verification-`));
3224
- if (!acceptedGoalVerifyRef?.hash) {
3225
- return `TruthAlignment must carry accepted .sdd/runs/${partition}/goal-verify/goal-verification-vN.md with a content hash.`;
3028
+ const acceptedEvidenceJudgmentRef = truthAlignment.acceptedRealityRefs.find((ref) => ref.kind === 'artifact' && ref.ref.startsWith(`.sdd/runs/${partition}/execute/evidence-judgment-`));
3029
+ if (!acceptedEvidenceJudgmentRef?.hash) {
3030
+ return `TruthAlignment must carry accepted .sdd/runs/${partition}/execute/evidence-judgment-vN.md with a content hash.`;
3226
3031
  }
3227
3032
  return validateTruthAlignmentRefHashes(projectRoot, [...truthAlignment.declaredTruthRefs, ...truthAlignment.acceptedRealityRefs]);
3228
3033
  }
@@ -3376,7 +3181,7 @@ function validateAllowedChangedFileRefs(changedFileRefs, allowedChangedFileRefs)
3376
3181
  }
3377
3182
  }
3378
3183
  const outsideBoundary = changedFileRefs.find((ref) => !allowedExact.has(ref.ref) && !allowedPatterns.some((pattern) => pattern.test(ref.ref)));
3379
- return outsideBoundary ? `Changed file ${outsideBoundary.ref} is outside the allowed do-stage task boundary.` : null;
3184
+ return outsideBoundary ? `Changed file ${outsideBoundary.ref} is outside the allowed execute task boundary.` : null;
3380
3185
  }
3381
3186
  function normalizeChangedFilePattern(value) {
3382
3187
  const normalized = normalizePortablePath(value);
@@ -3454,7 +3259,7 @@ function buildPlanWorkflowHandoff(scope, decision, input) {
3454
3259
  };
3455
3260
  }
3456
3261
  function buildTasksClosureStageRun(scope, runId, workOrder, health, input) {
3457
- const status = health === 'ready_for_verifies'
3262
+ const status = health === 'ready_for_execute'
3458
3263
  ? 'completed'
3459
3264
  : health === 'no-op'
3460
3265
  ? 'skipped'
@@ -3478,94 +3283,12 @@ function buildTasksClosureStageRun(scope, runId, workOrder, health, input) {
3478
3283
  function buildTasksWorkflowHandoff(scope, decision, input) {
3479
3284
  return {
3480
3285
  contract: WORKFLOW_HANDOFF_CONTRACT_VERSION,
3481
- id: stableId('tasks-verifies-handoff', scope, 'closure', input.generatedAt),
3286
+ id: stableId('tasks-execute-handoff', scope, 'closure', input.generatedAt),
3482
3287
  scope,
3483
3288
  fromStage: 'tasks',
3484
- toStage: 'verifies',
3289
+ toStage: 'execute',
3485
3290
  fromAgent: TASKS_STAGE_MANAGER,
3486
- toAgent: 'verifies-stage-runtime',
3487
- status: decision.profile === 'blocked' || decision.approvalPolicy === 'blocked' ? 'blocked' : 'proposed',
3488
- outputRefs: input.outputRefs,
3489
- requiredInputRefs: input.requiredInputRefs,
3490
- riskDecisionRef: input.riskDecisionRef,
3491
- evidenceRefs: input.evidenceRefs,
3492
- openQuestions: [],
3493
- blockingGaps: [],
3494
- createdAt: input.generatedAt
3495
- };
3496
- }
3497
- function buildVerifiesClosureStageRun(scope, runId, workOrder, health, input) {
3498
- const status = health === 'ready_for_do'
3499
- ? 'completed'
3500
- : health === 'no-op'
3501
- ? 'skipped'
3502
- : 'blocked';
3503
- return {
3504
- contract: STAGE_RUN_CONTRACT_VERSION,
3505
- id: stableId('stage-run-verifies', scope, runId, input.generatedAt),
3506
- scope,
3507
- stage: 'verifies',
3508
- ownerAgent: workOrder?.stageManager ?? 'runtime',
3509
- coMainAgents: workOrder?.agentTeam ?? [],
3510
- status,
3511
- inputRefs: input.inputRefs,
3512
- outputRefs: input.outputRefs,
3513
- decisionRefs: input.decisionRefs,
3514
- blockingReasons: status === 'blocked' ? [input.rejectionReason ?? `Verifies adjudication health is ${health}.`] : [],
3515
- createdAt: input.generatedAt,
3516
- updatedAt: input.generatedAt
3517
- };
3518
- }
3519
- function buildVerifiesWorkflowHandoff(scope, decision, input) {
3520
- return {
3521
- contract: WORKFLOW_HANDOFF_CONTRACT_VERSION,
3522
- id: stableId('verifies-do-handoff', scope, 'closure', input.generatedAt),
3523
- scope,
3524
- fromStage: 'verifies',
3525
- toStage: 'do',
3526
- fromAgent: VERIFIES_STAGE_MANAGER,
3527
- toAgent: 'do-stage-runtime',
3528
- status: decision.profile === 'blocked' || decision.approvalPolicy === 'blocked' ? 'blocked' : 'proposed',
3529
- outputRefs: input.outputRefs,
3530
- requiredInputRefs: input.requiredInputRefs,
3531
- riskDecisionRef: input.riskDecisionRef,
3532
- evidenceRefs: input.evidenceRefs,
3533
- openQuestions: [],
3534
- blockingGaps: [],
3535
- createdAt: input.generatedAt
3536
- };
3537
- }
3538
- function buildDoClosureStageRun(scope, runId, workOrder, health, input) {
3539
- const status = health === 'ready_for_test'
3540
- ? 'completed'
3541
- : health === 'no-op'
3542
- ? 'skipped'
3543
- : 'blocked';
3544
- return {
3545
- contract: STAGE_RUN_CONTRACT_VERSION,
3546
- id: stableId('stage-run-do', scope, runId, input.generatedAt),
3547
- scope,
3548
- stage: 'do',
3549
- ownerAgent: workOrder?.stageManager ?? 'runtime',
3550
- coMainAgents: workOrder?.agentTeam ?? [],
3551
- status,
3552
- inputRefs: input.inputRefs,
3553
- outputRefs: input.outputRefs,
3554
- decisionRefs: input.decisionRefs,
3555
- blockingReasons: status === 'blocked' ? [input.rejectionReason ?? `Do adjudication health is ${health}.`] : [],
3556
- createdAt: input.generatedAt,
3557
- updatedAt: input.generatedAt
3558
- };
3559
- }
3560
- function buildDoWorkflowHandoff(scope, decision, input) {
3561
- return {
3562
- contract: WORKFLOW_HANDOFF_CONTRACT_VERSION,
3563
- id: stableId('do-test-handoff', scope, 'closure', input.generatedAt),
3564
- scope,
3565
- fromStage: 'do',
3566
- toStage: 'test',
3567
- fromAgent: DO_STAGE_MANAGER,
3568
- toAgent: 'test-stage-runtime',
3291
+ toAgent: 'execute-stage-runtime',
3569
3292
  status: decision.profile === 'blocked' || decision.approvalPolicy === 'blocked' ? 'blocked' : 'proposed',
3570
3293
  outputRefs: input.outputRefs,
3571
3294
  requiredInputRefs: input.requiredInputRefs,
@@ -3576,37 +3299,37 @@ function buildDoWorkflowHandoff(scope, decision, input) {
3576
3299
  createdAt: input.generatedAt
3577
3300
  };
3578
3301
  }
3579
- function buildTestClosureStageRun(scope, runId, workOrder, health, input) {
3580
- const status = health === 'ready_for_goal_verify'
3302
+ function buildExecuteClosureStageRun(scope, runId, workOrder, health, input) {
3303
+ const status = health === 'ready_for_ship'
3581
3304
  ? 'completed'
3582
3305
  : health === 'no-op'
3583
3306
  ? 'skipped'
3584
3307
  : 'blocked';
3585
3308
  return {
3586
3309
  contract: STAGE_RUN_CONTRACT_VERSION,
3587
- id: stableId('stage-run-test', scope, runId, input.generatedAt),
3310
+ id: stableId('stage-run-execute', scope, runId, input.generatedAt),
3588
3311
  scope,
3589
- stage: 'test',
3312
+ stage: 'execute',
3590
3313
  ownerAgent: workOrder?.stageManager ?? 'runtime',
3591
3314
  coMainAgents: workOrder?.agentTeam ?? [],
3592
3315
  status,
3593
3316
  inputRefs: input.inputRefs,
3594
3317
  outputRefs: input.outputRefs,
3595
3318
  decisionRefs: input.decisionRefs,
3596
- blockingReasons: status === 'blocked' ? [input.rejectionReason ?? `Test adjudication health is ${health}.`] : [],
3319
+ blockingReasons: status === 'blocked' ? [input.rejectionReason ?? `Execute adjudication health is ${health}.`] : [],
3597
3320
  createdAt: input.generatedAt,
3598
3321
  updatedAt: input.generatedAt
3599
3322
  };
3600
3323
  }
3601
- function buildTestWorkflowHandoff(scope, decision, input) {
3324
+ function buildExecuteWorkflowHandoff(scope, decision, input) {
3602
3325
  return {
3603
3326
  contract: WORKFLOW_HANDOFF_CONTRACT_VERSION,
3604
- id: stableId('test-goal-verify-handoff', scope, 'closure', input.generatedAt),
3327
+ id: stableId('execute-ship-handoff', scope, 'closure', input.generatedAt),
3605
3328
  scope,
3606
- fromStage: 'test',
3607
- toStage: 'goal-verify',
3608
- fromAgent: TEST_STAGE_MANAGER,
3609
- toAgent: 'goal-verify-stage-runtime',
3329
+ fromStage: 'execute',
3330
+ toStage: 'ship',
3331
+ fromAgent: 'execute-manager',
3332
+ toAgent: 'ship-stage-runtime',
3610
3333
  status: decision.profile === 'blocked' || decision.approvalPolicy === 'blocked' ? 'blocked' : 'proposed',
3611
3334
  outputRefs: input.outputRefs,
3612
3335
  requiredInputRefs: input.requiredInputRefs,
@@ -3617,28 +3340,6 @@ function buildTestWorkflowHandoff(scope, decision, input) {
3617
3340
  createdAt: input.generatedAt
3618
3341
  };
3619
3342
  }
3620
- function buildGoalVerifyClosureStageRun(scope, runId, workOrder, health, input) {
3621
- const status = health === 'ready_for_ship'
3622
- ? 'completed'
3623
- : health === 'no-op'
3624
- ? 'skipped'
3625
- : 'blocked';
3626
- return {
3627
- contract: STAGE_RUN_CONTRACT_VERSION,
3628
- id: stableId('stage-run-goal-verify', scope, runId, input.generatedAt),
3629
- scope,
3630
- stage: 'goal-verify',
3631
- ownerAgent: workOrder?.stageManager ?? 'runtime',
3632
- coMainAgents: workOrder?.agentTeam ?? [],
3633
- status,
3634
- inputRefs: input.inputRefs,
3635
- outputRefs: input.outputRefs,
3636
- decisionRefs: input.decisionRefs,
3637
- blockingReasons: status === 'blocked' ? [input.rejectionReason ?? `Goal-verify adjudication health is ${health}.`] : [],
3638
- createdAt: input.generatedAt,
3639
- updatedAt: input.generatedAt
3640
- };
3641
- }
3642
3343
  function buildShipClosureStageRun(scope, runId, workOrder, health, input) {
3643
3344
  const status = health === 'ship_ready'
3644
3345
  ? 'completed'
@@ -3790,6 +3491,462 @@ function specArtifactStatusForHealth(health) {
3790
3491
  function isManagedStarterSpec(content) {
3791
3492
  return /^sdd_managed_starter:\s*true\s*$/m.test(content);
3792
3493
  }
3494
+ function validateSpecDocumentV3(content) {
3495
+ const errors = [];
3496
+ if (!/contract:\s*sdd-spec-doc-v3\b/.test(content)) {
3497
+ errors.push('missing contract: sdd-spec-doc-v3');
3498
+ }
3499
+ const requiredSections = [
3500
+ 'Problem Reframing / Intent Discovery',
3501
+ 'Change Delta',
3502
+ 'Scope',
3503
+ 'Requirements',
3504
+ 'Acceptance Criteria / Evidence Targets',
3505
+ 'Definitions / Rules',
3506
+ 'Planning Constraints / Signals',
3507
+ 'Open Questions / Ambiguity Ledger',
3508
+ 'Close Quality Evidence'
3509
+ ];
3510
+ for (const section of requiredSections) {
3511
+ const escaped = escapeRegex(section).replace(/\s+/g, '\\s+');
3512
+ if (!new RegExp(`^##\\s+(?:\\d+\\.\\s*)?${escaped}\\s*$`, 'im').test(content)) {
3513
+ errors.push(`missing section: ${section}`);
3514
+ }
3515
+ }
3516
+ const forbiddenSections = [/^##\s+Implementation Plan\s*$/im, /^##\s+Task List\s*$/im, /^##\s+Validation Plan\s*$/im, /^##\s+Runtime Gate Metadata\s*$/im, /^##\s+Subagent Trace\s*$/im];
3517
+ if (forbiddenSections.some((pattern) => pattern.test(content))) {
3518
+ errors.push('contains forbidden implementation/runtime/subagent section');
3519
+ }
3520
+ errors.push(...formatArtifactDepthBlockingIssues(evaluateSpecArtifactDepth(content)));
3521
+ return errors;
3522
+ }
3523
+ function validateSpecDepthSignals(content, errors) {
3524
+ const problem = extractMarkdownSection(content, 'Problem Reframing / Intent Discovery') ?? '';
3525
+ const changeDelta = extractMarkdownSection(content, 'Change Delta') ?? '';
3526
+ const requirements = extractMarkdownSection(content, 'Requirements') ?? '';
3527
+ const acceptance = extractMarkdownSection(content, 'Acceptance Criteria / Evidence Targets') ?? '';
3528
+ const definitions = extractMarkdownSection(content, 'Definitions / Rules') ?? '';
3529
+ const ambiguity = extractMarkdownSection(content, 'Open Questions / Ambiguity Ledger') ?? '';
3530
+ const closeEvidence = extractMarkdownSection(content, 'Close Quality Evidence') ?? '';
3531
+ if (!hasProblemReframingDepth(problem)) {
3532
+ errors.push('spec lacks problem reframing depth in Problem Reframing / Intent Discovery');
3533
+ }
3534
+ if (!hasChangeDeltaDepth(changeDelta)) {
3535
+ errors.push('spec lacks explicit current/target/delta/unchanged/non-goal depth in Change Delta');
3536
+ }
3537
+ if (!hasRequirementReasoningDepth(requirements, definitions)) {
3538
+ errors.push('spec lacks requirement reasoning or domain rule depth');
3539
+ }
3540
+ if (!hasAcceptanceEvidenceDepth(acceptance)) {
3541
+ errors.push('spec lacks acceptance evidence targets tied to requirements');
3542
+ }
3543
+ if (!hasAmbiguityRoutingDepth(ambiguity)) {
3544
+ errors.push('spec lacks explicit ambiguity routing for blocking decisions, researchable gaps, assumptions, or deferred items');
3545
+ }
3546
+ if (!closeEvidence) {
3547
+ errors.push('missing spec close quality evidence content');
3548
+ return;
3549
+ }
3550
+ const requiredEvidence = [
3551
+ ['requirement_review_sufficient', 'spec close quality evidence must declare requirement_review_sufficient: true'],
3552
+ ['problem_reframed', 'spec close quality evidence must declare problem_reframed: true'],
3553
+ ['domain_rules_confirmed_or_routed', 'spec close quality evidence must declare domain_rules_confirmed_or_routed: true'],
3554
+ ['acceptance_evidence_targets_defined', 'spec close quality evidence must declare acceptance_evidence_targets_defined: true'],
3555
+ ['ambiguity_routed', 'spec close quality evidence must declare ambiguity_routed: true'],
3556
+ ['ready_for_plan', 'spec close quality evidence must declare ready_for_plan: true']
3557
+ ];
3558
+ for (const [key, message] of requiredEvidence) {
3559
+ if (!new RegExp(`${key}\\s*:\\s*` + '`?' + 'true' + '`?', 'i').test(closeEvidence)) {
3560
+ errors.push(message);
3561
+ }
3562
+ }
3563
+ if (!/downstream_business_guesswork_remaining\s*:\s*\[\s*\]/i.test(closeEvidence)) {
3564
+ errors.push('spec close quality evidence must declare no downstream_business_guesswork_remaining');
3565
+ }
3566
+ }
3567
+ function hasProblemReframingDepth(section) {
3568
+ return /surface request/i.test(section)
3569
+ && /reframed problem/i.test(section)
3570
+ && /inferred real intent|real intent/i.test(section)
3571
+ && /observable success/i.test(section);
3572
+ }
3573
+ function hasChangeDeltaDepth(section) {
3574
+ return /current behavior/i.test(section)
3575
+ && /target behavior|desired behavior/i.test(section)
3576
+ && /delta/i.test(section)
3577
+ && /unchanged behavior/i.test(section)
3578
+ && /non-goals?/i.test(section);
3579
+ }
3580
+ function hasRequirementReasoningDepth(requirements, definitions) {
3581
+ const hasRequirement = /\bREQ-\d+\b/i.test(requirements);
3582
+ const hasReasoning = /reasoning|basis|source|constraint|because|why|rule|invariant|domain/i.test(`${requirements}\n${definitions}`);
3583
+ return hasRequirement && hasReasoning;
3584
+ }
3585
+ function hasAcceptanceEvidenceDepth(section) {
3586
+ return /\bAC-\d+\b/i.test(section)
3587
+ && /evidence target|api|ui|sql|test|manual|runtime|stage close/i.test(section)
3588
+ && /REQ-\d+/i.test(section);
3589
+ }
3590
+ function hasAmbiguityRoutingDepth(section) {
3591
+ return /blocking user decisions?|blocking before plan|no blocking/i.test(section)
3592
+ && /researchable|resolved by scout|scout|safe assumptions?|assumptions?|deferred/i.test(section);
3593
+ }
3594
+ function validatePlanDocumentV3(content, boundaryFacts) {
3595
+ const errors = [];
3596
+ if (!/contract:\s*sdd-plan-doc-v3\b/.test(content)) {
3597
+ errors.push('missing contract: sdd-plan-doc-v3');
3598
+ }
3599
+ const requiredSections = [
3600
+ 'Metadata',
3601
+ 'Upstream Spec Trace',
3602
+ 'Planning Problem / Strategy Framing',
3603
+ 'Current Implementation Map',
3604
+ 'Target Design Overview',
3605
+ 'Change Topology / Responsibility Boundaries',
3606
+ 'Interface / API / Schema Design',
3607
+ 'State / Data / Concurrency Design',
3608
+ 'Key Design Decisions',
3609
+ 'Alternatives Considered',
3610
+ 'Risk Controls',
3611
+ 'Validation Strategy',
3612
+ 'Rollout / Rollback / Compatibility',
3613
+ 'Task-stage Constraints',
3614
+ 'Open Questions / User Decisions',
3615
+ 'Plan Close Quality Evidence'
3616
+ ];
3617
+ for (const section of requiredSections) {
3618
+ const escaped = escapeRegex(section).replace(/\s+/g, '\\s+');
3619
+ if (!new RegExp(`^##\\s+(?:\\d+(?:\\.\\d+)*\\.?\\s+)?${escaped}\\s*$`, 'im').test(content)) {
3620
+ errors.push(`missing section: ${section}`);
3621
+ }
3622
+ }
3623
+ const forbiddenSections = ['Task Graph', 'Task Units', 'Task Breakdown Rationale', 'Implementation Diff', 'Validation Results', 'Runtime Gate Metadata', 'Subagent Trace'];
3624
+ const hasForbiddenSection = forbiddenSections.some((section) => {
3625
+ const escaped = escapeRegex(section).replace(/\s+/g, '\\s+');
3626
+ return new RegExp(`^##\\s+(?:\\d+(?:\\.\\d+)*\\.?\\s+)?${escaped}\\s*$`, 'im').test(content);
3627
+ });
3628
+ const taskLeakagePatterns = [/```sdd-task\b/i, /^###\s+T\d+\b/im, /^#{3,}\s+Task\s+Units?\b/im, /^\s*sourceRequirements\s*:/im, /^\s*sourceAcceptanceCriteria\s*:/im, /^\s*taskClass\s*:/im, /^\s*suggestedExecutionLane\s*:/im, /^\s*wave\s*:/im, /^\s*dependencies\s*:/im];
3629
+ if (hasForbiddenSection || taskLeakagePatterns.some((pattern) => pattern.test(content))) {
3630
+ errors.push('contains forbidden task/runtime/subagent section');
3631
+ }
3632
+ const closeEvidence = extractMarkdownSection(content, 'Plan Close Quality Evidence');
3633
+ if (!closeEvidence) {
3634
+ errors.push('missing plan close quality evidence content');
3635
+ }
3636
+ else if (/ready_for_tasks\s*:\s*`?false`?/i.test(closeEvidence) || !/ready_for_tasks\s*:\s*`?true`?/i.test(closeEvidence)) {
3637
+ errors.push('plan close quality evidence must declare ready_for_tasks: true');
3638
+ }
3639
+ validatePlanDepthSignals(content, boundaryFacts, errors);
3640
+ errors.push(...formatArtifactDepthBlockingIssues(evaluatePlanArtifactDepth(content)));
3641
+ return errors;
3642
+ }
3643
+ function validatePlanDepthSignals(_content, boundaryFacts, errors) {
3644
+ if (boundaryFacts?.blockingBeforeTasksCount !== undefined && boundaryFacts.blockingBeforeTasksCount !== 0) {
3645
+ errors.push('plan close quality evidence conflicts with runtime blockingBeforeTasksCount');
3646
+ }
3647
+ }
3648
+ function hasConcreteImplementationSurface(section) {
3649
+ if (/scout gap|needs scout|unresolved gap|not applicable|no existing surface/i.test(section)) {
3650
+ return true;
3651
+ }
3652
+ const namedSurfaces = section.match(/\b[A-Z][A-Za-z0-9_]*(?:Controller|Service|ServiceImpl|Mapper|Repository|Entity|DTO|VO|Request|Response|Component|Page|Config|Test)\b/g) ?? [];
3653
+ const fileRefs = section.match(/`[^`]+\.(?:ts|tsx|js|jsx|java|kt|go|py|rs|xml|sql|jsp|vue|md)`/g) ?? [];
3654
+ return namedSurfaces.length + fileRefs.length >= 2 && /reuse|change|do-not-reuse|do not reuse|owner|ownership|convention|boundary|surface/i.test(section);
3655
+ }
3656
+ function hasFieldApiSqlMapping(section) {
3657
+ if (/not applicable|no interface|no api|no schema/i.test(section) && /because|checked|reason/i.test(section)) {
3658
+ return true;
3659
+ }
3660
+ const backtickFields = section.match(/`[a-zA-Z_][\w.]*`/g) ?? [];
3661
+ const identifierFields = section.match(/\b[A-Za-z_][A-Za-z0-9_]*(?:Id|IDs|Hash|Ref|Refs|Count|Status|Type|Key|Keys|At|Path|Command|Query|DTO|VO|Request|Response|Mapper|Controller|Service)\b/g) ?? [];
3662
+ const hasApiShape = /\b(query|request|response|DTO|VO|endpoint|controller|service|mapper|SQL|MyBatis|分页|权限|错误|响应包装)\b/i.test(section);
3663
+ const hasMapping = /\b(source|table|mapper|SQL|field|column|join|group|aggregate|映射|字段|表|聚合|查询参数|返回字段)\b/i.test(section);
3664
+ return backtickFields.length + identifierFields.length >= 6 && hasApiShape && hasMapping;
3665
+ }
3666
+ function hasStateDataFailureDepth(section) {
3667
+ if (/not applicable|no persisted|no state/i.test(section) && /failure|rollback|stale|dirty|because|reason/i.test(section)) {
3668
+ return true;
3669
+ }
3670
+ const hasDataSources = /\b(table|source|asset|state|flow|idempot|transaction|rollback|failure|partial|dirty|stale|performance|limit|join|dedup|grain|表|状态|流程|失败|回滚|脏数据|性能|去重|粒度|资产池)\b/i.test(section);
3671
+ const identifierRules = section.match(/\b[A-Za-z_][A-Za-z0-9_]*(?:Id|Hash|Ref|Status|Type|Key|At|Path|Projection|Handoff|Stage|State|Scope|Owner|Content)\b/g) ?? [];
3672
+ const hasSpecificRules = (section.match(/`[^`]+`/g) ?? []).length >= 5 || identifierRules.length >= 5 || /@startuml|\|.*\|.*\|/m.test(section);
3673
+ const hasFailureOrLimit = /\b(fail|failure|rollback|partial|dirty|stale|limit|timeout|fallback|异常|失败|回滚|部分|脏|限制|超时|降级)\b/i.test(section);
3674
+ return hasDataSources && hasSpecificRules && hasFailureOrLimit;
3675
+ }
3676
+ function hasScenarioValidationMatrix(validationStrategy, riskControls) {
3677
+ const combined = `${validationStrategy}\n${riskControls}`;
3678
+ const hasScenario = /scenario|input data|user action|expected|proves|does not prove|场景|输入|预期|证明/i.test(combined);
3679
+ const hasEvidence = /command|evidence|manual|test|api|ui|sql|hook|artifact|证据|检查/i.test(combined);
3680
+ const hasRiskLink = /risk|impact|control|validation hook|task-stage constraint|风险|影响|控制/i.test(combined);
3681
+ return hasScenario && hasEvidence && hasRiskLink;
3682
+ }
3683
+ function hasTaskStageConstraintDepth(section) {
3684
+ return /boundary|constraint|rollback|ordering|dependency|validation coverage|risky seam|task-stage|atomic|边界|约束|回滚|依赖|验证/i.test(section)
3685
+ && !/```sdd-task\b/i.test(section);
3686
+ }
3687
+ function hasScoutResolutionSignal(implementationMap, openQuestions, closeEvidence) {
3688
+ return /scout|evidence|observed|grounded|resolved|logged|no existing surface|not applicable/i.test(`${implementationMap}\n${openQuestions}\n${closeEvidence}`);
3689
+ }
3690
+ function extractMarkdownSection(content, section) {
3691
+ for (const sectionName of Array.isArray(section) ? section : [section]) {
3692
+ const escaped = escapeRegex(sectionName).replace(/\s+/g, '\\s+');
3693
+ const match = new RegExp(`^##\\s+(?:\\d+(?:\\.\\d+)*\\.?\\s+)?${escaped}\\s*$`, 'im').exec(content);
3694
+ if (!match) {
3695
+ continue;
3696
+ }
3697
+ const start = match.index + match[0].length;
3698
+ const rest = content.slice(start);
3699
+ const next = /^##\s+/im.exec(rest);
3700
+ return (next ? rest.slice(0, next.index) : rest).trim();
3701
+ }
3702
+ return null;
3703
+ }
3704
+ function validateTasksDocumentV2(content, tasksPath = 'tasks.md') {
3705
+ const errors = [];
3706
+ if (!/contract:\s*sdd-tasks-doc-v2\b/.test(content)) {
3707
+ errors.push('missing contract: sdd-tasks-doc-v2');
3708
+ }
3709
+ const requiredSections = [
3710
+ ['Split Basis', 'Task Split Basis', 'Work Unit Split Basis'],
3711
+ ['Execution Order Overview'],
3712
+ ['Implementation Tasks', 'Implementation Work Units', 'Implementation Task Units'],
3713
+ ['Validation Tasks', 'Validation Work Units', 'Validation Task Units'],
3714
+ ['Task Dependencies and Handoff', 'Dependencies and Validation Handoff', 'Task Dependency and Validation Handoff'],
3715
+ ['Coverage Check'],
3716
+ ['Open Execution Questions', 'Open Questions', 'Execution Questions'],
3717
+ ['Tasks Close Quality Evidence', 'Close Quality Evidence']
3718
+ ];
3719
+ for (const sectionAliases of requiredSections) {
3720
+ if (!hasMarkdownSection(content, sectionAliases)) {
3721
+ errors.push(`missing section: ${sectionAliases[0]}`);
3722
+ }
3723
+ }
3724
+ const forbiddenSections = [/^##\s+(?:\d+(?:\.\d+)*\.?\s+)?Implementation Diff\s*$/im, /^##\s+(?:\d+(?:\.\d+)*\.?\s+)?Validation Results\s*$/im, /^##\s+(?:\d+(?:\.\d+)*\.?\s+)?Runtime Gate Metadata\s*$/im, /^##\s+(?:\d+(?:\.\d+)*\.?\s+)?Subagent Trace\s*$/im, /^##\s+(?:\d+(?:\.\d+)*\.?\s+)?Long-Term Backlog\s*$/im];
3725
+ if (forbiddenSections.some((pattern) => pattern.test(content)) || /\b(?:obligationMatrix|projectionPayload|runtimeGateMetadata)\b/i.test(content)) {
3726
+ errors.push('contains forbidden implementation/runtime/subagent section');
3727
+ }
3728
+ const parsed = parseSddTasksMarkdown(content, { tasksPath });
3729
+ if (parsed.tasks.length === 0) {
3730
+ errors.push('missing executable task units');
3731
+ }
3732
+ const taskIds = new Set(parsed.tasks.map((task) => task.id));
3733
+ const taskById = new Map(parsed.tasks.map((task) => [task.id, task]));
3734
+ let hasImplementationTask = false;
3735
+ let hasValidationTask = false;
3736
+ for (const task of parsed.tasks) {
3737
+ const metadata = task.rawMetadata;
3738
+ const taskClass = task.taskClass;
3739
+ const unitType = task.unitType;
3740
+ const dependencies = task.dependsOn;
3741
+ if (taskClass !== 'implementation' && taskClass !== 'validation') {
3742
+ errors.push(`task ${task.id} missing taskClass implementation|validation`);
3743
+ }
3744
+ if (!unitType) {
3745
+ errors.push(`task ${task.id} missing unitType`);
3746
+ }
3747
+ if (!Number.isInteger(task.wave) || (task.wave ?? 0) <= 0) {
3748
+ errors.push(`task ${task.id} missing execution wave`);
3749
+ }
3750
+ if (task.affectedFiles.length === 0) {
3751
+ errors.push(`task ${task.id} missing affected areas`);
3752
+ }
3753
+ for (const dependency of dependencies) {
3754
+ if (!taskIds.has(dependency)) {
3755
+ errors.push(`task ${task.id} references unknown dependency ${dependency}`);
3756
+ }
3757
+ }
3758
+ if (taskClass === 'implementation') {
3759
+ hasImplementationTask = true;
3760
+ const handoffTasks = task.validationHandoff;
3761
+ if (handoffTasks.length === 0) {
3762
+ errors.push(`task ${task.id} missing validation handoff`);
3763
+ }
3764
+ for (const handoffTaskId of handoffTasks) {
3765
+ const handoffTask = taskById.get(handoffTaskId);
3766
+ if (!handoffTask) {
3767
+ errors.push(`task ${task.id} hands off to unknown validation task ${handoffTaskId}`);
3768
+ }
3769
+ else if (handoffTask.taskClass !== 'validation') {
3770
+ errors.push(`task ${task.id} hands off to non-validation task ${handoffTaskId}`);
3771
+ }
3772
+ else if (Number.isInteger(task.wave) && Number.isInteger(handoffTask.wave) && (handoffTask.wave ?? 0) <= (task.wave ?? 0)) {
3773
+ errors.push(`task ${task.id} validation handoff ${handoffTaskId} must be in a later wave`);
3774
+ }
3775
+ }
3776
+ }
3777
+ if (taskClass === 'validation') {
3778
+ hasValidationTask = true;
3779
+ const validatesTasks = metadataNamedListValue(metadata, ['validatesImplementationTasks', 'validates_implementation_tasks']);
3780
+ if (validatesTasks.length === 0) {
3781
+ errors.push(`task ${task.id} missing validatesImplementationTasks`);
3782
+ }
3783
+ for (const validatedTask of validatesTasks) {
3784
+ if (!taskIds.has(validatedTask)) {
3785
+ errors.push(`task ${task.id} validates unknown implementation task ${validatedTask}`);
3786
+ }
3787
+ const validated = taskById.get(validatedTask);
3788
+ if (validated && validated.taskClass !== 'implementation') {
3789
+ errors.push(`task ${task.id} validates non-implementation task ${validatedTask}`);
3790
+ }
3791
+ if (validated && Number.isInteger(task.wave) && Number.isInteger(validated.wave) && (task.wave ?? 0) <= (validated.wave ?? 0)) {
3792
+ errors.push(`task ${task.id} must run after validated implementation task ${validatedTask}`);
3793
+ }
3794
+ if (!dependencies.includes(validatedTask)) {
3795
+ errors.push(`task ${task.id} must depend on validated implementation task ${validatedTask}`);
3796
+ }
3797
+ }
3798
+ }
3799
+ }
3800
+ if (!hasImplementationTask) {
3801
+ errors.push('missing implementation task');
3802
+ }
3803
+ if (!hasValidationTask) {
3804
+ errors.push('missing validation task');
3805
+ }
3806
+ errors.push(...validateTaskValidationTopology(parsed.tasks));
3807
+ validateTasksDepthSignals(content, errors);
3808
+ errors.push(...taskDependencyCycleErrors(parsed.tasks));
3809
+ return errors;
3810
+ }
3811
+ function validateTasksDepthSignals(content, errors) {
3812
+ const closeEvidence = extractMarkdownSection(content, ['Tasks Close Quality Evidence', 'Close Quality Evidence']) ?? '';
3813
+ if (!hasTaskReviewVerdict(closeEvidence) || !hasTaskReviewReconciliation(closeEvidence)) {
3814
+ errors.push('tasks close quality evidence must include task-review-agent verdict and tasks-manager review reconciliation');
3815
+ }
3816
+ if (!/downstream_execution_guesswork_remaining\s*:\s*\[\s*\]/i.test(closeEvidence)) {
3817
+ errors.push('tasks close quality evidence must declare downstream_execution_guesswork_remaining: []');
3818
+ }
3819
+ }
3820
+ function hasTaskReviewVerdict(section) {
3821
+ return /task-review-agent\s+(?:verdict|review)|review(?:_|\s+)signal|reviewed by task-review-agent/i.test(section);
3822
+ }
3823
+ function hasTaskReviewReconciliation(section) {
3824
+ return /review(?:_|\s+)reconciliation|tasks-manager\s+(?:review\s+)?reconciliation|tasks-manager\s+(?:resolved|adjudicated)|review findings? reconciled|blocking findings resolved|task-review-agent findings resolved/i.test(section);
3825
+ }
3826
+ function hasWorkUnitContextDepth(section) {
3827
+ return /why this task exists|work-unit context|plan decision|design part|must not reinterpret|risk/i.test(section);
3828
+ }
3829
+ function hasUpstreamTraceDepth(section) {
3830
+ return /REQ-\d+/i.test(section) && /AC-\d+/i.test(section) && /planRefs|plan section|plan decision|§\d+/i.test(section);
3831
+ }
3832
+ function hasModificationBoundaryDepth(section) {
3833
+ return /allowed files|allowed code|allowed .*changes|forbidden files|forbidden .*scope|what not to do|modification boundary|scope exclusions/i.test(section);
3834
+ }
3835
+ function hasRollbackUnitDepth(implementationTasks, dependencies) {
3836
+ return /rollback unit|reverted together|rollback boundary|shared rollback/i.test(`${implementationTasks}\n${dependencies}`);
3837
+ }
3838
+ function hasDependencyRationaleDepth(dependencies, implementationTasks) {
3839
+ return /because|why ordering matters|dependency rationale|unlocks|must complete before|parallel/i.test(`${dependencies}\n${implementationTasks}`);
3840
+ }
3841
+ function hasCompletionEvidenceDepth(section) {
3842
+ return /completion evidence|done criteria|observable completion|what does not count|code review|basic code sanity/i.test(section);
3843
+ }
3844
+ function hasValidationExpectedResultDepth(section) {
3845
+ return /expected result|pass criteria|evidence is enough|does not prove|acceptance checks|manual inspection|test/i.test(section);
3846
+ }
3847
+ function hasFailureRouteDepth(section) {
3848
+ return /failure routing|failure route|return to|plan repair|spec\/user decision|environment diagnostic|tasks repair/i.test(section);
3849
+ }
3850
+ function hasMarkdownSection(content, sectionAliases) {
3851
+ return sectionAliases.some((section) => {
3852
+ const escaped = escapeRegex(section).replace(/\s+/g, '\\s+');
3853
+ return new RegExp(`^##\\s+(?:\\d+(?:\\.\\d+)*\\.?\\s+)?${escaped}\\s*$`, 'im').test(content);
3854
+ });
3855
+ }
3856
+ function validateTaskValidationTopology(tasks) {
3857
+ const taskIds = new Set(tasks.map((task) => task.id));
3858
+ if (taskIds.size !== tasks.length) {
3859
+ return [];
3860
+ }
3861
+ const taskById = new Map(tasks.map((task) => [task.id, task]));
3862
+ const errors = [];
3863
+ for (const task of tasks) {
3864
+ if (task.taskClass === 'implementation') {
3865
+ if (task.validationHandoff.length !== 1) {
3866
+ errors.push(`task ${task.id} must hand off to exactly one validation task`);
3867
+ continue;
3868
+ }
3869
+ const validationTask = taskById.get(task.validationHandoff[0]);
3870
+ const validatesTasks = validationTask ? metadataNamedListValue(validationTask.rawMetadata, ['validatesImplementationTasks', 'validates_implementation_tasks']) : [];
3871
+ if (validationTask && (validatesTasks.length !== 1 || validatesTasks[0] !== task.id)) {
3872
+ errors.push(`task ${task.id} validation handoff ${validationTask.id} must validate exactly ${task.id}`);
3873
+ }
3874
+ }
3875
+ if (task.taskClass === 'validation') {
3876
+ const validatesTasks = metadataNamedListValue(task.rawMetadata, ['validatesImplementationTasks', 'validates_implementation_tasks']);
3877
+ if (validatesTasks.length !== 1) {
3878
+ errors.push(`task ${task.id} must validate exactly one implementation task`);
3879
+ continue;
3880
+ }
3881
+ const implementationTask = taskById.get(validatesTasks[0]);
3882
+ if (implementationTask?.taskClass === 'implementation' && (implementationTask.validationHandoff.length !== 1 || implementationTask.validationHandoff[0] !== task.id)) {
3883
+ errors.push(`task ${task.id} validates ${implementationTask.id} but ${implementationTask.id} must hand off only to ${task.id}`);
3884
+ }
3885
+ }
3886
+ }
3887
+ return errors;
3888
+ }
3889
+ function taskDependencyCycleErrors(tasks) {
3890
+ const taskIds = new Set(tasks.map((task) => task.id));
3891
+ const dependencies = new Map(tasks.map((task) => [task.id, task.dependsOn.filter((dependency) => taskIds.has(dependency))]));
3892
+ const visiting = new Set();
3893
+ const visited = new Set();
3894
+ const errors = [];
3895
+ const visit = (taskId, path) => {
3896
+ if (visited.has(taskId)) {
3897
+ return;
3898
+ }
3899
+ if (visiting.has(taskId)) {
3900
+ errors.push(`task dependency cycle: ${[...path, taskId].join(' -> ')}`);
3901
+ return;
3902
+ }
3903
+ visiting.add(taskId);
3904
+ for (const dependency of dependencies.get(taskId) ?? []) {
3905
+ visit(dependency, [...path, taskId]);
3906
+ }
3907
+ visiting.delete(taskId);
3908
+ visited.add(taskId);
3909
+ };
3910
+ for (const task of tasks) {
3911
+ visit(task.id, []);
3912
+ }
3913
+ return Array.from(new Set(errors));
3914
+ }
3915
+ function metadataNamedListValue(metadata, names) {
3916
+ for (const name of names) {
3917
+ const value = metadataListValue(metadata[name]);
3918
+ if (value.length > 0) {
3919
+ return value;
3920
+ }
3921
+ }
3922
+ return [];
3923
+ }
3924
+ function metadataNamedScalarValue(metadata, names) {
3925
+ for (const name of names) {
3926
+ const value = metadataScalarValue(metadata[name]);
3927
+ if (value !== null) {
3928
+ return value;
3929
+ }
3930
+ }
3931
+ return null;
3932
+ }
3933
+ function metadataListValue(value) {
3934
+ if (Array.isArray(value)) {
3935
+ return value.map((item) => String(item).trim()).filter((item) => item.length > 0);
3936
+ }
3937
+ const scalar = metadataScalarValue(value);
3938
+ return scalar ? [scalar] : [];
3939
+ }
3940
+ function metadataScalarValue(value) {
3941
+ if (typeof value === 'string') {
3942
+ const trimmed = value.trim();
3943
+ return trimmed.length > 0 ? trimmed : null;
3944
+ }
3945
+ if (typeof value === 'number' || typeof value === 'boolean') {
3946
+ return String(value);
3947
+ }
3948
+ return null;
3949
+ }
3793
3950
  async function readOptionalText(filePath) {
3794
3951
  try {
3795
3952
  return await readFile(filePath, 'utf8');
@@ -3819,28 +3976,10 @@ function tasksAdjudicationProjectionRef(scope) {
3819
3976
  ref: `${TASKS_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${tasksCollaborationScopeKey(scope)}`
3820
3977
  };
3821
3978
  }
3822
- function verifiesAdjudicationProjectionRef(scope) {
3979
+ function executeAdjudicationProjectionRef(scope) {
3823
3980
  return {
3824
3981
  kind: 'projection',
3825
- ref: `${VERIFIES_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${verifiesCollaborationScopeKey(scope)}`
3826
- };
3827
- }
3828
- function doAdjudicationProjectionRef(scope) {
3829
- return {
3830
- kind: 'projection',
3831
- ref: `${DO_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${doCollaborationScopeKey(scope)}`
3832
- };
3833
- }
3834
- function testAdjudicationProjectionRef(scope) {
3835
- return {
3836
- kind: 'projection',
3837
- ref: `${TEST_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${testCollaborationScopeKey(scope)}`
3838
- };
3839
- }
3840
- function goalVerifyAdjudicationProjectionRef(scope) {
3841
- return {
3842
- kind: 'projection',
3843
- ref: `${GOAL_VERIFY_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${goalVerifyCollaborationScopeKey(scope)}`
3982
+ ref: `${EXECUTE_COLLABORATION_ADJUDICATION_PROJECTION_TYPE}:${executeCollaborationScopeKey(scope)}`
3844
3983
  };
3845
3984
  }
3846
3985
  function shipAdjudicationProjectionRef(scope) {
@@ -3852,6 +3991,9 @@ function shipAdjudicationProjectionRef(scope) {
3852
3991
  function stableHash(value) {
3853
3992
  return createHash('sha256').update(value, 'utf8').digest('hex');
3854
3993
  }
3994
+ function uniqueStrings(values) {
3995
+ return Array.from(new Set(values.filter((value) => value.length > 0)));
3996
+ }
3855
3997
  function uniqueRuntimeRefs(refs) {
3856
3998
  const seen = new Set();
3857
3999
  return refs.filter((ref) => {
@@ -3863,6 +4005,12 @@ function uniqueRuntimeRefs(refs) {
3863
4005
  return true;
3864
4006
  });
3865
4007
  }
4008
+ function runtimeProjectionPayload(payload) {
4009
+ if (!payload || typeof payload !== 'object' || !('payload' in payload)) {
4010
+ return null;
4011
+ }
4012
+ return payload.payload;
4013
+ }
3866
4014
  function stableId(prefix, scope, ...parts) {
3867
4015
  const hash = createHash('sha256').update(JSON.stringify([scope, parts]), 'utf8').digest('hex').slice(0, 16);
3868
4016
  return `${prefix}-${hash}`;