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,192 @@
1
+ import crypto from 'crypto';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import type { VerificationStatus } from '../models/verification-result';
5
+ import type { CheckResult } from './verification-compiler';
6
+
7
+ export type VerificationProfile = 'quick' | 'standard' | 'critical';
8
+
9
+ export type FailureClass =
10
+ | 'deterministic'
11
+ | 'flaky'
12
+ | 'timeout'
13
+ | 'env_setup'
14
+ | 'policy_failure'
15
+ | 'evidence_missing';
16
+
17
+ export type VerificationGranularity = 'work_item' | 'wave' | 'run';
18
+
19
+ export interface ManifestCheck {
20
+ check_id: string;
21
+ acceptance_ref: string | null;
22
+ status: VerificationStatus;
23
+ failure_class: FailureClass | null;
24
+ evidence_refs: string[];
25
+ duration_ms: number;
26
+ }
27
+
28
+ export interface VerificationManifest {
29
+ manifest_id: string;
30
+ run_id: string;
31
+ work_item_id: string | null;
32
+ wave: number | null;
33
+ granularity: VerificationGranularity;
34
+ profile: VerificationProfile;
35
+ compiled_at: string;
36
+ checks: ManifestCheck[];
37
+ summary: {
38
+ total: number;
39
+ pass: number;
40
+ fail: number;
41
+ skip: number;
42
+ error: number;
43
+ all_passed: boolean;
44
+ };
45
+ }
46
+
47
+ export interface ResidualRisk {
48
+ risk_id: string;
49
+ work_item_id: string | null;
50
+ check_id: string | null;
51
+ failure_class: FailureClass;
52
+ description: string;
53
+ severity: 'low' | 'medium' | 'high' | 'critical';
54
+ mitigation: string | null;
55
+ }
56
+
57
+ export interface ResidualRiskLedger {
58
+ run_id: string;
59
+ generated_at: string;
60
+ risks: ResidualRisk[];
61
+ }
62
+
63
+ const PROFILE_REQUIRED_CHECKS: Record<VerificationProfile, FailureClass[]> = {
64
+ quick: ['deterministic'],
65
+ standard: ['deterministic', 'policy_failure'],
66
+ critical: ['deterministic', 'policy_failure', 'evidence_missing', 'flaky'],
67
+ };
68
+
69
+ export function classifyFailure(result: CheckResult): FailureClass | null {
70
+ if (result.status === 'pass' || result.status === 'skip') return null;
71
+ if (result.error && (result.error.toLowerCase().includes('timeout') || result.error.toLowerCase().includes('timed out'))) return 'timeout';
72
+ if (result.exit_code === null && result.error) return 'env_setup';
73
+ if (result.stderr.toLowerCase().includes('policy') || result.stderr.toLowerCase().includes('denied')) {
74
+ return 'policy_failure';
75
+ }
76
+ if (result.exit_code !== 0 && result.stderr === '' && result.stdout === '') return 'evidence_missing';
77
+ // Default: non-deterministic signals (no reliable exit code pattern)
78
+ return 'deterministic';
79
+ }
80
+
81
+ export function buildManifest(
82
+ runId: string,
83
+ results: CheckResult[],
84
+ options: {
85
+ workItemId?: string;
86
+ wave?: number;
87
+ granularity?: VerificationGranularity;
88
+ profile?: VerificationProfile;
89
+ evidenceRefs?: Map<string, string[]>;
90
+ } = {}
91
+ ): VerificationManifest {
92
+ const profile = options.profile ?? 'standard';
93
+ const granularity = options.granularity ?? 'run';
94
+ const evidenceRefs = options.evidenceRefs ?? new Map();
95
+
96
+ const checks: ManifestCheck[] = results.map((r) => ({
97
+ check_id: r.check_id,
98
+ acceptance_ref: r.acceptance_ref,
99
+ status: r.status,
100
+ failure_class: classifyFailure(r),
101
+ evidence_refs: evidenceRefs.get(r.check_id) ?? [],
102
+ duration_ms: r.duration_ms,
103
+ }));
104
+
105
+ const summary = {
106
+ total: checks.length,
107
+ pass: checks.filter((c) => c.status === 'pass').length,
108
+ fail: checks.filter((c) => c.status === 'fail').length,
109
+ skip: checks.filter((c) => c.status === 'skip').length,
110
+ error: checks.filter((c) => c.status === 'error').length,
111
+ all_passed: checks.every((c) => c.status === 'pass' || c.status === 'skip'),
112
+ };
113
+
114
+ return {
115
+ manifest_id: `vm-${crypto.randomBytes(4).toString('hex')}`,
116
+ run_id: runId,
117
+ work_item_id: options.workItemId ?? null,
118
+ wave: options.wave ?? null,
119
+ granularity,
120
+ profile,
121
+ compiled_at: new Date().toISOString(),
122
+ checks,
123
+ summary,
124
+ };
125
+ }
126
+
127
+ export function buildRiskLedger(
128
+ runId: string,
129
+ manifest: VerificationManifest
130
+ ): ResidualRiskLedger {
131
+ const risks: ResidualRisk[] = [];
132
+
133
+ for (const check of manifest.checks) {
134
+ if (check.status === 'pass' || check.status === 'skip') continue;
135
+ if (!check.failure_class) continue;
136
+
137
+ const required = PROFILE_REQUIRED_CHECKS[manifest.profile];
138
+ if (!required.includes(check.failure_class)) continue;
139
+
140
+ risks.push({
141
+ risk_id: `risk-${crypto.randomBytes(3).toString('hex')}`,
142
+ work_item_id: manifest.work_item_id,
143
+ check_id: check.check_id,
144
+ failure_class: check.failure_class,
145
+ description: `Check ${check.check_id} ${check.status}: ${check.failure_class}`,
146
+ severity: check.failure_class === 'policy_failure' || check.failure_class === 'deterministic'
147
+ ? 'high'
148
+ : check.failure_class === 'evidence_missing'
149
+ ? 'medium'
150
+ : 'low',
151
+ mitigation: null,
152
+ });
153
+ }
154
+
155
+ return {
156
+ run_id: runId,
157
+ generated_at: new Date().toISOString(),
158
+ risks,
159
+ };
160
+ }
161
+
162
+ export function saveManifest(projectRoot: string, runId: string, manifest: VerificationManifest): void {
163
+ const p = path.join(projectRoot, '.oxe', 'runs', runId, 'verification-manifest.json');
164
+ fs.mkdirSync(path.dirname(p), { recursive: true });
165
+ fs.writeFileSync(p, JSON.stringify(manifest, null, 2), 'utf8');
166
+ }
167
+
168
+ export function loadManifest(projectRoot: string, runId: string): VerificationManifest | null {
169
+ const p = path.join(projectRoot, '.oxe', 'runs', runId, 'verification-manifest.json');
170
+ if (!fs.existsSync(p)) return null;
171
+ try {
172
+ return JSON.parse(fs.readFileSync(p, 'utf8')) as VerificationManifest;
173
+ } catch {
174
+ return null;
175
+ }
176
+ }
177
+
178
+ export function saveRiskLedger(projectRoot: string, runId: string, ledger: ResidualRiskLedger): void {
179
+ const p = path.join(projectRoot, '.oxe', 'runs', runId, 'residual-risks.json');
180
+ fs.mkdirSync(path.dirname(p), { recursive: true });
181
+ fs.writeFileSync(p, JSON.stringify(ledger, null, 2), 'utf8');
182
+ }
183
+
184
+ export function loadRiskLedger(projectRoot: string, runId: string): ResidualRiskLedger | null {
185
+ const p = path.join(projectRoot, '.oxe', 'runs', runId, 'residual-risks.json');
186
+ if (!fs.existsSync(p)) return null;
187
+ try {
188
+ return JSON.parse(fs.readFileSync(p, 'utf8')) as ResidualRiskLedger;
189
+ } catch {
190
+ return null;
191
+ }
192
+ }
@@ -0,0 +1,5 @@
1
+ export * from './workspace-manager';
2
+ export { InplaceWorkspaceManager } from './strategies/inplace';
3
+ export { GitWorktreeManager } from './strategies/git-worktree';
4
+ export { EphemeralContainerManager } from './strategies/ephemeral-container';
5
+ export type { ContainerOptions } from './strategies/ephemeral-container';
@@ -0,0 +1,121 @@
1
+ import { execFileSync, spawnSync } from 'child_process';
2
+ import crypto from 'crypto';
3
+ import type { WorkspaceManager, WorkspaceRequest } from '../workspace-manager';
4
+ import type { WorkspaceLease, SnapshotRef } from '../../models/workspace';
5
+ import { GitWorktreeManager } from './git-worktree';
6
+
7
+ export interface ContainerOptions {
8
+ image: string;
9
+ mountPath: string;
10
+ extraEnv?: Record<string, string>;
11
+ /** Gracefully fall back to git_worktree if Docker is unavailable */
12
+ fallback?: boolean;
13
+ }
14
+
15
+ function isDockerAvailable(): boolean {
16
+ const result = spawnSync('docker', ['version', '--format', '{{.Server.Version}}'], {
17
+ encoding: 'utf8',
18
+ timeout: 5000,
19
+ });
20
+ return result.status === 0;
21
+ }
22
+
23
+ export class EphemeralContainerManager implements WorkspaceManager {
24
+ private readonly fallbackManager: GitWorktreeManager;
25
+ private containerIds = new Map<string, string>();
26
+ private useFallback = false;
27
+
28
+ constructor(
29
+ private readonly projectRoot: string,
30
+ private readonly opts: ContainerOptions = { image: 'node:20-alpine', mountPath: '/workspace', fallback: true }
31
+ ) {
32
+ this.fallbackManager = new GitWorktreeManager(projectRoot);
33
+ if (!isDockerAvailable()) {
34
+ if (opts.fallback !== false) {
35
+ this.useFallback = true;
36
+ } else {
37
+ throw new Error('Docker is not available and fallback is disabled');
38
+ }
39
+ }
40
+ }
41
+
42
+ get usingFallback(): boolean { return this.useFallback; }
43
+
44
+ async allocate(req: WorkspaceRequest): Promise<WorkspaceLease> {
45
+ if (this.useFallback) return this.fallbackManager.allocate(req);
46
+
47
+ const wsId = `ws-container-${req.work_item_id}-a${req.attempt_number}`;
48
+ const envArgs = Object.entries(this.opts.extraEnv ?? {}).flatMap(([k, v]) => ['-e', `${k}=${v}`]);
49
+
50
+ const result = spawnSync('docker', [
51
+ 'run', '-d',
52
+ '-v', `${this.projectRoot}:${this.opts.mountPath}`,
53
+ '-w', this.opts.mountPath,
54
+ ...envArgs,
55
+ this.opts.image,
56
+ 'sleep', '3600',
57
+ ], { encoding: 'utf8' });
58
+
59
+ if (result.status !== 0) {
60
+ if (this.opts.fallback !== false) {
61
+ this.useFallback = true;
62
+ return this.fallbackManager.allocate(req);
63
+ }
64
+ throw new Error(`docker run failed: ${result.stderr}`);
65
+ }
66
+
67
+ const containerId = result.stdout.trim().slice(0, 12);
68
+ this.containerIds.set(wsId, containerId);
69
+
70
+ return {
71
+ workspace_id: wsId,
72
+ strategy: 'ephemeral_container',
73
+ branch: null,
74
+ base_commit: null,
75
+ root_path: `docker:${containerId}:${this.opts.mountPath}`,
76
+ ttl_minutes: 60,
77
+ };
78
+ }
79
+
80
+ async snapshot(id: string): Promise<SnapshotRef> {
81
+ if (this.useFallback) return this.fallbackManager.snapshot(id);
82
+ const containerId = this.containerIds.get(id);
83
+ if (!containerId) throw new Error(`Container for workspace ${id} not found`);
84
+
85
+ const tag = `oxe-snap-${crypto.randomBytes(4).toString('hex')}`;
86
+ execFileSync('docker', ['commit', containerId, tag]);
87
+
88
+ return {
89
+ snapshot_id: tag,
90
+ workspace_id: id,
91
+ commit: tag,
92
+ created_at: new Date().toISOString(),
93
+ };
94
+ }
95
+
96
+ async reset(id: string, snapRef: SnapshotRef): Promise<void> {
97
+ if (this.useFallback) return this.fallbackManager.reset(id, snapRef);
98
+ const containerId = this.containerIds.get(id);
99
+ if (!containerId) return;
100
+ // Stop current container and start from snapshot
101
+ spawnSync('docker', ['stop', containerId]);
102
+ spawnSync('docker', ['rm', containerId]);
103
+ const result = spawnSync('docker', [
104
+ 'run', '-d',
105
+ '-v', `${this.projectRoot}:${this.opts.mountPath}`,
106
+ snapRef.commit,
107
+ 'sleep', '3600',
108
+ ], { encoding: 'utf8' });
109
+ const newId = result.stdout.trim().slice(0, 12);
110
+ this.containerIds.set(id, newId);
111
+ }
112
+
113
+ async dispose(id: string): Promise<void> {
114
+ if (this.useFallback) return this.fallbackManager.dispose(id);
115
+ const containerId = this.containerIds.get(id);
116
+ if (!containerId) return;
117
+ spawnSync('docker', ['stop', containerId], { encoding: 'utf8' });
118
+ spawnSync('docker', ['rm', containerId], { encoding: 'utf8' });
119
+ this.containerIds.delete(id);
120
+ }
121
+ }
@@ -0,0 +1,77 @@
1
+ import { execFileSync } from 'child_process';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import crypto from 'crypto';
5
+ import type { WorkspaceManager, WorkspaceRequest } from '../workspace-manager';
6
+ import type { WorkspaceLease, SnapshotRef } from '../../models/workspace';
7
+
8
+ export class GitWorktreeManager implements WorkspaceManager {
9
+ private leases = new Map<string, WorkspaceLease>();
10
+
11
+ constructor(private readonly projectRoot: string) {}
12
+
13
+ async allocate(req: WorkspaceRequest): Promise<WorkspaceLease> {
14
+ const wsId = `ws-${req.work_item_id}-a${req.attempt_number}`;
15
+ const branch = `oxe/${req.work_item_id}-attempt${req.attempt_number}`;
16
+ const worktreePath = path.join(this.projectRoot, '.oxe', 'workspaces', wsId);
17
+
18
+ const baseCommit = this.git(['rev-parse', 'HEAD']).trim();
19
+
20
+ fs.mkdirSync(path.dirname(worktreePath), { recursive: true });
21
+
22
+ // Create worktree on a new branch starting from HEAD
23
+ this.git(['worktree', 'add', worktreePath, '-b', branch]);
24
+
25
+ const lease: WorkspaceLease = {
26
+ workspace_id: wsId,
27
+ strategy: 'git_worktree',
28
+ branch,
29
+ base_commit: baseCommit,
30
+ root_path: worktreePath,
31
+ ttl_minutes: 45,
32
+ };
33
+ this.leases.set(wsId, lease);
34
+ return lease;
35
+ }
36
+
37
+ async snapshot(id: string): Promise<SnapshotRef> {
38
+ const lease = this.leases.get(id);
39
+ if (!lease || !lease.root_path) throw new Error(`Workspace ${id} not found`);
40
+ const commit = this.git(['rev-parse', 'HEAD'], lease.root_path).trim();
41
+ return {
42
+ snapshot_id: `snap-${crypto.randomBytes(4).toString('hex')}`,
43
+ workspace_id: id,
44
+ commit,
45
+ created_at: new Date().toISOString(),
46
+ };
47
+ }
48
+
49
+ async reset(id: string, snapRef: SnapshotRef): Promise<void> {
50
+ const lease = this.leases.get(id);
51
+ if (!lease) return;
52
+ this.git(['reset', '--hard', snapRef.commit], lease.root_path);
53
+ }
54
+
55
+ async dispose(id: string): Promise<void> {
56
+ const lease = this.leases.get(id);
57
+ if (!lease) return;
58
+ try {
59
+ this.git(['worktree', 'remove', lease.root_path, '--force']);
60
+ } catch {
61
+ // worktree may already be gone
62
+ }
63
+ try {
64
+ if (lease.branch) this.git(['branch', '-D', lease.branch]);
65
+ } catch {
66
+ // branch may already be deleted
67
+ }
68
+ this.leases.delete(id);
69
+ }
70
+
71
+ private git(args: string[], cwd?: string): string {
72
+ return execFileSync('git', args, {
73
+ cwd: cwd ?? this.projectRoot,
74
+ encoding: 'utf8',
75
+ });
76
+ }
77
+ }
@@ -0,0 +1,35 @@
1
+ import crypto from 'crypto';
2
+ import type { WorkspaceManager, WorkspaceRequest } from '../workspace-manager';
3
+ import type { WorkspaceLease, SnapshotRef } from '../../models/workspace';
4
+
5
+ export class InplaceWorkspaceManager implements WorkspaceManager {
6
+ constructor(private readonly projectRoot: string) {}
7
+
8
+ async allocate(req: WorkspaceRequest): Promise<WorkspaceLease> {
9
+ return {
10
+ workspace_id: `ws-inplace-${req.work_item_id}-a${req.attempt_number}`,
11
+ strategy: 'inplace',
12
+ branch: null,
13
+ base_commit: null,
14
+ root_path: this.projectRoot,
15
+ ttl_minutes: 60,
16
+ };
17
+ }
18
+
19
+ async snapshot(id: string): Promise<SnapshotRef> {
20
+ return {
21
+ snapshot_id: `snap-${crypto.randomBytes(4).toString('hex')}`,
22
+ workspace_id: id,
23
+ commit: 'HEAD',
24
+ created_at: new Date().toISOString(),
25
+ };
26
+ }
27
+
28
+ async reset(_id: string, _snapRef: SnapshotRef): Promise<void> {
29
+ // inplace: no filesystem isolation — reset is a no-op
30
+ }
31
+
32
+ async dispose(_id: string): Promise<void> {
33
+ // inplace: nothing to tear down
34
+ }
35
+ }
@@ -0,0 +1,15 @@
1
+ import type { WorkspaceLease, SnapshotRef, WorkspaceStrategy } from '../models/workspace';
2
+
3
+ export interface WorkspaceRequest {
4
+ work_item_id: string;
5
+ attempt_number: number;
6
+ strategy: WorkspaceStrategy;
7
+ mutation_scope: string[];
8
+ }
9
+
10
+ export interface WorkspaceManager {
11
+ allocate(req: WorkspaceRequest): Promise<WorkspaceLease>;
12
+ snapshot(id: string): Promise<SnapshotRef>;
13
+ reset(id: string, snapRef: SnapshotRef): Promise<void>;
14
+ dispose(id: string): Promise<void>;
15
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "moduleResolution": "node",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "declaration": true,
9
+ "declarationMap": false,
10
+ "sourceMap": false,
11
+ "outDir": "../../lib/runtime",
12
+ "rootDir": "src",
13
+ "skipLibCheck": true
14
+ },
15
+ "include": ["src/**/*.ts"],
16
+ "exclude": ["tests/**", "node_modules/**", "dist-tests/**"]
17
+ }
@@ -2,7 +2,7 @@
2
2
  "name": "oxe-agents",
3
3
  "displayName": "OXE Agents",
4
4
  "description": "Agentes OXE para GitHub Copilot Chat — cada fase do ciclo como um @agente no VS Code",
5
- "version": "0.9.2",
5
+ "version": "1.0.0",
6
6
  "publisher": "oxe-cc",
7
7
  "license": "MIT",
8
8
  "engines": {