sdd-agent-platform 0.4.2 → 0.5.1

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