oxe-cc 1.0.0 → 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 (207) 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-project-health.cjs +1 -1
  77. package/commands/oxe/ask.md +5 -1
  78. package/commands/oxe/checkpoint.md +1 -1
  79. package/commands/oxe/compact.md +1 -1
  80. package/commands/oxe/debug.md +1 -1
  81. package/commands/oxe/execute.md +2 -2
  82. package/commands/oxe/forensics.md +1 -1
  83. package/commands/oxe/loop.md +1 -1
  84. package/commands/oxe/milestone.md +1 -1
  85. package/commands/oxe/next.md +1 -1
  86. package/commands/oxe/obs.md +1 -1
  87. package/commands/oxe/oxe.md +3 -3
  88. package/commands/oxe/project.md +1 -1
  89. package/commands/oxe/research.md +1 -1
  90. package/commands/oxe/retro.md +1 -1
  91. package/commands/oxe/review-pr.md +1 -1
  92. package/commands/oxe/route.md +1 -1
  93. package/commands/oxe/scan.md +1 -1
  94. package/commands/oxe/security.md +1 -1
  95. package/commands/oxe/session.md +2 -2
  96. package/commands/oxe/ship.md +49 -0
  97. package/commands/oxe/spec.md +2 -2
  98. package/commands/oxe/ui-review.md +1 -1
  99. package/commands/oxe/ui-spec.md +1 -1
  100. package/commands/oxe/validate-gaps.md +1 -1
  101. package/commands/oxe/verify.md +2 -2
  102. package/commands/oxe/workstream.md +1 -1
  103. package/lib/runtime/audit/audit-trail.d.ts +71 -0
  104. package/lib/runtime/audit/audit-trail.js +154 -0
  105. package/lib/runtime/audit/index.d.ts +2 -0
  106. package/lib/runtime/audit/index.js +18 -0
  107. package/lib/runtime/audit/policy-pack.d.ts +15 -0
  108. package/lib/runtime/audit/policy-pack.js +57 -0
  109. package/lib/runtime/context/context-pack-builder.d.ts +15 -0
  110. package/lib/runtime/context/context-pack-builder.js +42 -0
  111. package/lib/runtime/context/context-pack-store.d.ts +38 -0
  112. package/lib/runtime/context/context-pack-store.js +142 -0
  113. package/lib/runtime/context/context-profiles.d.ts +11 -0
  114. package/lib/runtime/context/context-profiles.js +51 -0
  115. package/lib/runtime/context/index.d.ts +2 -0
  116. package/lib/runtime/context/index.js +2 -0
  117. package/lib/runtime/decision/decision-engine.d.ts +43 -0
  118. package/lib/runtime/decision/decision-engine.js +127 -0
  119. package/lib/runtime/decision/decision-memo.d.ts +53 -0
  120. package/lib/runtime/decision/decision-memo.js +173 -0
  121. package/lib/runtime/decision/index.d.ts +2 -0
  122. package/lib/runtime/decision/index.js +18 -0
  123. package/lib/runtime/delivery/index.d.ts +1 -0
  124. package/lib/runtime/delivery/index.js +1 -0
  125. package/lib/runtime/delivery/promotion-pipeline.d.ts +39 -0
  126. package/lib/runtime/delivery/promotion-pipeline.js +127 -0
  127. package/lib/runtime/index.d.ts +3 -0
  128. package/lib/runtime/index.js +4 -0
  129. package/lib/runtime/plugins/capability-matrix.d.ts +20 -0
  130. package/lib/runtime/plugins/capability-matrix.js +59 -0
  131. package/lib/runtime/plugins/index.d.ts +2 -0
  132. package/lib/runtime/plugins/index.js +2 -0
  133. package/lib/runtime/plugins/plugin-manifest.d.ts +22 -0
  134. package/lib/runtime/plugins/plugin-manifest.js +91 -0
  135. package/lib/runtime/plugins/plugin-registry.js +5 -0
  136. package/lib/runtime/policy/policy-engine.d.ts +28 -1
  137. package/lib/runtime/policy/policy-engine.js +96 -5
  138. package/lib/runtime/reducers/run-state-reducer.d.ts +26 -0
  139. package/lib/runtime/reducers/run-state-reducer.js +117 -1
  140. package/lib/runtime/scheduler/agent-registry.d.ts +44 -0
  141. package/lib/runtime/scheduler/agent-registry.js +96 -0
  142. package/lib/runtime/scheduler/agent-roles.d.ts +54 -0
  143. package/lib/runtime/scheduler/agent-roles.js +62 -0
  144. package/lib/runtime/scheduler/index.d.ts +3 -0
  145. package/lib/runtime/scheduler/index.js +3 -0
  146. package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +2 -0
  147. package/lib/runtime/scheduler/multi-agent-coordinator.js +91 -4
  148. package/lib/runtime/scheduler/run-journal.d.ts +18 -0
  149. package/lib/runtime/scheduler/run-journal.js +54 -0
  150. package/lib/runtime/scheduler/scheduler.d.ts +11 -1
  151. package/lib/runtime/scheduler/scheduler.js +135 -7
  152. package/lib/runtime/verification/index.d.ts +1 -0
  153. package/lib/runtime/verification/index.js +1 -0
  154. package/lib/runtime/verification/verification-manifest.d.ts +58 -0
  155. package/lib/runtime/verification/verification-manifest.js +129 -0
  156. package/oxe/workflows/ask.md +4 -0
  157. package/oxe/workflows/checkpoint.md +14 -10
  158. package/oxe/workflows/debug.md +19 -15
  159. package/oxe/workflows/execute.md +30 -2
  160. package/oxe/workflows/forensics.md +13 -9
  161. package/oxe/workflows/help.md +97 -49
  162. package/oxe/workflows/loop.md +17 -13
  163. package/oxe/workflows/obs.md +4 -0
  164. package/oxe/workflows/oxe.md +64 -31
  165. package/oxe/workflows/project.md +6 -1
  166. package/oxe/workflows/references/workflow-runtime-contracts.json +23 -0
  167. package/oxe/workflows/research.md +32 -28
  168. package/oxe/workflows/retro.md +4 -0
  169. package/oxe/workflows/review-pr.md +15 -11
  170. package/oxe/workflows/scan.md +4 -0
  171. package/oxe/workflows/security.md +14 -10
  172. package/oxe/workflows/session.md +17 -1
  173. package/oxe/workflows/ship.md +142 -0
  174. package/oxe/workflows/spec.md +15 -0
  175. package/oxe/workflows/ui-review.md +20 -16
  176. package/oxe/workflows/ui-spec.md +7 -3
  177. package/oxe/workflows/validate-gaps.md +13 -9
  178. package/oxe/workflows/verify.md +42 -3
  179. package/package.json +1 -1
  180. package/packages/runtime/src/audit/audit-trail.ts +243 -0
  181. package/packages/runtime/src/audit/index.ts +2 -0
  182. package/packages/runtime/src/audit/policy-pack.ts +62 -0
  183. package/packages/runtime/src/context/context-pack-builder.ts +66 -0
  184. package/packages/runtime/src/context/context-pack-store.ts +197 -0
  185. package/packages/runtime/src/context/context-profiles.ts +60 -0
  186. package/packages/runtime/src/context/index.ts +2 -0
  187. package/packages/runtime/src/decision/decision-engine.ts +174 -0
  188. package/packages/runtime/src/decision/decision-memo.ts +211 -0
  189. package/packages/runtime/src/decision/index.ts +2 -0
  190. package/packages/runtime/src/delivery/index.ts +1 -0
  191. package/packages/runtime/src/delivery/promotion-pipeline.ts +180 -0
  192. package/packages/runtime/src/index.ts +5 -0
  193. package/packages/runtime/src/plugins/capability-matrix.ts +83 -0
  194. package/packages/runtime/src/plugins/index.ts +2 -0
  195. package/packages/runtime/src/plugins/plugin-manifest.ts +113 -0
  196. package/packages/runtime/src/plugins/plugin-registry.ts +5 -0
  197. package/packages/runtime/src/policy/policy-engine.ts +138 -7
  198. package/packages/runtime/src/reducers/run-state-reducer.ts +143 -1
  199. package/packages/runtime/src/scheduler/agent-registry.ts +132 -0
  200. package/packages/runtime/src/scheduler/agent-roles.ts +109 -0
  201. package/packages/runtime/src/scheduler/index.ts +3 -0
  202. package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +106 -4
  203. package/packages/runtime/src/scheduler/run-journal.ts +62 -0
  204. package/packages/runtime/src/scheduler/scheduler.ts +168 -8
  205. package/packages/runtime/src/verification/index.ts +1 -0
  206. package/packages/runtime/src/verification/verification-manifest.ts +192 -0
  207. package/vscode-extension/oxe-agents-1.0.0.vsix +0 -0
@@ -0,0 +1,154 @@
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.AuditTrail = void 0;
7
+ exports.createQuota = createQuota;
8
+ exports.checkQuota = checkQuota;
9
+ exports.consumeQuota = consumeQuota;
10
+ const crypto_1 = __importDefault(require("crypto"));
11
+ const path_1 = __importDefault(require("path"));
12
+ const fs_1 = __importDefault(require("fs"));
13
+ const ACTION_SEVERITY = {
14
+ run_started: 'info',
15
+ run_completed: 'info',
16
+ run_paused: 'info',
17
+ run_recovered: 'warn',
18
+ gate_requested: 'warn',
19
+ gate_resolved: 'info',
20
+ policy_denied: 'warn',
21
+ plugin_registered: 'info',
22
+ plugin_invoked: 'info',
23
+ secret_accessed: 'critical',
24
+ infra_mutation: 'critical',
25
+ pr_created: 'info',
26
+ merge_approved: 'warn',
27
+ merge_blocked: 'warn',
28
+ };
29
+ class AuditTrail {
30
+ constructor(projectRoot, remoteSink) {
31
+ this.projectRoot = projectRoot;
32
+ this.remoteSink = remoteSink;
33
+ }
34
+ record(action, actor, options = {}) {
35
+ const entry = {
36
+ audit_id: `aud-${crypto_1.default.randomBytes(4).toString('hex')}`,
37
+ action,
38
+ severity: ACTION_SEVERITY[action],
39
+ run_id: options.runId ?? null,
40
+ work_item_id: options.workItemId ?? null,
41
+ actor,
42
+ resource: options.resource ?? null,
43
+ detail: options.detail ?? {},
44
+ timestamp: new Date().toISOString(),
45
+ };
46
+ this.append(entry);
47
+ return entry;
48
+ }
49
+ query(filter = {}) {
50
+ return this.load().filter((e) => {
51
+ if (filter.action && e.action !== filter.action)
52
+ return false;
53
+ if (filter.severity && e.severity !== filter.severity)
54
+ return false;
55
+ if (filter.runId && e.run_id !== filter.runId)
56
+ return false;
57
+ if (filter.since && e.timestamp < filter.since)
58
+ return false;
59
+ return true;
60
+ });
61
+ }
62
+ critical() {
63
+ return this.query({ severity: 'critical' });
64
+ }
65
+ metrics() {
66
+ const entries = this.load();
67
+ const by_action = {};
68
+ const actorSet = new Set();
69
+ let oldest = null;
70
+ let newest = null;
71
+ let critical_count = 0;
72
+ let warn_count = 0;
73
+ for (const e of entries) {
74
+ by_action[e.action] = (by_action[e.action] ?? 0) + 1;
75
+ actorSet.add(e.actor);
76
+ if (e.severity === 'critical')
77
+ critical_count++;
78
+ if (e.severity === 'warn')
79
+ warn_count++;
80
+ if (!oldest || e.timestamp < oldest)
81
+ oldest = e.timestamp;
82
+ if (!newest || e.timestamp > newest)
83
+ newest = e.timestamp;
84
+ }
85
+ return {
86
+ total_entries: entries.length,
87
+ critical_count,
88
+ warn_count,
89
+ by_action,
90
+ actors: [...actorSet],
91
+ oldest,
92
+ newest,
93
+ };
94
+ }
95
+ append(entry) {
96
+ const p = this.trailPath();
97
+ fs_1.default.mkdirSync(path_1.default.dirname(p), { recursive: true });
98
+ fs_1.default.appendFileSync(p, JSON.stringify(entry) + '\n', 'utf8');
99
+ // Fire-and-forget remote sink (failures are non-fatal)
100
+ if (this.remoteSink) {
101
+ this.remoteSink.write(entry).catch(() => { });
102
+ }
103
+ }
104
+ load() {
105
+ const p = this.trailPath();
106
+ if (!fs_1.default.existsSync(p))
107
+ return [];
108
+ try {
109
+ return fs_1.default
110
+ .readFileSync(p, 'utf8')
111
+ .split('\n')
112
+ .filter(Boolean)
113
+ .map((line) => JSON.parse(line));
114
+ }
115
+ catch {
116
+ return [];
117
+ }
118
+ }
119
+ trailPath() {
120
+ return path_1.default.join(this.projectRoot, '.oxe', 'AUDIT-TRAIL.ndjson');
121
+ }
122
+ }
123
+ exports.AuditTrail = AuditTrail;
124
+ // ─── RunQuota ─────────────────────────────────────────────────────────────────
125
+ function createQuota(runId, limits = {}) {
126
+ return {
127
+ run_id: runId,
128
+ max_work_items: limits.max_work_items ?? Infinity,
129
+ max_mutations: limits.max_mutations ?? Infinity,
130
+ max_retries_total: limits.max_retries_total ?? Infinity,
131
+ consumed_work_items: 0,
132
+ consumed_mutations: 0,
133
+ consumed_retries: 0,
134
+ };
135
+ }
136
+ function checkQuota(quota) {
137
+ if (quota.consumed_work_items > quota.max_work_items) {
138
+ return { quota_type: 'work_items', limit: quota.max_work_items, consumed: quota.consumed_work_items };
139
+ }
140
+ if (quota.consumed_mutations > quota.max_mutations) {
141
+ return { quota_type: 'mutations', limit: quota.max_mutations, consumed: quota.consumed_mutations };
142
+ }
143
+ if (quota.consumed_retries > quota.max_retries_total) {
144
+ return { quota_type: 'retries', limit: quota.max_retries_total, consumed: quota.consumed_retries };
145
+ }
146
+ return null;
147
+ }
148
+ function consumeQuota(quota, type, amount = 1) {
149
+ switch (type) {
150
+ case 'work_items': return { ...quota, consumed_work_items: quota.consumed_work_items + amount };
151
+ case 'mutations': return { ...quota, consumed_mutations: quota.consumed_mutations + amount };
152
+ case 'retries': return { ...quota, consumed_retries: quota.consumed_retries + amount };
153
+ }
154
+ }
@@ -0,0 +1,2 @@
1
+ export * from './audit-trail';
2
+ export * from './policy-pack';
@@ -0,0 +1,18 @@
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("./audit-trail"), exports);
18
+ __exportStar(require("./policy-pack"), exports);
@@ -0,0 +1,15 @@
1
+ import type { PolicyRule, EnvironmentGuardrail } from '../policy/policy-engine';
2
+ import { PolicyEngine } from '../policy/policy-engine';
3
+ export interface PolicyPack {
4
+ pack_id: string;
5
+ org_id: string;
6
+ name: string;
7
+ version: string;
8
+ policies: PolicyRule[];
9
+ guardrail: EnvironmentGuardrail;
10
+ created_at: string;
11
+ }
12
+ export declare function savePolicyPack(projectRoot: string, pack: PolicyPack): void;
13
+ export declare function loadPolicyPack(projectRoot: string, packId: string): PolicyPack | null;
14
+ export declare function listPolicyPacks(projectRoot: string): PolicyPack[];
15
+ export declare function applyPolicyPack(engine: PolicyEngine, pack: PolicyPack): PolicyEngine;
@@ -0,0 +1,57 @@
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.savePolicyPack = savePolicyPack;
7
+ exports.loadPolicyPack = loadPolicyPack;
8
+ exports.listPolicyPacks = listPolicyPacks;
9
+ exports.applyPolicyPack = applyPolicyPack;
10
+ const path_1 = __importDefault(require("path"));
11
+ const fs_1 = __importDefault(require("fs"));
12
+ function packDir(projectRoot) {
13
+ return path_1.default.join(projectRoot, '.oxe', 'policy-packs');
14
+ }
15
+ function packFilePath(projectRoot, packId) {
16
+ return path_1.default.join(packDir(projectRoot), `${packId}.json`);
17
+ }
18
+ function savePolicyPack(projectRoot, pack) {
19
+ const dir = packDir(projectRoot);
20
+ fs_1.default.mkdirSync(dir, { recursive: true });
21
+ fs_1.default.writeFileSync(packFilePath(projectRoot, pack.pack_id), JSON.stringify(pack, null, 2), 'utf8');
22
+ }
23
+ function loadPolicyPack(projectRoot, packId) {
24
+ const p = packFilePath(projectRoot, packId);
25
+ if (!fs_1.default.existsSync(p))
26
+ return null;
27
+ try {
28
+ return JSON.parse(fs_1.default.readFileSync(p, 'utf8'));
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ function listPolicyPacks(projectRoot) {
35
+ const dir = packDir(projectRoot);
36
+ if (!fs_1.default.existsSync(dir))
37
+ return [];
38
+ return fs_1.default
39
+ .readdirSync(dir)
40
+ .filter((f) => f.endsWith('.json'))
41
+ .map((f) => {
42
+ try {
43
+ return JSON.parse(fs_1.default.readFileSync(path_1.default.join(dir, f), 'utf8'));
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ })
49
+ .filter((p) => p !== null);
50
+ }
51
+ function applyPolicyPack(engine, pack) {
52
+ let result = engine.withGuardrail(pack.guardrail);
53
+ for (const rule of pack.policies) {
54
+ result = result.withRule(rule);
55
+ }
56
+ return result;
57
+ }
@@ -1,6 +1,8 @@
1
1
  import type { WorkItem } from '../models/work-item';
2
2
  import type { Evidence } from '../models/evidence';
3
3
  import type { RunState } from '../reducers/run-state-reducer';
4
+ import type { ContextProfile } from './context-profiles';
5
+ import type { AutonomyTier } from '../policy/policy-engine';
4
6
  export interface ContextArtifact {
5
7
  id: string;
6
8
  kind: 'evidence' | 'lesson' | 'file' | 'summary';
@@ -27,10 +29,23 @@ export interface ContextPack {
27
29
  redundancy_removed: number;
28
30
  built_at: string;
29
31
  }
32
+ export interface ContextQualityScore {
33
+ completeness: number;
34
+ relevance_mean: number;
35
+ redundancy: number;
36
+ recency_score: number;
37
+ overall: number;
38
+ }
39
+ export declare function scorePackQuality(pack: ContextPack, profile: ContextProfile): ContextQualityScore;
30
40
  export declare class ContextPackBuilder {
31
41
  private readonly opts;
32
42
  constructor(opts?: ContextPackOptions);
33
43
  build(workItem: WorkItem, state: RunState, evidenceItems: Evidence[], evidenceContents: Map<string, string>, lessons: LessonMetric[]): ContextPack;
34
44
  /** Convenience: build with no evidence, just lessons and state summary */
35
45
  buildLightweight(workItem: WorkItem, state: RunState, lessons: LessonMetric[]): ContextPack;
46
+ /**
47
+ * Filter artifacts to those whose path-like tags are within mutation_scope.
48
+ * L0/L1 tiers apply the filter; L2/L3 skip it (full access).
49
+ */
50
+ filterByMutationScope(artifacts: ContextArtifact[], mutationScope: string[], autonomyTier: AutonomyTier): ContextArtifact[];
36
51
  }
@@ -1,6 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
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
+ }
4
31
  // ─── Relevance scoring ────────────────────────────────────────────────────────
5
32
  function scoreEvidenceRelevance(evidence, workItem) {
6
33
  let score = 0.5;
@@ -132,5 +159,20 @@ class ContextPackBuilder {
132
159
  buildLightweight(workItem, state, lessons) {
133
160
  return this.build(workItem, state, [], new Map(), lessons);
134
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
+ }
135
177
  }
136
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
+ }
@@ -1 +1,3 @@
1
1
  export * from './context-pack-builder';
2
+ export * from './context-pack-store';
3
+ export * from './context-profiles';
@@ -15,3 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
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[];