sdd-agent-platform 0.4.0 → 0.4.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 (417) hide show
  1. package/README.md +18 -23
  2. package/node_modules/@sdd-agent-platform/core/dist/ai-tools.js +31 -28
  3. package/node_modules/@sdd-agent-platform/core/dist/ai-tools.js.map +1 -1
  4. package/node_modules/@sdd-agent-platform/core/dist/config/init-project.js +3 -2
  5. package/node_modules/@sdd-agent-platform/core/dist/config/init-project.js.map +1 -1
  6. package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.d.ts +1 -1
  7. package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.js +14 -5
  8. package/node_modules/@sdd-agent-platform/core/dist/config/starter-documents.js.map +1 -1
  9. package/node_modules/@sdd-agent-platform/core/dist/contracts.d.ts +2 -0
  10. package/node_modules/@sdd-agent-platform/core/dist/contracts.js +2 -0
  11. package/node_modules/@sdd-agent-platform/core/dist/contracts.js.map +1 -1
  12. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js +3 -3
  13. package/node_modules/@sdd-agent-platform/core/dist/doctor/checks/run-evidence.js.map +1 -1
  14. package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js +155 -1
  15. package/node_modules/@sdd-agent-platform/core/dist/doctor/doctor.js.map +1 -1
  16. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.d.ts +23 -0
  17. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js +54 -0
  18. package/node_modules/@sdd-agent-platform/core/dist/evidence/lookup.js.map +1 -0
  19. package/node_modules/@sdd-agent-platform/core/dist/evidence-runtime/contracts.d.ts +11 -0
  20. package/node_modules/@sdd-agent-platform/core/dist/execution/agent-execution-records.js +15 -8
  21. package/node_modules/@sdd-agent-platform/core/dist/execution/agent-execution-records.js.map +1 -1
  22. package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js +14 -6
  23. package/node_modules/@sdd-agent-platform/core/dist/execution/resident-worker.js.map +1 -1
  24. package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.d.ts +112 -0
  25. package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js +145 -0
  26. package/node_modules/@sdd-agent-platform/core/dist/execution/stage-team-runtime.js.map +1 -0
  27. package/node_modules/@sdd-agent-platform/core/dist/instructions.js +36 -36
  28. package/node_modules/@sdd-agent-platform/core/dist/instructions.js.map +1 -1
  29. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.d.ts +2 -0
  30. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js +37 -17
  31. package/node_modules/@sdd-agent-platform/core/dist/lifecycle/ship.js.map +1 -1
  32. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.d.ts +16 -1
  33. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js +174 -16
  34. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-capability-catalog.js.map +1 -1
  35. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js +2 -2
  36. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-registry.js.map +1 -1
  37. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.d.ts +10 -0
  38. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js +31 -1
  39. package/node_modules/@sdd-agent-platform/core/dist/registries/agent-runtime-static.js.map +1 -1
  40. package/node_modules/@sdd-agent-platform/core/dist/registries/capability-sources.d.ts +2 -17
  41. package/node_modules/@sdd-agent-platform/core/dist/registries/capability-sources.js +222 -10
  42. package/node_modules/@sdd-agent-platform/core/dist/registries/capability-sources.js.map +1 -1
  43. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js +5 -5
  44. package/node_modules/@sdd-agent-platform/core/dist/registries/workflow-gates.js.map +1 -1
  45. package/node_modules/@sdd-agent-platform/core/dist/router/agent-runtime-config.js +27 -12
  46. package/node_modules/@sdd-agent-platform/core/dist/router/agent-runtime-config.js.map +1 -1
  47. package/node_modules/@sdd-agent-platform/core/dist/router/agent-runtime.d.ts +59 -1
  48. package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.d.ts +3 -1
  49. package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js +191 -0
  50. package/node_modules/@sdd-agent-platform/core/dist/router/route-projection.js.map +1 -1
  51. package/node_modules/@sdd-agent-platform/core/dist/router/routing.js +32 -6
  52. package/node_modules/@sdd-agent-platform/core/dist/router/routing.js.map +1 -1
  53. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-inspection.js +11 -4
  54. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-inspection.js.map +1 -1
  55. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js +31 -3
  56. package/node_modules/@sdd-agent-platform/core/dist/router/runtime-validation.js.map +1 -1
  57. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js +48 -15
  58. package/node_modules/@sdd-agent-platform/core/dist/run-state/artifacts.js.map +1 -1
  59. package/node_modules/@sdd-agent-platform/core/dist/run-state/events.js +2 -2
  60. package/node_modules/@sdd-agent-platform/core/dist/run-state/events.js.map +1 -1
  61. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.d.ts +3 -1
  62. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js +15 -49
  63. package/node_modules/@sdd-agent-platform/core/dist/run-state/inspect-run.js.map +1 -1
  64. package/node_modules/@sdd-agent-platform/core/dist/run-state/invocation-ledger.js +2 -2
  65. package/node_modules/@sdd-agent-platform/core/dist/run-state/invocation-ledger.js.map +1 -1
  66. package/node_modules/@sdd-agent-platform/core/dist/run-state/model.d.ts +25 -1
  67. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js +21 -14
  68. package/node_modules/@sdd-agent-platform/core/dist/run-state/run-state.js.map +1 -1
  69. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.d.ts +62 -0
  70. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js +130 -0
  71. package/node_modules/@sdd-agent-platform/core/dist/run-state/task-evidence.js.map +1 -0
  72. package/node_modules/@sdd-agent-platform/core/dist/run-state.d.ts +1 -0
  73. package/node_modules/@sdd-agent-platform/core/dist/run-state.js +1 -0
  74. package/node_modules/@sdd-agent-platform/core/dist/run-state.js.map +1 -1
  75. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.d.ts +10 -0
  76. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js +44 -14
  77. package/node_modules/@sdd-agent-platform/core/dist/runtime-paths.js.map +1 -1
  78. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/context.js +1 -1
  79. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/context.js.map +1 -1
  80. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.d.ts +4 -0
  81. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js +189 -0
  82. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/document-hashes.js.map +1 -0
  83. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js +12 -3
  84. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/run-binding.js.map +1 -1
  85. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.d.ts +20 -0
  86. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js +101 -21
  87. package/node_modules/@sdd-agent-platform/core/dist/sdd-docs/task-parser.js.map +1 -1
  88. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.d.ts +62 -1
  89. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js +192 -4
  90. package/node_modules/@sdd-agent-platform/core/dist/status/project-status.js.map +1 -1
  91. package/node_modules/@sdd-agent-platform/core/dist/storage/runtime-store.d.ts +195 -2
  92. package/node_modules/@sdd-agent-platform/core/dist/storage/runtime-store.js +499 -2
  93. package/node_modules/@sdd-agent-platform/core/dist/storage/runtime-store.js.map +1 -1
  94. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js +23 -1
  95. package/node_modules/@sdd-agent-platform/core/dist/sync-back/apply.js.map +1 -1
  96. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.d.ts +19 -0
  97. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js +114 -12
  98. package/node_modules/@sdd-agent-platform/core/dist/sync-back/inspect.js.map +1 -1
  99. package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js +21 -0
  100. package/node_modules/@sdd-agent-platform/core/dist/test-support/fixtures.js.map +1 -1
  101. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js +16 -2
  102. package/node_modules/@sdd-agent-platform/core/dist/test-support/run-state.js.map +1 -1
  103. package/node_modules/@sdd-agent-platform/core/dist/tsconfig.tsbuildinfo +1 -1
  104. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js +34 -2
  105. package/node_modules/@sdd-agent-platform/core/dist/verification/goal-verify.js.map +1 -1
  106. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js +15 -5
  107. package/node_modules/@sdd-agent-platform/core/dist/verification/rendering.js.map +1 -1
  108. package/node_modules/@sdd-agent-platform/core/dist/verification/review-gate.d.ts +22 -0
  109. package/node_modules/@sdd-agent-platform/core/dist/verification/review-gate.js +53 -0
  110. package/node_modules/@sdd-agent-platform/core/dist/verification/review-gate.js.map +1 -0
  111. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js +102 -9
  112. package/node_modules/@sdd-agent-platform/core/dist/verification/single-task-loop.js.map +1 -1
  113. package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.d.ts +16 -1
  114. package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js +355 -69
  115. package/node_modules/@sdd-agent-platform/core/dist/verification/test-runtime.js.map +1 -1
  116. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.d.ts +58 -0
  117. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js +428 -0
  118. package/node_modules/@sdd-agent-platform/core/dist/verification/validation-wave.js.map +1 -0
  119. package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.d.ts +2 -0
  120. package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js +116 -18
  121. package/node_modules/@sdd-agent-platform/core/dist/verification/verify-contract.js.map +1 -1
  122. package/node_modules/@sdd-agent-platform/core/dist/verification.d.ts +2 -0
  123. package/node_modules/@sdd-agent-platform/core/dist/verification.js +2 -0
  124. package/node_modules/@sdd-agent-platform/core/dist/verification.js.map +1 -1
  125. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.d.ts +24 -0
  126. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js +182 -0
  127. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/evidence-packet.js.map +1 -0
  128. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.d.ts +4 -0
  129. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js +130 -0
  130. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/hard-checks.js.map +1 -0
  131. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.d.ts +4 -0
  132. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js +146 -0
  133. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/policy.js.map +1 -0
  134. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/types.d.ts +89 -0
  135. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/types.js +2 -0
  136. package/node_modules/@sdd-agent-platform/core/dist/workflow-gate/types.js.map +1 -0
  137. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
  138. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js +16 -1
  139. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
  140. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/dependencies.d.ts +8 -4
  141. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/dependencies.js +25 -11
  142. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/dependencies.js.map +1 -1
  143. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.d.ts +38 -0
  144. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js +122 -0
  145. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/latest-eligible-run.js.map +1 -0
  146. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.d.ts +27 -0
  147. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js +166 -37
  148. package/node_modules/@sdd-agent-platform/core/dist/workflow-state/resolve.js.map +1 -1
  149. package/node_modules/@sdd-agent-platform/core/dist/workflow-state.d.ts +1 -0
  150. package/node_modules/@sdd-agent-platform/core/dist/workflow-state.js +1 -0
  151. package/node_modules/@sdd-agent-platform/core/dist/workflow-state.js.map +1 -1
  152. package/node_modules/@sdd-agent-platform/core/package.json +1 -1
  153. package/node_modules/@sdd-agent-platform/core/src/ai-tools.ts +31 -28
  154. package/node_modules/@sdd-agent-platform/core/src/artifacts/sdd-result.test.ts +50 -4
  155. package/node_modules/@sdd-agent-platform/core/src/config/init-project.test.ts +13 -10
  156. package/node_modules/@sdd-agent-platform/core/src/config/init-project.ts +3 -2
  157. package/node_modules/@sdd-agent-platform/core/src/config/starter-documents.ts +15 -5
  158. package/node_modules/@sdd-agent-platform/core/src/contracts.ts +2 -0
  159. package/node_modules/@sdd-agent-platform/core/src/doctor/checks/run-evidence.ts +3 -3
  160. package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.test.ts +117 -5
  161. package/node_modules/@sdd-agent-platform/core/src/doctor/doctor.ts +164 -1
  162. package/node_modules/@sdd-agent-platform/core/src/evidence/lookup.ts +80 -0
  163. package/node_modules/@sdd-agent-platform/core/src/evidence-runtime/contracts.ts +12 -0
  164. package/node_modules/@sdd-agent-platform/core/src/execution/agent-execution-records.ts +16 -11
  165. package/node_modules/@sdd-agent-platform/core/src/execution/background-executor.test.ts +7 -0
  166. package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.test.ts +5 -0
  167. package/node_modules/@sdd-agent-platform/core/src/execution/resident-worker.ts +14 -6
  168. package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.test.ts +102 -0
  169. package/node_modules/@sdd-agent-platform/core/src/execution/stage-team-runtime.ts +271 -0
  170. package/node_modules/@sdd-agent-platform/core/src/execution/wave-executor.test.ts +4 -0
  171. package/node_modules/@sdd-agent-platform/core/src/governance/policy.test.ts +2 -0
  172. package/node_modules/@sdd-agent-platform/core/src/instructions.test.ts +11 -5
  173. package/node_modules/@sdd-agent-platform/core/src/instructions.ts +36 -36
  174. package/node_modules/@sdd-agent-platform/core/src/lifecycle/ship.ts +39 -17
  175. package/node_modules/@sdd-agent-platform/core/src/phase8-contracts.test.ts +3 -2
  176. package/node_modules/@sdd-agent-platform/core/src/phase8-risk-kernel.test.ts +5 -0
  177. package/node_modules/@sdd-agent-platform/core/src/planning/task-graph.test.ts +2 -0
  178. package/node_modules/@sdd-agent-platform/core/src/planning/wave-plan.test.ts +3 -0
  179. package/node_modules/@sdd-agent-platform/core/src/registries/agent-capability-catalog.ts +269 -17
  180. package/node_modules/@sdd-agent-platform/core/src/registries/agent-registry.ts +2 -2
  181. package/node_modules/@sdd-agent-platform/core/src/registries/agent-runtime-static.ts +41 -1
  182. package/node_modules/@sdd-agent-platform/core/src/registries/capability-sources.ts +238 -15
  183. package/node_modules/@sdd-agent-platform/core/src/registries/registries.test.ts +27 -2
  184. package/node_modules/@sdd-agent-platform/core/src/registries/workflow-gates.ts +5 -5
  185. package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime-config.ts +31 -12
  186. package/node_modules/@sdd-agent-platform/core/src/router/agent-runtime.ts +66 -1
  187. package/node_modules/@sdd-agent-platform/core/src/router/route-projection.ts +211 -0
  188. package/node_modules/@sdd-agent-platform/core/src/router/route-sdd-task.test.ts +151 -3
  189. package/node_modules/@sdd-agent-platform/core/src/router/routing.ts +35 -6
  190. package/node_modules/@sdd-agent-platform/core/src/router/runtime-inspection.ts +11 -4
  191. package/node_modules/@sdd-agent-platform/core/src/router/runtime-validation.ts +32 -3
  192. package/node_modules/@sdd-agent-platform/core/src/run-state/artifacts.ts +48 -15
  193. package/node_modules/@sdd-agent-platform/core/src/run-state/events.ts +2 -2
  194. package/node_modules/@sdd-agent-platform/core/src/run-state/inspect-run.ts +17 -52
  195. package/node_modules/@sdd-agent-platform/core/src/run-state/invocation-ledger.ts +2 -2
  196. package/node_modules/@sdd-agent-platform/core/src/run-state/model.ts +28 -1
  197. package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.test.ts +3 -0
  198. package/node_modules/@sdd-agent-platform/core/src/run-state/run-state.ts +22 -18
  199. package/node_modules/@sdd-agent-platform/core/src/run-state/task-evidence.ts +206 -0
  200. package/node_modules/@sdd-agent-platform/core/src/run-state.ts +1 -0
  201. package/node_modules/@sdd-agent-platform/core/src/runtime-paths.ts +54 -14
  202. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/context.ts +1 -1
  203. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/document-hashes.ts +207 -0
  204. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/run-binding.ts +12 -3
  205. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.test.ts +139 -0
  206. package/node_modules/@sdd-agent-platform/core/src/sdd-docs/task-parser.ts +137 -24
  207. package/node_modules/@sdd-agent-platform/core/src/status/project-status.ts +268 -5
  208. package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.test.ts +368 -4
  209. package/node_modules/@sdd-agent-platform/core/src/storage/runtime-store.ts +697 -2
  210. package/node_modules/@sdd-agent-platform/core/src/sync-back/apply.ts +23 -1
  211. package/node_modules/@sdd-agent-platform/core/src/sync-back/inspect.ts +145 -12
  212. package/node_modules/@sdd-agent-platform/core/src/sync-back/sync-back.test.ts +132 -9
  213. package/node_modules/@sdd-agent-platform/core/src/test-support/fixtures.ts +21 -0
  214. package/node_modules/@sdd-agent-platform/core/src/test-support/run-state.ts +16 -2
  215. package/node_modules/@sdd-agent-platform/core/src/verification/goal-verify.test.ts +1 -1
  216. package/node_modules/@sdd-agent-platform/core/src/verification/goal-verify.ts +38 -5
  217. package/node_modules/@sdd-agent-platform/core/src/verification/rendering.ts +15 -5
  218. package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.test.ts +77 -0
  219. package/node_modules/@sdd-agent-platform/core/src/verification/review-gate.ts +77 -0
  220. package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.test.ts +64 -4
  221. package/node_modules/@sdd-agent-platform/core/src/verification/single-task-loop.ts +110 -12
  222. package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.test.ts +72 -25
  223. package/node_modules/@sdd-agent-platform/core/src/verification/test-runtime.ts +402 -77
  224. package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.test.ts +341 -0
  225. package/node_modules/@sdd-agent-platform/core/src/verification/validation-wave.ts +513 -0
  226. package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.test.ts +144 -5
  227. package/node_modules/@sdd-agent-platform/core/src/verification/verify-contract.ts +129 -18
  228. package/node_modules/@sdd-agent-platform/core/src/verification.ts +2 -0
  229. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/evidence-packet.ts +196 -0
  230. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.test.ts +171 -0
  231. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/hard-checks.ts +143 -0
  232. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.test.ts +137 -0
  233. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/policy.ts +155 -0
  234. package/node_modules/@sdd-agent-platform/core/src/workflow-gate/types.ts +114 -0
  235. package/node_modules/@sdd-agent-platform/core/src/workflow-state/affected-file-conflicts.ts +18 -1
  236. package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.test.ts +1 -1
  237. package/node_modules/@sdd-agent-platform/core/src/workflow-state/dependencies.ts +33 -11
  238. package/node_modules/@sdd-agent-platform/core/src/workflow-state/latest-eligible-run.ts +156 -0
  239. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.test.ts +351 -2
  240. package/node_modules/@sdd-agent-platform/core/src/workflow-state/resolve.ts +227 -39
  241. package/node_modules/@sdd-agent-platform/core/src/workflow-state.ts +1 -0
  242. package/package.json +1 -1
  243. package/packages/cli/dist/commands/status.js +2 -2
  244. package/packages/cli/dist/commands/status.js.map +1 -1
  245. package/packages/cli/dist/commands/sync-back.js +1 -1
  246. package/packages/cli/dist/commands/sync-back.js.map +1 -1
  247. package/packages/cli/dist/commands/tasks.js +4 -4
  248. package/packages/cli/dist/commands/tasks.js.map +1 -1
  249. package/packages/cli/dist/commands/test.js +94 -5
  250. package/packages/cli/dist/commands/test.js.map +1 -1
  251. package/packages/cli/dist/commands/verifies.js +5 -3
  252. package/packages/cli/dist/commands/verifies.js.map +1 -1
  253. package/packages/cli/dist/commands/verify.js +48 -7
  254. package/packages/cli/dist/commands/verify.js.map +1 -1
  255. package/packages/cli/dist/help.js +32 -18
  256. package/packages/cli/dist/help.js.map +1 -1
  257. package/packages/cli/dist/renderers/artifacts.js +1 -1
  258. package/packages/cli/dist/renderers/artifacts.js.map +1 -1
  259. package/packages/cli/dist/renderers/registry-runtime.js +7 -2
  260. package/packages/cli/dist/renderers/registry-runtime.js.map +1 -1
  261. package/packages/cli/dist/renderers/router.js +4 -2
  262. package/packages/cli/dist/renderers/router.js.map +1 -1
  263. package/packages/cli/dist/renderers/workflow.js +33 -12
  264. package/packages/cli/dist/renderers/workflow.js.map +1 -1
  265. package/packages/cli/dist/tsconfig.tsbuildinfo +1 -1
  266. package/packages/cli/package.json +2 -2
  267. package/packages/core/dist/ai-tools.js +31 -28
  268. package/packages/core/dist/ai-tools.js.map +1 -1
  269. package/packages/core/dist/config/init-project.js +3 -2
  270. package/packages/core/dist/config/init-project.js.map +1 -1
  271. package/packages/core/dist/config/starter-documents.d.ts +1 -1
  272. package/packages/core/dist/config/starter-documents.js +14 -5
  273. package/packages/core/dist/config/starter-documents.js.map +1 -1
  274. package/packages/core/dist/contracts.d.ts +2 -0
  275. package/packages/core/dist/contracts.js +2 -0
  276. package/packages/core/dist/contracts.js.map +1 -1
  277. package/packages/core/dist/doctor/checks/run-evidence.js +3 -3
  278. package/packages/core/dist/doctor/checks/run-evidence.js.map +1 -1
  279. package/packages/core/dist/doctor/doctor.js +155 -1
  280. package/packages/core/dist/doctor/doctor.js.map +1 -1
  281. package/packages/core/dist/evidence/lookup.d.ts +23 -0
  282. package/packages/core/dist/evidence/lookup.js +54 -0
  283. package/packages/core/dist/evidence/lookup.js.map +1 -0
  284. package/packages/core/dist/evidence-runtime/contracts.d.ts +11 -0
  285. package/packages/core/dist/execution/agent-execution-records.js +15 -8
  286. package/packages/core/dist/execution/agent-execution-records.js.map +1 -1
  287. package/packages/core/dist/execution/resident-worker.js +14 -6
  288. package/packages/core/dist/execution/resident-worker.js.map +1 -1
  289. package/packages/core/dist/execution/stage-team-runtime.d.ts +112 -0
  290. package/packages/core/dist/execution/stage-team-runtime.js +145 -0
  291. package/packages/core/dist/execution/stage-team-runtime.js.map +1 -0
  292. package/packages/core/dist/instructions.js +36 -36
  293. package/packages/core/dist/instructions.js.map +1 -1
  294. package/packages/core/dist/lifecycle/ship.d.ts +2 -0
  295. package/packages/core/dist/lifecycle/ship.js +37 -17
  296. package/packages/core/dist/lifecycle/ship.js.map +1 -1
  297. package/packages/core/dist/registries/agent-capability-catalog.d.ts +16 -1
  298. package/packages/core/dist/registries/agent-capability-catalog.js +174 -16
  299. package/packages/core/dist/registries/agent-capability-catalog.js.map +1 -1
  300. package/packages/core/dist/registries/agent-registry.js +2 -2
  301. package/packages/core/dist/registries/agent-registry.js.map +1 -1
  302. package/packages/core/dist/registries/agent-runtime-static.d.ts +10 -0
  303. package/packages/core/dist/registries/agent-runtime-static.js +31 -1
  304. package/packages/core/dist/registries/agent-runtime-static.js.map +1 -1
  305. package/packages/core/dist/registries/capability-sources.d.ts +2 -17
  306. package/packages/core/dist/registries/capability-sources.js +222 -10
  307. package/packages/core/dist/registries/capability-sources.js.map +1 -1
  308. package/packages/core/dist/registries/workflow-gates.js +5 -5
  309. package/packages/core/dist/registries/workflow-gates.js.map +1 -1
  310. package/packages/core/dist/router/agent-runtime-config.js +27 -12
  311. package/packages/core/dist/router/agent-runtime-config.js.map +1 -1
  312. package/packages/core/dist/router/agent-runtime.d.ts +59 -1
  313. package/packages/core/dist/router/route-projection.d.ts +3 -1
  314. package/packages/core/dist/router/route-projection.js +191 -0
  315. package/packages/core/dist/router/route-projection.js.map +1 -1
  316. package/packages/core/dist/router/routing.js +32 -6
  317. package/packages/core/dist/router/routing.js.map +1 -1
  318. package/packages/core/dist/router/runtime-inspection.js +11 -4
  319. package/packages/core/dist/router/runtime-inspection.js.map +1 -1
  320. package/packages/core/dist/router/runtime-validation.js +31 -3
  321. package/packages/core/dist/router/runtime-validation.js.map +1 -1
  322. package/packages/core/dist/run-state/artifacts.js +48 -15
  323. package/packages/core/dist/run-state/artifacts.js.map +1 -1
  324. package/packages/core/dist/run-state/events.js +2 -2
  325. package/packages/core/dist/run-state/events.js.map +1 -1
  326. package/packages/core/dist/run-state/inspect-run.d.ts +3 -1
  327. package/packages/core/dist/run-state/inspect-run.js +15 -49
  328. package/packages/core/dist/run-state/inspect-run.js.map +1 -1
  329. package/packages/core/dist/run-state/invocation-ledger.js +2 -2
  330. package/packages/core/dist/run-state/invocation-ledger.js.map +1 -1
  331. package/packages/core/dist/run-state/model.d.ts +25 -1
  332. package/packages/core/dist/run-state/run-state.js +21 -14
  333. package/packages/core/dist/run-state/run-state.js.map +1 -1
  334. package/packages/core/dist/run-state/task-evidence.d.ts +62 -0
  335. package/packages/core/dist/run-state/task-evidence.js +130 -0
  336. package/packages/core/dist/run-state/task-evidence.js.map +1 -0
  337. package/packages/core/dist/run-state.d.ts +1 -0
  338. package/packages/core/dist/run-state.js +1 -0
  339. package/packages/core/dist/run-state.js.map +1 -1
  340. package/packages/core/dist/runtime-paths.d.ts +10 -0
  341. package/packages/core/dist/runtime-paths.js +44 -14
  342. package/packages/core/dist/runtime-paths.js.map +1 -1
  343. package/packages/core/dist/sdd-docs/context.js +1 -1
  344. package/packages/core/dist/sdd-docs/context.js.map +1 -1
  345. package/packages/core/dist/sdd-docs/document-hashes.d.ts +4 -0
  346. package/packages/core/dist/sdd-docs/document-hashes.js +189 -0
  347. package/packages/core/dist/sdd-docs/document-hashes.js.map +1 -0
  348. package/packages/core/dist/sdd-docs/run-binding.js +12 -3
  349. package/packages/core/dist/sdd-docs/run-binding.js.map +1 -1
  350. package/packages/core/dist/sdd-docs/task-parser.d.ts +20 -0
  351. package/packages/core/dist/sdd-docs/task-parser.js +101 -21
  352. package/packages/core/dist/sdd-docs/task-parser.js.map +1 -1
  353. package/packages/core/dist/status/project-status.d.ts +62 -1
  354. package/packages/core/dist/status/project-status.js +192 -4
  355. package/packages/core/dist/status/project-status.js.map +1 -1
  356. package/packages/core/dist/storage/runtime-store.d.ts +195 -2
  357. package/packages/core/dist/storage/runtime-store.js +499 -2
  358. package/packages/core/dist/storage/runtime-store.js.map +1 -1
  359. package/packages/core/dist/sync-back/apply.js +23 -1
  360. package/packages/core/dist/sync-back/apply.js.map +1 -1
  361. package/packages/core/dist/sync-back/inspect.d.ts +19 -0
  362. package/packages/core/dist/sync-back/inspect.js +114 -12
  363. package/packages/core/dist/sync-back/inspect.js.map +1 -1
  364. package/packages/core/dist/test-support/fixtures.js +21 -0
  365. package/packages/core/dist/test-support/fixtures.js.map +1 -1
  366. package/packages/core/dist/test-support/run-state.js +16 -2
  367. package/packages/core/dist/test-support/run-state.js.map +1 -1
  368. package/packages/core/dist/tsconfig.tsbuildinfo +1 -1
  369. package/packages/core/dist/verification/goal-verify.js +34 -2
  370. package/packages/core/dist/verification/goal-verify.js.map +1 -1
  371. package/packages/core/dist/verification/rendering.js +15 -5
  372. package/packages/core/dist/verification/rendering.js.map +1 -1
  373. package/packages/core/dist/verification/review-gate.d.ts +22 -0
  374. package/packages/core/dist/verification/review-gate.js +53 -0
  375. package/packages/core/dist/verification/review-gate.js.map +1 -0
  376. package/packages/core/dist/verification/single-task-loop.js +102 -9
  377. package/packages/core/dist/verification/single-task-loop.js.map +1 -1
  378. package/packages/core/dist/verification/test-runtime.d.ts +16 -1
  379. package/packages/core/dist/verification/test-runtime.js +355 -69
  380. package/packages/core/dist/verification/test-runtime.js.map +1 -1
  381. package/packages/core/dist/verification/validation-wave.d.ts +58 -0
  382. package/packages/core/dist/verification/validation-wave.js +428 -0
  383. package/packages/core/dist/verification/validation-wave.js.map +1 -0
  384. package/packages/core/dist/verification/verify-contract.d.ts +2 -0
  385. package/packages/core/dist/verification/verify-contract.js +116 -18
  386. package/packages/core/dist/verification/verify-contract.js.map +1 -1
  387. package/packages/core/dist/verification.d.ts +2 -0
  388. package/packages/core/dist/verification.js +2 -0
  389. package/packages/core/dist/verification.js.map +1 -1
  390. package/packages/core/dist/workflow-gate/evidence-packet.d.ts +24 -0
  391. package/packages/core/dist/workflow-gate/evidence-packet.js +182 -0
  392. package/packages/core/dist/workflow-gate/evidence-packet.js.map +1 -0
  393. package/packages/core/dist/workflow-gate/hard-checks.d.ts +4 -0
  394. package/packages/core/dist/workflow-gate/hard-checks.js +130 -0
  395. package/packages/core/dist/workflow-gate/hard-checks.js.map +1 -0
  396. package/packages/core/dist/workflow-gate/policy.d.ts +4 -0
  397. package/packages/core/dist/workflow-gate/policy.js +146 -0
  398. package/packages/core/dist/workflow-gate/policy.js.map +1 -0
  399. package/packages/core/dist/workflow-gate/types.d.ts +89 -0
  400. package/packages/core/dist/workflow-gate/types.js +2 -0
  401. package/packages/core/dist/workflow-gate/types.js.map +1 -0
  402. package/packages/core/dist/workflow-state/affected-file-conflicts.d.ts +1 -0
  403. package/packages/core/dist/workflow-state/affected-file-conflicts.js +16 -1
  404. package/packages/core/dist/workflow-state/affected-file-conflicts.js.map +1 -1
  405. package/packages/core/dist/workflow-state/dependencies.d.ts +8 -4
  406. package/packages/core/dist/workflow-state/dependencies.js +25 -11
  407. package/packages/core/dist/workflow-state/dependencies.js.map +1 -1
  408. package/packages/core/dist/workflow-state/latest-eligible-run.d.ts +38 -0
  409. package/packages/core/dist/workflow-state/latest-eligible-run.js +122 -0
  410. package/packages/core/dist/workflow-state/latest-eligible-run.js.map +1 -0
  411. package/packages/core/dist/workflow-state/resolve.d.ts +27 -0
  412. package/packages/core/dist/workflow-state/resolve.js +166 -37
  413. package/packages/core/dist/workflow-state/resolve.js.map +1 -1
  414. package/packages/core/dist/workflow-state.d.ts +1 -0
  415. package/packages/core/dist/workflow-state.js +1 -0
  416. package/packages/core/dist/workflow-state.js.map +1 -1
  417. package/packages/core/package.json +1 -1
@@ -1,3 +1,5 @@
1
+ import { readdir, stat } from 'node:fs/promises';
2
+ import path from 'node:path';
1
3
  import { inspectAiToolEntryEvidence } from './checks/ai-entries.js';
2
4
  import { inspectDocumentChainEvidence } from './checks/document-chain.js';
3
5
  import { inspectLocalRunIndexEvidence } from './checks/local-run-index.js';
@@ -5,7 +7,10 @@ import { inspectGitRepository, inspectProjectConfig, inspectRunsDirectoryAccess,
5
7
  import { inspectRunEvidence } from './checks/run-evidence.js';
6
8
  import { inspectAgentCapabilityCatalogDoctorContract, inspectAgentSkillTeamRuntimeDoctorContract, inspectCapabilityRegistry, inspectCommandTeamRuntimeDoctorContract, inspectGovernancePolicyContract, inspectHarnessLearningDoctorContract, inspectProjectContextPackDoctorContract, inspectQueryStatusBoundaryContract, inspectSkillAgentEvalDoctorContract, inspectToolPluginContracts } from './checks/registries.js';
7
9
  import { inspectBackgroundExecutorContract, inspectDelegationQueueContract, inspectDelegationStateMachineContract, inspectLocalRunIndexContract, inspectTaskGraphPlannerContract, inspectWaveExecutorContract, inspectWavePlannerContract, inspectWorkerAdapterContracts, inspectWorktreeIsolationContract, inspectWorktreeLifecycleContract } from './checks/runtime-contracts.js';
8
- import { inspectRuntimeStoreEvidence } from '../storage/runtime-store.js';
10
+ import { inspectRuntimeStoreEvidence, listRuntimeSyncBackDecisions } from '../storage/runtime-store.js';
11
+ import { getLegacyAgentExecutionsDir, getLegacyRunDir, getLegacyTeamSessionsDir, getLegacyWorkerRuntimesDir } from '../runtime-paths.js';
12
+ import { branchToSafePartition } from '../path-safety.js';
13
+ import { readAllRunStates } from '../run-state/run-state.js';
9
14
  import { getProjectStatus, statuslineProjectionFromStatus, type ProjectStatus } from '../status/project-status.js';
10
15
  import type { DoctorCheck, DoctorReport } from './model.js';
11
16
  import { summarizeDoctorStatus } from './summary.js';
@@ -58,6 +63,12 @@ export async function doctor(projectRoot: string, options: { allRuns?: boolean;
58
63
  checks.push(...inspectWorkflowHandoffRuntime(statusSnapshot));
59
64
  checks.push(...inspectContextOffloadRuntime(statusSnapshot));
60
65
  checks.push(...inspectSubagentDispatchRuntime(statusSnapshot));
66
+ checks.push(...inspectCapabilityHealthRuntime(statusSnapshot));
67
+ checks.push(...inspectLatestEligibleRunSelector(statusSnapshot));
68
+ checks.push(...inspectDurableGapRuntime(statusSnapshot));
69
+ checks.push(...inspectStageTeamRuntime(statusSnapshot));
70
+ checks.push(...inspectWorkflowGateRuntime(statusSnapshot));
71
+ checks.push(...await inspectPhase818Compatibility(projectRoot, options));
61
72
 
62
73
  return {
63
74
  status: summarizeDoctorStatus(checks),
@@ -90,6 +101,83 @@ function unavailableRuntimeCheck(check: string, label: string, error: unknown):
90
101
  }];
91
102
  }
92
103
 
104
+ async function inspectPhase818Compatibility(projectRoot: string, options: { allRuns?: boolean; branch?: string | null } = {}): Promise<DoctorCheck[]> {
105
+ try {
106
+ const branchPartition = options.branch ? branchToSafePartition(options.branch) : null;
107
+ const states = (await readAllRunStates(projectRoot))
108
+ .filter((state) => options.allRuns || state.status !== 'archived')
109
+ .filter((state) => !branchPartition || state.partition === branchPartition || state.gitBranch === options.branch || (state.gitBranch ? branchToSafePartition(state.gitBranch) === branchPartition : false));
110
+ const legacyRunFiles: string[] = [];
111
+ const legacySidecars: string[] = [];
112
+ const syncBackJsonOnly: string[] = [];
113
+ const syncBackDivergence: string[] = [];
114
+
115
+ for (const state of states) {
116
+ const legacyRunDir = getLegacyRunDir(projectRoot, state.runId);
117
+ const runLocalFiles = ['state.json', 'events.jsonl', 'invocations.jsonl'];
118
+ for (const fileName of runLocalFiles) {
119
+ if (await fileExists(path.join(legacyRunDir, fileName))) {
120
+ legacyRunFiles.push(`${state.runId}:${fileName}`);
121
+ }
122
+ }
123
+
124
+ const sidecarDirs = [
125
+ getLegacyAgentExecutionsDir(projectRoot, state.runId),
126
+ getLegacyTeamSessionsDir(projectRoot, state.runId),
127
+ getLegacyWorkerRuntimesDir(projectRoot, state.runId)
128
+ ];
129
+ if ((await Promise.all(sidecarDirs.map(directoryHasEntries))).some(Boolean)) {
130
+ legacySidecars.push(state.runId);
131
+ }
132
+
133
+ const decisions = await listRuntimeSyncBackDecisions(projectRoot, state.runId);
134
+ const latestDecision = decisions[0] ?? null;
135
+ if (state.syncBack.status !== 'not_created' && !latestDecision) {
136
+ syncBackJsonOnly.push(state.runId);
137
+ }
138
+ if (latestDecision && latestDecision.status !== state.syncBack.status) {
139
+ syncBackDivergence.push(`${state.runId}:${state.syncBack.status}->${latestDecision.status}`);
140
+ }
141
+ }
142
+
143
+ const oldSyncBackProjection = await fileExists(path.join(projectRoot, '.claude', 'commands', 'sdd', 'syncback.md'));
144
+ return [
145
+ legacyRunFiles.length > 0
146
+ ? { level: 'WARN', check: 'phase8_18_legacy_run_files', message: `legacy_run_files=${legacyRunFiles.join(',')}`, action: 'Runtime authority is runtime.sqlite; keep legacy run-local state/events/invocation files as import fallback only.' }
147
+ : { level: 'PASS', check: 'phase8_18_legacy_run_files', message: 'No legacy run-local state, event, or invocation files found in inspected runs.' },
148
+ legacySidecars.length > 0
149
+ ? { level: 'WARN', check: 'phase8_18_legacy_sidecars', message: `legacy_sidecar_runs=${legacySidecars.join(',')}`, action: 'Runtime authority is runtime.sqlite; keep old sidecars as import fallback and avoid writing new per-run structured sidecars.' }
150
+ : { level: 'PASS', check: 'phase8_18_legacy_sidecars', message: 'No legacy per-run agent/team/worker sidecar directories found in inspected runs.' },
151
+ syncBackJsonOnly.length > 0 || syncBackDivergence.length > 0
152
+ ? { level: 'WARN', check: 'phase8_18_sync_back_compat', message: `state_json_only=${syncBackJsonOnly.join(',') || 'none'} divergence=${syncBackDivergence.join(',') || 'none'}`, action: 'Use sdd sync-back inspect only for explicit diagnostic/recovery/replay, then reconcile canonical sync_back_decisions before relying on write-back state.' }
153
+ : { level: 'PASS', check: 'phase8_18_sync_back_compat', message: 'Canonical sync_back_decisions are consistent with inspected run compatibility summaries.' },
154
+ oldSyncBackProjection
155
+ ? { level: 'WARN', check: 'phase8_18_ai_projection_compat', message: 'Found legacy /sdd:syncback projection at .claude/commands/sdd/syncback.md.', action: 'Run sdd update to remove obsolete managed syncback projection; use diagnostic sync-back only when explicitly requested.' }
156
+ : { level: 'PASS', check: 'phase8_18_ai_projection_compat', message: 'No legacy /sdd:syncback projection found.' },
157
+ { level: 'PASS', check: 'phase9_readiness', message: 'code_graph_signals=optional_advisory_only authority=phase8_runtime_policy', action: 'Phase 9 graph providers may feed risk/context/test-impact/status/doctor signals but cannot replace Phase 8 gate truth.' }
158
+ ];
159
+ } catch (error) {
160
+ return unavailableRuntimeCheck('phase8_18_compatibility', 'Phase 8.18 compatibility diagnostics', error);
161
+ }
162
+ }
163
+
164
+ async function directoryHasEntries(directory: string): Promise<boolean> {
165
+ try {
166
+ return (await readdir(directory)).length > 0;
167
+ } catch {
168
+ return false;
169
+ }
170
+ }
171
+
172
+ async function fileExists(filePath: string): Promise<boolean> {
173
+ try {
174
+ await stat(filePath);
175
+ return true;
176
+ } catch {
177
+ return false;
178
+ }
179
+ }
180
+
93
181
  function inspectContextTokenRuntime(snapshot: DoctorProjectStatusSnapshot): DoctorCheck[] {
94
182
  if (!snapshot.status) {
95
183
  return unavailableRuntimeCheck('context_token_runtime', 'token runtime projection', snapshot.error);
@@ -153,4 +241,79 @@ function inspectSubagentDispatchRuntime(snapshot: DoctorProjectStatusSnapshot):
153
241
  message: `status=${dispatches.status} dispatches=${dispatches.dispatches} blocking_open=${dispatches.blockingOpen} failed=${dispatches.failed} stale=${dispatches.stale} completed=${dispatches.completed} archived=${dispatches.archived} superseded=${dispatches.superseded}`,
154
242
  action: dispatches.status === 'fresh' || dispatches.status === 'missing' ? undefined : dispatches.reasons.join(' ')
155
243
  }];
244
+ }
245
+
246
+ function inspectCapabilityHealthRuntime(snapshot: DoctorProjectStatusSnapshot): DoctorCheck[] {
247
+ if (!snapshot.status) {
248
+ return unavailableRuntimeCheck('capability_health', 'capability health', snapshot.error);
249
+ }
250
+ const health = snapshot.status.capabilityHealth;
251
+ return [{
252
+ level: health.status === 'blocked' ? 'FAIL' : health.status === 'warn' ? 'WARN' : 'PASS',
253
+ check: 'capability_health',
254
+ message: `status=${health.status} baseline=${health.baselineDomains.length}/${health.requiredProfessionalDomains.length} packs=${health.materialPacks} active=${health.activeDomains.join(',') || 'none'} sources_quarantined=${health.sources.quarantined} sources_denied=${health.sources.denied} evidence_candidate=${health.evidence.candidate} release_critical_gaps=${health.releaseCriticalGaps.join(',') || 'none'}`,
255
+ action: health.status === 'pass' ? undefined : health.reasons.join(' ')
256
+ }];
257
+ }
258
+
259
+ function inspectWorkflowGateRuntime(snapshot: DoctorProjectStatusSnapshot): DoctorCheck[] {
260
+ if (!snapshot.status) {
261
+ return unavailableRuntimeCheck('workflow_gate_runtime', 'workflow gate runtime', snapshot.error);
262
+ }
263
+ const health = snapshot.status.workflowGateHealth;
264
+ const latest = health.latestDecision;
265
+ const level = health.blocked > 0 || health.humanRequired > 0 || health.warnings > 0 ? 'WARN' : 'PASS';
266
+ return [{
267
+ level,
268
+ check: 'workflow_gate_runtime',
269
+ message: `decisions=${health.decisions} blocked=${health.blocked} warn=${health.warnings} human_required=${health.humanRequired} latest=${latest ? `${latest.decisionKind}:${latest.status}:${latest.decisionId}` : 'none'}`,
270
+ action: level === 'PASS' ? undefined : `Workflow gate decisions are audit evidence; rerun the relevant gate command for current enforcement on ${snapshot.status.branch}.`
271
+ }];
272
+ }
273
+
274
+ function inspectStageTeamRuntime(snapshot: DoctorProjectStatusSnapshot): DoctorCheck[] {
275
+ if (!snapshot.status) {
276
+ return unavailableRuntimeCheck('stage_team_runtime', 'stage team runtime', snapshot.error);
277
+ }
278
+ const health = snapshot.status.stageTeamHealth;
279
+ const level = health.highConcernAdvisors > 0 || !health.directProfileRequiresNoTeam ? 'WARN' : 'PASS';
280
+ return [{
281
+ level,
282
+ check: 'stage_team_runtime',
283
+ message: `sessions=${health.sessions} role_results=${health.roleResults} advisors=${health.advisorAssessments} high_concern=${health.highConcernAdvisors} fan_in=${health.fanInEvidenceSets} profiles=${health.lifecycleProfiles.join(',') || 'none'} direct_required_team=${!health.directProfileRequiresNoTeam}`,
284
+ action: level === 'PASS' ? undefined : `Inspect task evidence for ${snapshot.status.branch}; agent-team and advisor outputs are gate inputs, not final lifecycle authority.`
285
+ }];
286
+ }
287
+
288
+ function inspectDurableGapRuntime(snapshot: DoctorProjectStatusSnapshot): DoctorCheck[] {
289
+ if (!snapshot.status) {
290
+ return unavailableRuntimeCheck('durable_gap_runtime', 'durable gap runtime', snapshot.error);
291
+ }
292
+ const gaps = snapshot.status.durableGaps;
293
+ const blocking = gaps.filter((gap) => gap.severity === 'blocking').length;
294
+ const warnings = gaps.filter((gap) => gap.severity === 'warning').length;
295
+ const tasks = [...new Set(gaps.map((gap) => gap.taskId).filter((taskId): taskId is string => typeof taskId === 'string'))].sort();
296
+ return [{
297
+ level: blocking > 0 ? 'FAIL' : warnings > 0 ? 'WARN' : 'PASS',
298
+ check: 'durable_gap_runtime',
299
+ message: `open=${gaps.length} blocking=${blocking} warning=${warnings} tasks=${tasks.join(',') || 'none'}`,
300
+ action: gaps.length > 0 ? `Inspect task evidence or status for ${snapshot.status.branch}; terminal durable gap closure is runtime/gate-policy controlled.` : undefined
301
+ }];
302
+ }
303
+
304
+ function inspectLatestEligibleRunSelector(snapshot: DoctorProjectStatusSnapshot): DoctorCheck[] {
305
+ if (!snapshot.status) {
306
+ return unavailableRuntimeCheck('latest_eligible_run_selector', 'latest eligible run selector', snapshot.error);
307
+ }
308
+ const selections = snapshot.status.latestEligibleRunsByTask;
309
+ const selected = selections.filter((selection) => selection.selected).length;
310
+ const candidates = selections.reduce((sum, selection) => sum + selection.candidates.length, 0);
311
+ const rejected = selections.reduce((sum, selection) => sum + selection.rejected.length, 0);
312
+ const blockedTasks = selections.filter((selection) => !selection.selected && selection.candidates.length > 0).map((selection) => selection.taskId);
313
+ return [{
314
+ level: blockedTasks.length > 0 ? 'WARN' : 'PASS',
315
+ check: 'latest_eligible_run_selector',
316
+ message: `tasks=${selections.length} selected=${selected} candidates=${candidates} rejected=${rejected} blocked_tasks=${blockedTasks.join(',') || 'none'}`,
317
+ action: blockedTasks.length > 0 ? `Inspect rejected candidates with sdd status --branch ${snapshot.status.branch}; default apply only uses compatible eligible runs.` : undefined
318
+ }];
156
319
  }
@@ -0,0 +1,80 @@
1
+ import { branchToSafePartition } from '../path-safety.js';
2
+ import { listRuntimeArtifactPayloads } from '../storage/runtime-store.js';
3
+ import type { RuntimeArtifactPayloadRecord, RuntimeArtifactPayloadStatus } from '../storage/runtime-store.js';
4
+
5
+ export const EVIDENCE_LOOKUP_CONTRACT_VERSION = 'phase-8.12-evidence-lookup-v1';
6
+
7
+ export interface EvidenceLookupFilters {
8
+ branch?: string | null;
9
+ runId?: string | null;
10
+ taskId?: string | null;
11
+ logicalRef?: string | null;
12
+ status?: RuntimeArtifactPayloadStatus | 'any' | null;
13
+ role?: string | null;
14
+ kind?: string | null;
15
+ }
16
+
17
+ export interface EvidenceLookupResult {
18
+ contract: typeof EVIDENCE_LOOKUP_CONTRACT_VERSION;
19
+ generatedAt: string;
20
+ retrievalMemoryOnly: true;
21
+ gateTruthAuthority: false;
22
+ reason: string;
23
+ filters: EvidenceLookupFilters;
24
+ payloads: RuntimeArtifactPayloadRecord[];
25
+ resolvedPayloads: RuntimeArtifactPayloadRecord[];
26
+ counts: Record<RuntimeArtifactPayloadStatus, number>;
27
+ }
28
+
29
+ export async function lookupEvidence(projectRoot: string, filters: EvidenceLookupFilters = {}): Promise<EvidenceLookupResult> {
30
+ const payloads = await listRuntimeArtifactPayloads(projectRoot, {
31
+ runId: filters.runId ?? null,
32
+ branchSlug: filters.branch ? branchToSafePartition(filters.branch) : null,
33
+ taskId: filters.taskId ?? null,
34
+ logicalRef: filters.logicalRef ?? null,
35
+ status: filters.status && filters.status !== 'any' ? filters.status : null
36
+ });
37
+ const filtered = payloads.filter((payload) => matchesMetadata(payload, filters));
38
+ const resolvedPayloads = resolveActivePayloads(filtered);
39
+ return {
40
+ contract: EVIDENCE_LOOKUP_CONTRACT_VERSION,
41
+ generatedAt: new Date().toISOString(),
42
+ retrievalMemoryOnly: true,
43
+ gateTruthAuthority: false,
44
+ reason: 'Evidence Lookup is retrieval memory over SQLite metadata and payload refs; PASS, verify, and sync-back authority must use runtime evidence gates.',
45
+ filters,
46
+ payloads: filtered,
47
+ resolvedPayloads,
48
+ counts: {
49
+ active: filtered.filter((payload) => payload.status === 'active').length,
50
+ candidate: filtered.filter((payload) => payload.status === 'candidate').length,
51
+ rejected: filtered.filter((payload) => payload.status === 'rejected').length,
52
+ superseded: filtered.filter((payload) => payload.status === 'superseded').length
53
+ }
54
+ };
55
+ }
56
+
57
+ function matchesMetadata(payload: RuntimeArtifactPayloadRecord, filters: EvidenceLookupFilters): boolean {
58
+ if (filters.role && payload.artifactRole !== filters.role) {
59
+ return false;
60
+ }
61
+ if (filters.kind && payload.artifactRole !== filters.kind) {
62
+ return false;
63
+ }
64
+ return true;
65
+ }
66
+
67
+ function resolveActivePayloads(payloads: RuntimeArtifactPayloadRecord[]): RuntimeArtifactPayloadRecord[] {
68
+ const byLogicalRef = new Map<string, RuntimeArtifactPayloadRecord>();
69
+ for (const payload of payloads) {
70
+ if (payload.status !== 'active') {
71
+ continue;
72
+ }
73
+ const key = `${payload.branchSlug}\\0${payload.taskId ?? ''}\\0${payload.logicalRef}`;
74
+ const current = byLogicalRef.get(key);
75
+ if (!current || payload.sequence > current.sequence || (payload.sequence === current.sequence && payload.createdAt > current.createdAt)) {
76
+ byLogicalRef.set(key, payload);
77
+ }
78
+ }
79
+ return Array.from(byLogicalRef.values()).sort((left, right) => right.createdAt.localeCompare(left.createdAt) || right.sequence - left.sequence);
80
+ }
@@ -3,6 +3,7 @@ import { TEST_EVIDENCE_RUN_CONTRACT_VERSION } from '../contracts.js';
3
3
 
4
4
  export type TestEvidenceStatus = 'PASS' | 'FAIL' | 'BLOCKED';
5
5
  export type EvidenceCoverageStatus = 'complete' | 'partial' | 'missing' | 'stale';
6
+ export type CapabilityEvidenceClass = 'accepted' | 'candidate' | 'quarantined' | 'diagnostic' | 'blocked';
6
7
 
7
8
  export interface TestCommandEvidence {
8
9
  command: string;
@@ -21,6 +22,16 @@ export interface AcceptanceEvidenceCoverage {
21
22
  gaps: string[];
22
23
  }
23
24
 
25
+ export interface CapabilityEvidenceClassification {
26
+ class: CapabilityEvidenceClass;
27
+ source: 'professional_capability' | 'external_source' | 'runtime_diagnostic';
28
+ domainOrSourceId: string;
29
+ evidenceRefs: RuntimeRef[];
30
+ acceptanceRefs: string[];
31
+ provenanceRefs: RuntimeRef[];
32
+ reason: string;
33
+ }
34
+
24
35
  export interface UnifiedTestEvidenceRun {
25
36
  contract: typeof TEST_EVIDENCE_RUN_CONTRACT_VERSION;
26
37
  id: string;
@@ -30,6 +41,7 @@ export interface UnifiedTestEvidenceRun {
30
41
  policyJudgment: TestEvidenceStatus;
31
42
  commands: TestCommandEvidence[];
32
43
  acceptanceCoverage: AcceptanceEvidenceCoverage[];
44
+ capabilityEvidence: CapabilityEvidenceClassification[];
33
45
  syncBackReady: boolean;
34
46
  gaps: string[];
35
47
  next: string;
@@ -1,17 +1,16 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { readdir, readFile } from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  import {
5
5
  AGENT_EXECUTION_RECORD_CONTRACT_VERSION,
6
6
  TEAM_SESSION_RECORD_CONTRACT_VERSION
7
7
  } from '../contracts.js';
8
8
  import {
9
- getAgentExecutionRecordPath,
10
- getAgentExecutionsDir,
11
- getTeamSessionRecordPath,
12
- getTeamSessionsDir
9
+ getLegacyAgentExecutionsDir,
10
+ getLegacyTeamSessionsDir
13
11
  } from '../runtime-paths.js';
14
12
  import { exists } from '../storage/json-io.js';
13
+ import { listRuntimeAgentExecutions, listRuntimeTeamSessions, recordRuntimeAgentExecution, recordRuntimeTeamSession } from '../storage/runtime-store.js';
15
14
  import { BUILT_IN_SKILL_CAPABILITIES } from '../registries/skill-capabilities.js';
16
15
  import type { ArtifactResultIngestionRecord } from '../artifacts/ingestion.js';
17
16
  import type {
@@ -24,19 +23,21 @@ import type {
24
23
  } from '../router/agent-runtime.js';
25
24
 
26
25
  export async function writeAgentExecutionRecord(projectRoot: string, record: AgentExecutionRecord): Promise<AgentExecutionRecord> {
27
- await mkdir(getAgentExecutionsDir(projectRoot, record.runId), { recursive: true });
28
- await writeFile(getAgentExecutionRecordPath(projectRoot, record.runId, record.executionId), `${JSON.stringify(record, null, 2)}\n`, 'utf8');
26
+ await recordRuntimeAgentExecution(projectRoot, record);
29
27
  return record;
30
28
  }
31
29
 
32
30
  export async function writeTeamSessionRecord(projectRoot: string, record: TeamSessionRecord): Promise<TeamSessionRecord> {
33
- await mkdir(getTeamSessionsDir(projectRoot, record.runId), { recursive: true });
34
- await writeFile(getTeamSessionRecordPath(projectRoot, record.runId, record.teamId), `${JSON.stringify(record, null, 2)}\n`, 'utf8');
31
+ await recordRuntimeTeamSession(projectRoot, record);
35
32
  return record;
36
33
  }
37
34
 
38
35
  export async function listAgentExecutionRecords(projectRoot: string, runId: string): Promise<AgentExecutionRecord[]> {
39
- const recordsDir = getAgentExecutionsDir(projectRoot, runId);
36
+ const runtimeRecords = await listRuntimeAgentExecutions(projectRoot, runId);
37
+ if (runtimeRecords.length > 0) {
38
+ return runtimeRecords;
39
+ }
40
+ const recordsDir = getLegacyAgentExecutionsDir(projectRoot, runId);
40
41
  if (!await exists(recordsDir)) {
41
42
  return [];
42
43
  }
@@ -54,7 +55,11 @@ export async function listAgentExecutionRecords(projectRoot: string, runId: stri
54
55
  }
55
56
 
56
57
  export async function listTeamSessionRecords(projectRoot: string, runId: string): Promise<TeamSessionRecord[]> {
57
- const recordsDir = getTeamSessionsDir(projectRoot, runId);
58
+ const runtimeRecords = await listRuntimeTeamSessions(projectRoot, runId);
59
+ if (runtimeRecords.length > 0) {
60
+ return runtimeRecords;
61
+ }
62
+ const recordsDir = getLegacyTeamSessionsDir(projectRoot, runId);
58
63
  if (!await exists(recordsDir)) {
59
64
  return [];
60
65
  }
@@ -9,6 +9,7 @@ import { doctor } from '../doctor/doctor.js';
9
9
  import { writeArtifact } from '../run-state/artifacts.js';
10
10
  import { readRunState } from '../run-state/run-state.js';
11
11
  import { validResultArtifact, validTaskMarkdown, writeBranchDocs } from '../test-support/fixtures.js';
12
+ import { writeVerifyContract } from '../verification/verify-contract.js';
12
13
  import { inspectBackgroundExecutor, runBackgroundExecutor } from './background-executor.js';
13
14
 
14
15
  test('background executor claims one delegation and persists background run state', async () => {
@@ -16,6 +17,7 @@ test('background executor claims one delegation and persists background run stat
16
17
  try {
17
18
  await initProject(root);
18
19
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []));
20
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
19
21
 
20
22
  const result = await runBackgroundExecutor(root, { taskId: 'B1' });
21
23
  const state = await readRunState(root, result.runId);
@@ -39,6 +41,7 @@ test('background executor ingests supplied artifact and reaches terminal state',
39
41
  try {
40
42
  await initProject(root);
41
43
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []));
44
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
42
45
 
43
46
  const claimed = await runBackgroundExecutor(root, { taskId: 'B1' });
44
47
  await writeArtifact(root, claimed.runId, 'implementer-B1.md', validResultArtifact('implementer', 'B1', 'PASS', 'artifacts/implementer-B1.md'));
@@ -68,6 +71,7 @@ test('claude code subagent worker spawns host process and ingests stdout artifac
68
71
  try {
69
72
  await initProject(root);
70
73
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []));
74
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
71
75
  const hostScript = path.join(root, 'fake-claude-host.mjs');
72
76
  await writeFile(hostScript, [
73
77
  "const prompt = process.argv[2] ?? '';",
@@ -101,6 +105,7 @@ test('background executor blocks invalid artifact evidence instead of completing
101
105
  try {
102
106
  await initProject(root);
103
107
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []));
108
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
104
109
 
105
110
  const claimed = await runBackgroundExecutor(root, { taskId: 'B1' });
106
111
  await writeArtifact(root, claimed.runId, 'implementer-B1.md', '# Missing contract\n');
@@ -125,6 +130,7 @@ test('background executor requires approval for database manual gate and accepts
125
130
  try {
126
131
  await initProject(root);
127
132
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []).replace('risk: []', 'risk:\n - database'));
133
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
128
134
 
129
135
  const blocked = await runBackgroundExecutor(root, { taskId: 'B1' });
130
136
  assert.equal(blocked.status, 'blocked');
@@ -153,6 +159,7 @@ test('background executor blocks manual handoff worker adapters', async () => {
153
159
  try {
154
160
  await initProject(root);
155
161
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []));
162
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
156
163
 
157
164
  const result = await runBackgroundExecutor(root, { taskId: 'B1', workerAdapterId: 'manual-handoff-worker' });
158
165
 
@@ -11,6 +11,7 @@ import { writeArtifact } from '../run-state/artifacts.js';
11
11
  import { inspectRun } from '../run-state/inspect-run.js';
12
12
  import { readRunState } from '../run-state/run-state.js';
13
13
  import { validResultArtifact, validTaskMarkdown, writeBranchDocs } from '../test-support/fixtures.js';
14
+ import { writeVerifyContract } from '../verification/verify-contract.js';
14
15
  import { runBackgroundExecutor } from './background-executor.js';
15
16
  import {
16
17
  claimResidentWorkerRuntime,
@@ -26,6 +27,7 @@ test('resident worker runtime claim persists run-bound runtime evidence', async
26
27
  try {
27
28
  await initProject(root);
28
29
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []));
30
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
29
31
 
30
32
  const result = await claimResidentWorkerRuntime(root, { taskId: 'B1', runtimeId: 'R-B1-implementer-test', leaseSeconds: 60 });
31
33
  const runtime = await readResidentWorkerRuntimeRecord(root, result.runId, 'R-B1-implementer-test');
@@ -51,6 +53,7 @@ test('resident worker runtime heartbeat renews lease without completing task', a
51
53
  try {
52
54
  await initProject(root);
53
55
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []));
56
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
54
57
 
55
58
  const claimed = await claimResidentWorkerRuntime(root, { taskId: 'B1', runtimeId: 'R-B1-heartbeat', leaseSeconds: 60 });
56
59
  const before = claimed.runtime?.leaseExpiresAt;
@@ -74,6 +77,7 @@ test('resident worker runtime stale lease is visible to status and doctor', asyn
74
77
  try {
75
78
  await initProject(root);
76
79
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []));
80
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
77
81
 
78
82
  const claimed = await claimResidentWorkerRuntime(root, { taskId: 'B1', runtimeId: 'R-B1-stale', leaseSeconds: 60 });
79
83
  assert.ok(claimed.runtime);
@@ -104,6 +108,7 @@ test('resident worker runtime heartbeat does not reopen terminal delegations', a
104
108
  try {
105
109
  await initProject(root);
106
110
  await writeBranchDocs(root, 'master', validTaskMarkdown('B1', []));
111
+ await writeVerifyContract(root, { branch: 'master', branchSource: 'cli_option', force: true });
107
112
 
108
113
  const claimed = await claimResidentWorkerRuntime(root, { taskId: 'B1', runtimeId: 'R-B1-terminal', leaseSeconds: 60 });
109
114
  await writeArtifact(root, claimed.runId, 'implementer-B1.md', validResultArtifact('implementer', 'B1', 'PASS', 'artifacts/implementer-B1.md'));
@@ -1,13 +1,14 @@
1
- import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
1
+ import { readdir, readFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { RESIDENT_WORKER_RUNTIME_CONTRACT_VERSION } from '../contracts.js';
4
4
  import { contractIssue, messageFromError, type ContractValidationIssue } from '../contracts/issues.js';
5
5
  import { listDelegationQueueItems } from '../delegation/queue.js';
6
6
  import { isDelegationTerminal } from '../delegation/validation.js';
7
- import { getWorkerRuntimeRecordPath, getWorkerRuntimesDir } from '../runtime-paths.js';
7
+ import { getLegacyWorkerRuntimeRecordPath, getLegacyWorkerRuntimesDir } from '../runtime-paths.js';
8
8
  import { appendEvent } from '../run-state/events.js';
9
9
  import { readRunState, writeRunState } from '../run-state/run-state.js';
10
10
  import { exists } from '../storage/json-io.js';
11
+ import { listRuntimeWorkerRuntimes, readRuntimeWorkerRuntime, recordRuntimeWorkerRuntime } from '../storage/runtime-store.js';
11
12
  import type { DelegationQueueItem } from '../run-state/run-index.js';
12
13
  import { inspectWorkerAdapterContract, type WorkerAdapterContract } from '../registries/worker-adapters.js';
13
14
  import { toSafeRecordId } from './agent-execution-records.js';
@@ -108,18 +109,25 @@ export interface ResidentWorkerRuntimeList {
108
109
  }
109
110
 
110
111
  export async function writeResidentWorkerRuntimeRecord(projectRoot: string, record: ResidentWorkerRuntimeRecord): Promise<ResidentWorkerRuntimeRecord> {
111
- await mkdir(getWorkerRuntimesDir(projectRoot, record.runId), { recursive: true });
112
- await writeFile(getWorkerRuntimeRecordPath(projectRoot, record.runId, record.runtimeId), `${JSON.stringify(record, null, 2)}\n`, 'utf8');
112
+ await recordRuntimeWorkerRuntime(projectRoot, record);
113
113
  return record;
114
114
  }
115
115
 
116
116
  export async function readResidentWorkerRuntimeRecord(projectRoot: string, runId: string, runtimeId: string): Promise<ResidentWorkerRuntimeRecord> {
117
- const raw = await readFile(getWorkerRuntimeRecordPath(projectRoot, runId, runtimeId), 'utf8');
117
+ const runtimeRecord = await readRuntimeWorkerRuntime(projectRoot, runId, runtimeId);
118
+ if (runtimeRecord) {
119
+ return runtimeRecord;
120
+ }
121
+ const raw = await readFile(getLegacyWorkerRuntimeRecordPath(projectRoot, runId, runtimeId), 'utf8');
118
122
  return JSON.parse(raw) as ResidentWorkerRuntimeRecord;
119
123
  }
120
124
 
121
125
  export async function listResidentWorkerRuntimeRecords(projectRoot: string, runId: string): Promise<ResidentWorkerRuntimeRecord[]> {
122
- const recordsDir = getWorkerRuntimesDir(projectRoot, runId);
126
+ const runtimeRecords = await listRuntimeWorkerRuntimes(projectRoot, runId);
127
+ if (runtimeRecords.length > 0) {
128
+ return runtimeRecords;
129
+ }
130
+ const recordsDir = getLegacyWorkerRuntimesDir(projectRoot, runId);
123
131
  if (!await exists(recordsDir)) {
124
132
  return [];
125
133
  }
@@ -0,0 +1,102 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+
4
+ import { STAGE_TEAM_RUNTIME_CONTRACT_VERSION } from '../contracts.js';
5
+ import { assertAdvisoryAssessment, assertValidFanInEvidenceSet, assertValidStageRoleResult, buildFanInEvidenceSet, describeStageTeamActivation, type FanInEvidenceSetRecord, type LlmAdvisorAssessmentRecord, type StageRoleResultRecord } from './stage-team-runtime.js';
6
+
7
+ test('stage role results reject lifecycle transition authority fields', () => {
8
+ const result = roleResult({ payload: { final_pass: true } });
9
+
10
+ assert.throws(() => assertValidStageRoleResult(result), /final_pass/);
11
+ assert.throws(() => assertValidStageRoleResult({ ...roleResult(), syncBackApproved: true }), /syncBackApproved/);
12
+ assert.doesNotThrow(() => assertValidStageRoleResult(roleResult()));
13
+ });
14
+
15
+ test('advisor assessments are advisory-only and cannot carry lifecycle transitions', () => {
16
+ assert.throws(() => assertAdvisoryAssessment(advisor({ advisoryOnly: false } as unknown as Partial<LlmAdvisorAssessmentRecord>)), /advisoryOnly=true/);
17
+ assert.throws(() => assertAdvisoryAssessment(advisor({ payload: { ship_ready: true } })), /ship_ready/);
18
+ assert.doesNotThrow(() => assertAdvisoryAssessment(advisor()));
19
+ assert.throws(() => assertAdvisoryAssessment(advisor({ validity: 'unknown' } as unknown as Partial<LlmAdvisorAssessmentRecord>)), /validity/);
20
+ assert.throws(() => assertAdvisoryAssessment(advisor({ confidence: 'none' } as unknown as Partial<LlmAdvisorAssessmentRecord>)), /confidence/);
21
+ });
22
+
23
+ test('fan-in evidence set is gate input only and deduplicates referenced inputs', () => {
24
+ const fanIn = buildFanInEvidenceSet({
25
+ fanInId: 'fanin-001',
26
+ partition: 'feature',
27
+ runId: 'run-001',
28
+ taskId: 'T1',
29
+ stage: 'test',
30
+ roleResultIds: ['role-result-2', 'role-result-1', 'role-result-1'],
31
+ durableGapIds: ['gap-1'],
32
+ proposalRefs: ['proposal.md'],
33
+ advisorAssessmentIds: ['advisor-1'],
34
+ evidenceRefs: ['artifacts/validation-T1.md'],
35
+ canonicalEvidenceRefs: ['payload-1'],
36
+ createdAt: '2026-01-01T00:00:00.000Z',
37
+ payload: { note: 'input only' }
38
+ });
39
+
40
+ assert.equal(fanIn.gateInputOnly, true);
41
+ assert.deepEqual(fanIn.roleResultIds, ['role-result-1', 'role-result-2']);
42
+ assert.throws(() => buildFanInEvidenceSet({ ...fanIn, payload: { stagePassed: true } }), /stagePassed/);
43
+ assert.throws(() => assertValidFanInEvidenceSet({ ...fanIn, gateInputOnly: false } as unknown as FanInEvidenceSetRecord), /gateInputOnly=true/);
44
+ });
45
+
46
+ test('lifecycle profiles explain team activation without requiring direct team mode', () => {
47
+ const direct = describeStageTeamActivation('direct');
48
+ const recover = describeStageTeamActivation('recover');
49
+
50
+ assert.equal(direct.requiredTeam, false);
51
+ assert.equal(direct.roles.length, 0);
52
+ assert.equal(recover.requiredTeam, true);
53
+ assert.equal(recover.roles.some((role) => role.roleId === 'role.sync-risk-reviewer' && role.required), true);
54
+ });
55
+
56
+ function roleResult(overrides: Partial<StageRoleResultRecord> & Record<string, unknown> = {}): StageRoleResultRecord & Record<string, unknown> {
57
+ return {
58
+ contract: STAGE_TEAM_RUNTIME_CONTRACT_VERSION,
59
+ resultId: 'role-result-001',
60
+ sessionId: 'session-001',
61
+ assignmentId: 'assignment-001',
62
+ partition: 'feature',
63
+ runId: 'run-001',
64
+ taskId: 'T1',
65
+ roleId: 'role.evidence-runner',
66
+ agentId: 'validator',
67
+ outputKind: 'evidence',
68
+ authorityCeiling: 'gate_input',
69
+ status: 'accepted',
70
+ summary: 'Collected validation evidence.',
71
+ evidenceRefs: ['artifacts/validation-T1.md'],
72
+ durableGapIds: [],
73
+ proposalRefs: [],
74
+ advisorAssessmentIds: [],
75
+ createdAt: '2026-01-01T00:00:00.000Z',
76
+ payload: {},
77
+ ...overrides
78
+ };
79
+ }
80
+
81
+ function advisor(overrides: Partial<LlmAdvisorAssessmentRecord> & Record<string, unknown> = {}): LlmAdvisorAssessmentRecord & Record<string, unknown> {
82
+ return {
83
+ contract: STAGE_TEAM_RUNTIME_CONTRACT_VERSION,
84
+ assessmentId: 'advisor-001',
85
+ sessionId: 'session-001',
86
+ partition: 'feature',
87
+ runId: 'run-001',
88
+ taskId: 'T1',
89
+ kind: 'evidence_sufficiency',
90
+ concern: 'medium',
91
+ validity: 'valid',
92
+ confidence: 'high',
93
+ advisoryOnly: true,
94
+ summary: 'Evidence is sufficient for gate input, pending deterministic checks.',
95
+ evidenceRefs: ['artifacts/validation-T1.md'],
96
+ durableGapIds: [],
97
+ proposalRefs: [],
98
+ createdAt: '2026-01-01T00:00:00.000Z',
99
+ payload: {},
100
+ ...overrides
101
+ };
102
+ }