agentic-orchestrator 0.1.6 → 0.1.7

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 (426) hide show
  1. package/.prettierignore +10 -0
  2. package/.prettierrc.json +24 -0
  3. package/CLAUDE.md +3 -2
  4. package/README.md +47 -46
  5. package/agentic/orchestrator/defaults/policy.defaults.yaml +1 -1
  6. package/agentic/orchestrator/prompts/planner.system.md +1 -0
  7. package/agentic/orchestrator/schemas/agents.schema.json +4 -21
  8. package/agentic/orchestrator/schemas/gates.schema.json +4 -19
  9. package/agentic/orchestrator/schemas/index.schema.json +3 -14
  10. package/agentic/orchestrator/schemas/multi-project.schema.json +2 -8
  11. package/agentic/orchestrator/schemas/plan.schema.json +6 -26
  12. package/agentic/orchestrator/schemas/policy.schema.json +19 -81
  13. package/agentic/orchestrator/schemas/policy.user.schema.json +1 -5
  14. package/agentic/orchestrator/schemas/qa_test_index.schema.json +5 -29
  15. package/agentic/orchestrator/schemas/state.schema.json +11 -61
  16. package/agentic/orchestrator/tools/catalog.json +33 -164
  17. package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +1 -3
  18. package/agentic/orchestrator/tools/schemas/input/feature.delete.input.schema.json +1 -5
  19. package/agentic/orchestrator/tools/schemas/input/feature.get_context.input.schema.json +1 -3
  20. package/agentic/orchestrator/tools/schemas/input/feature.init.input.schema.json +1 -4
  21. package/agentic/orchestrator/tools/schemas/input/feature.log_append.input.schema.json +1 -5
  22. package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +1 -6
  23. package/agentic/orchestrator/tools/schemas/input/feature.state_get.input.schema.json +1 -3
  24. package/agentic/orchestrator/tools/schemas/input/feature.state_patch.input.schema.json +1 -5
  25. package/agentic/orchestrator/tools/schemas/input/gates.run.input.schema.json +1 -5
  26. package/agentic/orchestrator/tools/schemas/input/locks.acquire.input.schema.json +1 -5
  27. package/agentic/orchestrator/tools/schemas/input/locks.release.input.schema.json +1 -5
  28. package/agentic/orchestrator/tools/schemas/input/performance.record_outcome.input.schema.json +10 -1
  29. package/agentic/orchestrator/tools/schemas/input/plan.get.input.schema.json +1 -3
  30. package/agentic/orchestrator/tools/schemas/input/plan.submit.input.schema.json +1 -5
  31. package/agentic/orchestrator/tools/schemas/input/plan.update.input.schema.json +1 -6
  32. package/agentic/orchestrator/tools/schemas/input/qa.test_index_get.input.schema.json +1 -3
  33. package/agentic/orchestrator/tools/schemas/input/qa.test_index_update.input.schema.json +1 -6
  34. package/agentic/orchestrator/tools/schemas/input/repo.apply_patch.input.schema.json +1 -5
  35. package/agentic/orchestrator/tools/schemas/input/repo.diff.input.schema.json +1 -3
  36. package/agentic/orchestrator/tools/schemas/input/repo.diff_bundle.input.schema.json +1 -3
  37. package/agentic/orchestrator/tools/schemas/input/repo.ensure_worktree.input.schema.json +1 -4
  38. package/agentic/orchestrator/tools/schemas/input/repo.read_file.input.schema.json +1 -4
  39. package/agentic/orchestrator/tools/schemas/input/repo.search.input.schema.json +1 -4
  40. package/agentic/orchestrator/tools/schemas/input/repo.status.input.schema.json +1 -3
  41. package/agentic/orchestrator/tools/schemas/input/report.feature_summary.input.schema.json +1 -3
  42. package/agentic/orchestrator/tools/schemas/output/collisions.scan.output.schema.json +1 -3
  43. package/agentic/orchestrator/tools/schemas/output/evidence.latest.output.schema.json +1 -4
  44. package/agentic/orchestrator/tools/schemas/output/feature.delete.output.schema.json +4 -20
  45. package/agentic/orchestrator/tools/schemas/output/feature.discover_specs.output.schema.json +2 -7
  46. package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +1 -8
  47. package/agentic/orchestrator/tools/schemas/output/feature.init.output.schema.json +1 -5
  48. package/agentic/orchestrator/tools/schemas/output/feature.log_append.output.schema.json +1 -5
  49. package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +1 -6
  50. package/agentic/orchestrator/tools/schemas/output/feature.state_get.output.schema.json +1 -4
  51. package/agentic/orchestrator/tools/schemas/output/feature.state_patch.output.schema.json +1 -5
  52. package/agentic/orchestrator/tools/schemas/output/gates.list.output.schema.json +2 -7
  53. package/agentic/orchestrator/tools/schemas/output/gates.run.output.schema.json +1 -8
  54. package/agentic/orchestrator/tools/schemas/output/locks.acquire.output.schema.json +1 -7
  55. package/agentic/orchestrator/tools/schemas/output/locks.release.output.schema.json +1 -5
  56. package/agentic/orchestrator/tools/schemas/output/performance.get_analytics.output.schema.json +22 -2
  57. package/agentic/orchestrator/tools/schemas/output/plan.get.output.schema.json +1 -4
  58. package/agentic/orchestrator/tools/schemas/output/plan.submit.output.schema.json +1 -5
  59. package/agentic/orchestrator/tools/schemas/output/plan.update.output.schema.json +1 -5
  60. package/agentic/orchestrator/tools/schemas/output/qa.test_index_get.output.schema.json +1 -5
  61. package/agentic/orchestrator/tools/schemas/output/qa.test_index_update.output.schema.json +1 -4
  62. package/agentic/orchestrator/tools/schemas/output/repo.apply_patch.output.schema.json +1 -6
  63. package/agentic/orchestrator/tools/schemas/output/repo.diff.output.schema.json +1 -4
  64. package/agentic/orchestrator/tools/schemas/output/repo.diff_bundle.output.schema.json +1 -7
  65. package/agentic/orchestrator/tools/schemas/output/repo.ensure_worktree.output.schema.json +1 -6
  66. package/agentic/orchestrator/tools/schemas/output/repo.read_file.output.schema.json +1 -5
  67. package/agentic/orchestrator/tools/schemas/output/repo.search.output.schema.json +1 -5
  68. package/agentic/orchestrator/tools/schemas/output/repo.status.output.schema.json +1 -5
  69. package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +1 -4
  70. package/apps/control-plane/scripts/validate-architecture-rules.mjs +16 -5
  71. package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +30 -8
  72. package/apps/control-plane/scripts/validate-mcp-contracts.ts +13 -7
  73. package/apps/control-plane/src/application/adapters/adapter-registry.ts +35 -15
  74. package/apps/control-plane/src/application/multi-project-loader.ts +27 -10
  75. package/apps/control-plane/src/application/services/activity-monitor-service.ts +26 -14
  76. package/apps/control-plane/src/application/services/collision-queue-service.ts +31 -17
  77. package/apps/control-plane/src/application/services/cost-tracking-service.ts +23 -16
  78. package/apps/control-plane/src/application/services/dependency-scheduler-service.ts +12 -4
  79. package/apps/control-plane/src/application/services/feature-deletion-service.ts +94 -58
  80. package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +19 -13
  81. package/apps/control-plane/src/application/services/feature-state-service.ts +29 -19
  82. package/apps/control-plane/src/application/services/gate-interpolation-service.ts +7 -2
  83. package/apps/control-plane/src/application/services/gate-service.ts +64 -41
  84. package/apps/control-plane/src/application/services/instance-isolation-service.ts +1 -1
  85. package/apps/control-plane/src/application/services/issue-tracker-service.ts +49 -38
  86. package/apps/control-plane/src/application/services/lock-service.ts +75 -49
  87. package/apps/control-plane/src/application/services/merge-service.ts +91 -50
  88. package/apps/control-plane/src/application/services/notifier-service.ts +42 -20
  89. package/apps/control-plane/src/application/services/patch-service.ts +73 -44
  90. package/apps/control-plane/src/application/services/performance-analytics-service.ts +8 -6
  91. package/apps/control-plane/src/application/services/plan-service.ts +148 -89
  92. package/apps/control-plane/src/application/services/policy-loader-service.ts +10 -4
  93. package/apps/control-plane/src/application/services/pr-monitor-service.ts +33 -14
  94. package/apps/control-plane/src/application/services/qa-index-service.ts +20 -16
  95. package/apps/control-plane/src/application/services/reactions-service.ts +30 -15
  96. package/apps/control-plane/src/application/services/reporting-service.ts +16 -12
  97. package/apps/control-plane/src/application/services/run-lease-service.ts +138 -81
  98. package/apps/control-plane/src/application/tools/tool-metadata.ts +5 -5
  99. package/apps/control-plane/src/application/tools/tool-router.ts +6 -3
  100. package/apps/control-plane/src/cli/aop.ts +2 -2
  101. package/apps/control-plane/src/cli/attach-command-handler.ts +9 -9
  102. package/apps/control-plane/src/cli/cleanup-command-handler.ts +16 -11
  103. package/apps/control-plane/src/cli/cli-argument-parser.ts +6 -3
  104. package/apps/control-plane/src/cli/dashboard-command-handler.ts +28 -8
  105. package/apps/control-plane/src/cli/delete-command-handler.ts +7 -7
  106. package/apps/control-plane/src/cli/help-command-handler.ts +61 -32
  107. package/apps/control-plane/src/cli/init-command-handler.ts +110 -54
  108. package/apps/control-plane/src/cli/io.ts +7 -3
  109. package/apps/control-plane/src/cli/resume-command-handler.ts +21 -13
  110. package/apps/control-plane/src/cli/retry-command-handler.ts +12 -11
  111. package/apps/control-plane/src/cli/run-command-handler.ts +12 -8
  112. package/apps/control-plane/src/cli/send-command-handler.ts +6 -6
  113. package/apps/control-plane/src/cli/spec-ingestion-service.ts +14 -8
  114. package/apps/control-plane/src/cli/spec-input-resolver.ts +6 -1
  115. package/apps/control-plane/src/cli/spec-utils.ts +2 -2
  116. package/apps/control-plane/src/cli/status-command-handler.ts +13 -12
  117. package/apps/control-plane/src/cli/tooling.ts +3 -3
  118. package/apps/control-plane/src/cli/types.ts +1 -1
  119. package/apps/control-plane/src/core/collisions.ts +27 -10
  120. package/apps/control-plane/src/core/constants.ts +13 -7
  121. package/apps/control-plane/src/core/error-codes.ts +1 -1
  122. package/apps/control-plane/src/core/fs.ts +11 -5
  123. package/apps/control-plane/src/core/gates.ts +53 -27
  124. package/apps/control-plane/src/core/git.ts +18 -6
  125. package/apps/control-plane/src/core/kernel.ts +515 -227
  126. package/apps/control-plane/src/core/patch.ts +7 -3
  127. package/apps/control-plane/src/core/path-layout.ts +5 -1
  128. package/apps/control-plane/src/core/path-rules.ts +19 -5
  129. package/apps/control-plane/src/core/qa-index.ts +26 -12
  130. package/apps/control-plane/src/core/response.ts +9 -6
  131. package/apps/control-plane/src/core/schemas.ts +29 -10
  132. package/apps/control-plane/src/core/tool-caller.ts +1 -1
  133. package/apps/control-plane/src/core/workspace-hooks.ts +5 -5
  134. package/apps/control-plane/src/index.ts +3 -9
  135. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +69 -32
  136. package/apps/control-plane/src/mcp/kernel-tool-executor.ts +7 -3
  137. package/apps/control-plane/src/mcp/mcp-server-adapter.ts +12 -10
  138. package/apps/control-plane/src/mcp/operation-ledger.ts +18 -8
  139. package/apps/control-plane/src/mcp/protocol-contract.ts +2 -2
  140. package/apps/control-plane/src/mcp/runtime-factory.ts +15 -6
  141. package/apps/control-plane/src/mcp/token-auth-verifier.ts +3 -2
  142. package/apps/control-plane/src/mcp/token-claims-validator.ts +11 -7
  143. package/apps/control-plane/src/mcp/tool-authorizer.ts +1 -3
  144. package/apps/control-plane/src/mcp/tool-client.ts +17 -5
  145. package/apps/control-plane/src/mcp/tool-contract-validator.ts +17 -8
  146. package/apps/control-plane/src/mcp/tool-registry-loader.ts +7 -3
  147. package/apps/control-plane/src/mcp/tool-runtime.ts +66 -39
  148. package/apps/control-plane/src/mcp/tools-markdown-generator.ts +6 -1
  149. package/apps/control-plane/src/providers/providers.ts +72 -48
  150. package/apps/control-plane/src/supervisor/build-wave-executor.ts +44 -25
  151. package/apps/control-plane/src/supervisor/planning-wave-executor.ts +46 -33
  152. package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +1 -1
  153. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +38 -23
  154. package/apps/control-plane/src/supervisor/run-coordinator.ts +71 -36
  155. package/apps/control-plane/src/supervisor/runtime.ts +59 -35
  156. package/apps/control-plane/src/supervisor/session-orchestrator.ts +48 -31
  157. package/apps/control-plane/src/supervisor/types.ts +22 -7
  158. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +30 -20
  159. package/apps/control-plane/test/activity-monitor.spec.ts +54 -30
  160. package/apps/control-plane/test/adapter-registry.spec.ts +5 -5
  161. package/apps/control-plane/test/aop.spec.ts +4 -4
  162. package/apps/control-plane/test/batch-operations.spec.ts +20 -18
  163. package/apps/control-plane/test/bootstrap-attach.spec.ts +52 -19
  164. package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +58 -27
  165. package/apps/control-plane/test/bootstrap.spec.ts +72 -40
  166. package/apps/control-plane/test/cleanup-command.spec.ts +86 -32
  167. package/apps/control-plane/test/cli-helpers.spec.ts +119 -66
  168. package/apps/control-plane/test/cli.spec.ts +1 -1
  169. package/apps/control-plane/test/cli.unit.spec.ts +226 -167
  170. package/apps/control-plane/test/collision-queue.spec.ts +49 -40
  171. package/apps/control-plane/test/collisions.spec.ts +30 -30
  172. package/apps/control-plane/test/core-utils.spec.ts +29 -15
  173. package/apps/control-plane/test/cost-tracking.spec.ts +38 -22
  174. package/apps/control-plane/test/dashboard-api.integration.spec.ts +68 -36
  175. package/apps/control-plane/test/dashboard-client.spec.ts +18 -12
  176. package/apps/control-plane/test/dashboard-command.spec.ts +11 -7
  177. package/apps/control-plane/test/delete-command-handler.spec.ts +49 -41
  178. package/apps/control-plane/test/dependency-scheduler.spec.ts +47 -20
  179. package/apps/control-plane/test/epoch-tracking.spec.ts +9 -9
  180. package/apps/control-plane/test/feature-deletion-service.spec.ts +60 -52
  181. package/apps/control-plane/test/feature-lifecycle.spec.ts +36 -17
  182. package/apps/control-plane/test/gates.spec.ts +101 -81
  183. package/apps/control-plane/test/git-spawn-error.spec.ts +1 -1
  184. package/apps/control-plane/test/helpers.ts +10 -6
  185. package/apps/control-plane/test/incremental-gates.spec.ts +59 -20
  186. package/apps/control-plane/test/init-wizard.spec.ts +162 -67
  187. package/apps/control-plane/test/instance-isolation.spec.ts +43 -10
  188. package/apps/control-plane/test/issue-tracker.spec.ts +368 -128
  189. package/apps/control-plane/test/kernel-collision-replay.spec.ts +50 -29
  190. package/apps/control-plane/test/kernel.branches.spec.ts +64 -40
  191. package/apps/control-plane/test/kernel.coverage.spec.ts +85 -49
  192. package/apps/control-plane/test/kernel.coverage2.spec.ts +109 -65
  193. package/apps/control-plane/test/kernel.spec.ts +134 -51
  194. package/apps/control-plane/test/lock-service.spec.ts +92 -68
  195. package/apps/control-plane/test/mcp-helpers.spec.ts +53 -39
  196. package/apps/control-plane/test/mcp.spec.ts +231 -115
  197. package/apps/control-plane/test/merge-service.spec.ts +142 -94
  198. package/apps/control-plane/test/multi-project.spec.ts +28 -22
  199. package/apps/control-plane/test/notifier-service.spec.ts +136 -92
  200. package/apps/control-plane/test/parallel-gates.spec.ts +51 -35
  201. package/apps/control-plane/test/patch-service.spec.ts +128 -48
  202. package/apps/control-plane/test/performance-analytics.spec.ts +99 -63
  203. package/apps/control-plane/test/plan-service.spec.ts +50 -39
  204. package/apps/control-plane/test/planning-wave-executor.spec.ts +95 -71
  205. package/apps/control-plane/test/policy-loader-service.spec.ts +41 -19
  206. package/apps/control-plane/test/pr-monitor.spec.ts +113 -64
  207. package/apps/control-plane/test/providers.spec.ts +133 -102
  208. package/apps/control-plane/test/qa-index-service.spec.ts +31 -33
  209. package/apps/control-plane/test/qa-index.spec.ts +58 -61
  210. package/apps/control-plane/test/reactions.spec.ts +88 -45
  211. package/apps/control-plane/test/response.spec.ts +5 -5
  212. package/apps/control-plane/test/resume-command.spec.ts +121 -80
  213. package/apps/control-plane/test/run-coordinator.spec.ts +205 -136
  214. package/apps/control-plane/test/schema-date-time.spec.ts +49 -41
  215. package/apps/control-plane/test/service-retry-paths.spec.ts +77 -57
  216. package/apps/control-plane/test/services.spec.ts +147 -129
  217. package/apps/control-plane/test/session-management.spec.ts +136 -74
  218. package/apps/control-plane/test/spec-ingestion.spec.ts +23 -21
  219. package/apps/control-plane/test/spec-input-resolver.spec.ts +11 -10
  220. package/apps/control-plane/test/supervisor-collaborators.spec.ts +168 -121
  221. package/apps/control-plane/test/supervisor.calltool.spec.ts +21 -18
  222. package/apps/control-plane/test/supervisor.spec.ts +67 -43
  223. package/apps/control-plane/test/supervisor.unit.spec.ts +195 -126
  224. package/apps/control-plane/test/token-auth-verifier.spec.ts +29 -14
  225. package/apps/control-plane/test/tool-registry-loader.spec.ts +51 -27
  226. package/apps/control-plane/test/tool-runtime.spec.ts +63 -46
  227. package/apps/control-plane/test/worker-decision-loop.spec.ts +143 -122
  228. package/apps/control-plane/test/workspace-hooks.spec.ts +61 -23
  229. package/apps/control-plane/tsconfig.build.json +2 -7
  230. package/apps/control-plane/tsconfig.json +1 -5
  231. package/apps/control-plane/vitest.config.ts +7 -7
  232. package/dist/apps/control-plane/application/adapters/adapter-registry.js +12 -5
  233. package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -1
  234. package/dist/apps/control-plane/application/multi-project-loader.js +26 -9
  235. package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -1
  236. package/dist/apps/control-plane/application/services/activity-monitor-service.js +7 -7
  237. package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
  238. package/dist/apps/control-plane/application/services/collision-queue-service.js +7 -7
  239. package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
  240. package/dist/apps/control-plane/application/services/cost-tracking-service.js +6 -8
  241. package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
  242. package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -1
  243. package/dist/apps/control-plane/application/services/feature-deletion-service.js +37 -29
  244. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
  245. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +10 -10
  246. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
  247. package/dist/apps/control-plane/application/services/feature-state-service.js +11 -11
  248. package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
  249. package/dist/apps/control-plane/application/services/gate-interpolation-service.js +3 -1
  250. package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -1
  251. package/dist/apps/control-plane/application/services/gate-service.js +26 -26
  252. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
  253. package/dist/apps/control-plane/application/services/instance-isolation-service.js +1 -1
  254. package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -1
  255. package/dist/apps/control-plane/application/services/issue-tracker-service.js +25 -15
  256. package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
  257. package/dist/apps/control-plane/application/services/lock-service.js +32 -32
  258. package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
  259. package/dist/apps/control-plane/application/services/merge-service.js +41 -27
  260. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
  261. package/dist/apps/control-plane/application/services/notifier-service.js +29 -15
  262. package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
  263. package/dist/apps/control-plane/application/services/patch-service.js +21 -19
  264. package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
  265. package/dist/apps/control-plane/application/services/performance-analytics-service.js +4 -4
  266. package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
  267. package/dist/apps/control-plane/application/services/plan-service.js +33 -33
  268. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
  269. package/dist/apps/control-plane/application/services/policy-loader-service.js.map +1 -1
  270. package/dist/apps/control-plane/application/services/pr-monitor-service.js +23 -11
  271. package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
  272. package/dist/apps/control-plane/application/services/qa-index-service.js +11 -11
  273. package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
  274. package/dist/apps/control-plane/application/services/reactions-service.js +13 -9
  275. package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
  276. package/dist/apps/control-plane/application/services/reporting-service.js +11 -9
  277. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
  278. package/dist/apps/control-plane/application/services/run-lease-service.js +34 -33
  279. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
  280. package/dist/apps/control-plane/application/tools/tool-metadata.js +2 -2
  281. package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
  282. package/dist/apps/control-plane/cli/attach-command-handler.js +9 -9
  283. package/dist/apps/control-plane/cli/cleanup-command-handler.js +11 -9
  284. package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -1
  285. package/dist/apps/control-plane/cli/cli-argument-parser.js +4 -3
  286. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
  287. package/dist/apps/control-plane/cli/dashboard-command-handler.js +23 -7
  288. package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
  289. package/dist/apps/control-plane/cli/delete-command-handler.js +7 -7
  290. package/dist/apps/control-plane/cli/help-command-handler.js +58 -30
  291. package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
  292. package/dist/apps/control-plane/cli/init-command-handler.js +44 -33
  293. package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
  294. package/dist/apps/control-plane/cli/io.js +2 -2
  295. package/dist/apps/control-plane/cli/io.js.map +1 -1
  296. package/dist/apps/control-plane/cli/resume-command-handler.js +9 -9
  297. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
  298. package/dist/apps/control-plane/cli/retry-command-handler.js +12 -11
  299. package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
  300. package/dist/apps/control-plane/cli/run-command-handler.js +12 -8
  301. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
  302. package/dist/apps/control-plane/cli/send-command-handler.js +6 -6
  303. package/dist/apps/control-plane/cli/spec-ingestion-service.js +10 -8
  304. package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
  305. package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -1
  306. package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
  307. package/dist/apps/control-plane/cli/status-command-handler.js +8 -8
  308. package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
  309. package/dist/apps/control-plane/cli/tooling.js +1 -1
  310. package/dist/apps/control-plane/core/collisions.js +11 -8
  311. package/dist/apps/control-plane/core/collisions.js.map +1 -1
  312. package/dist/apps/control-plane/core/constants.js +13 -7
  313. package/dist/apps/control-plane/core/constants.js.map +1 -1
  314. package/dist/apps/control-plane/core/error-codes.js +1 -1
  315. package/dist/apps/control-plane/core/fs.js.map +1 -1
  316. package/dist/apps/control-plane/core/gates.d.ts +2 -2
  317. package/dist/apps/control-plane/core/gates.js +26 -19
  318. package/dist/apps/control-plane/core/gates.js.map +1 -1
  319. package/dist/apps/control-plane/core/git.js +3 -3
  320. package/dist/apps/control-plane/core/git.js.map +1 -1
  321. package/dist/apps/control-plane/core/kernel.d.ts +1 -0
  322. package/dist/apps/control-plane/core/kernel.js +134 -81
  323. package/dist/apps/control-plane/core/kernel.js.map +1 -1
  324. package/dist/apps/control-plane/core/patch.js +7 -3
  325. package/dist/apps/control-plane/core/patch.js.map +1 -1
  326. package/dist/apps/control-plane/core/path-layout.d.ts +1 -0
  327. package/dist/apps/control-plane/core/path-layout.js +4 -1
  328. package/dist/apps/control-plane/core/path-layout.js.map +1 -1
  329. package/dist/apps/control-plane/core/path-rules.js +3 -1
  330. package/dist/apps/control-plane/core/path-rules.js.map +1 -1
  331. package/dist/apps/control-plane/core/qa-index.js +5 -5
  332. package/dist/apps/control-plane/core/qa-index.js.map +1 -1
  333. package/dist/apps/control-plane/core/response.js +3 -3
  334. package/dist/apps/control-plane/core/response.js.map +1 -1
  335. package/dist/apps/control-plane/core/schemas.js +10 -6
  336. package/dist/apps/control-plane/core/schemas.js.map +1 -1
  337. package/dist/apps/control-plane/core/workspace-hooks.js +3 -3
  338. package/dist/apps/control-plane/index.d.ts +1 -1
  339. package/dist/apps/control-plane/index.js +1 -1
  340. package/dist/apps/control-plane/index.js.map +1 -1
  341. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +31 -20
  342. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
  343. package/dist/apps/control-plane/mcp/kernel-tool-executor.js +1 -1
  344. package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
  345. package/dist/apps/control-plane/mcp/mcp-server-adapter.js +6 -7
  346. package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -1
  347. package/dist/apps/control-plane/mcp/operation-ledger.js +5 -5
  348. package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -1
  349. package/dist/apps/control-plane/mcp/protocol-contract.js +2 -2
  350. package/dist/apps/control-plane/mcp/runtime-factory.js +2 -2
  351. package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -1
  352. package/dist/apps/control-plane/mcp/token-auth-verifier.js +1 -1
  353. package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -1
  354. package/dist/apps/control-plane/mcp/token-claims-validator.js +5 -5
  355. package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -1
  356. package/dist/apps/control-plane/mcp/tool-authorizer.js +1 -3
  357. package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -1
  358. package/dist/apps/control-plane/mcp/tool-client.js +2 -2
  359. package/dist/apps/control-plane/mcp/tool-client.js.map +1 -1
  360. package/dist/apps/control-plane/mcp/tool-contract-validator.js +3 -3
  361. package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -1
  362. package/dist/apps/control-plane/mcp/tool-registry-loader.js +1 -1
  363. package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -1
  364. package/dist/apps/control-plane/mcp/tool-runtime.js +17 -17
  365. package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
  366. package/dist/apps/control-plane/mcp/tools-markdown-generator.js +6 -1
  367. package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -1
  368. package/dist/apps/control-plane/providers/providers.d.ts +1 -1
  369. package/dist/apps/control-plane/providers/providers.js +31 -34
  370. package/dist/apps/control-plane/providers/providers.js.map +1 -1
  371. package/dist/apps/control-plane/supervisor/build-wave-executor.js +12 -12
  372. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
  373. package/dist/apps/control-plane/supervisor/planning-wave-executor.js +19 -16
  374. package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
  375. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +1 -1
  376. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +13 -13
  377. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
  378. package/dist/apps/control-plane/supervisor/run-coordinator.js +37 -20
  379. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
  380. package/dist/apps/control-plane/supervisor/runtime.js +25 -21
  381. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
  382. package/dist/apps/control-plane/supervisor/session-orchestrator.js +29 -23
  383. package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
  384. package/dist/apps/control-plane/supervisor/types.d.ts +3 -3
  385. package/dist/apps/control-plane/supervisor/types.js.map +1 -1
  386. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +14 -16
  387. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
  388. package/eslint.config.mjs +20 -20
  389. package/example-configurations/README.md +1 -1
  390. package/example-configurations/java/agents.yaml +3 -3
  391. package/example-configurations/java/policy.yaml +1 -1
  392. package/example-configurations/node/agents.yaml +3 -3
  393. package/example-configurations/node/policy.yaml +1 -1
  394. package/package.json +10 -5
  395. package/packages/web-dashboard/next.config.js +2 -2
  396. package/packages/web-dashboard/src/app/api/actions/route.ts +25 -9
  397. package/packages/web-dashboard/src/app/api/events/route.ts +20 -6
  398. package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +88 -37
  399. package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +8 -5
  400. package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +27 -9
  401. package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -2
  402. package/packages/web-dashboard/src/app/api/projects/route.ts +5 -5
  403. package/packages/web-dashboard/src/app/globals.css +10 -2
  404. package/packages/web-dashboard/src/app/page.tsx +100 -37
  405. package/packages/web-dashboard/src/lib/aop-client.ts +68 -37
  406. package/packages/web-dashboard/src/lib/multi-project-config.ts +28 -7
  407. package/packages/web-dashboard/src/lib/orchestrator-tools.ts +59 -36
  408. package/packages/web-dashboard/tsconfig.json +3 -11
  409. package/scripts/nx-safe.mjs +10 -10
  410. package/spec-files/completed/agentic_orchestrator_cli_delete_command_spec.md +5 -0
  411. package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +187 -90
  412. package/spec-files/completed/agentic_orchestrator_init_policy_ux_simplification_spec.md +49 -16
  413. package/spec-files/completed/agentic_orchestrator_mcp_formalization_spec.md +24 -1
  414. package/spec-files/completed/agentic_orchestrator_single_global_orchestrator_spec.md +9 -0
  415. package/spec-files/completed/agentic_orchestrator_spec.md +171 -75
  416. package/spec-files/completed/agentic_orchestrator_validator_hardening_spec.md +25 -17
  417. package/spec-files/outstanding/agentic_orchestrator_artifact_database_publishing_spec.md +40 -5
  418. package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +23 -12
  419. package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +16 -4
  420. package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +42 -2
  421. package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +209 -130
  422. package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +56 -3
  423. package/spec-files/outstanding/agentic_orchestrator_productization_commercial_spec.md +77 -10
  424. package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +29 -14
  425. package/spec-files/progress.md +186 -175
  426. package/tsconfig.json +2 -8
@@ -13,18 +13,23 @@ describe('RunCoordinator iteration behavior', () => {
13
13
  run_id: 'run:test',
14
14
  owner_instance_id: 'owner:test',
15
15
  orchestrator_session_id: 'orch:test',
16
- feature_sessions: {}
17
- }))
18
- ,
16
+ feature_sessions: {},
17
+ })),
19
18
  updateState: vi.fn(async () => ({})),
20
- checkBudget: vi.fn(async () => ({ over_budget: false, alert_threshold_reached: false, current_cost_usd: 0, limit_usd: -1, alert_threshold: 0.8 }))
19
+ checkBudget: vi.fn(async () => ({
20
+ over_budget: false,
21
+ alert_threshold_reached: false,
22
+ current_cost_usd: 0,
23
+ limit_usd: -1,
24
+ alert_threshold: 0.8,
25
+ })),
21
26
  };
22
27
 
23
28
  const provider = {
24
29
  selection: {
25
30
  provider: 'custom',
26
- model: 'model-test'
27
- }
31
+ model: 'model-test',
32
+ },
28
33
  };
29
34
 
30
35
  const toolCaller = {
@@ -33,7 +38,7 @@ describe('RunCoordinator iteration behavior', () => {
33
38
  return { ok: true, data: { features: [] } };
34
39
  }
35
40
  return { ok: true, data: {} };
36
- })
41
+ }),
37
42
  };
38
43
 
39
44
  const state = {
@@ -42,7 +47,7 @@ describe('RunCoordinator iteration behavior', () => {
42
47
  orchestratorSessionId: 'orch:test',
43
48
  sessionsByFeature: new Map<string, { planner: string; builder: string; qa: string }>(),
44
49
  queue: [] as Array<{ feature_id: string }>,
45
- runMetadata: {}
50
+ runMetadata: {},
46
51
  };
47
52
 
48
53
  const sessionOrchestrator = {
@@ -50,24 +55,24 @@ describe('RunCoordinator iteration behavior', () => {
50
55
  cleanupOrphanWorkerSessions: vi.fn(async () => undefined),
51
56
  initializeFeatureCluster: vi.fn(async () => undefined),
52
57
  reconcileQueuedFeatures: vi.fn(async () => undefined),
53
- enforceActiveFeatureInvariant: vi.fn(async () => undefined)
58
+ enforceActiveFeatureInvariant: vi.fn(async () => undefined),
54
59
  };
55
60
 
56
61
  const planningWaveExecutor = {
57
62
  run: vi.fn(async () => undefined),
58
- runPostQaReconciliation: vi.fn(async () => undefined)
63
+ runPostQaReconciliation: vi.fn(async () => undefined),
59
64
  };
60
65
 
61
66
  const buildWaveExecutor = {
62
- run: vi.fn(async () => undefined)
67
+ run: vi.fn(async () => undefined),
63
68
  };
64
69
 
65
70
  const qaWaveExecutor = {
66
- run: vi.fn(async () => undefined)
71
+ run: vi.fn(async () => undefined),
67
72
  };
68
73
 
69
74
  const leaseHeartbeatService = {
70
- renew: vi.fn(async () => undefined)
75
+ renew: vi.fn(async () => undefined),
71
76
  };
72
77
 
73
78
  const coordinator = new RunCoordinator({
@@ -84,10 +89,13 @@ describe('RunCoordinator iteration behavior', () => {
84
89
  maxParallelGateRuns: 2,
85
90
  maxIterationsPerPhase: 3,
86
91
  takeoverStaleRun: false,
87
- providerConfigRefHash: () => 'hash'
92
+ providerConfigRefHash: () => 'hash',
88
93
  });
89
94
 
90
- const result = await coordinator.start([{ feature_id: 'feature_b' }, { feature_id: 'feature_a' }]);
95
+ const result = await coordinator.start([
96
+ { feature_id: 'feature_b' },
97
+ { feature_id: 'feature_a' },
98
+ ]);
91
99
 
92
100
  expect(result.queue_depth).toBe(0);
93
101
  expect(leaseHeartbeatService.renew).toHaveBeenCalledTimes(3);
@@ -96,9 +104,21 @@ describe('RunCoordinator iteration behavior', () => {
96
104
  expect(qaWaveExecutor.run).toHaveBeenCalledTimes(3);
97
105
  expect(planningWaveExecutor.runPostQaReconciliation).toHaveBeenCalledTimes(3);
98
106
  expect(planningWaveExecutor.run).toHaveBeenNthCalledWith(1, ['feature_a', 'feature_b']);
99
- expect(planningWaveExecutor.runPostQaReconciliation).toHaveBeenNthCalledWith(1, ['feature_a', 'feature_b'], 1);
100
- expect(planningWaveExecutor.runPostQaReconciliation).toHaveBeenNthCalledWith(2, ['feature_a', 'feature_b'], 2);
101
- expect(planningWaveExecutor.runPostQaReconciliation).toHaveBeenNthCalledWith(3, ['feature_a', 'feature_b'], 3);
107
+ expect(planningWaveExecutor.runPostQaReconciliation).toHaveBeenNthCalledWith(
108
+ 1,
109
+ ['feature_a', 'feature_b'],
110
+ 1,
111
+ );
112
+ expect(planningWaveExecutor.runPostQaReconciliation).toHaveBeenNthCalledWith(
113
+ 2,
114
+ ['feature_a', 'feature_b'],
115
+ 2,
116
+ );
117
+ expect(planningWaveExecutor.runPostQaReconciliation).toHaveBeenNthCalledWith(
118
+ 3,
119
+ ['feature_a', 'feature_b'],
120
+ 3,
121
+ );
102
122
  });
103
123
 
104
124
  it('GIVEN_terminal_active_feature_WHEN_slots_free_up_THEN_promotes_next_queued_feature_deterministically', async () => {
@@ -111,23 +131,28 @@ describe('RunCoordinator iteration behavior', () => {
111
131
  run_id: 'run:test',
112
132
  owner_instance_id: 'owner:test',
113
133
  orchestrator_session_id: 'orch:test',
114
- feature_sessions: {}
115
- }))
116
- ,
134
+ feature_sessions: {},
135
+ })),
117
136
  updateState: vi.fn(async () => ({})),
118
- checkBudget: vi.fn(async () => ({ over_budget: false, alert_threshold_reached: false, current_cost_usd: 0, limit_usd: -1, alert_threshold: 0.8 }))
137
+ checkBudget: vi.fn(async () => ({
138
+ over_budget: false,
139
+ alert_threshold_reached: false,
140
+ current_cost_usd: 0,
141
+ limit_usd: -1,
142
+ alert_threshold: 0.8,
143
+ })),
119
144
  };
120
145
 
121
146
  const provider = {
122
147
  selection: {
123
148
  provider: 'custom',
124
- model: 'model-test'
125
- }
149
+ model: 'model-test',
150
+ },
126
151
  };
127
152
 
128
153
  const statusReads = new Map<string, string[]>([
129
154
  ['feature_a', ['planning', 'merged']],
130
- ['feature_b', ['planning']]
155
+ ['feature_b', ['planning']],
131
156
  ]);
132
157
 
133
158
  const toolCaller = {
@@ -141,16 +166,16 @@ describe('RunCoordinator iteration behavior', () => {
141
166
  ok: true,
142
167
  data: {
143
168
  front_matter: {
144
- status
145
- }
146
- }
169
+ status,
170
+ },
171
+ },
147
172
  };
148
173
  }
149
174
  if (toolName === TOOLS.REPORT_DASHBOARD) {
150
175
  return { ok: true, data: { features: [] } };
151
176
  }
152
177
  return { ok: true, data: {} };
153
- })
178
+ }),
154
179
  };
155
180
 
156
181
  const state = {
@@ -159,7 +184,7 @@ describe('RunCoordinator iteration behavior', () => {
159
184
  orchestratorSessionId: 'orch:test',
160
185
  sessionsByFeature: new Map<string, { planner: string; builder: string; qa: string }>(),
161
186
  queue: [] as Array<{ feature_id: string }>,
162
- runMetadata: {}
187
+ runMetadata: {},
163
188
  };
164
189
 
165
190
  const sessionOrchestrator = {
@@ -169,31 +194,31 @@ describe('RunCoordinator iteration behavior', () => {
169
194
  state.sessionsByFeature.set(featureId, {
170
195
  planner: `${featureId}:planner`,
171
196
  builder: `${featureId}:builder`,
172
- qa: `${featureId}:qa`
197
+ qa: `${featureId}:qa`,
173
198
  });
174
199
  }),
175
200
  closeFeatureCluster: vi.fn(async (featureId: string) => {
176
201
  state.sessionsByFeature.delete(featureId);
177
202
  }),
178
203
  reconcileQueuedFeatures: vi.fn(async () => undefined),
179
- enforceActiveFeatureInvariant: vi.fn(async () => undefined)
204
+ enforceActiveFeatureInvariant: vi.fn(async () => undefined),
180
205
  };
181
206
 
182
207
  const planningWaveExecutor = {
183
208
  run: vi.fn(async () => undefined),
184
- runPostQaReconciliation: vi.fn(async () => undefined)
209
+ runPostQaReconciliation: vi.fn(async () => undefined),
185
210
  };
186
211
 
187
212
  const buildWaveExecutor = {
188
- run: vi.fn(async () => undefined)
213
+ run: vi.fn(async () => undefined),
189
214
  };
190
215
 
191
216
  const qaWaveExecutor = {
192
- run: vi.fn(async () => undefined)
217
+ run: vi.fn(async () => undefined),
193
218
  };
194
219
 
195
220
  const leaseHeartbeatService = {
196
- renew: vi.fn(async () => undefined)
221
+ renew: vi.fn(async () => undefined),
197
222
  };
198
223
 
199
224
  const coordinator = new RunCoordinator({
@@ -210,10 +235,13 @@ describe('RunCoordinator iteration behavior', () => {
210
235
  maxParallelGateRuns: 2,
211
236
  maxIterationsPerPhase: 2,
212
237
  takeoverStaleRun: false,
213
- providerConfigRefHash: () => 'hash'
238
+ providerConfigRefHash: () => 'hash',
214
239
  });
215
240
 
216
- const result = await coordinator.start([{ feature_id: 'feature_a' }, { feature_id: 'feature_b' }]);
241
+ const result = await coordinator.start([
242
+ { feature_id: 'feature_a' },
243
+ { feature_id: 'feature_b' },
244
+ ]);
217
245
 
218
246
  expect(result.queue_depth).toBe(0);
219
247
  expect(sessionOrchestrator.initializeFeatureCluster).toHaveBeenNthCalledWith(1, 'feature_a');
@@ -233,18 +261,23 @@ describe('RunCoordinator iteration behavior', () => {
233
261
  run_id: 'run:test',
234
262
  owner_instance_id: 'owner:test',
235
263
  orchestrator_session_id: 'orch:test',
236
- feature_sessions: {}
237
- }))
238
- ,
264
+ feature_sessions: {},
265
+ })),
239
266
  updateState: vi.fn(async () => ({})),
240
- checkBudget: vi.fn(async () => ({ over_budget: false, alert_threshold_reached: false, current_cost_usd: 0, limit_usd: -1, alert_threshold: 0.8 }))
267
+ checkBudget: vi.fn(async () => ({
268
+ over_budget: false,
269
+ alert_threshold_reached: false,
270
+ current_cost_usd: 0,
271
+ limit_usd: -1,
272
+ alert_threshold: 0.8,
273
+ })),
241
274
  };
242
275
 
243
276
  const provider = {
244
277
  selection: {
245
278
  provider: 'custom',
246
- model: 'model-test'
247
- }
279
+ model: 'model-test',
280
+ },
248
281
  };
249
282
 
250
283
  const toolCaller = {
@@ -254,16 +287,16 @@ describe('RunCoordinator iteration behavior', () => {
254
287
  ok: true,
255
288
  data: {
256
289
  front_matter: {
257
- status: 'planning'
258
- }
259
- }
290
+ status: 'planning',
291
+ },
292
+ },
260
293
  };
261
294
  }
262
295
  if (toolName === TOOLS.REPORT_DASHBOARD) {
263
296
  return { ok: true, data: { features: [] } };
264
297
  }
265
298
  return { ok: true, data: {} };
266
- })
299
+ }),
267
300
  };
268
301
 
269
302
  const state = {
@@ -272,7 +305,7 @@ describe('RunCoordinator iteration behavior', () => {
272
305
  orchestratorSessionId: 'orch:test',
273
306
  sessionsByFeature: new Map<string, { planner: string; builder: string; qa: string }>(),
274
307
  queue: [] as Array<{ feature_id: string }>,
275
- runMetadata: {}
308
+ runMetadata: {},
276
309
  };
277
310
 
278
311
  const sessionOrchestrator = {
@@ -282,29 +315,29 @@ describe('RunCoordinator iteration behavior', () => {
282
315
  state.sessionsByFeature.set(featureId, {
283
316
  planner: `${featureId}:planner`,
284
317
  builder: `${featureId}:builder`,
285
- qa: `${featureId}:qa`
318
+ qa: `${featureId}:qa`,
286
319
  });
287
320
  }),
288
321
  closeFeatureCluster: vi.fn(async (_featureId: string) => undefined),
289
322
  reconcileQueuedFeatures: vi.fn(async () => undefined),
290
- enforceActiveFeatureInvariant: vi.fn(async () => undefined)
323
+ enforceActiveFeatureInvariant: vi.fn(async () => undefined),
291
324
  };
292
325
 
293
326
  const planningWaveExecutor = {
294
327
  run: vi.fn(async () => undefined),
295
- runPostQaReconciliation: vi.fn(async () => undefined)
328
+ runPostQaReconciliation: vi.fn(async () => undefined),
296
329
  };
297
330
 
298
331
  const buildWaveExecutor = {
299
- run: vi.fn(async () => undefined)
332
+ run: vi.fn(async () => undefined),
300
333
  };
301
334
 
302
335
  const qaWaveExecutor = {
303
- run: vi.fn(async () => undefined)
336
+ run: vi.fn(async () => undefined),
304
337
  };
305
338
 
306
339
  const leaseHeartbeatService = {
307
- renew: vi.fn(async () => undefined)
340
+ renew: vi.fn(async () => undefined),
308
341
  };
309
342
 
310
343
  const workerDecisionRunner = {
@@ -314,8 +347,8 @@ describe('RunCoordinator iteration behavior', () => {
314
347
  noteLogged: false,
315
348
  requestHandled: true,
316
349
  priorityOrder: ['feature_b'],
317
- toolResults: []
318
- }))
350
+ toolResults: [],
351
+ })),
319
352
  };
320
353
 
321
354
  const coordinator = new RunCoordinator({
@@ -333,7 +366,7 @@ describe('RunCoordinator iteration behavior', () => {
333
366
  maxIterationsPerPhase: 1,
334
367
  takeoverStaleRun: false,
335
368
  providerConfigRefHash: () => 'hash',
336
- workerDecisionRunner: workerDecisionRunner as never
369
+ workerDecisionRunner: workerDecisionRunner as never,
337
370
  });
338
371
 
339
372
  await coordinator.start([{ feature_id: 'feature_a' }, { feature_id: 'feature_b' }]);
@@ -343,27 +376,31 @@ describe('RunCoordinator iteration behavior', () => {
343
376
  });
344
377
 
345
378
  describe('RunCoordinator notification and budget branches', () => {
346
- beforeEach(() => { vi.clearAllMocks(); });
347
-
348
- function makeCoordinatorDeps(opts: {
349
- checkBudgetImpl?: () => Promise<{
350
- over_budget: boolean;
351
- alert_threshold_reached: boolean;
352
- current_cost_usd: number;
353
- limit_usd: number;
354
- alert_threshold: number;
355
- }>;
356
- toolCallerImpl?: (role: string, toolName: string) => Promise<{ ok: boolean; data: unknown }>;
357
- notifier?: { notify: ReturnType<typeof vi.fn> };
358
- prMonitor?: { checkAndUpdate: ReturnType<typeof vi.fn> };
359
- issueTracker?: {
360
- getIssue: ReturnType<typeof vi.fn>;
361
- addComment: ReturnType<typeof vi.fn>;
362
- updateIssueStatus: ReturnType<typeof vi.fn>;
363
- };
364
- maxIterationsPerPhase?: number;
365
- maxActiveFeatures?: number;
366
- } = {}) {
379
+ beforeEach(() => {
380
+ vi.clearAllMocks();
381
+ });
382
+
383
+ function makeCoordinatorDeps(
384
+ opts: {
385
+ checkBudgetImpl?: () => Promise<{
386
+ over_budget: boolean;
387
+ alert_threshold_reached: boolean;
388
+ current_cost_usd: number;
389
+ limit_usd: number;
390
+ alert_threshold: number;
391
+ }>;
392
+ toolCallerImpl?: (role: string, toolName: string) => Promise<{ ok: boolean; data: unknown }>;
393
+ notifier?: { notify: ReturnType<typeof vi.fn> };
394
+ prMonitor?: { checkAndUpdate: ReturnType<typeof vi.fn> };
395
+ issueTracker?: {
396
+ getIssue: ReturnType<typeof vi.fn>;
397
+ addComment: ReturnType<typeof vi.fn>;
398
+ updateIssueStatus: ReturnType<typeof vi.fn>;
399
+ };
400
+ maxIterationsPerPhase?: number;
401
+ maxActiveFeatures?: number;
402
+ } = {},
403
+ ) {
367
404
  const kernel = {
368
405
  ensureLoaded: vi.fn(async () => undefined),
369
406
  recoverFromState: vi.fn(async () => ({ data: { recovered: true } })),
@@ -373,7 +410,7 @@ describe('RunCoordinator notification and budget branches', () => {
373
410
  run_id: 'run:test',
374
411
  owner_instance_id: 'owner:test',
375
412
  orchestrator_session_id: 'orch:test',
376
- feature_sessions: {}
413
+ feature_sessions: {},
377
414
  })),
378
415
  updateState: vi.fn(async () => ({})),
379
416
  checkBudget: opts.checkBudgetImpl
@@ -383,8 +420,8 @@ describe('RunCoordinator notification and budget branches', () => {
383
420
  alert_threshold_reached: false,
384
421
  current_cost_usd: 0,
385
422
  limit_usd: -1,
386
- alert_threshold: 0.8
387
- }))
423
+ alert_threshold: 0.8,
424
+ })),
388
425
  };
389
426
 
390
427
  const state = {
@@ -393,7 +430,7 @@ describe('RunCoordinator notification and budget branches', () => {
393
430
  orchestratorSessionId: 'orch:test',
394
431
  sessionsByFeature: new Map<string, { planner: string; builder: string; qa: string }>(),
395
432
  queue: [] as Array<{ feature_id: string }>,
396
- runMetadata: {}
433
+ runMetadata: {},
397
434
  };
398
435
 
399
436
  const defaultToolCallerImpl = async (_role: string, toolName: string) => {
@@ -404,9 +441,7 @@ describe('RunCoordinator notification and budget branches', () => {
404
441
  };
405
442
 
406
443
  const toolCaller = {
407
- callTool: opts.toolCallerImpl
408
- ? vi.fn(opts.toolCallerImpl)
409
- : vi.fn(defaultToolCallerImpl)
444
+ callTool: opts.toolCallerImpl ? vi.fn(opts.toolCallerImpl) : vi.fn(defaultToolCallerImpl),
410
445
  };
411
446
 
412
447
  const sessionOrchestrator = {
@@ -415,12 +450,12 @@ describe('RunCoordinator notification and budget branches', () => {
415
450
  initializeFeatureCluster: vi.fn(async () => undefined),
416
451
  closeFeatureCluster: vi.fn(async () => undefined),
417
452
  reconcileQueuedFeatures: vi.fn(async () => undefined),
418
- enforceActiveFeatureInvariant: vi.fn(async () => undefined)
453
+ enforceActiveFeatureInvariant: vi.fn(async () => undefined),
419
454
  };
420
455
 
421
456
  const planningWaveExecutor = {
422
457
  run: vi.fn(async () => undefined),
423
- runPostQaReconciliation: vi.fn(async () => undefined)
458
+ runPostQaReconciliation: vi.fn(async () => undefined),
424
459
  };
425
460
  const buildWaveExecutor = { run: vi.fn(async () => undefined) };
426
461
  const qaWaveExecutor = { run: vi.fn(async () => undefined) };
@@ -444,7 +479,7 @@ describe('RunCoordinator notification and budget branches', () => {
444
479
  providerConfigRefHash: () => 'hash',
445
480
  notifier: opts.notifier as never,
446
481
  prMonitor: opts.prMonitor as never,
447
- issueTracker: opts.issueTracker as never
482
+ issueTracker: opts.issueTracker as never,
448
483
  });
449
484
 
450
485
  return { coordinator, kernel, toolCaller, sessionOrchestrator };
@@ -457,8 +492,8 @@ describe('RunCoordinator notification and budget branches', () => {
457
492
  alert_threshold_reached: false,
458
493
  current_cost_usd: 5.5,
459
494
  limit_usd: 5.0,
460
- alert_threshold: 0.8
461
- })
495
+ alert_threshold: 0.8,
496
+ }),
462
497
  });
463
498
 
464
499
  await coordinator.start([{ feature_id: 'feature_x' }]);
@@ -466,7 +501,9 @@ describe('RunCoordinator notification and budget branches', () => {
466
501
  expect(kernel.updateState).toHaveBeenCalledWith('feature_x', null, expect.any(Function));
467
502
  const updateStateCall = kernel.updateState.mock.calls[0] as unknown[] | undefined;
468
503
  expect(updateStateCall).toBeDefined();
469
- const callbackArg = updateStateCall?.[2] as ((fm: object) => Promise<{ frontMatter: { status: string } }>) | undefined;
504
+ const callbackArg = updateStateCall?.[2] as
505
+ | ((fm: object) => Promise<{ frontMatter: { status: string } }>)
506
+ | undefined;
470
507
  expect(callbackArg).toBeDefined();
471
508
  if (callbackArg == null) {
472
509
  throw new Error('missing updateState callback');
@@ -484,14 +521,17 @@ describe('RunCoordinator notification and budget branches', () => {
484
521
  alert_threshold_reached: false,
485
522
  current_cost_usd: 5.5,
486
523
  limit_usd: 5.0,
487
- alert_threshold: 0.8
524
+ alert_threshold: 0.8,
488
525
  }),
489
- notifier
526
+ notifier,
490
527
  });
491
528
 
492
529
  await coordinator.start([{ feature_id: 'feature_x' }]);
493
530
 
494
- expect(notifier.notify).toHaveBeenCalledWith('budget_exceeded', expect.objectContaining({ feature_id: 'feature_x' }));
531
+ expect(notifier.notify).toHaveBeenCalledWith(
532
+ 'budget_exceeded',
533
+ expect.objectContaining({ feature_id: 'feature_x' }),
534
+ );
495
535
  });
496
536
 
497
537
  it('GIVEN_alert_threshold_reached_WHEN_pauseOverBudgetFeatures_runs_THEN_notifies_budget_alert', async () => {
@@ -502,14 +542,17 @@ describe('RunCoordinator notification and budget branches', () => {
502
542
  alert_threshold_reached: true,
503
543
  current_cost_usd: 4.5,
504
544
  limit_usd: 5.0,
505
- alert_threshold: 0.9
545
+ alert_threshold: 0.9,
506
546
  }),
507
- notifier
547
+ notifier,
508
548
  });
509
549
 
510
550
  await coordinator.start([{ feature_id: 'feature_x' }]);
511
551
 
512
- expect(notifier.notify).toHaveBeenCalledWith('budget_alert', expect.objectContaining({ feature_id: 'feature_x' }));
552
+ expect(notifier.notify).toHaveBeenCalledWith(
553
+ 'budget_alert',
554
+ expect.objectContaining({ feature_id: 'feature_x' }),
555
+ );
513
556
  });
514
557
 
515
558
  it('GIVEN_feature_transitions_to_BLOCKED_from_PLANNING_WHEN_notifyStatusTransitions_THEN_notifies_collision_detected', async () => {
@@ -529,12 +572,15 @@ describe('RunCoordinator notification and budget branches', () => {
529
572
  return { ok: true, data: {} };
530
573
  },
531
574
  notifier,
532
- maxIterationsPerPhase: 2
575
+ maxIterationsPerPhase: 2,
533
576
  });
534
577
 
535
578
  await coordinator.start([{ feature_id: 'feature_x' }]);
536
579
 
537
- expect(notifier.notify).toHaveBeenCalledWith('collision_detected', expect.objectContaining({ feature_id: 'feature_x' }));
580
+ expect(notifier.notify).toHaveBeenCalledWith(
581
+ 'collision_detected',
582
+ expect.objectContaining({ feature_id: 'feature_x' }),
583
+ );
538
584
  });
539
585
 
540
586
  it('GIVEN_feature_transitions_to_BLOCKED_from_non_PLANNING_WHEN_notifyStatusTransitions_THEN_notifies_gate_failed', async () => {
@@ -552,12 +598,15 @@ describe('RunCoordinator notification and budget branches', () => {
552
598
  }
553
599
  return { ok: true, data: {} };
554
600
  },
555
- notifier
601
+ notifier,
556
602
  });
557
603
 
558
604
  await coordinator.start([{ feature_id: 'feature_x' }]);
559
605
 
560
- expect(notifier.notify).toHaveBeenCalledWith('gate_failed', expect.objectContaining({ feature_id: 'feature_x' }));
606
+ expect(notifier.notify).toHaveBeenCalledWith(
607
+ 'gate_failed',
608
+ expect.objectContaining({ feature_id: 'feature_x' }),
609
+ );
561
610
  });
562
611
 
563
612
  it('GIVEN_feature_transitions_to_READY_TO_MERGE_WHEN_notifyStatusTransitions_THEN_notifies_and_calls_prMonitor', async () => {
@@ -577,12 +626,15 @@ describe('RunCoordinator notification and budget branches', () => {
577
626
  return { ok: true, data: {} };
578
627
  },
579
628
  notifier,
580
- prMonitor
629
+ prMonitor,
581
630
  });
582
631
 
583
632
  await coordinator.start([{ feature_id: 'feature_x' }]);
584
633
 
585
- expect(notifier.notify).toHaveBeenCalledWith('ready_to_merge', expect.objectContaining({ feature_id: 'feature_x' }));
634
+ expect(notifier.notify).toHaveBeenCalledWith(
635
+ 'ready_to_merge',
636
+ expect.objectContaining({ feature_id: 'feature_x' }),
637
+ );
586
638
  expect(prMonitor.checkAndUpdate).toHaveBeenCalledWith('feature_x', 'feature_x');
587
639
  });
588
640
 
@@ -596,9 +648,9 @@ describe('RunCoordinator notification and budget branches', () => {
596
648
  data: {
597
649
  front_matter: {
598
650
  status: STATUS.QA,
599
- pr: { number: 77, url: 'https://example.com/pr/77' }
600
- }
601
- }
651
+ pr: { number: 77, url: 'https://example.com/pr/77' },
652
+ },
653
+ },
602
654
  };
603
655
  }
604
656
  if (toolName === TOOLS.REPORT_DASHBOARD) {
@@ -607,7 +659,7 @@ describe('RunCoordinator notification and budget branches', () => {
607
659
  return { ok: true, data: {} };
608
660
  },
609
661
  prMonitor,
610
- maxIterationsPerPhase: 2
662
+ maxIterationsPerPhase: 2,
611
663
  });
612
664
 
613
665
  await coordinator.start([{ feature_id: 'feature_x' }]);
@@ -630,37 +682,36 @@ describe('RunCoordinator notification and budget branches', () => {
630
682
  }
631
683
  return { ok: true, data: {} };
632
684
  },
633
- notifier
685
+ notifier,
634
686
  });
635
687
 
636
688
  await coordinator.start([{ feature_id: 'feature_x' }]);
637
689
 
638
- expect(notifier.notify).toHaveBeenCalledWith('feature_merged', expect.objectContaining({ feature_id: 'feature_x' }));
690
+ expect(notifier.notify).toHaveBeenCalledWith(
691
+ 'feature_merged',
692
+ expect.objectContaining({ feature_id: 'feature_x' }),
693
+ );
639
694
  });
640
695
 
641
696
  it('GIVEN_issue_tracker_WHEN_feature_first_enters_PLANNING_THEN_fetches_issue_and_stores_in_frontmatter', async () => {
642
697
  const issueTracker = {
643
698
  getIssue: vi.fn(async () => ({ id: '123', title: 'Test Issue', url: 'http://test' })),
644
699
  addComment: vi.fn(async () => undefined),
645
- updateIssueStatus: vi.fn(async () => undefined)
700
+ updateIssueStatus: vi.fn(async () => undefined),
646
701
  };
647
702
  const { coordinator, kernel } = makeCoordinatorDeps({ issueTracker });
648
703
 
649
704
  await coordinator.start([{ feature_id: 'feature_x' }]);
650
705
 
651
706
  expect(issueTracker.getIssue).toHaveBeenCalledWith('x');
652
- expect(kernel.updateState).toHaveBeenCalledWith(
653
- 'feature_x',
654
- null,
655
- expect.any(Function)
656
- );
707
+ expect(kernel.updateState).toHaveBeenCalledWith('feature_x', null, expect.any(Function));
657
708
  });
658
709
 
659
710
  it('GIVEN_issue_tracker_WHEN_status_transitions_THEN_adds_comment', async () => {
660
711
  const issueTracker = {
661
712
  getIssue: vi.fn(async () => ({ id: '123', title: 'Test Issue', url: 'http://test' })),
662
713
  addComment: vi.fn(async () => undefined),
663
- updateIssueStatus: vi.fn(async () => undefined)
714
+ updateIssueStatus: vi.fn(async () => undefined),
664
715
  };
665
716
  const { coordinator } = makeCoordinatorDeps({ issueTracker });
666
717
 
@@ -673,7 +724,7 @@ describe('RunCoordinator notification and budget branches', () => {
673
724
  const issueTracker = {
674
725
  getIssue: vi.fn(async () => ({ id: '123', title: 'Test Issue', url: 'http://test' })),
675
726
  addComment: vi.fn(async () => undefined),
676
- updateIssueStatus: vi.fn(async () => undefined)
727
+ updateIssueStatus: vi.fn(async () => undefined),
677
728
  };
678
729
  const { coordinator } = makeCoordinatorDeps({ issueTracker });
679
730
 
@@ -686,7 +737,7 @@ describe('RunCoordinator notification and budget branches', () => {
686
737
  const issueTracker = {
687
738
  getIssue: vi.fn(async () => ({ id: '123', title: 'Test Issue', url: 'http://test' })),
688
739
  addComment: vi.fn(async () => undefined),
689
- updateIssueStatus: vi.fn(async () => undefined)
740
+ updateIssueStatus: vi.fn(async () => undefined),
690
741
  };
691
742
  let callCount = 0;
692
743
  const { coordinator } = makeCoordinatorDeps({
@@ -701,7 +752,7 @@ describe('RunCoordinator notification and budget branches', () => {
701
752
  }
702
753
  return { ok: true, data: {} };
703
754
  },
704
- issueTracker
755
+ issueTracker,
705
756
  });
706
757
 
707
758
  await coordinator.start([{ feature_id: 'feature_x' }]);
@@ -714,14 +765,14 @@ describe('RunCoordinator notification and budget branches', () => {
714
765
  const { coordinator } = makeCoordinatorDeps({
715
766
  // always returns PLANNING — second iteration sees same status, should not re-notify
716
767
  notifier,
717
- maxIterationsPerPhase: 2
768
+ maxIterationsPerPhase: 2,
718
769
  });
719
770
 
720
771
  await coordinator.start([{ feature_id: 'feature_x' }]);
721
772
 
722
773
  // notify called once only — second iteration sees same status, skipped
723
774
  const planningNotifies = notifier.notify.mock.calls.filter(
724
- (c: unknown[]) => c[0] !== 'budget_alert' && c[0] !== 'budget_exceeded'
775
+ (c: unknown[]) => c[0] !== 'budget_alert' && c[0] !== 'budget_exceeded',
725
776
  );
726
777
  expect(planningNotifies.length).toBe(0); // PLANNING has no notifier branch, just confirm no error
727
778
  });
@@ -730,7 +781,7 @@ describe('RunCoordinator notification and budget branches', () => {
730
781
  const issueTracker = {
731
782
  getIssue: vi.fn(async () => ({ id: '123', title: '', url: 'http://test' })),
732
783
  addComment: vi.fn(async () => undefined),
733
- updateIssueStatus: vi.fn(async () => undefined)
784
+ updateIssueStatus: vi.fn(async () => undefined),
734
785
  };
735
786
  const { coordinator, kernel } = makeCoordinatorDeps({ issueTracker });
736
787
 
@@ -739,7 +790,7 @@ describe('RunCoordinator notification and budget branches', () => {
739
790
  expect(issueTracker.getIssue).toHaveBeenCalledWith('x');
740
791
  // updateState should NOT be called since issue has no title
741
792
  const stateUpdateForIssue = kernel.updateState.mock.calls.filter(
742
- (c: unknown[]) => c[0] === 'feature_x'
793
+ (c: unknown[]) => c[0] === 'feature_x',
743
794
  );
744
795
  expect(stateUpdateForIssue.length).toBe(0);
745
796
  });
@@ -752,8 +803,8 @@ describe('RunCoordinator notification and budget branches', () => {
752
803
  noteLogged: false,
753
804
  requestHandled: true,
754
805
  priorityOrder: ['unknown_feature', 'feature_b'],
755
- toolResults: []
756
- }))
806
+ toolResults: [],
807
+ })),
757
808
  };
758
809
 
759
810
  const { ...rest } = makeCoordinatorDeps({ maxActiveFeatures: 2, maxIterationsPerPhase: 1 });
@@ -764,15 +815,27 @@ describe('RunCoordinator notification and budget branches', () => {
764
815
  acquireRunLease: vi.fn(async () => ({ data: { took_over_stale: false } })),
765
816
  pruneFeatureSessionAssignments: vi.fn(async () => ({ data: { removed: [] as string[] } })),
766
817
  getRuntimeSessions: vi.fn(async () => ({
767
- run_id: 'run:test', owner_instance_id: 'owner:test', orchestrator_session_id: 'orch:test', feature_sessions: {}
818
+ run_id: 'run:test',
819
+ owner_instance_id: 'owner:test',
820
+ orchestrator_session_id: 'orch:test',
821
+ feature_sessions: {},
768
822
  })),
769
823
  updateState: vi.fn(async () => ({})),
770
- checkBudget: vi.fn(async () => ({ over_budget: false, alert_threshold_reached: false, current_cost_usd: 0, limit_usd: -1, alert_threshold: 0.8 }))
824
+ checkBudget: vi.fn(async () => ({
825
+ over_budget: false,
826
+ alert_threshold_reached: false,
827
+ current_cost_usd: 0,
828
+ limit_usd: -1,
829
+ alert_threshold: 0.8,
830
+ })),
771
831
  };
772
832
  const state2 = {
773
- runId: 'run:test', ownerInstanceId: 'owner:test', orchestratorSessionId: 'orch:test',
833
+ runId: 'run:test',
834
+ ownerInstanceId: 'owner:test',
835
+ orchestratorSessionId: 'orch:test',
774
836
  sessionsByFeature: new Map<string, { planner: string; builder: string; qa: string }>(),
775
- queue: [] as Array<{ feature_id: string }>, runMetadata: {}
837
+ queue: [] as Array<{ feature_id: string }>,
838
+ runMetadata: {},
776
839
  };
777
840
  const toolCaller2 = {
778
841
  callTool: vi.fn(async (_role: string, toolName: string) => {
@@ -780,7 +843,7 @@ describe('RunCoordinator notification and budget branches', () => {
780
843
  return { ok: true, data: { features: [] } };
781
844
  }
782
845
  return { ok: true, data: { front_matter: { status: STATUS.PLANNING } } };
783
- })
846
+ }),
784
847
  };
785
848
  const sessionOrchestrator2 = {
786
849
  ensureGlobalOrchestratorSession: vi.fn(async () => undefined),
@@ -788,7 +851,7 @@ describe('RunCoordinator notification and budget branches', () => {
788
851
  initializeFeatureCluster: vi.fn(async () => undefined),
789
852
  closeFeatureCluster: vi.fn(async () => undefined),
790
853
  reconcileQueuedFeatures: vi.fn(async () => undefined),
791
- enforceActiveFeatureInvariant: vi.fn(async () => undefined)
854
+ enforceActiveFeatureInvariant: vi.fn(async () => undefined),
792
855
  };
793
856
  const coord2 = new RunCoordinator({
794
857
  kernel: kernel2 as never,
@@ -796,13 +859,19 @@ describe('RunCoordinator notification and budget branches', () => {
796
859
  toolCaller: toolCaller2 as never,
797
860
  state: state2 as never,
798
861
  sessionOrchestrator: sessionOrchestrator2 as never,
799
- planningWaveExecutor: { run: vi.fn(async () => undefined), runPostQaReconciliation: vi.fn(async () => undefined) } as never,
862
+ planningWaveExecutor: {
863
+ run: vi.fn(async () => undefined),
864
+ runPostQaReconciliation: vi.fn(async () => undefined),
865
+ } as never,
800
866
  buildWaveExecutor: { run: vi.fn(async () => undefined) } as never,
801
867
  qaWaveExecutor: { run: vi.fn(async () => undefined) } as never,
802
868
  leaseHeartbeatService: { renew: vi.fn(async () => undefined) } as never,
803
- maxActiveFeatures: 2, maxParallelGateRuns: 2, maxIterationsPerPhase: 1,
804
- takeoverStaleRun: false, providerConfigRefHash: () => 'hash',
805
- workerDecisionRunner: workerDecisionRunner as never
869
+ maxActiveFeatures: 2,
870
+ maxParallelGateRuns: 2,
871
+ maxIterationsPerPhase: 1,
872
+ takeoverStaleRun: false,
873
+ providerConfigRefHash: () => 'hash',
874
+ workerDecisionRunner: workerDecisionRunner as never,
806
875
  });
807
876
 
808
877
  void rest; // suppress unused warning