oxe-cc 1.2.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/.cursor/commands/oxe-ask.md +2 -2
  2. package/.cursor/commands/oxe-capabilities.md +2 -2
  3. package/.cursor/commands/oxe-checkpoint.md +2 -2
  4. package/.cursor/commands/oxe-compact.md +2 -2
  5. package/.cursor/commands/oxe-dashboard.md +2 -2
  6. package/.cursor/commands/oxe-debug.md +2 -2
  7. package/.cursor/commands/oxe-discuss.md +2 -2
  8. package/.cursor/commands/oxe-execute.md +5 -2
  9. package/.cursor/commands/oxe-forensics.md +2 -2
  10. package/.cursor/commands/oxe-help.md +2 -2
  11. package/.cursor/commands/oxe-loop.md +2 -2
  12. package/.cursor/commands/oxe-milestone.md +2 -2
  13. package/.cursor/commands/oxe-next.md +2 -2
  14. package/.cursor/commands/oxe-obs.md +2 -2
  15. package/.cursor/commands/oxe-plan-agent.md +2 -2
  16. package/.cursor/commands/oxe-plan.md +2 -2
  17. package/.cursor/commands/oxe-project.md +2 -2
  18. package/.cursor/commands/oxe-quick.md +2 -2
  19. package/.cursor/commands/oxe-research.md +2 -2
  20. package/.cursor/commands/oxe-retro.md +2 -2
  21. package/.cursor/commands/oxe-review-pr.md +2 -2
  22. package/.cursor/commands/oxe-route.md +2 -2
  23. package/.cursor/commands/oxe-scan.md +2 -2
  24. package/.cursor/commands/oxe-security.md +2 -2
  25. package/.cursor/commands/oxe-session.md +2 -2
  26. package/.cursor/commands/oxe-ship.md +2 -2
  27. package/.cursor/commands/oxe-skill.md +2 -2
  28. package/.cursor/commands/oxe-spec.md +2 -2
  29. package/.cursor/commands/oxe-ui-review.md +2 -2
  30. package/.cursor/commands/oxe-ui-spec.md +2 -2
  31. package/.cursor/commands/oxe-update.md +2 -2
  32. package/.cursor/commands/oxe-validate-gaps.md +2 -2
  33. package/.cursor/commands/oxe-verify.md +5 -2
  34. package/.cursor/commands/oxe-workstream.md +2 -2
  35. package/.cursor/commands/oxe.md +2 -2
  36. package/.github/copilot-instructions.md +13 -13
  37. package/.github/prompts/oxe-ask.prompt.md +2 -2
  38. package/.github/prompts/oxe-capabilities.prompt.md +2 -2
  39. package/.github/prompts/oxe-checkpoint.prompt.md +2 -2
  40. package/.github/prompts/oxe-compact.prompt.md +2 -2
  41. package/.github/prompts/oxe-dashboard.prompt.md +2 -2
  42. package/.github/prompts/oxe-debug.prompt.md +2 -2
  43. package/.github/prompts/oxe-discuss.prompt.md +2 -2
  44. package/.github/prompts/oxe-execute.prompt.md +5 -2
  45. package/.github/prompts/oxe-forensics.prompt.md +2 -2
  46. package/.github/prompts/oxe-help.prompt.md +2 -2
  47. package/.github/prompts/oxe-loop.prompt.md +2 -2
  48. package/.github/prompts/oxe-milestone.prompt.md +2 -2
  49. package/.github/prompts/oxe-next.prompt.md +2 -2
  50. package/.github/prompts/oxe-obs.prompt.md +2 -2
  51. package/.github/prompts/oxe-plan-agent.prompt.md +2 -2
  52. package/.github/prompts/oxe-plan.prompt.md +2 -2
  53. package/.github/prompts/oxe-project.prompt.md +2 -2
  54. package/.github/prompts/oxe-quick.prompt.md +2 -2
  55. package/.github/prompts/oxe-research.prompt.md +2 -2
  56. package/.github/prompts/oxe-retro.prompt.md +2 -2
  57. package/.github/prompts/oxe-review-pr.prompt.md +2 -2
  58. package/.github/prompts/oxe-route.prompt.md +2 -2
  59. package/.github/prompts/oxe-scan.prompt.md +2 -2
  60. package/.github/prompts/oxe-security.prompt.md +2 -2
  61. package/.github/prompts/oxe-session.prompt.md +2 -2
  62. package/.github/prompts/oxe-ship.prompt.md +2 -2
  63. package/.github/prompts/oxe-skill.prompt.md +2 -2
  64. package/.github/prompts/oxe-spec.prompt.md +2 -2
  65. package/.github/prompts/oxe-ui-review.prompt.md +2 -2
  66. package/.github/prompts/oxe-ui-spec.prompt.md +2 -2
  67. package/.github/prompts/oxe-update.prompt.md +2 -2
  68. package/.github/prompts/oxe-validate-gaps.prompt.md +2 -2
  69. package/.github/prompts/oxe-verify.prompt.md +5 -2
  70. package/.github/prompts/oxe-workstream.prompt.md +2 -2
  71. package/.github/prompts/oxe.prompt.md +2 -2
  72. package/AGENTS.md +5 -3
  73. package/CHANGELOG.md +72 -10
  74. package/LICENSE +21 -674
  75. package/README.md +631 -535
  76. package/bin/banner.txt +6 -6
  77. package/bin/lib/oxe-agent-install.cjs +69 -69
  78. package/bin/lib/oxe-azure.cjs +1445 -1445
  79. package/bin/lib/oxe-context-engine.cjs +867 -867
  80. package/bin/lib/oxe-dashboard.cjs +76 -28
  81. package/bin/lib/oxe-operational.cjs +2144 -1340
  82. package/bin/lib/oxe-project-health.cjs +483 -1
  83. package/bin/lib/oxe-runtime-semantics.cjs +12 -0
  84. package/bin/oxe-cc.js +554 -152
  85. package/commands/oxe/ask.md +2 -2
  86. package/commands/oxe/capabilities.md +2 -2
  87. package/commands/oxe/checkpoint.md +2 -2
  88. package/commands/oxe/compact.md +2 -2
  89. package/commands/oxe/dashboard.md +2 -2
  90. package/commands/oxe/debug.md +2 -2
  91. package/commands/oxe/discuss.md +2 -2
  92. package/commands/oxe/execute.md +5 -2
  93. package/commands/oxe/forensics.md +2 -2
  94. package/commands/oxe/help.md +2 -2
  95. package/commands/oxe/loop.md +2 -2
  96. package/commands/oxe/milestone.md +2 -2
  97. package/commands/oxe/next.md +2 -2
  98. package/commands/oxe/obs.md +2 -2
  99. package/commands/oxe/oxe.md +2 -2
  100. package/commands/oxe/plan-agent.md +2 -2
  101. package/commands/oxe/plan.md +2 -2
  102. package/commands/oxe/project.md +2 -2
  103. package/commands/oxe/quick.md +2 -2
  104. package/commands/oxe/research.md +2 -2
  105. package/commands/oxe/retro.md +2 -2
  106. package/commands/oxe/review-pr.md +2 -2
  107. package/commands/oxe/route.md +2 -2
  108. package/commands/oxe/scan.md +2 -2
  109. package/commands/oxe/security.md +2 -2
  110. package/commands/oxe/session.md +2 -2
  111. package/commands/oxe/ship.md +2 -2
  112. package/commands/oxe/skill.md +2 -2
  113. package/commands/oxe/spec.md +2 -2
  114. package/commands/oxe/ui-review.md +2 -2
  115. package/commands/oxe/ui-spec.md +2 -2
  116. package/commands/oxe/update.md +2 -2
  117. package/commands/oxe/validate-gaps.md +2 -2
  118. package/commands/oxe/verify.md +5 -2
  119. package/commands/oxe/workstream.md +2 -2
  120. package/lib/runtime/delivery/branch-manager.d.ts +1 -0
  121. package/lib/runtime/delivery/branch-manager.js +7 -0
  122. package/lib/runtime/delivery/ci-checks.js +34 -1
  123. package/lib/runtime/delivery/delivery-records.d.ts +34 -0
  124. package/lib/runtime/delivery/delivery-records.js +48 -0
  125. package/lib/runtime/delivery/index.d.ts +1 -0
  126. package/lib/runtime/delivery/index.js +1 -0
  127. package/lib/runtime/delivery/promotion-pipeline.d.ts +26 -2
  128. package/lib/runtime/delivery/promotion-pipeline.js +111 -14
  129. package/lib/runtime/gate/gate-manager.d.ts +41 -0
  130. package/lib/runtime/gate/gate-manager.js +108 -1
  131. package/lib/runtime/index.d.ts +2 -2
  132. package/lib/runtime/index.js +3 -1
  133. package/lib/runtime/models/gate-decision.d.ts +4 -1
  134. package/lib/runtime/models/workspace.d.ts +3 -0
  135. package/lib/runtime/plugins/capability-adapter.d.ts +12 -0
  136. package/lib/runtime/plugins/capability-adapter.js +204 -0
  137. package/lib/runtime/plugins/capability-matrix.d.ts +5 -0
  138. package/lib/runtime/plugins/capability-matrix.js +48 -17
  139. package/lib/runtime/plugins/index.d.ts +1 -0
  140. package/lib/runtime/plugins/index.js +1 -0
  141. package/lib/runtime/plugins/plugin-abi.d.ts +2 -0
  142. package/lib/runtime/plugins/plugin-manifest.d.ts +1 -1
  143. package/lib/runtime/plugins/plugin-manifest.js +6 -2
  144. package/lib/runtime/plugins/plugin-registry.d.ts +46 -0
  145. package/lib/runtime/plugins/plugin-registry.js +79 -2
  146. package/lib/runtime/policy/policy-engine.d.ts +19 -0
  147. package/lib/runtime/policy/policy-engine.js +76 -4
  148. package/lib/runtime/projection/projection-engine.d.ts +9 -1
  149. package/lib/runtime/projection/projection-engine.js +73 -3
  150. package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +43 -1
  151. package/lib/runtime/scheduler/multi-agent-coordinator.js +151 -39
  152. package/lib/runtime/scheduler/run-journal.d.ts +1 -1
  153. package/lib/runtime/scheduler/scheduler.d.ts +19 -1
  154. package/lib/runtime/scheduler/scheduler.js +258 -13
  155. package/lib/runtime/verification/verification-compiler.d.ts +43 -0
  156. package/lib/runtime/verification/verification-compiler.js +137 -0
  157. package/lib/runtime/verification/verification-manifest.d.ts +9 -0
  158. package/lib/runtime/verification/verification-manifest.js +56 -6
  159. package/lib/runtime/workspace/strategies/ephemeral-container.d.ts +1 -0
  160. package/lib/runtime/workspace/strategies/ephemeral-container.js +4 -0
  161. package/lib/runtime/workspace/strategies/git-worktree.d.ts +1 -0
  162. package/lib/runtime/workspace/strategies/git-worktree.js +2 -0
  163. package/lib/runtime/workspace/strategies/inplace.d.ts +1 -0
  164. package/lib/runtime/workspace/strategies/inplace.js +2 -0
  165. package/lib/runtime/workspace/workspace-manager.d.ts +2 -1
  166. package/lib/sdk/README.md +20 -8
  167. package/lib/sdk/index.cjs +33 -24
  168. package/lib/sdk/index.d.ts +149 -14
  169. package/oxe/templates/ACTIVE-RUN.template.json +32 -32
  170. package/oxe/templates/CAPABILITIES.template.md +7 -7
  171. package/oxe/templates/CAPABILITY.template.md +45 -45
  172. package/oxe/templates/CHECKPOINTS.template.md +7 -7
  173. package/oxe/templates/EXECUTION-RUNTIME.template.md +68 -68
  174. package/oxe/templates/HYPOTHESES.template.md +33 -33
  175. package/oxe/templates/LESSONS-METRICS.template.json +13 -13
  176. package/oxe/templates/NOTES.template.md +16 -16
  177. package/oxe/templates/PLAN-REVIEW.template.md +31 -31
  178. package/oxe/templates/SESSION.template.md +34 -34
  179. package/oxe/templates/SKILL.template.md +26 -26
  180. package/oxe/templates/STATE.md +55 -55
  181. package/oxe/templates/WORKFLOW_AUTHORING.md +18 -18
  182. package/oxe/workflows/ask.md +96 -96
  183. package/oxe/workflows/capabilities.md +25 -25
  184. package/oxe/workflows/dashboard.md +33 -33
  185. package/oxe/workflows/discuss.md +12 -12
  186. package/oxe/workflows/execute.md +14 -0
  187. package/oxe/workflows/help.md +352 -352
  188. package/oxe/workflows/next.md +22 -22
  189. package/oxe/workflows/oxe.md +6 -6
  190. package/oxe/workflows/plan-agent.md +9 -9
  191. package/oxe/workflows/plan.md +51 -20
  192. package/oxe/workflows/quick.md +10 -10
  193. package/oxe/workflows/references/reasoning-discovery.md +28 -28
  194. package/oxe/workflows/references/reasoning-execution.md +29 -29
  195. package/oxe/workflows/references/reasoning-planning.md +32 -32
  196. package/oxe/workflows/references/reasoning-review.md +29 -29
  197. package/oxe/workflows/references/reasoning-status.md +24 -24
  198. package/oxe/workflows/references/robustness-elevation.md +295 -295
  199. package/oxe/workflows/references/workflow-runtime-contracts.json +952 -930
  200. package/oxe/workflows/route.md +16 -16
  201. package/oxe/workflows/session.md +213 -213
  202. package/oxe/workflows/ship.md +142 -142
  203. package/oxe/workflows/skill.md +44 -44
  204. package/oxe/workflows/ui-review.md +36 -36
  205. package/oxe/workflows/verify-audit.md +73 -73
  206. package/oxe/workflows/verify.md +10 -0
  207. package/package.json +92 -92
  208. package/packages/runtime/package.json +16 -15
  209. package/packages/runtime/src/audit/audit-trail.ts +243 -243
  210. package/packages/runtime/src/audit/index.ts +2 -2
  211. package/packages/runtime/src/audit/policy-pack.ts +62 -62
  212. package/packages/runtime/src/compiler/graph-compiler.ts +245 -245
  213. package/packages/runtime/src/compiler/index.ts +1 -1
  214. package/packages/runtime/src/context/context-pack-builder.ts +259 -259
  215. package/packages/runtime/src/context/context-pack-store.ts +197 -197
  216. package/packages/runtime/src/context/context-profiles.ts +60 -60
  217. package/packages/runtime/src/context/index.ts +3 -3
  218. package/packages/runtime/src/decision/decision-engine.ts +174 -174
  219. package/packages/runtime/src/decision/decision-memo.ts +211 -211
  220. package/packages/runtime/src/decision/index.ts +2 -2
  221. package/packages/runtime/src/delivery/branch-manager.ts +91 -84
  222. package/packages/runtime/src/delivery/ci-checks.ts +285 -252
  223. package/packages/runtime/src/delivery/delivery-records.ts +75 -0
  224. package/packages/runtime/src/delivery/index.ts +5 -4
  225. package/packages/runtime/src/delivery/pr-manager.ts +112 -112
  226. package/packages/runtime/src/delivery/promotion-pipeline.ts +334 -180
  227. package/packages/runtime/src/events/bus.ts +92 -92
  228. package/packages/runtime/src/events/catalog.ts +29 -29
  229. package/packages/runtime/src/events/envelope.ts +14 -14
  230. package/packages/runtime/src/events/index.ts +3 -3
  231. package/packages/runtime/src/evidence/evidence-store.ts +130 -130
  232. package/packages/runtime/src/evidence/index.ts +1 -1
  233. package/packages/runtime/src/gate/gate-manager.ts +289 -137
  234. package/packages/runtime/src/gate/index.ts +1 -1
  235. package/packages/runtime/src/index.ts +41 -37
  236. package/packages/runtime/src/models/attempt.ts +19 -19
  237. package/packages/runtime/src/models/evidence.ts +21 -21
  238. package/packages/runtime/src/models/gate-decision.ts +25 -21
  239. package/packages/runtime/src/models/index.ts +8 -8
  240. package/packages/runtime/src/models/run.ts +24 -24
  241. package/packages/runtime/src/models/session.ts +11 -11
  242. package/packages/runtime/src/models/verification-result.ts +10 -10
  243. package/packages/runtime/src/models/work-item.ts +25 -25
  244. package/packages/runtime/src/models/workspace.ts +31 -28
  245. package/packages/runtime/src/plugins/capability-adapter.ts +206 -0
  246. package/packages/runtime/src/plugins/capability-matrix.ts +126 -83
  247. package/packages/runtime/src/plugins/index.ts +5 -4
  248. package/packages/runtime/src/plugins/plugin-abi.ts +97 -95
  249. package/packages/runtime/src/plugins/plugin-manifest.ts +118 -113
  250. package/packages/runtime/src/plugins/plugin-registry.ts +232 -124
  251. package/packages/runtime/src/policy/index.ts +1 -1
  252. package/packages/runtime/src/policy/policy-engine.ts +330 -244
  253. package/packages/runtime/src/projection/index.ts +1 -1
  254. package/packages/runtime/src/projection/projection-engine.ts +328 -249
  255. package/packages/runtime/src/reducers/debug-reducer.ts +36 -36
  256. package/packages/runtime/src/reducers/index.ts +2 -2
  257. package/packages/runtime/src/reducers/run-state-reducer.ts +269 -269
  258. package/packages/runtime/src/scheduler/agent-registry.ts +132 -132
  259. package/packages/runtime/src/scheduler/agent-roles.ts +109 -109
  260. package/packages/runtime/src/scheduler/index.ts +4 -4
  261. package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +521 -333
  262. package/packages/runtime/src/scheduler/run-journal.ts +62 -62
  263. package/packages/runtime/src/scheduler/scheduler.ts +722 -441
  264. package/packages/runtime/src/verification/index.ts +2 -2
  265. package/packages/runtime/src/verification/verification-compiler.ts +436 -225
  266. package/packages/runtime/src/verification/verification-manifest.ts +252 -192
  267. package/packages/runtime/src/workspace/index.ts +5 -5
  268. package/packages/runtime/src/workspace/strategies/ephemeral-container.ts +126 -121
  269. package/packages/runtime/src/workspace/strategies/git-worktree.ts +79 -77
  270. package/packages/runtime/src/workspace/strategies/inplace.ts +38 -35
  271. package/packages/runtime/src/workspace/workspace-manager.ts +16 -15
  272. package/packages/runtime/tsconfig.json +17 -17
  273. package/vscode-extension/.vscodeignore +7 -7
  274. package/vscode-extension/LICENSE +21 -0
  275. package/vscode-extension/oxe-agents-1.0.0.vsix +0 -0
  276. package/vscode-extension/oxe-agents-1.4.0.vsix +0 -0
  277. package/vscode-extension/package.json +184 -184
  278. package/vscode-extension/src/extension.js +310 -310
  279. package/vscode-extension/src/shared/contextLoader.js +137 -137
  280. package/vscode-extension/src/shared/contractBuilder.js +159 -159
  281. package/vscode-extension/src/shared/stateReader.js +101 -101
@@ -1,192 +1,252 @@
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
- }
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
+ export interface EvidenceCoverageSummary {
64
+ total_checks: number;
65
+ checks_with_evidence: number;
66
+ total_evidence_refs: number;
67
+ coverage_percent: number;
68
+ }
69
+
70
+ function runDir(projectRoot: string, runId: string): string {
71
+ return path.join(projectRoot, '.oxe', 'runs', runId);
72
+ }
73
+
74
+ function manifestPath(projectRoot: string, runId: string): string {
75
+ return path.join(runDir(projectRoot, runId), 'verification-manifest.json');
76
+ }
77
+
78
+ function riskLedgerPath(projectRoot: string, runId: string): string {
79
+ return path.join(runDir(projectRoot, runId), 'residual-risk-ledger.json');
80
+ }
81
+
82
+ function legacyRiskLedgerPath(projectRoot: string, runId: string): string {
83
+ return path.join(runDir(projectRoot, runId), 'residual-risks.json');
84
+ }
85
+
86
+ function evidenceCoveragePath(projectRoot: string, runId: string): string {
87
+ return path.join(runDir(projectRoot, runId), 'evidence-coverage.json');
88
+ }
89
+
90
+ const PROFILE_REQUIRED_CHECKS: Record<VerificationProfile, FailureClass[]> = {
91
+ quick: ['deterministic'],
92
+ standard: ['deterministic', 'policy_failure'],
93
+ critical: ['deterministic', 'policy_failure', 'evidence_missing', 'flaky'],
94
+ };
95
+
96
+ export function classifyFailure(result: CheckResult): FailureClass | null {
97
+ if (result.status === 'pass' || result.status === 'skip') return null;
98
+ if (result.error && (result.error.toLowerCase().includes('timeout') || result.error.toLowerCase().includes('timed out'))) return 'timeout';
99
+ if (result.exit_code === null && result.error) return 'env_setup';
100
+ if (result.stderr.toLowerCase().includes('policy') || result.stderr.toLowerCase().includes('denied')) {
101
+ return 'policy_failure';
102
+ }
103
+ if (result.exit_code !== 0 && result.stderr === '' && result.stdout === '') return 'evidence_missing';
104
+ // Default: non-deterministic signals (no reliable exit code pattern)
105
+ return 'deterministic';
106
+ }
107
+
108
+ export function buildManifest(
109
+ runId: string,
110
+ results: CheckResult[],
111
+ options: {
112
+ workItemId?: string;
113
+ wave?: number;
114
+ granularity?: VerificationGranularity;
115
+ profile?: VerificationProfile;
116
+ evidenceRefs?: Map<string, string[]>;
117
+ } = {}
118
+ ): VerificationManifest {
119
+ const profile = options.profile ?? 'standard';
120
+ const granularity = options.granularity ?? 'run';
121
+ const evidenceRefs = options.evidenceRefs ?? new Map();
122
+
123
+ const checks: ManifestCheck[] = results.map((r) => ({
124
+ check_id: r.check_id,
125
+ acceptance_ref: r.acceptance_ref,
126
+ status: r.status,
127
+ failure_class: classifyFailure(r),
128
+ evidence_refs: evidenceRefs.get(r.check_id) ?? [],
129
+ duration_ms: r.duration_ms,
130
+ }));
131
+
132
+ const summary = {
133
+ total: checks.length,
134
+ pass: checks.filter((c) => c.status === 'pass').length,
135
+ fail: checks.filter((c) => c.status === 'fail').length,
136
+ skip: checks.filter((c) => c.status === 'skip').length,
137
+ error: checks.filter((c) => c.status === 'error').length,
138
+ all_passed: checks.every((c) => c.status === 'pass' || c.status === 'skip'),
139
+ };
140
+
141
+ return {
142
+ manifest_id: `vm-${crypto.randomBytes(4).toString('hex')}`,
143
+ run_id: runId,
144
+ work_item_id: options.workItemId ?? null,
145
+ wave: options.wave ?? null,
146
+ granularity,
147
+ profile,
148
+ compiled_at: new Date().toISOString(),
149
+ checks,
150
+ summary,
151
+ };
152
+ }
153
+
154
+ export function buildRiskLedger(
155
+ runId: string,
156
+ manifest: VerificationManifest
157
+ ): ResidualRiskLedger {
158
+ const risks: ResidualRisk[] = [];
159
+
160
+ for (const check of manifest.checks) {
161
+ if (check.status === 'pass' || check.status === 'skip') continue;
162
+ if (!check.failure_class) continue;
163
+
164
+ const required = PROFILE_REQUIRED_CHECKS[manifest.profile];
165
+ if (!required.includes(check.failure_class)) continue;
166
+
167
+ risks.push({
168
+ risk_id: `risk-${crypto.randomBytes(3).toString('hex')}`,
169
+ work_item_id: manifest.work_item_id,
170
+ check_id: check.check_id,
171
+ failure_class: check.failure_class,
172
+ description: `Check ${check.check_id} ${check.status}: ${check.failure_class}`,
173
+ severity: check.failure_class === 'policy_failure' || check.failure_class === 'deterministic'
174
+ ? 'high'
175
+ : check.failure_class === 'evidence_missing'
176
+ ? 'medium'
177
+ : 'low',
178
+ mitigation: null,
179
+ });
180
+ }
181
+
182
+ return {
183
+ run_id: runId,
184
+ generated_at: new Date().toISOString(),
185
+ risks,
186
+ };
187
+ }
188
+
189
+ export function summarizeEvidenceCoverage(manifest: VerificationManifest): EvidenceCoverageSummary {
190
+ const totalChecks = manifest.checks.length;
191
+ const checksWithEvidence = manifest.checks.filter((check) => check.evidence_refs.length > 0).length;
192
+ const totalEvidenceRefs = manifest.checks.reduce((sum, check) => sum + check.evidence_refs.length, 0);
193
+ const coveragePercent = totalChecks === 0 ? 100 : Math.round((checksWithEvidence / totalChecks) * 100);
194
+ return {
195
+ total_checks: totalChecks,
196
+ checks_with_evidence: checksWithEvidence,
197
+ total_evidence_refs: totalEvidenceRefs,
198
+ coverage_percent: coveragePercent,
199
+ };
200
+ }
201
+
202
+ export function saveManifest(projectRoot: string, runId: string, manifest: VerificationManifest): void {
203
+ const p = manifestPath(projectRoot, runId);
204
+ fs.mkdirSync(path.dirname(p), { recursive: true });
205
+ fs.writeFileSync(p, JSON.stringify(manifest, null, 2), 'utf8');
206
+ }
207
+
208
+ export function loadManifest(projectRoot: string, runId: string): VerificationManifest | null {
209
+ const p = manifestPath(projectRoot, runId);
210
+ if (!fs.existsSync(p)) return null;
211
+ try {
212
+ return JSON.parse(fs.readFileSync(p, 'utf8')) as VerificationManifest;
213
+ } catch {
214
+ return null;
215
+ }
216
+ }
217
+
218
+ export function saveRiskLedger(projectRoot: string, runId: string, ledger: ResidualRiskLedger): void {
219
+ const canonical = riskLedgerPath(projectRoot, runId);
220
+ const legacy = legacyRiskLedgerPath(projectRoot, runId);
221
+ fs.mkdirSync(path.dirname(canonical), { recursive: true });
222
+ fs.writeFileSync(canonical, JSON.stringify(ledger, null, 2), 'utf8');
223
+ fs.writeFileSync(legacy, JSON.stringify(ledger, null, 2), 'utf8');
224
+ }
225
+
226
+ export function loadRiskLedger(projectRoot: string, runId: string): ResidualRiskLedger | null {
227
+ const canonical = riskLedgerPath(projectRoot, runId);
228
+ const legacy = legacyRiskLedgerPath(projectRoot, runId);
229
+ const p = fs.existsSync(canonical) ? canonical : legacy;
230
+ if (!fs.existsSync(p)) return null;
231
+ try {
232
+ return JSON.parse(fs.readFileSync(p, 'utf8')) as ResidualRiskLedger;
233
+ } catch {
234
+ return null;
235
+ }
236
+ }
237
+
238
+ export function saveEvidenceCoverage(projectRoot: string, runId: string, coverage: EvidenceCoverageSummary): void {
239
+ const p = evidenceCoveragePath(projectRoot, runId);
240
+ fs.mkdirSync(path.dirname(p), { recursive: true });
241
+ fs.writeFileSync(p, JSON.stringify(coverage, null, 2), 'utf8');
242
+ }
243
+
244
+ export function loadEvidenceCoverage(projectRoot: string, runId: string): EvidenceCoverageSummary | null {
245
+ const p = evidenceCoveragePath(projectRoot, runId);
246
+ if (!fs.existsSync(p)) return null;
247
+ try {
248
+ return JSON.parse(fs.readFileSync(p, 'utf8')) as EvidenceCoverageSummary;
249
+ } catch {
250
+ return null;
251
+ }
252
+ }
@@ -1,5 +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';
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';