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
@@ -1,24 +1,47 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { ensureDir, pathExists, readJson, atomicWriteJson, atomicWriteFile, withFileLock, nowIso, stableHash } from './fs.js';
3
+ import {
4
+ ensureDir,
5
+ pathExists,
6
+ readJson,
7
+ atomicWriteJson,
8
+ atomicWriteFile,
9
+ withFileLock,
10
+ nowIso,
11
+ stableHash,
12
+ } from './fs.js';
4
13
  import { SchemaRegistry, loadAndValidateYaml } from './schemas.js';
5
14
  import { normalizeRepoPath } from './path-rules.js';
6
15
  import { parseFrontMatter, buildFrontMatter } from './frontmatter.js';
7
16
  import { runGit, runCommand } from './git.js';
8
17
  import { ERROR_CODES } from './error-codes.js';
9
18
  import { ok, fail, withSuggestedActions, type ToolResponse } from './response.js';
10
- import { ALLOWED_ACTORS, DEFAULT_CLUSTER, DEFAULT_ROLE_STATUS, GATE_RESULT, STATUS, TOOLS } from './constants.js';
19
+ import {
20
+ ALLOWED_ACTORS,
21
+ DEFAULT_CLUSTER,
22
+ DEFAULT_ROLE_STATUS,
23
+ GATE_RESULT,
24
+ STATUS,
25
+ TOOLS,
26
+ } from './constants.js';
11
27
  import { AopPathLayout, ensureAopRuntimeLayout } from './path-layout.js';
12
28
  import {
13
29
  applyWorktreeSymlinks,
14
30
  formatWorkspaceHookWarning,
15
31
  runWorktreePostCreate,
16
- type WorkspaceHookWarning
32
+ type WorkspaceHookWarning,
17
33
  } from './workspace-hooks.js';
18
34
  import type { RuntimeSessionsSnapshot } from './runtime-sessions.js';
19
35
  import { ToolRegistryLoader } from '../mcp/tool-registry-loader.js';
20
- import { ToolHandlerRegistry, ToolRouter, type ToolHandlerContext } from '../application/tools/tool-router.js';
21
- import { RunLeaseService, type AcquireRunLeaseInput } from '../application/services/run-lease-service.js';
36
+ import {
37
+ ToolHandlerRegistry,
38
+ ToolRouter,
39
+ type ToolHandlerContext,
40
+ } from '../application/tools/tool-router.js';
41
+ import {
42
+ RunLeaseService,
43
+ type AcquireRunLeaseInput,
44
+ } from '../application/services/run-lease-service.js';
22
45
  import { LockService } from '../application/services/lock-service.js';
23
46
  import { ReportingService } from '../application/services/reporting-service.js';
24
47
  import { FeatureStateService } from '../application/services/feature-state-service.js';
@@ -29,15 +52,21 @@ import { GateService } from '../application/services/gate-service.js';
29
52
  import { QaIndexService } from '../application/services/qa-index-service.js';
30
53
  import { MergeService } from '../application/services/merge-service.js';
31
54
  import { CollisionQueueService } from '../application/services/collision-queue-service.js';
32
- import { FeatureDeletionService, type FeatureDeleteResult } from '../application/services/feature-deletion-service.js';
55
+ import {
56
+ FeatureDeletionService,
57
+ type FeatureDeleteResult,
58
+ } from '../application/services/feature-deletion-service.js';
33
59
  import { CostTrackingService } from '../application/services/cost-tracking-service.js';
34
- import { PerformanceAnalyticsService, type FeatureOutcome } from '../application/services/performance-analytics-service.js';
60
+ import {
61
+ PerformanceAnalyticsService,
62
+ type FeatureOutcome,
63
+ } from '../application/services/performance-analytics-service.js';
35
64
  import { loadComposedPolicy } from '../application/services/policy-loader-service.js';
36
65
  import {
37
66
  ACTIVITY_DETECTOR_SLOT,
38
67
  NOTIFICATION_CHANNEL_SLOT,
39
68
  SCM_PROVIDER_SLOT,
40
- globalAdapterRegistry
69
+ globalAdapterRegistry,
41
70
  } from '../application/adapters/adapter-registry.js';
42
71
  import type { WorkerProvider } from '../providers/providers.js';
43
72
 
@@ -137,7 +166,11 @@ export class AopKernel {
137
166
  private provider: WorkerProvider | null = null;
138
167
  private readonly configOverrides: KernelConfigOverrides;
139
168
 
140
- constructor(repoRoot: string, instanceId = 'default', configOverrides: KernelConfigOverrides = {}) {
169
+ constructor(
170
+ repoRoot: string,
171
+ instanceId = 'default',
172
+ configOverrides: KernelConfigOverrides = {},
173
+ ) {
141
174
  this.repoRoot = repoRoot;
142
175
  this.instanceId = instanceId;
143
176
  this.configOverrides = configOverrides;
@@ -169,9 +202,9 @@ export class AopKernel {
169
202
  Promise.resolve(
170
203
  fail(ERROR_CODES.INVALID_ARGUMENT, `Unknown tool ${toolName}`, {
171
204
  retryable: false,
172
- requires_human: true
173
- })
174
- )
205
+ requires_human: true,
206
+ }),
207
+ ),
175
208
  );
176
209
  }
177
210
 
@@ -244,7 +277,7 @@ export class AopKernel {
244
277
  last_heartbeat_at: at,
245
278
  lease_expires_at: at,
246
279
  orchestrator_epoch: 0,
247
- feature_sessions: {}
280
+ feature_sessions: {},
248
281
  };
249
282
  }
250
283
 
@@ -267,7 +300,7 @@ export class AopKernel {
267
300
  typeof typed.planner_session_id === 'string' ? typed.planner_session_id : 'unassigned',
268
301
  builder_session_id:
269
302
  typeof typed.builder_session_id === 'string' ? typed.builder_session_id : 'unassigned',
270
- qa_session_id: typeof typed.qa_session_id === 'string' ? typed.qa_session_id : 'unassigned'
303
+ qa_session_id: typeof typed.qa_session_id === 'string' ? typed.qa_session_id : 'unassigned',
271
304
  };
272
305
  }
273
306
 
@@ -282,7 +315,10 @@ export class AopKernel {
282
315
  typeof source.orchestrator_session_id === 'string' && source.orchestrator_session_id
283
316
  ? source.orchestrator_session_id
284
317
  : fallback.orchestrator_session_id,
285
- provider: typeof source.provider === 'string' && source.provider ? source.provider : fallback.provider,
318
+ provider:
319
+ typeof source.provider === 'string' && source.provider
320
+ ? source.provider
321
+ : fallback.provider,
286
322
  model: typeof source.model === 'string' && source.model ? source.model : fallback.model,
287
323
  provider_config_ref_hash:
288
324
  typeof source.provider_config_ref_hash === 'string' && source.provider_config_ref_hash
@@ -292,8 +328,14 @@ export class AopKernel {
292
328
  typeof source.owner_instance_id === 'string' && source.owner_instance_id
293
329
  ? source.owner_instance_id
294
330
  : fallback.owner_instance_id,
295
- lease_id: typeof source.lease_id === 'string' && source.lease_id ? source.lease_id : fallback.lease_id,
296
- started_at: typeof source.started_at === 'string' && source.started_at ? source.started_at : fallback.started_at,
331
+ lease_id:
332
+ typeof source.lease_id === 'string' && source.lease_id
333
+ ? source.lease_id
334
+ : fallback.lease_id,
335
+ started_at:
336
+ typeof source.started_at === 'string' && source.started_at
337
+ ? source.started_at
338
+ : fallback.started_at,
297
339
  last_heartbeat_at:
298
340
  typeof source.last_heartbeat_at === 'string' && source.last_heartbeat_at
299
341
  ? source.last_heartbeat_at
@@ -303,7 +345,7 @@ export class AopKernel {
303
345
  ? source.lease_expires_at
304
346
  : fallback.lease_expires_at,
305
347
  orchestrator_epoch: epoch,
306
- feature_sessions: featureSessions
348
+ feature_sessions: featureSessions,
307
349
  };
308
350
  }
309
351
 
@@ -311,16 +353,29 @@ export class AopKernel {
311
353
  const now = nowIso();
312
354
  const source = value && typeof value === 'object' ? (value as Record<string, unknown>) : {};
313
355
  return {
314
- version: typeof source.version === 'number' && Number.isFinite(source.version) ? Math.max(1, Math.floor(source.version)) : 1,
315
- active: normalizeSet(asArray<string>(source.active).filter((item) => typeof item === 'string')),
316
- blocked: normalizeSet(asArray<string>(source.blocked).filter((item) => typeof item === 'string')),
317
- merged: normalizeSet(asArray<string>(source.merged).filter((item) => typeof item === 'string')),
356
+ version:
357
+ typeof source.version === 'number' && Number.isFinite(source.version)
358
+ ? Math.max(1, Math.floor(source.version))
359
+ : 1,
360
+ active: normalizeSet(
361
+ asArray<string>(source.active).filter((item) => typeof item === 'string'),
362
+ ),
363
+ blocked: normalizeSet(
364
+ asArray<string>(source.blocked).filter((item) => typeof item === 'string'),
365
+ ),
366
+ merged: normalizeSet(
367
+ asArray<string>(source.merged).filter((item) => typeof item === 'string'),
368
+ ),
318
369
  locks: source.locks && typeof source.locks === 'object' ? source.locks : {},
319
- lock_leases: source.lock_leases && typeof source.lock_leases === 'object' ? source.lock_leases : {},
320
- blocked_queue: asArray(source.blocked_queue).filter((item) => item && typeof item === 'object'),
370
+ lock_leases:
371
+ source.lock_leases && typeof source.lock_leases === 'object' ? source.lock_leases : {},
372
+ blocked_queue: asArray(source.blocked_queue).filter(
373
+ (item) => item && typeof item === 'object',
374
+ ),
321
375
  dep_blocked: asArray(source.dep_blocked).filter((item) => item && typeof item === 'object'),
322
- updated_at: typeof source.updated_at === 'string' && source.updated_at ? source.updated_at : now,
323
- runtime_sessions: this.normalizeRuntimeSessions(source.runtime_sessions, now)
376
+ updated_at:
377
+ typeof source.updated_at === 'string' && source.updated_at ? source.updated_at : now,
378
+ runtime_sessions: this.normalizeRuntimeSessions(source.runtime_sessions, now),
324
379
  };
325
380
  }
326
381
 
@@ -332,20 +387,40 @@ export class AopKernel {
332
387
  return expiry > Date.now();
333
388
  }
334
389
 
390
+ private async resolveDefaultConfigPath(fileName: string): Promise<string> {
391
+ const primary = path.join(this.pathLayout.orchestratorRoot, fileName);
392
+ if (await pathExists(primary)) {
393
+ return primary;
394
+ }
395
+ const legacy = path.join(this.pathLayout.legacyOrchestratorRoot, fileName);
396
+ if (await pathExists(legacy)) {
397
+ return legacy;
398
+ }
399
+ return primary;
400
+ }
401
+
335
402
  async load() {
336
403
  await ensureAopRuntimeLayout(this.pathLayout);
337
404
 
338
- const gatesPath = this.configOverrides.gatesPath ?? path.join(this.orchestratorDir, 'gates.yaml');
339
- const policyPath = this.configOverrides.policyPath ?? path.join(this.orchestratorDir, 'policy.yaml');
340
- const agentsPath = this.configOverrides.agentsPath ?? path.join(this.orchestratorDir, 'agents.yaml');
341
- const adaptersPath = this.configOverrides.adaptersPath ?? path.join(this.orchestratorDir, 'adapters.yaml');
405
+ const gatesPath =
406
+ this.configOverrides.gatesPath ?? (await this.resolveDefaultConfigPath('gates.yaml'));
407
+ const policyPath =
408
+ this.configOverrides.policyPath ?? (await this.resolveDefaultConfigPath('policy.yaml'));
409
+ const agentsPath =
410
+ this.configOverrides.agentsPath ?? (await this.resolveDefaultConfigPath('agents.yaml'));
411
+ const adaptersPath =
412
+ this.configOverrides.adaptersPath ?? (await this.resolveDefaultConfigPath('adapters.yaml'));
342
413
 
343
414
  const gates = await loadAndValidateYaml(this.schemaRegistry, 'gates.schema.json', gatesPath);
344
415
  if (!gates.validation.valid) {
345
416
  throw new Error(`invalid_gates_yaml:${JSON.stringify(gates.validation.errors)}`);
346
417
  }
347
418
 
348
- const { mergedPolicy } = await loadComposedPolicy(this.repoRoot, policyPath, this.schemaRegistry);
419
+ const { mergedPolicy } = await loadComposedPolicy(
420
+ this.repoRoot,
421
+ policyPath,
422
+ this.schemaRegistry,
423
+ );
349
424
  const parsedPolicy = mergedPolicy as PolicyConfigSnapshot;
350
425
  const implementation = readObjectField(parsedPolicy, 'implementation');
351
426
  const testing = readObjectField(parsedPolicy, 'testing');
@@ -369,7 +444,11 @@ export class AopKernel {
369
444
  const adaptersExists = await pathExists(adaptersPath);
370
445
  let adapters = { parsed: {}, validation: { valid: true, errors: [] as unknown[] } };
371
446
  if (adaptersExists) {
372
- adapters = await loadAndValidateYaml(this.schemaRegistry, 'adapters.schema.json', adaptersPath);
447
+ adapters = await loadAndValidateYaml(
448
+ this.schemaRegistry,
449
+ 'adapters.schema.json',
450
+ adaptersPath,
451
+ );
373
452
  if (!adapters.validation.valid) {
374
453
  throw new Error(`invalid_adapters_yaml:${JSON.stringify(adapters.validation.errors)}`);
375
454
  }
@@ -379,7 +458,9 @@ export class AopKernel {
379
458
  try {
380
459
  globalAdapterRegistry.resolve(NOTIFICATION_CHANNEL_SLOT, notificationChannel, {});
381
460
  } catch {
382
- throw new Error(`adapter_not_found:${NOTIFICATION_CHANNEL_SLOT.name}:${notificationChannel}`);
461
+ throw new Error(
462
+ `adapter_not_found:${NOTIFICATION_CHANNEL_SLOT.name}:${notificationChannel}`,
463
+ );
383
464
  }
384
465
  }
385
466
  const activityDetector = readStringField(parsedAdapters, ACTIVITY_DETECTOR_SLOT.name);
@@ -427,7 +508,11 @@ export class AopKernel {
427
508
  return allowedTools.includes(toolName);
428
509
  }
429
510
 
430
- async invoke(toolName: string, args: AnyRecord = {}, context: KernelContext = {}): Promise<AnyRecord> {
511
+ async invoke(
512
+ toolName: string,
513
+ args: AnyRecord = {},
514
+ context: KernelContext = {},
515
+ ): Promise<AnyRecord> {
431
516
  await this.ensureLoaded();
432
517
  const actorType = context.actor_type ?? 'system';
433
518
  const actorId = context.actor_id ?? 'system';
@@ -436,7 +521,10 @@ export class AopKernel {
436
521
  return fail(
437
522
  ERROR_CODES.FORBIDDEN_TOOL_FOR_ROLE,
438
523
  `Tool ${toolName} is not allowed for role ${actorType}`,
439
- withSuggestedActions({ actor_type: actorType, tool_name: toolName, retryable: false, requires_human: true }, ['Use orchestrator role for this operation'])
524
+ withSuggestedActions(
525
+ { actor_type: actorType, tool_name: toolName, retryable: false, requires_human: true },
526
+ ['Use orchestrator role for this operation'],
527
+ ),
440
528
  );
441
529
  }
442
530
 
@@ -466,14 +554,14 @@ export class AopKernel {
466
554
  if (text.startsWith('path_out_of_bounds')) {
467
555
  return fail(ERROR_CODES.PATH_OUT_OF_BOUNDS, 'Path escapes repository root', {
468
556
  retryable: false,
469
- requires_human: true
557
+ requires_human: true,
470
558
  });
471
559
  }
472
560
 
473
561
  if (text.startsWith('lock_timeout:')) {
474
562
  return fail(ERROR_CODES.LOCK_CONFLICT, 'Timed out waiting for lock', {
475
563
  retryable: true,
476
- requires_human: false
564
+ requires_human: false,
477
565
  });
478
566
  }
479
567
 
@@ -481,7 +569,7 @@ export class AopKernel {
481
569
  return fail(ERROR_CODES.UNKNOWN_GATE_PROFILE_OR_MODE, 'Unknown gate profile or mode', {
482
570
  value: text.split(':')[1],
483
571
  retryable: false,
484
- requires_human: true
572
+ requires_human: true,
485
573
  });
486
574
  }
487
575
 
@@ -489,140 +577,234 @@ export class AopKernel {
489
577
  return fail(ERROR_CODES.UNSUPPORTED_PARSER, 'Gate parser type is not supported', {
490
578
  parser: text.split(':')[1],
491
579
  retryable: false,
492
- requires_human: true
580
+ requires_human: true,
493
581
  });
494
582
  }
495
583
 
496
584
  if (text.includes('qa_index_version_conflict')) {
497
- return fail(ERROR_CODES.QA_INDEX_VERSION_CONFLICT, 'QA index expected_version did not match current version', {
498
- retryable: true,
499
- requires_human: false
500
- });
585
+ return fail(
586
+ ERROR_CODES.QA_INDEX_VERSION_CONFLICT,
587
+ 'QA index expected_version did not match current version',
588
+ {
589
+ retryable: true,
590
+ requires_human: false,
591
+ },
592
+ );
501
593
  }
502
594
 
503
595
  return fail(ERROR_CODES.INTERNAL_ERROR, text, {
504
596
  retryable: false,
505
- requires_human: true
597
+ requires_human: true,
506
598
  });
507
599
  }
508
600
 
509
- async dispatchTool(toolName: string, args: AnyRecord, context: ToolHandlerContext): Promise<unknown> {
601
+ async dispatchTool(
602
+ toolName: string,
603
+ args: AnyRecord,
604
+ context: ToolHandlerContext,
605
+ ): Promise<unknown> {
510
606
  return await this.toolRouter.route(toolName, args, context);
511
607
  }
512
608
 
513
609
  private registerToolHandlers(): void {
514
- this.toolHandlers.register(TOOLS.FEATURE_DISCOVER_SPECS, async () => await this.featureDiscoverSpecs());
515
- this.toolHandlers.register(TOOLS.FEATURE_INIT, async (args) => await this.featureInit(readStringField(args, 'feature_id')));
516
- this.toolHandlers.register(TOOLS.FEATURE_GET_CONTEXT, async (args) =>
517
- await this.featureGetContext(readStringField(args, 'feature_id'))
610
+ this.toolHandlers.register(
611
+ TOOLS.FEATURE_DISCOVER_SPECS,
612
+ async () => await this.featureDiscoverSpecs(),
518
613
  );
519
- this.toolHandlers.register(TOOLS.FEATURE_STATE_GET, async (args) =>
520
- await this.featureStateGet(readStringField(args, 'feature_id'))
614
+ this.toolHandlers.register(
615
+ TOOLS.FEATURE_INIT,
616
+ async (args) => await this.featureInit(readStringField(args, 'feature_id')),
521
617
  );
522
- this.toolHandlers.register(TOOLS.FEATURE_STATE_PATCH, async (args) =>
523
- await this.featureStatePatch(
524
- readStringField(args, 'feature_id'),
525
- readNumberField(args, 'expected_version'),
526
- args.patch
527
- )
618
+ this.toolHandlers.register(
619
+ TOOLS.FEATURE_GET_CONTEXT,
620
+ async (args) => await this.featureGetContext(readStringField(args, 'feature_id')),
528
621
  );
529
- this.toolHandlers.register(TOOLS.FEATURE_LOG_APPEND, async (args, context) =>
530
- await this.featureLogAppend(readStringField(args, 'feature_id'), readStringField(args, 'note'), context)
622
+ this.toolHandlers.register(
623
+ TOOLS.FEATURE_STATE_GET,
624
+ async (args) => await this.featureStateGet(readStringField(args, 'feature_id')),
531
625
  );
532
- this.toolHandlers.register(TOOLS.PLAN_SUBMIT, async (args) =>
533
- await this.planSubmit(readStringField(args, 'feature_id'), args.plan_json, readNumberField(args, 'expected_version'))
626
+ this.toolHandlers.register(
627
+ TOOLS.FEATURE_STATE_PATCH,
628
+ async (args) =>
629
+ await this.featureStatePatch(
630
+ readStringField(args, 'feature_id'),
631
+ readNumberField(args, 'expected_version'),
632
+ args.patch,
633
+ ),
534
634
  );
535
- this.toolHandlers.register(TOOLS.PLAN_GET, async (args) => await this.planGet(readStringField(args, 'feature_id')));
536
- this.toolHandlers.register(TOOLS.PLAN_UPDATE, async (args) =>
537
- await this.planUpdate(readStringField(args, 'feature_id'), readNumberField(args, 'expected_plan_version'), args.plan_json)
635
+ this.toolHandlers.register(
636
+ TOOLS.FEATURE_LOG_APPEND,
637
+ async (args, context) =>
638
+ await this.featureLogAppend(
639
+ readStringField(args, 'feature_id'),
640
+ readStringField(args, 'note'),
641
+ context,
642
+ ),
538
643
  );
539
- this.toolHandlers.register(TOOLS.REPO_ENSURE_WORKTREE, async (args) =>
540
- await this.repoEnsureWorktree(readStringField(args, 'feature_id'))
644
+ this.toolHandlers.register(
645
+ TOOLS.PLAN_SUBMIT,
646
+ async (args) =>
647
+ await this.planSubmit(
648
+ readStringField(args, 'feature_id'),
649
+ args.plan_json,
650
+ readNumberField(args, 'expected_version'),
651
+ ),
541
652
  );
542
- this.toolHandlers.register(TOOLS.REPO_APPLY_PATCH, async (args) =>
543
- await this.repoApplyPatch(readStringField(args, 'feature_id'), readStringField(args, 'unified_diff'))
653
+ this.toolHandlers.register(
654
+ TOOLS.PLAN_GET,
655
+ async (args) => await this.planGet(readStringField(args, 'feature_id')),
544
656
  );
545
- this.toolHandlers.register(TOOLS.REPO_STATUS, async (args) => await this.repoStatus(readStringField(args, 'feature_id')));
546
- this.toolHandlers.register(TOOLS.REPO_DIFF, async (args) =>
547
- await this.repoDiff(readStringField(args, 'feature_id'), asArray<string>(args.options))
657
+ this.toolHandlers.register(
658
+ TOOLS.PLAN_UPDATE,
659
+ async (args) =>
660
+ await this.planUpdate(
661
+ readStringField(args, 'feature_id'),
662
+ readNumberField(args, 'expected_plan_version'),
663
+ args.plan_json,
664
+ ),
548
665
  );
549
- this.toolHandlers.register(TOOLS.REPO_READ_FILE, async (args) =>
550
- await this.repoReadFile(readStringField(args, 'feature_id'), readStringField(args, 'path'))
666
+ this.toolHandlers.register(
667
+ TOOLS.REPO_ENSURE_WORKTREE,
668
+ async (args) => await this.repoEnsureWorktree(readStringField(args, 'feature_id')),
551
669
  );
552
- this.toolHandlers.register(TOOLS.REPO_SEARCH, async (args) =>
553
- await this.repoSearch(readStringField(args, 'feature_id'), readStringField(args, 'query'))
670
+ this.toolHandlers.register(
671
+ TOOLS.REPO_APPLY_PATCH,
672
+ async (args) =>
673
+ await this.repoApplyPatch(
674
+ readStringField(args, 'feature_id'),
675
+ readStringField(args, 'unified_diff'),
676
+ ),
554
677
  );
555
- this.toolHandlers.register(TOOLS.REPO_DIFF_BUNDLE, async (args) =>
556
- await this.repoDiffBundle(readStringField(args, 'feature_id'))
678
+ this.toolHandlers.register(
679
+ TOOLS.REPO_STATUS,
680
+ async (args) => await this.repoStatus(readStringField(args, 'feature_id')),
557
681
  );
558
- this.toolHandlers.register(TOOLS.FEATURE_READY_TO_MERGE, async (args) =>
559
- await this.featureReadyToMerge(
560
- readStringField(args, 'feature_id'),
561
- readStringField(args, 'commit_message'),
562
- readStringField(args, 'merge_strategy'),
563
- readStringField(args, 'user_approval_token')
564
- )
682
+ this.toolHandlers.register(
683
+ TOOLS.REPO_DIFF,
684
+ async (args) =>
685
+ await this.repoDiff(readStringField(args, 'feature_id'), asArray<string>(args.options)),
565
686
  );
566
- this.toolHandlers.register(TOOLS.FEATURE_DELETE, async (args) =>
567
- await this.featureDelete(
568
- readStringField(args, 'feature_id'),
569
- readBooleanField(args, 'dry_run'),
570
- readBooleanField(args, 'confirm'),
571
- readBooleanField(args, 'remove_worktree'),
572
- readStringField(args, 'remove_branch')
573
- )
687
+ this.toolHandlers.register(
688
+ TOOLS.REPO_READ_FILE,
689
+ async (args) =>
690
+ await this.repoReadFile(readStringField(args, 'feature_id'), readStringField(args, 'path')),
574
691
  );
575
- this.toolHandlers.register(TOOLS.GATES_LIST, async (args) => await this.gatesList(readStringField(args, 'profile')));
576
- this.toolHandlers.register(TOOLS.GATES_RUN, async (args) =>
577
- await this.gatesRun(readStringField(args, 'feature_id'), readStringField(args, 'profile'), readStringField(args, 'mode'))
692
+ this.toolHandlers.register(
693
+ TOOLS.REPO_SEARCH,
694
+ async (args) =>
695
+ await this.repoSearch(readStringField(args, 'feature_id'), readStringField(args, 'query')),
578
696
  );
579
- this.toolHandlers.register(TOOLS.EVIDENCE_LATEST, async (args) =>
580
- await this.evidenceLatest(readStringField(args, 'feature_id'))
697
+ this.toolHandlers.register(
698
+ TOOLS.REPO_DIFF_BUNDLE,
699
+ async (args) => await this.repoDiffBundle(readStringField(args, 'feature_id')),
581
700
  );
582
- this.toolHandlers.register(TOOLS.QA_TEST_INDEX_GET, async (args) =>
583
- await this.qaTestIndexGet(readStringField(args, 'feature_id'))
701
+ this.toolHandlers.register(
702
+ TOOLS.FEATURE_READY_TO_MERGE,
703
+ async (args) =>
704
+ await this.featureReadyToMerge(
705
+ readStringField(args, 'feature_id'),
706
+ readStringField(args, 'commit_message'),
707
+ readStringField(args, 'merge_strategy'),
708
+ readStringField(args, 'user_approval_token'),
709
+ ),
584
710
  );
585
- this.toolHandlers.register(TOOLS.QA_TEST_INDEX_UPDATE, async (args) =>
586
- await this.qaTestIndexUpdate(
587
- readStringField(args, 'feature_id'),
588
- readNumberField(args, 'expected_version'),
589
- args.updates,
590
- asArray(args.evidence_refs)
591
- )
711
+ this.toolHandlers.register(
712
+ TOOLS.FEATURE_DELETE,
713
+ async (args) =>
714
+ await this.featureDelete(
715
+ readStringField(args, 'feature_id'),
716
+ readBooleanField(args, 'dry_run'),
717
+ readBooleanField(args, 'confirm'),
718
+ readBooleanField(args, 'remove_worktree'),
719
+ readStringField(args, 'remove_branch'),
720
+ ),
592
721
  );
593
- this.toolHandlers.register(TOOLS.LOCKS_ACQUIRE, async (args) =>
594
- await this.locksAcquire(
595
- readStringField(args, 'resource'),
596
- readStringField(args, 'feature_id'),
597
- readNumberField(args, 'wait_timeout_seconds')
598
- )
722
+ this.toolHandlers.register(
723
+ TOOLS.GATES_LIST,
724
+ async (args) => await this.gatesList(readStringField(args, 'profile')),
599
725
  );
600
- this.toolHandlers.register(TOOLS.LOCKS_RELEASE, async (args) =>
601
- await this.locksRelease(readStringField(args, 'resource'), readStringField(args, 'feature_id'))
726
+ this.toolHandlers.register(
727
+ TOOLS.GATES_RUN,
728
+ async (args) =>
729
+ await this.gatesRun(
730
+ readStringField(args, 'feature_id'),
731
+ readStringField(args, 'profile'),
732
+ readStringField(args, 'mode'),
733
+ ),
734
+ );
735
+ this.toolHandlers.register(
736
+ TOOLS.EVIDENCE_LATEST,
737
+ async (args) => await this.evidenceLatest(readStringField(args, 'feature_id')),
738
+ );
739
+ this.toolHandlers.register(
740
+ TOOLS.QA_TEST_INDEX_GET,
741
+ async (args) => await this.qaTestIndexGet(readStringField(args, 'feature_id')),
742
+ );
743
+ this.toolHandlers.register(
744
+ TOOLS.QA_TEST_INDEX_UPDATE,
745
+ async (args) =>
746
+ await this.qaTestIndexUpdate(
747
+ readStringField(args, 'feature_id'),
748
+ readNumberField(args, 'expected_version'),
749
+ args.updates,
750
+ asArray(args.evidence_refs),
751
+ ),
752
+ );
753
+ this.toolHandlers.register(
754
+ TOOLS.LOCKS_ACQUIRE,
755
+ async (args) =>
756
+ await this.locksAcquire(
757
+ readStringField(args, 'resource'),
758
+ readStringField(args, 'feature_id'),
759
+ readNumberField(args, 'wait_timeout_seconds'),
760
+ ),
761
+ );
762
+ this.toolHandlers.register(
763
+ TOOLS.LOCKS_RELEASE,
764
+ async (args) =>
765
+ await this.locksRelease(
766
+ readStringField(args, 'resource'),
767
+ readStringField(args, 'feature_id'),
768
+ ),
602
769
  );
603
770
  this.toolHandlers.register(TOOLS.COLLISIONS_SCAN, async () => await this.collisionsScan());
604
771
  this.toolHandlers.register(TOOLS.REPORT_DASHBOARD, async () => await this.reportDashboard());
605
- this.toolHandlers.register(TOOLS.REPORT_FEATURE_SUMMARY, async (args) =>
606
- await this.reportFeatureSummary(readStringField(args, 'feature_id'))
772
+ this.toolHandlers.register(
773
+ TOOLS.REPORT_FEATURE_SUMMARY,
774
+ async (args) => await this.reportFeatureSummary(readStringField(args, 'feature_id')),
607
775
  );
608
- this.toolHandlers.register(TOOLS.FEATURE_SEND_MESSAGE, async (args) =>
609
- await this.featureSendMessage(readStringField(args, 'feature_id'), readStringField(args, 'message'))
776
+ this.toolHandlers.register(
777
+ TOOLS.FEATURE_SEND_MESSAGE,
778
+ async (args) =>
779
+ await this.featureSendMessage(
780
+ readStringField(args, 'feature_id'),
781
+ readStringField(args, 'message'),
782
+ ),
610
783
  );
611
- this.toolHandlers.register(TOOLS.COST_RECORD, async (args) =>
612
- await this.costRecord(
613
- readStringField(args, 'feature_id'),
614
- typeof args.tokens_used_delta === 'number' ? args.tokens_used_delta : 0,
615
- typeof args.estimated_cost_usd_delta === 'number' ? args.estimated_cost_usd_delta : 0
616
- )
784
+ this.toolHandlers.register(
785
+ TOOLS.COST_RECORD,
786
+ async (args) =>
787
+ await this.costRecord(
788
+ readStringField(args, 'feature_id'),
789
+ typeof args.tokens_used_delta === 'number' ? args.tokens_used_delta : 0,
790
+ typeof args.estimated_cost_usd_delta === 'number' ? args.estimated_cost_usd_delta : 0,
791
+ ),
617
792
  );
618
- this.toolHandlers.register(TOOLS.COST_GET, async (args) =>
619
- await this.costGet(readStringField(args, 'feature_id'))
793
+ this.toolHandlers.register(
794
+ TOOLS.COST_GET,
795
+ async (args) => await this.costGet(readStringField(args, 'feature_id')),
620
796
  );
621
- this.toolHandlers.register(TOOLS.PERFORMANCE_RECORD_OUTCOME, async (args) =>
622
- await this.performanceRecordOutcome(args)
797
+ this.toolHandlers.register(
798
+ TOOLS.PERFORMANCE_RECORD_OUTCOME,
799
+ async (args) => await this.performanceRecordOutcome(args),
623
800
  );
624
- this.toolHandlers.register(TOOLS.PERFORMANCE_GET_ANALYTICS, async (args) =>
625
- await this.performanceGetAnalytics(readStringField(args, 'provider'), readStringField(args, 'model'))
801
+ this.toolHandlers.register(
802
+ TOOLS.PERFORMANCE_GET_ANALYTICS,
803
+ async (args) =>
804
+ await this.performanceGetAnalytics(
805
+ readStringField(args, 'provider'),
806
+ readStringField(args, 'model'),
807
+ ),
626
808
  );
627
809
  }
628
810
 
@@ -697,30 +879,32 @@ export class AopKernel {
697
879
  plan: GATE_RESULT.NA,
698
880
  fast: GATE_RESULT.NA,
699
881
  full: GATE_RESULT.NA,
700
- merge: GATE_RESULT.NA
882
+ merge: GATE_RESULT.NA,
701
883
  },
702
884
  locks: {
703
- held: []
885
+ held: [],
704
886
  },
705
887
  collisions: {
706
888
  files: [],
707
889
  areas: [],
708
- contracts: []
890
+ contracts: [],
709
891
  },
710
892
  cluster: { ...DEFAULT_CLUSTER },
711
893
  role_status: { ...DEFAULT_ROLE_STATUS },
712
- last_updated: nowIso()
894
+ last_updated: nowIso(),
713
895
  };
714
896
  }
715
897
 
716
- async readState(featureId: string): Promise<{ frontMatter: AnyRecord; body: string; raw: string }> {
898
+ async readState(
899
+ featureId: string,
900
+ ): Promise<{ frontMatter: AnyRecord; body: string; raw: string }> {
717
901
  const filePath = this.statePath(featureId);
718
902
  const raw = await fs.readFile(filePath, 'utf8');
719
903
  const parsed = parseFrontMatter(raw);
720
904
  return {
721
905
  frontMatter: parsed.frontMatter,
722
906
  body: parsed.body,
723
- raw
907
+ raw,
724
908
  };
725
909
  }
726
910
 
@@ -728,11 +912,15 @@ export class AopKernel {
728
912
  const validation = await this.schemaRegistry.validate('state.schema.json', frontMatter);
729
913
  if (!validation.valid) {
730
914
  throw {
731
- normalizedResponse: fail(ERROR_CODES.STATE_VALIDATION_FAILED, 'state.md front matter failed schema validation', {
732
- errors: validation.errors,
733
- retryable: false,
734
- requires_human: true
735
- })
915
+ normalizedResponse: fail(
916
+ ERROR_CODES.STATE_VALIDATION_FAILED,
917
+ 'state.md front matter failed schema validation',
918
+ {
919
+ errors: validation.errors,
920
+ retryable: false,
921
+ requires_human: true,
922
+ },
923
+ ),
736
924
  };
737
925
  }
738
926
 
@@ -742,13 +930,13 @@ export class AopKernel {
742
930
 
743
931
  async withFeatureLock<T>(featureId: string, operation: () => Promise<T>): Promise<T> {
744
932
  return await withFileLock<T>(this.featureLockPath(featureId), operation, {
745
- timeoutMs: 30_000
933
+ timeoutMs: 30_000,
746
934
  });
747
935
  }
748
936
 
749
937
  async withIndexLock<T>(operation: () => Promise<T>): Promise<T> {
750
938
  return await withFileLock<T>(this.indexLockPath, operation, {
751
- timeoutMs: 30_000
939
+ timeoutMs: 30_000,
752
940
  });
753
941
  }
754
942
 
@@ -767,18 +955,25 @@ export class AopKernel {
767
955
  const validation = await this.schemaRegistry.validate('index.schema.json', normalized);
768
956
  if (!validation.valid) {
769
957
  throw {
770
- normalizedResponse: fail(ERROR_CODES.INDEX_VALIDATION_FAILED, 'index.json failed schema validation', {
771
- errors: validation.errors,
772
- retryable: false,
773
- requires_human: true
774
- })
958
+ normalizedResponse: fail(
959
+ ERROR_CODES.INDEX_VALIDATION_FAILED,
960
+ 'index.json failed schema validation',
961
+ {
962
+ errors: validation.errors,
963
+ retryable: false,
964
+ requires_human: true,
965
+ },
966
+ ),
775
967
  };
776
968
  }
777
969
 
778
970
  await atomicWriteJson(this.indexPath, normalized);
779
971
  }
780
972
 
781
- async validateSchema(schemaName: string, value: unknown): Promise<{ valid: boolean; errors?: unknown }> {
973
+ async validateSchema(
974
+ schemaName: string,
975
+ value: unknown,
976
+ ): Promise<{ valid: boolean; errors?: unknown }> {
782
977
  return await this.schemaRegistry.validate(schemaName, value);
783
978
  }
784
979
 
@@ -806,15 +1001,27 @@ export class AopKernel {
806
1001
  await atomicWriteJson(runLeasePath, data);
807
1002
  }
808
1003
 
809
- async acquireRunLease(input: AcquireRunLeaseInput): Promise<{ data: { runtime_sessions: RuntimeSessionsSnapshot; took_over_stale: boolean; reused_existing_owner: boolean } }> {
1004
+ async acquireRunLease(input: AcquireRunLeaseInput): Promise<{
1005
+ data: {
1006
+ runtime_sessions: RuntimeSessionsSnapshot;
1007
+ took_over_stale: boolean;
1008
+ reused_existing_owner: boolean;
1009
+ };
1010
+ }> {
810
1011
  return await this.runLeaseService.acquireRunLease(input);
811
1012
  }
812
1013
 
813
- async renewRunLease(runId: string, ownerInstanceId: string): Promise<{ data: { lease_expires_at: string } }> {
1014
+ async renewRunLease(
1015
+ runId: string,
1016
+ ownerInstanceId: string,
1017
+ ): Promise<{ data: { lease_expires_at: string } }> {
814
1018
  return await this.runLeaseService.renewRunLease(runId, ownerInstanceId);
815
1019
  }
816
1020
 
817
- async releaseRunLease(runId: string, ownerInstanceId: string): Promise<{ data: { released: boolean } }> {
1021
+ async releaseRunLease(
1022
+ runId: string,
1023
+ ownerInstanceId: string,
1024
+ ): Promise<{ data: { released: boolean } }> {
818
1025
  return await this.runLeaseService.releaseRunLease(runId, ownerInstanceId);
819
1026
  }
820
1027
 
@@ -849,7 +1056,10 @@ export class AopKernel {
849
1056
  async updateState(
850
1057
  featureId: string,
851
1058
  expectedVersion: number | null,
852
- updater: (frontMatter: AnyRecord, body: string) => Promise<{ frontMatter?: AnyRecord; body?: string }>
1059
+ updater: (
1060
+ frontMatter: AnyRecord,
1061
+ body: string,
1062
+ ) => Promise<{ frontMatter?: AnyRecord; body?: string }>,
853
1063
  ) {
854
1064
  return await this.featureStateService.updateState(featureId, expectedVersion, updater);
855
1065
  }
@@ -925,8 +1135,8 @@ export class AopKernel {
925
1135
  feature_id: featureId,
926
1136
  branch,
927
1137
  worktree_path_abs: worktree,
928
- existed: true
929
- }
1138
+ existed: true,
1139
+ },
930
1140
  };
931
1141
  }
932
1142
 
@@ -939,15 +1149,20 @@ export class AopKernel {
939
1149
  const branchCreate = await runGit(this.repoRoot, ['branch', branch, baseRef]);
940
1150
  if (branchCreate.code !== 0) {
941
1151
  throw {
942
- normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'Unable to create feature branch', {
943
- feature_id: featureId,
944
- stderr: branchCreate.stderr,
945
- retryable: false,
946
- requires_human: true
947
- }, {
948
- command: ['git', 'branch', branch, baseRef],
949
- exit_code: branchCreate.code
950
- })
1152
+ normalizedResponse: fail(
1153
+ ERROR_CODES.GIT_FAILURE,
1154
+ 'Unable to create feature branch',
1155
+ {
1156
+ feature_id: featureId,
1157
+ stderr: branchCreate.stderr,
1158
+ retryable: false,
1159
+ requires_human: true,
1160
+ },
1161
+ {
1162
+ command: ['git', 'branch', branch, baseRef],
1163
+ exit_code: branchCreate.code,
1164
+ },
1165
+ ),
951
1166
  };
952
1167
  }
953
1168
  }
@@ -955,30 +1170,42 @@ export class AopKernel {
955
1170
  const addWorktree = await runGit(this.repoRoot, ['worktree', 'add', worktree, branch]);
956
1171
  if (addWorktree.code !== 0) {
957
1172
  throw {
958
- normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'Unable to create git worktree', {
959
- feature_id: featureId,
960
- stderr: addWorktree.stderr,
961
- retryable: false,
962
- requires_human: true
963
- }, {
964
- command: ['git', 'worktree', 'add', worktree, branch],
965
- exit_code: addWorktree.code
966
- })
1173
+ normalizedResponse: fail(
1174
+ ERROR_CODES.GIT_FAILURE,
1175
+ 'Unable to create git worktree',
1176
+ {
1177
+ feature_id: featureId,
1178
+ stderr: addWorktree.stderr,
1179
+ retryable: false,
1180
+ requires_human: true,
1181
+ },
1182
+ {
1183
+ command: ['git', 'worktree', 'add', worktree, branch],
1184
+ exit_code: addWorktree.code,
1185
+ },
1186
+ ),
967
1187
  };
968
1188
  }
969
1189
 
970
- const worktreeConfig = this.policy.worktree as {
971
- base_branch: string;
972
- symlinks?: string[];
973
- post_create?: string[];
974
- } | undefined;
1190
+ const worktreeConfig = this.policy.worktree as
1191
+ | {
1192
+ base_branch: string;
1193
+ symlinks?: string[];
1194
+ post_create?: string[];
1195
+ }
1196
+ | undefined;
975
1197
  const hookWarnings: WorkspaceHookWarning[] = [];
976
1198
  const collectHookWarning = (warning: WorkspaceHookWarning) => {
977
1199
  hookWarnings.push(warning);
978
1200
  };
979
1201
 
980
1202
  if (worktreeConfig?.symlinks?.length) {
981
- await applyWorktreeSymlinks(this.repoRoot, worktree, worktreeConfig.symlinks, collectHookWarning);
1203
+ await applyWorktreeSymlinks(
1204
+ this.repoRoot,
1205
+ worktree,
1206
+ worktreeConfig.symlinks,
1207
+ collectHookWarning,
1208
+ );
982
1209
  }
983
1210
 
984
1211
  if (worktreeConfig?.post_create?.length) {
@@ -995,8 +1222,8 @@ export class AopKernel {
995
1222
  feature_id: featureId,
996
1223
  branch,
997
1224
  worktree_path_abs: worktree,
998
- existed: false
999
- }
1225
+ existed: false,
1226
+ },
1000
1227
  };
1001
1228
  }
1002
1229
 
@@ -1015,33 +1242,42 @@ export class AopKernel {
1015
1242
  async repoStatus(featureId) {
1016
1243
  const worktree = this.worktreePath(featureId);
1017
1244
  const status = await runGit(this.repoRoot, ['status', '--porcelain'], { cwd: worktree });
1018
- const branch = await runGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: worktree });
1245
+ const branch = await runGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'], {
1246
+ cwd: worktree,
1247
+ });
1019
1248
 
1020
1249
  return {
1021
1250
  data: {
1022
1251
  feature_id: featureId,
1023
1252
  branch: branch.stdout.trim(),
1024
- status_porcelain: status.stdout.trim().split('\n').filter(Boolean)
1025
- }
1253
+ status_porcelain: status.stdout.trim().split('\n').filter(Boolean),
1254
+ },
1026
1255
  };
1027
1256
  }
1028
1257
 
1029
1258
  async repoDiff(featureId, options = []) {
1030
1259
  const safeOptions = asArray<string>(options).filter(
1031
- (option) => typeof option === 'string' && option.startsWith('--')
1260
+ (option) => typeof option === 'string' && option.startsWith('--'),
1032
1261
  );
1033
- const diff = await runGit(this.repoRoot, ['diff', ...safeOptions], { cwd: this.worktreePath(featureId) });
1262
+ const diff = await runGit(this.repoRoot, ['diff', ...safeOptions], {
1263
+ cwd: this.worktreePath(featureId),
1264
+ });
1034
1265
  return {
1035
1266
  data: {
1036
1267
  feature_id: featureId,
1037
- diff: diff.stdout
1038
- }
1268
+ diff: diff.stdout,
1269
+ },
1039
1270
  };
1040
1271
  }
1041
1272
 
1042
1273
  async repoReadFile(featureId, filePath) {
1043
- const normalized = await normalizeRepoPath(this.repoRoot, path.join(this.worktreePath(featureId), filePath), this.policy.path_rules.allow_symlink_traversal)
1044
- .then((relative) => normalizeFromWorktree(this.worktreePath(featureId), this.repoRoot, relative));
1274
+ const normalized = await normalizeRepoPath(
1275
+ this.repoRoot,
1276
+ path.join(this.worktreePath(featureId), filePath),
1277
+ this.policy.path_rules.allow_symlink_traversal,
1278
+ ).then((relative) =>
1279
+ normalizeFromWorktree(this.worktreePath(featureId), this.repoRoot, relative),
1280
+ );
1045
1281
  const absolute = path.join(this.repoRoot, normalized);
1046
1282
  const exists = await pathExists(absolute);
1047
1283
  if (!exists) {
@@ -1049,8 +1285,8 @@ export class AopKernel {
1049
1285
  normalizedResponse: fail(ERROR_CODES.FILE_NOT_FOUND, 'File not found', {
1050
1286
  path: normalized,
1051
1287
  retryable: false,
1052
- requires_human: false
1053
- })
1288
+ requires_human: false,
1289
+ }),
1054
1290
  };
1055
1291
  }
1056
1292
  const content = await fs.readFile(absolute, 'utf8');
@@ -1058,8 +1294,8 @@ export class AopKernel {
1058
1294
  data: {
1059
1295
  feature_id: featureId,
1060
1296
  path: normalized,
1061
- content
1062
- }
1297
+ content,
1298
+ },
1063
1299
  };
1064
1300
  }
1065
1301
 
@@ -1067,16 +1303,20 @@ export class AopKernel {
1067
1303
  const worktree = this.worktreePath(featureId);
1068
1304
  const rgResult = await runCommand('rg', ['-n', '--no-heading', query, '.'], {
1069
1305
  cwd: worktree,
1070
- timeoutMs: 30_000
1306
+ timeoutMs: 30_000,
1071
1307
  });
1072
1308
 
1073
1309
  if (rgResult.code === 127) {
1074
1310
  throw {
1075
- normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'ripgrep (rg) not found - required for search functionality', {
1076
- stderr: rgResult.stderr,
1077
- retryable: false,
1078
- requires_human: true
1079
- })
1311
+ normalizedResponse: fail(
1312
+ ERROR_CODES.GIT_FAILURE,
1313
+ 'ripgrep (rg) not found - required for search functionality',
1314
+ {
1315
+ stderr: rgResult.stderr,
1316
+ retryable: false,
1317
+ requires_human: true,
1318
+ },
1319
+ ),
1080
1320
  };
1081
1321
  }
1082
1322
 
@@ -1085,8 +1325,8 @@ export class AopKernel {
1085
1325
  normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'Search failed', {
1086
1326
  stderr: rgResult.stderr,
1087
1327
  retryable: true,
1088
- requires_human: false
1089
- })
1328
+ requires_human: false,
1329
+ }),
1090
1330
  };
1091
1331
  }
1092
1332
 
@@ -1103,7 +1343,7 @@ export class AopKernel {
1103
1343
  return {
1104
1344
  path: line.slice(0, firstColon),
1105
1345
  line: Number(line.slice(firstColon + 1, secondColon)),
1106
- snippet: line.slice(secondColon + 1)
1346
+ snippet: line.slice(secondColon + 1),
1107
1347
  };
1108
1348
  });
1109
1349
 
@@ -1111,15 +1351,19 @@ export class AopKernel {
1111
1351
  data: {
1112
1352
  feature_id: featureId,
1113
1353
  query,
1114
- matches
1115
- }
1354
+ matches,
1355
+ },
1116
1356
  };
1117
1357
  }
1118
1358
 
1119
1359
  async repoDiffBundle(featureId) {
1120
- const stat = await runGit(this.repoRoot, ['diff', '--stat'], { cwd: this.worktreePath(featureId) });
1360
+ const stat = await runGit(this.repoRoot, ['diff', '--stat'], {
1361
+ cwd: this.worktreePath(featureId),
1362
+ });
1121
1363
  const full = await runGit(this.repoRoot, ['diff'], { cwd: this.worktreePath(featureId) });
1122
- const names = await runGit(this.repoRoot, ['diff', '--name-only'], { cwd: this.worktreePath(featureId) });
1364
+ const names = await runGit(this.repoRoot, ['diff', '--name-only'], {
1365
+ cwd: this.worktreePath(featureId),
1366
+ });
1123
1367
  const latest = await this.evidenceLatest(featureId);
1124
1368
 
1125
1369
  return {
@@ -1127,9 +1371,12 @@ export class AopKernel {
1127
1371
  feature_id: featureId,
1128
1372
  diff_stat: stat.stdout,
1129
1373
  diff: full.stdout,
1130
- touched_files: names.stdout.split('\n').map((x) => x.trim()).filter(Boolean),
1131
- last_gate_summary: latest.data?.latest ?? null
1132
- }
1374
+ touched_files: names.stdout
1375
+ .split('\n')
1376
+ .map((x) => x.trim())
1377
+ .filter(Boolean),
1378
+ last_gate_summary: latest.data?.latest ?? null,
1379
+ },
1133
1380
  };
1134
1381
  }
1135
1382
 
@@ -1154,7 +1401,12 @@ export class AopKernel {
1154
1401
  }
1155
1402
 
1156
1403
  async qaTestIndexUpdate(featureId, expectedVersion, updates, evidenceRefs) {
1157
- return await this.qaIndexService.qaTestIndexUpdate(featureId, expectedVersion, updates, evidenceRefs);
1404
+ return await this.qaIndexService.qaTestIndexUpdate(
1405
+ featureId,
1406
+ expectedVersion,
1407
+ updates,
1408
+ evidenceRefs,
1409
+ );
1158
1410
  }
1159
1411
 
1160
1412
  async locksAcquire(resource, featureId, waitTimeoutSeconds = null) {
@@ -1178,7 +1430,12 @@ export class AopKernel {
1178
1430
  }
1179
1431
 
1180
1432
  async featureReadyToMerge(featureId, commitMessage, mergeStrategy, userApprovalToken) {
1181
- return await this.mergeService.featureReadyToMerge(featureId, commitMessage, mergeStrategy, userApprovalToken);
1433
+ return await this.mergeService.featureReadyToMerge(
1434
+ featureId,
1435
+ commitMessage,
1436
+ mergeStrategy,
1437
+ userApprovalToken,
1438
+ );
1182
1439
  }
1183
1440
 
1184
1441
  async featureDelete(
@@ -1186,13 +1443,13 @@ export class AopKernel {
1186
1443
  dryRun: boolean | null,
1187
1444
  confirm: boolean | null,
1188
1445
  removeWorktree: boolean | null,
1189
- removeBranch: string | null
1446
+ removeBranch: string | null,
1190
1447
  ): Promise<FeatureDeleteResult> {
1191
1448
  return await this.featureDeletionService.featureDelete(featureId, {
1192
1449
  dryRun: dryRun ?? undefined,
1193
1450
  confirm: confirm ?? undefined,
1194
1451
  removeWorktree: removeWorktree ?? undefined,
1195
- removeBranch: removeBranch ?? undefined
1452
+ removeBranch: removeBranch ?? undefined,
1196
1453
  });
1197
1454
  }
1198
1455
 
@@ -1224,21 +1481,34 @@ export class AopKernel {
1224
1481
  }
1225
1482
  }
1226
1483
 
1227
- async featureSendMessage(
1228
- featureId: string | null,
1229
- message: string | null
1230
- ): Promise<unknown> {
1484
+ async featureSendMessage(featureId: string | null, message: string | null): Promise<unknown> {
1231
1485
  if (!featureId) {
1232
- throw { normalizedResponse: fail(ERROR_CODES.INVALID_ARGUMENT, 'feature_id is required', { retryable: false, requires_human: false }) };
1486
+ throw {
1487
+ normalizedResponse: fail(ERROR_CODES.INVALID_ARGUMENT, 'feature_id is required', {
1488
+ retryable: false,
1489
+ requires_human: false,
1490
+ }),
1491
+ };
1233
1492
  }
1234
1493
  if (!message) {
1235
- throw { normalizedResponse: fail(ERROR_CODES.INVALID_ARGUMENT, 'message is required and must not be empty', { retryable: false, requires_human: false }) };
1494
+ throw {
1495
+ normalizedResponse: fail(
1496
+ ERROR_CODES.INVALID_ARGUMENT,
1497
+ 'message is required and must not be empty',
1498
+ { retryable: false, requires_human: false },
1499
+ ),
1500
+ };
1236
1501
  }
1237
1502
 
1238
1503
  const runtimeSessions = await this.getRuntimeSessions();
1239
1504
  const featureSession = runtimeSessions.feature_sessions?.[featureId];
1240
1505
  if (!featureSession) {
1241
- throw { normalizedResponse: { ok: false, error: { code: 'session_not_found', message: 'No active session cluster for feature' } } };
1506
+ throw {
1507
+ normalizedResponse: {
1508
+ ok: false,
1509
+ error: { code: 'session_not_found', message: 'No active session cluster for feature' },
1510
+ },
1511
+ };
1242
1512
  }
1243
1513
 
1244
1514
  const state = await this.readState(featureId);
@@ -1275,7 +1545,12 @@ export class AopKernel {
1275
1545
  }
1276
1546
 
1277
1547
  if (!this.provider?.sendMessage) {
1278
- throw { normalizedResponse: { ok: false, error: { code: 'provider_unsupported', message: 'Provider does not support sendMessage' } } };
1548
+ throw {
1549
+ normalizedResponse: {
1550
+ ok: false,
1551
+ error: { code: 'provider_unsupported', message: 'Provider does not support sendMessage' },
1552
+ },
1553
+ };
1279
1554
  }
1280
1555
 
1281
1556
  await this.waitForSessionToBecomeActive(targetSessionId);
@@ -1285,7 +1560,7 @@ export class AopKernel {
1285
1560
  session_id: targetSessionId,
1286
1561
  target_role: targetRole,
1287
1562
  status,
1288
- delivered: true
1563
+ delivered: true,
1289
1564
  };
1290
1565
  }
1291
1566
 
@@ -1313,7 +1588,7 @@ export class AopKernel {
1313
1588
  retry_count: typeof args.retry_count === 'number' ? args.retry_count : 0,
1314
1589
  duration_ms: typeof args.duration_ms === 'number' ? args.duration_ms : 0,
1315
1590
  cost_usd: typeof args.cost_usd === 'number' ? args.cost_usd : 0,
1316
- recorded_at: nowIso()
1591
+ recorded_at: nowIso(),
1317
1592
  };
1318
1593
  const snapshot = await this.performanceAnalyticsService.recordOutcome(outcome);
1319
1594
  return { ok: true as const, data: { total_outcomes: snapshot.outcomes.length } };
@@ -1323,10 +1598,17 @@ export class AopKernel {
1323
1598
  if (provider || model) {
1324
1599
  const stats = await this.performanceAnalyticsService.getProviderStats(
1325
1600
  provider ?? undefined,
1326
- model ?? undefined
1601
+ model ?? undefined,
1327
1602
  );
1328
1603
  const snapshot = await this.performanceAnalyticsService.getAnalytics();
1329
- return { ok: true as const, data: { outcomes: snapshot.outcomes, aggregates: stats, generated_at: snapshot.generated_at } };
1604
+ return {
1605
+ ok: true as const,
1606
+ data: {
1607
+ outcomes: snapshot.outcomes,
1608
+ aggregates: stats,
1609
+ generated_at: snapshot.generated_at,
1610
+ },
1611
+ };
1330
1612
  }
1331
1613
  const snapshot = await this.performanceAnalyticsService.getAnalytics();
1332
1614
  return { ok: true as const, data: snapshot };
@@ -1341,7 +1623,11 @@ function normalizeRepoPathForState(repoRoot: string, absolutePath: string) {
1341
1623
  return relative;
1342
1624
  }
1343
1625
 
1344
- function normalizeFromWorktree(worktreePath: string, repoRoot: string, repoRelativeFromWorktree: string) {
1626
+ function normalizeFromWorktree(
1627
+ worktreePath: string,
1628
+ repoRoot: string,
1629
+ repoRelativeFromWorktree: string,
1630
+ ) {
1345
1631
  const absolute = path.resolve(repoRoot, repoRelativeFromWorktree);
1346
1632
  const maybeRelativeToWorktree = path.relative(worktreePath, absolute).replaceAll('\\\\', '/');
1347
1633
  if (!maybeRelativeToWorktree.startsWith('../')) {