oxe-cc 1.2.1 → 1.4.0

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 (281) hide show
  1. package/.cursor/commands/oxe-ask.md +2 -2
  2. package/.cursor/commands/oxe-capabilities.md +2 -2
  3. package/.cursor/commands/oxe-checkpoint.md +2 -2
  4. package/.cursor/commands/oxe-compact.md +2 -2
  5. package/.cursor/commands/oxe-dashboard.md +2 -2
  6. package/.cursor/commands/oxe-debug.md +2 -2
  7. package/.cursor/commands/oxe-discuss.md +2 -2
  8. package/.cursor/commands/oxe-execute.md +5 -2
  9. package/.cursor/commands/oxe-forensics.md +2 -2
  10. package/.cursor/commands/oxe-help.md +2 -2
  11. package/.cursor/commands/oxe-loop.md +2 -2
  12. package/.cursor/commands/oxe-milestone.md +2 -2
  13. package/.cursor/commands/oxe-next.md +2 -2
  14. package/.cursor/commands/oxe-obs.md +2 -2
  15. package/.cursor/commands/oxe-plan-agent.md +2 -2
  16. package/.cursor/commands/oxe-plan.md +2 -2
  17. package/.cursor/commands/oxe-project.md +2 -2
  18. package/.cursor/commands/oxe-quick.md +2 -2
  19. package/.cursor/commands/oxe-research.md +2 -2
  20. package/.cursor/commands/oxe-retro.md +2 -2
  21. package/.cursor/commands/oxe-review-pr.md +2 -2
  22. package/.cursor/commands/oxe-route.md +2 -2
  23. package/.cursor/commands/oxe-scan.md +2 -2
  24. package/.cursor/commands/oxe-security.md +2 -2
  25. package/.cursor/commands/oxe-session.md +2 -2
  26. package/.cursor/commands/oxe-ship.md +2 -2
  27. package/.cursor/commands/oxe-skill.md +2 -2
  28. package/.cursor/commands/oxe-spec.md +2 -2
  29. package/.cursor/commands/oxe-ui-review.md +2 -2
  30. package/.cursor/commands/oxe-ui-spec.md +2 -2
  31. package/.cursor/commands/oxe-update.md +2 -2
  32. package/.cursor/commands/oxe-validate-gaps.md +2 -2
  33. package/.cursor/commands/oxe-verify.md +5 -2
  34. package/.cursor/commands/oxe-workstream.md +2 -2
  35. package/.cursor/commands/oxe.md +2 -2
  36. package/.github/copilot-instructions.md +13 -13
  37. package/.github/prompts/oxe-ask.prompt.md +2 -2
  38. package/.github/prompts/oxe-capabilities.prompt.md +2 -2
  39. package/.github/prompts/oxe-checkpoint.prompt.md +2 -2
  40. package/.github/prompts/oxe-compact.prompt.md +2 -2
  41. package/.github/prompts/oxe-dashboard.prompt.md +2 -2
  42. package/.github/prompts/oxe-debug.prompt.md +2 -2
  43. package/.github/prompts/oxe-discuss.prompt.md +2 -2
  44. package/.github/prompts/oxe-execute.prompt.md +5 -2
  45. package/.github/prompts/oxe-forensics.prompt.md +2 -2
  46. package/.github/prompts/oxe-help.prompt.md +2 -2
  47. package/.github/prompts/oxe-loop.prompt.md +2 -2
  48. package/.github/prompts/oxe-milestone.prompt.md +2 -2
  49. package/.github/prompts/oxe-next.prompt.md +2 -2
  50. package/.github/prompts/oxe-obs.prompt.md +2 -2
  51. package/.github/prompts/oxe-plan-agent.prompt.md +2 -2
  52. package/.github/prompts/oxe-plan.prompt.md +2 -2
  53. package/.github/prompts/oxe-project.prompt.md +2 -2
  54. package/.github/prompts/oxe-quick.prompt.md +2 -2
  55. package/.github/prompts/oxe-research.prompt.md +2 -2
  56. package/.github/prompts/oxe-retro.prompt.md +2 -2
  57. package/.github/prompts/oxe-review-pr.prompt.md +2 -2
  58. package/.github/prompts/oxe-route.prompt.md +2 -2
  59. package/.github/prompts/oxe-scan.prompt.md +2 -2
  60. package/.github/prompts/oxe-security.prompt.md +2 -2
  61. package/.github/prompts/oxe-session.prompt.md +2 -2
  62. package/.github/prompts/oxe-ship.prompt.md +2 -2
  63. package/.github/prompts/oxe-skill.prompt.md +2 -2
  64. package/.github/prompts/oxe-spec.prompt.md +2 -2
  65. package/.github/prompts/oxe-ui-review.prompt.md +2 -2
  66. package/.github/prompts/oxe-ui-spec.prompt.md +2 -2
  67. package/.github/prompts/oxe-update.prompt.md +2 -2
  68. package/.github/prompts/oxe-validate-gaps.prompt.md +2 -2
  69. package/.github/prompts/oxe-verify.prompt.md +5 -2
  70. package/.github/prompts/oxe-workstream.prompt.md +2 -2
  71. package/.github/prompts/oxe.prompt.md +2 -2
  72. package/AGENTS.md +5 -3
  73. package/CHANGELOG.md +72 -10
  74. package/LICENSE +21 -674
  75. package/README.md +631 -535
  76. package/bin/banner.txt +6 -6
  77. package/bin/lib/oxe-agent-install.cjs +69 -69
  78. package/bin/lib/oxe-azure.cjs +1445 -1445
  79. package/bin/lib/oxe-context-engine.cjs +867 -867
  80. package/bin/lib/oxe-dashboard.cjs +76 -28
  81. package/bin/lib/oxe-operational.cjs +2144 -1340
  82. package/bin/lib/oxe-project-health.cjs +483 -1
  83. package/bin/lib/oxe-runtime-semantics.cjs +12 -0
  84. package/bin/oxe-cc.js +554 -152
  85. package/commands/oxe/ask.md +2 -2
  86. package/commands/oxe/capabilities.md +2 -2
  87. package/commands/oxe/checkpoint.md +2 -2
  88. package/commands/oxe/compact.md +2 -2
  89. package/commands/oxe/dashboard.md +2 -2
  90. package/commands/oxe/debug.md +2 -2
  91. package/commands/oxe/discuss.md +2 -2
  92. package/commands/oxe/execute.md +5 -2
  93. package/commands/oxe/forensics.md +2 -2
  94. package/commands/oxe/help.md +2 -2
  95. package/commands/oxe/loop.md +2 -2
  96. package/commands/oxe/milestone.md +2 -2
  97. package/commands/oxe/next.md +2 -2
  98. package/commands/oxe/obs.md +2 -2
  99. package/commands/oxe/oxe.md +2 -2
  100. package/commands/oxe/plan-agent.md +2 -2
  101. package/commands/oxe/plan.md +2 -2
  102. package/commands/oxe/project.md +2 -2
  103. package/commands/oxe/quick.md +2 -2
  104. package/commands/oxe/research.md +2 -2
  105. package/commands/oxe/retro.md +2 -2
  106. package/commands/oxe/review-pr.md +2 -2
  107. package/commands/oxe/route.md +2 -2
  108. package/commands/oxe/scan.md +2 -2
  109. package/commands/oxe/security.md +2 -2
  110. package/commands/oxe/session.md +2 -2
  111. package/commands/oxe/ship.md +2 -2
  112. package/commands/oxe/skill.md +2 -2
  113. package/commands/oxe/spec.md +2 -2
  114. package/commands/oxe/ui-review.md +2 -2
  115. package/commands/oxe/ui-spec.md +2 -2
  116. package/commands/oxe/update.md +2 -2
  117. package/commands/oxe/validate-gaps.md +2 -2
  118. package/commands/oxe/verify.md +5 -2
  119. package/commands/oxe/workstream.md +2 -2
  120. package/lib/runtime/delivery/branch-manager.d.ts +1 -0
  121. package/lib/runtime/delivery/branch-manager.js +7 -0
  122. package/lib/runtime/delivery/ci-checks.js +34 -1
  123. package/lib/runtime/delivery/delivery-records.d.ts +34 -0
  124. package/lib/runtime/delivery/delivery-records.js +48 -0
  125. package/lib/runtime/delivery/index.d.ts +1 -0
  126. package/lib/runtime/delivery/index.js +1 -0
  127. package/lib/runtime/delivery/promotion-pipeline.d.ts +26 -2
  128. package/lib/runtime/delivery/promotion-pipeline.js +111 -14
  129. package/lib/runtime/gate/gate-manager.d.ts +41 -0
  130. package/lib/runtime/gate/gate-manager.js +108 -1
  131. package/lib/runtime/index.d.ts +2 -2
  132. package/lib/runtime/index.js +3 -1
  133. package/lib/runtime/models/gate-decision.d.ts +4 -1
  134. package/lib/runtime/models/workspace.d.ts +3 -0
  135. package/lib/runtime/plugins/capability-adapter.d.ts +12 -0
  136. package/lib/runtime/plugins/capability-adapter.js +204 -0
  137. package/lib/runtime/plugins/capability-matrix.d.ts +5 -0
  138. package/lib/runtime/plugins/capability-matrix.js +48 -17
  139. package/lib/runtime/plugins/index.d.ts +1 -0
  140. package/lib/runtime/plugins/index.js +1 -0
  141. package/lib/runtime/plugins/plugin-abi.d.ts +2 -0
  142. package/lib/runtime/plugins/plugin-manifest.d.ts +1 -1
  143. package/lib/runtime/plugins/plugin-manifest.js +6 -2
  144. package/lib/runtime/plugins/plugin-registry.d.ts +46 -0
  145. package/lib/runtime/plugins/plugin-registry.js +79 -2
  146. package/lib/runtime/policy/policy-engine.d.ts +19 -0
  147. package/lib/runtime/policy/policy-engine.js +76 -4
  148. package/lib/runtime/projection/projection-engine.d.ts +9 -1
  149. package/lib/runtime/projection/projection-engine.js +73 -3
  150. package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +43 -1
  151. package/lib/runtime/scheduler/multi-agent-coordinator.js +151 -39
  152. package/lib/runtime/scheduler/run-journal.d.ts +1 -1
  153. package/lib/runtime/scheduler/scheduler.d.ts +19 -1
  154. package/lib/runtime/scheduler/scheduler.js +258 -13
  155. package/lib/runtime/verification/verification-compiler.d.ts +43 -0
  156. package/lib/runtime/verification/verification-compiler.js +137 -0
  157. package/lib/runtime/verification/verification-manifest.d.ts +9 -0
  158. package/lib/runtime/verification/verification-manifest.js +56 -6
  159. package/lib/runtime/workspace/strategies/ephemeral-container.d.ts +1 -0
  160. package/lib/runtime/workspace/strategies/ephemeral-container.js +4 -0
  161. package/lib/runtime/workspace/strategies/git-worktree.d.ts +1 -0
  162. package/lib/runtime/workspace/strategies/git-worktree.js +2 -0
  163. package/lib/runtime/workspace/strategies/inplace.d.ts +1 -0
  164. package/lib/runtime/workspace/strategies/inplace.js +2 -0
  165. package/lib/runtime/workspace/workspace-manager.d.ts +2 -1
  166. package/lib/sdk/README.md +20 -8
  167. package/lib/sdk/index.cjs +33 -24
  168. package/lib/sdk/index.d.ts +149 -14
  169. package/oxe/templates/ACTIVE-RUN.template.json +32 -32
  170. package/oxe/templates/CAPABILITIES.template.md +7 -7
  171. package/oxe/templates/CAPABILITY.template.md +45 -45
  172. package/oxe/templates/CHECKPOINTS.template.md +7 -7
  173. package/oxe/templates/EXECUTION-RUNTIME.template.md +68 -68
  174. package/oxe/templates/HYPOTHESES.template.md +33 -33
  175. package/oxe/templates/LESSONS-METRICS.template.json +13 -13
  176. package/oxe/templates/NOTES.template.md +16 -16
  177. package/oxe/templates/PLAN-REVIEW.template.md +31 -31
  178. package/oxe/templates/SESSION.template.md +34 -34
  179. package/oxe/templates/SKILL.template.md +26 -26
  180. package/oxe/templates/STATE.md +55 -55
  181. package/oxe/templates/WORKFLOW_AUTHORING.md +18 -18
  182. package/oxe/workflows/ask.md +96 -96
  183. package/oxe/workflows/capabilities.md +25 -25
  184. package/oxe/workflows/dashboard.md +33 -33
  185. package/oxe/workflows/discuss.md +12 -12
  186. package/oxe/workflows/execute.md +14 -0
  187. package/oxe/workflows/help.md +352 -352
  188. package/oxe/workflows/next.md +22 -22
  189. package/oxe/workflows/oxe.md +6 -6
  190. package/oxe/workflows/plan-agent.md +9 -9
  191. package/oxe/workflows/plan.md +51 -20
  192. package/oxe/workflows/quick.md +10 -10
  193. package/oxe/workflows/references/reasoning-discovery.md +28 -28
  194. package/oxe/workflows/references/reasoning-execution.md +29 -29
  195. package/oxe/workflows/references/reasoning-planning.md +32 -32
  196. package/oxe/workflows/references/reasoning-review.md +29 -29
  197. package/oxe/workflows/references/reasoning-status.md +24 -24
  198. package/oxe/workflows/references/robustness-elevation.md +295 -295
  199. package/oxe/workflows/references/workflow-runtime-contracts.json +952 -930
  200. package/oxe/workflows/route.md +16 -16
  201. package/oxe/workflows/session.md +213 -213
  202. package/oxe/workflows/ship.md +142 -142
  203. package/oxe/workflows/skill.md +44 -44
  204. package/oxe/workflows/ui-review.md +36 -36
  205. package/oxe/workflows/verify-audit.md +73 -73
  206. package/oxe/workflows/verify.md +10 -0
  207. package/package.json +92 -92
  208. package/packages/runtime/package.json +16 -15
  209. package/packages/runtime/src/audit/audit-trail.ts +243 -243
  210. package/packages/runtime/src/audit/index.ts +2 -2
  211. package/packages/runtime/src/audit/policy-pack.ts +62 -62
  212. package/packages/runtime/src/compiler/graph-compiler.ts +245 -245
  213. package/packages/runtime/src/compiler/index.ts +1 -1
  214. package/packages/runtime/src/context/context-pack-builder.ts +259 -259
  215. package/packages/runtime/src/context/context-pack-store.ts +197 -197
  216. package/packages/runtime/src/context/context-profiles.ts +60 -60
  217. package/packages/runtime/src/context/index.ts +3 -3
  218. package/packages/runtime/src/decision/decision-engine.ts +174 -174
  219. package/packages/runtime/src/decision/decision-memo.ts +211 -211
  220. package/packages/runtime/src/decision/index.ts +2 -2
  221. package/packages/runtime/src/delivery/branch-manager.ts +91 -84
  222. package/packages/runtime/src/delivery/ci-checks.ts +285 -252
  223. package/packages/runtime/src/delivery/delivery-records.ts +75 -0
  224. package/packages/runtime/src/delivery/index.ts +5 -4
  225. package/packages/runtime/src/delivery/pr-manager.ts +112 -112
  226. package/packages/runtime/src/delivery/promotion-pipeline.ts +334 -180
  227. package/packages/runtime/src/events/bus.ts +92 -92
  228. package/packages/runtime/src/events/catalog.ts +29 -29
  229. package/packages/runtime/src/events/envelope.ts +14 -14
  230. package/packages/runtime/src/events/index.ts +3 -3
  231. package/packages/runtime/src/evidence/evidence-store.ts +130 -130
  232. package/packages/runtime/src/evidence/index.ts +1 -1
  233. package/packages/runtime/src/gate/gate-manager.ts +289 -137
  234. package/packages/runtime/src/gate/index.ts +1 -1
  235. package/packages/runtime/src/index.ts +41 -37
  236. package/packages/runtime/src/models/attempt.ts +19 -19
  237. package/packages/runtime/src/models/evidence.ts +21 -21
  238. package/packages/runtime/src/models/gate-decision.ts +25 -21
  239. package/packages/runtime/src/models/index.ts +8 -8
  240. package/packages/runtime/src/models/run.ts +24 -24
  241. package/packages/runtime/src/models/session.ts +11 -11
  242. package/packages/runtime/src/models/verification-result.ts +10 -10
  243. package/packages/runtime/src/models/work-item.ts +25 -25
  244. package/packages/runtime/src/models/workspace.ts +31 -28
  245. package/packages/runtime/src/plugins/capability-adapter.ts +206 -0
  246. package/packages/runtime/src/plugins/capability-matrix.ts +126 -83
  247. package/packages/runtime/src/plugins/index.ts +5 -4
  248. package/packages/runtime/src/plugins/plugin-abi.ts +97 -95
  249. package/packages/runtime/src/plugins/plugin-manifest.ts +118 -113
  250. package/packages/runtime/src/plugins/plugin-registry.ts +232 -124
  251. package/packages/runtime/src/policy/index.ts +1 -1
  252. package/packages/runtime/src/policy/policy-engine.ts +330 -244
  253. package/packages/runtime/src/projection/index.ts +1 -1
  254. package/packages/runtime/src/projection/projection-engine.ts +328 -249
  255. package/packages/runtime/src/reducers/debug-reducer.ts +36 -36
  256. package/packages/runtime/src/reducers/index.ts +2 -2
  257. package/packages/runtime/src/reducers/run-state-reducer.ts +269 -269
  258. package/packages/runtime/src/scheduler/agent-registry.ts +132 -132
  259. package/packages/runtime/src/scheduler/agent-roles.ts +109 -109
  260. package/packages/runtime/src/scheduler/index.ts +4 -4
  261. package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +521 -333
  262. package/packages/runtime/src/scheduler/run-journal.ts +62 -62
  263. package/packages/runtime/src/scheduler/scheduler.ts +722 -441
  264. package/packages/runtime/src/verification/index.ts +2 -2
  265. package/packages/runtime/src/verification/verification-compiler.ts +436 -225
  266. package/packages/runtime/src/verification/verification-manifest.ts +252 -192
  267. package/packages/runtime/src/workspace/index.ts +5 -5
  268. package/packages/runtime/src/workspace/strategies/ephemeral-container.ts +126 -121
  269. package/packages/runtime/src/workspace/strategies/git-worktree.ts +79 -77
  270. package/packages/runtime/src/workspace/strategies/inplace.ts +38 -35
  271. package/packages/runtime/src/workspace/workspace-manager.ts +16 -15
  272. package/packages/runtime/tsconfig.json +17 -17
  273. package/vscode-extension/.vscodeignore +7 -7
  274. package/vscode-extension/LICENSE +21 -0
  275. package/vscode-extension/oxe-agents-1.0.0.vsix +0 -0
  276. package/vscode-extension/oxe-agents-1.4.0.vsix +0 -0
  277. package/vscode-extension/package.json +184 -184
  278. package/vscode-extension/src/extension.js +310 -310
  279. package/vscode-extension/src/shared/contextLoader.js +137 -137
  280. package/vscode-extension/src/shared/contractBuilder.js +159 -159
  281. package/vscode-extension/src/shared/stateReader.js +101 -101
@@ -1,26 +1,86 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.MultiAgentCoordinator = void 0;
7
+ exports.multiAgentStatePath = multiAgentStatePath;
8
+ exports.loadMultiAgentState = loadMultiAgentState;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
4
11
  const bus_1 = require("../events/bus");
5
12
  const scheduler_1 = require("./scheduler");
6
13
  const agent_roles_1 = require("./agent-roles");
14
+ function ensureRunDir(projectRoot, runId) {
15
+ const dir = path_1.default.join(projectRoot, '.oxe', 'runs', runId);
16
+ fs_1.default.mkdirSync(dir, { recursive: true });
17
+ return dir;
18
+ }
19
+ function persistMultiAgentArtifacts(projectRoot, runId, state, handoffs = [], arbitrationResults = []) {
20
+ const runDir = ensureRunDir(projectRoot, runId);
21
+ fs_1.default.writeFileSync(path_1.default.join(runDir, 'multi-agent-state.json'), JSON.stringify(state, null, 2), 'utf8');
22
+ fs_1.default.writeFileSync(path_1.default.join(runDir, 'handoffs.json'), JSON.stringify(handoffs, null, 2), 'utf8');
23
+ fs_1.default.writeFileSync(path_1.default.join(runDir, 'arbitration-results.json'), JSON.stringify(arbitrationResults, null, 2), 'utf8');
24
+ }
25
+ function ensureIsolatedAgents(agents) {
26
+ const shared = agents.filter((agent) => agent.workspaceManager.isolation_level !== 'isolated');
27
+ if (shared.length === 0)
28
+ return;
29
+ const ids = shared.map((agent) => `${agent.id}:${agent.workspaceManager.isolation_level}`).join(', ');
30
+ throw new Error(`Multi-agent requires isolated workspaces. Invalid agents: ${ids}`);
31
+ }
32
+ function buildOwnership(agents, partitions) {
33
+ const ownership = [];
34
+ for (let idx = 0; idx < agents.length; idx += 1) {
35
+ for (const workItemId of partitions[idx] ?? []) {
36
+ ownership.push({
37
+ work_item_id: workItemId,
38
+ owner_agent_id: agents[idx].id,
39
+ });
40
+ }
41
+ }
42
+ return ownership;
43
+ }
44
+ function makeState(mode, runId, agents, partitions, agentResults, completed, failed, blocked, orphanReassignments) {
45
+ return {
46
+ run_id: runId,
47
+ mode,
48
+ workspace_isolation_required: 'isolated',
49
+ workspace_isolation_enforced: true,
50
+ agent_count: agents.length,
51
+ ownership: buildOwnership(agents, partitions),
52
+ completed,
53
+ failed,
54
+ blocked,
55
+ agent_results: agents.map((agent, idx) => {
56
+ const result = agentResults.find((entry) => entry.agent_id === agent.id);
57
+ return {
58
+ agent_id: agent.id,
59
+ isolation_level: agent.workspaceManager.isolation_level,
60
+ assigned_task_ids: partitions[idx] ?? agent.assignedTaskIds ?? [],
61
+ completed: result?.completed ?? [],
62
+ failed: result?.failed ?? [],
63
+ };
64
+ }),
65
+ orphan_reassignments: orphanReassignments,
66
+ updated_at: new Date().toISOString(),
67
+ };
68
+ }
7
69
  // ─── Parallel mode ───────────────────────────────────────────────────────────
8
- // Tasks are partitioned across agents. Each agent runs its own Scheduler
9
- // on a sub-graph. Results are merged.
10
70
  async function runParallel(graph, opts) {
11
71
  const { agents, projectRoot, sessionId, runId } = opts;
12
- // Partition tasks across agents (round-robin if assignedTaskIds not set)
13
- const partitions = agents.map((a) => a.assignedTaskIds ?? []);
14
- if (partitions.every((p) => p.length === 0)) {
72
+ ensureIsolatedAgents(agents);
73
+ const partitions = agents.map((agent) => [...(agent.assignedTaskIds ?? [])]);
74
+ if (partitions.every((partition) => partition.length === 0)) {
15
75
  const allIds = [...graph.nodes.keys()];
16
- allIds.forEach((id, i) => {
17
- partitions[i % agents.length].push(id);
76
+ allIds.forEach((id, index) => {
77
+ partitions[index % agents.length].push(id);
18
78
  });
19
79
  }
20
80
  (0, bus_1.appendEvent)(projectRoot, sessionId, {
21
81
  type: 'RunStarted',
22
82
  run_id: runId,
23
- payload: { mode: 'parallel', agent_count: agents.length },
83
+ payload: { mode: 'parallel', agent_count: agents.length, isolation_level: 'isolated' },
24
84
  });
25
85
  const agentResults = await Promise.all(agents.map(async (agent, idx) => {
26
86
  const subGraph = subGraphFor(graph, partitions[idx]);
@@ -39,35 +99,49 @@ async function runParallel(graph, opts) {
39
99
  const result = await scheduler.run(subGraph, ctx);
40
100
  return { agent_id: agent.id, completed: result.completed, failed: result.failed };
41
101
  }));
42
- const completed = agentResults.flatMap((r) => r.completed);
43
- const failed = agentResults.flatMap((r) => r.failed);
102
+ const completed = agentResults.flatMap((result) => result.completed);
103
+ const failed = agentResults.flatMap((result) => result.failed);
104
+ const blocked = [];
105
+ const orphanReassignments = [];
106
+ const state = makeState('parallel', runId, agents, partitions, agentResults, completed, failed, blocked, orphanReassignments);
107
+ persistMultiAgentArtifacts(projectRoot, runId, state);
44
108
  (0, bus_1.appendEvent)(projectRoot, sessionId, {
45
109
  type: 'RunCompleted',
46
110
  run_id: runId,
47
111
  payload: { mode: 'parallel', completed: completed.length, failed: failed.length },
48
112
  });
49
- return { mode: 'parallel', run_id: runId, completed, failed, blocked: [], agent_results: agentResults };
113
+ return {
114
+ mode: 'parallel',
115
+ run_id: runId,
116
+ completed,
117
+ failed,
118
+ blocked,
119
+ agent_results: agentResults,
120
+ arbitration_results: [],
121
+ state,
122
+ };
50
123
  }
51
124
  // ─── Competitive mode ────────────────────────────────────────────────────────
52
- // Two agents attempt the same task. First success wins; the loser's workspace
53
- // is disposed. Requires exactly 2 agents.
54
125
  async function runCompetitive(graph, opts) {
55
126
  if (opts.agents.length < 2) {
56
127
  throw new Error('Competitive mode requires at least 2 agents');
57
128
  }
129
+ ensureIsolatedAgents(opts.agents);
58
130
  const [agentA, agentB] = opts.agents;
59
131
  const { projectRoot, sessionId, runId } = opts;
60
132
  (0, bus_1.appendEvent)(projectRoot, sessionId, {
61
133
  type: 'RunStarted',
62
134
  run_id: runId,
63
- payload: { mode: 'competitive' },
135
+ payload: { mode: 'competitive', isolation_level: 'isolated' },
64
136
  });
65
137
  const completed = [];
66
138
  const failed = [];
139
+ const blocked = [];
140
+ const arbitrationResults = [];
67
141
  for (const wave of graph.waves) {
68
142
  for (const nodeId of wave.node_ids) {
69
143
  const node = graph.nodes.get(nodeId);
70
- const result = await competeTwoAgents(nodeId, node, agentA, agentB, opts);
144
+ const result = await competeTwoAgents(nodeId, node, agentA, agentB, opts, arbitrationResults);
71
145
  if (result.success)
72
146
  completed.push(nodeId);
73
147
  else
@@ -78,6 +152,12 @@ async function runCompetitive(graph, opts) {
78
152
  if (failed.length > 0)
79
153
  break;
80
154
  }
155
+ const partitions = [Array.from(graph.nodes.keys()), Array.from(graph.nodes.keys())];
156
+ const state = makeState('competitive', runId, opts.agents, partitions, [
157
+ { agent_id: agentA.id, completed, failed },
158
+ { agent_id: agentB.id, completed: [], failed: [] },
159
+ ], completed, failed, blocked, []);
160
+ persistMultiAgentArtifacts(projectRoot, runId, state, [], arbitrationResults);
81
161
  (0, bus_1.appendEvent)(projectRoot, sessionId, {
82
162
  type: 'RunCompleted',
83
163
  run_id: runId,
@@ -88,14 +168,16 @@ async function runCompetitive(graph, opts) {
88
168
  run_id: runId,
89
169
  completed,
90
170
  failed,
91
- blocked: [],
171
+ blocked,
92
172
  agent_results: [
93
173
  { agent_id: agentA.id, completed, failed },
94
174
  { agent_id: agentB.id, completed: [], failed: [] },
95
175
  ],
176
+ arbitration_results: arbitrationResults,
177
+ state,
96
178
  };
97
179
  }
98
- async function competeTwoAgents(nodeId, node, agentA, agentB, opts) {
180
+ async function competeTwoAgents(nodeId, node, agentA, agentB, opts, arbitrationResults) {
99
181
  const { projectRoot, sessionId, runId } = opts;
100
182
  const allocA = await agentA.workspaceManager.allocate({
101
183
  work_item_id: nodeId, attempt_number: 1, strategy: node.workspace_strategy, mutation_scope: node.mutation_scope,
@@ -109,51 +191,58 @@ async function competeTwoAgents(nodeId, node, agentA, agentB, opts) {
109
191
  work_item_id: nodeId,
110
192
  payload: { mode: 'competitive', agents: [agentA.id, agentB.id] },
111
193
  });
112
- // Race both agents — first success wins
113
194
  const [resultA, resultB] = await Promise.all([
114
- agentA.executor.execute(node, allocA, runId, 1).catch((e) => ({
115
- success: false, failure_class: 'env', evidence: [], output: String(e),
195
+ agentA.executor.execute(node, allocA, runId, 1).catch((error) => ({
196
+ success: false, failure_class: 'env', evidence: [], output: String(error),
116
197
  })),
117
- agentB.executor.execute(node, allocB, runId, 1).catch((e) => ({
118
- success: false, failure_class: 'env', evidence: [], output: String(e),
198
+ agentB.executor.execute(node, allocB, runId, 1).catch((error) => ({
199
+ success: false, failure_class: 'env', evidence: [], output: String(error),
119
200
  })),
120
201
  ]);
121
- // Clean up both workspaces
122
202
  await Promise.all([
123
203
  agentA.workspaceManager.dispose(allocA.workspace_id).catch(() => { }),
124
204
  agentB.workspaceManager.dispose(allocB.workspace_id).catch(() => { }),
125
205
  ]);
126
- // Pick winner: prefer success; if both succeed, prefer A (primary agent)
127
206
  const winner = resultA.success ? resultA : resultB.success ? resultB : resultA;
207
+ const winnerAgentId = resultA.success ? agentA.id : resultB.success ? agentB.id : agentA.id;
208
+ arbitrationResults.push({
209
+ work_item_id: nodeId,
210
+ mode: 'competitive',
211
+ winner_agent_id: winnerAgentId,
212
+ participant_agent_ids: [agentA.id, agentB.id],
213
+ success: winner.success,
214
+ failure_class: winner.failure_class,
215
+ evidence_count: winner.evidence.length,
216
+ recorded_at: new Date().toISOString(),
217
+ });
128
218
  if (winner.success) {
129
- (0, bus_1.appendEvent)(projectRoot, sessionId, { type: 'WorkItemCompleted', run_id: runId, work_item_id: nodeId, payload: { mode: 'competitive' } });
219
+ (0, bus_1.appendEvent)(projectRoot, sessionId, { type: 'WorkItemCompleted', run_id: runId, work_item_id: nodeId, payload: { mode: 'competitive', winner_agent_id: winnerAgentId } });
130
220
  }
131
221
  else {
132
- (0, bus_1.appendEvent)(projectRoot, sessionId, { type: 'WorkItemBlocked', run_id: runId, work_item_id: nodeId, payload: { mode: 'competitive', failure_class: winner.failure_class } });
222
+ (0, bus_1.appendEvent)(projectRoot, sessionId, { type: 'WorkItemBlocked', run_id: runId, work_item_id: nodeId, payload: { mode: 'competitive', failure_class: winner.failure_class, winner_agent_id: winnerAgentId } });
133
223
  }
134
224
  return winner;
135
225
  }
136
226
  // ─── Cooperative mode ────────────────────────────────────────────────────────
137
- // planner (agent[0]) does a dry-run to collect context, then hands off to
138
- // executor (agent[1]) which performs the real run. Handoffs are recorded.
139
227
  async function runCooperative(graph, opts) {
140
228
  if (opts.agents.length < 2) {
141
229
  throw new Error('Cooperative mode requires at least 2 agents');
142
230
  }
231
+ ensureIsolatedAgents(opts.agents);
143
232
  const [planner, executor] = opts.agents;
144
233
  const { projectRoot, sessionId, runId } = opts;
145
234
  const handoffs = [];
146
235
  (0, bus_1.appendEvent)(projectRoot, sessionId, {
147
236
  type: 'RunStarted',
148
237
  run_id: runId,
149
- payload: { mode: 'cooperative', planner: planner.id, executor: executor.id },
238
+ payload: { mode: 'cooperative', planner: planner.id, executor: executor.id, isolation_level: 'isolated' },
150
239
  });
151
240
  const completed = [];
152
241
  const failed = [];
242
+ const blocked = [];
153
243
  for (const wave of graph.waves) {
154
244
  for (const nodeId of wave.node_ids) {
155
245
  const node = graph.nodes.get(nodeId);
156
- // Phase 1: planner allocates workspace + signals readiness (no output used)
157
246
  const planAlloc = await planner.workspaceManager.allocate({
158
247
  work_item_id: nodeId,
159
248
  attempt_number: 1,
@@ -176,7 +265,6 @@ async function runCooperative(graph, opts) {
176
265
  work_item_id: nodeId,
177
266
  payload: { mode: 'cooperative', handoff_id: handoff.handoff_id },
178
267
  });
179
- // Phase 2: executor performs the real task
180
268
  const execAlloc = await executor.workspaceManager.allocate({
181
269
  work_item_id: nodeId,
182
270
  attempt_number: 1,
@@ -187,8 +275,8 @@ async function runCooperative(graph, opts) {
187
275
  try {
188
276
  result = await executor.executor.execute(node, execAlloc, runId, 1);
189
277
  }
190
- catch (e) {
191
- result = { success: false, failure_class: 'env', evidence: [], output: String(e) };
278
+ catch (error) {
279
+ result = { success: false, failure_class: 'env', evidence: [], output: String(error) };
192
280
  }
193
281
  await executor.workspaceManager.dispose(execAlloc.workspace_id).catch(() => { });
194
282
  if (result.success) {
@@ -204,6 +292,12 @@ async function runCooperative(graph, opts) {
204
292
  if (failed.length > 0)
205
293
  break;
206
294
  }
295
+ const partitions = [Array.from(graph.nodes.keys()), Array.from(graph.nodes.keys())];
296
+ const state = makeState('cooperative', runId, opts.agents, partitions, [
297
+ { agent_id: planner.id, completed: [], failed: [] },
298
+ { agent_id: executor.id, completed, failed },
299
+ ], completed, failed, blocked, []);
300
+ persistMultiAgentArtifacts(projectRoot, runId, state, handoffs, []);
207
301
  (0, bus_1.appendEvent)(projectRoot, sessionId, {
208
302
  type: 'RunCompleted',
209
303
  run_id: runId,
@@ -214,12 +308,14 @@ async function runCooperative(graph, opts) {
214
308
  run_id: runId,
215
309
  completed,
216
310
  failed,
217
- blocked: [],
311
+ blocked,
218
312
  agent_results: [
219
313
  { agent_id: planner.id, completed: [], failed: [] },
220
314
  { agent_id: executor.id, completed, failed },
221
315
  ],
222
316
  handoffs,
317
+ arbitration_results: [],
318
+ state,
223
319
  };
224
320
  }
225
321
  // ─── Public API ──────────────────────────────────────────────────────────────
@@ -235,15 +331,31 @@ class MultiAgentCoordinator {
235
331
  }
236
332
  }
237
333
  exports.MultiAgentCoordinator = MultiAgentCoordinator;
334
+ function multiAgentStatePath(projectRoot, runId) {
335
+ return path_1.default.join(projectRoot, '.oxe', 'runs', runId, 'multi-agent-state.json');
336
+ }
337
+ function loadMultiAgentState(projectRoot, runId) {
338
+ const statePath = multiAgentStatePath(projectRoot, runId);
339
+ if (!fs_1.default.existsSync(statePath))
340
+ return null;
341
+ try {
342
+ return JSON.parse(fs_1.default.readFileSync(statePath, 'utf8'));
343
+ }
344
+ catch {
345
+ return null;
346
+ }
347
+ }
238
348
  // ─── Helpers ─────────────────────────────────────────────────────────────────
239
349
  function subGraphFor(graph, nodeIds) {
240
350
  const ids = new Set(nodeIds);
241
351
  const nodes = new Map([...graph.nodes].filter(([id]) => ids.has(id)));
242
- const edges = graph.edges.filter((e) => ids.has(e.from) && ids.has(e.to));
243
- const waves = graph.waves.map((w) => ({
244
- wave_number: w.wave_number,
245
- node_ids: w.node_ids.filter((id) => ids.has(id)),
246
- })).filter((w) => w.node_ids.length > 0);
352
+ const edges = graph.edges.filter((edge) => ids.has(edge.from) && ids.has(edge.to));
353
+ const waves = graph.waves
354
+ .map((wave) => ({
355
+ wave_number: wave.wave_number,
356
+ node_ids: wave.node_ids.filter((id) => ids.has(id)),
357
+ }))
358
+ .filter((wave) => wave.node_ids.length > 0);
247
359
  return {
248
360
  nodes,
249
361
  edges,
@@ -9,7 +9,7 @@ export interface RunJournal {
9
9
  blocked_work_items: string[];
10
10
  pending_gates: string[];
11
11
  replay_cursor: string | null;
12
- scheduler_state: 'running' | 'paused' | 'cancelled' | 'completed';
12
+ scheduler_state: 'running' | 'paused' | 'cancelled' | 'completed' | 'blocked';
13
13
  partial_result: Omit<RunResult, 'status'> | null;
14
14
  }
15
15
  export declare function saveJournal(projectRoot: string, runId: string, journal: RunJournal): void;
@@ -2,6 +2,11 @@ import type { OxeEvent } from '../events/envelope';
2
2
  import type { ExecutionGraph, GraphNode } from '../compiler/graph-compiler';
3
3
  import type { WorkspaceManager } from '../workspace/workspace-manager';
4
4
  import type { WorkspaceLease } from '../models/workspace';
5
+ import type { GateManager } from '../gate/gate-manager';
6
+ import type { PolicyEngine } from '../policy/policy-engine';
7
+ import type { PluginRegistry } from '../plugins/plugin-registry';
8
+ import type { AuditTrail } from '../audit/audit-trail';
9
+ import type { RunQuota } from '../audit/audit-trail';
5
10
  import type { RunJournal } from './run-journal';
6
11
  export interface TaskResult {
7
12
  success: boolean;
@@ -18,14 +23,21 @@ export interface SchedulerContext {
18
23
  runId: string;
19
24
  executor: TaskExecutor;
20
25
  workspaceManager: WorkspaceManager;
26
+ gateManager?: GateManager;
27
+ policyEngine?: PolicyEngine;
28
+ pluginRegistry?: PluginRegistry;
29
+ auditTrail?: AuditTrail;
30
+ quota?: RunQuota;
31
+ policyActor?: string;
21
32
  onEvent?: (event: OxeEvent) => void;
22
33
  }
23
34
  export interface RunResult {
24
35
  run_id: string;
25
- status: 'completed' | 'failed' | 'cancelled' | 'paused';
36
+ status: 'completed' | 'failed' | 'blocked' | 'cancelled' | 'paused';
26
37
  completed: string[];
27
38
  failed: string[];
28
39
  blocked: string[];
40
+ pending_gates?: string[];
29
41
  }
30
42
  export declare class Scheduler {
31
43
  private cancelled;
@@ -45,5 +57,11 @@ export declare class Scheduler {
45
57
  cancel(): void;
46
58
  getJournal(): RunJournal | null;
47
59
  static loadJournal(projectRoot: string, runId: string): RunJournal | null;
60
+ private executeNode;
61
+ private evaluatePolicyForNode;
62
+ private requestGateForNode;
63
+ private blockNode;
64
+ private consumeQuotaForNode;
65
+ private consumeRetryQuota;
48
66
  private emit;
49
67
  }