oxe-cc 0.9.3 → 1.2.1

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 (319) hide show
  1. package/.cursor/commands/oxe-ask.md +1 -1
  2. package/.cursor/commands/oxe-capabilities.md +1 -1
  3. package/.cursor/commands/oxe-checkpoint.md +1 -1
  4. package/.cursor/commands/oxe-compact.md +1 -1
  5. package/.cursor/commands/oxe-dashboard.md +1 -1
  6. package/.cursor/commands/oxe-debug.md +1 -1
  7. package/.cursor/commands/oxe-discuss.md +1 -1
  8. package/.cursor/commands/oxe-execute.md +2 -2
  9. package/.cursor/commands/oxe-forensics.md +1 -1
  10. package/.cursor/commands/oxe-help.md +1 -1
  11. package/.cursor/commands/oxe-loop.md +1 -1
  12. package/.cursor/commands/oxe-milestone.md +1 -1
  13. package/.cursor/commands/oxe-next.md +1 -1
  14. package/.cursor/commands/oxe-obs.md +1 -1
  15. package/.cursor/commands/oxe-plan-agent.md +1 -1
  16. package/.cursor/commands/oxe-plan.md +1 -1
  17. package/.cursor/commands/oxe-project.md +1 -1
  18. package/.cursor/commands/oxe-quick.md +1 -1
  19. package/.cursor/commands/oxe-research.md +1 -1
  20. package/.cursor/commands/oxe-retro.md +1 -1
  21. package/.cursor/commands/oxe-review-pr.md +1 -1
  22. package/.cursor/commands/oxe-route.md +1 -1
  23. package/.cursor/commands/oxe-scan.md +1 -1
  24. package/.cursor/commands/oxe-security.md +1 -1
  25. package/.cursor/commands/oxe-session.md +2 -2
  26. package/.cursor/commands/oxe-ship.md +45 -0
  27. package/.cursor/commands/oxe-skill.md +1 -1
  28. package/.cursor/commands/oxe-spec.md +1 -1
  29. package/.cursor/commands/oxe-ui-review.md +1 -1
  30. package/.cursor/commands/oxe-ui-spec.md +1 -1
  31. package/.cursor/commands/oxe-update.md +1 -1
  32. package/.cursor/commands/oxe-validate-gaps.md +1 -1
  33. package/.cursor/commands/oxe-verify.md +1 -1
  34. package/.cursor/commands/oxe-workstream.md +1 -1
  35. package/.cursor/commands/oxe.md +4 -4
  36. package/.github/copilot-instructions.md +91 -1
  37. package/.github/prompts/oxe-ask.prompt.md +1 -1
  38. package/.github/prompts/oxe-capabilities.prompt.md +1 -1
  39. package/.github/prompts/oxe-checkpoint.prompt.md +1 -1
  40. package/.github/prompts/oxe-compact.prompt.md +1 -1
  41. package/.github/prompts/oxe-dashboard.prompt.md +1 -1
  42. package/.github/prompts/oxe-debug.prompt.md +1 -1
  43. package/.github/prompts/oxe-discuss.prompt.md +1 -1
  44. package/.github/prompts/oxe-execute.prompt.md +2 -2
  45. package/.github/prompts/oxe-forensics.prompt.md +1 -1
  46. package/.github/prompts/oxe-help.prompt.md +1 -1
  47. package/.github/prompts/oxe-loop.prompt.md +1 -1
  48. package/.github/prompts/oxe-milestone.prompt.md +1 -1
  49. package/.github/prompts/oxe-next.prompt.md +1 -1
  50. package/.github/prompts/oxe-obs.prompt.md +1 -1
  51. package/.github/prompts/oxe-plan-agent.prompt.md +1 -1
  52. package/.github/prompts/oxe-plan.prompt.md +1 -1
  53. package/.github/prompts/oxe-project.prompt.md +1 -1
  54. package/.github/prompts/oxe-quick.prompt.md +1 -1
  55. package/.github/prompts/oxe-research.prompt.md +1 -1
  56. package/.github/prompts/oxe-retro.prompt.md +1 -1
  57. package/.github/prompts/oxe-review-pr.prompt.md +1 -1
  58. package/.github/prompts/oxe-route.prompt.md +1 -1
  59. package/.github/prompts/oxe-scan.prompt.md +1 -1
  60. package/.github/prompts/oxe-security.prompt.md +1 -1
  61. package/.github/prompts/oxe-session.prompt.md +2 -2
  62. package/.github/prompts/oxe-ship.prompt.md +45 -0
  63. package/.github/prompts/oxe-skill.prompt.md +1 -1
  64. package/.github/prompts/oxe-spec.prompt.md +1 -1
  65. package/.github/prompts/oxe-ui-review.prompt.md +1 -1
  66. package/.github/prompts/oxe-ui-spec.prompt.md +1 -1
  67. package/.github/prompts/oxe-update.prompt.md +1 -1
  68. package/.github/prompts/oxe-validate-gaps.prompt.md +1 -1
  69. package/.github/prompts/oxe-verify.prompt.md +1 -1
  70. package/.github/prompts/oxe-workstream.prompt.md +1 -1
  71. package/.github/prompts/oxe.prompt.md +3 -3
  72. package/AGENTS.md +43 -28
  73. package/CHANGELOG.md +158 -0
  74. package/README.md +72 -50
  75. package/bin/banner.txt +1 -1
  76. package/bin/lib/oxe-dashboard.cjs +9 -7
  77. package/bin/lib/oxe-operational.cjs +569 -4
  78. package/bin/lib/oxe-project-health.cjs +1 -1
  79. package/bin/oxe-cc.js +141 -57
  80. package/commands/oxe/ask.md +5 -1
  81. package/commands/oxe/checkpoint.md +1 -1
  82. package/commands/oxe/compact.md +1 -1
  83. package/commands/oxe/debug.md +1 -1
  84. package/commands/oxe/execute.md +2 -2
  85. package/commands/oxe/forensics.md +1 -1
  86. package/commands/oxe/loop.md +1 -1
  87. package/commands/oxe/milestone.md +1 -1
  88. package/commands/oxe/next.md +1 -1
  89. package/commands/oxe/obs.md +1 -1
  90. package/commands/oxe/oxe.md +3 -3
  91. package/commands/oxe/project.md +1 -1
  92. package/commands/oxe/research.md +1 -1
  93. package/commands/oxe/retro.md +1 -1
  94. package/commands/oxe/review-pr.md +1 -1
  95. package/commands/oxe/route.md +1 -1
  96. package/commands/oxe/scan.md +1 -1
  97. package/commands/oxe/security.md +1 -1
  98. package/commands/oxe/session.md +2 -2
  99. package/commands/oxe/ship.md +49 -0
  100. package/commands/oxe/spec.md +2 -2
  101. package/commands/oxe/ui-review.md +1 -1
  102. package/commands/oxe/ui-spec.md +1 -1
  103. package/commands/oxe/validate-gaps.md +1 -1
  104. package/commands/oxe/verify.md +2 -2
  105. package/commands/oxe/workstream.md +1 -1
  106. package/lib/runtime/audit/audit-trail.d.ts +71 -0
  107. package/lib/runtime/audit/audit-trail.js +154 -0
  108. package/lib/runtime/audit/index.d.ts +2 -0
  109. package/lib/runtime/audit/index.js +18 -0
  110. package/lib/runtime/audit/policy-pack.d.ts +15 -0
  111. package/lib/runtime/audit/policy-pack.js +57 -0
  112. package/lib/runtime/compiler/graph-compiler.d.ts +83 -0
  113. package/lib/runtime/compiler/graph-compiler.js +135 -0
  114. package/lib/runtime/compiler/index.d.ts +1 -0
  115. package/lib/runtime/compiler/index.js +17 -0
  116. package/lib/runtime/context/context-pack-builder.d.ts +51 -0
  117. package/lib/runtime/context/context-pack-builder.js +178 -0
  118. package/lib/runtime/context/context-pack-store.d.ts +38 -0
  119. package/lib/runtime/context/context-pack-store.js +142 -0
  120. package/lib/runtime/context/context-profiles.d.ts +11 -0
  121. package/lib/runtime/context/context-profiles.js +51 -0
  122. package/lib/runtime/context/index.d.ts +3 -0
  123. package/lib/runtime/context/index.js +19 -0
  124. package/lib/runtime/decision/decision-engine.d.ts +43 -0
  125. package/lib/runtime/decision/decision-engine.js +127 -0
  126. package/lib/runtime/decision/decision-memo.d.ts +53 -0
  127. package/lib/runtime/decision/decision-memo.js +173 -0
  128. package/lib/runtime/decision/index.d.ts +2 -0
  129. package/lib/runtime/decision/index.js +18 -0
  130. package/lib/runtime/delivery/branch-manager.d.ts +19 -0
  131. package/lib/runtime/delivery/branch-manager.js +78 -0
  132. package/lib/runtime/delivery/ci-checks.d.ts +34 -0
  133. package/lib/runtime/delivery/ci-checks.js +209 -0
  134. package/lib/runtime/delivery/index.d.ts +4 -0
  135. package/lib/runtime/delivery/index.js +20 -0
  136. package/lib/runtime/delivery/pr-manager.d.ts +30 -0
  137. package/lib/runtime/delivery/pr-manager.js +82 -0
  138. package/lib/runtime/delivery/promotion-pipeline.d.ts +39 -0
  139. package/lib/runtime/delivery/promotion-pipeline.js +127 -0
  140. package/lib/runtime/events/bus.d.ts +9 -0
  141. package/lib/runtime/events/bus.js +63 -0
  142. package/lib/runtime/events/catalog.d.ts +3 -0
  143. package/lib/runtime/events/catalog.js +30 -0
  144. package/lib/runtime/events/envelope.d.ts +13 -0
  145. package/lib/runtime/events/envelope.js +2 -0
  146. package/lib/runtime/events/index.d.ts +3 -0
  147. package/lib/runtime/events/index.js +19 -0
  148. package/lib/runtime/evidence/evidence-store.d.ts +22 -0
  149. package/lib/runtime/evidence/evidence-store.js +106 -0
  150. package/lib/runtime/evidence/index.d.ts +1 -0
  151. package/lib/runtime/evidence/index.js +17 -0
  152. package/lib/runtime/gate/gate-manager.d.ts +39 -0
  153. package/lib/runtime/gate/gate-manager.js +104 -0
  154. package/lib/runtime/gate/index.d.ts +1 -0
  155. package/lib/runtime/gate/index.js +17 -0
  156. package/lib/runtime/index.d.ts +19 -0
  157. package/lib/runtime/index.js +44 -0
  158. package/lib/runtime/models/attempt.d.ts +12 -0
  159. package/lib/runtime/models/attempt.js +2 -0
  160. package/lib/runtime/models/evidence.d.ts +9 -0
  161. package/lib/runtime/models/evidence.js +2 -0
  162. package/lib/runtime/models/gate-decision.d.ts +10 -0
  163. package/lib/runtime/models/gate-decision.js +2 -0
  164. package/lib/runtime/models/index.d.ts +8 -0
  165. package/lib/runtime/models/index.js +24 -0
  166. package/lib/runtime/models/run.d.ts +13 -0
  167. package/lib/runtime/models/run.js +2 -0
  168. package/lib/runtime/models/session.d.ts +10 -0
  169. package/lib/runtime/models/session.js +2 -0
  170. package/lib/runtime/models/verification-result.d.ts +9 -0
  171. package/lib/runtime/models/verification-result.js +2 -0
  172. package/lib/runtime/models/work-item.d.ts +15 -0
  173. package/lib/runtime/models/work-item.js +2 -0
  174. package/lib/runtime/models/workspace.d.ts +25 -0
  175. package/lib/runtime/models/workspace.js +2 -0
  176. package/lib/runtime/plugins/capability-matrix.d.ts +20 -0
  177. package/lib/runtime/plugins/capability-matrix.js +59 -0
  178. package/lib/runtime/plugins/index.d.ts +4 -0
  179. package/lib/runtime/plugins/index.js +20 -0
  180. package/lib/runtime/plugins/plugin-abi.d.ts +76 -0
  181. package/lib/runtime/plugins/plugin-abi.js +2 -0
  182. package/lib/runtime/plugins/plugin-manifest.d.ts +22 -0
  183. package/lib/runtime/plugins/plugin-manifest.js +91 -0
  184. package/lib/runtime/plugins/plugin-registry.d.ts +21 -0
  185. package/lib/runtime/plugins/plugin-registry.js +119 -0
  186. package/lib/runtime/policy/index.d.ts +1 -0
  187. package/lib/runtime/policy/index.js +17 -0
  188. package/lib/runtime/policy/policy-engine.d.ts +67 -0
  189. package/lib/runtime/policy/policy-engine.js +171 -0
  190. package/lib/runtime/projection/index.d.ts +1 -0
  191. package/lib/runtime/projection/index.js +17 -0
  192. package/lib/runtime/projection/projection-engine.d.ts +11 -0
  193. package/lib/runtime/projection/projection-engine.js +218 -0
  194. package/lib/runtime/reducers/debug-reducer.d.ts +10 -0
  195. package/lib/runtime/reducers/debug-reducer.js +30 -0
  196. package/lib/runtime/reducers/index.d.ts +2 -0
  197. package/lib/runtime/reducers/index.js +18 -0
  198. package/lib/runtime/reducers/run-state-reducer.d.ts +46 -0
  199. package/lib/runtime/reducers/run-state-reducer.js +226 -0
  200. package/lib/runtime/scheduler/agent-registry.d.ts +44 -0
  201. package/lib/runtime/scheduler/agent-registry.js +96 -0
  202. package/lib/runtime/scheduler/agent-roles.d.ts +54 -0
  203. package/lib/runtime/scheduler/agent-roles.js +62 -0
  204. package/lib/runtime/scheduler/index.d.ts +4 -0
  205. package/lib/runtime/scheduler/index.js +20 -0
  206. package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +36 -0
  207. package/lib/runtime/scheduler/multi-agent-coordinator.js +253 -0
  208. package/lib/runtime/scheduler/run-journal.d.ts +18 -0
  209. package/lib/runtime/scheduler/run-journal.js +54 -0
  210. package/lib/runtime/scheduler/scheduler.d.ts +49 -0
  211. package/lib/runtime/scheduler/scheduler.js +324 -0
  212. package/lib/runtime/verification/index.d.ts +2 -0
  213. package/lib/runtime/verification/index.js +18 -0
  214. package/lib/runtime/verification/verification-compiler.d.ts +56 -0
  215. package/lib/runtime/verification/verification-compiler.js +147 -0
  216. package/lib/runtime/verification/verification-manifest.d.ts +58 -0
  217. package/lib/runtime/verification/verification-manifest.js +129 -0
  218. package/lib/runtime/workspace/index.d.ts +5 -0
  219. package/lib/runtime/workspace/index.js +24 -0
  220. package/lib/runtime/workspace/strategies/ephemeral-container.d.ts +22 -0
  221. package/lib/runtime/workspace/strategies/ephemeral-container.js +109 -0
  222. package/lib/runtime/workspace/strategies/git-worktree.d.ts +12 -0
  223. package/lib/runtime/workspace/strategies/git-worktree.js +79 -0
  224. package/lib/runtime/workspace/strategies/inplace.d.ts +10 -0
  225. package/lib/runtime/workspace/strategies/inplace.js +37 -0
  226. package/lib/runtime/workspace/workspace-manager.d.ts +13 -0
  227. package/lib/runtime/workspace/workspace-manager.js +2 -0
  228. package/lib/sdk/index.cjs +24 -7
  229. package/lib/sdk/index.d.ts +17 -7
  230. package/oxe/workflows/ask.md +4 -0
  231. package/oxe/workflows/checkpoint.md +14 -10
  232. package/oxe/workflows/debug.md +19 -15
  233. package/oxe/workflows/execute.md +30 -2
  234. package/oxe/workflows/forensics.md +13 -9
  235. package/oxe/workflows/help.md +97 -49
  236. package/oxe/workflows/loop.md +17 -13
  237. package/oxe/workflows/obs.md +4 -0
  238. package/oxe/workflows/oxe.md +64 -31
  239. package/oxe/workflows/project.md +6 -1
  240. package/oxe/workflows/references/workflow-runtime-contracts.json +23 -0
  241. package/oxe/workflows/research.md +32 -28
  242. package/oxe/workflows/retro.md +4 -0
  243. package/oxe/workflows/review-pr.md +15 -11
  244. package/oxe/workflows/scan.md +4 -0
  245. package/oxe/workflows/security.md +14 -10
  246. package/oxe/workflows/session.md +17 -1
  247. package/oxe/workflows/ship.md +142 -0
  248. package/oxe/workflows/spec.md +15 -0
  249. package/oxe/workflows/ui-review.md +20 -16
  250. package/oxe/workflows/ui-spec.md +7 -3
  251. package/oxe/workflows/validate-gaps.md +13 -9
  252. package/oxe/workflows/verify.md +42 -3
  253. package/package.json +9 -3
  254. package/packages/runtime/package.json +17 -0
  255. package/packages/runtime/src/audit/audit-trail.ts +243 -0
  256. package/packages/runtime/src/audit/index.ts +2 -0
  257. package/packages/runtime/src/audit/policy-pack.ts +62 -0
  258. package/packages/runtime/src/compiler/graph-compiler.ts +245 -0
  259. package/packages/runtime/src/compiler/index.ts +1 -0
  260. package/packages/runtime/src/context/context-pack-builder.ts +259 -0
  261. package/packages/runtime/src/context/context-pack-store.ts +197 -0
  262. package/packages/runtime/src/context/context-profiles.ts +60 -0
  263. package/packages/runtime/src/context/index.ts +3 -0
  264. package/packages/runtime/src/decision/decision-engine.ts +174 -0
  265. package/packages/runtime/src/decision/decision-memo.ts +211 -0
  266. package/packages/runtime/src/decision/index.ts +2 -0
  267. package/packages/runtime/src/delivery/branch-manager.ts +84 -0
  268. package/packages/runtime/src/delivery/ci-checks.ts +252 -0
  269. package/packages/runtime/src/delivery/index.ts +4 -0
  270. package/packages/runtime/src/delivery/pr-manager.ts +112 -0
  271. package/packages/runtime/src/delivery/promotion-pipeline.ts +180 -0
  272. package/packages/runtime/src/events/bus.ts +92 -0
  273. package/packages/runtime/src/events/catalog.ts +29 -0
  274. package/packages/runtime/src/events/envelope.ts +14 -0
  275. package/packages/runtime/src/events/index.ts +3 -0
  276. package/packages/runtime/src/evidence/evidence-store.ts +130 -0
  277. package/packages/runtime/src/evidence/index.ts +1 -0
  278. package/packages/runtime/src/gate/gate-manager.ts +137 -0
  279. package/packages/runtime/src/gate/index.ts +1 -0
  280. package/packages/runtime/src/index.ts +37 -0
  281. package/packages/runtime/src/models/attempt.ts +19 -0
  282. package/packages/runtime/src/models/evidence.ts +21 -0
  283. package/packages/runtime/src/models/gate-decision.ts +21 -0
  284. package/packages/runtime/src/models/index.ts +8 -0
  285. package/packages/runtime/src/models/run.ts +24 -0
  286. package/packages/runtime/src/models/session.ts +11 -0
  287. package/packages/runtime/src/models/verification-result.ts +10 -0
  288. package/packages/runtime/src/models/work-item.ts +25 -0
  289. package/packages/runtime/src/models/workspace.ts +28 -0
  290. package/packages/runtime/src/plugins/capability-matrix.ts +83 -0
  291. package/packages/runtime/src/plugins/index.ts +4 -0
  292. package/packages/runtime/src/plugins/plugin-abi.ts +95 -0
  293. package/packages/runtime/src/plugins/plugin-manifest.ts +113 -0
  294. package/packages/runtime/src/plugins/plugin-registry.ts +124 -0
  295. package/packages/runtime/src/policy/index.ts +1 -0
  296. package/packages/runtime/src/policy/policy-engine.ts +244 -0
  297. package/packages/runtime/src/projection/index.ts +1 -0
  298. package/packages/runtime/src/projection/projection-engine.ts +249 -0
  299. package/packages/runtime/src/reducers/debug-reducer.ts +36 -0
  300. package/packages/runtime/src/reducers/index.ts +2 -0
  301. package/packages/runtime/src/reducers/run-state-reducer.ts +269 -0
  302. package/packages/runtime/src/scheduler/agent-registry.ts +132 -0
  303. package/packages/runtime/src/scheduler/agent-roles.ts +109 -0
  304. package/packages/runtime/src/scheduler/index.ts +4 -0
  305. package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +333 -0
  306. package/packages/runtime/src/scheduler/run-journal.ts +62 -0
  307. package/packages/runtime/src/scheduler/scheduler.ts +441 -0
  308. package/packages/runtime/src/verification/index.ts +2 -0
  309. package/packages/runtime/src/verification/verification-compiler.ts +225 -0
  310. package/packages/runtime/src/verification/verification-manifest.ts +192 -0
  311. package/packages/runtime/src/workspace/index.ts +5 -0
  312. package/packages/runtime/src/workspace/strategies/ephemeral-container.ts +121 -0
  313. package/packages/runtime/src/workspace/strategies/git-worktree.ts +77 -0
  314. package/packages/runtime/src/workspace/strategies/inplace.ts +35 -0
  315. package/packages/runtime/src/workspace/workspace-manager.ts +15 -0
  316. package/packages/runtime/tsconfig.json +17 -0
  317. package/vscode-extension/oxe-agents-0.9.2.vsix +0 -0
  318. package/vscode-extension/oxe-agents-1.0.0.vsix +0 -0
  319. package/vscode-extension/package.json +1 -1
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContextPackBuilder = void 0;
4
+ exports.scorePackQuality = scorePackQuality;
5
+ function scorePackQuality(pack, profile) {
6
+ const expectedKinds = Object.keys(profile.artifact_kind_weights);
7
+ const presentKinds = new Set(pack.artifacts.map((a) => a.kind));
8
+ const completeness = expectedKinds.length > 0
9
+ ? expectedKinds.filter((k) => presentKinds.has(k)).length / expectedKinds.length
10
+ : 0;
11
+ const relevance_mean = pack.artifacts.length > 0
12
+ ? pack.artifacts.reduce((sum, a) => sum + a.relevanceScore, 0) / pack.artifacts.length
13
+ : 0;
14
+ const total = pack.total_artifacts_considered;
15
+ const redundancy = total > 0 ? 1 - (pack.artifacts.length / total) : 0;
16
+ const ageMs = Date.now() - new Date(pack.built_at).getTime();
17
+ const maxAgeMs = 24 * 60 * 60 * 1000;
18
+ const recency_score = Math.max(0, 1 - ageMs / maxAgeMs);
19
+ const overall = Math.min(1, 0.3 * completeness +
20
+ 0.35 * relevance_mean +
21
+ 0.1 * (1 - redundancy) +
22
+ 0.25 * recency_score);
23
+ return {
24
+ completeness: Math.round(completeness * 100) / 100,
25
+ relevance_mean: Math.round(relevance_mean * 100) / 100,
26
+ redundancy: Math.round(redundancy * 100) / 100,
27
+ recency_score: Math.round(recency_score * 100) / 100,
28
+ overall: Math.round(overall * 100) / 100,
29
+ };
30
+ }
31
+ // ─── Relevance scoring ────────────────────────────────────────────────────────
32
+ function scoreEvidenceRelevance(evidence, workItem) {
33
+ let score = 0.5;
34
+ const eid = evidence.evidence_id.toLowerCase();
35
+ const title = workItem.title.toLowerCase();
36
+ const scope = workItem.mutation_scope ?? [];
37
+ if (scope.some((s) => eid.includes(s.toLowerCase())))
38
+ score += 0.3;
39
+ if (title.split(/\s+/).some((w) => w.length > 3 && eid.includes(w)))
40
+ score += 0.1;
41
+ if (evidence.type === 'junit_xml')
42
+ score += 0.05;
43
+ if (evidence.type === 'diff')
44
+ score += 0.05;
45
+ return Math.min(score, 1.0);
46
+ }
47
+ function scoreLessonRelevance(lesson, workItem) {
48
+ const itemTags = new Set([
49
+ ...workItem.mutation_scope.map((s) => s.toLowerCase()),
50
+ ...workItem.title.toLowerCase().split(/\s+/).filter((w) => w.length > 3),
51
+ ]);
52
+ const lessonTags = lesson.tags.map((t) => t.toLowerCase());
53
+ const overlap = lessonTags.filter((t) => itemTags.has(t)).length;
54
+ const jaccard = overlap / (itemTags.size + lessonTags.length - overlap || 1);
55
+ return Math.min(0.3 + jaccard * 0.7, 1.0);
56
+ }
57
+ // ─── Redundancy elimination ───────────────────────────────────────────────────
58
+ function cosineSimilarity(a, b) {
59
+ const wordsA = new Set(a.content.toLowerCase().split(/\W+/).filter((w) => w.length > 3));
60
+ const wordsB = new Set(b.content.toLowerCase().split(/\W+/).filter((w) => w.length > 3));
61
+ if (wordsA.size === 0 || wordsB.size === 0)
62
+ return 0;
63
+ let intersection = 0;
64
+ for (const w of wordsA)
65
+ if (wordsB.has(w))
66
+ intersection++;
67
+ return intersection / Math.sqrt(wordsA.size * wordsB.size);
68
+ }
69
+ function deduplicateArtifacts(artifacts, threshold) {
70
+ const kept = [];
71
+ let removed = 0;
72
+ for (const candidate of artifacts) {
73
+ const isDuplicate = kept.some((existing) => cosineSimilarity(candidate, existing) >= threshold);
74
+ if (isDuplicate) {
75
+ removed++;
76
+ }
77
+ else {
78
+ kept.push(candidate);
79
+ }
80
+ }
81
+ return { kept, removed };
82
+ }
83
+ // ─── Token budget estimation ──────────────────────────────────────────────────
84
+ function estimateTokens(text) {
85
+ return Math.ceil(text.length / 4);
86
+ }
87
+ function applyTokenBudget(artifacts, maxTokens) {
88
+ let used = 0;
89
+ const result = [];
90
+ for (const a of artifacts) {
91
+ const t = estimateTokens(a.content);
92
+ if (used + t > maxTokens)
93
+ break;
94
+ result.push(a);
95
+ used += t;
96
+ }
97
+ return result;
98
+ }
99
+ // ─── Context Pack Builder ─────────────────────────────────────────────────────
100
+ class ContextPackBuilder {
101
+ constructor(opts = {}) {
102
+ this.opts = opts;
103
+ }
104
+ build(workItem, state, evidenceItems, evidenceContents, lessons) {
105
+ const { maxArtifacts = 20, maxTokensEstimate = 8000, deduplicateThreshold = 0.85, } = this.opts;
106
+ const raw = [];
107
+ // Score and collect evidence
108
+ for (const ev of evidenceItems) {
109
+ const content = evidenceContents.get(ev.evidence_id) ?? '';
110
+ if (!content)
111
+ continue;
112
+ raw.push({
113
+ id: ev.evidence_id,
114
+ kind: 'evidence',
115
+ content,
116
+ relevanceScore: scoreEvidenceRelevance(ev, workItem),
117
+ tags: [ev.type, workItem.work_item_id],
118
+ });
119
+ }
120
+ // Score and collect lessons
121
+ for (const lesson of lessons) {
122
+ raw.push({
123
+ id: lesson.lesson_id,
124
+ kind: 'lesson',
125
+ content: lesson.content,
126
+ relevanceScore: scoreLessonRelevance(lesson, workItem),
127
+ tags: lesson.tags,
128
+ });
129
+ }
130
+ // Add run-level summary if available
131
+ const completedCount = state.completedWorkItems.size;
132
+ if (completedCount > 0) {
133
+ raw.push({
134
+ id: `run-summary-${workItem.run_id}`,
135
+ kind: 'summary',
136
+ content: `Run progress: ${completedCount} completed, ${state.failedWorkItems.size} failed, ${state.blockedWorkItems.size} blocked.`,
137
+ relevanceScore: 0.4,
138
+ tags: ['run-context'],
139
+ });
140
+ }
141
+ const totalConsidered = raw.length;
142
+ // Sort by relevance descending
143
+ raw.sort((a, b) => b.relevanceScore - a.relevanceScore);
144
+ // Deduplicate
145
+ const { kept, removed } = deduplicateArtifacts(raw, deduplicateThreshold);
146
+ // Apply max artifacts cap
147
+ const capped = kept.slice(0, maxArtifacts);
148
+ // Apply token budget
149
+ const final = applyTokenBudget(capped, maxTokensEstimate);
150
+ return {
151
+ work_item_id: workItem.work_item_id,
152
+ artifacts: final,
153
+ total_artifacts_considered: totalConsidered,
154
+ redundancy_removed: removed,
155
+ built_at: new Date().toISOString(),
156
+ };
157
+ }
158
+ /** Convenience: build with no evidence, just lessons and state summary */
159
+ buildLightweight(workItem, state, lessons) {
160
+ return this.build(workItem, state, [], new Map(), lessons);
161
+ }
162
+ /**
163
+ * Filter artifacts to those whose path-like tags are within mutation_scope.
164
+ * L0/L1 tiers apply the filter; L2/L3 skip it (full access).
165
+ */
166
+ filterByMutationScope(artifacts, mutationScope, autonomyTier) {
167
+ if (autonomyTier === 'L2' || autonomyTier === 'L3')
168
+ return artifacts;
169
+ const scope = mutationScope.map((s) => s.toLowerCase());
170
+ return artifacts.filter((a) => {
171
+ const pathTags = a.tags.filter((t) => t.includes('/') || t.includes('\\'));
172
+ if (pathTags.length === 0)
173
+ return true;
174
+ return pathTags.some((tag) => scope.some((s) => tag.toLowerCase().includes(s) || s.includes(tag.toLowerCase())));
175
+ });
176
+ }
177
+ }
178
+ exports.ContextPackBuilder = ContextPackBuilder;
@@ -0,0 +1,38 @@
1
+ import type { ContextPack, ContextQualityScore } from './context-pack-builder';
2
+ export interface ContextPackMeta {
3
+ pack_id: string;
4
+ work_item_id: string;
5
+ run_id: string;
6
+ built_at: string;
7
+ artifact_count: number;
8
+ estimated_tokens: number;
9
+ stale: boolean;
10
+ stale_reason: string | null;
11
+ }
12
+ export interface ContextPackDiff {
13
+ added: string[];
14
+ removed: string[];
15
+ score_changed: Array<{
16
+ id: string;
17
+ before: number;
18
+ after: number;
19
+ }>;
20
+ }
21
+ export declare function savePack(projectRoot: string, runId: string, pack: ContextPack): ContextPackMeta;
22
+ export declare function loadPack(projectRoot: string, runId: string, workItemId: string): ContextPack | null;
23
+ export declare function markStale(projectRoot: string, runId: string, workItemId: string, reason: string): void;
24
+ export declare function isStale(projectRoot: string, runId: string, workItemId: string): boolean;
25
+ export declare function diffPacks(before: ContextPack, after: ContextPack): ContextPackDiff;
26
+ export declare function listPackMeta(projectRoot: string, runId: string): ContextPackMeta[];
27
+ export interface ContextPackRef {
28
+ ref_id: string;
29
+ pack_id: string;
30
+ attempt_id: string;
31
+ work_item_id: string;
32
+ run_id: string;
33
+ artifacts_used: string[];
34
+ quality: ContextQualityScore;
35
+ linked_at: string;
36
+ }
37
+ export declare function linkPackToAttempt(projectRoot: string, runId: string, attemptId: string, pack: ContextPack, quality: ContextQualityScore): ContextPackRef;
38
+ export declare function getPackRefForAttempt(projectRoot: string, runId: string, attemptId: string): ContextPackRef | null;
@@ -0,0 +1,142 @@
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.savePack = savePack;
7
+ exports.loadPack = loadPack;
8
+ exports.markStale = markStale;
9
+ exports.isStale = isStale;
10
+ exports.diffPacks = diffPacks;
11
+ exports.listPackMeta = listPackMeta;
12
+ exports.linkPackToAttempt = linkPackToAttempt;
13
+ exports.getPackRefForAttempt = getPackRefForAttempt;
14
+ const path_1 = __importDefault(require("path"));
15
+ const fs_1 = __importDefault(require("fs"));
16
+ function packPath(projectRoot, runId, workItemId) {
17
+ return path_1.default.join(projectRoot, '.oxe', 'runs', runId, `context-pack-${workItemId}.json`);
18
+ }
19
+ function metaIndexPath(projectRoot, runId) {
20
+ return path_1.default.join(projectRoot, '.oxe', 'runs', runId, 'context-packs.index.json');
21
+ }
22
+ function estimateTokens(pack) {
23
+ return Math.ceil(pack.artifacts.reduce((sum, a) => sum + a.content.length, 0) / 4);
24
+ }
25
+ function savePack(projectRoot, runId, pack) {
26
+ const p = packPath(projectRoot, runId, pack.work_item_id);
27
+ fs_1.default.mkdirSync(path_1.default.dirname(p), { recursive: true });
28
+ fs_1.default.writeFileSync(p, JSON.stringify(pack, null, 2), 'utf8');
29
+ const meta = {
30
+ pack_id: `cp-${runId}-${pack.work_item_id}`,
31
+ work_item_id: pack.work_item_id,
32
+ run_id: runId,
33
+ built_at: pack.built_at,
34
+ artifact_count: pack.artifacts.length,
35
+ estimated_tokens: estimateTokens(pack),
36
+ stale: false,
37
+ stale_reason: null,
38
+ };
39
+ updateMetaIndex(projectRoot, runId, meta);
40
+ return meta;
41
+ }
42
+ function loadPack(projectRoot, runId, workItemId) {
43
+ const p = packPath(projectRoot, runId, workItemId);
44
+ if (!fs_1.default.existsSync(p))
45
+ return null;
46
+ try {
47
+ return JSON.parse(fs_1.default.readFileSync(p, 'utf8'));
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ function markStale(projectRoot, runId, workItemId, reason) {
54
+ const index = loadMetaIndex(projectRoot, runId);
55
+ const meta = index.find((m) => m.work_item_id === workItemId);
56
+ if (!meta)
57
+ return;
58
+ meta.stale = true;
59
+ meta.stale_reason = reason;
60
+ saveMetaIndex(projectRoot, runId, index);
61
+ }
62
+ function isStale(projectRoot, runId, workItemId) {
63
+ const index = loadMetaIndex(projectRoot, runId);
64
+ return index.find((m) => m.work_item_id === workItemId)?.stale ?? false;
65
+ }
66
+ function diffPacks(before, after) {
67
+ const beforeIds = new Set(before.artifacts.map((a) => a.id));
68
+ const afterIds = new Set(after.artifacts.map((a) => a.id));
69
+ const beforeMap = new Map(before.artifacts.map((a) => [a.id, a]));
70
+ const afterMap = new Map(after.artifacts.map((a) => [a.id, a]));
71
+ const added = [...afterIds].filter((id) => !beforeIds.has(id));
72
+ const removed = [...beforeIds].filter((id) => !afterIds.has(id));
73
+ const score_changed = [];
74
+ for (const id of afterIds) {
75
+ if (!beforeIds.has(id))
76
+ continue;
77
+ const bScore = beforeMap.get(id).relevanceScore;
78
+ const aScore = afterMap.get(id).relevanceScore;
79
+ if (Math.abs(bScore - aScore) > 0.05) {
80
+ score_changed.push({ id, before: bScore, after: aScore });
81
+ }
82
+ }
83
+ return { added, removed, score_changed };
84
+ }
85
+ function listPackMeta(projectRoot, runId) {
86
+ return loadMetaIndex(projectRoot, runId);
87
+ }
88
+ function packRefPath(projectRoot, runId, attemptId) {
89
+ return path_1.default.join(projectRoot, '.oxe', 'runs', runId, `context-ref-${attemptId}.json`);
90
+ }
91
+ function linkPackToAttempt(projectRoot, runId, attemptId, pack, quality) {
92
+ const ref = {
93
+ ref_id: `ref-${runId}-${attemptId}`,
94
+ pack_id: `cp-${runId}-${pack.work_item_id}`,
95
+ attempt_id: attemptId,
96
+ work_item_id: pack.work_item_id,
97
+ run_id: runId,
98
+ artifacts_used: pack.artifacts.map((a) => a.id),
99
+ quality,
100
+ linked_at: new Date().toISOString(),
101
+ };
102
+ const p = packRefPath(projectRoot, runId, attemptId);
103
+ fs_1.default.mkdirSync(path_1.default.dirname(p), { recursive: true });
104
+ fs_1.default.writeFileSync(p, JSON.stringify(ref, null, 2), 'utf8');
105
+ return ref;
106
+ }
107
+ function getPackRefForAttempt(projectRoot, runId, attemptId) {
108
+ const p = packRefPath(projectRoot, runId, attemptId);
109
+ if (!fs_1.default.existsSync(p))
110
+ return null;
111
+ try {
112
+ return JSON.parse(fs_1.default.readFileSync(p, 'utf8'));
113
+ }
114
+ catch {
115
+ return null;
116
+ }
117
+ }
118
+ function loadMetaIndex(projectRoot, runId) {
119
+ const p = metaIndexPath(projectRoot, runId);
120
+ if (!fs_1.default.existsSync(p))
121
+ return [];
122
+ try {
123
+ return JSON.parse(fs_1.default.readFileSync(p, 'utf8'));
124
+ }
125
+ catch {
126
+ return [];
127
+ }
128
+ }
129
+ function saveMetaIndex(projectRoot, runId, index) {
130
+ const p = metaIndexPath(projectRoot, runId);
131
+ fs_1.default.mkdirSync(path_1.default.dirname(p), { recursive: true });
132
+ fs_1.default.writeFileSync(p, JSON.stringify(index, null, 2), 'utf8');
133
+ }
134
+ function updateMetaIndex(projectRoot, runId, meta) {
135
+ const index = loadMetaIndex(projectRoot, runId);
136
+ const idx = index.findIndex((m) => m.work_item_id === meta.work_item_id);
137
+ if (idx >= 0)
138
+ index[idx] = meta;
139
+ else
140
+ index.push(meta);
141
+ saveMetaIndex(projectRoot, runId, index);
142
+ }
@@ -0,0 +1,11 @@
1
+ import type { ContextArtifact } from './context-pack-builder';
2
+ export type ContextDecisionType = 'execute' | 'verify' | 'plan' | 'review' | 'debug' | 'migration';
3
+ export interface ContextProfile {
4
+ decision_type: ContextDecisionType;
5
+ artifact_kind_weights: Record<ContextArtifact['kind'], number>;
6
+ quality_threshold: number;
7
+ max_artifacts: number;
8
+ max_tokens: number;
9
+ }
10
+ export declare const DEFAULT_PROFILES: Record<ContextDecisionType, ContextProfile>;
11
+ export declare function getProfile(decisionType: ContextDecisionType): ContextProfile;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_PROFILES = void 0;
4
+ exports.getProfile = getProfile;
5
+ exports.DEFAULT_PROFILES = {
6
+ execute: {
7
+ decision_type: 'execute',
8
+ artifact_kind_weights: { evidence: 0.8, lesson: 0.3, file: 0.6, summary: 0.4 },
9
+ quality_threshold: 0.6,
10
+ max_artifacts: 20,
11
+ max_tokens: 8000,
12
+ },
13
+ verify: {
14
+ decision_type: 'verify',
15
+ artifact_kind_weights: { evidence: 0.9, lesson: 0.2, file: 0.5, summary: 0.5 },
16
+ quality_threshold: 0.7,
17
+ max_artifacts: 15,
18
+ max_tokens: 6000,
19
+ },
20
+ plan: {
21
+ decision_type: 'plan',
22
+ artifact_kind_weights: { evidence: 0.4, lesson: 0.9, file: 0.7, summary: 0.6 },
23
+ quality_threshold: 0.5,
24
+ max_artifacts: 25,
25
+ max_tokens: 10000,
26
+ },
27
+ review: {
28
+ decision_type: 'review',
29
+ artifact_kind_weights: { evidence: 0.6, lesson: 0.5, file: 0.8, summary: 0.5 },
30
+ quality_threshold: 0.55,
31
+ max_artifacts: 20,
32
+ max_tokens: 8000,
33
+ },
34
+ debug: {
35
+ decision_type: 'debug',
36
+ artifact_kind_weights: { evidence: 0.9, lesson: 0.6, file: 0.7, summary: 0.4 },
37
+ quality_threshold: 0.6,
38
+ max_artifacts: 20,
39
+ max_tokens: 8000,
40
+ },
41
+ migration: {
42
+ decision_type: 'migration',
43
+ artifact_kind_weights: { evidence: 0.7, lesson: 0.7, file: 0.9, summary: 0.5 },
44
+ quality_threshold: 0.65,
45
+ max_artifacts: 30,
46
+ max_tokens: 12000,
47
+ },
48
+ };
49
+ function getProfile(decisionType) {
50
+ return exports.DEFAULT_PROFILES[decisionType];
51
+ }
@@ -0,0 +1,3 @@
1
+ export * from './context-pack-builder';
2
+ export * from './context-pack-store';
3
+ export * from './context-profiles';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./context-pack-builder"), exports);
18
+ __exportStar(require("./context-pack-store"), exports);
19
+ __exportStar(require("./context-profiles"), exports);
@@ -0,0 +1,43 @@
1
+ import type { DecisionMemo } from './decision-memo';
2
+ export type DecisionType = 'proceed' | 'retry' | 'escalate_gate' | 'skip' | 'abort' | 'promote_lesson';
3
+ export type DecisionSignal = 'policy_allowed' | 'policy_denied' | 'gate_pending' | 'gate_approved' | 'evidence_sufficient' | 'evidence_missing' | 'retry_budget_available' | 'retry_budget_exhausted' | 'lesson_match' | 'risk_high';
4
+ export type SeniorityLevel = 'junior' | 'standard' | 'senior' | 'expert';
5
+ export interface DecisionRecord {
6
+ decision_id: string;
7
+ work_item_id: string | null;
8
+ run_id: string;
9
+ type: DecisionType;
10
+ seniority: SeniorityLevel;
11
+ confidence: number;
12
+ signals: DecisionSignal[];
13
+ rationale: string;
14
+ timestamp: string;
15
+ memo?: DecisionMemo;
16
+ }
17
+ export interface DecisionLog {
18
+ run_id: string;
19
+ decisions: DecisionRecord[];
20
+ }
21
+ export interface DecisionInput {
22
+ work_item_id?: string;
23
+ run_id: string;
24
+ policy_allowed: boolean;
25
+ gate_pending: boolean;
26
+ gate_approved: boolean;
27
+ retry_count: number;
28
+ max_retries: number;
29
+ evidence_count: number;
30
+ risk_level: 'none' | 'low' | 'medium' | 'high' | 'critical';
31
+ lesson_match: boolean;
32
+ memo?: DecisionMemo;
33
+ }
34
+ export declare class DecisionEngine {
35
+ evaluate(input: DecisionInput): DecisionRecord;
36
+ }
37
+ export declare function appendDecision(projectRoot: string, runId: string, record: DecisionRecord): void;
38
+ export declare function loadDecisionLog(projectRoot: string, runId: string): DecisionLog | null;
39
+ export declare function queryDecisions(log: DecisionLog, filter: {
40
+ type?: DecisionType;
41
+ workItemId?: string;
42
+ minConfidence?: number;
43
+ }): DecisionRecord[];
@@ -0,0 +1,127 @@
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.DecisionEngine = void 0;
7
+ exports.appendDecision = appendDecision;
8
+ exports.loadDecisionLog = loadDecisionLog;
9
+ exports.queryDecisions = queryDecisions;
10
+ const crypto_1 = __importDefault(require("crypto"));
11
+ const path_1 = __importDefault(require("path"));
12
+ const fs_1 = __importDefault(require("fs"));
13
+ function computeSeniority(confidence) {
14
+ if (confidence >= 0.9)
15
+ return 'expert';
16
+ if (confidence >= 0.75)
17
+ return 'senior';
18
+ if (confidence >= 0.5)
19
+ return 'standard';
20
+ return 'junior';
21
+ }
22
+ class DecisionEngine {
23
+ evaluate(input) {
24
+ const signals = [];
25
+ let type = 'proceed';
26
+ let confidence = 0.8;
27
+ let rationale = '';
28
+ if (!input.policy_allowed) {
29
+ signals.push('policy_denied');
30
+ type = 'abort';
31
+ confidence = 1.0;
32
+ rationale = 'Policy denied execution — aborting without retry.';
33
+ }
34
+ else {
35
+ signals.push('policy_allowed');
36
+ if (input.gate_pending && !input.gate_approved) {
37
+ signals.push('gate_pending');
38
+ type = 'escalate_gate';
39
+ confidence = 0.95;
40
+ rationale = 'Human gate pending — escalating for approval before proceeding.';
41
+ }
42
+ else {
43
+ if (input.gate_approved)
44
+ signals.push('gate_approved');
45
+ if (input.risk_level === 'high' || input.risk_level === 'critical') {
46
+ signals.push('risk_high');
47
+ confidence = Math.max(0.4, confidence - 0.3);
48
+ rationale += 'High residual risk detected. ';
49
+ }
50
+ if (input.retry_count >= input.max_retries) {
51
+ signals.push('retry_budget_exhausted');
52
+ type = 'abort';
53
+ confidence = 0.9;
54
+ rationale += `Retry budget exhausted (${input.retry_count}/${input.max_retries}).`;
55
+ }
56
+ else if (input.retry_count > 0) {
57
+ signals.push('retry_budget_available');
58
+ type = 'retry';
59
+ confidence = 0.7;
60
+ rationale += `Retrying (attempt ${input.retry_count + 1}/${input.max_retries + 1}).`;
61
+ }
62
+ else {
63
+ if (input.evidence_count > 0) {
64
+ signals.push('evidence_sufficient');
65
+ confidence = Math.min(1.0, confidence + 0.1);
66
+ }
67
+ else {
68
+ signals.push('evidence_missing');
69
+ confidence = Math.max(0.3, confidence - 0.2);
70
+ }
71
+ if (input.lesson_match) {
72
+ signals.push('lesson_match');
73
+ type = 'promote_lesson';
74
+ confidence = Math.min(1.0, confidence + 0.05);
75
+ }
76
+ if (!rationale)
77
+ rationale = 'All signals green — proceeding with execution.';
78
+ }
79
+ }
80
+ }
81
+ return {
82
+ decision_id: `dec-${crypto_1.default.randomBytes(4).toString('hex')}`,
83
+ work_item_id: input.work_item_id ?? null,
84
+ run_id: input.run_id,
85
+ type,
86
+ seniority: computeSeniority(confidence),
87
+ confidence: Math.round(confidence * 100) / 100,
88
+ signals,
89
+ rationale: rationale.trim(),
90
+ timestamp: new Date().toISOString(),
91
+ ...(input.memo !== undefined ? { memo: input.memo } : {}),
92
+ };
93
+ }
94
+ }
95
+ exports.DecisionEngine = DecisionEngine;
96
+ function appendDecision(projectRoot, runId, record) {
97
+ const p = logPath(projectRoot, runId);
98
+ fs_1.default.mkdirSync(path_1.default.dirname(p), { recursive: true });
99
+ const log = loadDecisionLog(projectRoot, runId) ?? { run_id: runId, decisions: [] };
100
+ log.decisions.push(record);
101
+ fs_1.default.writeFileSync(p, JSON.stringify(log, null, 2), 'utf8');
102
+ }
103
+ function loadDecisionLog(projectRoot, runId) {
104
+ const p = logPath(projectRoot, runId);
105
+ if (!fs_1.default.existsSync(p))
106
+ return null;
107
+ try {
108
+ return JSON.parse(fs_1.default.readFileSync(p, 'utf8'));
109
+ }
110
+ catch {
111
+ return null;
112
+ }
113
+ }
114
+ function queryDecisions(log, filter) {
115
+ return log.decisions.filter((d) => {
116
+ if (filter.type && d.type !== filter.type)
117
+ return false;
118
+ if (filter.workItemId && d.work_item_id !== filter.workItemId)
119
+ return false;
120
+ if (filter.minConfidence !== undefined && d.confidence < filter.minConfidence)
121
+ return false;
122
+ return true;
123
+ });
124
+ }
125
+ function logPath(projectRoot, runId) {
126
+ return path_1.default.join(projectRoot, '.oxe', 'runs', runId, 'decisions.json');
127
+ }
@@ -0,0 +1,53 @@
1
+ export type ChangeStrategy = 'minimal_patch' | 'isolated_refactor' | 'expand_contract' | 'feature_flag' | 'no_op';
2
+ export interface BlastRadiusEstimate {
3
+ estimated_files: number;
4
+ subsystems: string[];
5
+ risk_score: number;
6
+ reversible: boolean;
7
+ }
8
+ export interface RollbackPlan {
9
+ strategy: 'revert_commit' | 'restore_workspace' | 'undo_patch' | 'no_rollback';
10
+ steps: string[];
11
+ estimated_cost: 'low' | 'medium' | 'high';
12
+ preconditions: string[];
13
+ }
14
+ export interface DecisionMemo {
15
+ memo_id: string;
16
+ work_item_id: string;
17
+ run_id: string;
18
+ problem_summary: string;
19
+ chosen_strategy: ChangeStrategy;
20
+ alternatives_rejected: Array<{
21
+ strategy: ChangeStrategy;
22
+ reason: string;
23
+ }>;
24
+ blast_radius: BlastRadiusEstimate;
25
+ rollback_plan: RollbackPlan;
26
+ min_evidence_required: string[];
27
+ confidence: number;
28
+ created_at: string;
29
+ }
30
+ export declare function buildBlastRadius(mutationScope: string[], retryCount: number, riskLevel: string): BlastRadiusEstimate;
31
+ export declare function buildRollbackPlan(blastRadius: BlastRadiusEstimate, retryCount: number): RollbackPlan;
32
+ export declare class StrategySelector {
33
+ select(mutationScope: string[], retryCount: number, riskLevel: string): ChangeStrategy;
34
+ alternatives(chosen: ChangeStrategy, mutationScope: string[], riskLevel: string): Array<{
35
+ strategy: ChangeStrategy;
36
+ reason: string;
37
+ }>;
38
+ private rejectionReason;
39
+ }
40
+ export interface BuildMemoInput {
41
+ work_item_id: string;
42
+ run_id: string;
43
+ problem_summary: string;
44
+ mutation_scope: string[];
45
+ retry_count: number;
46
+ risk_level: string;
47
+ min_evidence_required?: string[];
48
+ confidence?: number;
49
+ }
50
+ export declare function buildMemo(input: BuildMemoInput): DecisionMemo;
51
+ export declare function saveMemo(projectRoot: string, memo: DecisionMemo): void;
52
+ export declare function loadMemo(projectRoot: string, runId: string, memoId: string): DecisionMemo | null;
53
+ export declare function listMemos(projectRoot: string, runId: string): DecisionMemo[];