agentic-orchestrator 0.1.2 → 0.1.4

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 (300) hide show
  1. package/.claude/settings.local.json +15 -0
  2. package/CLAUDE.md +126 -0
  3. package/README.md +166 -25
  4. package/agentic/orchestrator/adapters.yaml +3 -0
  5. package/agentic/orchestrator/gates.yaml +47 -0
  6. package/agentic/orchestrator/policy.yaml +89 -0
  7. package/agentic/orchestrator/schemas/adapters.schema.json +12 -0
  8. package/agentic/orchestrator/schemas/gates.schema.json +6 -1
  9. package/agentic/orchestrator/schemas/index.schema.json +14 -0
  10. package/agentic/orchestrator/schemas/multi-project.schema.json +41 -0
  11. package/agentic/orchestrator/schemas/policy.schema.json +449 -52
  12. package/agentic/orchestrator/schemas/state.schema.json +16 -0
  13. package/agentic/orchestrator/tools/catalog.json +68 -0
  14. package/agentic/orchestrator/tools/schemas/input/cost.get.input.schema.json +10 -0
  15. package/agentic/orchestrator/tools/schemas/input/cost.record.input.schema.json +13 -0
  16. package/agentic/orchestrator/tools/schemas/input/feature.send_message.input.schema.json +11 -0
  17. package/agentic/orchestrator/tools/schemas/input/performance.get_analytics.input.schema.json +10 -0
  18. package/agentic/orchestrator/tools/schemas/input/performance.record_outcome.input.schema.json +18 -0
  19. package/agentic/orchestrator/tools/schemas/output/cost.get.output.schema.json +13 -0
  20. package/agentic/orchestrator/tools/schemas/output/cost.record.output.schema.json +13 -0
  21. package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +7 -0
  22. package/agentic/orchestrator/tools/schemas/output/feature.send_message.output.schema.json +23 -0
  23. package/agentic/orchestrator/tools/schemas/output/performance.get_analytics.output.schema.json +46 -0
  24. package/agentic/orchestrator/tools/schemas/output/performance.record_outcome.output.schema.json +10 -0
  25. package/agentic/orchestrator/tools.md +5 -0
  26. package/apps/control-plane/scripts/validate-architecture-rules.mjs +28 -2
  27. package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +12 -0
  28. package/apps/control-plane/scripts/validate-mcp-contracts.ts +92 -0
  29. package/apps/control-plane/src/application/adapters/adapter-registry.ts +169 -0
  30. package/apps/control-plane/src/application/multi-project-loader.ts +119 -0
  31. package/apps/control-plane/src/application/services/activity-monitor-service.ts +199 -0
  32. package/apps/control-plane/src/application/services/cost-tracking-service.ts +82 -0
  33. package/apps/control-plane/src/application/services/dependency-scheduler-service.ts +86 -0
  34. package/apps/control-plane/src/application/services/feature-deletion-service.ts +8 -7
  35. package/apps/control-plane/src/application/services/gate-interpolation-service.ts +15 -0
  36. package/apps/control-plane/src/application/services/gate-service.ts +38 -2
  37. package/apps/control-plane/src/application/services/instance-isolation-service.ts +18 -0
  38. package/apps/control-plane/src/application/services/issue-tracker-service.ts +469 -0
  39. package/apps/control-plane/src/application/services/merge-service.ts +67 -3
  40. package/apps/control-plane/src/application/services/notifier-service.ts +295 -0
  41. package/apps/control-plane/src/application/services/performance-analytics-service.ts +122 -0
  42. package/apps/control-plane/src/application/services/plan-service.ts +51 -0
  43. package/apps/control-plane/src/application/services/pr-monitor-service.ts +262 -0
  44. package/apps/control-plane/src/application/services/reactions-service.ts +175 -0
  45. package/apps/control-plane/src/application/services/reporting-service.ts +17 -2
  46. package/apps/control-plane/src/application/services/run-lease-service.ts +16 -38
  47. package/apps/control-plane/src/application/tools/tool-metadata.ts +4 -1
  48. package/apps/control-plane/src/cli/aop.ts +1 -1
  49. package/apps/control-plane/src/cli/attach-command-handler.ts +120 -0
  50. package/apps/control-plane/src/cli/cleanup-command-handler.ts +190 -0
  51. package/apps/control-plane/src/cli/cli-argument-parser.ts +69 -3
  52. package/apps/control-plane/src/cli/dashboard-command-handler.ts +57 -0
  53. package/apps/control-plane/src/cli/help-command-handler.ts +163 -0
  54. package/apps/control-plane/src/cli/init-command-handler.ts +609 -0
  55. package/apps/control-plane/src/cli/resume-command-handler.ts +1 -0
  56. package/apps/control-plane/src/cli/retry-command-handler.ts +138 -0
  57. package/apps/control-plane/src/cli/run-command-handler.ts +115 -3
  58. package/apps/control-plane/src/cli/send-command-handler.ts +65 -0
  59. package/apps/control-plane/src/cli/status-command-handler.ts +102 -2
  60. package/apps/control-plane/src/cli/types.ts +26 -1
  61. package/apps/control-plane/src/core/constants.ts +8 -2
  62. package/apps/control-plane/src/core/error-codes.ts +3 -1
  63. package/apps/control-plane/src/core/gates.ts +170 -50
  64. package/apps/control-plane/src/core/kernel.ts +280 -5
  65. package/apps/control-plane/src/core/path-layout.ts +12 -0
  66. package/apps/control-plane/src/core/tool-caller.ts +36 -0
  67. package/apps/control-plane/src/core/workspace-hooks.ts +87 -0
  68. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +258 -9
  69. package/apps/control-plane/src/providers/providers.ts +235 -14
  70. package/apps/control-plane/src/supervisor/build-wave-executor.ts +129 -8
  71. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +123 -5
  72. package/apps/control-plane/src/supervisor/run-coordinator.ts +143 -6
  73. package/apps/control-plane/src/supervisor/runtime.ts +135 -6
  74. package/apps/control-plane/src/supervisor/types.ts +12 -21
  75. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +8 -0
  76. package/apps/control-plane/test/activity-monitor.spec.ts +294 -0
  77. package/apps/control-plane/test/adapter-registry.spec.ts +132 -0
  78. package/apps/control-plane/test/batch-operations.spec.ts +112 -0
  79. package/apps/control-plane/test/bootstrap-attach.spec.ts +102 -0
  80. package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +252 -0
  81. package/apps/control-plane/test/bootstrap.spec.ts +560 -0
  82. package/apps/control-plane/test/cleanup-command.spec.ts +301 -0
  83. package/apps/control-plane/test/cli-helpers.spec.ts +404 -1
  84. package/apps/control-plane/test/cli.unit.spec.ts +182 -1
  85. package/apps/control-plane/test/collision-queue.spec.ts +104 -1
  86. package/apps/control-plane/test/core-utils.spec.ts +175 -2
  87. package/apps/control-plane/test/cost-tracking.spec.ts +143 -0
  88. package/apps/control-plane/test/dashboard-api.integration.spec.ts +247 -0
  89. package/apps/control-plane/test/dashboard-client.spec.ts +116 -0
  90. package/apps/control-plane/test/dashboard-command.spec.ts +103 -0
  91. package/apps/control-plane/test/dependency-scheduler.spec.ts +189 -0
  92. package/apps/control-plane/test/epoch-tracking.spec.ts +4 -4
  93. package/apps/control-plane/test/feature-deletion-service.spec.ts +422 -0
  94. package/apps/control-plane/test/feature-lifecycle.spec.ts +202 -0
  95. package/apps/control-plane/test/git-spawn-error.spec.ts +24 -0
  96. package/apps/control-plane/test/incremental-gates.spec.ts +137 -0
  97. package/apps/control-plane/test/init-wizard.spec.ts +506 -0
  98. package/apps/control-plane/test/instance-isolation.spec.ts +83 -0
  99. package/apps/control-plane/test/issue-tracker.spec.ts +890 -0
  100. package/apps/control-plane/test/kernel.coverage.spec.ts +3 -5
  101. package/apps/control-plane/test/kernel.coverage2.spec.ts +871 -0
  102. package/apps/control-plane/test/kernel.spec.ts +13 -11
  103. package/apps/control-plane/test/lock-service.spec.ts +508 -0
  104. package/apps/control-plane/test/mcp-helpers.spec.ts +176 -0
  105. package/apps/control-plane/test/mcp.spec.ts +50 -15
  106. package/apps/control-plane/test/merge-service.spec.ts +67 -4
  107. package/apps/control-plane/test/multi-project.spec.ts +372 -0
  108. package/apps/control-plane/test/notifier-service.spec.ts +388 -0
  109. package/apps/control-plane/test/parallel-gates.spec.ts +312 -0
  110. package/apps/control-plane/test/patch-service.spec.ts +253 -0
  111. package/apps/control-plane/test/performance-analytics.spec.ts +338 -0
  112. package/apps/control-plane/test/planning-wave-executor.spec.ts +168 -0
  113. package/apps/control-plane/test/pr-monitor.spec.ts +385 -0
  114. package/apps/control-plane/test/providers.spec.ts +344 -1
  115. package/apps/control-plane/test/reactions.spec.ts +392 -0
  116. package/apps/control-plane/test/resume-command.spec.ts +390 -0
  117. package/apps/control-plane/test/run-coordinator.spec.ts +481 -2
  118. package/apps/control-plane/test/schema-date-time.spec.ts +46 -0
  119. package/apps/control-plane/test/service-retry-paths.spec.ts +30 -0
  120. package/apps/control-plane/test/services.spec.ts +95 -2
  121. package/apps/control-plane/test/session-management.spec.ts +450 -0
  122. package/apps/control-plane/test/spec-ingestion.spec.ts +190 -0
  123. package/apps/control-plane/test/supervisor-collaborators.spec.ts +699 -2
  124. package/apps/control-plane/test/supervisor.spec.ts +36 -30
  125. package/apps/control-plane/test/supervisor.unit.spec.ts +405 -0
  126. package/apps/control-plane/test/worker-decision-loop.spec.ts +57 -0
  127. package/apps/control-plane/test/workspace-hooks.spec.ts +177 -0
  128. package/apps/control-plane/vitest.config.ts +21 -5
  129. package/dist/apps/control-plane/application/adapters/adapter-registry.d.ts +44 -0
  130. package/dist/apps/control-plane/application/adapters/adapter-registry.js +76 -0
  131. package/dist/apps/control-plane/application/adapters/adapter-registry.js.map +1 -0
  132. package/dist/apps/control-plane/application/multi-project-loader.d.ts +31 -0
  133. package/dist/apps/control-plane/application/multi-project-loader.js +82 -0
  134. package/dist/apps/control-plane/application/multi-project-loader.js.map +1 -0
  135. package/dist/apps/control-plane/application/services/activity-monitor-service.d.ts +43 -0
  136. package/dist/apps/control-plane/application/services/activity-monitor-service.js +132 -0
  137. package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -0
  138. package/dist/apps/control-plane/application/services/cost-tracking-service.d.ts +28 -0
  139. package/dist/apps/control-plane/application/services/cost-tracking-service.js +48 -0
  140. package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -0
  141. package/dist/apps/control-plane/application/services/dependency-scheduler-service.d.ts +26 -0
  142. package/dist/apps/control-plane/application/services/dependency-scheduler-service.js +75 -0
  143. package/dist/apps/control-plane/application/services/dependency-scheduler-service.js.map +1 -0
  144. package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +2 -0
  145. package/dist/apps/control-plane/application/services/feature-deletion-service.js +6 -7
  146. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
  147. package/dist/apps/control-plane/application/services/gate-interpolation-service.d.ts +7 -0
  148. package/dist/apps/control-plane/application/services/gate-interpolation-service.js +7 -0
  149. package/dist/apps/control-plane/application/services/gate-interpolation-service.js.map +1 -0
  150. package/dist/apps/control-plane/application/services/gate-service.js +32 -2
  151. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
  152. package/dist/apps/control-plane/application/services/instance-isolation-service.d.ts +11 -0
  153. package/dist/apps/control-plane/application/services/instance-isolation-service.js +17 -0
  154. package/dist/apps/control-plane/application/services/instance-isolation-service.js.map +1 -0
  155. package/dist/apps/control-plane/application/services/issue-tracker-service.d.ts +65 -0
  156. package/dist/apps/control-plane/application/services/issue-tracker-service.js +358 -0
  157. package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -0
  158. package/dist/apps/control-plane/application/services/merge-service.d.ts +4 -0
  159. package/dist/apps/control-plane/application/services/merge-service.js +44 -2
  160. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
  161. package/dist/apps/control-plane/application/services/notifier-service.d.ts +74 -0
  162. package/dist/apps/control-plane/application/services/notifier-service.js +212 -0
  163. package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -0
  164. package/dist/apps/control-plane/application/services/performance-analytics-service.d.ts +39 -0
  165. package/dist/apps/control-plane/application/services/performance-analytics-service.js +75 -0
  166. package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -0
  167. package/dist/apps/control-plane/application/services/plan-service.d.ts +1 -0
  168. package/dist/apps/control-plane/application/services/plan-service.js +53 -0
  169. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
  170. package/dist/apps/control-plane/application/services/pr-monitor-service.d.ts +44 -0
  171. package/dist/apps/control-plane/application/services/pr-monitor-service.js +192 -0
  172. package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -0
  173. package/dist/apps/control-plane/application/services/reactions-service.d.ts +67 -0
  174. package/dist/apps/control-plane/application/services/reactions-service.js +114 -0
  175. package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -0
  176. package/dist/apps/control-plane/application/services/reporting-service.d.ts +1 -0
  177. package/dist/apps/control-plane/application/services/reporting-service.js +13 -2
  178. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
  179. package/dist/apps/control-plane/application/services/run-lease-service.d.ts +2 -0
  180. package/dist/apps/control-plane/application/services/run-lease-service.js +14 -38
  181. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
  182. package/dist/apps/control-plane/application/tools/tool-metadata.js +3 -1
  183. package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -1
  184. package/dist/apps/control-plane/cli/aop.d.ts +1 -1
  185. package/dist/apps/control-plane/cli/aop.js +1 -1
  186. package/dist/apps/control-plane/cli/attach-command-handler.d.ts +12 -0
  187. package/dist/apps/control-plane/cli/attach-command-handler.js +98 -0
  188. package/dist/apps/control-plane/cli/attach-command-handler.js.map +1 -0
  189. package/dist/apps/control-plane/cli/cleanup-command-handler.d.ts +12 -0
  190. package/dist/apps/control-plane/cli/cleanup-command-handler.js +162 -0
  191. package/dist/apps/control-plane/cli/cleanup-command-handler.js.map +1 -0
  192. package/dist/apps/control-plane/cli/cli-argument-parser.js +73 -3
  193. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
  194. package/dist/apps/control-plane/cli/dashboard-command-handler.d.ts +7 -0
  195. package/dist/apps/control-plane/cli/dashboard-command-handler.js +45 -0
  196. package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -0
  197. package/dist/apps/control-plane/cli/help-command-handler.d.ts +8 -0
  198. package/dist/apps/control-plane/cli/help-command-handler.js +146 -0
  199. package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -0
  200. package/dist/apps/control-plane/cli/init-command-handler.d.ts +26 -0
  201. package/dist/apps/control-plane/cli/init-command-handler.js +517 -0
  202. package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -0
  203. package/dist/apps/control-plane/cli/resume-command-handler.js +1 -1
  204. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
  205. package/dist/apps/control-plane/cli/retry-command-handler.d.ts +8 -0
  206. package/dist/apps/control-plane/cli/retry-command-handler.js +111 -0
  207. package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -0
  208. package/dist/apps/control-plane/cli/run-command-handler.d.ts +5 -0
  209. package/dist/apps/control-plane/cli/run-command-handler.js +82 -3
  210. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
  211. package/dist/apps/control-plane/cli/send-command-handler.d.ts +8 -0
  212. package/dist/apps/control-plane/cli/send-command-handler.js +55 -0
  213. package/dist/apps/control-plane/cli/send-command-handler.js.map +1 -0
  214. package/dist/apps/control-plane/cli/status-command-handler.d.ts +12 -1
  215. package/dist/apps/control-plane/cli/status-command-handler.js +55 -2
  216. package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
  217. package/dist/apps/control-plane/cli/types.d.ts +26 -1
  218. package/dist/apps/control-plane/cli/types.js +15 -1
  219. package/dist/apps/control-plane/cli/types.js.map +1 -1
  220. package/dist/apps/control-plane/core/constants.d.ts +6 -0
  221. package/dist/apps/control-plane/core/constants.js +8 -2
  222. package/dist/apps/control-plane/core/constants.js.map +1 -1
  223. package/dist/apps/control-plane/core/error-codes.d.ts +2 -0
  224. package/dist/apps/control-plane/core/error-codes.js +3 -1
  225. package/dist/apps/control-plane/core/error-codes.js.map +1 -1
  226. package/dist/apps/control-plane/core/gates.d.ts +4 -0
  227. package/dist/apps/control-plane/core/gates.js +140 -43
  228. package/dist/apps/control-plane/core/gates.js.map +1 -1
  229. package/dist/apps/control-plane/core/kernel.d.ts +50 -1
  230. package/dist/apps/control-plane/core/kernel.js +220 -7
  231. package/dist/apps/control-plane/core/kernel.js.map +1 -1
  232. package/dist/apps/control-plane/core/path-layout.d.ts +3 -0
  233. package/dist/apps/control-plane/core/path-layout.js +9 -0
  234. package/dist/apps/control-plane/core/path-layout.js.map +1 -1
  235. package/dist/apps/control-plane/core/tool-caller.d.ts +32 -0
  236. package/dist/apps/control-plane/core/tool-caller.js +2 -0
  237. package/dist/apps/control-plane/core/tool-caller.js.map +1 -0
  238. package/dist/apps/control-plane/core/workspace-hooks.d.ts +20 -0
  239. package/dist/apps/control-plane/core/workspace-hooks.js +69 -0
  240. package/dist/apps/control-plane/core/workspace-hooks.js.map +1 -0
  241. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +245 -9
  242. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
  243. package/dist/apps/control-plane/providers/providers.d.ts +42 -3
  244. package/dist/apps/control-plane/providers/providers.js +216 -5
  245. package/dist/apps/control-plane/providers/providers.js.map +1 -1
  246. package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +3 -0
  247. package/dist/apps/control-plane/supervisor/build-wave-executor.js +115 -6
  248. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
  249. package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +3 -0
  250. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +109 -5
  251. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
  252. package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +15 -0
  253. package/dist/apps/control-plane/supervisor/run-coordinator.js +132 -6
  254. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
  255. package/dist/apps/control-plane/supervisor/runtime.d.ts +3 -0
  256. package/dist/apps/control-plane/supervisor/runtime.js +110 -6
  257. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
  258. package/dist/apps/control-plane/supervisor/types.d.ts +9 -16
  259. package/dist/apps/control-plane/supervisor/types.js.map +1 -1
  260. package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +3 -0
  261. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +5 -0
  262. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
  263. package/eslint.config.mjs +2 -1
  264. package/package.json +12 -2
  265. package/packages/web-dashboard/next-env.d.ts +5 -0
  266. package/packages/web-dashboard/next.config.js +7 -0
  267. package/packages/web-dashboard/package.json +26 -0
  268. package/packages/web-dashboard/src/app/api/actions/route.ts +64 -0
  269. package/packages/web-dashboard/src/app/api/events/route.ts +51 -0
  270. package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +256 -0
  271. package/packages/web-dashboard/src/app/api/features/[id]/diff/route.ts +10 -0
  272. package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +25 -0
  273. package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +63 -0
  274. package/packages/web-dashboard/src/app/api/features/[id]/route.ts +16 -0
  275. package/packages/web-dashboard/src/app/api/projects/route.ts +31 -0
  276. package/packages/web-dashboard/src/app/api/status/route.ts +15 -0
  277. package/packages/web-dashboard/src/app/globals.css +2 -0
  278. package/packages/web-dashboard/src/app/layout.tsx +15 -0
  279. package/packages/web-dashboard/src/app/page.tsx +393 -0
  280. package/packages/web-dashboard/src/lib/aop-client.ts +244 -0
  281. package/packages/web-dashboard/src/lib/multi-project-config.ts +116 -0
  282. package/packages/web-dashboard/src/lib/orchestrator-tools.ts +284 -0
  283. package/packages/web-dashboard/src/lib/types.ts +58 -0
  284. package/packages/web-dashboard/tsconfig.json +40 -0
  285. package/packages/web-dashboard/vitest.config.ts +6 -0
  286. package/spec-files/completed/agentic_orchestrator_feature_gaps_closure_spec.md +1764 -0
  287. package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +348 -0
  288. package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +344 -0
  289. package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +374 -0
  290. package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +1059 -0
  291. package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +466 -0
  292. package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +198 -0
  293. package/spec-files/outstanding/agentic_orchestrator_validator_hardening_spec.md +365 -0
  294. package/spec-files/progress.md +481 -52
  295. /package/spec-files/{agentic_orchestrator_cli_delete_command_spec.md → completed/agentic_orchestrator_cli_delete_command_spec.md} +0 -0
  296. /package/spec-files/{agentic_orchestrator_dot_aop_generated_artifacts_spec.md → completed/agentic_orchestrator_dot_aop_generated_artifacts_spec.md} +0 -0
  297. /package/spec-files/{agentic_orchestrator_mcp_formalization_spec.md → completed/agentic_orchestrator_mcp_formalization_spec.md} +0 -0
  298. /package/spec-files/{agentic_orchestrator_oop_refactor_spec.md → completed/agentic_orchestrator_oop_refactor_spec.md} +0 -0
  299. /package/spec-files/{agentic_orchestrator_single_global_orchestrator_spec.md → completed/agentic_orchestrator_single_global_orchestrator_spec.md} +0 -0
  300. /package/spec-files/{agentic_orchestrator_spec.md → completed/agentic_orchestrator_spec.md} +0 -0
@@ -1,5 +1,7 @@
1
1
  import crypto from 'node:crypto';
2
+ import { spawn } from 'node:child_process';
2
3
  import { ERROR_CODES } from '../core/error-codes.js';
4
+ import { REGISTERED_PROVIDER_NAMES } from '../application/adapters/adapter-registry.js';
3
5
 
4
6
  export interface AppError extends Error {
5
7
  code?: string;
@@ -7,7 +9,7 @@ export interface AppError extends Error {
7
9
  }
8
10
 
9
11
  export interface ProviderSelection {
10
- provider: 'codex' | 'claude' | 'gemini' | 'custom' | 'kiro-cli' | 'copilot';
12
+ provider: string;
11
13
  model: string;
12
14
  provider_config_env: string | null;
13
15
  provider_config_ref: string | null;
@@ -85,15 +87,8 @@ function resolveConfiguredAgentConfig(
85
87
  return null;
86
88
  }
87
89
 
88
- export const SUPPORTED_PROVIDERS = new Set<ProviderSelection['provider']>([
89
- 'codex',
90
- 'claude',
91
- 'gemini',
92
- 'custom',
93
- 'kiro-cli',
94
- 'copilot'
95
- ]);
96
- export const AUTH_REQUIRED_PROVIDERS = new Set<ProviderSelection['provider']>(['codex', 'claude', 'gemini']);
90
+ export const SUPPORTED_PROVIDERS: Set<string> = new Set(REGISTERED_PROVIDER_NAMES);
91
+ export const AUTH_REQUIRED_PROVIDERS: Set<string> = new Set(['codex', 'claude', 'gemini']);
97
92
  export type ProviderSelectionResolver = (input: ResolveSelectionInput) => ProviderSelection;
98
93
 
99
94
  export const resolveProviderSelection: ProviderSelectionResolver = ({ cli, env, agentsConfig }) => {
@@ -121,7 +116,7 @@ export const resolveProviderSelection: ProviderSelectionResolver = ({ cli, env,
121
116
  throw error;
122
117
  }
123
118
 
124
- if (!SUPPORTED_PROVIDERS.has(provider as ProviderSelection['provider'])) {
119
+ if (!SUPPORTED_PROVIDERS.has(provider)) {
125
120
  const error = new Error(ERROR_CODES.UNSUPPORTED_AGENT_PROVIDER) as AppError;
126
121
  error.code = ERROR_CODES.UNSUPPORTED_AGENT_PROVIDER;
127
122
  error.details = { provider };
@@ -129,7 +124,7 @@ export const resolveProviderSelection: ProviderSelectionResolver = ({ cli, env,
129
124
  }
130
125
 
131
126
  if (
132
- AUTH_REQUIRED_PROVIDERS.has(provider as ProviderSelection['provider']) &&
127
+ AUTH_REQUIRED_PROVIDERS.has(provider) &&
133
128
  (!providerConfigEnv || !env[providerConfigEnv])
134
129
  ) {
135
130
  const error = new Error(ERROR_CODES.PROVIDER_AUTH_MISSING) as AppError;
@@ -151,7 +146,7 @@ export const resolveProviderSelection: ProviderSelectionResolver = ({ cli, env,
151
146
  : resolveConfiguredAgentConfig(provider, agentsConfig?.runtime);
152
147
 
153
148
  return {
154
- provider: provider as ProviderSelection['provider'],
149
+ provider,
155
150
  model: model ?? `${provider}-default`,
156
151
  provider_config_env: providerConfigEnv,
157
152
  provider_config_ref: providerConfigEnv ? env[providerConfigEnv] ?? null : null,
@@ -183,13 +178,205 @@ export interface WorkerProvider {
183
178
  provider_config_ref: string | null;
184
179
  };
185
180
  }): Promise<Record<string, unknown>>;
181
+ sendMessage?(sessionId: string, message: string): Promise<void>;
182
+ attachToSession?(sessionId: string): Promise<void>;
183
+ getSessionInfo?(sessionId: string): Promise<{ active: boolean; provider: string }>;
184
+ }
185
+
186
+ export interface ProviderCommandResult {
187
+ exitCode: number;
188
+ signal: NodeJS.Signals | null;
189
+ errorCode?: number | string;
190
+ }
191
+
192
+ export interface ProviderCommandRunnerOptions {
193
+ interactive?: boolean;
194
+ stdin?: string;
195
+ env?: NodeJS.ProcessEnv;
196
+ timeoutMs?: number;
197
+ }
198
+
199
+ export interface ProviderCommandRunner {
200
+ run(command: string, args: string[], options?: ProviderCommandRunnerOptions): Promise<ProviderCommandResult>;
201
+ }
202
+
203
+ export class NodeProviderCommandRunner implements ProviderCommandRunner {
204
+ async run(command: string, args: string[], options: ProviderCommandRunnerOptions = {}): Promise<ProviderCommandResult> {
205
+ return await new Promise<ProviderCommandResult>((resolve) => {
206
+ let child;
207
+ try {
208
+ child = spawn(command, args, {
209
+ env: options.env,
210
+ stdio: options.interactive ? 'inherit' : ['pipe', 'pipe', 'pipe']
211
+ });
212
+ } catch {
213
+ resolve({
214
+ exitCode: 127,
215
+ signal: null,
216
+ errorCode: 'ENOENT'
217
+ });
218
+ return;
219
+ }
220
+
221
+ let spawnErrorCode: number | string | undefined;
222
+ child.on('error', (error: NodeJS.ErrnoException) => {
223
+ spawnErrorCode = error.code;
224
+ });
225
+
226
+ if (!options.interactive && typeof options.stdin === 'string' && child.stdin) {
227
+ child.stdin.write(options.stdin);
228
+ }
229
+ if (!options.interactive && child.stdin) {
230
+ child.stdin.end();
231
+ }
232
+
233
+ let timeoutHandle: NodeJS.Timeout | null = null;
234
+ if (!options.interactive && typeof options.timeoutMs === 'number' && options.timeoutMs > 0) {
235
+ timeoutHandle = setTimeout(() => {
236
+ child.kill('SIGKILL');
237
+ }, options.timeoutMs);
238
+ }
239
+
240
+ child.on('close', (code, signal) => {
241
+ if (timeoutHandle) {
242
+ clearTimeout(timeoutHandle);
243
+ }
244
+ resolve({
245
+ exitCode: code ?? (spawnErrorCode === 'ENOENT' ? 127 : 1),
246
+ signal,
247
+ errorCode: spawnErrorCode
248
+ });
249
+ });
250
+ });
251
+ }
252
+ }
253
+
254
+ interface ProviderCommandTemplate {
255
+ command: string;
256
+ args: string[];
257
+ }
258
+
259
+ interface ProviderCliCommands {
260
+ attach?: ProviderCommandTemplate;
261
+ send?: ProviderCommandTemplate;
262
+ }
263
+
264
+ interface NullWorkerProviderOptions {
265
+ commandRunner?: ProviderCommandRunner;
266
+ }
267
+
268
+ function readStringArray(value: unknown): string[] | null {
269
+ if (!Array.isArray(value)) {
270
+ return null;
271
+ }
272
+ const strings = value.filter((item): item is string => typeof item === 'string');
273
+ return strings.length === value.length ? strings : null;
274
+ }
275
+
276
+ function resolveTemplateFromAgentConfig(
277
+ agentConfig: Record<string, unknown> | null | undefined,
278
+ kind: 'attach' | 'send',
279
+ fallback: ProviderCommandTemplate | undefined
280
+ ): ProviderCommandTemplate | undefined {
281
+ const nested = agentConfig?.[kind];
282
+ const nestedRecord = isPlainObject(nested) ? nested : null;
283
+
284
+ const explicitCommandKey = `${kind}_command`;
285
+ const explicitArgsKey = `${kind}_args`;
286
+ const explicitCommandValue = agentConfig?.[explicitCommandKey];
287
+ const command =
288
+ (nestedRecord && typeof nestedRecord.command === 'string' && nestedRecord.command.length > 0
289
+ ? nestedRecord.command
290
+ : null) ??
291
+ (typeof explicitCommandValue === 'string' && explicitCommandValue.length > 0
292
+ ? explicitCommandValue
293
+ : null) ??
294
+ fallback?.command;
295
+
296
+ const nestedArgs = nestedRecord ? readStringArray(nestedRecord.args) : null;
297
+ const explicitArgs = readStringArray(agentConfig?.[explicitArgsKey]);
298
+ const args = nestedArgs ?? explicitArgs ?? fallback?.args;
299
+
300
+ if (!command || !args) {
301
+ return undefined;
302
+ }
303
+ return { command, args };
304
+ }
305
+
306
+ function resolveProviderCommands(selection: ProviderSelection): ProviderCliCommands {
307
+ const defaults: Record<string, ProviderCliCommands> = {
308
+ codex: {
309
+ attach: { command: 'codex', args: ['chat', '--session', '{session_id}'] },
310
+ send: { command: 'codex', args: ['chat', '--session', '{session_id}', '--message', '{message}'] }
311
+ },
312
+ claude: {
313
+ attach: { command: 'claude-code', args: ['chat', '--session', '{session_id}'] },
314
+ send: { command: 'claude-code', args: ['chat', '--session', '{session_id}', '--message', '{message}'] }
315
+ }
316
+ };
317
+
318
+ const defaultsForProvider = defaults[selection.provider] ?? {};
319
+ return {
320
+ attach: resolveTemplateFromAgentConfig(selection.agent_config, 'attach', defaultsForProvider.attach),
321
+ send: resolveTemplateFromAgentConfig(selection.agent_config, 'send', defaultsForProvider.send)
322
+ };
323
+ }
324
+
325
+ function applyCommandArgsTemplate(
326
+ args: string[],
327
+ values: { sessionId: string; message?: string }
328
+ ): string[] {
329
+ return args.map((arg) => {
330
+ if (arg === '{session_id}') {
331
+ return values.sessionId;
332
+ }
333
+ if (arg === '{message}') {
334
+ return values.message ?? '';
335
+ }
336
+ return arg;
337
+ });
338
+ }
339
+
340
+ function commandFailureError(
341
+ provider: string,
342
+ capability: 'attach' | 'send',
343
+ details: Record<string, unknown>,
344
+ code: string
345
+ ): AppError {
346
+ const error = new Error(`${provider} provider ${capability} failed`) as AppError;
347
+ error.code = code;
348
+ error.details = details;
349
+ return error;
186
350
  }
187
351
 
188
352
  export class NullWorkerProvider implements WorkerProvider {
189
353
  selection: ProviderSelection;
354
+ sendMessage?: (sessionId: string, message: string) => Promise<void>;
355
+ attachToSession?: (sessionId: string) => Promise<void>;
356
+ getSessionInfo?: (sessionId: string) => Promise<{ active: boolean; provider: string }>;
357
+ private readonly commandRunner: ProviderCommandRunner;
358
+ private readonly commands: ProviderCliCommands;
190
359
 
191
- constructor(selection: ProviderSelection) {
360
+ constructor(selection: ProviderSelection, options: NullWorkerProviderOptions = {}) {
192
361
  this.selection = selection;
362
+ this.commandRunner = options.commandRunner ?? new NodeProviderCommandRunner();
363
+ this.commands = resolveProviderCommands(selection);
364
+
365
+ if (this.commands.send) {
366
+ this.sendMessage = async (sessionId: string, message: string) => {
367
+ await this.executeCommand('send', sessionId, message);
368
+ };
369
+ }
370
+ if (this.commands.attach) {
371
+ this.attachToSession = async (sessionId: string) => {
372
+ await this.executeCommand('attach', sessionId);
373
+ };
374
+ this.getSessionInfo = (sessionId: string) =>
375
+ Promise.resolve({
376
+ active: Boolean(sessionId) && sessionId !== 'unknown' && sessionId !== 'unassigned',
377
+ provider: this.selection.provider
378
+ });
379
+ }
193
380
  }
194
381
 
195
382
  createSession(role: string, featureId: string, systemPrompt: string | null): Promise<WorkerSession> {
@@ -255,4 +442,38 @@ export class NullWorkerProvider implements WorkerProvider {
255
442
  content: `${role} session active for ${feature_id}.`
256
443
  });
257
444
  }
445
+
446
+ private async executeCommand(kind: 'attach' | 'send', sessionId: string, message?: string): Promise<void> {
447
+ const template = kind === 'attach' ? this.commands.attach : this.commands.send;
448
+ if (!template) {
449
+ throw commandFailureError(
450
+ this.selection.provider,
451
+ kind,
452
+ { reason: `Provider ${this.selection.provider} does not support ${kind}` },
453
+ ERROR_CODES.UNSUPPORTED_AGENT_PROVIDER
454
+ );
455
+ }
456
+
457
+ const args = applyCommandArgsTemplate(template.args, { sessionId, message });
458
+ const result = await this.commandRunner.run(template.command, args, {
459
+ interactive: kind === 'attach',
460
+ timeoutMs: kind === 'send' ? 15_000 : undefined
461
+ });
462
+
463
+ if (result.exitCode === 0) {
464
+ return;
465
+ }
466
+
467
+ const details = {
468
+ command: template.command,
469
+ args,
470
+ exit_code: result.exitCode,
471
+ signal: result.signal,
472
+ error_code: result.errorCode
473
+ };
474
+ if (result.exitCode === 127 || result.errorCode === 'ENOENT') {
475
+ throw commandFailureError(this.selection.provider, kind, details, ERROR_CODES.UNSUPPORTED_AGENT_PROVIDER);
476
+ }
477
+ throw commandFailureError(this.selection.provider, kind, details, ERROR_CODES.INTERNAL_ERROR);
478
+ }
258
479
  }
@@ -1,19 +1,28 @@
1
- import { STATUS, TOOLS } from '../core/constants.js';
1
+ import { GATE_RESULT, STATUS, TOOLS } from '../core/constants.js';
2
2
  import type { FeatureStatePayload, SupervisorToolCaller } from './types.js';
3
3
  import { NOOP_WORKER_DECISION_RUNNER, type WorkerDecisionRunner } from './worker-decision-loop.js';
4
+ import type { GateRepairContext, ReactionsService } from '../application/services/reactions-service.js';
5
+
6
+ interface GatesRunData {
7
+ overall?: string;
8
+ evidence_path?: string;
9
+ }
4
10
 
5
11
  interface BuildWaveExecutorDependencies {
6
12
  toolCaller: SupervisorToolCaller;
7
13
  workerDecisionRunner?: WorkerDecisionRunner;
14
+ reactionsService?: ReactionsService;
8
15
  }
9
16
 
10
17
  export class BuildWaveExecutor {
11
18
  private readonly toolCaller: SupervisorToolCaller;
12
19
  private readonly workerDecisionRunner: WorkerDecisionRunner;
20
+ private readonly reactionsService: ReactionsService | undefined;
13
21
 
14
22
  constructor(dependencies: BuildWaveExecutorDependencies) {
15
23
  this.toolCaller = dependencies.toolCaller;
16
24
  this.workerDecisionRunner = dependencies.workerDecisionRunner ?? NOOP_WORKER_DECISION_RUNNER;
25
+ this.reactionsService = dependencies.reactionsService;
17
26
  }
18
27
 
19
28
  async run(featureIds: string[], maxParallelGateRuns: number): Promise<void> {
@@ -42,13 +51,125 @@ export class BuildWaveExecutor {
42
51
  });
43
52
  }
44
53
 
45
- const executing = selected.map((featureId) =>
46
- this.toolCaller.callTool('builder', TOOLS.GATES_RUN, {
47
- feature_id: featureId,
48
- profile: null,
49
- mode: 'fast'
50
- })
51
- );
54
+ const executing = selected.map(async (featureId) => {
55
+ const stateForRetry = await this.toolCaller.callTool<FeatureStatePayload>('builder', TOOLS.FEATURE_STATE_GET, {
56
+ feature_id: featureId
57
+ });
58
+ const initialRetryCount = stateForRetry.data.front_matter.gate_retry_count ?? 0;
59
+
60
+ let gateOverall: string;
61
+ let gateExitCode: number;
62
+ let gateEvidencePath = '';
63
+ let gateLogs = '';
64
+ const failureHistory: GateRepairContext['failureHistory'] = [];
65
+
66
+ try {
67
+ const gateResult = await this.toolCaller.callTool<GatesRunData>('builder', TOOLS.GATES_RUN, {
68
+ feature_id: featureId,
69
+ profile: null,
70
+ mode: 'fast'
71
+ });
72
+ gateOverall = gateResult.data.overall ?? GATE_RESULT.PASS;
73
+ gateExitCode = gateOverall === GATE_RESULT.FAIL ? 1 : 0;
74
+ gateEvidencePath = gateResult.data.evidence_path ?? '';
75
+ } catch (error) {
76
+ gateOverall = GATE_RESULT.FAIL;
77
+ gateExitCode = 1;
78
+ const typed = error as { message?: string };
79
+ gateLogs = typed.message ?? '';
80
+ }
81
+
82
+ if (gateOverall === GATE_RESULT.FAIL) {
83
+ failureHistory.push({
84
+ attempt: initialRetryCount + 1,
85
+ gate_name: 'fast',
86
+ exit_code: gateExitCode,
87
+ evidence_summary: gateEvidencePath,
88
+ logs_excerpt: gateLogs.slice(0, 800),
89
+ failed_at: new Date().toISOString(),
90
+ retry_delay_ms: this.reactionsService?.retryDelayMs()
91
+ });
92
+ }
93
+
94
+ if (this.reactionsService && gateOverall === GATE_RESULT.FAIL) {
95
+ const context = await this.toolCaller.callTool('builder', TOOLS.FEATURE_GET_CONTEXT, {
96
+ feature_id: featureId
97
+ });
98
+ let retryCount = initialRetryCount;
99
+ const retryDelayMs = this.reactionsService.retryDelayMs();
100
+ while (this.reactionsService.shouldRetry(featureId, retryCount)) {
101
+ if (typeof this.reactionsService.waitBeforeRetry === 'function') {
102
+ await this.reactionsService.waitBeforeRetry();
103
+ }
104
+ const attempt = retryCount + 2;
105
+ const ctx: GateRepairContext = {
106
+ featureId,
107
+ gateName: 'fast',
108
+ exitCode: gateExitCode,
109
+ logs: gateLogs,
110
+ evidenceSummary: gateEvidencePath,
111
+ retryCount,
112
+ failureHistory
113
+ };
114
+ const repairPrompt = this.reactionsService.buildRepairPrompt(ctx);
115
+ await this.workerDecisionRunner.execute({
116
+ role: 'builder',
117
+ featureId,
118
+ contextBundle: context.data,
119
+ instructions: repairPrompt
120
+ });
121
+
122
+ try {
123
+ const retryResult = await this.toolCaller.callTool<GatesRunData>('builder', TOOLS.GATES_RUN, {
124
+ feature_id: featureId,
125
+ profile: null,
126
+ mode: 'fast'
127
+ });
128
+ gateOverall = retryResult.data.overall ?? GATE_RESULT.PASS;
129
+ gateExitCode = gateOverall === GATE_RESULT.FAIL ? 1 : 0;
130
+ gateEvidencePath = retryResult.data.evidence_path ?? gateEvidencePath;
131
+ gateLogs = '';
132
+ } catch (error) {
133
+ gateOverall = GATE_RESULT.FAIL;
134
+ gateExitCode = 1;
135
+ const typed = error as { message?: string };
136
+ gateLogs = typed.message ?? '';
137
+ }
138
+
139
+ retryCount += 1;
140
+ await this.reactionsService.recordRetry(featureId, retryCount);
141
+
142
+ if (gateOverall === GATE_RESULT.FAIL) {
143
+ failureHistory.push({
144
+ attempt,
145
+ gate_name: 'fast',
146
+ exit_code: gateExitCode,
147
+ evidence_summary: gateEvidencePath,
148
+ logs_excerpt: gateLogs.slice(0, 800),
149
+ failed_at: new Date().toISOString(),
150
+ retry_delay_ms: retryDelayMs
151
+ });
152
+ }
153
+
154
+ if (gateOverall === GATE_RESULT.PASS) {
155
+ break;
156
+ }
157
+ }
158
+
159
+ if (gateOverall === GATE_RESULT.FAIL && this.reactionsService.shouldEscalate(retryCount)) {
160
+ const escalateCtx: GateRepairContext = {
161
+ featureId,
162
+ gateName: 'fast',
163
+ exitCode: gateExitCode,
164
+ logs: gateLogs,
165
+ evidenceSummary: gateEvidencePath,
166
+ retryCount,
167
+ failureHistory
168
+ };
169
+ await this.reactionsService.notifyEscalation(featureId, escalateCtx);
170
+ }
171
+ }
172
+ });
52
173
 
53
174
  await Promise.allSettled(executing);
54
175
  }
@@ -1,4 +1,4 @@
1
- import { STATUS, TOOLS } from '../core/constants.js';
1
+ import { GATE_RESULT, STATUS, TOOLS } from '../core/constants.js';
2
2
  import type { WorkerProvider } from '../providers/providers.js';
3
3
  import type {
4
4
  AgentPromptProvider,
@@ -10,6 +10,12 @@ import type {
10
10
  } from './types.js';
11
11
  import { UNASSIGNED_SESSION_ID } from './types.js';
12
12
  import { NOOP_WORKER_DECISION_RUNNER, type WorkerDecisionRunner } from './worker-decision-loop.js';
13
+ import type { GateRepairContext, ReactionsService } from '../application/services/reactions-service.js';
14
+
15
+ interface GatesRunData {
16
+ overall?: string;
17
+ evidence_path?: string;
18
+ }
13
19
 
14
20
  interface QaWaveExecutorDependencies {
15
21
  kernel: FeatureOrchestrationPort;
@@ -19,6 +25,7 @@ interface QaWaveExecutorDependencies {
19
25
  featureClusterPatcher: FeatureClusterPatcher;
20
26
  state: SupervisorRuntimeState;
21
27
  workerDecisionRunner?: WorkerDecisionRunner;
28
+ reactionsService?: ReactionsService;
22
29
  }
23
30
 
24
31
  export class QaWaveExecutor {
@@ -29,6 +36,7 @@ export class QaWaveExecutor {
29
36
  private readonly featureClusterPatcher: FeatureClusterPatcher;
30
37
  private readonly state: SupervisorRuntimeState;
31
38
  private readonly workerDecisionRunner: WorkerDecisionRunner;
39
+ private readonly reactionsService: ReactionsService | undefined;
32
40
 
33
41
  constructor(dependencies: QaWaveExecutorDependencies) {
34
42
  this.kernel = dependencies.kernel;
@@ -38,6 +46,7 @@ export class QaWaveExecutor {
38
46
  this.featureClusterPatcher = dependencies.featureClusterPatcher;
39
47
  this.state = dependencies.state;
40
48
  this.workerDecisionRunner = dependencies.workerDecisionRunner ?? NOOP_WORKER_DECISION_RUNNER;
49
+ this.reactionsService = dependencies.reactionsService;
41
50
  }
42
51
 
43
52
  async run(featureIds: string[], maxParallelGateRuns: number): Promise<void> {
@@ -64,11 +73,120 @@ export class QaWaveExecutor {
64
73
  'Emit PATCH outputs for deterministic QA remediations, NOTE outputs for findings, and REQUEST outputs for lock/context needs.'
65
74
  });
66
75
 
67
- await this.toolCaller.callTool('qa', TOOLS.GATES_RUN, {
68
- feature_id: featureId,
69
- profile: null,
70
- mode: 'full'
76
+ const stateForRetry = await this.toolCaller.callTool<FeatureStatePayload>('qa', TOOLS.FEATURE_STATE_GET, {
77
+ feature_id: featureId
71
78
  });
79
+ const initialRetryCount = stateForRetry.data.front_matter.gate_retry_count ?? 0;
80
+
81
+ let gateOverall: string;
82
+ let gateExitCode = 0;
83
+ let gateEvidencePath = '';
84
+ let gateLogs = '';
85
+ const failureHistory: GateRepairContext['failureHistory'] = [];
86
+
87
+ try {
88
+ const gateResult = await this.toolCaller.callTool<GatesRunData>('qa', TOOLS.GATES_RUN, {
89
+ feature_id: featureId,
90
+ profile: null,
91
+ mode: 'full'
92
+ });
93
+ gateOverall = gateResult.data.overall ?? GATE_RESULT.PASS;
94
+ gateExitCode = gateOverall === GATE_RESULT.FAIL ? 1 : 0;
95
+ gateEvidencePath = gateResult.data.evidence_path ?? '';
96
+ } catch (error) {
97
+ gateOverall = GATE_RESULT.FAIL;
98
+ gateExitCode = 1;
99
+ const typed = error as { message?: string };
100
+ gateLogs = typed.message ?? '';
101
+ }
102
+
103
+ if (gateOverall === GATE_RESULT.FAIL) {
104
+ failureHistory.push({
105
+ attempt: initialRetryCount + 1,
106
+ gate_name: 'full',
107
+ exit_code: gateExitCode,
108
+ evidence_summary: gateEvidencePath,
109
+ logs_excerpt: gateLogs.slice(0, 800),
110
+ failed_at: new Date().toISOString(),
111
+ retry_delay_ms: this.reactionsService?.retryDelayMs()
112
+ });
113
+ }
114
+
115
+ if (this.reactionsService && gateOverall === GATE_RESULT.FAIL) {
116
+ let retryCount = initialRetryCount;
117
+ const retryDelayMs = this.reactionsService.retryDelayMs();
118
+ while (this.reactionsService.shouldRetry(featureId, retryCount)) {
119
+ if (typeof this.reactionsService.waitBeforeRetry === 'function') {
120
+ await this.reactionsService.waitBeforeRetry();
121
+ }
122
+ const attempt = retryCount + 2;
123
+ const ctx: GateRepairContext = {
124
+ featureId,
125
+ gateName: 'full',
126
+ exitCode: gateExitCode,
127
+ logs: gateLogs,
128
+ evidenceSummary: gateEvidencePath,
129
+ retryCount,
130
+ failureHistory
131
+ };
132
+ const repairPrompt = this.reactionsService.buildRepairPrompt(ctx);
133
+ await this.workerDecisionRunner.execute({
134
+ role: 'qa',
135
+ featureId,
136
+ contextBundle: context.data,
137
+ instructions: repairPrompt
138
+ });
139
+
140
+ try {
141
+ const retryResult = await this.toolCaller.callTool<GatesRunData>('qa', TOOLS.GATES_RUN, {
142
+ feature_id: featureId,
143
+ profile: null,
144
+ mode: 'full'
145
+ });
146
+ gateOverall = retryResult.data.overall ?? GATE_RESULT.PASS;
147
+ gateExitCode = gateOverall === GATE_RESULT.FAIL ? 1 : 0;
148
+ gateEvidencePath = retryResult.data.evidence_path ?? gateEvidencePath;
149
+ gateLogs = '';
150
+ } catch (error) {
151
+ gateOverall = GATE_RESULT.FAIL;
152
+ gateExitCode = 1;
153
+ const typed = error as { message?: string };
154
+ gateLogs = typed.message ?? '';
155
+ }
156
+
157
+ retryCount += 1;
158
+ await this.reactionsService.recordRetry(featureId, retryCount);
159
+
160
+ if (gateOverall === GATE_RESULT.FAIL) {
161
+ failureHistory.push({
162
+ attempt,
163
+ gate_name: 'full',
164
+ exit_code: gateExitCode,
165
+ evidence_summary: gateEvidencePath,
166
+ logs_excerpt: gateLogs.slice(0, 800),
167
+ failed_at: new Date().toISOString(),
168
+ retry_delay_ms: retryDelayMs
169
+ });
170
+ }
171
+
172
+ if (gateOverall === GATE_RESULT.PASS) {
173
+ break;
174
+ }
175
+ }
176
+
177
+ if (gateOverall === GATE_RESULT.FAIL && this.reactionsService.shouldEscalate(retryCount)) {
178
+ const escalateCtx: GateRepairContext = {
179
+ featureId,
180
+ gateName: 'full',
181
+ exitCode: gateExitCode,
182
+ logs: gateLogs,
183
+ evidenceSummary: gateEvidencePath,
184
+ retryCount,
185
+ failureHistory
186
+ };
187
+ await this.reactionsService.notifyEscalation(featureId, escalateCtx);
188
+ }
189
+ }
72
190
 
73
191
  const sessions = this.state.sessionsByFeature.get(featureId);
74
192
  if (sessions?.qa) {