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