sdd-agent-platform 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (826) hide show
  1. package/README.md +33 -39
  2. package/node_modules/@sdd-agent-platform/core/dist/ai-tools.js +56 -73
  3. package/node_modules/@sdd-agent-platform/core/dist/ai-tools.js.map +1 -1
  4. package/node_modules/@sdd-agent-platform/core/dist/artifacts/ingestion.js +9 -64
  5. package/node_modules/@sdd-agent-platform/core/dist/artifacts/ingestion.js.map +1 -1
  6. package/node_modules/@sdd-agent-platform/core/dist/artifacts/sdd-evidence.js +1 -0
  7. package/node_modules/@sdd-agent-platform/core/dist/artifacts/sdd-evidence.js.map +1 -1
  8. package/node_modules/@sdd-agent-platform/core/dist/artifacts/sdd-result.js +17 -26
  9. package/node_modules/@sdd-agent-platform/core/dist/artifacts/sdd-result.js.map +1 -1
  10. package/node_modules/@sdd-agent-platform/core/dist/config/init-project.d.ts +8 -7
  11. package/node_modules/@sdd-agent-platform/core/dist/config/init-project.js +8 -12
  12. package/node_modules/@sdd-agent-platform/core/dist/config/init-project.js.map +1 -1
  13. package/node_modules/@sdd-agent-platform/core/dist/config/project-config.d.ts +1 -1
  14. package/node_modules/@sdd-agent-platform/core/dist/config/project-config.js +1 -1
  15. package/node_modules/@sdd-agent-platform/core/dist/config/project-config.js.map +1 -1
  16. package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.d.ts +3 -4
  17. package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.js +377 -411
  18. package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.js.map +1 -1
  19. package/node_modules/@sdd-agent-platform/core/dist/context/build-package.d.ts +1 -1
  20. package/node_modules/@sdd-agent-platform/core/dist/context/build-package.js +7 -13
  21. package/node_modules/@sdd-agent-platform/core/dist/context/build-package.js.map +1 -1
  22. package/node_modules/@sdd-agent-platform/core/dist/context/evidence-summary.js +8 -26
  23. package/node_modules/@sdd-agent-platform/core/dist/context/evidence-summary.js.map +1 -1
  24. package/node_modules/@sdd-agent-platform/core/dist/context/log-worker.js +2 -2
  25. package/node_modules/@sdd-agent-platform/core/dist/context/log-worker.js.map +1 -1
  26. package/node_modules/@sdd-agent-platform/core/dist/context-offload/contracts.d.ts +1 -1
  27. package/node_modules/@sdd-agent-platform/core/dist/contracts.d.ts +6 -1
  28. package/node_modules/@sdd-agent-platform/core/dist/contracts.js +5 -0
  29. package/node_modules/@sdd-agent-platform/core/dist/contracts.js.map +1 -1
  30. package/node_modules/@sdd-agent-platform/core/dist/delegation/model.d.ts +0 -3
  31. package/node_modules/@sdd-agent-platform/core/dist/delegation/validation.d.ts +0 -3
  32. package/node_modules/@sdd-agent-platform/core/dist/delegation/validation.js +4 -7
  33. package/node_modules/@sdd-agent-platform/core/dist/delegation/validation.js.map +1 -1
  34. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/document-chain.js +3 -13
  35. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/document-chain.js.map +1 -1
  36. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/project.js +8 -8
  37. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/project.js.map +1 -1
  38. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/registries.js +1 -0
  39. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/registries.js.map +1 -1
  40. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js +4 -4
  41. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js.map +1 -1
  42. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-trust.js +24 -0
  43. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-trust.js.map +1 -1
  44. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/runtime-contracts.js +1 -1
  45. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/runtime-contracts.js.map +1 -1
  46. package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js +43 -180
  47. package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js.map +1 -1
  48. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.d.ts +1 -1
  49. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js +7 -14
  50. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js.map +1 -1
  51. package/node_modules/@sdd-agent-platform/core/dist/evidence-runtime/coordination.js +110 -0
  52. package/node_modules/@sdd-agent-platform/core/dist/evidence-runtime/coordination.js.map +1 -0
  53. package/node_modules/@sdd-agent-platform/core/dist/execution/background-executor.js +4 -4
  54. package/node_modules/@sdd-agent-platform/core/dist/execution/background-executor.js.map +1 -1
  55. package/node_modules/@sdd-agent-platform/core/dist/execution/foreground-subagents.js +3 -3
  56. package/node_modules/@sdd-agent-platform/core/dist/execution/foreground-subagents.js.map +1 -1
  57. package/node_modules/@sdd-agent-platform/core/dist/execution/host-invocation.js +85 -86
  58. package/node_modules/@sdd-agent-platform/core/dist/execution/host-invocation.js.map +1 -1
  59. package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js +2 -3
  60. package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js.map +1 -1
  61. package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js +2 -2
  62. package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js.map +1 -1
  63. package/node_modules/@sdd-agent-platform/core/dist/governance/policy.d.ts +1 -1
  64. package/node_modules/@sdd-agent-platform/core/dist/governance/policy.js +1 -1
  65. package/node_modules/@sdd-agent-platform/core/dist/governance/policy.js.map +1 -1
  66. package/node_modules/@sdd-agent-platform/core/dist/instructions.d.ts +1 -1
  67. package/node_modules/@sdd-agent-platform/core/dist/instructions.js +31 -67
  68. package/node_modules/@sdd-agent-platform/core/dist/instructions.js.map +1 -1
  69. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/decision-gate.js +1 -1
  70. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/decision-gate.js.map +1 -1
  71. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.d.ts +0 -1
  72. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js +59 -85
  73. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js.map +1 -1
  74. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/contracts.d.ts +159 -0
  75. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/contracts.js +7 -0
  76. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/contracts.js.map +1 -0
  77. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/kernel.d.ts +16 -0
  78. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/kernel.js +461 -0
  79. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph/kernel.js.map +1 -0
  80. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph.d.ts +2 -0
  81. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph.js +3 -0
  82. package/node_modules/@sdd-agent-platform/core/dist/lifecycle-graph.js.map +1 -0
  83. package/node_modules/@sdd-agent-platform/core/dist/orchestration/contracts.d.ts +1 -1
  84. package/node_modules/@sdd-agent-platform/core/dist/orchestration/runtime.d.ts +2 -12
  85. package/node_modules/@sdd-agent-platform/core/dist/orchestration/runtime.js +32 -80
  86. package/node_modules/@sdd-agent-platform/core/dist/orchestration/runtime.js.map +1 -1
  87. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.d.ts +2 -5
  88. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js +27 -69
  89. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js.map +1 -1
  90. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js +118 -34
  91. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js.map +1 -1
  92. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js +1 -1
  93. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js.map +1 -1
  94. package/node_modules/@sdd-agent-platform/core/dist/registries/capability-sources.js +1 -1
  95. package/node_modules/@sdd-agent-platform/core/dist/registries/command-team-runtime.d.ts +1 -1
  96. package/node_modules/@sdd-agent-platform/core/dist/registries/command-team-runtime.js +8 -15
  97. package/node_modules/@sdd-agent-platform/core/dist/registries/command-team-runtime.js.map +1 -1
  98. package/node_modules/@sdd-agent-platform/core/dist/registries/eval-learning-context.js +4 -4
  99. package/node_modules/@sdd-agent-platform/core/dist/registries/eval-learning-context.js.map +1 -1
  100. package/node_modules/@sdd-agent-platform/core/dist/registries/plan-scout-domains.d.ts +13 -0
  101. package/node_modules/@sdd-agent-platform/core/dist/registries/plan-scout-domains.js +76 -0
  102. package/node_modules/@sdd-agent-platform/core/dist/registries/plan-scout-domains.js.map +1 -0
  103. package/node_modules/@sdd-agent-platform/core/dist/registries/query-status.js +2 -2
  104. package/node_modules/@sdd-agent-platform/core/dist/registries/query-status.js.map +1 -1
  105. package/node_modules/@sdd-agent-platform/core/dist/registries/skill-capabilities.js +7 -7
  106. package/node_modules/@sdd-agent-platform/core/dist/registries/skill-capabilities.js.map +1 -1
  107. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-capabilities.js +4 -4
  108. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-capabilities.js.map +1 -1
  109. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-plugins.js +2 -2
  110. package/node_modules/@sdd-agent-platform/core/dist/registries/tool-plugins.js.map +1 -1
  111. package/node_modules/@sdd-agent-platform/core/dist/registries/worker-adapters.js +11 -11
  112. package/node_modules/@sdd-agent-platform/core/dist/registries/worker-adapters.js.map +1 -1
  113. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.d.ts +1 -1
  114. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js +21 -21
  115. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js.map +1 -1
  116. package/node_modules/@sdd-agent-platform/core/dist/risk/consumer-diagnostics.js +2 -1
  117. package/node_modules/@sdd-agent-platform/core/dist/risk/consumer-diagnostics.js.map +1 -1
  118. package/node_modules/@sdd-agent-platform/core/dist/risk/kernel.js +6 -6
  119. package/node_modules/@sdd-agent-platform/core/dist/risk/kernel.js.map +1 -1
  120. package/node_modules/@sdd-agent-platform/core/dist/risk/legacy-adapters.js +11 -23
  121. package/node_modules/@sdd-agent-platform/core/dist/risk/legacy-adapters.js.map +1 -1
  122. package/node_modules/@sdd-agent-platform/core/dist/risk/workflow-gates.d.ts +2 -2
  123. package/node_modules/@sdd-agent-platform/core/dist/risk/workflow-gates.js +18 -20
  124. package/node_modules/@sdd-agent-platform/core/dist/risk/workflow-gates.js.map +1 -1
  125. package/node_modules/@sdd-agent-platform/core/dist/router/agent-runtime.d.ts +0 -2
  126. package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js +1 -1
  127. package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js.map +1 -1
  128. package/node_modules/@sdd-agent-platform/core/dist/router/routing.js +16 -48
  129. package/node_modules/@sdd-agent-platform/core/dist/router/routing.js.map +1 -1
  130. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-import.js +11 -1
  131. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-import.js.map +1 -1
  132. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js +2 -2
  133. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js.map +1 -1
  134. package/node_modules/@sdd-agent-platform/core/dist/router/stage-route-binding.d.ts +2 -2
  135. package/node_modules/@sdd-agent-platform/core/dist/router/stage-route-binding.js +20 -28
  136. package/node_modules/@sdd-agent-platform/core/dist/router/stage-route-binding.js.map +1 -1
  137. package/node_modules/@sdd-agent-platform/core/dist/router.d.ts +0 -1
  138. package/node_modules/@sdd-agent-platform/core/dist/router.js +0 -1
  139. package/node_modules/@sdd-agent-platform/core/dist/router.js.map +1 -1
  140. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.d.ts +6 -6
  141. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js +13 -124
  142. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js.map +1 -1
  143. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.d.ts +2 -0
  144. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js +5 -7
  145. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js.map +1 -1
  146. package/node_modules/@sdd-agent-platform/core/dist/run-state/model.d.ts +28 -28
  147. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-index.d.ts +2 -0
  148. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-index.js +3 -1
  149. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-index.js.map +1 -1
  150. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js +26 -36
  151. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js.map +1 -1
  152. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.d.ts +0 -4
  153. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js +5 -51
  154. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js.map +1 -1
  155. package/node_modules/@sdd-agent-platform/core/dist/run-state.d.ts +0 -1
  156. package/node_modules/@sdd-agent-platform/core/dist/run-state.js +0 -1
  157. package/node_modules/@sdd-agent-platform/core/dist/run-state.js.map +1 -1
  158. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/build.js +1 -1
  159. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/build.js.map +1 -1
  160. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/findings.js +5 -5
  161. package/node_modules/@sdd-agent-platform/core/dist/runtime-analysis/findings.js.map +1 -1
  162. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js +1 -1
  163. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js.map +1 -1
  164. package/node_modules/@sdd-agent-platform/core/dist/runtime-projection-p0.d.ts +2 -2
  165. package/node_modules/@sdd-agent-platform/core/dist/runtime-projection-p0.js +11 -0
  166. package/node_modules/@sdd-agent-platform/core/dist/runtime-projection-p0.js.map +1 -1
  167. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/artifact-depth.d.ts +14 -0
  168. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/artifact-depth.js +179 -0
  169. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/artifact-depth.js.map +1 -0
  170. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.d.ts +0 -2
  171. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js +10 -97
  172. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js.map +1 -1
  173. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.d.ts +1 -1
  174. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js +6 -8
  175. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js.map +1 -1
  176. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.d.ts +5 -2
  177. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js +85 -68
  178. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js.map +1 -1
  179. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-rendering.js +2 -2
  180. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-rendering.js.map +1 -1
  181. package/node_modules/@sdd-agent-platform/core/dist/spec-entry.js +40 -0
  182. package/node_modules/@sdd-agent-platform/core/dist/spec-entry.js.map +1 -0
  183. package/node_modules/@sdd-agent-platform/core/dist/spec-manager-contracts.d.ts +12 -0
  184. package/node_modules/@sdd-agent-platform/core/dist/spec-manager-contracts.js +2 -0
  185. package/node_modules/@sdd-agent-platform/core/dist/spec-manager-contracts.js.map +1 -0
  186. package/node_modules/@sdd-agent-platform/core/dist/stage-artifacts.d.ts +2 -2
  187. package/node_modules/@sdd-agent-platform/core/dist/stage-artifacts.js +19 -26
  188. package/node_modules/@sdd-agent-platform/core/dist/stage-artifacts.js.map +1 -1
  189. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration-contracts.d.ts +1 -1
  190. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration-contracts.js +3 -6
  191. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration-contracts.js.map +1 -1
  192. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration.d.ts +111 -263
  193. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration.js +1272 -1124
  194. package/node_modules/@sdd-agent-platform/core/dist/stage-collaboration.js.map +1 -1
  195. package/node_modules/@sdd-agent-platform/core/dist/stage-runtime/runtime.js +5 -5
  196. package/node_modules/@sdd-agent-platform/core/dist/stage-runtime/runtime.js.map +1 -1
  197. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.d.ts +1 -44
  198. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js +47 -170
  199. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js.map +1 -1
  200. package/node_modules/@sdd-agent-platform/core/dist/storage/runtime-store.js +73 -73
  201. package/node_modules/@sdd-agent-platform/core/dist/subagents/contracts.d.ts +1 -1
  202. package/node_modules/@sdd-agent-platform/core/dist/subagents/runtime.js +7 -7
  203. package/node_modules/@sdd-agent-platform/core/dist/subagents/runtime.js.map +1 -1
  204. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.d.ts +1 -0
  205. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js +2 -0
  206. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js.map +1 -0
  207. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.d.ts +1 -0
  208. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js +2 -0
  209. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js.map +1 -0
  210. package/node_modules/@sdd-agent-platform/core/dist/sync-back.d.ts +1 -0
  211. package/node_modules/@sdd-agent-platform/core/dist/sync-back.js +2 -0
  212. package/node_modules/@sdd-agent-platform/core/dist/sync-back.js.map +1 -0
  213. package/node_modules/@sdd-agent-platform/core/dist/task-execution-contract.d.ts +167 -0
  214. package/node_modules/@sdd-agent-platform/core/dist/task-execution-contract.js +377 -0
  215. package/node_modules/@sdd-agent-platform/core/dist/task-execution-contract.js.map +1 -0
  216. package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js +329 -314
  217. package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js.map +1 -1
  218. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.d.ts +1 -0
  219. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js +53 -7
  220. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js.map +1 -1
  221. package/node_modules/@sdd-agent-platform/core/dist/truth-reconciliation.js +9 -12
  222. package/node_modules/@sdd-agent-platform/core/dist/truth-reconciliation.js.map +1 -1
  223. package/node_modules/@sdd-agent-platform/core/dist/tsconfig.tsbuildinfo +1 -1
  224. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.d.ts +0 -48
  225. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js +1 -520
  226. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js.map +1 -1
  227. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.d.ts +5 -5
  228. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js +14 -14
  229. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js.map +1 -1
  230. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.d.ts +1 -0
  231. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js +111 -159
  232. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js.map +1 -1
  233. package/node_modules/@sdd-agent-platform/core/dist/verification/task-evidence-judgment.d.ts +49 -0
  234. package/node_modules/@sdd-agent-platform/core/dist/verification/task-evidence-judgment.js +521 -0
  235. package/node_modules/@sdd-agent-platform/core/dist/verification/task-evidence-judgment.js.map +1 -0
  236. package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js +21 -21
  237. package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js.map +1 -1
  238. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.d.ts +0 -18
  239. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js +5 -27
  240. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js.map +1 -1
  241. package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js +45 -45
  242. package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js.map +1 -1
  243. package/node_modules/@sdd-agent-platform/core/dist/verification.d.ts +3 -3
  244. package/node_modules/@sdd-agent-platform/core/dist/verification.js +2 -2
  245. package/node_modules/@sdd-agent-platform/core/dist/verification.js.map +1 -1
  246. package/node_modules/@sdd-agent-platform/core/dist/work-units/contracts.d.ts +1 -1
  247. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js +9 -227
  248. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js.map +1 -1
  249. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js +9 -50
  250. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js.map +1 -1
  251. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js +4 -42
  252. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js.map +1 -1
  253. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/types.d.ts +2 -3
  254. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
  255. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js +2 -1
  256. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
  257. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/dependencies.js +1 -1
  258. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.d.ts +1 -0
  259. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js +23 -63
  260. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js.map +1 -1
  261. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.d.ts +2 -2
  262. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js +43 -65
  263. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js.map +1 -1
  264. package/node_modules/@sdd-agent-platform/core/package.json +5 -2
  265. package/node_modules/@sdd-agent-platform/core/src/ai-tools.test.ts +238 -185
  266. package/node_modules/@sdd-agent-platform/core/src/ai-tools.ts +56 -73
  267. package/node_modules/@sdd-agent-platform/core/src/artifacts/ingestion.test.ts +189 -227
  268. package/node_modules/@sdd-agent-platform/core/src/artifacts/ingestion.ts +222 -278
  269. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-evidence.test.ts +28 -28
  270. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-evidence.ts +302 -301
  271. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-result.test.ts +181 -181
  272. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-result.ts +231 -240
  273. package/node_modules/@sdd-agent-platform/core/src/artifacts/templates.ts +99 -99
  274. package/node_modules/@sdd-agent-platform/core/src/artifacts.ts +4 -4
  275. package/node_modules/@sdd-agent-platform/core/src/coding-facts/contracts.ts +79 -79
  276. package/node_modules/@sdd-agent-platform/core/src/coding-facts.ts +1 -1
  277. package/node_modules/@sdd-agent-platform/core/src/config/init-project.test.ts +314 -318
  278. package/node_modules/@sdd-agent-platform/core/src/config/init-project.ts +128 -123
  279. package/node_modules/@sdd-agent-platform/core/src/config/project-config.ts +265 -265
  280. package/node_modules/@sdd-agent-platform/core/src/config/project-detection.ts +147 -147
  281. package/node_modules/@sdd-agent-platform/core/src/config/starter-documents.ts +400 -432
  282. package/node_modules/@sdd-agent-platform/core/src/context/budget.ts +30 -30
  283. package/node_modules/@sdd-agent-platform/core/src/context/build-package.ts +305 -311
  284. package/node_modules/@sdd-agent-platform/core/src/context/command-summary.ts +45 -45
  285. package/node_modules/@sdd-agent-platform/core/src/context/context-build.test.ts +188 -189
  286. package/node_modules/@sdd-agent-platform/core/src/context/evidence-summary.ts +144 -163
  287. package/node_modules/@sdd-agent-platform/core/src/context/log-worker.ts +48 -48
  288. package/node_modules/@sdd-agent-platform/core/src/context/source-refs.ts +41 -41
  289. package/node_modules/@sdd-agent-platform/core/src/context-offload/contracts.ts +47 -47
  290. package/node_modules/@sdd-agent-platform/core/src/context-offload/runtime.test.ts +71 -71
  291. package/node_modules/@sdd-agent-platform/core/src/context-offload/runtime.ts +178 -178
  292. package/node_modules/@sdd-agent-platform/core/src/context-offload.ts +2 -2
  293. package/node_modules/@sdd-agent-platform/core/src/context.ts +6 -6
  294. package/node_modules/@sdd-agent-platform/core/src/contracts/issues.ts +13 -13
  295. package/node_modules/@sdd-agent-platform/core/src/contracts.test.ts +9 -9
  296. package/node_modules/@sdd-agent-platform/core/src/contracts.ts +121 -116
  297. package/node_modules/@sdd-agent-platform/core/src/delegation/delegation.test.ts +183 -183
  298. package/node_modules/@sdd-agent-platform/core/src/delegation/model.ts +23 -26
  299. package/node_modules/@sdd-agent-platform/core/src/delegation/queue.ts +58 -58
  300. package/node_modules/@sdd-agent-platform/core/src/delegation/run-state.ts +14 -14
  301. package/node_modules/@sdd-agent-platform/core/src/delegation/state-machine.ts +90 -90
  302. package/node_modules/@sdd-agent-platform/core/src/delegation/validation.ts +124 -127
  303. package/node_modules/@sdd-agent-platform/core/src/delegation.ts +26 -26
  304. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/ai-entries.ts +28 -28
  305. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/document-chain.ts +104 -112
  306. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/local-run-index.ts +27 -27
  307. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/project.ts +84 -84
  308. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/registries.ts +252 -251
  309. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-evidence.ts +330 -330
  310. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-records.ts +79 -79
  311. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-trust.ts +128 -107
  312. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/runtime-contracts.ts +300 -300
  313. package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.test.ts +627 -755
  314. package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.ts +301 -453
  315. package/node_modules/@sdd-agent-platform/core/src/doctor/model.ts +13 -13
  316. package/node_modules/@sdd-agent-platform/core/src/doctor/summary.ts +11 -11
  317. package/node_modules/@sdd-agent-platform/core/src/doctor.ts +2 -2
  318. package/node_modules/@sdd-agent-platform/core/src/evidence/lookup.ts +80 -88
  319. package/node_modules/@sdd-agent-platform/core/src/evidence-runtime/contracts.ts +48 -48
  320. package/node_modules/@sdd-agent-platform/core/src/evidence-runtime.ts +1 -1
  321. package/node_modules/@sdd-agent-platform/core/src/execution/agent-execution-records.ts +195 -195
  322. package/node_modules/@sdd-agent-platform/core/src/execution/background-executor.test.ts +187 -235
  323. package/node_modules/@sdd-agent-platform/core/src/execution/background-executor.ts +305 -305
  324. package/node_modules/@sdd-agent-platform/core/src/execution/foreground-subagents.test.ts +97 -106
  325. package/node_modules/@sdd-agent-platform/core/src/execution/foreground-subagents.ts +453 -453
  326. package/node_modules/@sdd-agent-platform/core/src/execution/host-invocation.ts +225 -226
  327. package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.test.ts +132 -143
  328. package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.ts +436 -437
  329. package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.test.ts +102 -102
  330. package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.ts +271 -271
  331. package/node_modules/@sdd-agent-platform/core/src/execution/wave-executor.test.ts +111 -121
  332. package/node_modules/@sdd-agent-platform/core/src/execution/wave-executor.ts +231 -231
  333. package/node_modules/@sdd-agent-platform/core/src/execution.ts +5 -5
  334. package/node_modules/@sdd-agent-platform/core/src/governance/policy.test.ts +57 -65
  335. package/node_modules/@sdd-agent-platform/core/src/governance/policy.ts +175 -175
  336. package/node_modules/@sdd-agent-platform/core/src/governance.ts +1 -1
  337. package/node_modules/@sdd-agent-platform/core/src/instructions.test.ts +80 -64
  338. package/node_modules/@sdd-agent-platform/core/src/instructions.ts +32 -68
  339. package/node_modules/@sdd-agent-platform/core/src/lifecycle/decision-gate.test.ts +174 -174
  340. package/node_modules/@sdd-agent-platform/core/src/lifecycle/decision-gate.ts +373 -373
  341. package/node_modules/@sdd-agent-platform/core/src/lifecycle/rendering.ts +29 -29
  342. package/node_modules/@sdd-agent-platform/core/src/lifecycle/risk-signals.ts +146 -146
  343. package/node_modules/@sdd-agent-platform/core/src/lifecycle/ship.test.ts +47 -47
  344. package/node_modules/@sdd-agent-platform/core/src/lifecycle/ship.ts +255 -280
  345. package/node_modules/@sdd-agent-platform/core/src/lifecycle-graph/contracts.ts +179 -0
  346. package/node_modules/@sdd-agent-platform/core/src/lifecycle-graph/kernel.ts +522 -0
  347. package/node_modules/@sdd-agent-platform/core/src/lifecycle-graph.ts +2 -0
  348. package/node_modules/@sdd-agent-platform/core/src/lifecycle.ts +4 -4
  349. package/node_modules/@sdd-agent-platform/core/src/orchestration/contracts.ts +50 -50
  350. package/node_modules/@sdd-agent-platform/core/src/orchestration/index.ts +2 -2
  351. package/node_modules/@sdd-agent-platform/core/src/orchestration/runtime.ts +331 -394
  352. package/node_modules/@sdd-agent-platform/core/src/path-safety.test.ts +22 -22
  353. package/node_modules/@sdd-agent-platform/core/src/phase8-contracts.test.ts +243 -242
  354. package/node_modules/@sdd-agent-platform/core/src/phase8-projection-compat.test.ts +152 -153
  355. package/node_modules/@sdd-agent-platform/core/src/phase8-risk-kernel.test.ts +277 -277
  356. package/node_modules/@sdd-agent-platform/core/src/phase9-lifecycle-graph.test.ts +103 -0
  357. package/node_modules/@sdd-agent-platform/core/src/planning/task-graph.test.ts +88 -88
  358. package/node_modules/@sdd-agent-platform/core/src/planning/task-graph.ts +222 -222
  359. package/node_modules/@sdd-agent-platform/core/src/planning/wave-plan.test.ts +79 -79
  360. package/node_modules/@sdd-agent-platform/core/src/planning/wave-plan.ts +160 -160
  361. package/node_modules/@sdd-agent-platform/core/src/planning.ts +2 -2
  362. package/node_modules/@sdd-agent-platform/core/src/registries/agent-capability-catalog.ts +426 -473
  363. package/node_modules/@sdd-agent-platform/core/src/registries/agent-registry.ts +230 -146
  364. package/node_modules/@sdd-agent-platform/core/src/registries/agent-runtime-static.ts +142 -142
  365. package/node_modules/@sdd-agent-platform/core/src/registries/capability-sources.ts +253 -253
  366. package/node_modules/@sdd-agent-platform/core/src/registries/command-team-runtime.ts +302 -309
  367. package/node_modules/@sdd-agent-platform/core/src/registries/eval-learning-context.ts +246 -246
  368. package/node_modules/@sdd-agent-platform/core/src/registries/plan-scout-domains.ts +89 -0
  369. package/node_modules/@sdd-agent-platform/core/src/registries/query-status.ts +119 -119
  370. package/node_modules/@sdd-agent-platform/core/src/registries/registries.test.ts +454 -445
  371. package/node_modules/@sdd-agent-platform/core/src/registries/skill-capabilities.ts +37 -37
  372. package/node_modules/@sdd-agent-platform/core/src/registries/tool-capabilities.ts +135 -135
  373. package/node_modules/@sdd-agent-platform/core/src/registries/tool-plugins.ts +132 -132
  374. package/node_modules/@sdd-agent-platform/core/src/registries/worker-adapters.ts +144 -144
  375. package/node_modules/@sdd-agent-platform/core/src/registries/workflow-gates.ts +111 -111
  376. package/node_modules/@sdd-agent-platform/core/src/registries.ts +42 -42
  377. package/node_modules/@sdd-agent-platform/core/src/risk/consumer-diagnostics.ts +98 -97
  378. package/node_modules/@sdd-agent-platform/core/src/risk/contracts.ts +63 -63
  379. package/node_modules/@sdd-agent-platform/core/src/risk/kernel.ts +233 -233
  380. package/node_modules/@sdd-agent-platform/core/src/risk/legacy-adapters.ts +251 -263
  381. package/node_modules/@sdd-agent-platform/core/src/risk/workflow-gates.ts +203 -205
  382. package/node_modules/@sdd-agent-platform/core/src/risk.ts +5 -5
  383. package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime-config.ts +327 -327
  384. package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime.ts +388 -390
  385. package/node_modules/@sdd-agent-platform/core/src/router/profile-resolution.ts +154 -154
  386. package/node_modules/@sdd-agent-platform/core/src/router/risk-policy.ts +33 -33
  387. package/node_modules/@sdd-agent-platform/core/src/router/route-cache.ts +100 -100
  388. package/node_modules/@sdd-agent-platform/core/src/router/route-projection.ts +356 -356
  389. package/node_modules/@sdd-agent-platform/core/src/router/route-sdd-task.test.ts +428 -665
  390. package/node_modules/@sdd-agent-platform/core/src/router/route-sdd-task.ts +2 -2
  391. package/node_modules/@sdd-agent-platform/core/src/router/routing-rules.ts +73 -73
  392. package/node_modules/@sdd-agent-platform/core/src/router/routing.ts +189 -223
  393. package/node_modules/@sdd-agent-platform/core/src/router/runtime-import.ts +464 -453
  394. package/node_modules/@sdd-agent-platform/core/src/router/runtime-inspection.ts +124 -124
  395. package/node_modules/@sdd-agent-platform/core/src/router/runtime-registry.ts +123 -123
  396. package/node_modules/@sdd-agent-platform/core/src/router/runtime-validation.ts +277 -277
  397. package/node_modules/@sdd-agent-platform/core/src/router/stage-route-binding.ts +273 -279
  398. package/node_modules/@sdd-agent-platform/core/src/router/team-mode.ts +170 -170
  399. package/node_modules/@sdd-agent-platform/core/src/router.ts +5 -6
  400. package/node_modules/@sdd-agent-platform/core/src/run-state/artifacts.ts +126 -240
  401. package/node_modules/@sdd-agent-platform/core/src/run-state/events.ts +27 -27
  402. package/node_modules/@sdd-agent-platform/core/src/run-state/inspect-run.ts +172 -172
  403. package/node_modules/@sdd-agent-platform/core/src/run-state/invocation-ledger.ts +109 -109
  404. package/node_modules/@sdd-agent-platform/core/src/run-state/model.ts +252 -253
  405. package/node_modules/@sdd-agent-platform/core/src/run-state/run-index.test.ts +52 -52
  406. package/node_modules/@sdd-agent-platform/core/src/run-state/run-index.ts +356 -352
  407. package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.test.ts +70 -118
  408. package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.ts +406 -416
  409. package/node_modules/@sdd-agent-platform/core/src/run-state/task-evidence.ts +198 -252
  410. package/node_modules/@sdd-agent-platform/core/src/run-state/timing.ts +146 -146
  411. package/node_modules/@sdd-agent-platform/core/src/run-state.ts +8 -9
  412. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis/build.ts +60 -60
  413. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis/findings.ts +257 -256
  414. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis/model.ts +140 -140
  415. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis.test.ts +66 -66
  416. package/node_modules/@sdd-agent-platform/core/src/runtime-analysis.ts +2 -2
  417. package/node_modules/@sdd-agent-platform/core/src/runtime-paths.ts +253 -253
  418. package/node_modules/@sdd-agent-platform/core/src/runtime-projection-p0.test.ts +101 -96
  419. package/node_modules/@sdd-agent-platform/core/src/runtime-projection-p0.ts +314 -292
  420. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/artifact-depth.test.ts +380 -0
  421. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/artifact-depth.ts +207 -0
  422. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/context.ts +111 -111
  423. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/document-hashes.ts +207 -306
  424. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/run-binding.ts +95 -97
  425. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-inspection.ts +39 -39
  426. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.test.ts +467 -523
  427. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.ts +738 -709
  428. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-rendering.ts +81 -81
  429. package/node_modules/@sdd-agent-platform/core/src/sdd-docs.ts +5 -5
  430. package/node_modules/@sdd-agent-platform/core/src/spec-manager-contracts.ts +13 -0
  431. package/node_modules/@sdd-agent-platform/core/src/stage-artifacts.ts +435 -450
  432. package/node_modules/@sdd-agent-platform/core/src/stage-collaboration-contracts.ts +316 -322
  433. package/node_modules/@sdd-agent-platform/core/src/stage-collaboration.test.ts +2963 -2902
  434. package/node_modules/@sdd-agent-platform/core/src/stage-collaboration.ts +5856 -5831
  435. package/node_modules/@sdd-agent-platform/core/src/stage-runtime/contracts.ts +40 -40
  436. package/node_modules/@sdd-agent-platform/core/src/stage-runtime/runtime.test.ts +209 -209
  437. package/node_modules/@sdd-agent-platform/core/src/stage-runtime/runtime.ts +360 -360
  438. package/node_modules/@sdd-agent-platform/core/src/stage-runtime.ts +2 -2
  439. package/node_modules/@sdd-agent-platform/core/src/status/project-status.test.ts +288 -511
  440. package/node_modules/@sdd-agent-platform/core/src/status/project-status.ts +651 -851
  441. package/node_modules/@sdd-agent-platform/core/src/status.ts +2 -2
  442. package/node_modules/@sdd-agent-platform/core/src/storage/json-io.ts +10 -10
  443. package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.test.ts +489 -681
  444. package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.ts +1981 -1981
  445. package/node_modules/@sdd-agent-platform/core/src/subagents/contracts.ts +45 -45
  446. package/node_modules/@sdd-agent-platform/core/src/subagents/runtime.test.ts +232 -232
  447. package/node_modules/@sdd-agent-platform/core/src/subagents/runtime.ts +307 -307
  448. package/node_modules/@sdd-agent-platform/core/src/subagents.ts +2 -2
  449. package/node_modules/@sdd-agent-platform/core/src/task-execution-contract.test.ts +141 -0
  450. package/node_modules/@sdd-agent-platform/core/src/task-execution-contract.ts +566 -0
  451. package/node_modules/@sdd-agent-platform/core/src/task-risk-profile.ts +193 -193
  452. package/node_modules/@sdd-agent-platform/core/src/test-support/fixtures.ts +413 -398
  453. package/node_modules/@sdd-agent-platform/core/src/test-support/run-state.ts +102 -56
  454. package/node_modules/@sdd-agent-platform/core/src/test-support.ts +2 -2
  455. package/node_modules/@sdd-agent-platform/core/src/truth-reconciliation.test.ts +72 -72
  456. package/node_modules/@sdd-agent-platform/core/src/truth-reconciliation.ts +9 -12
  457. package/node_modules/@sdd-agent-platform/core/src/verification/rendering.ts +137 -137
  458. package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.test.ts +77 -84
  459. package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.ts +77 -77
  460. package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.ts +455 -506
  461. package/node_modules/@sdd-agent-platform/core/src/verification/{goal-verify.test.ts → task-evidence-judgment.test.ts} +261 -261
  462. package/node_modules/@sdd-agent-platform/core/src/verification/{goal-verify.ts → task-evidence-judgment.ts} +619 -619
  463. package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.ts +1190 -1190
  464. package/node_modules/@sdd-agent-platform/core/src/verification/validation-cache.ts +106 -106
  465. package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.ts +513 -556
  466. package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.ts +334 -334
  467. package/node_modules/@sdd-agent-platform/core/src/verification.ts +8 -8
  468. package/node_modules/@sdd-agent-platform/core/src/work-units/contracts.ts +26 -26
  469. package/node_modules/@sdd-agent-platform/core/src/work-units/runtime.test.ts +88 -88
  470. package/node_modules/@sdd-agent-platform/core/src/work-units/runtime.ts +112 -112
  471. package/node_modules/@sdd-agent-platform/core/src/work-units.ts +2 -2
  472. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/evidence-packet.ts +190 -425
  473. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.test.ts +169 -507
  474. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.ts +136 -182
  475. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.test.ts +135 -174
  476. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.ts +153 -194
  477. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/types.ts +111 -115
  478. package/node_modules/@sdd-agent-platform/core/src/workflow-state/affected-file-conflicts.ts +95 -93
  479. package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.test.ts +32 -32
  480. package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.ts +114 -114
  481. package/node_modules/@sdd-agent-platform/core/src/workflow-state/latest-eligible-run.ts +184 -224
  482. package/node_modules/@sdd-agent-platform/core/src/workflow-state/migration-recovery.ts +158 -158
  483. package/node_modules/@sdd-agent-platform/core/src/workflow-state/repair-contract.ts +77 -77
  484. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve-task-run.ts +114 -114
  485. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.test.ts +969 -956
  486. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.ts +967 -992
  487. package/node_modules/@sdd-agent-platform/core/src/workflow-state/runtime-projections.ts +712 -712
  488. package/node_modules/@sdd-agent-platform/core/src/workflow-state.ts +2 -2
  489. package/node_modules/@sdd-agent-platform/core/src/worktree/isolation.ts +130 -130
  490. package/node_modules/@sdd-agent-platform/core/src/worktree/lifecycle.ts +269 -269
  491. package/node_modules/@sdd-agent-platform/core/src/worktree/worktree.test.ts +150 -150
  492. package/node_modules/@sdd-agent-platform/core/src/worktree.ts +2 -2
  493. package/node_modules/@sdd-agent-platform/core/tsconfig.json +15 -15
  494. package/package.json +2 -2
  495. package/packages/cli/dist/args.js +2 -2
  496. package/packages/cli/dist/args.js.map +1 -1
  497. package/packages/cli/dist/commands/ai-tools.js +2 -13
  498. package/packages/cli/dist/commands/ai-tools.js.map +1 -1
  499. package/packages/cli/dist/commands/{verifies.d.ts → artifact.d.ts} +1 -1
  500. package/packages/cli/dist/commands/artifact.js +168 -0
  501. package/packages/cli/dist/commands/artifact.js.map +1 -0
  502. package/packages/cli/dist/commands/context.js +1 -1
  503. package/packages/cli/dist/commands/context.js.map +1 -1
  504. package/packages/cli/dist/commands/evidence.js.map +1 -0
  505. package/packages/cli/dist/commands/execution.js +127 -49
  506. package/packages/cli/dist/commands/execution.js.map +1 -1
  507. package/packages/cli/dist/commands/governance.js +1 -1
  508. package/packages/cli/dist/commands/governance.js.map +1 -1
  509. package/packages/cli/dist/commands/init.js +1 -6
  510. package/packages/cli/dist/commands/init.js.map +1 -1
  511. package/packages/cli/dist/commands/instructions.d.ts +1 -1
  512. package/packages/cli/dist/commands/instructions.js +15 -1
  513. package/packages/cli/dist/commands/instructions.js.map +1 -1
  514. package/packages/cli/dist/commands/registry/runtime.js +63 -40
  515. package/packages/cli/dist/commands/registry/runtime.js.map +1 -1
  516. package/packages/cli/dist/commands/run.js +13 -52
  517. package/packages/cli/dist/commands/run.js.map +1 -1
  518. package/packages/cli/dist/commands/stage-close.d.ts +60 -0
  519. package/packages/cli/dist/commands/stage-close.js +270 -41
  520. package/packages/cli/dist/commands/stage-close.js.map +1 -1
  521. package/packages/cli/dist/commands/status.js +9 -68
  522. package/packages/cli/dist/commands/status.js.map +1 -1
  523. package/packages/cli/dist/commands/tasks.js.map +1 -1
  524. package/packages/cli/dist/dispatch.js +6 -26
  525. package/packages/cli/dist/dispatch.js.map +1 -1
  526. package/packages/cli/dist/help.js +153 -159
  527. package/packages/cli/dist/help.js.map +1 -1
  528. package/packages/cli/dist/renderers/artifacts.d.ts +5 -0
  529. package/packages/cli/dist/renderers/artifacts.js +43 -0
  530. package/packages/cli/dist/renderers/artifacts.js.map +1 -0
  531. package/packages/cli/dist/renderers/doctor.js +1 -1
  532. package/packages/cli/dist/renderers/doctor.js.map +1 -1
  533. package/packages/cli/dist/renderers/execution.js +1 -1
  534. package/packages/cli/dist/renderers/execution.js.map +1 -1
  535. package/packages/cli/dist/renderers/json.d.ts +0 -1
  536. package/packages/cli/dist/renderers/json.js +0 -3
  537. package/packages/cli/dist/renderers/json.js.map +1 -1
  538. package/packages/cli/dist/renderers/registry-runtime.d.ts +1 -2
  539. package/packages/cli/dist/renderers/registry-runtime.js +0 -20
  540. package/packages/cli/dist/renderers/registry-runtime.js.map +1 -1
  541. package/packages/cli/dist/renderers/router.js +1 -1
  542. package/packages/cli/dist/renderers/router.js.map +1 -1
  543. package/packages/cli/dist/renderers/workflow.d.ts +53 -0
  544. package/packages/cli/dist/renderers/workflow.js +89 -30
  545. package/packages/cli/dist/renderers/workflow.js.map +1 -1
  546. package/packages/cli/dist/tsconfig.tsbuildinfo +1 -1
  547. package/packages/cli/package.json +2 -2
  548. package/packages/core/dist/ai-tools.js +56 -73
  549. package/packages/core/dist/ai-tools.js.map +1 -1
  550. package/packages/core/dist/artifacts/ingestion.js +9 -64
  551. package/packages/core/dist/artifacts/ingestion.js.map +1 -1
  552. package/packages/core/dist/artifacts/sdd-evidence.js +1 -0
  553. package/packages/core/dist/artifacts/sdd-evidence.js.map +1 -1
  554. package/packages/core/dist/artifacts/sdd-result.js +17 -26
  555. package/packages/core/dist/artifacts/sdd-result.js.map +1 -1
  556. package/packages/core/dist/config/init-project.d.ts +8 -7
  557. package/packages/core/dist/config/init-project.js +8 -12
  558. package/packages/core/dist/config/init-project.js.map +1 -1
  559. package/packages/core/dist/config/project-config.d.ts +1 -1
  560. package/packages/core/dist/config/project-config.js +1 -1
  561. package/packages/core/dist/config/project-config.js.map +1 -1
  562. package/packages/core/dist/config/starter-documents.d.ts +3 -4
  563. package/packages/core/dist/config/starter-documents.js +377 -411
  564. package/packages/core/dist/config/starter-documents.js.map +1 -1
  565. package/packages/core/dist/context/build-package.d.ts +1 -1
  566. package/packages/core/dist/context/build-package.js +7 -13
  567. package/packages/core/dist/context/build-package.js.map +1 -1
  568. package/packages/core/dist/context/evidence-summary.js +8 -26
  569. package/packages/core/dist/context/evidence-summary.js.map +1 -1
  570. package/packages/core/dist/context/log-worker.js +2 -2
  571. package/packages/core/dist/context/log-worker.js.map +1 -1
  572. package/packages/core/dist/context-offload/contracts.d.ts +1 -1
  573. package/packages/core/dist/contracts.d.ts +6 -1
  574. package/packages/core/dist/contracts.js +5 -0
  575. package/packages/core/dist/contracts.js.map +1 -1
  576. package/packages/core/dist/delegation/model.d.ts +0 -3
  577. package/packages/core/dist/delegation/validation.d.ts +0 -3
  578. package/packages/core/dist/delegation/validation.js +4 -7
  579. package/packages/core/dist/delegation/validation.js.map +1 -1
  580. package/packages/core/dist/doctor/checks/document-chain.js +3 -13
  581. package/packages/core/dist/doctor/checks/document-chain.js.map +1 -1
  582. package/packages/core/dist/doctor/checks/project.js +8 -8
  583. package/packages/core/dist/doctor/checks/project.js.map +1 -1
  584. package/packages/core/dist/doctor/checks/registries.js +1 -0
  585. package/packages/core/dist/doctor/checks/registries.js.map +1 -1
  586. package/packages/core/dist/doctor/checks/run-evidence.js +4 -4
  587. package/packages/core/dist/doctor/checks/run-evidence.js.map +1 -1
  588. package/packages/core/dist/doctor/checks/run-trust.js +24 -0
  589. package/packages/core/dist/doctor/checks/run-trust.js.map +1 -1
  590. package/packages/core/dist/doctor/checks/runtime-contracts.js +1 -1
  591. package/packages/core/dist/doctor/checks/runtime-contracts.js.map +1 -1
  592. package/packages/core/dist/doctor/doctor.js +43 -180
  593. package/packages/core/dist/doctor/doctor.js.map +1 -1
  594. package/packages/core/dist/evidence/lookup.d.ts +1 -1
  595. package/packages/core/dist/evidence/lookup.js +7 -14
  596. package/packages/core/dist/evidence/lookup.js.map +1 -1
  597. package/packages/core/dist/evidence-runtime/coordination.js +110 -0
  598. package/packages/core/dist/evidence-runtime/coordination.js.map +1 -0
  599. package/packages/core/dist/execution/background-executor.js +4 -4
  600. package/packages/core/dist/execution/background-executor.js.map +1 -1
  601. package/packages/core/dist/execution/foreground-subagents.js +3 -3
  602. package/packages/core/dist/execution/foreground-subagents.js.map +1 -1
  603. package/packages/core/dist/execution/host-invocation.js +85 -86
  604. package/packages/core/dist/execution/host-invocation.js.map +1 -1
  605. package/packages/core/dist/execution/resident-worker.js +2 -3
  606. package/packages/core/dist/execution/resident-worker.js.map +1 -1
  607. package/packages/core/dist/execution/stage-team-runtime.js +2 -2
  608. package/packages/core/dist/execution/stage-team-runtime.js.map +1 -1
  609. package/packages/core/dist/governance/policy.d.ts +1 -1
  610. package/packages/core/dist/governance/policy.js +1 -1
  611. package/packages/core/dist/governance/policy.js.map +1 -1
  612. package/packages/core/dist/instructions.d.ts +1 -1
  613. package/packages/core/dist/instructions.js +31 -67
  614. package/packages/core/dist/instructions.js.map +1 -1
  615. package/packages/core/dist/lifecycle/decision-gate.js +1 -1
  616. package/packages/core/dist/lifecycle/decision-gate.js.map +1 -1
  617. package/packages/core/dist/lifecycle/ship.d.ts +0 -1
  618. package/packages/core/dist/lifecycle/ship.js +59 -85
  619. package/packages/core/dist/lifecycle/ship.js.map +1 -1
  620. package/packages/core/dist/lifecycle-graph/contracts.d.ts +159 -0
  621. package/packages/core/dist/lifecycle-graph/contracts.js +7 -0
  622. package/packages/core/dist/lifecycle-graph/contracts.js.map +1 -0
  623. package/packages/core/dist/lifecycle-graph/kernel.d.ts +16 -0
  624. package/packages/core/dist/lifecycle-graph/kernel.js +461 -0
  625. package/packages/core/dist/lifecycle-graph/kernel.js.map +1 -0
  626. package/packages/core/dist/lifecycle-graph.d.ts +2 -0
  627. package/packages/core/dist/lifecycle-graph.js +3 -0
  628. package/packages/core/dist/lifecycle-graph.js.map +1 -0
  629. package/packages/core/dist/orchestration/contracts.d.ts +1 -1
  630. package/packages/core/dist/orchestration/runtime.d.ts +2 -12
  631. package/packages/core/dist/orchestration/runtime.js +32 -80
  632. package/packages/core/dist/orchestration/runtime.js.map +1 -1
  633. package/packages/core/dist/registries/agent-capability-catalog.d.ts +2 -5
  634. package/packages/core/dist/registries/agent-capability-catalog.js +27 -69
  635. package/packages/core/dist/registries/agent-capability-catalog.js.map +1 -1
  636. package/packages/core/dist/registries/agent-registry.js +118 -34
  637. package/packages/core/dist/registries/agent-registry.js.map +1 -1
  638. package/packages/core/dist/registries/agent-runtime-static.js +1 -1
  639. package/packages/core/dist/registries/agent-runtime-static.js.map +1 -1
  640. package/packages/core/dist/registries/capability-sources.js +1 -1
  641. package/packages/core/dist/registries/command-team-runtime.d.ts +1 -1
  642. package/packages/core/dist/registries/command-team-runtime.js +8 -15
  643. package/packages/core/dist/registries/command-team-runtime.js.map +1 -1
  644. package/packages/core/dist/registries/eval-learning-context.js +4 -4
  645. package/packages/core/dist/registries/eval-learning-context.js.map +1 -1
  646. package/packages/core/dist/registries/plan-scout-domains.d.ts +13 -0
  647. package/packages/core/dist/registries/plan-scout-domains.js +76 -0
  648. package/packages/core/dist/registries/plan-scout-domains.js.map +1 -0
  649. package/packages/core/dist/registries/query-status.js +2 -2
  650. package/packages/core/dist/registries/query-status.js.map +1 -1
  651. package/packages/core/dist/registries/skill-capabilities.js +7 -7
  652. package/packages/core/dist/registries/skill-capabilities.js.map +1 -1
  653. package/packages/core/dist/registries/tool-capabilities.js +4 -4
  654. package/packages/core/dist/registries/tool-capabilities.js.map +1 -1
  655. package/packages/core/dist/registries/tool-plugins.js +2 -2
  656. package/packages/core/dist/registries/tool-plugins.js.map +1 -1
  657. package/packages/core/dist/registries/worker-adapters.js +11 -11
  658. package/packages/core/dist/registries/worker-adapters.js.map +1 -1
  659. package/packages/core/dist/registries/workflow-gates.d.ts +1 -1
  660. package/packages/core/dist/registries/workflow-gates.js +21 -21
  661. package/packages/core/dist/registries/workflow-gates.js.map +1 -1
  662. package/packages/core/dist/risk/consumer-diagnostics.js +2 -1
  663. package/packages/core/dist/risk/consumer-diagnostics.js.map +1 -1
  664. package/packages/core/dist/risk/kernel.js +6 -6
  665. package/packages/core/dist/risk/kernel.js.map +1 -1
  666. package/packages/core/dist/risk/legacy-adapters.js +11 -23
  667. package/packages/core/dist/risk/legacy-adapters.js.map +1 -1
  668. package/packages/core/dist/risk/workflow-gates.d.ts +2 -2
  669. package/packages/core/dist/risk/workflow-gates.js +18 -20
  670. package/packages/core/dist/risk/workflow-gates.js.map +1 -1
  671. package/packages/core/dist/router/agent-runtime.d.ts +0 -2
  672. package/packages/core/dist/router/route-projection.js +1 -1
  673. package/packages/core/dist/router/route-projection.js.map +1 -1
  674. package/packages/core/dist/router/routing.js +16 -48
  675. package/packages/core/dist/router/routing.js.map +1 -1
  676. package/packages/core/dist/router/runtime-import.js +11 -1
  677. package/packages/core/dist/router/runtime-import.js.map +1 -1
  678. package/packages/core/dist/router/runtime-validation.js +2 -2
  679. package/packages/core/dist/router/runtime-validation.js.map +1 -1
  680. package/packages/core/dist/router/stage-route-binding.d.ts +2 -2
  681. package/packages/core/dist/router/stage-route-binding.js +20 -28
  682. package/packages/core/dist/router/stage-route-binding.js.map +1 -1
  683. package/packages/core/dist/router.d.ts +0 -1
  684. package/packages/core/dist/router.js +0 -1
  685. package/packages/core/dist/router.js.map +1 -1
  686. package/packages/core/dist/run-state/artifacts.d.ts +6 -6
  687. package/packages/core/dist/run-state/artifacts.js +13 -124
  688. package/packages/core/dist/run-state/artifacts.js.map +1 -1
  689. package/packages/core/dist/run-state/inspect-run.d.ts +2 -0
  690. package/packages/core/dist/run-state/inspect-run.js +5 -7
  691. package/packages/core/dist/run-state/inspect-run.js.map +1 -1
  692. package/packages/core/dist/run-state/model.d.ts +28 -28
  693. package/packages/core/dist/run-state/run-index.d.ts +2 -0
  694. package/packages/core/dist/run-state/run-index.js +3 -1
  695. package/packages/core/dist/run-state/run-index.js.map +1 -1
  696. package/packages/core/dist/run-state/run-state.js +26 -36
  697. package/packages/core/dist/run-state/run-state.js.map +1 -1
  698. package/packages/core/dist/run-state/task-evidence.d.ts +0 -4
  699. package/packages/core/dist/run-state/task-evidence.js +5 -51
  700. package/packages/core/dist/run-state/task-evidence.js.map +1 -1
  701. package/packages/core/dist/run-state.d.ts +0 -1
  702. package/packages/core/dist/run-state.js +0 -1
  703. package/packages/core/dist/run-state.js.map +1 -1
  704. package/packages/core/dist/runtime-analysis/build.js +1 -1
  705. package/packages/core/dist/runtime-analysis/build.js.map +1 -1
  706. package/packages/core/dist/runtime-analysis/findings.js +5 -5
  707. package/packages/core/dist/runtime-analysis/findings.js.map +1 -1
  708. package/packages/core/dist/runtime-paths.js +1 -1
  709. package/packages/core/dist/runtime-paths.js.map +1 -1
  710. package/packages/core/dist/runtime-projection-p0.d.ts +2 -2
  711. package/packages/core/dist/runtime-projection-p0.js +11 -0
  712. package/packages/core/dist/runtime-projection-p0.js.map +1 -1
  713. package/packages/core/dist/sdd-docs/artifact-depth.d.ts +14 -0
  714. package/packages/core/dist/sdd-docs/artifact-depth.js +179 -0
  715. package/packages/core/dist/sdd-docs/artifact-depth.js.map +1 -0
  716. package/packages/core/dist/sdd-docs/document-hashes.d.ts +0 -2
  717. package/packages/core/dist/sdd-docs/document-hashes.js +10 -97
  718. package/packages/core/dist/sdd-docs/document-hashes.js.map +1 -1
  719. package/packages/core/dist/sdd-docs/run-binding.d.ts +1 -1
  720. package/packages/core/dist/sdd-docs/run-binding.js +6 -8
  721. package/packages/core/dist/sdd-docs/run-binding.js.map +1 -1
  722. package/packages/core/dist/sdd-docs/task-parser.d.ts +5 -2
  723. package/packages/core/dist/sdd-docs/task-parser.js +85 -68
  724. package/packages/core/dist/sdd-docs/task-parser.js.map +1 -1
  725. package/packages/core/dist/sdd-docs/task-rendering.js +2 -2
  726. package/packages/core/dist/sdd-docs/task-rendering.js.map +1 -1
  727. package/packages/core/dist/spec-entry.js +40 -0
  728. package/packages/core/dist/spec-entry.js.map +1 -0
  729. package/packages/core/dist/spec-manager-contracts.d.ts +12 -0
  730. package/packages/core/dist/spec-manager-contracts.js +2 -0
  731. package/packages/core/dist/spec-manager-contracts.js.map +1 -0
  732. package/packages/core/dist/stage-artifacts.d.ts +2 -2
  733. package/packages/core/dist/stage-artifacts.js +19 -26
  734. package/packages/core/dist/stage-artifacts.js.map +1 -1
  735. package/packages/core/dist/stage-collaboration-contracts.d.ts +1 -1
  736. package/packages/core/dist/stage-collaboration-contracts.js +3 -6
  737. package/packages/core/dist/stage-collaboration-contracts.js.map +1 -1
  738. package/packages/core/dist/stage-collaboration.d.ts +111 -263
  739. package/packages/core/dist/stage-collaboration.js +1272 -1124
  740. package/packages/core/dist/stage-collaboration.js.map +1 -1
  741. package/packages/core/dist/stage-runtime/runtime.js +5 -5
  742. package/packages/core/dist/stage-runtime/runtime.js.map +1 -1
  743. package/packages/core/dist/status/project-status.d.ts +1 -44
  744. package/packages/core/dist/status/project-status.js +47 -170
  745. package/packages/core/dist/status/project-status.js.map +1 -1
  746. package/packages/core/dist/storage/runtime-store.js +73 -73
  747. package/packages/core/dist/subagents/contracts.d.ts +1 -1
  748. package/packages/core/dist/subagents/runtime.js +7 -7
  749. package/packages/core/dist/subagents/runtime.js.map +1 -1
  750. package/packages/core/dist/sync-back/apply.d.ts +1 -0
  751. package/packages/core/dist/sync-back/apply.js +2 -0
  752. package/packages/core/dist/sync-back/apply.js.map +1 -0
  753. package/packages/core/dist/sync-back/inspect.d.ts +1 -0
  754. package/packages/core/dist/sync-back/inspect.js +2 -0
  755. package/packages/core/dist/sync-back/inspect.js.map +1 -0
  756. package/packages/core/dist/sync-back.d.ts +1 -0
  757. package/packages/core/dist/sync-back.js +2 -0
  758. package/packages/core/dist/sync-back.js.map +1 -0
  759. package/packages/core/dist/task-execution-contract.d.ts +167 -0
  760. package/packages/core/dist/task-execution-contract.js +377 -0
  761. package/packages/core/dist/task-execution-contract.js.map +1 -0
  762. package/packages/core/dist/test-support/fixtures.js +329 -314
  763. package/packages/core/dist/test-support/fixtures.js.map +1 -1
  764. package/packages/core/dist/test-support/run-state.d.ts +1 -0
  765. package/packages/core/dist/test-support/run-state.js +53 -7
  766. package/packages/core/dist/test-support/run-state.js.map +1 -1
  767. package/packages/core/dist/truth-reconciliation.js +9 -12
  768. package/packages/core/dist/truth-reconciliation.js.map +1 -1
  769. package/packages/core/dist/tsconfig.tsbuildinfo +1 -1
  770. package/packages/core/dist/verification/goal-verify.d.ts +0 -48
  771. package/packages/core/dist/verification/goal-verify.js +1 -520
  772. package/packages/core/dist/verification/goal-verify.js.map +1 -1
  773. package/packages/core/dist/verification/rendering.d.ts +5 -5
  774. package/packages/core/dist/verification/rendering.js +14 -14
  775. package/packages/core/dist/verification/rendering.js.map +1 -1
  776. package/packages/core/dist/verification/single-task-loop.d.ts +1 -0
  777. package/packages/core/dist/verification/single-task-loop.js +111 -159
  778. package/packages/core/dist/verification/single-task-loop.js.map +1 -1
  779. package/packages/core/dist/verification/task-evidence-judgment.d.ts +49 -0
  780. package/packages/core/dist/verification/task-evidence-judgment.js +521 -0
  781. package/packages/core/dist/verification/task-evidence-judgment.js.map +1 -0
  782. package/packages/core/dist/verification/test-runtime.js +21 -21
  783. package/packages/core/dist/verification/test-runtime.js.map +1 -1
  784. package/packages/core/dist/verification/validation-wave.d.ts +0 -18
  785. package/packages/core/dist/verification/validation-wave.js +5 -27
  786. package/packages/core/dist/verification/validation-wave.js.map +1 -1
  787. package/packages/core/dist/verification/verify-contract.js +45 -45
  788. package/packages/core/dist/verification/verify-contract.js.map +1 -1
  789. package/packages/core/dist/verification.d.ts +3 -3
  790. package/packages/core/dist/verification.js +2 -2
  791. package/packages/core/dist/verification.js.map +1 -1
  792. package/packages/core/dist/work-units/contracts.d.ts +1 -1
  793. package/packages/core/dist/workflow-gate/evidence-packet.js +9 -227
  794. package/packages/core/dist/workflow-gate/evidence-packet.js.map +1 -1
  795. package/packages/core/dist/workflow-gate/hard-checks.js +9 -50
  796. package/packages/core/dist/workflow-gate/hard-checks.js.map +1 -1
  797. package/packages/core/dist/workflow-gate/policy.js +4 -42
  798. package/packages/core/dist/workflow-gate/policy.js.map +1 -1
  799. package/packages/core/dist/workflow-gate/types.d.ts +2 -3
  800. package/packages/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
  801. package/packages/core/dist/workflow-state/affected-file-conflicts.js +2 -1
  802. package/packages/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
  803. package/packages/core/dist/workflow-state/dependencies.js +1 -1
  804. package/packages/core/dist/workflow-state/latest-eligible-run.d.ts +1 -0
  805. package/packages/core/dist/workflow-state/latest-eligible-run.js +23 -63
  806. package/packages/core/dist/workflow-state/latest-eligible-run.js.map +1 -1
  807. package/packages/core/dist/workflow-state/resolve.d.ts +2 -2
  808. package/packages/core/dist/workflow-state/resolve.js +43 -65
  809. package/packages/core/dist/workflow-state/resolve.js.map +1 -1
  810. package/packages/core/package.json +5 -2
  811. package/tsconfig.build.json +6 -7
  812. package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.test.ts +0 -269
  813. package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.test.ts +0 -492
  814. package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.test.ts +0 -383
  815. package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.test.ts +0 -188
  816. package/packages/cli/dist/commands/lifecycle.d.ts +0 -6
  817. package/packages/cli/dist/commands/lifecycle.js +0 -125
  818. package/packages/cli/dist/commands/lifecycle.js.map +0 -1
  819. package/packages/cli/dist/commands/test.d.ts +0 -6
  820. package/packages/cli/dist/commands/test.js +0 -373
  821. package/packages/cli/dist/commands/test.js.map +0 -1
  822. package/packages/cli/dist/commands/verifies.js +0 -87
  823. package/packages/cli/dist/commands/verifies.js.map +0 -1
  824. package/packages/cli/dist/commands/verify.d.ts +0 -6
  825. package/packages/cli/dist/commands/verify.js +0 -330
  826. package/packages/cli/dist/commands/verify.js.map +0 -1
@@ -1,755 +1,627 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { execFile } from 'node:child_process';
4
- import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
5
- import { tmpdir } from 'node:os';
6
- import path from 'node:path';
7
- import { promisify } from 'node:util';
8
-
9
- import { ingestArtifactResult } from '../artifacts/ingestion.js';
10
- import { initProject } from '../config/init-project.js';
11
- import { createDelegationRecord } from '../delegation/validation.js';
12
- import { writeArtifact } from '../run-state/artifacts.js';
13
- import { appendEvent, readRunEvents } from '../run-state/events.js';
14
- import { rebuildLocalRunIndex } from '../run-state/run-index.js';
15
- import { archiveRun, createRun, readRunState, writeRunState } from '../run-state/run-state.js';
16
- import { validResultArtifact, validTaskMarkdown, writeBranchDocs } from '../test-support/fixtures.js';
17
- import { bindTestRunState } from '../test-support/run-state.js';
18
- import { EVENT_LOG_CONTRACT, STAGE_RUN_CONTRACT_VERSION, SUBAGENT_DISPATCH_CONTRACT_VERSION, WORKFLOW_HANDOFF_CONTRACT_VERSION, type RuntimeScope } from '../contracts.js';
19
- import { recordStageRunProjection, recordWorkflowHandoffProjection, type StageRun, type WorkflowHandoff } from '../stage-runtime.js';
20
- import { decideContextOffload, evaluateContextLoadSignal, recordContextLoadSignalProjection, recordContextOffloadDecisionProjection } from '../context-offload.js';
21
- import { recordSubagentDispatchProjection, type SubagentDispatch } from '../subagents.js';
22
- import { runShip } from '../lifecycle/ship.js';
23
- import { listRuntimeRepairs, recordRuntimeCapabilityAdoption, recordRuntimeEvent, recordRuntimeTestRun, recordRuntimeTestStep, runtimeScopedId, withRuntimeStore } from '../storage/runtime-store.js';
24
- import { getProjectStatus } from '../status/project-status.js';
25
- import { writeVerifyContract } from '../verification/verify-contract.js';
26
- import { doctor } from './doctor.js';
27
-
28
- const execFileAsync = promisify(execFile);
29
-
30
-
31
- test('doctor reports AI entry drift after init', async () => {
32
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-drift-'));
33
- try {
34
- await initProject(root);
35
- const skillPath = path.join(root, '.claude', 'skills', 'sdd', 'SKILL.md');
36
- await writeFile(skillPath, `${await readFile(skillPath, 'utf8')}\nmanual drift\n`, 'utf8');
37
-
38
- const report = await doctor(root);
39
-
40
- assert.equal(report.status, 'FAIL');
41
- assert.equal(report.checks.some((check) => check.check === 'ai_entry_sdd' && check.level === 'FAIL' && /will not overwrite user-modified/.test(check.action ?? '')), true);
42
- } finally {
43
- await rm(root, { recursive: true, force: true });
44
- }
45
- });
46
-
47
- test('doctor reports missing git repo as fail in temp directory', async () => {
48
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-runtime-'));
49
- try {
50
- await initProject(root);
51
- const report = await doctor(root);
52
- assert.equal(report.status, 'FAIL');
53
- assert.equal(report.checks.some((check) => check.check === 'git_repo' && check.level === 'FAIL'), true);
54
- assert.equal(report.checks.some((check) => check.check === 'git_repo' && /git init/.test(check.action ?? '')), true);
55
- } finally {
56
- await rm(root, { recursive: true, force: true });
57
- }
58
- });
59
-
60
- test('doctor reports broken document-chain refs and high-risk evidence gaps', async () => {
61
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-document-chain-doctor-'));
62
- try {
63
- await initProject(root);
64
- await writeBranchDocs(root, 'master', `# Tasks
65
-
66
- ### D1: Broken document chain
67
-
68
- \`\`\`sdd-task
69
- id: D1
70
- status: pending
71
- wave: 1
72
- depends_on: []
73
- acceptance_refs:
74
- - AC-404
75
- affected_files:
76
- - packages/core/src/index.ts
77
- validation:
78
- - npm test
79
- risk:
80
- - database
81
- \`\`\`
82
-
83
- #### Boundary
84
-
85
- Stay inside document-chain checks.
86
-
87
- #### Acceptance
88
-
89
- - Broken ref is detected.
90
- `);
91
- await writeFile(path.join(root, 'specs', 'master', 'spec.md'), '# Spec\n\n| ID | Acceptance |\n|---|---|\n| AC-1 | Existing acceptance. |\n', 'utf8');
92
-
93
- const report = await doctor(root, { latestOnly: true });
94
-
95
- assert.equal(report.checks.some((check) => check.check === 'document_chain_acceptance_ref' && check.level === 'FAIL' && /AC-404/.test(check.message)), true);
96
- assert.equal(report.checks.some((check) => check.check === 'document_chain_high_risk_evidence' && check.level === 'FAIL' && /D1/.test(check.message)), true);
97
- } finally {
98
- await rm(root, { recursive: true, force: true });
99
- }
100
- });
101
-
102
- test('doctor reports local run index drift with rebuild action', async () => {
103
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-local-index-doctor-'));
104
- try {
105
- await initProject(root);
106
- const run = await createRun(root, { runId: 'run-1' });
107
- await rebuildLocalRunIndex(root);
108
- await writeRunState(root, { ...run, status: 'completed', tasks: { T2: { status: 'completed' } } });
109
-
110
- const report = await doctor(root);
111
-
112
- assert.equal(report.checks.some((check) => check.check === 'local_run_index' && check.level === 'WARN' && /rebuild/.test(check.action ?? '')), true);
113
- assert.equal(report.checks.some((check) => check.check === 'local_run_index_contract' && check.level === 'PASS'), true);
114
- } finally {
115
- await rm(root, { recursive: true, force: true });
116
- }
117
- });
118
-
119
- test('doctor reports artifact writes attached to unscoped runs', async () => {
120
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-artifact-scope-'));
121
- try {
122
- await initProject(root);
123
- const state = await createRun(root, { runId: 'run-1' });
124
- await writeArtifact(root, state.runId, 'review-T1.md', validResultArtifact('reviewer', 'T1', 'PASS', 'artifacts/review-T1.md'));
125
-
126
- const report = await doctor(root, { allRuns: true });
127
-
128
- assert.equal(report.checks.some((check) => check.check === 'artifact_scope' && check.level === 'FAIL' && /unscoped run/.test(check.message)), true);
129
- } finally {
130
- await rm(root, { recursive: true, force: true });
131
- }
132
- });
133
-
134
- test('doctor reports stale delegation and terminal event gaps without auto-fix', async () => {
135
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-hardening-'));
136
- try {
137
- await initProject(root);
138
- const state = await createRun(root, { runId: 'run-1' });
139
- const stale = createDelegationRecord({
140
- delegationId: 'D-T1-reviewer-001',
141
- task: 'T1',
142
- agent: 'reviewer',
143
- expectedArtifact: 'artifacts/review-T1.md',
144
- startedAt: '2020-01-01T00:00:00.000Z',
145
- timeoutSeconds: 1
146
- });
147
- const completed = createDelegationRecord({
148
- delegationId: 'D-T1-validator-001',
149
- task: 'T1',
150
- agent: 'validator',
151
- expectedArtifact: 'artifacts/validation-T1.md',
152
- status: 'COMPLETED'
153
- });
154
- await writeRunState(root, { ...state, delegations: { [stale.delegationId]: stale, [completed.delegationId]: completed } });
155
- await appendEvent(root, state.runId, { event: 'delegation_started', runId: state.runId, data: { delegationId: stale.delegationId } });
156
-
157
- const report = await doctor(root);
158
-
159
- assert.equal(report.status, 'FAIL');
160
- assert.equal(report.checks.some((check) => check.check === 'stale_delegation'), true);
161
- assert.equal(report.checks.some((check) => check.check === 'terminal_event_missing'), true);
162
- assert.equal(report.checks.some((check) => check.check === 'artifact_invalid'), true);
163
- } finally {
164
- await rm(root, { recursive: true, force: true });
165
- }
166
- });
167
-
168
- test('archiveRun cancels running delegations and normal doctor skips archived evidence', async () => {
169
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-archive-run-'));
170
- try {
171
- await initProject(root);
172
- const state = await createRun(root, { runId: 'run-1' });
173
- const running = createDelegationRecord({
174
- delegationId: 'D-T1-reviewer-001',
175
- task: 'T1',
176
- agent: 'reviewer',
177
- expectedArtifact: 'artifacts/review-T1.md',
178
- startedAt: '2020-01-01T00:00:00.000Z',
179
- timeoutSeconds: 1
180
- });
181
- await writeRunState(root, { ...state, delegations: { [running.delegationId]: running } });
182
- await appendEvent(root, state.runId, { event: 'delegation_started', runId: state.runId, data: { delegationId: running.delegationId } });
183
-
184
- const archived = await archiveRun(root, state.runId, { reason: 'exploratory failure' });
185
- const normalDoctor = await doctor(root);
186
- const allRunsDoctor = await doctor(root, { allRuns: true });
187
- const events = await readRunEvents(root, state.runId);
188
-
189
- assert.equal(archived.status, 'archived');
190
- assert.equal(archived.delegations[running.delegationId].status, 'CANCELLED');
191
- assert.equal(events.some((event) => event.event === 'delegation_cancelled'), true);
192
- assert.equal(events.some((event) => event.event === 'run_archived'), true);
193
- assert.equal(normalDoctor.checks.some((check) => check.check === 'stale_delegation'), false);
194
- assert.equal(normalDoctor.checks.some((check) => check.check === 'run_evidence_scope'), true);
195
- assert.equal(allRunsDoctor.checks.some((check) => check.check === 'stale_delegation'), false);
196
- } finally {
197
- await rm(root, { recursive: true, force: true });
198
- }
199
- });
200
-
201
- test('doctor latestOnly ignores older failed run evidence', async () => {
202
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-latest-only-'));
203
- try {
204
- await initProject(root);
205
- const older = await createRun(root, { runId: 'run-older' });
206
- const newer = await createRun(root, { runId: 'run-newer' });
207
- const stale = createDelegationRecord({
208
- delegationId: 'D-T1-reviewer-001',
209
- task: 'T1',
210
- agent: 'reviewer',
211
- expectedArtifact: 'artifacts/review-T1.md',
212
- startedAt: '2020-01-01T00:00:00.000Z',
213
- timeoutSeconds: 1
214
- });
215
- await writeRunState(root, { ...older, updatedAt: '2026-05-01T00:00:00.000Z', delegations: { [stale.delegationId]: stale } });
216
- await writeRunState(root, { ...newer, updatedAt: '2026-05-02T00:00:00.000Z' });
217
- await appendEvent(root, older.runId, { event: 'delegation_started', runId: older.runId, data: { delegationId: stale.delegationId } });
218
-
219
- const latestOnly = await doctor(root, { latestOnly: true });
220
- const allRuns = await doctor(root, { allRuns: true });
221
-
222
- assert.equal(latestOnly.checks.some((check) => check.check === 'stale_delegation'), false);
223
- assert.equal(latestOnly.checks.some((check) => check.check === 'run_evidence_fast_path'), true);
224
- assert.equal(allRuns.checks.some((check) => check.check === 'stale_delegation'), true);
225
- } finally {
226
- await rm(root, { recursive: true, force: true });
227
- }
228
- });
229
-
230
- test('doctor reports runtime performance observability warnings', async () => {
231
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-runtime-performance-doctor-'));
232
- try {
233
- await initProject(root);
234
- const staleRun = await createRun(root, { runId: 'run-stale' });
235
- const missingStepsRun = await createRun(root, { runId: 'run-missing-steps' });
236
- const waitingRun = await createRun(root, { runId: 'run-waiting' });
237
- const slowRun = await createRun(root, { runId: 'run-slow-validation' });
238
-
239
- const staleState = { ...staleRun, status: 'running' as const, updatedAt: '2020-01-01T00:00:00.000Z' };
240
- await withRuntimeStore(root, ({ db }) => {
241
- db.prepare('UPDATE runs SET status = ?, updated_at = ?, state_json = ?, state_hash = ? WHERE run_id = ?')
242
- .run(staleState.status, staleState.updatedAt, JSON.stringify(staleState), 'test-stale', staleState.runId);
243
- });
244
- await recordRuntimeTestRun(root, {
245
- testRunId: 'test-run-missing-steps',
246
- runId: missingStepsRun.runId,
247
- partition: 'master',
248
- taskId: 'T1',
249
- status: 'PASS',
250
- startedAt: '2026-05-01T00:00:00.000Z',
251
- completedAt: '2026-05-01T00:00:02.000Z',
252
- payload: {}
253
- });
254
- const waitingState = { ...waitingRun, createdAt: '2026-05-01T00:00:00.000Z', updatedAt: '2026-05-01T00:00:40.000Z' };
255
- await withRuntimeStore(root, ({ db }) => {
256
- db.prepare('DELETE FROM events WHERE run_id = ?').run(waitingRun.runId);
257
- db.prepare('UPDATE runs SET updated_at = ?, state_json = ?, state_hash = ? WHERE run_id = ?')
258
- .run(waitingState.updatedAt, JSON.stringify(waitingState), 'test-waiting', waitingState.runId);
259
- });
260
- await recordRuntimeEvent(root, { contract: EVENT_LOG_CONTRACT, runId: waitingRun.runId, time: '2026-05-01T00:00:00.000Z', event: 'agent_invocation_started' });
261
- await recordRuntimeEvent(root, { contract: EVENT_LOG_CONTRACT, runId: waitingRun.runId, time: '2026-05-01T00:00:30.000Z', event: 'run_context_bound' });
262
- await recordRuntimeTestRun(root, {
263
- testRunId: 'test-run-slow-validation',
264
- runId: slowRun.runId,
265
- partition: 'master',
266
- taskId: 'T1',
267
- status: 'PASS',
268
- startedAt: '2026-05-01T00:00:00.000Z',
269
- completedAt: '2026-05-01T00:01:00.000Z',
270
- payload: {}
271
- });
272
- await recordRuntimeTestStep(root, {
273
- stepId: 'test-run-slow-validation:001',
274
- testRunId: 'test-run-slow-validation',
275
- runId: slowRun.runId,
276
- taskId: 'T1',
277
- command: 'npm test',
278
- status: 'PASS',
279
- exitCode: 0,
280
- durationMs: 45_000,
281
- outputArtifact: 'artifacts/test-T1-001.log',
282
- payload: { startedAt: '2026-05-01T00:00:00.000Z', endedAt: '2026-05-01T00:00:45.000Z' }
283
- });
284
-
285
- const report = await doctor(root, { allRuns: true });
286
- const check = report.checks.find((candidate) => candidate.check === 'runtime_performance_observability');
287
-
288
- assert.equal(check?.level, 'WARN');
289
- assert.match(check?.message ?? '', /stale_open=.*run-stale/);
290
- assert.match(check?.message ?? '', /missing_test_steps=run-missing-steps/);
291
- assert.match(check?.message ?? '', /waiting_dominated=run-waiting:30000ms/);
292
- assert.match(check?.message ?? '', /host_no_output=run-waiting:30000ms/);
293
- assert.match(check?.message ?? '', /slow_validation=run-slow-validation:test-run-slow-validation:001:45000ms/);
294
- } finally {
295
- await rm(root, { recursive: true, force: true });
296
- }
297
- });
298
-
299
- test('doctor reports mixed-version recovery plan without legacy based_on repair', async () => {
300
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-mixed-version-recovery-'));
301
- try {
302
- await initProject(root);
303
- const taskMarkdown = validTaskMarkdown('T1', [])
304
- .replace('validation:\n - npm test', 'validation:\n - ```powershell npm test')
305
- .replace('risk: []', 'required_artifacts:\n - specs/feature/artifacts/implement-T1.md\nrisk: []');
306
- await writeBranchDocs(root, 'feature', taskMarkdown);
307
- await writeFile(path.join(root, 'specs', 'feature', 'verify.md'), '# Verify\n\nbased_on_tasks_hash: legacy\n', 'utf8');
308
-
309
- const report = await doctor(root, { branch: 'feature', latestOnly: true });
310
- const check = report.checks.find((candidate) => candidate.check === 'mixed_version_recovery');
311
-
312
- assert.equal(check?.level, 'FAIL');
313
- assert.match(check?.message ?? '', /issues=2/);
314
- assert.match(check?.message ?? '', /safe_fixes=1/);
315
- assert.match(check?.message ?? '', /behavior_changes=1/);
316
- assert.match(check?.message ?? '', /legacy_artifacts=none/);
317
- assert.match(check?.message ?? '', /sdd doctor --branch feature --latest-only/);
318
- assert.match(check?.action ?? '', /do not promote legacy stale runs as accepted truth/);
319
- } finally {
320
- await rm(root, { recursive: true, force: true });
321
- }
322
- });
323
-
324
-
325
- test('doctor trust suite flags mention-only acceptance and weak validator PASS artifacts', async () => {
326
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-trust-'));
327
- try {
328
- await initProject(root);
329
- await writeBranchDocs(root, 'feature', validTaskMarkdown('T1', []));
330
- const state = await createRun(root, { runId: 'run-1' });
331
- await bindTestRunState(root, state.runId, 'feature', 'T1');
332
- await writeArtifact(root, state.runId, 'validation-T1.md', validResultArtifact('validator', 'T1', 'PASS', 'artifacts/validation-T1.md'));
333
- const restored = await readRunState(root, state.runId);
334
- await writeRunState(root, {
335
- ...restored,
336
- status: 'completed',
337
- validation: {
338
- status: 'pass',
339
- commands: ['npm test'],
340
- evidence: ['artifacts/validation-T1.md']
341
- },
342
- tasks: {
343
- T1: {
344
- status: 'verified',
345
- verifyStatus: 'PASS',
346
- gaps: [],
347
- artifacts: ['artifacts/validation-T1.md'],
348
- acceptanceCoverage: [{ acceptance: 'AC-1', status: 'PASS', evidence: 'Mentioned in artifacts/validation-T1.md.' }]
349
- }
350
- },
351
- artifacts: [{ path: 'artifacts/validation-T1.md', kind: 'validation', task: 'T1', agent: 'validator', createdAt: new Date().toISOString() }]
352
- });
353
-
354
- const report = await doctor(root, { allRuns: true, branch: 'feature' });
355
-
356
- assert.equal(report.checks.some((check) => check.check === 'acceptance_trust' && check.level === 'FAIL'), true);
357
- assert.equal(report.checks.some((check) => check.check === 'artifact_trust' && check.level === 'FAIL' && /UNSOURCED_PASS/.test(check.message)), true);
358
- } finally {
359
- await rm(root, { recursive: true, force: true });
360
- }
361
- });
362
-
363
- test('doctor reports artifact ingestion state mismatch', async () => {
364
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-artifact-ingest-doctor-'));
365
- try {
366
- await initProject(root);
367
- const state = await createRun(root, { runId: 'run-1' });
368
- const delegation = createDelegationRecord({
369
- delegationId: 'D-T1-reviewer-001',
370
- task: 'T1',
371
- agent: 'reviewer',
372
- expectedArtifact: 'artifacts/review-T1.md'
373
- });
374
- await writeRunState(root, { ...state, delegations: { [delegation.delegationId]: delegation } });
375
- await appendEvent(root, state.runId, { event: 'delegation_started', runId: state.runId, data: { delegationId: delegation.delegationId } });
376
- await writeArtifact(root, state.runId, 'review-T1.md', `# Review
377
-
378
- \`\`\`sdd-result
379
- contract: sdd-result-v1
380
- version: 1.3.0
381
- agent: reviewer
382
- task: T1
383
- status: PASS
384
- artifacts:
385
- - artifacts/review-T1.md
386
- \`\`\`
387
- `);
388
- const ingested = await ingestArtifactResult(root, state.runId, { delegationId: delegation.delegationId, artifactPath: 'artifacts/review-T1.md' });
389
- const acceptedState = await readRunState(root, state.runId);
390
- await writeRunState(root, {
391
- ...acceptedState,
392
- artifacts: [],
393
- artifactIngestions: {
394
- [`${delegation.delegationId}:artifacts/review-T1.md`]: ingested.record
395
- }
396
- });
397
-
398
- const report = await doctor(root);
399
-
400
- assert.equal(report.status, 'FAIL');
401
- assert.equal(report.checks.some((check) => check.check === 'artifact_result_ingestion' && /missing from run artifact index/.test(check.message)), true);
402
- } finally {
403
- await rm(root, { recursive: true, force: true });
404
- }
405
- });
406
-
407
- test('doctor honors explicit branch for document-chain scope', async () => {
408
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-branch-'));
409
- try {
410
- await initProject(root);
411
- await execFileAsync('git', ['init'], { cwd: root });
412
- await execFileAsync('git', ['checkout', '-b', 'other'], { cwd: root });
413
-
414
- const report = await doctor(root, { latestOnly: true, branch: 'master' });
415
-
416
- assert.equal(report.checks.some((check) => /Document chain skipped for other/.test(check.message)), false);
417
- assert.equal(report.checks.some((check) => check.check.startsWith('document_chain')), true);
418
- } finally {
419
- await rm(root, { recursive: true, force: true });
420
- }
421
- });
422
-
423
- test('doctor reports workflow handoff state diagnostics', async () => {
424
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-handoff-'));
425
- try {
426
- await initProject(root);
427
- await recordStageRunProjection(root, doctorStageRun());
428
- await recordWorkflowHandoffProjection(root, doctorHandoff());
429
-
430
- const report = await doctor(root, { latestOnly: true, branch: 'master' });
431
-
432
- assert.equal(report.checks.some((check) => check.check === 'workflow_handoff_state' && check.level === 'PASS' && /status=fresh/.test(check.message)), true);
433
- assert.equal(report.checks.some((check) => check.check === 'workflow_handoff_state' && /do->test:accepted/.test(check.message)), true);
434
- } finally {
435
- await rm(root, { recursive: true, force: true });
436
- }
437
- });
438
-
439
- test('doctor reports context offload and subagent dispatch state diagnostics', async () => {
440
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-context-subagent-'));
441
- try {
442
- await initProject(root);
443
- const signal = evaluateContextLoadSignal({
444
- scope: doctorScope,
445
- refs: [{ kind: 'document', ref: 'specs/master/tasks.md' }],
446
- fileCount: 20,
447
- artifactBytes: 200_000,
448
- dependencyFanout: 12,
449
- unknownImpact: true,
450
- generatedAt: '2026-05-18T00:00:00.000Z'
451
- });
452
- await recordContextLoadSignalProjection(root, signal);
453
- await recordContextOffloadDecisionProjection(root, decideContextOffload(signal, { dispatchRefs: [{ kind: 'projection', ref: 'phase8_subagent_dispatch:master:T1:run-1:none:dispatch-1' }] }));
454
- await recordSubagentDispatchProjection(root, doctorSubagentDispatch());
455
-
456
- const report = await doctor(root, { latestOnly: true, branch: 'master' });
457
-
458
- assert.equal(report.checks.some((check) => check.check === 'context_offload_state' && check.level === 'PASS' && /level=high action=dispatch-subagent/.test(check.message)), true);
459
- assert.equal(report.checks.some((check) => check.check === 'subagent_dispatch_state' && check.level === 'FAIL' && /status=blocked/.test(check.message)), true);
460
- } finally {
461
- await rm(root, { recursive: true, force: true });
462
- }
463
- });
464
-
465
- test('archived failed subagent dispatch no longer blocks doctor or ship subagent gates', async () => {
466
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-archived-subagent-'));
467
- try {
468
- await initProject(root);
469
- await createRun(root, { runId: 'run-1' });
470
- await recordSubagentDispatchProjection(root, {
471
- ...doctorSubagentDispatch(),
472
- status: 'failed',
473
- updatedAt: '2026-05-18T00:02:00.000Z'
474
- });
475
- const failed = await doctor(root, { latestOnly: true, branch: 'master' });
476
- assert.equal(failed.checks.some((check) => check.check === 'subagent_dispatch_state' && check.level === 'FAIL' && /status=failed/.test(check.message)), true);
477
-
478
- await archiveRun(root, 'run-1', { reason: 'failed subagent superseded by rerun' });
479
- const recovered = await doctor(root, { latestOnly: true, branch: 'master' });
480
- const ship = await runShip(root, { branch: 'master', dryRun: true });
481
-
482
- assert.equal(recovered.checks.some((check) => check.check === 'subagent_dispatch_state' && check.level === 'PASS' && /status=missing/.test(check.message)), true);
483
- assert.equal(ship.checks.some((check) => check.name === 'subagent_dispatches' && check.status === 'PASS' && /status=missing/.test(check.message)), true);
484
- } finally {
485
- await rm(root, { recursive: true, force: true });
486
- }
487
- });
488
-
489
- test('doctor reports unavailable Phase 8 runtime checks as warnings', async () => {
490
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-runtime-unavailable-'));
491
- try {
492
- await initProject(root);
493
- await withRuntimeStore(root, ({ db }) => {
494
- db.prepare('INSERT INTO projections (projection_id, projection_type, scope_key, generated_at, payload_json) VALUES (?, ?, ?, ?, ?)')
495
- .run('bad-context-build', 'context_build', 'master:T1:run-1:none', new Date().toISOString(), '{');
496
- });
497
-
498
- const report = await doctor(root, { latestOnly: true, branch: 'master' });
499
- const warningRepairs = await listRuntimeRepairs(root, { branchSlug: 'master', status: 'open' });
500
-
501
- assert.equal(report.checks.some((check) => check.check === 'lifecycle_risk_decision' && check.level === 'WARN' && /unavailable/.test(check.message)), true);
502
- assert.equal(report.checks.some((check) => check.check === 'workflow_handoff_state' && check.level === 'WARN' && /unavailable/.test(check.message)), true);
503
- assert.equal(report.checks.some((check) => check.check === 'context_offload_state' && check.level === 'WARN' && /unavailable/.test(check.message)), true);
504
- assert.equal(report.checks.some((check) => check.check === 'subagent_dispatch_state' && check.level === 'WARN' && /unavailable/.test(check.message)), true);
505
- assert.equal(warningRepairs.some((repair) => repair.blockers.some((blocker) => /lifecycle_risk_decision|workflow_handoff_state|context_offload_state|subagent_dispatch_state/.test(blocker))), false);
506
- } finally {
507
- await rm(root, { recursive: true, force: true });
508
- }
509
- });
510
-
511
- test('Phase 8.28 blocks release-critical capability gaps until adoption is recorded', async () => {
512
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-capability-health-'));
513
- try {
514
- await initProject(root);
515
- await writeBranchDocs(root, 'master', capabilityHealthTaskMarkdown('SECURITY'));
516
-
517
- const status = await getProjectStatus(root, { branch: 'master' });
518
- const report = await doctor(root, { latestOnly: true, branch: 'master' });
519
- const ship = await runShip(root, { branch: 'master', dryRun: true });
520
- const doctorCheck = report.checks.find((check) => check.check === 'capability_health');
521
- const shipCheck = ship.checks.find((check) => check.name === 'capability_health');
522
-
523
- assert.equal(status.capabilityHealth.status, 'blocked');
524
- assert.equal(status.capabilityHealth.missingBaselineDomains.length, 0);
525
- assert.equal(status.capabilityHealth.sources.quarantined > 0, true);
526
- assert.equal(status.capabilityHealth.sources.denied > 0, true);
527
- assert.deepEqual(status.capabilityHealth.releaseCriticalGaps, ['security-engineering']);
528
- assert.equal(status.capabilityHealth.warnings.some((warning) => /release-critical capability gap security-engineering/.test(warning)), true);
529
- assert.equal(doctorCheck?.level, 'FAIL');
530
- assert.match(doctorCheck?.message ?? '', /release_critical_gaps=security-engineering/);
531
- assert.equal(shipCheck?.status, 'BLOCKED');
532
- const capabilityRepairs = await listRuntimeRepairs(root, { branchSlug: 'master', status: 'open' });
533
- assert.equal(capabilityRepairs.some((repair) => repair.blockers.some((blocker) => blocker.startsWith('capability_health:'))), false);
534
-
535
- await recordRuntimeCapabilityAdoption(root, {
536
- adoptionId: runtimeScopedId('capability-adoption', 'master', 'ship', 'security-engineering'),
537
- branchSlug: 'master',
538
- lifecycleStage: 'ship',
539
- capabilityDomain: 'security-engineering',
540
- sourceId: 'sdd_professional_baseline',
541
- status: 'rejected',
542
- reason: 'Security capability reviewed; no additional security evidence is required for this scoped release task.',
543
- evidenceRefs: ['tasks:SECURITY'],
544
- finalAuthority: 'sdd_gate',
545
- createdAt: '2026-05-27T00:00:00.000Z',
546
- updatedAt: '2026-05-27T00:00:00.000Z',
547
- payload: { releaseCritical: true }
548
- });
549
-
550
- const adoptedStatus = await getProjectStatus(root, { branch: 'master' });
551
- const adoptedReport = await doctor(root, { latestOnly: true, branch: 'master' });
552
- const adoptedShip = await runShip(root, { branch: 'master', dryRun: true });
553
- const adoptedDoctorCheck = adoptedReport.checks.find((check) => check.check === 'capability_health');
554
- const adoptedShipCheck = adoptedShip.checks.find((check) => check.name === 'capability_health');
555
-
556
- assert.equal(adoptedStatus.capabilityHealth.status, 'pass');
557
- assert.deepEqual(adoptedStatus.capabilityHealth.releaseCriticalGaps, []);
558
- assert.deepEqual(adoptedStatus.capabilityHealth.adoptions.releaseCriticalClosures, ['security-engineering']);
559
- assert.equal(adoptedDoctorCheck?.level, 'PASS');
560
- assert.match(adoptedDoctorCheck?.message ?? '', /adoption_closures=security-engineering/);
561
- assert.equal(adoptedShipCheck?.status, 'PASS');
562
- assert.match(adoptedShipCheck?.message ?? '', /adoption_closures=security-engineering/);
563
- assert.equal(adoptedShipCheck?.nextAction, undefined);
564
- } finally {
565
- await rm(root, { recursive: true, force: true });
566
- }
567
- });
568
-
569
- test('ship reports token pressure as diagnostic pass', async () => {
570
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-ship-token-diagnostic-'));
571
- try {
572
- await initProject(root);
573
- await withRuntimeStore(root, ({ db }) => {
574
- db.prepare('INSERT INTO projections (projection_id, projection_type, scope_key, generated_at, payload_json) VALUES (?, ?, ?, ?, ?)')
575
- .run('context-build-pressure', 'context_build', 'master:T1:run-1:none', '2026-05-18T00:00:00.000Z', JSON.stringify({
576
- taskId: 'T1',
577
- profile: 'normal',
578
- budget: { estimatedBytes: 900, maxBytes: 1000, estimatedTokens: 225 }
579
- }));
580
- });
581
-
582
- const ship = await runShip(root, { branch: 'master', dryRun: true });
583
- const tokenCheck = ship.checks.find((check) => check.name === 'token_health');
584
-
585
- assert.equal(tokenCheck?.status, 'PASS');
586
- assert.match(tokenCheck?.message ?? '', /token_health=pressure/);
587
- } finally {
588
- await rm(root, { recursive: true, force: true });
589
- }
590
- });
591
-
592
- test('ship accepts validated runs without requiring a removed sync-back stage', async () => {
593
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-ship-eight-stage-ready-'));
594
- try {
595
- await initProject(root);
596
- await writeBranchDocs(root, 'master', validTaskMarkdown('T1', []));
597
- await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option' });
598
- const state = await createRun(root, { runId: 'run-1' });
599
- await bindTestRunState(root, state.runId, 'master', 'T1');
600
- const bound = await readRunState(root, state.runId);
601
- await writeRunState(root, {
602
- ...bound,
603
- status: 'completed',
604
- validation: {
605
- status: 'pass',
606
- commands: ['npm test'],
607
- evidence: []
608
- }
609
- });
610
-
611
- const ship = await runShip(root, { branch: 'master', dryRun: true });
612
- const latestRunCheck = ship.checks.find((check) => check.name === 'latest_run');
613
-
614
- assert.equal(latestRunCheck?.status, 'PASS');
615
- assert.match(latestRunCheck?.message ?? '', /run=run-1 status=completed validation=pass/);
616
- } finally {
617
- await rm(root, { recursive: true, force: true });
618
- }
619
- });
620
-
621
- test('doctor does not report historical legacy file diagnostics', async () => {
622
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-phase818-doctor-'));
623
- try {
624
- await initProject(root);
625
- await writeBranchDocs(root, 'master', validTaskMarkdown('T1', []));
626
- const state = await createRun(root, { runId: 'run-1', branch: 'master', taskId: 'T1' });
627
- await writeArtifact(root, state.runId, 'review-T1.md', validResultArtifact('reviewer', 'T1', 'PASS', 'artifacts/review-T1.md'));
628
- const legacyRunDir = path.join(root, '.sdd', 'runs', state.runId);
629
- await mkdir(path.join(legacyRunDir, 'agent-executions'), { recursive: true });
630
- await writeFile(path.join(legacyRunDir, 'state.json'), '{}', 'utf8');
631
- await writeFile(path.join(legacyRunDir, 'events.jsonl'), '{}\n', 'utf8');
632
- await writeFile(path.join(legacyRunDir, 'invocations.jsonl'), '{}\n', 'utf8');
633
- await writeFile(path.join(legacyRunDir, 'agent-executions', 'legacy.json'), '{}', 'utf8');
634
- const report = await doctor(root, { allRuns: true, branch: 'master' });
635
-
636
- assert.equal(report.checks.some((check) => check.check === 'phase8_18_legacy_run_files'), false);
637
- assert.equal(report.checks.some((check) => check.check === 'phase8_18_legacy_sidecars'), false);
638
- } finally {
639
- await rm(root, { recursive: true, force: true });
640
- }
641
- });
642
-
643
- test('ship still blocks context offload curation', async () => {
644
- const root = await mkdtemp(path.join(tmpdir(), 'sdd-ship-context-curation-'));
645
- try {
646
- await initProject(root);
647
- const signal = evaluateContextLoadSignal({
648
- scope: doctorScope,
649
- fileCount: 50,
650
- artifactBytes: 600_000,
651
- dependencyFanout: 30,
652
- unknownImpact: true,
653
- generatedAt: '2026-05-18T00:00:00.000Z'
654
- });
655
- await recordContextLoadSignalProjection(root, signal);
656
- await recordContextOffloadDecisionProjection(root, decideContextOffload(signal));
657
-
658
- const ship = await runShip(root, { branch: 'master', dryRun: true });
659
- const contextCheck = ship.checks.find((check) => check.name === 'context_offload');
660
-
661
- assert.equal(contextCheck?.status, 'BLOCKED');
662
- assert.match(contextCheck?.message ?? '', /action=block-for-curation/);
663
- assert.equal(ship.nextActions.some((action) => /Curate context before ship/.test(action)), true);
664
- } finally {
665
- await rm(root, { recursive: true, force: true });
666
- }
667
- });
668
-
669
- function capabilityHealthTaskMarkdown(taskId: string): string {
670
- return `# Tasks
671
-
672
- ### ${taskId}: Security readiness task
673
-
674
- \`\`\`sdd-task
675
- id: ${taskId}
676
- status: pending
677
- wave: 1
678
- depends_on: []
679
- acceptance_refs:
680
- - AC-1
681
- affected_files:
682
- - packages/core/src/auth.ts
683
- validation:
684
- - npm test
685
- risk:
686
- - security
687
- \`\`\`
688
-
689
- #### Boundary
690
-
691
- Stay inside security readiness fixtures.
692
-
693
- #### Acceptance
694
-
695
- - AC-1: Security readiness is covered.
696
- `;
697
- }
698
-
699
- const doctorScope: RuntimeScope = { branch: 'master', taskId: 'T1', runId: 'run-1' };
700
-
701
- function doctorStageRun(): StageRun {
702
- return {
703
- contract: STAGE_RUN_CONTRACT_VERSION,
704
- id: 'doctor-stage-do',
705
- scope: doctorScope,
706
- stage: 'do',
707
- ownerAgent: 'implementer',
708
- coMainAgents: ['reviewer'],
709
- status: 'completed',
710
- inputRefs: [{ kind: 'projection', ref: 'phase8_lifecycle_risk_decision:master:T1:run-1:none' }],
711
- outputRefs: [{ kind: 'artifact', ref: 'artifacts/doctor-handoff.md' }],
712
- decisionRefs: [{ kind: 'projection', ref: 'phase8_lifecycle_risk_decision:master:T1:run-1:none' }],
713
- blockingReasons: [],
714
- createdAt: '2026-05-18T00:00:00.000Z',
715
- updatedAt: '2026-05-18T00:01:00.000Z'
716
- };
717
- }
718
-
719
- function doctorHandoff(): WorkflowHandoff {
720
- return {
721
- contract: WORKFLOW_HANDOFF_CONTRACT_VERSION,
722
- id: 'doctor-handoff-do-test',
723
- scope: doctorScope,
724
- fromStage: 'do',
725
- toStage: 'test',
726
- fromAgent: 'implementer',
727
- toAgent: 'validator',
728
- status: 'accepted',
729
- outputRefs: [{ kind: 'artifact', ref: 'artifacts/doctor-handoff.md' }],
730
- requiredInputRefs: [{ kind: 'projection', ref: 'phase8_lifecycle_risk_decision:master:T1:run-1:none' }],
731
- riskDecisionRef: { kind: 'projection', ref: 'phase8_lifecycle_risk_decision:master:T1:run-1:none' },
732
- evidenceRefs: [{ kind: 'evidence', ref: 'artifacts/doctor-handoff-validation.md#AC-1' }],
733
- openQuestions: [],
734
- blockingGaps: [],
735
- createdAt: '2026-05-18T00:02:00.000Z',
736
- decidedAt: '2026-05-18T00:03:00.000Z'
737
- };
738
- }
739
-
740
- function doctorSubagentDispatch(): SubagentDispatch {
741
- return {
742
- contract: SUBAGENT_DISPATCH_CONTRACT_VERSION,
743
- id: 'dispatch-1',
744
- scope: doctorScope,
745
- workUnitId: 'wu-subagent-1',
746
- definitionName: 'test-writer',
747
- mode: 'background',
748
- status: 'queued',
749
- blocking: true,
750
- requiredBefore: 'handoff',
751
- contextRef: { kind: 'projection', ref: 'sdd-scoped-context-handoff:T1' },
752
- createdAt: '2026-05-18T00:00:00.000Z',
753
- updatedAt: '2026-05-18T00:01:00.000Z'
754
- };
755
- }
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { execFile } from 'node:child_process';
4
+ import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
5
+ import { tmpdir } from 'node:os';
6
+ import path from 'node:path';
7
+ import { promisify } from 'node:util';
8
+
9
+ import { ingestArtifactResult } from '../artifacts/ingestion.js';
10
+ import { initProject } from '../config/init-project.js';
11
+ import { createDelegationRecord } from '../delegation/validation.js';
12
+ import { writeArtifact } from '../run-state/artifacts.js';
13
+ import { appendEvent, readRunEvents } from '../run-state/events.js';
14
+ import { rebuildLocalRunIndex } from '../run-state/run-index.js';
15
+ import { archiveRun, createRun, readRunState, writeRunState } from '../run-state/run-state.js';
16
+ import { validResultArtifact, validTaskMarkdown, writeBranchDocs } from '../test-support/fixtures.js';
17
+ import { bindTestRunState } from '../test-support/run-state.js';
18
+ import { STAGE_RUN_CONTRACT_VERSION, SUBAGENT_DISPATCH_CONTRACT_VERSION, WORKFLOW_HANDOFF_CONTRACT_VERSION, type RuntimeScope } from '../contracts.js';
19
+ import { recordStageRunProjection, recordWorkflowHandoffProjection, type StageRun, type WorkflowHandoff } from '../stage-runtime.js';
20
+ import { decideContextOffload, evaluateContextLoadSignal, recordContextLoadSignalProjection, recordContextOffloadDecisionProjection } from '../context-offload.js';
21
+ import { recordSubagentDispatchProjection, type SubagentDispatch } from '../subagents.js';
22
+ import { runShip } from '../lifecycle/ship.js';
23
+ import { withRuntimeStore } from '../storage/runtime-store.js';
24
+ import { getProjectStatus } from '../status/project-status.js';
25
+ import { doctor } from './doctor.js';
26
+
27
+ const execFileAsync = promisify(execFile);
28
+
29
+
30
+ test('doctor reports AI entry drift after init', async () => {
31
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-drift-'));
32
+ try {
33
+ await initProject(root);
34
+ const skillPath = path.join(root, '.claude', 'skills', 'sdd', 'SKILL.md');
35
+ await writeFile(skillPath, `${await readFile(skillPath, 'utf8')}\nmanual drift\n`, 'utf8');
36
+
37
+ const report = await doctor(root);
38
+
39
+ assert.equal(report.status, 'FAIL');
40
+ assert.equal(report.checks.some((check) => check.check === 'ai_entry_sdd' && check.level === 'FAIL' && /will not overwrite user-modified/.test(check.action ?? '')), true);
41
+ } finally {
42
+ await rm(root, { recursive: true, force: true });
43
+ }
44
+ });
45
+
46
+ test('doctor reports missing git repo as fail in temp directory', async () => {
47
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-runtime-'));
48
+ try {
49
+ await initProject(root);
50
+ const report = await doctor(root);
51
+ assert.equal(report.status, 'FAIL');
52
+ assert.equal(report.checks.some((check) => check.check === 'git_repo' && check.level === 'FAIL'), true);
53
+ assert.equal(report.checks.some((check) => check.check === 'git_repo' && /git init/.test(check.action ?? '')), true);
54
+ } finally {
55
+ await rm(root, { recursive: true, force: true });
56
+ }
57
+ });
58
+
59
+ test('doctor reports broken document-chain refs and high-risk evidence gaps', async () => {
60
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-document-chain-doctor-'));
61
+ try {
62
+ await initProject(root);
63
+ await writeBranchDocs(root, 'master', `# Tasks
64
+
65
+ ### D1: Broken document chain
66
+
67
+ \`\`\`sdd-task
68
+ id: D1
69
+ status: pending
70
+ wave: 1
71
+ depends_on: []
72
+ acceptance_refs:
73
+ - AC-404
74
+ affected_files:
75
+ - packages/core/src/index.ts
76
+ validation:
77
+ - npm test
78
+ risk:
79
+ - database
80
+ \`\`\`
81
+
82
+ #### Boundary
83
+
84
+ Stay inside document-chain checks.
85
+
86
+ #### Acceptance
87
+
88
+ - Broken ref is detected.
89
+ `);
90
+ await writeFile(path.join(root, 'specs', 'master', 'spec.md'), '# Spec\n\n| ID | Acceptance |\n|---|---|\n| AC-1 | Existing acceptance. |\n', 'utf8');
91
+
92
+ const report = await doctor(root, { latestOnly: true });
93
+
94
+ assert.equal(report.checks.some((check) => check.check === 'document_chain_acceptance_ref' && check.level === 'FAIL' && /AC-404/.test(check.message)), true);
95
+ assert.equal(report.checks.some((check) => check.check === 'document_chain_high_risk_evidence' && check.level === 'FAIL' && /D1/.test(check.message)), true);
96
+ } finally {
97
+ await rm(root, { recursive: true, force: true });
98
+ }
99
+ });
100
+
101
+ test('doctor reports local run index drift with rebuild action', async () => {
102
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-local-index-doctor-'));
103
+ try {
104
+ await initProject(root);
105
+ const run = await createRun(root, { runId: 'run-1' });
106
+ await rebuildLocalRunIndex(root);
107
+ await writeRunState(root, { ...run, status: 'completed', tasks: { T2: { status: 'completed' } } });
108
+
109
+ const report = await doctor(root);
110
+
111
+ assert.equal(report.checks.some((check) => check.check === 'local_run_index' && check.level === 'WARN' && /rebuild/.test(check.action ?? '')), true);
112
+ assert.equal(report.checks.some((check) => check.check === 'local_run_index_contract' && check.level === 'PASS'), true);
113
+ } finally {
114
+ await rm(root, { recursive: true, force: true });
115
+ }
116
+ });
117
+
118
+ test('doctor reports artifact writes attached to unscoped runs', async () => {
119
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-artifact-scope-'));
120
+ try {
121
+ await initProject(root);
122
+ const state = await createRun(root, { runId: 'run-1' });
123
+ await writeArtifact(root, state.runId, 'review-T1.md', validResultArtifact('reviewer', 'T1', 'PASS', 'artifacts/review-T1.md'));
124
+
125
+ const report = await doctor(root, { allRuns: true });
126
+
127
+ assert.equal(report.checks.some((check) => check.check === 'artifact_scope' && check.level === 'FAIL' && /unscoped run/.test(check.message)), true);
128
+ } finally {
129
+ await rm(root, { recursive: true, force: true });
130
+ }
131
+ });
132
+
133
+ test('doctor reports stale delegation and terminal event gaps without auto-fix', async () => {
134
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-hardening-'));
135
+ try {
136
+ await initProject(root);
137
+ const state = await createRun(root, { runId: 'run-1' });
138
+ const stale = createDelegationRecord({
139
+ delegationId: 'D-T1-reviewer-001',
140
+ task: 'T1',
141
+ agent: 'reviewer',
142
+ expectedArtifact: 'artifacts/review-T1.md',
143
+ startedAt: '2020-01-01T00:00:00.000Z',
144
+ timeoutSeconds: 1
145
+ });
146
+ const completed = createDelegationRecord({
147
+ delegationId: 'D-T1-validator-001',
148
+ task: 'T1',
149
+ agent: 'validator',
150
+ expectedArtifact: 'artifacts/validation-T1.md',
151
+ status: 'COMPLETED'
152
+ });
153
+ await writeRunState(root, { ...state, delegations: { [stale.delegationId]: stale, [completed.delegationId]: completed } });
154
+ await appendEvent(root, state.runId, { event: 'delegation_started', runId: state.runId, data: { delegationId: stale.delegationId } });
155
+
156
+ const report = await doctor(root);
157
+
158
+ assert.equal(report.status, 'FAIL');
159
+ assert.equal(report.checks.some((check) => check.check === 'stale_delegation'), true);
160
+ assert.equal(report.checks.some((check) => check.check === 'terminal_event_missing'), true);
161
+ assert.equal(report.checks.some((check) => check.check === 'artifact_invalid'), true);
162
+ } finally {
163
+ await rm(root, { recursive: true, force: true });
164
+ }
165
+ });
166
+
167
+ test('archiveRun cancels running delegations and normal doctor skips archived evidence', async () => {
168
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-archive-run-'));
169
+ try {
170
+ await initProject(root);
171
+ const state = await createRun(root, { runId: 'run-1' });
172
+ const running = createDelegationRecord({
173
+ delegationId: 'D-T1-reviewer-001',
174
+ task: 'T1',
175
+ agent: 'reviewer',
176
+ expectedArtifact: 'artifacts/review-T1.md',
177
+ startedAt: '2020-01-01T00:00:00.000Z',
178
+ timeoutSeconds: 1
179
+ });
180
+ await writeRunState(root, { ...state, delegations: { [running.delegationId]: running } });
181
+ await appendEvent(root, state.runId, { event: 'delegation_started', runId: state.runId, data: { delegationId: running.delegationId } });
182
+
183
+ const archived = await archiveRun(root, state.runId, { reason: 'exploratory failure' });
184
+ const normalDoctor = await doctor(root);
185
+ const allRunsDoctor = await doctor(root, { allRuns: true });
186
+ const events = await readRunEvents(root, state.runId);
187
+
188
+ assert.equal(archived.status, 'archived');
189
+ assert.equal(archived.delegations[running.delegationId].status, 'CANCELLED');
190
+ assert.equal(events.some((event) => event.event === 'delegation_cancelled'), true);
191
+ assert.equal(events.some((event) => event.event === 'run_archived'), true);
192
+ assert.equal(normalDoctor.checks.some((check) => check.check === 'stale_delegation'), false);
193
+ assert.equal(normalDoctor.checks.some((check) => check.check === 'run_evidence_scope'), true);
194
+ assert.equal(allRunsDoctor.checks.some((check) => check.check === 'stale_delegation'), false);
195
+ } finally {
196
+ await rm(root, { recursive: true, force: true });
197
+ }
198
+ });
199
+
200
+ test('doctor latestOnly ignores older failed run evidence', async () => {
201
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-latest-only-'));
202
+ try {
203
+ await initProject(root);
204
+ const older = await createRun(root, { runId: 'run-older' });
205
+ const newer = await createRun(root, { runId: 'run-newer' });
206
+ const stale = createDelegationRecord({
207
+ delegationId: 'D-T1-reviewer-001',
208
+ task: 'T1',
209
+ agent: 'reviewer',
210
+ expectedArtifact: 'artifacts/review-T1.md',
211
+ startedAt: '2020-01-01T00:00:00.000Z',
212
+ timeoutSeconds: 1
213
+ });
214
+ await writeRunState(root, { ...older, updatedAt: '2026-05-01T00:00:00.000Z', delegations: { [stale.delegationId]: stale } });
215
+ await writeRunState(root, { ...newer, updatedAt: '2026-05-02T00:00:00.000Z' });
216
+ await appendEvent(root, older.runId, { event: 'delegation_started', runId: older.runId, data: { delegationId: stale.delegationId } });
217
+
218
+ const latestOnly = await doctor(root, { latestOnly: true });
219
+ const allRuns = await doctor(root, { allRuns: true });
220
+
221
+ assert.equal(latestOnly.checks.some((check) => check.check === 'stale_delegation'), false);
222
+ assert.equal(latestOnly.checks.some((check) => check.check === 'run_evidence_fast_path'), true);
223
+ assert.equal(allRuns.checks.some((check) => check.check === 'stale_delegation'), true);
224
+ } finally {
225
+ await rm(root, { recursive: true, force: true });
226
+ }
227
+ });
228
+
229
+ test('doctor trust suite flags mention-only acceptance and weak validator PASS artifacts', async () => {
230
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-trust-'));
231
+ try {
232
+ await initProject(root);
233
+ await writeBranchDocs(root, 'feature', validTaskMarkdown('T1', []));
234
+ const state = await createRun(root, { runId: 'run-1' });
235
+ await bindTestRunState(root, state.runId, 'feature', 'T1');
236
+ await writeArtifact(root, state.runId, 'validation-T1.md', validResultArtifact('validator', 'T1', 'PASS', 'artifacts/validation-T1.md'));
237
+ const restored = await readRunState(root, state.runId);
238
+ await writeRunState(root, {
239
+ ...restored,
240
+ status: 'completed',
241
+ validation: {
242
+ status: 'pass',
243
+ commands: ['npm test'],
244
+ evidence: ['artifacts/validation-T1.md']
245
+ },
246
+ tasks: {
247
+ T1: {
248
+ status: 'verified',
249
+ verifyStatus: 'PASS',
250
+ gaps: [],
251
+ artifacts: ['artifacts/validation-T1.md'],
252
+ acceptanceCoverage: [{ acceptance: 'AC-1', status: 'PASS', evidence: 'Mentioned in artifacts/validation-T1.md.' }]
253
+ }
254
+ },
255
+ artifacts: [{ path: 'artifacts/validation-T1.md', kind: 'validation', task: 'T1', agent: 'validator', createdAt: new Date().toISOString() }]
256
+ });
257
+
258
+ const report = await doctor(root, { allRuns: true, branch: 'feature' });
259
+
260
+ assert.equal(report.checks.some((check) => check.check === 'acceptance_trust' && check.level === 'FAIL'), true);
261
+ assert.equal(report.checks.some((check) => check.check === 'artifact_trust' && check.level === 'FAIL' && /UNSOURCED_PASS/.test(check.message)), true);
262
+ } finally {
263
+ await rm(root, { recursive: true, force: true });
264
+ }
265
+ });
266
+
267
+ test('doctor reports artifact ingestion state mismatch', async () => {
268
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-artifact-ingest-doctor-'));
269
+ try {
270
+ await initProject(root);
271
+ const state = await createRun(root, { runId: 'run-1' });
272
+ const delegation = createDelegationRecord({
273
+ delegationId: 'D-T1-reviewer-001',
274
+ task: 'T1',
275
+ agent: 'reviewer',
276
+ expectedArtifact: 'artifacts/review-T1.md'
277
+ });
278
+ await writeRunState(root, { ...state, delegations: { [delegation.delegationId]: delegation } });
279
+ await appendEvent(root, state.runId, { event: 'delegation_started', runId: state.runId, data: { delegationId: delegation.delegationId } });
280
+ await writeArtifact(root, state.runId, 'review-T1.md', `# Review
281
+
282
+ \`\`\`sdd-result
283
+ contract: sdd-result-v1
284
+ version: 1.3.0
285
+ agent: reviewer
286
+ task: T1
287
+ status: PASS
288
+ artifacts:
289
+ - artifacts/review-T1.md
290
+ \`\`\`
291
+ `);
292
+ const ingested = await ingestArtifactResult(root, state.runId, { delegationId: delegation.delegationId, artifactPath: 'artifacts/review-T1.md' });
293
+ const acceptedState = await readRunState(root, state.runId);
294
+ await writeRunState(root, {
295
+ ...acceptedState,
296
+ artifacts: [],
297
+ artifactIngestions: {
298
+ [`${delegation.delegationId}:artifacts/review-T1.md`]: ingested.record
299
+ }
300
+ });
301
+
302
+ const report = await doctor(root);
303
+
304
+ assert.equal(report.status, 'FAIL');
305
+ assert.equal(report.checks.some((check) => check.check === 'artifact_result_ingestion' && /missing from run artifact index/.test(check.message)), true);
306
+ } finally {
307
+ await rm(root, { recursive: true, force: true });
308
+ }
309
+ });
310
+
311
+ test('doctor honors explicit branch for document-chain scope', async () => {
312
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-branch-'));
313
+ try {
314
+ await initProject(root);
315
+ await execFileAsync('git', ['init'], { cwd: root });
316
+ await execFileAsync('git', ['checkout', '-b', 'other'], { cwd: root });
317
+
318
+ const report = await doctor(root, { latestOnly: true, branch: 'master' });
319
+
320
+ assert.equal(report.checks.some((check) => /Document chain skipped for other/.test(check.message)), false);
321
+ assert.equal(report.checks.some((check) => check.check.startsWith('document_chain')), true);
322
+ } finally {
323
+ await rm(root, { recursive: true, force: true });
324
+ }
325
+ });
326
+
327
+ test('doctor reports workflow handoff state diagnostics', async () => {
328
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-handoff-'));
329
+ try {
330
+ await initProject(root);
331
+ await recordStageRunProjection(root, doctorStageRun());
332
+ await recordWorkflowHandoffProjection(root, doctorHandoff());
333
+
334
+ const report = await doctor(root, { latestOnly: true, branch: 'master' });
335
+
336
+ assert.equal(report.checks.some((check) => check.check === 'workflow_handoff_state' && check.level === 'PASS' && /status=fresh/.test(check.message)), true);
337
+ assert.equal(report.checks.some((check) => check.check === 'workflow_handoff_state' && /do->test:accepted/.test(check.message)), true);
338
+ } finally {
339
+ await rm(root, { recursive: true, force: true });
340
+ }
341
+ });
342
+
343
+ test('doctor reports context offload and subagent dispatch state diagnostics', async () => {
344
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-context-subagent-'));
345
+ try {
346
+ await initProject(root);
347
+ const signal = evaluateContextLoadSignal({
348
+ scope: doctorScope,
349
+ refs: [{ kind: 'document', ref: 'specs/master/tasks.md' }],
350
+ fileCount: 20,
351
+ artifactBytes: 200_000,
352
+ dependencyFanout: 12,
353
+ unknownImpact: true,
354
+ generatedAt: '2026-05-18T00:00:00.000Z'
355
+ });
356
+ await recordContextLoadSignalProjection(root, signal);
357
+ await recordContextOffloadDecisionProjection(root, decideContextOffload(signal, { dispatchRefs: [{ kind: 'projection', ref: 'phase8_subagent_dispatch:master:T1:run-1:none:dispatch-1' }] }));
358
+ await recordSubagentDispatchProjection(root, doctorSubagentDispatch());
359
+
360
+ const report = await doctor(root, { latestOnly: true, branch: 'master' });
361
+
362
+ assert.equal(report.checks.some((check) => check.check === 'context_offload_state' && check.level === 'PASS' && /level=high action=dispatch-subagent/.test(check.message)), true);
363
+ assert.equal(report.checks.some((check) => check.check === 'subagent_dispatch_state' && check.level === 'FAIL' && /status=blocked/.test(check.message)), true);
364
+ } finally {
365
+ await rm(root, { recursive: true, force: true });
366
+ }
367
+ });
368
+
369
+ test('archived failed subagent dispatch no longer blocks doctor diagnostics', async () => {
370
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-archived-subagent-'));
371
+ try {
372
+ await initProject(root);
373
+ await createRun(root, { runId: 'run-1' });
374
+ await recordSubagentDispatchProjection(root, {
375
+ ...doctorSubagentDispatch(),
376
+ status: 'failed',
377
+ updatedAt: '2026-05-18T00:02:00.000Z'
378
+ });
379
+ const failed = await doctor(root, { latestOnly: true, branch: 'master' });
380
+ assert.equal(failed.checks.some((check) => check.check === 'subagent_dispatch_state' && check.level === 'FAIL' && /status=failed/.test(check.message)), true);
381
+
382
+ await archiveRun(root, 'run-1', { reason: 'failed subagent superseded by rerun' });
383
+ const recovered = await doctor(root, { latestOnly: true, branch: 'master' });
384
+
385
+ assert.equal(recovered.checks.some((check) => check.check === 'subagent_dispatch_state' && check.level === 'PASS' && /status=missing/.test(check.message)), true);
386
+ } finally {
387
+ await rm(root, { recursive: true, force: true });
388
+ }
389
+ });
390
+
391
+ test('doctor reports unavailable Phase 8 runtime checks as warnings', async () => {
392
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-doctor-runtime-unavailable-'));
393
+ try {
394
+ await initProject(root);
395
+ await withRuntimeStore(root, ({ db }) => {
396
+ db.prepare('INSERT INTO projections (projection_id, projection_type, scope_key, generated_at, payload_json) VALUES (?, ?, ?, ?, ?)')
397
+ .run('bad-context-build', 'context_build', 'master:T1:run-1:none', new Date().toISOString(), '{');
398
+ });
399
+
400
+ const report = await doctor(root, { latestOnly: true, branch: 'master' });
401
+
402
+ assert.equal(report.checks.some((check) => check.check === 'lifecycle_risk_decision' && check.level === 'WARN' && /unavailable/.test(check.message)), true);
403
+ assert.equal(report.checks.some((check) => check.check === 'workflow_handoff_state' && check.level === 'WARN' && /unavailable/.test(check.message)), true);
404
+ assert.equal(report.checks.some((check) => check.check === 'context_offload_state' && check.level === 'WARN' && /unavailable/.test(check.message)), true);
405
+ assert.equal(report.checks.some((check) => check.check === 'subagent_dispatch_state' && check.level === 'WARN' && /unavailable/.test(check.message)), true);
406
+ } finally {
407
+ await rm(root, { recursive: true, force: true });
408
+ }
409
+ });
410
+
411
+ test('Phase 8.9 surfaces capability health in status, doctor, and ship gates', async () => {
412
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-capability-health-'));
413
+ try {
414
+ await initProject(root);
415
+ await writeBranchDocs(root, 'master', capabilityHealthTaskMarkdown('SECURITY'));
416
+
417
+ const status = await getProjectStatus(root, { branch: 'master' });
418
+ const report = await doctor(root, { latestOnly: true, branch: 'master' });
419
+ const ship = await runShip(root, { branch: 'master', dryRun: true });
420
+ const doctorCheck = report.checks.find((check) => check.check === 'capability_health');
421
+
422
+ assert.equal(status.capabilityHealth.status, 'warn');
423
+ assert.equal(status.capabilityHealth.missingBaselineDomains.length, 0);
424
+ assert.equal(status.capabilityHealth.sources.quarantined > 0, true);
425
+ assert.equal(status.capabilityHealth.sources.denied > 0, true);
426
+ assert.deepEqual(status.capabilityHealth.releaseCriticalGaps, ['security-engineering']);
427
+ assert.equal(status.capabilityHealth.warnings.some((warning) => /release-critical capability gap security-engineering/.test(warning)), true);
428
+ assert.equal(doctorCheck?.level, 'WARN');
429
+ assert.match(doctorCheck?.message ?? '', /release_critical_gaps=security-engineering/);
430
+ assert.deepEqual(ship.projectStatus.capabilityHealth.releaseCriticalGaps, ['security-engineering']);
431
+ } finally {
432
+ await rm(root, { recursive: true, force: true });
433
+ }
434
+ });
435
+
436
+ test('ship reports token pressure as diagnostic pass', async () => {
437
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-ship-token-diagnostic-'));
438
+ try {
439
+ await initProject(root);
440
+ await withRuntimeStore(root, ({ db }) => {
441
+ db.prepare('INSERT INTO projections (projection_id, projection_type, scope_key, generated_at, payload_json) VALUES (?, ?, ?, ?, ?)')
442
+ .run('context-build-pressure', 'context_build', 'master:T1:run-1:none', '2026-05-18T00:00:00.000Z', JSON.stringify({
443
+ taskId: 'T1',
444
+ profile: 'normal',
445
+ budget: { estimatedBytes: 900, maxBytes: 1000, estimatedTokens: 225 }
446
+ }));
447
+ });
448
+
449
+ const ship = await runShip(root, { branch: 'master', dryRun: true });
450
+
451
+ assert.equal(ship.projectStatus.tokenProjection.health, 'pressure');
452
+ } finally {
453
+ await rm(root, { recursive: true, force: true });
454
+ }
455
+ });
456
+
457
+ test.skip('ship accepts validated runs without requiring sync-back apply', async () => {
458
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-ship-syncback-not-required-'));
459
+ try {
460
+ await initProject(root);
461
+ await writeBranchDocs(root, 'master', validTaskMarkdown('T1', []));
462
+ const state = await createRun(root, { runId: 'run-1' });
463
+ await bindTestRunState(root, state.runId, 'master', 'T1');
464
+ const bound = await readRunState(root, state.runId);
465
+ await writeRunState(root, {
466
+ ...bound,
467
+ status: 'completed',
468
+ validation: {
469
+ status: 'pass',
470
+ commands: ['npm test'],
471
+ evidence: []
472
+ }
473
+ });
474
+
475
+ const ship = await runShip(root, { branch: 'master', dryRun: true });
476
+ const latestRunCheck = ship.checks.find((check) => check.name === 'latest_run');
477
+
478
+ assert.equal(latestRunCheck?.status, 'PASS');
479
+ assert.match(latestRunCheck?.message ?? '', /sync_back=not_created/);
480
+ } finally {
481
+ await rm(root, { recursive: true, force: true });
482
+ }
483
+ });
484
+
485
+ test.skip('doctor reports Phase 8.18 compatibility and Phase 9 readiness diagnostics', async () => {
486
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-phase818-doctor-'));
487
+ try {
488
+ await initProject(root);
489
+ await writeBranchDocs(root, 'master', validTaskMarkdown('T1', []));
490
+ const state = await createRun(root, { runId: 'run-1', branch: 'master', taskId: 'T1' });
491
+ await writeArtifact(root, state.runId, 'review-T1.md', validResultArtifact('reviewer', 'T1', 'PASS', 'artifacts/review-T1.md'));
492
+ const legacyRunDir = path.join(root, '.sdd', 'runs', state.runId);
493
+ await mkdir(path.join(legacyRunDir, 'agent-executions'), { recursive: true });
494
+ await writeFile(path.join(legacyRunDir, 'state.json'), '{}', 'utf8');
495
+ await writeFile(path.join(legacyRunDir, 'events.jsonl'), '{}\n', 'utf8');
496
+ await writeFile(path.join(legacyRunDir, 'invocations.jsonl'), '{}\n', 'utf8');
497
+ await writeFile(path.join(legacyRunDir, 'agent-executions', 'legacy.json'), '{}', 'utf8');
498
+
499
+ const report = await doctor(root, { allRuns: true, branch: 'master' });
500
+
501
+ const legacyRunFiles = report.checks.find((check) => check.check === 'phase8_18_legacy_run_files');
502
+ assert.equal(legacyRunFiles?.level, 'WARN');
503
+ assert.match(legacyRunFiles?.message ?? '', /run-1:state\.json/);
504
+ assert.match(legacyRunFiles?.message ?? '', /run-1:events\.jsonl/);
505
+ assert.match(legacyRunFiles?.message ?? '', /run-1:invocations\.jsonl/);
506
+ assert.doesNotMatch(legacyRunFiles?.message ?? '', /evidence/);
507
+ assert.equal(report.checks.some((check) => check.check === 'phase8_18_legacy_sidecars' && check.level === 'WARN' && /run-1/.test(check.message)), true);
508
+ assert.equal(report.checks.some((check) => check.check === 'phase9_readiness' && check.level === 'PASS' && /optional_advisory_only/.test(check.message)), true);
509
+ } finally {
510
+ await rm(root, { recursive: true, force: true });
511
+ }
512
+ });
513
+
514
+ test('ship blocks context offload curation through doctor gate', async () => {
515
+ const root = await mkdtemp(path.join(tmpdir(), 'sdd-ship-context-curation-'));
516
+ try {
517
+ await initProject(root);
518
+ const signal = evaluateContextLoadSignal({
519
+ scope: doctorScope,
520
+ fileCount: 50,
521
+ artifactBytes: 600_000,
522
+ dependencyFanout: 30,
523
+ unknownImpact: true,
524
+ generatedAt: '2026-05-18T00:00:00.000Z'
525
+ });
526
+ await recordContextLoadSignalProjection(root, signal);
527
+ await recordContextOffloadDecisionProjection(root, decideContextOffload(signal));
528
+
529
+ const ship = await runShip(root, { branch: 'master', dryRun: true });
530
+ const doctorFastCheck = ship.checks.find((check) => check.name === 'doctor_fast');
531
+
532
+ assert.equal(ship.status, 'BLOCKED');
533
+ assert.equal(doctorFastCheck?.status, 'BLOCKED');
534
+ assert.match(doctorFastCheck?.message ?? '', /doctor_status=FAIL/);
535
+ assert.equal(ship.nextActions.some((action) => /sdd doctor fast --branch master/.test(action)), true);
536
+ } finally {
537
+ await rm(root, { recursive: true, force: true });
538
+ }
539
+ });
540
+
541
+ function capabilityHealthTaskMarkdown(taskId: string): string {
542
+ return `# Tasks
543
+
544
+ ### ${taskId}: Security readiness task
545
+
546
+ \`\`\`sdd-task
547
+ id: ${taskId}
548
+ status: pending
549
+ wave: 1
550
+ depends_on: []
551
+ acceptance_refs:
552
+ - AC-1
553
+ affected_files:
554
+ - packages/core/src/auth.ts
555
+ validation:
556
+ - npm test
557
+ risk:
558
+ - security
559
+ \`\`\`
560
+
561
+ #### Boundary
562
+
563
+ Stay inside security readiness fixtures.
564
+
565
+ #### Acceptance
566
+
567
+ - AC-1: Security readiness is covered.
568
+ `;
569
+ }
570
+
571
+ const doctorScope: RuntimeScope = { branch: 'master', taskId: 'T1', runId: 'run-1' };
572
+
573
+ function doctorStageRun(): StageRun {
574
+ return {
575
+ contract: STAGE_RUN_CONTRACT_VERSION,
576
+ id: 'doctor-stage-do',
577
+ scope: doctorScope,
578
+ stage: 'do',
579
+ ownerAgent: 'implementer',
580
+ coMainAgents: ['reviewer'],
581
+ status: 'completed',
582
+ inputRefs: [{ kind: 'projection', ref: 'phase8_lifecycle_risk_decision:master:T1:run-1:none' }],
583
+ outputRefs: [{ kind: 'artifact', ref: 'artifacts/doctor-handoff.md' }],
584
+ decisionRefs: [{ kind: 'projection', ref: 'phase8_lifecycle_risk_decision:master:T1:run-1:none' }],
585
+ blockingReasons: [],
586
+ createdAt: '2026-05-18T00:00:00.000Z',
587
+ updatedAt: '2026-05-18T00:01:00.000Z'
588
+ };
589
+ }
590
+
591
+ function doctorHandoff(): WorkflowHandoff {
592
+ return {
593
+ contract: WORKFLOW_HANDOFF_CONTRACT_VERSION,
594
+ id: 'doctor-handoff-do-test',
595
+ scope: doctorScope,
596
+ fromStage: 'do',
597
+ toStage: 'test',
598
+ fromAgent: 'implementer',
599
+ toAgent: 'validator',
600
+ status: 'accepted',
601
+ outputRefs: [{ kind: 'artifact', ref: 'artifacts/doctor-handoff.md' }],
602
+ requiredInputRefs: [{ kind: 'projection', ref: 'phase8_lifecycle_risk_decision:master:T1:run-1:none' }],
603
+ riskDecisionRef: { kind: 'projection', ref: 'phase8_lifecycle_risk_decision:master:T1:run-1:none' },
604
+ evidenceRefs: [{ kind: 'evidence', ref: 'artifacts/doctor-handoff-validation.md#AC-1' }],
605
+ openQuestions: [],
606
+ blockingGaps: [],
607
+ createdAt: '2026-05-18T00:02:00.000Z',
608
+ decidedAt: '2026-05-18T00:03:00.000Z'
609
+ };
610
+ }
611
+
612
+ function doctorSubagentDispatch(): SubagentDispatch {
613
+ return {
614
+ contract: SUBAGENT_DISPATCH_CONTRACT_VERSION,
615
+ id: 'dispatch-1',
616
+ scope: doctorScope,
617
+ workUnitId: 'wu-subagent-1',
618
+ definitionName: 'test-writer',
619
+ mode: 'background',
620
+ status: 'queued',
621
+ blocking: true,
622
+ requiredBefore: 'handoff',
623
+ contextRef: { kind: 'projection', ref: 'sdd-scoped-context-handoff:T1' },
624
+ createdAt: '2026-05-18T00:00:00.000Z',
625
+ updatedAt: '2026-05-18T00:01:00.000Z'
626
+ };
627
+ }