agentic-orchestrator 0.1.6 → 0.1.8

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 (438) hide show
  1. package/.prettierignore +10 -0
  2. package/.prettierrc.json +24 -0
  3. package/CLAUDE.md +3 -2
  4. package/README.md +71 -48
  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 +5 -22
  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/env-file.ts +115 -0
  107. package/apps/control-plane/src/cli/help-command-handler.ts +61 -32
  108. package/apps/control-plane/src/cli/init-command-handler.ts +182 -56
  109. package/apps/control-plane/src/cli/io.ts +7 -3
  110. package/apps/control-plane/src/cli/resume-command-handler.ts +21 -13
  111. package/apps/control-plane/src/cli/retry-command-handler.ts +12 -11
  112. package/apps/control-plane/src/cli/run-command-handler.ts +12 -8
  113. package/apps/control-plane/src/cli/send-command-handler.ts +6 -6
  114. package/apps/control-plane/src/cli/spec-ingestion-service.ts +14 -8
  115. package/apps/control-plane/src/cli/spec-input-resolver.ts +6 -1
  116. package/apps/control-plane/src/cli/spec-utils.ts +2 -2
  117. package/apps/control-plane/src/cli/status-command-handler.ts +13 -12
  118. package/apps/control-plane/src/cli/tooling.ts +3 -3
  119. package/apps/control-plane/src/cli/types.ts +1 -1
  120. package/apps/control-plane/src/core/collisions.ts +27 -10
  121. package/apps/control-plane/src/core/constants.ts +13 -7
  122. package/apps/control-plane/src/core/error-codes.ts +1 -1
  123. package/apps/control-plane/src/core/fs.ts +11 -5
  124. package/apps/control-plane/src/core/gates.ts +53 -27
  125. package/apps/control-plane/src/core/git.ts +18 -6
  126. package/apps/control-plane/src/core/kernel.ts +513 -227
  127. package/apps/control-plane/src/core/patch.ts +7 -3
  128. package/apps/control-plane/src/core/path-layout.ts +5 -1
  129. package/apps/control-plane/src/core/path-rules.ts +19 -5
  130. package/apps/control-plane/src/core/qa-index.ts +26 -12
  131. package/apps/control-plane/src/core/response.ts +9 -6
  132. package/apps/control-plane/src/core/schemas.ts +29 -10
  133. package/apps/control-plane/src/core/tool-caller.ts +1 -1
  134. package/apps/control-plane/src/core/workspace-hooks.ts +5 -5
  135. package/apps/control-plane/src/index.ts +3 -9
  136. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +79 -35
  137. package/apps/control-plane/src/mcp/kernel-tool-executor.ts +7 -3
  138. package/apps/control-plane/src/mcp/mcp-server-adapter.ts +12 -10
  139. package/apps/control-plane/src/mcp/operation-ledger.ts +18 -8
  140. package/apps/control-plane/src/mcp/protocol-contract.ts +2 -2
  141. package/apps/control-plane/src/mcp/runtime-factory.ts +15 -6
  142. package/apps/control-plane/src/mcp/token-auth-verifier.ts +3 -2
  143. package/apps/control-plane/src/mcp/token-claims-validator.ts +11 -7
  144. package/apps/control-plane/src/mcp/tool-authorizer.ts +1 -3
  145. package/apps/control-plane/src/mcp/tool-client.ts +17 -5
  146. package/apps/control-plane/src/mcp/tool-contract-validator.ts +17 -8
  147. package/apps/control-plane/src/mcp/tool-registry-loader.ts +7 -3
  148. package/apps/control-plane/src/mcp/tool-runtime.ts +66 -39
  149. package/apps/control-plane/src/mcp/tools-markdown-generator.ts +6 -1
  150. package/apps/control-plane/src/providers/providers.ts +137 -54
  151. package/apps/control-plane/src/supervisor/build-wave-executor.ts +44 -25
  152. package/apps/control-plane/src/supervisor/planning-wave-executor.ts +46 -33
  153. package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +1 -1
  154. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +38 -23
  155. package/apps/control-plane/src/supervisor/run-coordinator.ts +71 -36
  156. package/apps/control-plane/src/supervisor/runtime.ts +59 -35
  157. package/apps/control-plane/src/supervisor/session-orchestrator.ts +48 -31
  158. package/apps/control-plane/src/supervisor/types.ts +22 -7
  159. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +30 -20
  160. package/apps/control-plane/test/activity-monitor.spec.ts +54 -30
  161. package/apps/control-plane/test/adapter-registry.spec.ts +5 -5
  162. package/apps/control-plane/test/aop.spec.ts +4 -4
  163. package/apps/control-plane/test/batch-operations.spec.ts +20 -18
  164. package/apps/control-plane/test/bootstrap-attach.spec.ts +52 -19
  165. package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +58 -27
  166. package/apps/control-plane/test/bootstrap.spec.ts +72 -40
  167. package/apps/control-plane/test/cleanup-command.spec.ts +86 -32
  168. package/apps/control-plane/test/cli-helpers.spec.ts +119 -66
  169. package/apps/control-plane/test/cli.spec.ts +1 -1
  170. package/apps/control-plane/test/cli.unit.spec.ts +226 -167
  171. package/apps/control-plane/test/collision-queue.spec.ts +49 -40
  172. package/apps/control-plane/test/collisions.spec.ts +30 -30
  173. package/apps/control-plane/test/core-utils.spec.ts +29 -15
  174. package/apps/control-plane/test/cost-tracking.spec.ts +38 -22
  175. package/apps/control-plane/test/dashboard-api.integration.spec.ts +68 -36
  176. package/apps/control-plane/test/dashboard-client.spec.ts +18 -12
  177. package/apps/control-plane/test/dashboard-command.spec.ts +11 -7
  178. package/apps/control-plane/test/delete-command-handler.spec.ts +49 -41
  179. package/apps/control-plane/test/dependency-scheduler.spec.ts +47 -20
  180. package/apps/control-plane/test/epoch-tracking.spec.ts +9 -9
  181. package/apps/control-plane/test/feature-deletion-service.spec.ts +60 -52
  182. package/apps/control-plane/test/feature-lifecycle.spec.ts +36 -17
  183. package/apps/control-plane/test/gates.spec.ts +101 -81
  184. package/apps/control-plane/test/git-spawn-error.spec.ts +1 -1
  185. package/apps/control-plane/test/helpers.ts +10 -6
  186. package/apps/control-plane/test/incremental-gates.spec.ts +59 -20
  187. package/apps/control-plane/test/init-wizard.spec.ts +328 -68
  188. package/apps/control-plane/test/instance-isolation.spec.ts +43 -10
  189. package/apps/control-plane/test/issue-tracker.spec.ts +368 -128
  190. package/apps/control-plane/test/kernel-collision-replay.spec.ts +50 -29
  191. package/apps/control-plane/test/kernel.branches.spec.ts +64 -40
  192. package/apps/control-plane/test/kernel.coverage.spec.ts +85 -49
  193. package/apps/control-plane/test/kernel.coverage2.spec.ts +109 -65
  194. package/apps/control-plane/test/kernel.spec.ts +134 -51
  195. package/apps/control-plane/test/lock-service.spec.ts +92 -68
  196. package/apps/control-plane/test/mcp-helpers.spec.ts +53 -39
  197. package/apps/control-plane/test/mcp.spec.ts +231 -115
  198. package/apps/control-plane/test/merge-service.spec.ts +142 -94
  199. package/apps/control-plane/test/multi-project.spec.ts +28 -22
  200. package/apps/control-plane/test/notifier-service.spec.ts +136 -92
  201. package/apps/control-plane/test/parallel-gates.spec.ts +51 -35
  202. package/apps/control-plane/test/patch-service.spec.ts +128 -48
  203. package/apps/control-plane/test/performance-analytics.spec.ts +99 -63
  204. package/apps/control-plane/test/plan-service.spec.ts +50 -39
  205. package/apps/control-plane/test/planning-wave-executor.spec.ts +95 -71
  206. package/apps/control-plane/test/policy-loader-service.spec.ts +41 -19
  207. package/apps/control-plane/test/pr-monitor.spec.ts +113 -64
  208. package/apps/control-plane/test/providers.spec.ts +208 -104
  209. package/apps/control-plane/test/qa-index-service.spec.ts +31 -33
  210. package/apps/control-plane/test/qa-index.spec.ts +58 -61
  211. package/apps/control-plane/test/reactions.spec.ts +88 -45
  212. package/apps/control-plane/test/response.spec.ts +5 -5
  213. package/apps/control-plane/test/resume-command.spec.ts +121 -80
  214. package/apps/control-plane/test/run-coordinator.spec.ts +205 -136
  215. package/apps/control-plane/test/schema-date-time.spec.ts +49 -41
  216. package/apps/control-plane/test/service-retry-paths.spec.ts +77 -57
  217. package/apps/control-plane/test/services.spec.ts +147 -129
  218. package/apps/control-plane/test/session-management.spec.ts +136 -74
  219. package/apps/control-plane/test/spec-ingestion.spec.ts +23 -21
  220. package/apps/control-plane/test/spec-input-resolver.spec.ts +11 -10
  221. package/apps/control-plane/test/supervisor-collaborators.spec.ts +168 -121
  222. package/apps/control-plane/test/supervisor.calltool.spec.ts +21 -18
  223. package/apps/control-plane/test/supervisor.spec.ts +67 -43
  224. package/apps/control-plane/test/supervisor.unit.spec.ts +195 -126
  225. package/apps/control-plane/test/token-auth-verifier.spec.ts +29 -14
  226. package/apps/control-plane/test/tool-registry-loader.spec.ts +51 -27
  227. package/apps/control-plane/test/tool-runtime.spec.ts +63 -46
  228. package/apps/control-plane/test/worker-decision-loop.spec.ts +143 -122
  229. package/apps/control-plane/test/workspace-hooks.spec.ts +61 -23
  230. package/apps/control-plane/tsconfig.build.json +2 -7
  231. package/apps/control-plane/tsconfig.json +1 -5
  232. package/apps/control-plane/vitest.config.ts +7 -7
  233. package/config/agentic/orchestrator/adapters.yaml +3 -0
  234. package/config/agentic/orchestrator/agents.yaml +14 -0
  235. package/config/agentic/orchestrator/gates.yaml +28 -0
  236. package/config/agentic/orchestrator/policy.yaml +22 -0
  237. package/config/agentic/orchestrator/prompts/builder.system.md +1 -0
  238. package/config/agentic/orchestrator/prompts/planner.system.md +16 -0
  239. package/config/agentic/orchestrator/prompts/qa.system.md +1 -0
  240. package/dist/apps/control-plane/application/adapters/adapter-registry.js +12 -5
  241. package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -1
  242. package/dist/apps/control-plane/application/multi-project-loader.js +26 -9
  243. package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -1
  244. package/dist/apps/control-plane/application/services/activity-monitor-service.js +7 -7
  245. package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
  246. package/dist/apps/control-plane/application/services/collision-queue-service.js +7 -7
  247. package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
  248. package/dist/apps/control-plane/application/services/cost-tracking-service.js +6 -8
  249. package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
  250. package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -1
  251. package/dist/apps/control-plane/application/services/feature-deletion-service.js +37 -29
  252. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
  253. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +10 -10
  254. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
  255. package/dist/apps/control-plane/application/services/feature-state-service.js +11 -11
  256. package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
  257. package/dist/apps/control-plane/application/services/gate-interpolation-service.js +3 -1
  258. package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -1
  259. package/dist/apps/control-plane/application/services/gate-service.js +26 -26
  260. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
  261. package/dist/apps/control-plane/application/services/instance-isolation-service.js +1 -1
  262. package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -1
  263. package/dist/apps/control-plane/application/services/issue-tracker-service.js +25 -15
  264. package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
  265. package/dist/apps/control-plane/application/services/lock-service.js +32 -32
  266. package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
  267. package/dist/apps/control-plane/application/services/merge-service.js +41 -27
  268. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
  269. package/dist/apps/control-plane/application/services/notifier-service.js +29 -15
  270. package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
  271. package/dist/apps/control-plane/application/services/patch-service.js +21 -19
  272. package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
  273. package/dist/apps/control-plane/application/services/performance-analytics-service.js +4 -4
  274. package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
  275. package/dist/apps/control-plane/application/services/plan-service.js +33 -33
  276. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
  277. package/dist/apps/control-plane/application/services/policy-loader-service.js.map +1 -1
  278. package/dist/apps/control-plane/application/services/pr-monitor-service.js +23 -11
  279. package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
  280. package/dist/apps/control-plane/application/services/qa-index-service.js +11 -11
  281. package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
  282. package/dist/apps/control-plane/application/services/reactions-service.js +13 -9
  283. package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
  284. package/dist/apps/control-plane/application/services/reporting-service.js +11 -9
  285. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
  286. package/dist/apps/control-plane/application/services/run-lease-service.js +34 -33
  287. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
  288. package/dist/apps/control-plane/application/tools/tool-metadata.js +2 -2
  289. package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
  290. package/dist/apps/control-plane/cli/attach-command-handler.js +9 -9
  291. package/dist/apps/control-plane/cli/cleanup-command-handler.js +11 -9
  292. package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -1
  293. package/dist/apps/control-plane/cli/cli-argument-parser.js +4 -3
  294. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
  295. package/dist/apps/control-plane/cli/dashboard-command-handler.js +23 -7
  296. package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
  297. package/dist/apps/control-plane/cli/delete-command-handler.js +7 -7
  298. package/dist/apps/control-plane/cli/env-file.d.ts +4 -0
  299. package/dist/apps/control-plane/cli/env-file.js +89 -0
  300. package/dist/apps/control-plane/cli/env-file.js.map +1 -0
  301. package/dist/apps/control-plane/cli/help-command-handler.js +58 -30
  302. package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
  303. package/dist/apps/control-plane/cli/init-command-handler.js +97 -37
  304. package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
  305. package/dist/apps/control-plane/cli/io.js +2 -2
  306. package/dist/apps/control-plane/cli/io.js.map +1 -1
  307. package/dist/apps/control-plane/cli/resume-command-handler.js +9 -9
  308. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
  309. package/dist/apps/control-plane/cli/retry-command-handler.js +12 -11
  310. package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
  311. package/dist/apps/control-plane/cli/run-command-handler.js +12 -8
  312. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
  313. package/dist/apps/control-plane/cli/send-command-handler.js +6 -6
  314. package/dist/apps/control-plane/cli/spec-ingestion-service.js +10 -8
  315. package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
  316. package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -1
  317. package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
  318. package/dist/apps/control-plane/cli/status-command-handler.js +8 -8
  319. package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
  320. package/dist/apps/control-plane/cli/tooling.js +1 -1
  321. package/dist/apps/control-plane/core/collisions.js +11 -8
  322. package/dist/apps/control-plane/core/collisions.js.map +1 -1
  323. package/dist/apps/control-plane/core/constants.js +13 -7
  324. package/dist/apps/control-plane/core/constants.js.map +1 -1
  325. package/dist/apps/control-plane/core/error-codes.js +1 -1
  326. package/dist/apps/control-plane/core/fs.js.map +1 -1
  327. package/dist/apps/control-plane/core/gates.d.ts +2 -2
  328. package/dist/apps/control-plane/core/gates.js +26 -19
  329. package/dist/apps/control-plane/core/gates.js.map +1 -1
  330. package/dist/apps/control-plane/core/git.js +3 -3
  331. package/dist/apps/control-plane/core/git.js.map +1 -1
  332. package/dist/apps/control-plane/core/kernel.d.ts +1 -0
  333. package/dist/apps/control-plane/core/kernel.js +134 -81
  334. package/dist/apps/control-plane/core/kernel.js.map +1 -1
  335. package/dist/apps/control-plane/core/patch.js +7 -3
  336. package/dist/apps/control-plane/core/patch.js.map +1 -1
  337. package/dist/apps/control-plane/core/path-layout.d.ts +1 -0
  338. package/dist/apps/control-plane/core/path-layout.js +4 -1
  339. package/dist/apps/control-plane/core/path-layout.js.map +1 -1
  340. package/dist/apps/control-plane/core/path-rules.js +3 -1
  341. package/dist/apps/control-plane/core/path-rules.js.map +1 -1
  342. package/dist/apps/control-plane/core/qa-index.js +5 -5
  343. package/dist/apps/control-plane/core/qa-index.js.map +1 -1
  344. package/dist/apps/control-plane/core/response.js +3 -3
  345. package/dist/apps/control-plane/core/response.js.map +1 -1
  346. package/dist/apps/control-plane/core/schemas.js +10 -6
  347. package/dist/apps/control-plane/core/schemas.js.map +1 -1
  348. package/dist/apps/control-plane/core/workspace-hooks.js +3 -3
  349. package/dist/apps/control-plane/index.d.ts +1 -1
  350. package/dist/apps/control-plane/index.js +1 -1
  351. package/dist/apps/control-plane/index.js.map +1 -1
  352. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +40 -23
  353. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
  354. package/dist/apps/control-plane/mcp/kernel-tool-executor.js +1 -1
  355. package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
  356. package/dist/apps/control-plane/mcp/mcp-server-adapter.js +6 -7
  357. package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -1
  358. package/dist/apps/control-plane/mcp/operation-ledger.js +5 -5
  359. package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -1
  360. package/dist/apps/control-plane/mcp/protocol-contract.js +2 -2
  361. package/dist/apps/control-plane/mcp/runtime-factory.js +2 -2
  362. package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -1
  363. package/dist/apps/control-plane/mcp/token-auth-verifier.js +1 -1
  364. package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -1
  365. package/dist/apps/control-plane/mcp/token-claims-validator.js +5 -5
  366. package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -1
  367. package/dist/apps/control-plane/mcp/tool-authorizer.js +1 -3
  368. package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -1
  369. package/dist/apps/control-plane/mcp/tool-client.js +2 -2
  370. package/dist/apps/control-plane/mcp/tool-client.js.map +1 -1
  371. package/dist/apps/control-plane/mcp/tool-contract-validator.js +3 -3
  372. package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -1
  373. package/dist/apps/control-plane/mcp/tool-registry-loader.js +1 -1
  374. package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -1
  375. package/dist/apps/control-plane/mcp/tool-runtime.js +17 -17
  376. package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
  377. package/dist/apps/control-plane/mcp/tools-markdown-generator.js +6 -1
  378. package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -1
  379. package/dist/apps/control-plane/providers/providers.d.ts +3 -2
  380. package/dist/apps/control-plane/providers/providers.js +81 -39
  381. package/dist/apps/control-plane/providers/providers.js.map +1 -1
  382. package/dist/apps/control-plane/supervisor/build-wave-executor.js +12 -12
  383. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
  384. package/dist/apps/control-plane/supervisor/planning-wave-executor.js +19 -16
  385. package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
  386. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +1 -1
  387. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +13 -13
  388. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
  389. package/dist/apps/control-plane/supervisor/run-coordinator.js +37 -20
  390. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
  391. package/dist/apps/control-plane/supervisor/runtime.js +25 -21
  392. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
  393. package/dist/apps/control-plane/supervisor/session-orchestrator.js +29 -23
  394. package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
  395. package/dist/apps/control-plane/supervisor/types.d.ts +3 -3
  396. package/dist/apps/control-plane/supervisor/types.js.map +1 -1
  397. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +14 -16
  398. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
  399. package/eslint.config.mjs +20 -20
  400. package/example-configurations/README.md +1 -1
  401. package/example-configurations/java/agents.yaml +3 -3
  402. package/example-configurations/java/policy.yaml +1 -1
  403. package/example-configurations/node/agents.yaml +3 -3
  404. package/example-configurations/node/policy.yaml +1 -1
  405. package/package.json +10 -5
  406. package/packages/web-dashboard/next.config.js +2 -2
  407. package/packages/web-dashboard/src/app/api/actions/route.ts +25 -9
  408. package/packages/web-dashboard/src/app/api/events/route.ts +20 -6
  409. package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +88 -37
  410. package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +8 -5
  411. package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +27 -9
  412. package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -2
  413. package/packages/web-dashboard/src/app/api/projects/route.ts +5 -5
  414. package/packages/web-dashboard/src/app/globals.css +10 -2
  415. package/packages/web-dashboard/src/app/page.tsx +100 -37
  416. package/packages/web-dashboard/src/lib/aop-client.ts +68 -37
  417. package/packages/web-dashboard/src/lib/multi-project-config.ts +28 -7
  418. package/packages/web-dashboard/src/lib/orchestrator-tools.ts +59 -36
  419. package/packages/web-dashboard/tsconfig.json +3 -11
  420. package/scripts/nx-safe.mjs +10 -10
  421. package/spec-files/completed/agentic_orchestrator_cli_delete_command_spec.md +5 -0
  422. package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +189 -90
  423. package/spec-files/completed/agentic_orchestrator_init_policy_ux_simplification_spec.md +49 -16
  424. package/spec-files/completed/agentic_orchestrator_mcp_formalization_spec.md +24 -1
  425. package/spec-files/completed/agentic_orchestrator_single_global_orchestrator_spec.md +9 -0
  426. package/spec-files/completed/agentic_orchestrator_spec.md +171 -75
  427. package/spec-files/completed/agentic_orchestrator_validator_hardening_spec.md +25 -17
  428. package/spec-files/outstanding/agentic_orchestrator_artifact_database_publishing_spec.md +40 -5
  429. package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +23 -12
  430. package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +16 -4
  431. package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +42 -2
  432. package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +209 -130
  433. package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +56 -3
  434. package/spec-files/outstanding/agentic_orchestrator_productization_commercial_spec.md +77 -10
  435. package/spec-files/outstanding/agentic_orchestrator_provider_auth_bootstrap_spec.md +384 -0
  436. package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +29 -14
  437. package/spec-files/progress.md +186 -175
  438. package/tsconfig.json +2 -8
@@ -9,7 +9,9 @@ function makeTmpDir(): string {
9
9
  return path.join(os.tmpdir(), `aop-lifecycle-test-${process.pid}-${Date.now()}`);
10
10
  }
11
11
 
12
- function makePort(overrides: Partial<FeatureLifecycleServicePort> = {}): FeatureLifecycleServicePort {
12
+ function makePort(
13
+ overrides: Partial<FeatureLifecycleServicePort> = {},
14
+ ): FeatureLifecycleServicePort {
13
15
  const repoRoot = '/tmp/repo';
14
16
  const featuresDir = '/tmp/repo/.aop/features';
15
17
 
@@ -25,14 +27,18 @@ function makePort(overrides: Partial<FeatureLifecycleServicePort> = {}): Feature
25
27
  repoEnsureWorktree: vi.fn(async () => ({ data: { worktree_path_abs: `/tmp/worktrees/f1` } })),
26
28
  makeDefaultState: vi.fn(() => ({ feature_id: 'f1', status: 'planning', version: 0 })),
27
29
  writeState: vi.fn(async () => {}),
28
- withIndexLock: vi.fn(async (op: () => Promise<unknown>) => await op()) as unknown as <T>(operation: () => Promise<T>) => Promise<T>,
30
+ withIndexLock: vi.fn(async (op: () => Promise<unknown>) => await op()) as unknown as <T>(
31
+ operation: () => Promise<T>,
32
+ ) => Promise<T>,
29
33
  readIndex: vi.fn(async () => ({ active: [], blocked: [], version: 0, updated_at: '' })),
30
34
  writeIndex: vi.fn(async () => {}),
31
- featureStateGet: vi.fn(async () => ({ data: { front_matter: { version: 1, status: 'planning' }, body: '' } })),
35
+ featureStateGet: vi.fn(async () => ({
36
+ data: { front_matter: { version: 1, status: 'planning' }, body: '' },
37
+ })),
32
38
  planGet: vi.fn(async () => ({ data: { plan: { files: {} } } })),
33
39
  qaTestIndexGet: vi.fn(async () => ({ data: { items: [] } })),
34
40
  evidenceLatest: vi.fn(async () => ({ data: { latest: null } })),
35
- ...overrides
41
+ ...overrides,
36
42
  };
37
43
  }
38
44
 
@@ -46,7 +52,7 @@ describe('FeatureLifecycleService', () => {
46
52
  const tmpDir = makeTmpDir();
47
53
  const port = makePort({
48
54
  getRepoRoot: vi.fn(() => tmpDir),
49
- getFeaturesDir: vi.fn(() => path.join(tmpDir, '.aop', 'features'))
55
+ getFeaturesDir: vi.fn(() => path.join(tmpDir, '.aop', 'features')),
50
56
  });
51
57
  const service = new FeatureLifecycleService(port);
52
58
  const result = await service.featureDiscoverSpecs();
@@ -65,7 +71,7 @@ describe('FeatureLifecycleService', () => {
65
71
 
66
72
  const port = makePort({
67
73
  getRepoRoot: vi.fn(() => tmpDir),
68
- getFeaturesDir: vi.fn(() => featuresDir)
74
+ getFeaturesDir: vi.fn(() => featuresDir),
69
75
  });
70
76
  const service = new FeatureLifecycleService(port);
71
77
  const result = await service.featureDiscoverSpecs();
@@ -81,7 +87,7 @@ describe('FeatureLifecycleService', () => {
81
87
  it('GIVEN_null_featureId_WHEN_featureInit_called_THEN_throws_INVALID_ARGUMENT', async () => {
82
88
  const service = new FeatureLifecycleService(makePort());
83
89
  await expect(service.featureInit(null)).rejects.toMatchObject({
84
- normalizedResponse: { error: { code: 'invalid_argument' } }
90
+ normalizedResponse: { error: { code: 'invalid_argument' } },
85
91
  });
86
92
  });
87
93
 
@@ -91,7 +97,7 @@ describe('FeatureLifecycleService', () => {
91
97
  const port = makePort({
92
98
  getRepoRoot: vi.fn(() => tmpDir),
93
99
  statePath: vi.fn(() => path.join(tmpDir, 'nonexistent-state.md')),
94
- qaIndexPath: vi.fn(() => path.join(tmpDir, 'nonexistent-qa.json'))
100
+ qaIndexPath: vi.fn(() => path.join(tmpDir, 'nonexistent-qa.json')),
95
101
  });
96
102
  const service = new FeatureLifecycleService(port);
97
103
  const result = await service.featureInit('test_feature');
@@ -112,7 +118,7 @@ describe('FeatureLifecycleService', () => {
112
118
  const port = makePort({
113
119
  getRepoRoot: vi.fn(() => tmpDir),
114
120
  statePath: vi.fn(() => path.join(tmpDir, 'state.md')),
115
- qaIndexPath: vi.fn(() => path.join(tmpDir, 'qa.json'))
121
+ qaIndexPath: vi.fn(() => path.join(tmpDir, 'qa.json')),
116
122
  });
117
123
  const service = new FeatureLifecycleService(port);
118
124
  await service.featureInit('f1');
@@ -126,7 +132,7 @@ describe('FeatureLifecycleService', () => {
126
132
  describe('featureGetContext', () => {
127
133
  it('GIVEN_featureId_with_no_spec_file_WHEN_featureGetContext_called_THEN_spec_is_empty_string', async () => {
128
134
  const port = makePort({
129
- specPath: vi.fn(() => '/nonexistent/spec.md')
135
+ specPath: vi.fn(() => '/nonexistent/spec.md'),
130
136
  });
131
137
  const service = new FeatureLifecycleService(port);
132
138
  const result = await service.featureGetContext('f1');
@@ -138,7 +144,7 @@ describe('FeatureLifecycleService', () => {
138
144
  const evidence = { gate_profile: 'fast', passed: true };
139
145
  const port = makePort({
140
146
  evidenceLatest: vi.fn(async () => ({ data: { latest: evidence } })),
141
- specPath: vi.fn(() => '/nonexistent/spec.md')
147
+ specPath: vi.fn(() => '/nonexistent/spec.md'),
142
148
  });
143
149
  const service = new FeatureLifecycleService(port);
144
150
  const result = await service.featureGetContext('f1');
@@ -153,10 +159,13 @@ describe('FeatureLifecycleService', () => {
153
159
  const logPath = path.join(tmpDir, 'decisions.md');
154
160
  const port = makePort({
155
161
  getRepoRoot: vi.fn(() => tmpDir),
156
- decisionsPath: vi.fn(() => logPath)
162
+ decisionsPath: vi.fn(() => logPath),
157
163
  });
158
164
  const service = new FeatureLifecycleService(port);
159
- const result = await service.featureLogAppend('f1', 'starting build', { actorType: 'orchestrator', actorId: 'orch-1' });
165
+ const result = await service.featureLogAppend('f1', 'starting build', {
166
+ actorType: 'orchestrator',
167
+ actorId: 'orch-1',
168
+ });
160
169
  expect(result.data.appended).toBe(true);
161
170
  const content = await fs.readFile(logPath, 'utf8');
162
171
  expect(content).toContain('[orchestrator:orch-1] starting build');
@@ -169,7 +178,8 @@ describe('FeatureLifecycleService', () => {
169
178
 
170
179
  describe('ToolRouter and ToolHandlerRegistry', () => {
171
180
  it('GIVEN_registered_handler_WHEN_route_called_THEN_handler_invoked', async () => {
172
- const { ToolHandlerRegistry, ToolRouter } = await import('../src/application/tools/tool-router.js');
181
+ const { ToolHandlerRegistry, ToolRouter } =
182
+ await import('../src/application/tools/tool-router.js');
173
183
  const registry = new ToolHandlerRegistry();
174
184
  const handler = vi.fn(async () => ({ ok: true }));
175
185
  registry.register('test.tool', handler);
@@ -177,19 +187,28 @@ describe('ToolRouter and ToolHandlerRegistry', () => {
177
187
  const unknownHandler = vi.fn(async () => ({ error: 'unknown' }));
178
188
  const router = new ToolRouter(registry, unknownHandler);
179
189
 
180
- const result = await router.route('test.tool', { arg: 1 }, { actorType: 'orchestrator', actorId: 'o1' });
190
+ const result = await router.route(
191
+ 'test.tool',
192
+ { arg: 1 },
193
+ { actorType: 'orchestrator', actorId: 'o1' },
194
+ );
181
195
  expect(handler).toHaveBeenCalledWith({ arg: 1 }, { actorType: 'orchestrator', actorId: 'o1' });
182
196
  expect(result).toEqual({ ok: true });
183
197
  expect(unknownHandler).not.toHaveBeenCalled();
184
198
  });
185
199
 
186
200
  it('GIVEN_no_handler_registered_WHEN_route_called_THEN_unknown_handler_invoked', async () => {
187
- const { ToolHandlerRegistry, ToolRouter } = await import('../src/application/tools/tool-router.js');
201
+ const { ToolHandlerRegistry, ToolRouter } =
202
+ await import('../src/application/tools/tool-router.js');
188
203
  const registry = new ToolHandlerRegistry();
189
204
  const unknownHandler = vi.fn(async (name: string) => ({ error: `unknown: ${name}` }));
190
205
  const router = new ToolRouter(registry, unknownHandler);
191
206
 
192
- const result = await router.route('nonexistent.tool', {}, { actorType: 'builder', actorId: 'b1' });
207
+ const result = await router.route(
208
+ 'nonexistent.tool',
209
+ {},
210
+ { actorType: 'builder', actorId: 'b1' },
211
+ );
193
212
  expect(unknownHandler).toHaveBeenCalledWith('nonexistent.tool');
194
213
  expect(result).toEqual({ error: 'unknown: nonexistent.tool' });
195
214
  });
@@ -6,7 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
6
6
  const runCommandMock = vi.hoisted(() => vi.fn());
7
7
 
8
8
  vi.mock('../src/core/git.js', () => ({
9
- runCommand: runCommandMock
9
+ runCommand: runCommandMock,
10
10
  }));
11
11
 
12
12
  import { parseCoverage, runGateMode } from '../src/core/gates.js';
@@ -15,17 +15,17 @@ const basePolicy = {
15
15
  execution: {
16
16
  retry_policy: {
17
17
  transient_max_retries: 1,
18
- transient_error_codes: [124]
18
+ transient_error_codes: [124],
19
19
  },
20
20
  env_allowlist: ['TEST_ALLOWED_ENV'],
21
- default_step_timeout_seconds: 1
21
+ default_step_timeout_seconds: 1,
22
22
  },
23
23
  testing: {
24
24
  coverage: {
25
25
  minimums: { line: 0.9, branch: 0.9 },
26
- targets: { line: 1.0, branch: 1.0 }
27
- }
28
- }
26
+ targets: { line: 1.0, branch: 1.0 },
27
+ },
28
+ },
29
29
  };
30
30
 
31
31
  describe('gates helpers', () => {
@@ -51,48 +51,56 @@ describe('gates helpers', () => {
51
51
  await fs.writeFile(
52
52
  path.join(tempRoot, 'lcov.info'),
53
53
  ['TN:', 'SF:src/a.ts', 'LF:10', 'LH:8', 'BRF:4', 'BRH:3', 'end_of_record', ''].join('\n'),
54
- 'utf8'
54
+ 'utf8',
55
55
  );
56
56
  await fs.writeFile(
57
57
  path.join(tempRoot, 'junit.xml'),
58
58
  '<testsuite tests="5" failures="1" errors="1"></testsuite>',
59
- 'utf8'
59
+ 'utf8',
60
60
  );
61
61
  await fs.writeFile(
62
62
  path.join(tempRoot, 'jacoco.xml'),
63
63
  '<report><counter type="LINE" missed="2" covered="8"/><counter type="BRANCH" missed="3" covered="9"/></report>',
64
- 'utf8'
64
+ 'utf8',
65
65
  );
66
66
  await fs.writeFile(
67
67
  path.join(tempRoot, 'cobertura.xml'),
68
68
  '<coverage line-rate="0.75" branch-rate="0.5"></coverage>',
69
- 'utf8'
69
+ 'utf8',
70
70
  );
71
71
 
72
- await expect(parseCoverage({ type: 'lcov', path: 'lcov.info' }, tempRoot)).resolves.toMatchObject({
72
+ await expect(
73
+ parseCoverage({ type: 'lcov', path: 'lcov.info' }, tempRoot),
74
+ ).resolves.toMatchObject({
73
75
  line: 0.8,
74
76
  branch: 0.75,
75
- details: { linesFound: 10, linesHit: 8, branchesFound: 4, branchesHit: 3 }
77
+ details: { linesFound: 10, linesHit: 8, branchesFound: 4, branchesHit: 3 },
76
78
  });
77
- await expect(parseCoverage({ type: 'junit_xml', path: 'junit.xml' }, tempRoot)).resolves.toMatchObject({
79
+ await expect(
80
+ parseCoverage({ type: 'junit_xml', path: 'junit.xml' }, tempRoot),
81
+ ).resolves.toMatchObject({
78
82
  line: 0.6,
79
- branch: 0.6
83
+ branch: 0.6,
80
84
  });
81
- await expect(parseCoverage({ type: 'jacoco_xml', path: 'jacoco.xml' }, tempRoot)).resolves.toMatchObject({
85
+ await expect(
86
+ parseCoverage({ type: 'jacoco_xml', path: 'jacoco.xml' }, tempRoot),
87
+ ).resolves.toMatchObject({
82
88
  line: 0.8,
83
- branch: 0.75
89
+ branch: 0.75,
84
90
  });
85
- await expect(parseCoverage({ type: 'cobertura_xml', path: 'cobertura.xml' }, tempRoot)).resolves.toMatchObject({
91
+ await expect(
92
+ parseCoverage({ type: 'cobertura_xml', path: 'cobertura.xml' }, tempRoot),
93
+ ).resolves.toMatchObject({
86
94
  line: 0.75,
87
- branch: 0.5
95
+ branch: 0.5,
88
96
  });
89
97
  });
90
98
 
91
99
  it('GIVEN_unsupported_parser_WHEN_parsing_coverage_THEN_throws_error', async () => {
92
100
  await fs.writeFile(path.join(tempRoot, 'raw.txt'), 'x', 'utf8');
93
- await expect(parseCoverage({ type: 'custom_parser', path: 'raw.txt' }, tempRoot)).rejects.toThrow(
94
- 'unsupported_parser:custom_parser'
95
- );
101
+ await expect(
102
+ parseCoverage({ type: 'custom_parser', path: 'raw.txt' }, tempRoot),
103
+ ).rejects.toThrow('unsupported_parser:custom_parser');
96
104
  });
97
105
 
98
106
  it('GIVEN_missing_mode_definition_WHEN_running_gate_mode_THEN_throws_unknown_mode_error', async () => {
@@ -105,8 +113,8 @@ describe('gates helpers', () => {
105
113
  policy: basePolicy as any,
106
114
  worktreePath: tempRoot,
107
115
  logDirectory: path.join(tempRoot, 'logs'),
108
- evidenceDirectory: path.join(tempRoot, 'evidence')
109
- })
116
+ evidenceDirectory: path.join(tempRoot, 'evidence'),
117
+ }),
110
118
  ).rejects.toThrow('unknown_gate_profile_or_mode:default/fast');
111
119
  });
112
120
 
@@ -117,14 +125,14 @@ describe('gates helpers', () => {
117
125
  signal: null,
118
126
  stdout: '',
119
127
  stderr: 'timeout',
120
- timeout: false
128
+ timeout: false,
121
129
  })
122
130
  .mockResolvedValueOnce({
123
131
  code: 0,
124
132
  signal: null,
125
133
  stdout: 'ok',
126
134
  stderr: '',
127
- timeout: false
135
+ timeout: false,
128
136
  });
129
137
 
130
138
  const result = await runGateMode({
@@ -138,16 +146,16 @@ describe('gates helpers', () => {
138
146
  name: 'lint',
139
147
  cmd: ['npm', 'run', 'lint'],
140
148
  env: { EXTRA: '1' },
141
- timeout_seconds: 2
142
- }
143
- ]
149
+ timeout_seconds: 2,
150
+ },
151
+ ],
144
152
  },
145
- parsers: { coverage: { type: 'none' } }
153
+ parsers: { coverage: { type: 'none' } },
146
154
  },
147
155
  policy: basePolicy as any,
148
156
  worktreePath: tempRoot,
149
157
  logDirectory: path.join(tempRoot, 'logs'),
150
- evidenceDirectory: path.join(tempRoot, 'evidence')
158
+ evidenceDirectory: path.join(tempRoot, 'evidence'),
151
159
  });
152
160
 
153
161
  expect(result.overall).toBe('pass');
@@ -157,8 +165,8 @@ describe('gates helpers', () => {
157
165
  name: 'lint',
158
166
  attempts: 2,
159
167
  exit_code: 0,
160
- timeout: false
161
- })
168
+ timeout: false,
169
+ }),
162
170
  ]);
163
171
  expect(runCommandMock).toHaveBeenCalledTimes(2);
164
172
 
@@ -166,7 +174,7 @@ describe('gates helpers', () => {
166
174
  expect(firstCallOptions.timeoutMs).toBe(2000);
167
175
  expect(firstCallOptions.env).toMatchObject({
168
176
  TEST_ALLOWED_ENV: 'allowed-value',
169
- EXTRA: '1'
177
+ EXTRA: '1',
170
178
  });
171
179
 
172
180
  await expect(fs.stat(result.evidence_path as string)).resolves.toBeTruthy();
@@ -179,7 +187,7 @@ describe('gates helpers', () => {
179
187
  signal: null,
180
188
  stdout: '',
181
189
  stderr: 'bad command',
182
- timeout: false
190
+ timeout: false,
183
191
  });
184
192
 
185
193
  const result = await runGateMode({
@@ -188,21 +196,21 @@ describe('gates helpers', () => {
188
196
  profileName: 'default',
189
197
  profile: {
190
198
  modes: {
191
- fast: [{ name: 'lint', cmd: ['npm', 'run', 'lint'] }]
192
- }
199
+ fast: [{ name: 'lint', cmd: ['npm', 'run', 'lint'] }],
200
+ },
193
201
  },
194
202
  policy: basePolicy as any,
195
203
  worktreePath: tempRoot,
196
204
  logDirectory: path.join(tempRoot, 'logs'),
197
- evidenceDirectory: path.join(tempRoot, 'evidence')
205
+ evidenceDirectory: path.join(tempRoot, 'evidence'),
198
206
  });
199
207
 
200
208
  expect(result.overall).toBe('fail');
201
209
  expect(result.step_results).toEqual([
202
210
  expect.objectContaining({
203
211
  attempts: 1,
204
- exit_code: 2
205
- })
212
+ exit_code: 2,
213
+ }),
206
214
  ]);
207
215
  expect(runCommandMock).toHaveBeenCalledTimes(1);
208
216
  });
@@ -213,7 +221,7 @@ describe('gates helpers', () => {
213
221
  signal: null,
214
222
  stdout: '',
215
223
  stderr: 'timeout',
216
- timeout: true
224
+ timeout: true,
217
225
  });
218
226
 
219
227
  const timeoutResult = await runGateMode({
@@ -222,13 +230,13 @@ describe('gates helpers', () => {
222
230
  profileName: 'default',
223
231
  profile: {
224
232
  modes: {
225
- fast: [{ name: 'lint', cmd: ['npm', 'run', 'lint'] }]
226
- }
233
+ fast: [{ name: 'lint', cmd: ['npm', 'run', 'lint'] }],
234
+ },
227
235
  },
228
236
  policy: basePolicy as any,
229
237
  worktreePath: tempRoot,
230
238
  logDirectory: path.join(tempRoot, 'logs'),
231
- evidenceDirectory: path.join(tempRoot, 'evidence')
239
+ evidenceDirectory: path.join(tempRoot, 'evidence'),
232
240
  });
233
241
 
234
242
  expect(timeoutResult.overall).toBe('fail');
@@ -241,14 +249,14 @@ describe('gates helpers', () => {
241
249
  signal: null,
242
250
  stdout: '',
243
251
  stderr: 'timeout',
244
- timeout: false
252
+ timeout: false,
245
253
  })
246
254
  .mockResolvedValueOnce({
247
255
  code: 124,
248
256
  signal: null,
249
257
  stdout: '',
250
258
  stderr: 'timeout',
251
- timeout: false
259
+ timeout: false,
252
260
  });
253
261
 
254
262
  const exhaustedRetries = await runGateMode({
@@ -257,13 +265,13 @@ describe('gates helpers', () => {
257
265
  profileName: 'default',
258
266
  profile: {
259
267
  modes: {
260
- fast: [{ name: 'lint', cmd: ['npm', 'run', 'lint'] }]
261
- }
268
+ fast: [{ name: 'lint', cmd: ['npm', 'run', 'lint'] }],
269
+ },
262
270
  },
263
271
  policy: basePolicy as any,
264
272
  worktreePath: tempRoot,
265
273
  logDirectory: path.join(tempRoot, 'logs'),
266
- evidenceDirectory: path.join(tempRoot, 'evidence')
274
+ evidenceDirectory: path.join(tempRoot, 'evidence'),
267
275
  });
268
276
 
269
277
  expect(exhaustedRetries.overall).toBe('fail');
@@ -276,7 +284,7 @@ describe('gates helpers', () => {
276
284
  signal: null,
277
285
  stdout: 'ok',
278
286
  stderr: '',
279
- timeout: false
287
+ timeout: false,
280
288
  });
281
289
 
282
290
  const missingCoverage = await runGateMode({
@@ -285,14 +293,14 @@ describe('gates helpers', () => {
285
293
  profileName: 'default',
286
294
  profile: {
287
295
  modes: {
288
- full: [{ name: 'tests', cmd: ['npm', 'test'] }]
296
+ full: [{ name: 'tests', cmd: ['npm', 'test'] }],
289
297
  },
290
- parsers: { coverage: { type: 'lcov', path: 'missing/lcov.info' } }
298
+ parsers: { coverage: { type: 'lcov', path: 'missing/lcov.info' } },
291
299
  },
292
300
  policy: basePolicy as any,
293
301
  worktreePath: tempRoot,
294
302
  logDirectory: path.join(tempRoot, 'logs'),
295
- evidenceDirectory: path.join(tempRoot, 'evidence')
303
+ evidenceDirectory: path.join(tempRoot, 'evidence'),
296
304
  });
297
305
  expect(missingCoverage.overall).toBe('pass');
298
306
  expect(missingCoverage.coverage_status).toBe('na');
@@ -302,7 +310,7 @@ describe('gates helpers', () => {
302
310
  await fs.writeFile(
303
311
  path.join(coverageDir, 'lcov.info'),
304
312
  ['TN:', 'SF:src/a.ts', 'LF:20', 'LH:20', 'BRF:10', 'BRH:10', 'end_of_record', ''].join('\n'),
305
- 'utf8'
313
+ 'utf8',
306
314
  );
307
315
 
308
316
  const highCoverage = await runGateMode({
@@ -311,24 +319,24 @@ describe('gates helpers', () => {
311
319
  profileName: 'default',
312
320
  profile: {
313
321
  modes: {
314
- full: [{ name: 'tests', cmd: ['npm', 'test'] }]
322
+ full: [{ name: 'tests', cmd: ['npm', 'test'] }],
315
323
  },
316
324
  parsers: { coverage: { type: 'lcov', path: 'coverage-pass/lcov.info' } },
317
325
  thresholds: {
318
326
  coverage_line_min: 0.5,
319
- coverage_branch_min: 0.5
320
- }
327
+ coverage_branch_min: 0.5,
328
+ },
321
329
  },
322
330
  policy: basePolicy as any,
323
331
  worktreePath: tempRoot,
324
332
  logDirectory: path.join(tempRoot, 'logs'),
325
- evidenceDirectory: path.join(tempRoot, 'evidence')
333
+ evidenceDirectory: path.join(tempRoot, 'evidence'),
326
334
  });
327
335
  expect(highCoverage.overall).toBe('pass');
328
336
  expect(highCoverage.coverage_status).toBe('pass');
329
337
  expect(highCoverage.thresholds).toMatchObject({
330
338
  coverage_line_min: 0.9,
331
- coverage_branch_min: 0.9
339
+ coverage_branch_min: 0.9,
332
340
  });
333
341
  });
334
342
 
@@ -338,7 +346,7 @@ describe('gates helpers', () => {
338
346
  await fs.writeFile(
339
347
  path.join(coverageDir, 'lcov.info'),
340
348
  ['TN:', 'SF:src/a.ts', 'LF:20', 'LH:10', 'BRF:10', 'BRH:3', 'end_of_record', ''].join('\n'),
341
- 'utf8'
349
+ 'utf8',
342
350
  );
343
351
 
344
352
  runCommandMock.mockResolvedValue({
@@ -346,7 +354,7 @@ describe('gates helpers', () => {
346
354
  signal: null,
347
355
  stdout: 'ok',
348
356
  stderr: '',
349
- timeout: false
357
+ timeout: false,
350
358
  });
351
359
 
352
360
  const result = await runGateMode({
@@ -355,21 +363,21 @@ describe('gates helpers', () => {
355
363
  profileName: 'default',
356
364
  profile: {
357
365
  modes: {
358
- full: [{ name: 'tests', cmd: ['npm', 'test'] }]
366
+ full: [{ name: 'tests', cmd: ['npm', 'test'] }],
359
367
  },
360
- parsers: { coverage: { type: 'lcov', path: 'coverage/lcov.info' } }
368
+ parsers: { coverage: { type: 'lcov', path: 'coverage/lcov.info' } },
361
369
  },
362
370
  policy: basePolicy as any,
363
371
  worktreePath: tempRoot,
364
372
  logDirectory: path.join(tempRoot, 'logs'),
365
- evidenceDirectory: path.join(tempRoot, 'evidence')
373
+ evidenceDirectory: path.join(tempRoot, 'evidence'),
366
374
  });
367
375
 
368
376
  expect(result.overall).toBe('fail');
369
377
  expect(result.coverage_status).toBe('fail');
370
378
  expect(result.coverage).toMatchObject({
371
379
  line: 0.5,
372
- branch: 0.3
380
+ branch: 0.3,
373
381
  });
374
382
 
375
383
  const latest = JSON.parse(await fs.readFile(result.latest_path as string, 'utf8'));
@@ -377,34 +385,46 @@ describe('gates helpers', () => {
377
385
  line: 0.5,
378
386
  branch: 0.3,
379
387
  min_line: 0.9,
380
- min_branch: 0.9
388
+ min_branch: 0.9,
381
389
  });
382
390
  });
383
391
 
384
392
  it('GIVEN_sparse_coverage_artifacts_WHEN_parsing_THEN_uses_safe_default_metrics', async () => {
385
- await fs.writeFile(path.join(tempRoot, 'lcov-empty.info'), 'TN:\nSF:src/a.ts\nend_of_record\n', 'utf8');
393
+ await fs.writeFile(
394
+ path.join(tempRoot, 'lcov-empty.info'),
395
+ 'TN:\nSF:src/a.ts\nend_of_record\n',
396
+ 'utf8',
397
+ );
386
398
  await fs.writeFile(path.join(tempRoot, 'junit-empty.xml'), '<testsuite></testsuite>', 'utf8');
387
399
  await fs.writeFile(path.join(tempRoot, 'jacoco-empty.xml'), '<report></report>', 'utf8');
388
400
  await fs.writeFile(path.join(tempRoot, 'cobertura-empty.xml'), '<coverage></coverage>', 'utf8');
389
401
 
390
- await expect(parseCoverage({ type: 'lcov', path: 'lcov-empty.info' }, tempRoot)).resolves.toMatchObject({
402
+ await expect(
403
+ parseCoverage({ type: 'lcov', path: 'lcov-empty.info' }, tempRoot),
404
+ ).resolves.toMatchObject({
391
405
  line: 1,
392
406
  branch: 1,
393
- details: { linesFound: 0, linesHit: 0, branchesFound: 0, branchesHit: 0 }
407
+ details: { linesFound: 0, linesHit: 0, branchesFound: 0, branchesHit: 0 },
394
408
  });
395
- await expect(parseCoverage({ type: 'junit_xml', path: 'junit-empty.xml' }, tempRoot)).resolves.toMatchObject({
409
+ await expect(
410
+ parseCoverage({ type: 'junit_xml', path: 'junit-empty.xml' }, tempRoot),
411
+ ).resolves.toMatchObject({
396
412
  line: 1,
397
- branch: 1
413
+ branch: 1,
398
414
  });
399
- await expect(parseCoverage({ type: 'jacoco_xml', path: 'jacoco-empty.xml' }, tempRoot)).resolves.toMatchObject({
415
+ await expect(
416
+ parseCoverage({ type: 'jacoco_xml', path: 'jacoco-empty.xml' }, tempRoot),
417
+ ).resolves.toMatchObject({
400
418
  line: 1,
401
419
  branch: 1,
402
- details: { lineMissed: 0, lineCovered: 0, branchMissed: 0, branchCovered: 0 }
420
+ details: { lineMissed: 0, lineCovered: 0, branchMissed: 0, branchCovered: 0 },
403
421
  });
404
- await expect(parseCoverage({ type: 'cobertura_xml', path: 'cobertura-empty.xml' }, tempRoot)).resolves.toMatchObject({
422
+ await expect(
423
+ parseCoverage({ type: 'cobertura_xml', path: 'cobertura-empty.xml' }, tempRoot),
424
+ ).resolves.toMatchObject({
405
425
  line: 1,
406
426
  branch: 1,
407
- details: { lineRate: 1, branchRate: 1 }
427
+ details: { lineRate: 1, branchRate: 1 },
408
428
  });
409
429
  });
410
430
 
@@ -413,11 +433,11 @@ describe('gates helpers', () => {
413
433
  await fs.writeFile(
414
434
  standaloneLcov,
415
435
  ['TN:', 'SF:src/a.ts', 'LF:2', 'LH:1', 'BRF:2', 'BRH:1', 'end_of_record', ''].join('\n'),
416
- 'utf8'
436
+ 'utf8',
417
437
  );
418
438
  await expect(parseCoverage({ type: 'lcov' }, standaloneLcov)).resolves.toMatchObject({
419
439
  line: 0.5,
420
- branch: 0.5
440
+ branch: 0.5,
421
441
  });
422
442
 
423
443
  runCommandMock.mockResolvedValue({
@@ -425,7 +445,7 @@ describe('gates helpers', () => {
425
445
  signal: null,
426
446
  stdout: 'ok',
427
447
  stderr: '',
428
- timeout: false
448
+ timeout: false,
429
449
  });
430
450
 
431
451
  const result = await runGateMode({
@@ -434,19 +454,19 @@ describe('gates helpers', () => {
434
454
  profileName: 'default',
435
455
  profile: {
436
456
  modes: {
437
- fast: [{ name: 'lint', cmd: ['npm', 'run', 'lint'], cwd: 'packages/app' }]
457
+ fast: [{ name: 'lint', cmd: ['npm', 'run', 'lint'], cwd: 'packages/app' }],
438
458
  },
439
- parsers: { coverage: { type: 'none' } }
459
+ parsers: { coverage: { type: 'none' } },
440
460
  },
441
461
  policy: basePolicy as any,
442
462
  worktreePath: tempRoot,
443
463
  logDirectory: path.join(tempRoot, 'logs'),
444
- evidenceDirectory: path.join(tempRoot, 'evidence')
464
+ evidenceDirectory: path.join(tempRoot, 'evidence'),
445
465
  });
446
466
 
447
467
  expect(result.overall).toBe('pass');
448
468
  expect(runCommandMock.mock.calls[0]?.[2]).toMatchObject({
449
- cwd: path.join(tempRoot, 'packages/app')
469
+ cwd: path.join(tempRoot, 'packages/app'),
450
470
  });
451
471
  });
452
472
  });
@@ -7,7 +7,7 @@ vi.mock('node:child_process', async (importOriginal) => {
7
7
  ...actual,
8
8
  spawn: vi.fn().mockImplementationOnce(() => {
9
9
  throw new Error('spawn sync error');
10
- })
10
+ }),
11
11
  };
12
12
  });
13
13
 
@@ -12,7 +12,7 @@ async function copyTemplateSubtree(templateRoot, tempRoot, dirName) {
12
12
  try {
13
13
  await fs.cp(sourceDir, destinationDir, {
14
14
  recursive: true,
15
- filter: (entryPath) => !path.basename(entryPath).startsWith('.tmp-tools.md-')
15
+ filter: (entryPath) => !path.basename(entryPath).startsWith('.tmp-tools.md-'),
16
16
  });
17
17
  return;
18
18
  } catch (error) {
@@ -63,13 +63,13 @@ export async function makeTempRepo(templateRoot) {
63
63
  last_heartbeat_at: now,
64
64
  lease_expires_at: now,
65
65
  orchestrator_epoch: 0,
66
- feature_sessions: {}
67
- }
66
+ feature_sessions: {},
67
+ },
68
68
  },
69
69
  null,
70
- 2
70
+ 2,
71
71
  )}\n`,
72
- 'utf8'
72
+ 'utf8',
73
73
  );
74
74
 
75
75
  await runCommand('git', ['init', '-b', 'main'], { cwd: tempRoot });
@@ -81,7 +81,11 @@ export async function makeTempRepo(templateRoot) {
81
81
  return tempRoot;
82
82
  }
83
83
 
84
- export async function writeFeatureSpec(repoRoot, featureId, content = '# Spec\n\nBuild something.\n') {
84
+ export async function writeFeatureSpec(
85
+ repoRoot,
86
+ featureId,
87
+ content = '# Spec\n\nBuild something.\n',
88
+ ) {
85
89
  const featureDir = path.join(repoRoot, '.aop', 'features', featureId);
86
90
  await fs.mkdir(featureDir, { recursive: true });
87
91
  await fs.writeFile(path.join(featureDir, 'spec.md'), content, 'utf8');