agentic-orchestrator 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (426) hide show
  1. package/.prettierignore +10 -0
  2. package/.prettierrc.json +24 -0
  3. package/CLAUDE.md +3 -2
  4. package/README.md +47 -46
  5. package/agentic/orchestrator/defaults/policy.defaults.yaml +1 -1
  6. package/agentic/orchestrator/prompts/planner.system.md +1 -0
  7. package/agentic/orchestrator/schemas/agents.schema.json +4 -21
  8. package/agentic/orchestrator/schemas/gates.schema.json +4 -19
  9. package/agentic/orchestrator/schemas/index.schema.json +3 -14
  10. package/agentic/orchestrator/schemas/multi-project.schema.json +2 -8
  11. package/agentic/orchestrator/schemas/plan.schema.json +6 -26
  12. package/agentic/orchestrator/schemas/policy.schema.json +19 -81
  13. package/agentic/orchestrator/schemas/policy.user.schema.json +1 -5
  14. package/agentic/orchestrator/schemas/qa_test_index.schema.json +5 -29
  15. package/agentic/orchestrator/schemas/state.schema.json +11 -61
  16. package/agentic/orchestrator/tools/catalog.json +33 -164
  17. package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +1 -3
  18. package/agentic/orchestrator/tools/schemas/input/feature.delete.input.schema.json +1 -5
  19. package/agentic/orchestrator/tools/schemas/input/feature.get_context.input.schema.json +1 -3
  20. package/agentic/orchestrator/tools/schemas/input/feature.init.input.schema.json +1 -4
  21. package/agentic/orchestrator/tools/schemas/input/feature.log_append.input.schema.json +1 -5
  22. package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +1 -6
  23. package/agentic/orchestrator/tools/schemas/input/feature.state_get.input.schema.json +1 -3
  24. package/agentic/orchestrator/tools/schemas/input/feature.state_patch.input.schema.json +1 -5
  25. package/agentic/orchestrator/tools/schemas/input/gates.run.input.schema.json +1 -5
  26. package/agentic/orchestrator/tools/schemas/input/locks.acquire.input.schema.json +1 -5
  27. package/agentic/orchestrator/tools/schemas/input/locks.release.input.schema.json +1 -5
  28. package/agentic/orchestrator/tools/schemas/input/performance.record_outcome.input.schema.json +10 -1
  29. package/agentic/orchestrator/tools/schemas/input/plan.get.input.schema.json +1 -3
  30. package/agentic/orchestrator/tools/schemas/input/plan.submit.input.schema.json +1 -5
  31. package/agentic/orchestrator/tools/schemas/input/plan.update.input.schema.json +1 -6
  32. package/agentic/orchestrator/tools/schemas/input/qa.test_index_get.input.schema.json +1 -3
  33. package/agentic/orchestrator/tools/schemas/input/qa.test_index_update.input.schema.json +1 -6
  34. package/agentic/orchestrator/tools/schemas/input/repo.apply_patch.input.schema.json +1 -5
  35. package/agentic/orchestrator/tools/schemas/input/repo.diff.input.schema.json +1 -3
  36. package/agentic/orchestrator/tools/schemas/input/repo.diff_bundle.input.schema.json +1 -3
  37. package/agentic/orchestrator/tools/schemas/input/repo.ensure_worktree.input.schema.json +1 -4
  38. package/agentic/orchestrator/tools/schemas/input/repo.read_file.input.schema.json +1 -4
  39. package/agentic/orchestrator/tools/schemas/input/repo.search.input.schema.json +1 -4
  40. package/agentic/orchestrator/tools/schemas/input/repo.status.input.schema.json +1 -3
  41. package/agentic/orchestrator/tools/schemas/input/report.feature_summary.input.schema.json +1 -3
  42. package/agentic/orchestrator/tools/schemas/output/collisions.scan.output.schema.json +1 -3
  43. package/agentic/orchestrator/tools/schemas/output/evidence.latest.output.schema.json +1 -4
  44. package/agentic/orchestrator/tools/schemas/output/feature.delete.output.schema.json +4 -20
  45. package/agentic/orchestrator/tools/schemas/output/feature.discover_specs.output.schema.json +2 -7
  46. package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +1 -8
  47. package/agentic/orchestrator/tools/schemas/output/feature.init.output.schema.json +1 -5
  48. package/agentic/orchestrator/tools/schemas/output/feature.log_append.output.schema.json +1 -5
  49. package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +1 -6
  50. package/agentic/orchestrator/tools/schemas/output/feature.state_get.output.schema.json +1 -4
  51. package/agentic/orchestrator/tools/schemas/output/feature.state_patch.output.schema.json +1 -5
  52. package/agentic/orchestrator/tools/schemas/output/gates.list.output.schema.json +2 -7
  53. package/agentic/orchestrator/tools/schemas/output/gates.run.output.schema.json +1 -8
  54. package/agentic/orchestrator/tools/schemas/output/locks.acquire.output.schema.json +1 -7
  55. package/agentic/orchestrator/tools/schemas/output/locks.release.output.schema.json +1 -5
  56. package/agentic/orchestrator/tools/schemas/output/performance.get_analytics.output.schema.json +22 -2
  57. package/agentic/orchestrator/tools/schemas/output/plan.get.output.schema.json +1 -4
  58. package/agentic/orchestrator/tools/schemas/output/plan.submit.output.schema.json +1 -5
  59. package/agentic/orchestrator/tools/schemas/output/plan.update.output.schema.json +1 -5
  60. package/agentic/orchestrator/tools/schemas/output/qa.test_index_get.output.schema.json +1 -5
  61. package/agentic/orchestrator/tools/schemas/output/qa.test_index_update.output.schema.json +1 -4
  62. package/agentic/orchestrator/tools/schemas/output/repo.apply_patch.output.schema.json +1 -6
  63. package/agentic/orchestrator/tools/schemas/output/repo.diff.output.schema.json +1 -4
  64. package/agentic/orchestrator/tools/schemas/output/repo.diff_bundle.output.schema.json +1 -7
  65. package/agentic/orchestrator/tools/schemas/output/repo.ensure_worktree.output.schema.json +1 -6
  66. package/agentic/orchestrator/tools/schemas/output/repo.read_file.output.schema.json +1 -5
  67. package/agentic/orchestrator/tools/schemas/output/repo.search.output.schema.json +1 -5
  68. package/agentic/orchestrator/tools/schemas/output/repo.status.output.schema.json +1 -5
  69. package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +1 -4
  70. package/apps/control-plane/scripts/validate-architecture-rules.mjs +16 -5
  71. package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +30 -8
  72. package/apps/control-plane/scripts/validate-mcp-contracts.ts +13 -7
  73. package/apps/control-plane/src/application/adapters/adapter-registry.ts +35 -15
  74. package/apps/control-plane/src/application/multi-project-loader.ts +27 -10
  75. package/apps/control-plane/src/application/services/activity-monitor-service.ts +26 -14
  76. package/apps/control-plane/src/application/services/collision-queue-service.ts +31 -17
  77. package/apps/control-plane/src/application/services/cost-tracking-service.ts +23 -16
  78. package/apps/control-plane/src/application/services/dependency-scheduler-service.ts +12 -4
  79. package/apps/control-plane/src/application/services/feature-deletion-service.ts +94 -58
  80. package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +19 -13
  81. package/apps/control-plane/src/application/services/feature-state-service.ts +29 -19
  82. package/apps/control-plane/src/application/services/gate-interpolation-service.ts +7 -2
  83. package/apps/control-plane/src/application/services/gate-service.ts +64 -41
  84. package/apps/control-plane/src/application/services/instance-isolation-service.ts +1 -1
  85. package/apps/control-plane/src/application/services/issue-tracker-service.ts +49 -38
  86. package/apps/control-plane/src/application/services/lock-service.ts +75 -49
  87. package/apps/control-plane/src/application/services/merge-service.ts +91 -50
  88. package/apps/control-plane/src/application/services/notifier-service.ts +42 -20
  89. package/apps/control-plane/src/application/services/patch-service.ts +73 -44
  90. package/apps/control-plane/src/application/services/performance-analytics-service.ts +8 -6
  91. package/apps/control-plane/src/application/services/plan-service.ts +148 -89
  92. package/apps/control-plane/src/application/services/policy-loader-service.ts +10 -4
  93. package/apps/control-plane/src/application/services/pr-monitor-service.ts +33 -14
  94. package/apps/control-plane/src/application/services/qa-index-service.ts +20 -16
  95. package/apps/control-plane/src/application/services/reactions-service.ts +30 -15
  96. package/apps/control-plane/src/application/services/reporting-service.ts +16 -12
  97. package/apps/control-plane/src/application/services/run-lease-service.ts +138 -81
  98. package/apps/control-plane/src/application/tools/tool-metadata.ts +5 -5
  99. package/apps/control-plane/src/application/tools/tool-router.ts +6 -3
  100. package/apps/control-plane/src/cli/aop.ts +2 -2
  101. package/apps/control-plane/src/cli/attach-command-handler.ts +9 -9
  102. package/apps/control-plane/src/cli/cleanup-command-handler.ts +16 -11
  103. package/apps/control-plane/src/cli/cli-argument-parser.ts +6 -3
  104. package/apps/control-plane/src/cli/dashboard-command-handler.ts +28 -8
  105. package/apps/control-plane/src/cli/delete-command-handler.ts +7 -7
  106. package/apps/control-plane/src/cli/help-command-handler.ts +61 -32
  107. package/apps/control-plane/src/cli/init-command-handler.ts +110 -54
  108. package/apps/control-plane/src/cli/io.ts +7 -3
  109. package/apps/control-plane/src/cli/resume-command-handler.ts +21 -13
  110. package/apps/control-plane/src/cli/retry-command-handler.ts +12 -11
  111. package/apps/control-plane/src/cli/run-command-handler.ts +12 -8
  112. package/apps/control-plane/src/cli/send-command-handler.ts +6 -6
  113. package/apps/control-plane/src/cli/spec-ingestion-service.ts +14 -8
  114. package/apps/control-plane/src/cli/spec-input-resolver.ts +6 -1
  115. package/apps/control-plane/src/cli/spec-utils.ts +2 -2
  116. package/apps/control-plane/src/cli/status-command-handler.ts +13 -12
  117. package/apps/control-plane/src/cli/tooling.ts +3 -3
  118. package/apps/control-plane/src/cli/types.ts +1 -1
  119. package/apps/control-plane/src/core/collisions.ts +27 -10
  120. package/apps/control-plane/src/core/constants.ts +13 -7
  121. package/apps/control-plane/src/core/error-codes.ts +1 -1
  122. package/apps/control-plane/src/core/fs.ts +11 -5
  123. package/apps/control-plane/src/core/gates.ts +53 -27
  124. package/apps/control-plane/src/core/git.ts +18 -6
  125. package/apps/control-plane/src/core/kernel.ts +515 -227
  126. package/apps/control-plane/src/core/patch.ts +7 -3
  127. package/apps/control-plane/src/core/path-layout.ts +5 -1
  128. package/apps/control-plane/src/core/path-rules.ts +19 -5
  129. package/apps/control-plane/src/core/qa-index.ts +26 -12
  130. package/apps/control-plane/src/core/response.ts +9 -6
  131. package/apps/control-plane/src/core/schemas.ts +29 -10
  132. package/apps/control-plane/src/core/tool-caller.ts +1 -1
  133. package/apps/control-plane/src/core/workspace-hooks.ts +5 -5
  134. package/apps/control-plane/src/index.ts +3 -9
  135. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +69 -32
  136. package/apps/control-plane/src/mcp/kernel-tool-executor.ts +7 -3
  137. package/apps/control-plane/src/mcp/mcp-server-adapter.ts +12 -10
  138. package/apps/control-plane/src/mcp/operation-ledger.ts +18 -8
  139. package/apps/control-plane/src/mcp/protocol-contract.ts +2 -2
  140. package/apps/control-plane/src/mcp/runtime-factory.ts +15 -6
  141. package/apps/control-plane/src/mcp/token-auth-verifier.ts +3 -2
  142. package/apps/control-plane/src/mcp/token-claims-validator.ts +11 -7
  143. package/apps/control-plane/src/mcp/tool-authorizer.ts +1 -3
  144. package/apps/control-plane/src/mcp/tool-client.ts +17 -5
  145. package/apps/control-plane/src/mcp/tool-contract-validator.ts +17 -8
  146. package/apps/control-plane/src/mcp/tool-registry-loader.ts +7 -3
  147. package/apps/control-plane/src/mcp/tool-runtime.ts +66 -39
  148. package/apps/control-plane/src/mcp/tools-markdown-generator.ts +6 -1
  149. package/apps/control-plane/src/providers/providers.ts +72 -48
  150. package/apps/control-plane/src/supervisor/build-wave-executor.ts +44 -25
  151. package/apps/control-plane/src/supervisor/planning-wave-executor.ts +46 -33
  152. package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +1 -1
  153. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +38 -23
  154. package/apps/control-plane/src/supervisor/run-coordinator.ts +71 -36
  155. package/apps/control-plane/src/supervisor/runtime.ts +59 -35
  156. package/apps/control-plane/src/supervisor/session-orchestrator.ts +48 -31
  157. package/apps/control-plane/src/supervisor/types.ts +22 -7
  158. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +30 -20
  159. package/apps/control-plane/test/activity-monitor.spec.ts +54 -30
  160. package/apps/control-plane/test/adapter-registry.spec.ts +5 -5
  161. package/apps/control-plane/test/aop.spec.ts +4 -4
  162. package/apps/control-plane/test/batch-operations.spec.ts +20 -18
  163. package/apps/control-plane/test/bootstrap-attach.spec.ts +52 -19
  164. package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +58 -27
  165. package/apps/control-plane/test/bootstrap.spec.ts +72 -40
  166. package/apps/control-plane/test/cleanup-command.spec.ts +86 -32
  167. package/apps/control-plane/test/cli-helpers.spec.ts +119 -66
  168. package/apps/control-plane/test/cli.spec.ts +1 -1
  169. package/apps/control-plane/test/cli.unit.spec.ts +226 -167
  170. package/apps/control-plane/test/collision-queue.spec.ts +49 -40
  171. package/apps/control-plane/test/collisions.spec.ts +30 -30
  172. package/apps/control-plane/test/core-utils.spec.ts +29 -15
  173. package/apps/control-plane/test/cost-tracking.spec.ts +38 -22
  174. package/apps/control-plane/test/dashboard-api.integration.spec.ts +68 -36
  175. package/apps/control-plane/test/dashboard-client.spec.ts +18 -12
  176. package/apps/control-plane/test/dashboard-command.spec.ts +11 -7
  177. package/apps/control-plane/test/delete-command-handler.spec.ts +49 -41
  178. package/apps/control-plane/test/dependency-scheduler.spec.ts +47 -20
  179. package/apps/control-plane/test/epoch-tracking.spec.ts +9 -9
  180. package/apps/control-plane/test/feature-deletion-service.spec.ts +60 -52
  181. package/apps/control-plane/test/feature-lifecycle.spec.ts +36 -17
  182. package/apps/control-plane/test/gates.spec.ts +101 -81
  183. package/apps/control-plane/test/git-spawn-error.spec.ts +1 -1
  184. package/apps/control-plane/test/helpers.ts +10 -6
  185. package/apps/control-plane/test/incremental-gates.spec.ts +59 -20
  186. package/apps/control-plane/test/init-wizard.spec.ts +162 -67
  187. package/apps/control-plane/test/instance-isolation.spec.ts +43 -10
  188. package/apps/control-plane/test/issue-tracker.spec.ts +368 -128
  189. package/apps/control-plane/test/kernel-collision-replay.spec.ts +50 -29
  190. package/apps/control-plane/test/kernel.branches.spec.ts +64 -40
  191. package/apps/control-plane/test/kernel.coverage.spec.ts +85 -49
  192. package/apps/control-plane/test/kernel.coverage2.spec.ts +109 -65
  193. package/apps/control-plane/test/kernel.spec.ts +134 -51
  194. package/apps/control-plane/test/lock-service.spec.ts +92 -68
  195. package/apps/control-plane/test/mcp-helpers.spec.ts +53 -39
  196. package/apps/control-plane/test/mcp.spec.ts +231 -115
  197. package/apps/control-plane/test/merge-service.spec.ts +142 -94
  198. package/apps/control-plane/test/multi-project.spec.ts +28 -22
  199. package/apps/control-plane/test/notifier-service.spec.ts +136 -92
  200. package/apps/control-plane/test/parallel-gates.spec.ts +51 -35
  201. package/apps/control-plane/test/patch-service.spec.ts +128 -48
  202. package/apps/control-plane/test/performance-analytics.spec.ts +99 -63
  203. package/apps/control-plane/test/plan-service.spec.ts +50 -39
  204. package/apps/control-plane/test/planning-wave-executor.spec.ts +95 -71
  205. package/apps/control-plane/test/policy-loader-service.spec.ts +41 -19
  206. package/apps/control-plane/test/pr-monitor.spec.ts +113 -64
  207. package/apps/control-plane/test/providers.spec.ts +133 -102
  208. package/apps/control-plane/test/qa-index-service.spec.ts +31 -33
  209. package/apps/control-plane/test/qa-index.spec.ts +58 -61
  210. package/apps/control-plane/test/reactions.spec.ts +88 -45
  211. package/apps/control-plane/test/response.spec.ts +5 -5
  212. package/apps/control-plane/test/resume-command.spec.ts +121 -80
  213. package/apps/control-plane/test/run-coordinator.spec.ts +205 -136
  214. package/apps/control-plane/test/schema-date-time.spec.ts +49 -41
  215. package/apps/control-plane/test/service-retry-paths.spec.ts +77 -57
  216. package/apps/control-plane/test/services.spec.ts +147 -129
  217. package/apps/control-plane/test/session-management.spec.ts +136 -74
  218. package/apps/control-plane/test/spec-ingestion.spec.ts +23 -21
  219. package/apps/control-plane/test/spec-input-resolver.spec.ts +11 -10
  220. package/apps/control-plane/test/supervisor-collaborators.spec.ts +168 -121
  221. package/apps/control-plane/test/supervisor.calltool.spec.ts +21 -18
  222. package/apps/control-plane/test/supervisor.spec.ts +67 -43
  223. package/apps/control-plane/test/supervisor.unit.spec.ts +195 -126
  224. package/apps/control-plane/test/token-auth-verifier.spec.ts +29 -14
  225. package/apps/control-plane/test/tool-registry-loader.spec.ts +51 -27
  226. package/apps/control-plane/test/tool-runtime.spec.ts +63 -46
  227. package/apps/control-plane/test/worker-decision-loop.spec.ts +143 -122
  228. package/apps/control-plane/test/workspace-hooks.spec.ts +61 -23
  229. package/apps/control-plane/tsconfig.build.json +2 -7
  230. package/apps/control-plane/tsconfig.json +1 -5
  231. package/apps/control-plane/vitest.config.ts +7 -7
  232. package/dist/apps/control-plane/application/adapters/adapter-registry.js +12 -5
  233. package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -1
  234. package/dist/apps/control-plane/application/multi-project-loader.js +26 -9
  235. package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -1
  236. package/dist/apps/control-plane/application/services/activity-monitor-service.js +7 -7
  237. package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
  238. package/dist/apps/control-plane/application/services/collision-queue-service.js +7 -7
  239. package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
  240. package/dist/apps/control-plane/application/services/cost-tracking-service.js +6 -8
  241. package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
  242. package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -1
  243. package/dist/apps/control-plane/application/services/feature-deletion-service.js +37 -29
  244. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
  245. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +10 -10
  246. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
  247. package/dist/apps/control-plane/application/services/feature-state-service.js +11 -11
  248. package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
  249. package/dist/apps/control-plane/application/services/gate-interpolation-service.js +3 -1
  250. package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -1
  251. package/dist/apps/control-plane/application/services/gate-service.js +26 -26
  252. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
  253. package/dist/apps/control-plane/application/services/instance-isolation-service.js +1 -1
  254. package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -1
  255. package/dist/apps/control-plane/application/services/issue-tracker-service.js +25 -15
  256. package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
  257. package/dist/apps/control-plane/application/services/lock-service.js +32 -32
  258. package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
  259. package/dist/apps/control-plane/application/services/merge-service.js +41 -27
  260. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
  261. package/dist/apps/control-plane/application/services/notifier-service.js +29 -15
  262. package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
  263. package/dist/apps/control-plane/application/services/patch-service.js +21 -19
  264. package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
  265. package/dist/apps/control-plane/application/services/performance-analytics-service.js +4 -4
  266. package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
  267. package/dist/apps/control-plane/application/services/plan-service.js +33 -33
  268. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
  269. package/dist/apps/control-plane/application/services/policy-loader-service.js.map +1 -1
  270. package/dist/apps/control-plane/application/services/pr-monitor-service.js +23 -11
  271. package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
  272. package/dist/apps/control-plane/application/services/qa-index-service.js +11 -11
  273. package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
  274. package/dist/apps/control-plane/application/services/reactions-service.js +13 -9
  275. package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
  276. package/dist/apps/control-plane/application/services/reporting-service.js +11 -9
  277. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
  278. package/dist/apps/control-plane/application/services/run-lease-service.js +34 -33
  279. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
  280. package/dist/apps/control-plane/application/tools/tool-metadata.js +2 -2
  281. package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
  282. package/dist/apps/control-plane/cli/attach-command-handler.js +9 -9
  283. package/dist/apps/control-plane/cli/cleanup-command-handler.js +11 -9
  284. package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -1
  285. package/dist/apps/control-plane/cli/cli-argument-parser.js +4 -3
  286. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
  287. package/dist/apps/control-plane/cli/dashboard-command-handler.js +23 -7
  288. package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
  289. package/dist/apps/control-plane/cli/delete-command-handler.js +7 -7
  290. package/dist/apps/control-plane/cli/help-command-handler.js +58 -30
  291. package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
  292. package/dist/apps/control-plane/cli/init-command-handler.js +44 -33
  293. package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
  294. package/dist/apps/control-plane/cli/io.js +2 -2
  295. package/dist/apps/control-plane/cli/io.js.map +1 -1
  296. package/dist/apps/control-plane/cli/resume-command-handler.js +9 -9
  297. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
  298. package/dist/apps/control-plane/cli/retry-command-handler.js +12 -11
  299. package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
  300. package/dist/apps/control-plane/cli/run-command-handler.js +12 -8
  301. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
  302. package/dist/apps/control-plane/cli/send-command-handler.js +6 -6
  303. package/dist/apps/control-plane/cli/spec-ingestion-service.js +10 -8
  304. package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
  305. package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -1
  306. package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
  307. package/dist/apps/control-plane/cli/status-command-handler.js +8 -8
  308. package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
  309. package/dist/apps/control-plane/cli/tooling.js +1 -1
  310. package/dist/apps/control-plane/core/collisions.js +11 -8
  311. package/dist/apps/control-plane/core/collisions.js.map +1 -1
  312. package/dist/apps/control-plane/core/constants.js +13 -7
  313. package/dist/apps/control-plane/core/constants.js.map +1 -1
  314. package/dist/apps/control-plane/core/error-codes.js +1 -1
  315. package/dist/apps/control-plane/core/fs.js.map +1 -1
  316. package/dist/apps/control-plane/core/gates.d.ts +2 -2
  317. package/dist/apps/control-plane/core/gates.js +26 -19
  318. package/dist/apps/control-plane/core/gates.js.map +1 -1
  319. package/dist/apps/control-plane/core/git.js +3 -3
  320. package/dist/apps/control-plane/core/git.js.map +1 -1
  321. package/dist/apps/control-plane/core/kernel.d.ts +1 -0
  322. package/dist/apps/control-plane/core/kernel.js +134 -81
  323. package/dist/apps/control-plane/core/kernel.js.map +1 -1
  324. package/dist/apps/control-plane/core/patch.js +7 -3
  325. package/dist/apps/control-plane/core/patch.js.map +1 -1
  326. package/dist/apps/control-plane/core/path-layout.d.ts +1 -0
  327. package/dist/apps/control-plane/core/path-layout.js +4 -1
  328. package/dist/apps/control-plane/core/path-layout.js.map +1 -1
  329. package/dist/apps/control-plane/core/path-rules.js +3 -1
  330. package/dist/apps/control-plane/core/path-rules.js.map +1 -1
  331. package/dist/apps/control-plane/core/qa-index.js +5 -5
  332. package/dist/apps/control-plane/core/qa-index.js.map +1 -1
  333. package/dist/apps/control-plane/core/response.js +3 -3
  334. package/dist/apps/control-plane/core/response.js.map +1 -1
  335. package/dist/apps/control-plane/core/schemas.js +10 -6
  336. package/dist/apps/control-plane/core/schemas.js.map +1 -1
  337. package/dist/apps/control-plane/core/workspace-hooks.js +3 -3
  338. package/dist/apps/control-plane/index.d.ts +1 -1
  339. package/dist/apps/control-plane/index.js +1 -1
  340. package/dist/apps/control-plane/index.js.map +1 -1
  341. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +31 -20
  342. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
  343. package/dist/apps/control-plane/mcp/kernel-tool-executor.js +1 -1
  344. package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
  345. package/dist/apps/control-plane/mcp/mcp-server-adapter.js +6 -7
  346. package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -1
  347. package/dist/apps/control-plane/mcp/operation-ledger.js +5 -5
  348. package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -1
  349. package/dist/apps/control-plane/mcp/protocol-contract.js +2 -2
  350. package/dist/apps/control-plane/mcp/runtime-factory.js +2 -2
  351. package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -1
  352. package/dist/apps/control-plane/mcp/token-auth-verifier.js +1 -1
  353. package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -1
  354. package/dist/apps/control-plane/mcp/token-claims-validator.js +5 -5
  355. package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -1
  356. package/dist/apps/control-plane/mcp/tool-authorizer.js +1 -3
  357. package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -1
  358. package/dist/apps/control-plane/mcp/tool-client.js +2 -2
  359. package/dist/apps/control-plane/mcp/tool-client.js.map +1 -1
  360. package/dist/apps/control-plane/mcp/tool-contract-validator.js +3 -3
  361. package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -1
  362. package/dist/apps/control-plane/mcp/tool-registry-loader.js +1 -1
  363. package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -1
  364. package/dist/apps/control-plane/mcp/tool-runtime.js +17 -17
  365. package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
  366. package/dist/apps/control-plane/mcp/tools-markdown-generator.js +6 -1
  367. package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -1
  368. package/dist/apps/control-plane/providers/providers.d.ts +1 -1
  369. package/dist/apps/control-plane/providers/providers.js +31 -34
  370. package/dist/apps/control-plane/providers/providers.js.map +1 -1
  371. package/dist/apps/control-plane/supervisor/build-wave-executor.js +12 -12
  372. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
  373. package/dist/apps/control-plane/supervisor/planning-wave-executor.js +19 -16
  374. package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
  375. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +1 -1
  376. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +13 -13
  377. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
  378. package/dist/apps/control-plane/supervisor/run-coordinator.js +37 -20
  379. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
  380. package/dist/apps/control-plane/supervisor/runtime.js +25 -21
  381. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
  382. package/dist/apps/control-plane/supervisor/session-orchestrator.js +29 -23
  383. package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
  384. package/dist/apps/control-plane/supervisor/types.d.ts +3 -3
  385. package/dist/apps/control-plane/supervisor/types.js.map +1 -1
  386. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +14 -16
  387. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
  388. package/eslint.config.mjs +20 -20
  389. package/example-configurations/README.md +1 -1
  390. package/example-configurations/java/agents.yaml +3 -3
  391. package/example-configurations/java/policy.yaml +1 -1
  392. package/example-configurations/node/agents.yaml +3 -3
  393. package/example-configurations/node/policy.yaml +1 -1
  394. package/package.json +10 -5
  395. package/packages/web-dashboard/next.config.js +2 -2
  396. package/packages/web-dashboard/src/app/api/actions/route.ts +25 -9
  397. package/packages/web-dashboard/src/app/api/events/route.ts +20 -6
  398. package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +88 -37
  399. package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +8 -5
  400. package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +27 -9
  401. package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -2
  402. package/packages/web-dashboard/src/app/api/projects/route.ts +5 -5
  403. package/packages/web-dashboard/src/app/globals.css +10 -2
  404. package/packages/web-dashboard/src/app/page.tsx +100 -37
  405. package/packages/web-dashboard/src/lib/aop-client.ts +68 -37
  406. package/packages/web-dashboard/src/lib/multi-project-config.ts +28 -7
  407. package/packages/web-dashboard/src/lib/orchestrator-tools.ts +59 -36
  408. package/packages/web-dashboard/tsconfig.json +3 -11
  409. package/scripts/nx-safe.mjs +10 -10
  410. package/spec-files/completed/agentic_orchestrator_cli_delete_command_spec.md +5 -0
  411. package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +187 -90
  412. package/spec-files/completed/agentic_orchestrator_init_policy_ux_simplification_spec.md +49 -16
  413. package/spec-files/completed/agentic_orchestrator_mcp_formalization_spec.md +24 -1
  414. package/spec-files/completed/agentic_orchestrator_single_global_orchestrator_spec.md +9 -0
  415. package/spec-files/completed/agentic_orchestrator_spec.md +171 -75
  416. package/spec-files/completed/agentic_orchestrator_validator_hardening_spec.md +25 -17
  417. package/spec-files/outstanding/agentic_orchestrator_artifact_database_publishing_spec.md +40 -5
  418. package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +23 -12
  419. package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +16 -4
  420. package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +42 -2
  421. package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +209 -130
  422. package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +56 -3
  423. package/spec-files/outstanding/agentic_orchestrator_productization_commercial_spec.md +77 -10
  424. package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +29 -14
  425. package/spec-files/progress.md +186 -175
  426. package/tsconfig.json +2 -8
@@ -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,29 @@ 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(
1005
+ input: AcquireRunLeaseInput,
1006
+ ): Promise<{
1007
+ data: {
1008
+ runtime_sessions: RuntimeSessionsSnapshot;
1009
+ took_over_stale: boolean;
1010
+ reused_existing_owner: boolean;
1011
+ };
1012
+ }> {
810
1013
  return await this.runLeaseService.acquireRunLease(input);
811
1014
  }
812
1015
 
813
- async renewRunLease(runId: string, ownerInstanceId: string): Promise<{ data: { lease_expires_at: string } }> {
1016
+ async renewRunLease(
1017
+ runId: string,
1018
+ ownerInstanceId: string,
1019
+ ): Promise<{ data: { lease_expires_at: string } }> {
814
1020
  return await this.runLeaseService.renewRunLease(runId, ownerInstanceId);
815
1021
  }
816
1022
 
817
- async releaseRunLease(runId: string, ownerInstanceId: string): Promise<{ data: { released: boolean } }> {
1023
+ async releaseRunLease(
1024
+ runId: string,
1025
+ ownerInstanceId: string,
1026
+ ): Promise<{ data: { released: boolean } }> {
818
1027
  return await this.runLeaseService.releaseRunLease(runId, ownerInstanceId);
819
1028
  }
820
1029
 
@@ -849,7 +1058,10 @@ export class AopKernel {
849
1058
  async updateState(
850
1059
  featureId: string,
851
1060
  expectedVersion: number | null,
852
- updater: (frontMatter: AnyRecord, body: string) => Promise<{ frontMatter?: AnyRecord; body?: string }>
1061
+ updater: (
1062
+ frontMatter: AnyRecord,
1063
+ body: string,
1064
+ ) => Promise<{ frontMatter?: AnyRecord; body?: string }>,
853
1065
  ) {
854
1066
  return await this.featureStateService.updateState(featureId, expectedVersion, updater);
855
1067
  }
@@ -925,8 +1137,8 @@ export class AopKernel {
925
1137
  feature_id: featureId,
926
1138
  branch,
927
1139
  worktree_path_abs: worktree,
928
- existed: true
929
- }
1140
+ existed: true,
1141
+ },
930
1142
  };
931
1143
  }
932
1144
 
@@ -939,15 +1151,20 @@ export class AopKernel {
939
1151
  const branchCreate = await runGit(this.repoRoot, ['branch', branch, baseRef]);
940
1152
  if (branchCreate.code !== 0) {
941
1153
  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
- })
1154
+ normalizedResponse: fail(
1155
+ ERROR_CODES.GIT_FAILURE,
1156
+ 'Unable to create feature branch',
1157
+ {
1158
+ feature_id: featureId,
1159
+ stderr: branchCreate.stderr,
1160
+ retryable: false,
1161
+ requires_human: true,
1162
+ },
1163
+ {
1164
+ command: ['git', 'branch', branch, baseRef],
1165
+ exit_code: branchCreate.code,
1166
+ },
1167
+ ),
951
1168
  };
952
1169
  }
953
1170
  }
@@ -955,30 +1172,42 @@ export class AopKernel {
955
1172
  const addWorktree = await runGit(this.repoRoot, ['worktree', 'add', worktree, branch]);
956
1173
  if (addWorktree.code !== 0) {
957
1174
  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
- })
1175
+ normalizedResponse: fail(
1176
+ ERROR_CODES.GIT_FAILURE,
1177
+ 'Unable to create git worktree',
1178
+ {
1179
+ feature_id: featureId,
1180
+ stderr: addWorktree.stderr,
1181
+ retryable: false,
1182
+ requires_human: true,
1183
+ },
1184
+ {
1185
+ command: ['git', 'worktree', 'add', worktree, branch],
1186
+ exit_code: addWorktree.code,
1187
+ },
1188
+ ),
967
1189
  };
968
1190
  }
969
1191
 
970
- const worktreeConfig = this.policy.worktree as {
971
- base_branch: string;
972
- symlinks?: string[];
973
- post_create?: string[];
974
- } | undefined;
1192
+ const worktreeConfig = this.policy.worktree as
1193
+ | {
1194
+ base_branch: string;
1195
+ symlinks?: string[];
1196
+ post_create?: string[];
1197
+ }
1198
+ | undefined;
975
1199
  const hookWarnings: WorkspaceHookWarning[] = [];
976
1200
  const collectHookWarning = (warning: WorkspaceHookWarning) => {
977
1201
  hookWarnings.push(warning);
978
1202
  };
979
1203
 
980
1204
  if (worktreeConfig?.symlinks?.length) {
981
- await applyWorktreeSymlinks(this.repoRoot, worktree, worktreeConfig.symlinks, collectHookWarning);
1205
+ await applyWorktreeSymlinks(
1206
+ this.repoRoot,
1207
+ worktree,
1208
+ worktreeConfig.symlinks,
1209
+ collectHookWarning,
1210
+ );
982
1211
  }
983
1212
 
984
1213
  if (worktreeConfig?.post_create?.length) {
@@ -995,8 +1224,8 @@ export class AopKernel {
995
1224
  feature_id: featureId,
996
1225
  branch,
997
1226
  worktree_path_abs: worktree,
998
- existed: false
999
- }
1227
+ existed: false,
1228
+ },
1000
1229
  };
1001
1230
  }
1002
1231
 
@@ -1015,33 +1244,42 @@ export class AopKernel {
1015
1244
  async repoStatus(featureId) {
1016
1245
  const worktree = this.worktreePath(featureId);
1017
1246
  const status = await runGit(this.repoRoot, ['status', '--porcelain'], { cwd: worktree });
1018
- const branch = await runGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: worktree });
1247
+ const branch = await runGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'], {
1248
+ cwd: worktree,
1249
+ });
1019
1250
 
1020
1251
  return {
1021
1252
  data: {
1022
1253
  feature_id: featureId,
1023
1254
  branch: branch.stdout.trim(),
1024
- status_porcelain: status.stdout.trim().split('\n').filter(Boolean)
1025
- }
1255
+ status_porcelain: status.stdout.trim().split('\n').filter(Boolean),
1256
+ },
1026
1257
  };
1027
1258
  }
1028
1259
 
1029
1260
  async repoDiff(featureId, options = []) {
1030
1261
  const safeOptions = asArray<string>(options).filter(
1031
- (option) => typeof option === 'string' && option.startsWith('--')
1262
+ (option) => typeof option === 'string' && option.startsWith('--'),
1032
1263
  );
1033
- const diff = await runGit(this.repoRoot, ['diff', ...safeOptions], { cwd: this.worktreePath(featureId) });
1264
+ const diff = await runGit(this.repoRoot, ['diff', ...safeOptions], {
1265
+ cwd: this.worktreePath(featureId),
1266
+ });
1034
1267
  return {
1035
1268
  data: {
1036
1269
  feature_id: featureId,
1037
- diff: diff.stdout
1038
- }
1270
+ diff: diff.stdout,
1271
+ },
1039
1272
  };
1040
1273
  }
1041
1274
 
1042
1275
  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));
1276
+ const normalized = await normalizeRepoPath(
1277
+ this.repoRoot,
1278
+ path.join(this.worktreePath(featureId), filePath),
1279
+ this.policy.path_rules.allow_symlink_traversal,
1280
+ ).then((relative) =>
1281
+ normalizeFromWorktree(this.worktreePath(featureId), this.repoRoot, relative),
1282
+ );
1045
1283
  const absolute = path.join(this.repoRoot, normalized);
1046
1284
  const exists = await pathExists(absolute);
1047
1285
  if (!exists) {
@@ -1049,8 +1287,8 @@ export class AopKernel {
1049
1287
  normalizedResponse: fail(ERROR_CODES.FILE_NOT_FOUND, 'File not found', {
1050
1288
  path: normalized,
1051
1289
  retryable: false,
1052
- requires_human: false
1053
- })
1290
+ requires_human: false,
1291
+ }),
1054
1292
  };
1055
1293
  }
1056
1294
  const content = await fs.readFile(absolute, 'utf8');
@@ -1058,8 +1296,8 @@ export class AopKernel {
1058
1296
  data: {
1059
1297
  feature_id: featureId,
1060
1298
  path: normalized,
1061
- content
1062
- }
1299
+ content,
1300
+ },
1063
1301
  };
1064
1302
  }
1065
1303
 
@@ -1067,16 +1305,20 @@ export class AopKernel {
1067
1305
  const worktree = this.worktreePath(featureId);
1068
1306
  const rgResult = await runCommand('rg', ['-n', '--no-heading', query, '.'], {
1069
1307
  cwd: worktree,
1070
- timeoutMs: 30_000
1308
+ timeoutMs: 30_000,
1071
1309
  });
1072
1310
 
1073
1311
  if (rgResult.code === 127) {
1074
1312
  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
- })
1313
+ normalizedResponse: fail(
1314
+ ERROR_CODES.GIT_FAILURE,
1315
+ 'ripgrep (rg) not found - required for search functionality',
1316
+ {
1317
+ stderr: rgResult.stderr,
1318
+ retryable: false,
1319
+ requires_human: true,
1320
+ },
1321
+ ),
1080
1322
  };
1081
1323
  }
1082
1324
 
@@ -1085,8 +1327,8 @@ export class AopKernel {
1085
1327
  normalizedResponse: fail(ERROR_CODES.GIT_FAILURE, 'Search failed', {
1086
1328
  stderr: rgResult.stderr,
1087
1329
  retryable: true,
1088
- requires_human: false
1089
- })
1330
+ requires_human: false,
1331
+ }),
1090
1332
  };
1091
1333
  }
1092
1334
 
@@ -1103,7 +1345,7 @@ export class AopKernel {
1103
1345
  return {
1104
1346
  path: line.slice(0, firstColon),
1105
1347
  line: Number(line.slice(firstColon + 1, secondColon)),
1106
- snippet: line.slice(secondColon + 1)
1348
+ snippet: line.slice(secondColon + 1),
1107
1349
  };
1108
1350
  });
1109
1351
 
@@ -1111,15 +1353,19 @@ export class AopKernel {
1111
1353
  data: {
1112
1354
  feature_id: featureId,
1113
1355
  query,
1114
- matches
1115
- }
1356
+ matches,
1357
+ },
1116
1358
  };
1117
1359
  }
1118
1360
 
1119
1361
  async repoDiffBundle(featureId) {
1120
- const stat = await runGit(this.repoRoot, ['diff', '--stat'], { cwd: this.worktreePath(featureId) });
1362
+ const stat = await runGit(this.repoRoot, ['diff', '--stat'], {
1363
+ cwd: this.worktreePath(featureId),
1364
+ });
1121
1365
  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) });
1366
+ const names = await runGit(this.repoRoot, ['diff', '--name-only'], {
1367
+ cwd: this.worktreePath(featureId),
1368
+ });
1123
1369
  const latest = await this.evidenceLatest(featureId);
1124
1370
 
1125
1371
  return {
@@ -1127,9 +1373,12 @@ export class AopKernel {
1127
1373
  feature_id: featureId,
1128
1374
  diff_stat: stat.stdout,
1129
1375
  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
- }
1376
+ touched_files: names.stdout
1377
+ .split('\n')
1378
+ .map((x) => x.trim())
1379
+ .filter(Boolean),
1380
+ last_gate_summary: latest.data?.latest ?? null,
1381
+ },
1133
1382
  };
1134
1383
  }
1135
1384
 
@@ -1154,7 +1403,12 @@ export class AopKernel {
1154
1403
  }
1155
1404
 
1156
1405
  async qaTestIndexUpdate(featureId, expectedVersion, updates, evidenceRefs) {
1157
- return await this.qaIndexService.qaTestIndexUpdate(featureId, expectedVersion, updates, evidenceRefs);
1406
+ return await this.qaIndexService.qaTestIndexUpdate(
1407
+ featureId,
1408
+ expectedVersion,
1409
+ updates,
1410
+ evidenceRefs,
1411
+ );
1158
1412
  }
1159
1413
 
1160
1414
  async locksAcquire(resource, featureId, waitTimeoutSeconds = null) {
@@ -1178,7 +1432,12 @@ export class AopKernel {
1178
1432
  }
1179
1433
 
1180
1434
  async featureReadyToMerge(featureId, commitMessage, mergeStrategy, userApprovalToken) {
1181
- return await this.mergeService.featureReadyToMerge(featureId, commitMessage, mergeStrategy, userApprovalToken);
1435
+ return await this.mergeService.featureReadyToMerge(
1436
+ featureId,
1437
+ commitMessage,
1438
+ mergeStrategy,
1439
+ userApprovalToken,
1440
+ );
1182
1441
  }
1183
1442
 
1184
1443
  async featureDelete(
@@ -1186,13 +1445,13 @@ export class AopKernel {
1186
1445
  dryRun: boolean | null,
1187
1446
  confirm: boolean | null,
1188
1447
  removeWorktree: boolean | null,
1189
- removeBranch: string | null
1448
+ removeBranch: string | null,
1190
1449
  ): Promise<FeatureDeleteResult> {
1191
1450
  return await this.featureDeletionService.featureDelete(featureId, {
1192
1451
  dryRun: dryRun ?? undefined,
1193
1452
  confirm: confirm ?? undefined,
1194
1453
  removeWorktree: removeWorktree ?? undefined,
1195
- removeBranch: removeBranch ?? undefined
1454
+ removeBranch: removeBranch ?? undefined,
1196
1455
  });
1197
1456
  }
1198
1457
 
@@ -1224,21 +1483,34 @@ export class AopKernel {
1224
1483
  }
1225
1484
  }
1226
1485
 
1227
- async featureSendMessage(
1228
- featureId: string | null,
1229
- message: string | null
1230
- ): Promise<unknown> {
1486
+ async featureSendMessage(featureId: string | null, message: string | null): Promise<unknown> {
1231
1487
  if (!featureId) {
1232
- throw { normalizedResponse: fail(ERROR_CODES.INVALID_ARGUMENT, 'feature_id is required', { retryable: false, requires_human: false }) };
1488
+ throw {
1489
+ normalizedResponse: fail(ERROR_CODES.INVALID_ARGUMENT, 'feature_id is required', {
1490
+ retryable: false,
1491
+ requires_human: false,
1492
+ }),
1493
+ };
1233
1494
  }
1234
1495
  if (!message) {
1235
- throw { normalizedResponse: fail(ERROR_CODES.INVALID_ARGUMENT, 'message is required and must not be empty', { retryable: false, requires_human: false }) };
1496
+ throw {
1497
+ normalizedResponse: fail(
1498
+ ERROR_CODES.INVALID_ARGUMENT,
1499
+ 'message is required and must not be empty',
1500
+ { retryable: false, requires_human: false },
1501
+ ),
1502
+ };
1236
1503
  }
1237
1504
 
1238
1505
  const runtimeSessions = await this.getRuntimeSessions();
1239
1506
  const featureSession = runtimeSessions.feature_sessions?.[featureId];
1240
1507
  if (!featureSession) {
1241
- throw { normalizedResponse: { ok: false, error: { code: 'session_not_found', message: 'No active session cluster for feature' } } };
1508
+ throw {
1509
+ normalizedResponse: {
1510
+ ok: false,
1511
+ error: { code: 'session_not_found', message: 'No active session cluster for feature' },
1512
+ },
1513
+ };
1242
1514
  }
1243
1515
 
1244
1516
  const state = await this.readState(featureId);
@@ -1275,7 +1547,12 @@ export class AopKernel {
1275
1547
  }
1276
1548
 
1277
1549
  if (!this.provider?.sendMessage) {
1278
- throw { normalizedResponse: { ok: false, error: { code: 'provider_unsupported', message: 'Provider does not support sendMessage' } } };
1550
+ throw {
1551
+ normalizedResponse: {
1552
+ ok: false,
1553
+ error: { code: 'provider_unsupported', message: 'Provider does not support sendMessage' },
1554
+ },
1555
+ };
1279
1556
  }
1280
1557
 
1281
1558
  await this.waitForSessionToBecomeActive(targetSessionId);
@@ -1285,7 +1562,7 @@ export class AopKernel {
1285
1562
  session_id: targetSessionId,
1286
1563
  target_role: targetRole,
1287
1564
  status,
1288
- delivered: true
1565
+ delivered: true,
1289
1566
  };
1290
1567
  }
1291
1568
 
@@ -1313,7 +1590,7 @@ export class AopKernel {
1313
1590
  retry_count: typeof args.retry_count === 'number' ? args.retry_count : 0,
1314
1591
  duration_ms: typeof args.duration_ms === 'number' ? args.duration_ms : 0,
1315
1592
  cost_usd: typeof args.cost_usd === 'number' ? args.cost_usd : 0,
1316
- recorded_at: nowIso()
1593
+ recorded_at: nowIso(),
1317
1594
  };
1318
1595
  const snapshot = await this.performanceAnalyticsService.recordOutcome(outcome);
1319
1596
  return { ok: true as const, data: { total_outcomes: snapshot.outcomes.length } };
@@ -1323,10 +1600,17 @@ export class AopKernel {
1323
1600
  if (provider || model) {
1324
1601
  const stats = await this.performanceAnalyticsService.getProviderStats(
1325
1602
  provider ?? undefined,
1326
- model ?? undefined
1603
+ model ?? undefined,
1327
1604
  );
1328
1605
  const snapshot = await this.performanceAnalyticsService.getAnalytics();
1329
- return { ok: true as const, data: { outcomes: snapshot.outcomes, aggregates: stats, generated_at: snapshot.generated_at } };
1606
+ return {
1607
+ ok: true as const,
1608
+ data: {
1609
+ outcomes: snapshot.outcomes,
1610
+ aggregates: stats,
1611
+ generated_at: snapshot.generated_at,
1612
+ },
1613
+ };
1330
1614
  }
1331
1615
  const snapshot = await this.performanceAnalyticsService.getAnalytics();
1332
1616
  return { ok: true as const, data: snapshot };
@@ -1341,7 +1625,11 @@ function normalizeRepoPathForState(repoRoot: string, absolutePath: string) {
1341
1625
  return relative;
1342
1626
  }
1343
1627
 
1344
- function normalizeFromWorktree(worktreePath: string, repoRoot: string, repoRelativeFromWorktree: string) {
1628
+ function normalizeFromWorktree(
1629
+ worktreePath: string,
1630
+ repoRoot: string,
1631
+ repoRelativeFromWorktree: string,
1632
+ ) {
1345
1633
  const absolute = path.resolve(repoRoot, repoRelativeFromWorktree);
1346
1634
  const maybeRelativeToWorktree = path.relative(worktreePath, absolute).replaceAll('\\\\', '/');
1347
1635
  if (!maybeRelativeToWorktree.startsWith('../')) {