oxe-cc 0.9.2 → 1.0.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.
- package/.cursor/commands/oxe-retro.md +2 -2
- package/.cursor/commands/oxe-spec.md +2 -2
- package/.github/prompts/oxe-retro.prompt.md +2 -2
- package/.github/prompts/oxe-spec.prompt.md +2 -2
- package/README.md +1 -1
- package/bin/banner.txt +1 -1
- package/bin/lib/oxe-context-engine.cjs +1 -0
- package/bin/lib/oxe-dashboard.cjs +9 -7
- package/bin/lib/oxe-operational.cjs +569 -4
- package/bin/oxe-cc.js +141 -57
- package/commands/oxe/retro.md +2 -2
- package/commands/oxe/spec.md +2 -2
- package/lib/runtime/compiler/graph-compiler.d.ts +83 -0
- package/lib/runtime/compiler/graph-compiler.js +135 -0
- package/lib/runtime/compiler/index.d.ts +1 -0
- package/lib/runtime/compiler/index.js +17 -0
- package/lib/runtime/context/context-pack-builder.d.ts +36 -0
- package/lib/runtime/context/context-pack-builder.js +136 -0
- package/lib/runtime/context/index.d.ts +1 -0
- package/lib/runtime/context/index.js +17 -0
- package/lib/runtime/delivery/branch-manager.d.ts +19 -0
- package/lib/runtime/delivery/branch-manager.js +78 -0
- package/lib/runtime/delivery/ci-checks.d.ts +34 -0
- package/lib/runtime/delivery/ci-checks.js +209 -0
- package/lib/runtime/delivery/index.d.ts +3 -0
- package/lib/runtime/delivery/index.js +19 -0
- package/lib/runtime/delivery/pr-manager.d.ts +30 -0
- package/lib/runtime/delivery/pr-manager.js +82 -0
- package/lib/runtime/events/bus.d.ts +9 -0
- package/lib/runtime/events/bus.js +63 -0
- package/lib/runtime/events/catalog.d.ts +3 -0
- package/lib/runtime/events/catalog.js +30 -0
- package/lib/runtime/events/envelope.d.ts +13 -0
- package/lib/runtime/events/envelope.js +2 -0
- package/lib/runtime/events/index.d.ts +3 -0
- package/lib/runtime/events/index.js +19 -0
- package/lib/runtime/evidence/evidence-store.d.ts +22 -0
- package/lib/runtime/evidence/evidence-store.js +106 -0
- package/lib/runtime/evidence/index.d.ts +1 -0
- package/lib/runtime/evidence/index.js +17 -0
- package/lib/runtime/gate/gate-manager.d.ts +39 -0
- package/lib/runtime/gate/gate-manager.js +104 -0
- package/lib/runtime/gate/index.d.ts +1 -0
- package/lib/runtime/gate/index.js +17 -0
- package/lib/runtime/index.d.ts +16 -0
- package/lib/runtime/index.js +40 -0
- package/lib/runtime/models/attempt.d.ts +12 -0
- package/lib/runtime/models/attempt.js +2 -0
- package/lib/runtime/models/evidence.d.ts +9 -0
- package/lib/runtime/models/evidence.js +2 -0
- package/lib/runtime/models/gate-decision.d.ts +10 -0
- package/lib/runtime/models/gate-decision.js +2 -0
- package/lib/runtime/models/index.d.ts +8 -0
- package/lib/runtime/models/index.js +24 -0
- package/lib/runtime/models/run.d.ts +13 -0
- package/lib/runtime/models/run.js +2 -0
- package/lib/runtime/models/session.d.ts +10 -0
- package/lib/runtime/models/session.js +2 -0
- package/lib/runtime/models/verification-result.d.ts +9 -0
- package/lib/runtime/models/verification-result.js +2 -0
- package/lib/runtime/models/work-item.d.ts +15 -0
- package/lib/runtime/models/work-item.js +2 -0
- package/lib/runtime/models/workspace.d.ts +25 -0
- package/lib/runtime/models/workspace.js +2 -0
- package/lib/runtime/plugins/index.d.ts +2 -0
- package/lib/runtime/plugins/index.js +18 -0
- package/lib/runtime/plugins/plugin-abi.d.ts +76 -0
- package/lib/runtime/plugins/plugin-abi.js +2 -0
- package/lib/runtime/plugins/plugin-registry.d.ts +21 -0
- package/lib/runtime/plugins/plugin-registry.js +114 -0
- package/lib/runtime/policy/index.d.ts +1 -0
- package/lib/runtime/policy/index.js +17 -0
- package/lib/runtime/policy/policy-engine.d.ts +40 -0
- package/lib/runtime/policy/policy-engine.js +80 -0
- package/lib/runtime/projection/index.d.ts +1 -0
- package/lib/runtime/projection/index.js +17 -0
- package/lib/runtime/projection/projection-engine.d.ts +11 -0
- package/lib/runtime/projection/projection-engine.js +218 -0
- package/lib/runtime/reducers/debug-reducer.d.ts +10 -0
- package/lib/runtime/reducers/debug-reducer.js +30 -0
- package/lib/runtime/reducers/index.d.ts +2 -0
- package/lib/runtime/reducers/index.js +18 -0
- package/lib/runtime/reducers/run-state-reducer.d.ts +20 -0
- package/lib/runtime/reducers/run-state-reducer.js +110 -0
- package/lib/runtime/scheduler/index.d.ts +1 -0
- package/lib/runtime/scheduler/index.js +17 -0
- package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +34 -0
- package/lib/runtime/scheduler/multi-agent-coordinator.js +166 -0
- package/lib/runtime/scheduler/scheduler.d.ts +39 -0
- package/lib/runtime/scheduler/scheduler.js +196 -0
- package/lib/runtime/verification/index.d.ts +1 -0
- package/lib/runtime/verification/index.js +17 -0
- package/lib/runtime/verification/verification-compiler.d.ts +56 -0
- package/lib/runtime/verification/verification-compiler.js +147 -0
- package/lib/runtime/workspace/index.d.ts +5 -0
- package/lib/runtime/workspace/index.js +24 -0
- package/lib/runtime/workspace/strategies/ephemeral-container.d.ts +22 -0
- package/lib/runtime/workspace/strategies/ephemeral-container.js +109 -0
- package/lib/runtime/workspace/strategies/git-worktree.d.ts +12 -0
- package/lib/runtime/workspace/strategies/git-worktree.js +79 -0
- package/lib/runtime/workspace/strategies/inplace.d.ts +10 -0
- package/lib/runtime/workspace/strategies/inplace.js +37 -0
- package/lib/runtime/workspace/workspace-manager.d.ts +13 -0
- package/lib/runtime/workspace/workspace-manager.js +2 -0
- package/lib/sdk/index.cjs +24 -7
- package/lib/sdk/index.d.ts +17 -7
- package/oxe/templates/LESSONS-METRICS.template.json +13 -0
- package/oxe/workflows/references/robustness-elevation.md +295 -0
- package/oxe/workflows/references/workflow-runtime-contracts.json +32 -4
- package/oxe/workflows/retro.md +21 -0
- package/oxe/workflows/spec.md +50 -26
- package/oxe/workflows/verify.md +36 -0
- package/package.json +9 -3
- package/packages/runtime/package.json +17 -0
- package/packages/runtime/src/compiler/graph-compiler.ts +245 -0
- package/packages/runtime/src/compiler/index.ts +1 -0
- package/packages/runtime/src/context/context-pack-builder.ts +193 -0
- package/packages/runtime/src/context/index.ts +1 -0
- package/packages/runtime/src/delivery/branch-manager.ts +84 -0
- package/packages/runtime/src/delivery/ci-checks.ts +252 -0
- package/packages/runtime/src/delivery/index.ts +3 -0
- package/packages/runtime/src/delivery/pr-manager.ts +112 -0
- package/packages/runtime/src/events/bus.ts +92 -0
- package/packages/runtime/src/events/catalog.ts +29 -0
- package/packages/runtime/src/events/envelope.ts +14 -0
- package/packages/runtime/src/events/index.ts +3 -0
- package/packages/runtime/src/evidence/evidence-store.ts +130 -0
- package/packages/runtime/src/evidence/index.ts +1 -0
- package/packages/runtime/src/gate/gate-manager.ts +137 -0
- package/packages/runtime/src/gate/index.ts +1 -0
- package/packages/runtime/src/index.ts +32 -0
- package/packages/runtime/src/models/attempt.ts +19 -0
- package/packages/runtime/src/models/evidence.ts +21 -0
- package/packages/runtime/src/models/gate-decision.ts +21 -0
- package/packages/runtime/src/models/index.ts +8 -0
- package/packages/runtime/src/models/run.ts +24 -0
- package/packages/runtime/src/models/session.ts +11 -0
- package/packages/runtime/src/models/verification-result.ts +10 -0
- package/packages/runtime/src/models/work-item.ts +25 -0
- package/packages/runtime/src/models/workspace.ts +28 -0
- package/packages/runtime/src/plugins/index.ts +2 -0
- package/packages/runtime/src/plugins/plugin-abi.ts +95 -0
- package/packages/runtime/src/plugins/plugin-registry.ts +119 -0
- package/packages/runtime/src/policy/index.ts +1 -0
- package/packages/runtime/src/policy/policy-engine.ts +113 -0
- package/packages/runtime/src/projection/index.ts +1 -0
- package/packages/runtime/src/projection/projection-engine.ts +249 -0
- package/packages/runtime/src/reducers/debug-reducer.ts +36 -0
- package/packages/runtime/src/reducers/index.ts +2 -0
- package/packages/runtime/src/reducers/run-state-reducer.ts +127 -0
- package/packages/runtime/src/scheduler/index.ts +1 -0
- package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +231 -0
- package/packages/runtime/src/scheduler/scheduler.ts +281 -0
- package/packages/runtime/src/verification/index.ts +1 -0
- package/packages/runtime/src/verification/verification-compiler.ts +225 -0
- package/packages/runtime/src/workspace/index.ts +5 -0
- package/packages/runtime/src/workspace/strategies/ephemeral-container.ts +121 -0
- package/packages/runtime/src/workspace/strategies/git-worktree.ts +77 -0
- package/packages/runtime/src/workspace/strategies/inplace.ts +35 -0
- package/packages/runtime/src/workspace/workspace-manager.ts +15 -0
- package/packages/runtime/tsconfig.json +17 -0
- package/vscode-extension/oxe-agents-1.0.0.vsix +0 -0
- package/vscode-extension/package.json +1 -1
|
@@ -70,6 +70,544 @@ function parseArrayField(value) {
|
|
|
70
70
|
return raw.split(',').map((item) => item.trim()).filter(Boolean);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
function loadRuntimeModule() {
|
|
74
|
+
try {
|
|
75
|
+
return require('../../lib/runtime/index.js');
|
|
76
|
+
} catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function loadSdkParsers() {
|
|
82
|
+
try {
|
|
83
|
+
const sdk = require('../../lib/sdk/index.cjs');
|
|
84
|
+
if (sdk && typeof sdk.parsePlan === 'function' && typeof sdk.parseSpec === 'function') {
|
|
85
|
+
return { parsePlan: sdk.parsePlan, parseSpec: sdk.parseSpec };
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
} catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function loadProjectHealth() {
|
|
94
|
+
try {
|
|
95
|
+
return require('./oxe-project-health.cjs');
|
|
96
|
+
} catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function readJsonIfExists(filePath) {
|
|
102
|
+
const raw = readTextIfExists(filePath);
|
|
103
|
+
if (!raw) return null;
|
|
104
|
+
try {
|
|
105
|
+
return JSON.parse(raw);
|
|
106
|
+
} catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function preferExistingPath(primaryPath, fallbackPath) {
|
|
112
|
+
if (primaryPath && fs.existsSync(primaryPath)) return primaryPath;
|
|
113
|
+
return fallbackPath || primaryPath || null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function resolveRuntimeArtifactPaths(projectRoot, activeSession) {
|
|
117
|
+
const health = loadProjectHealth();
|
|
118
|
+
if (!health || typeof health.oxePaths !== 'function' || typeof health.scopedOxePaths !== 'function') {
|
|
119
|
+
const oxeDir = path.join(projectRoot, '.oxe');
|
|
120
|
+
if (!activeSession) {
|
|
121
|
+
return {
|
|
122
|
+
state: path.join(oxeDir, 'STATE.md'),
|
|
123
|
+
spec: path.join(oxeDir, 'SPEC.md'),
|
|
124
|
+
plan: path.join(oxeDir, 'PLAN.md'),
|
|
125
|
+
verify: path.join(oxeDir, 'VERIFY.md'),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const sessionRoot = path.join(oxeDir, ...String(activeSession).split('/'));
|
|
129
|
+
return {
|
|
130
|
+
state: path.join(oxeDir, 'STATE.md'),
|
|
131
|
+
spec: preferExistingPath(path.join(sessionRoot, 'spec', 'SPEC.md'), path.join(oxeDir, 'SPEC.md')),
|
|
132
|
+
plan: preferExistingPath(path.join(sessionRoot, 'plan', 'PLAN.md'), path.join(oxeDir, 'PLAN.md')),
|
|
133
|
+
verify: preferExistingPath(path.join(sessionRoot, 'verification', 'VERIFY.md'), path.join(oxeDir, 'VERIFY.md')),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const base = health.oxePaths(projectRoot);
|
|
137
|
+
const scoped = health.scopedOxePaths(projectRoot, activeSession || null);
|
|
138
|
+
return {
|
|
139
|
+
state: base.state,
|
|
140
|
+
spec: preferExistingPath(scoped.spec, base.spec),
|
|
141
|
+
plan: preferExistingPath(scoped.plan, base.plan),
|
|
142
|
+
verify: preferExistingPath(scoped.verify, base.verify),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function normalizeRuntimeEventType(type) {
|
|
147
|
+
const raw = String(type || '').trim();
|
|
148
|
+
if (!raw) return 'RunStarted';
|
|
149
|
+
const directMap = {
|
|
150
|
+
SessionCreated: 'SessionCreated',
|
|
151
|
+
RunStarted: 'RunStarted',
|
|
152
|
+
GraphCompiled: 'GraphCompiled',
|
|
153
|
+
WorkItemReady: 'WorkItemReady',
|
|
154
|
+
WorkspaceAllocated: 'WorkspaceAllocated',
|
|
155
|
+
AttemptStarted: 'AttemptStarted',
|
|
156
|
+
ToolInvoked: 'ToolInvoked',
|
|
157
|
+
ToolCompleted: 'ToolCompleted',
|
|
158
|
+
ToolFailed: 'ToolFailed',
|
|
159
|
+
EvidenceCollected: 'EvidenceCollected',
|
|
160
|
+
PolicyEvaluated: 'PolicyEvaluated',
|
|
161
|
+
GateRequested: 'GateRequested',
|
|
162
|
+
GateResolved: 'GateResolved',
|
|
163
|
+
VerificationStarted: 'VerificationStarted',
|
|
164
|
+
VerificationCompleted: 'VerificationCompleted',
|
|
165
|
+
RetryScheduled: 'RetryScheduled',
|
|
166
|
+
WorkItemCompleted: 'WorkItemCompleted',
|
|
167
|
+
WorkItemBlocked: 'WorkItemBlocked',
|
|
168
|
+
RunCompleted: 'RunCompleted',
|
|
169
|
+
RetroPublished: 'RetroPublished',
|
|
170
|
+
LessonPromoted: 'LessonPromoted',
|
|
171
|
+
};
|
|
172
|
+
if (directMap[raw]) return directMap[raw];
|
|
173
|
+
const lower = raw.toLowerCase();
|
|
174
|
+
const legacyMap = {
|
|
175
|
+
session_created: 'SessionCreated',
|
|
176
|
+
run_started: 'RunStarted',
|
|
177
|
+
graph_compiled: 'GraphCompiled',
|
|
178
|
+
work_item_ready: 'WorkItemReady',
|
|
179
|
+
task_ready: 'WorkItemReady',
|
|
180
|
+
workspace_allocated: 'WorkspaceAllocated',
|
|
181
|
+
attempt_started: 'AttemptStarted',
|
|
182
|
+
tool_invoked: 'ToolInvoked',
|
|
183
|
+
tool_completed: 'ToolCompleted',
|
|
184
|
+
tool_failed: 'ToolFailed',
|
|
185
|
+
evidence_collected: 'EvidenceCollected',
|
|
186
|
+
policy_evaluated: 'PolicyEvaluated',
|
|
187
|
+
gate_requested: 'GateRequested',
|
|
188
|
+
gate_resolved: 'GateResolved',
|
|
189
|
+
checkpoint_opened: 'GateRequested',
|
|
190
|
+
checkpoint_resolved: 'GateResolved',
|
|
191
|
+
verification_started: 'VerificationStarted',
|
|
192
|
+
verification_completed: 'VerificationCompleted',
|
|
193
|
+
verify_complete: 'VerificationCompleted',
|
|
194
|
+
retry_scheduled: 'RetryScheduled',
|
|
195
|
+
work_item_completed: 'WorkItemCompleted',
|
|
196
|
+
task_completed: 'WorkItemCompleted',
|
|
197
|
+
work_item_blocked: 'WorkItemBlocked',
|
|
198
|
+
task_blocked: 'WorkItemBlocked',
|
|
199
|
+
run_completed: 'RunCompleted',
|
|
200
|
+
retro_published: 'RetroPublished',
|
|
201
|
+
lesson_promoted: 'LessonPromoted',
|
|
202
|
+
};
|
|
203
|
+
return legacyMap[lower] || raw;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function toRuntimeEventEnvelope(event = {}, activeSession) {
|
|
207
|
+
const type = normalizeRuntimeEventType(event.type);
|
|
208
|
+
const payload = event.payload && typeof event.payload === 'object' ? { ...event.payload } : {};
|
|
209
|
+
const workItemId = event.work_item_id || event.task_id || payload.work_item_id || payload.task_id || null;
|
|
210
|
+
const attemptId = event.attempt_id || payload.attempt_id || null;
|
|
211
|
+
if (type === 'RunStarted') {
|
|
212
|
+
payload.run_id = payload.run_id || event.run_id || null;
|
|
213
|
+
payload.session_id = payload.session_id || activeSession || event.session_id || null;
|
|
214
|
+
payload.graph_version = payload.graph_version || 'legacy';
|
|
215
|
+
payload.started_at = payload.started_at || event.timestamp || new Date().toISOString();
|
|
216
|
+
payload.ended_at = payload.ended_at == null ? null : payload.ended_at;
|
|
217
|
+
payload.status = payload.status || 'running';
|
|
218
|
+
payload.initiator = payload.initiator || 'scheduler';
|
|
219
|
+
payload.mode = payload.mode || 'por_onda';
|
|
220
|
+
} else if (type === 'RunCompleted') {
|
|
221
|
+
payload.run_id = payload.run_id || event.run_id || null;
|
|
222
|
+
payload.status = payload.status || 'completed';
|
|
223
|
+
} else if (type === 'WorkItemReady') {
|
|
224
|
+
payload.work_item_id = payload.work_item_id || workItemId;
|
|
225
|
+
payload.title = payload.title || workItemId || 'work-item';
|
|
226
|
+
payload.type = payload.type || 'task';
|
|
227
|
+
payload.depends_on = Array.isArray(payload.depends_on) ? payload.depends_on : [];
|
|
228
|
+
payload.mutation_scope = Array.isArray(payload.mutation_scope) ? payload.mutation_scope : [];
|
|
229
|
+
payload.policy_ref = payload.policy_ref || null;
|
|
230
|
+
payload.verify_ref = Array.isArray(payload.verify_ref) ? payload.verify_ref : [];
|
|
231
|
+
payload.status = payload.status || 'pending';
|
|
232
|
+
payload.workspace_strategy = payload.workspace_strategy || 'inplace';
|
|
233
|
+
payload.run_id = payload.run_id || event.run_id || null;
|
|
234
|
+
} else if (type === 'AttemptStarted') {
|
|
235
|
+
payload.attempt_number = payload.attempt_number || 1;
|
|
236
|
+
} else if (type === 'WorkspaceAllocated') {
|
|
237
|
+
payload.workspace_id = payload.workspace_id || `ws-${workItemId || 'runtime'}`;
|
|
238
|
+
payload.strategy = payload.strategy || payload.workspace_strategy || 'inplace';
|
|
239
|
+
payload.root_path = payload.root_path || null;
|
|
240
|
+
payload.base_commit = payload.base_commit || null;
|
|
241
|
+
payload.branch = payload.branch || null;
|
|
242
|
+
payload.container_ref = payload.container_ref || null;
|
|
243
|
+
payload.status = payload.status || 'ready';
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
id: String(event.event_id || ''),
|
|
247
|
+
type,
|
|
248
|
+
timestamp: event.timestamp || new Date().toISOString(),
|
|
249
|
+
session_id: activeSession || event.session_id || null,
|
|
250
|
+
run_id: event.run_id || payload.run_id || null,
|
|
251
|
+
work_item_id: workItemId,
|
|
252
|
+
attempt_id: attemptId,
|
|
253
|
+
causation_id: event.causation_id || payload.causation_id || null,
|
|
254
|
+
correlation_id: event.correlation_id || payload.correlation_id || null,
|
|
255
|
+
payload,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function serializeCanonicalState(state) {
|
|
260
|
+
if (!state || typeof state !== 'object') return null;
|
|
261
|
+
return {
|
|
262
|
+
run: state.run || null,
|
|
263
|
+
workItems: Array.from((state.workItems && state.workItems.values()) || []),
|
|
264
|
+
attempts: Object.fromEntries(Array.from((state.attempts && state.attempts.entries()) || [])),
|
|
265
|
+
workspaces: Array.from((state.workspaces && state.workspaces.values()) || []),
|
|
266
|
+
completedWorkItems: Array.from(state.completedWorkItems || []),
|
|
267
|
+
failedWorkItems: Array.from(state.failedWorkItems || []),
|
|
268
|
+
blockedWorkItems: Array.from(state.blockedWorkItems || []),
|
|
269
|
+
summary: {
|
|
270
|
+
work_item_count: state.workItems instanceof Map ? state.workItems.size : 0,
|
|
271
|
+
attempt_count: state.attempts instanceof Map
|
|
272
|
+
? Array.from(state.attempts.values()).reduce((acc, list) => acc + (Array.isArray(list) ? list.length : 0), 0)
|
|
273
|
+
: 0,
|
|
274
|
+
workspace_count: state.workspaces instanceof Map ? state.workspaces.size : 0,
|
|
275
|
+
completed: state.completedWorkItems instanceof Set ? state.completedWorkItems.size : 0,
|
|
276
|
+
failed: state.failedWorkItems instanceof Set ? state.failedWorkItems.size : 0,
|
|
277
|
+
blocked: state.blockedWorkItems instanceof Set ? state.blockedWorkItems.size : 0,
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function hydrateCanonicalState(serialized) {
|
|
283
|
+
const safe = serialized && typeof serialized === 'object' ? serialized : {};
|
|
284
|
+
return {
|
|
285
|
+
run: safe.run || null,
|
|
286
|
+
workItems: new Map(
|
|
287
|
+
Array.isArray(safe.workItems)
|
|
288
|
+
? safe.workItems
|
|
289
|
+
.filter((item) => item && item.work_item_id)
|
|
290
|
+
.map((item) => [item.work_item_id, item])
|
|
291
|
+
: []
|
|
292
|
+
),
|
|
293
|
+
attempts: new Map(Object.entries(safe.attempts && typeof safe.attempts === 'object' ? safe.attempts : {})),
|
|
294
|
+
workspaces: new Map(
|
|
295
|
+
Array.isArray(safe.workspaces)
|
|
296
|
+
? safe.workspaces
|
|
297
|
+
.filter((item) => item && item.workspace_id)
|
|
298
|
+
.map((item) => [item.workspace_id, item])
|
|
299
|
+
: []
|
|
300
|
+
),
|
|
301
|
+
completedWorkItems: new Set(Array.isArray(safe.completedWorkItems) ? safe.completedWorkItems : []),
|
|
302
|
+
failedWorkItems: new Set(Array.isArray(safe.failedWorkItems) ? safe.failedWorkItems : []),
|
|
303
|
+
blockedWorkItems: new Set(Array.isArray(safe.blockedWorkItems) ? safe.blockedWorkItems : []),
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function mergeCanonicalStateWithRunState(serializedState, runState = {}, activeSession, compiledGraph) {
|
|
308
|
+
const live = hydrateCanonicalState(serializedState);
|
|
309
|
+
const runId = runState.run_id || (live.run && live.run.run_id) || null;
|
|
310
|
+
if (!live.run && runId) {
|
|
311
|
+
live.run = {
|
|
312
|
+
run_id: runId,
|
|
313
|
+
session_id: activeSession || null,
|
|
314
|
+
graph_version: (compiledGraph && compiledGraph.metadata && compiledGraph.metadata.plan_hash) || 'legacy',
|
|
315
|
+
started_at: runState.created_at || new Date().toISOString(),
|
|
316
|
+
ended_at: /completed|failed|aborted|cancelled/.test(String(runState.status || '')) ? (runState.updated_at || null) : null,
|
|
317
|
+
status: runState.status || 'planned',
|
|
318
|
+
initiator: 'scheduler',
|
|
319
|
+
mode: runState.cursor && runState.cursor.mode === 'task'
|
|
320
|
+
? 'por_tarefa'
|
|
321
|
+
: runState.cursor && runState.cursor.mode === 'wave'
|
|
322
|
+
? 'por_onda'
|
|
323
|
+
: 'completo',
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const compiledNodes = compiledGraph && compiledGraph.nodes && typeof compiledGraph.nodes === 'object'
|
|
328
|
+
? Object.values(compiledGraph.nodes)
|
|
329
|
+
: [];
|
|
330
|
+
for (const node of compiledNodes) {
|
|
331
|
+
if (!node || !node.id || live.workItems.has(node.id)) continue;
|
|
332
|
+
live.workItems.set(node.id, {
|
|
333
|
+
work_item_id: node.id,
|
|
334
|
+
run_id: runId,
|
|
335
|
+
title: node.title || node.id,
|
|
336
|
+
type: 'task',
|
|
337
|
+
depends_on: Array.isArray(node.depends_on) ? node.depends_on : [],
|
|
338
|
+
mutation_scope: Array.isArray(node.mutation_scope) ? node.mutation_scope : [],
|
|
339
|
+
policy_ref: node.policy && node.policy.requires_human_approval ? 'human_approval' : null,
|
|
340
|
+
verify_ref: node.verify && Array.isArray(node.verify.acceptance_refs) ? node.verify.acceptance_refs : [],
|
|
341
|
+
status: 'pending',
|
|
342
|
+
workspace_strategy: node.workspace_strategy || 'inplace',
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const activeTasks = Array.isArray(runState.active_tasks) ? runState.active_tasks.map(String) : [];
|
|
347
|
+
for (const taskId of activeTasks) {
|
|
348
|
+
const currentItem = live.workItems.get(taskId) || {
|
|
349
|
+
work_item_id: taskId,
|
|
350
|
+
run_id: runId,
|
|
351
|
+
title: taskId,
|
|
352
|
+
type: 'task',
|
|
353
|
+
depends_on: [],
|
|
354
|
+
mutation_scope: [],
|
|
355
|
+
policy_ref: null,
|
|
356
|
+
verify_ref: [],
|
|
357
|
+
status: 'pending',
|
|
358
|
+
workspace_strategy: 'inplace',
|
|
359
|
+
};
|
|
360
|
+
live.workItems.set(taskId, { ...currentItem, status: 'running' });
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
for (const blockedId of Array.isArray(runState.pending_checkpoints) ? runState.pending_checkpoints.map(String) : []) {
|
|
364
|
+
if (!live.blockedWorkItems.has(blockedId)) live.blockedWorkItems.add(blockedId);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (Array.isArray(runState.failures)) {
|
|
368
|
+
for (const failure of runState.failures) {
|
|
369
|
+
const ref = failure && typeof failure === 'object'
|
|
370
|
+
? String(failure.work_item_id || failure.task_id || failure.id || '')
|
|
371
|
+
: '';
|
|
372
|
+
if (ref) {
|
|
373
|
+
live.failedWorkItems.add(ref);
|
|
374
|
+
const item = live.workItems.get(ref);
|
|
375
|
+
if (item) live.workItems.set(ref, { ...item, status: 'failed' });
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (Array.isArray(runState.evidence) && runState.evidence.length && live.run) {
|
|
381
|
+
live.run = { ...live.run, evidence_count: runState.evidence.length };
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
for (const completedId of live.completedWorkItems) {
|
|
385
|
+
const item = live.workItems.get(completedId);
|
|
386
|
+
if (item) live.workItems.set(completedId, { ...item, status: 'completed' });
|
|
387
|
+
}
|
|
388
|
+
for (const failedId of live.failedWorkItems) {
|
|
389
|
+
const item = live.workItems.get(failedId);
|
|
390
|
+
if (item) live.workItems.set(failedId, { ...item, status: 'failed' });
|
|
391
|
+
}
|
|
392
|
+
for (const blockedId of live.blockedWorkItems) {
|
|
393
|
+
const item = live.workItems.get(blockedId);
|
|
394
|
+
if (item) live.workItems.set(blockedId, { ...item, status: 'blocked' });
|
|
395
|
+
}
|
|
396
|
+
return live;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function reduceCanonicalRunStateLive(projectRoot, activeSession, options = {}) {
|
|
400
|
+
const runtime = loadRuntimeModule();
|
|
401
|
+
if (!runtime || typeof runtime.reduce !== 'function') return null;
|
|
402
|
+
const currentRun = options.runState || readRunState(projectRoot, activeSession) || null;
|
|
403
|
+
const runId = options.runId || (currentRun && currentRun.run_id) || null;
|
|
404
|
+
let events = readEvents(projectRoot, activeSession);
|
|
405
|
+
if (runId) events = events.filter((event) => !event.run_id || event.run_id === runId);
|
|
406
|
+
const reduced = runtime.reduce(events.map((event) => toRuntimeEventEnvelope(event, activeSession)));
|
|
407
|
+
return mergeCanonicalStateWithRunState(
|
|
408
|
+
serializeCanonicalState(reduced),
|
|
409
|
+
currentRun || {},
|
|
410
|
+
activeSession,
|
|
411
|
+
currentRun && currentRun.compiled_graph ? currentRun.compiled_graph : null
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function reduceCanonicalRunState(projectRoot, activeSession, options = {}) {
|
|
416
|
+
return serializeCanonicalState(reduceCanonicalRunStateLive(projectRoot, activeSession, options));
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function compileExecutionGraphFromArtifacts(projectRoot, activeSession, options = {}) {
|
|
420
|
+
const runtime = loadRuntimeModule();
|
|
421
|
+
const parsers = loadSdkParsers();
|
|
422
|
+
if (!runtime || typeof runtime.compile !== 'function' || typeof runtime.toSerializable !== 'function') {
|
|
423
|
+
throw new Error('Runtime package não está disponível. Rode npm run build:runtime.');
|
|
424
|
+
}
|
|
425
|
+
if (!parsers) {
|
|
426
|
+
throw new Error('Parsers do SDK indisponíveis para compilar o grafo.');
|
|
427
|
+
}
|
|
428
|
+
const artifactPaths = resolveRuntimeArtifactPaths(projectRoot, activeSession);
|
|
429
|
+
const specText = readTextIfExists(artifactPaths.spec);
|
|
430
|
+
const planText = readTextIfExists(artifactPaths.plan);
|
|
431
|
+
if (!specText) throw new Error(`SPEC.md ausente em ${artifactPaths.spec}`);
|
|
432
|
+
if (!planText) throw new Error(`PLAN.md ausente em ${artifactPaths.plan}`);
|
|
433
|
+
const parsedSpec = parsers.parseSpec(specText);
|
|
434
|
+
const parsedPlan = parsers.parsePlan(planText);
|
|
435
|
+
const graph = runtime.compile(parsedPlan, parsedSpec, options.compilerOptions || {});
|
|
436
|
+
const validationErrors = typeof runtime.validateGraph === 'function' ? runtime.validateGraph(graph) : [];
|
|
437
|
+
const compiledGraph = runtime.toSerializable(graph);
|
|
438
|
+
const current = options.runState || readRunState(projectRoot, activeSession) || {};
|
|
439
|
+
const runId = current.run_id || makeRunId();
|
|
440
|
+
const next = writeRunState(projectRoot, activeSession, {
|
|
441
|
+
...current,
|
|
442
|
+
run_id: runId,
|
|
443
|
+
status: current.status || 'planned',
|
|
444
|
+
compiled_graph: compiledGraph,
|
|
445
|
+
graph_version: compiledGraph.metadata && compiledGraph.metadata.plan_hash ? compiledGraph.metadata.plan_hash : 'compiled',
|
|
446
|
+
canonical_state: serializeCanonicalState(
|
|
447
|
+
mergeCanonicalStateWithRunState(
|
|
448
|
+
reduceCanonicalRunState(projectRoot, activeSession, { runState: { ...current, run_id: runId } }),
|
|
449
|
+
{ ...current, run_id: runId },
|
|
450
|
+
activeSession,
|
|
451
|
+
compiledGraph
|
|
452
|
+
)
|
|
453
|
+
),
|
|
454
|
+
projections: current.projections || {},
|
|
455
|
+
});
|
|
456
|
+
appendEvent(projectRoot, activeSession, {
|
|
457
|
+
type: 'GraphCompiled',
|
|
458
|
+
run_id: next.run_id,
|
|
459
|
+
payload: {
|
|
460
|
+
node_count: compiledGraph.metadata && compiledGraph.metadata.node_count || 0,
|
|
461
|
+
wave_count: compiledGraph.metadata && compiledGraph.metadata.wave_count || 0,
|
|
462
|
+
plan_hash: compiledGraph.metadata && compiledGraph.metadata.plan_hash || null,
|
|
463
|
+
spec_hash: compiledGraph.metadata && compiledGraph.metadata.spec_hash || null,
|
|
464
|
+
},
|
|
465
|
+
});
|
|
466
|
+
return {
|
|
467
|
+
run: next,
|
|
468
|
+
graph: compiledGraph,
|
|
469
|
+
validationErrors,
|
|
470
|
+
parsedPlan,
|
|
471
|
+
parsedSpec,
|
|
472
|
+
paths: artifactPaths,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function compileVerificationSuiteFromArtifacts(projectRoot, activeSession, options = {}) {
|
|
477
|
+
const runtime = loadRuntimeModule();
|
|
478
|
+
const parsers = loadSdkParsers();
|
|
479
|
+
if (!runtime || typeof runtime.compileVerification !== 'function') {
|
|
480
|
+
throw new Error('Runtime package não está disponível. Rode npm run build:runtime.');
|
|
481
|
+
}
|
|
482
|
+
if (!parsers) {
|
|
483
|
+
throw new Error('Parsers do SDK indisponíveis para compilar verification suite.');
|
|
484
|
+
}
|
|
485
|
+
const artifactPaths = resolveRuntimeArtifactPaths(projectRoot, activeSession);
|
|
486
|
+
const specText = readTextIfExists(artifactPaths.spec);
|
|
487
|
+
const planText = readTextIfExists(artifactPaths.plan);
|
|
488
|
+
if (!specText || !planText) {
|
|
489
|
+
throw new Error('SPEC.md e PLAN.md são obrigatórios para compilar a suite de verificação.');
|
|
490
|
+
}
|
|
491
|
+
const suite = runtime.compileVerification(parsers.parseSpec(specText), parsers.parsePlan(planText), options.compilerOptions || {});
|
|
492
|
+
const current = options.runState || readRunState(projectRoot, activeSession) || {};
|
|
493
|
+
const runId = current.run_id || makeRunId();
|
|
494
|
+
const next = writeRunState(projectRoot, activeSession, {
|
|
495
|
+
...current,
|
|
496
|
+
run_id: runId,
|
|
497
|
+
status: current.status || 'planned',
|
|
498
|
+
verification_suite: suite,
|
|
499
|
+
});
|
|
500
|
+
appendEvent(projectRoot, activeSession, {
|
|
501
|
+
type: 'verification_suite_compiled',
|
|
502
|
+
run_id: next.run_id,
|
|
503
|
+
payload: {
|
|
504
|
+
total_checks: Array.isArray(suite.checks) ? suite.checks.length : 0,
|
|
505
|
+
spec_hash: suite.spec_hash || null,
|
|
506
|
+
plan_hash: suite.plan_hash || null,
|
|
507
|
+
},
|
|
508
|
+
});
|
|
509
|
+
return { run: next, suite, paths: artifactPaths };
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function projectRuntimeArtifacts(projectRoot, activeSession, options = {}) {
|
|
513
|
+
const runtime = loadRuntimeModule();
|
|
514
|
+
if (!runtime || typeof runtime.ProjectionEngine !== 'function' || typeof runtime.fromSerializable !== 'function') {
|
|
515
|
+
throw new Error('Runtime package não está disponível. Rode npm run build:runtime.');
|
|
516
|
+
}
|
|
517
|
+
let current = options.runState || readRunState(projectRoot, activeSession);
|
|
518
|
+
if (!current) {
|
|
519
|
+
current = writeRunState(projectRoot, activeSession, {});
|
|
520
|
+
}
|
|
521
|
+
if (!current.compiled_graph) {
|
|
522
|
+
current = compileExecutionGraphFromArtifacts(projectRoot, activeSession, { runState: current }).run;
|
|
523
|
+
}
|
|
524
|
+
const graph = runtime.fromSerializable(current.compiled_graph);
|
|
525
|
+
const canonicalLive = current.canonical_state
|
|
526
|
+
? mergeCanonicalStateWithRunState(current.canonical_state, current, activeSession, current.compiled_graph)
|
|
527
|
+
: reduceCanonicalRunStateLive(projectRoot, activeSession, { runState: current });
|
|
528
|
+
if (!canonicalLive) {
|
|
529
|
+
throw new Error('Não foi possível reconstruir o estado canônico da run.');
|
|
530
|
+
}
|
|
531
|
+
const canonicalState = serializeCanonicalState(canonicalLive);
|
|
532
|
+
const projector = new runtime.ProjectionEngine();
|
|
533
|
+
const verificationResults = Array.isArray(current.verification_results) ? current.verification_results : [];
|
|
534
|
+
const verificationCheckResults = Array.isArray(current.verification_check_results) ? current.verification_check_results : [];
|
|
535
|
+
const projections = {
|
|
536
|
+
plan: projector.projectPlan(canonicalLive, graph),
|
|
537
|
+
verify: projector.projectVerify(canonicalLive, verificationResults, verificationCheckResults),
|
|
538
|
+
state: projector.projectState(canonicalLive),
|
|
539
|
+
runSummary: projector.projectRunSummary(canonicalLive),
|
|
540
|
+
prSummary: projector.projectPRSummary(canonicalLive, graph),
|
|
541
|
+
};
|
|
542
|
+
const paths = resolveRuntimeArtifactPaths(projectRoot, activeSession);
|
|
543
|
+
const op = operationalPaths(projectRoot, activeSession);
|
|
544
|
+
const projectionRefs = {
|
|
545
|
+
plan_ref: path.relative(projectRoot, paths.plan).replace(/\\/g, '/'),
|
|
546
|
+
verify_ref: path.relative(projectRoot, paths.verify).replace(/\\/g, '/'),
|
|
547
|
+
state_ref: path.relative(projectRoot, paths.state).replace(/\\/g, '/'),
|
|
548
|
+
run_summary_ref: path.relative(projectRoot, path.join(op.executionRoot, 'RUN-SUMMARY.md')).replace(/\\/g, '/'),
|
|
549
|
+
pr_summary_ref: path.relative(projectRoot, path.join(op.executionRoot, 'PR-SUMMARY.md')).replace(/\\/g, '/'),
|
|
550
|
+
generated_at: new Date().toISOString(),
|
|
551
|
+
};
|
|
552
|
+
if (options.write !== false) {
|
|
553
|
+
ensureDirForFile(paths.plan);
|
|
554
|
+
ensureDirForFile(paths.verify);
|
|
555
|
+
ensureDirForFile(paths.state);
|
|
556
|
+
fs.writeFileSync(paths.plan, projections.plan + '\n', 'utf8');
|
|
557
|
+
fs.writeFileSync(paths.verify, projections.verify + '\n', 'utf8');
|
|
558
|
+
fs.writeFileSync(paths.state, projections.state + '\n', 'utf8');
|
|
559
|
+
fs.writeFileSync(path.join(op.executionRoot, 'RUN-SUMMARY.md'), projections.runSummary + '\n', 'utf8');
|
|
560
|
+
fs.writeFileSync(path.join(op.executionRoot, 'PR-SUMMARY.md'), projections.prSummary + '\n', 'utf8');
|
|
561
|
+
}
|
|
562
|
+
const next = writeRunState(projectRoot, activeSession, {
|
|
563
|
+
...current,
|
|
564
|
+
canonical_state: canonicalState,
|
|
565
|
+
projections: projectionRefs,
|
|
566
|
+
});
|
|
567
|
+
return { run: next, projections, paths: { ...paths, runSummary: path.join(op.executionRoot, 'RUN-SUMMARY.md'), prSummary: path.join(op.executionRoot, 'PR-SUMMARY.md') } };
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
async function runRuntimeCiChecks(projectRoot, activeSession, options = {}) {
|
|
571
|
+
const runtime = loadRuntimeModule();
|
|
572
|
+
if (!runtime || typeof runtime.runCIChecks !== 'function' || typeof runtime.summarizeCIResults !== 'function') {
|
|
573
|
+
throw new Error('Runtime package não está disponível. Rode npm run build:runtime.');
|
|
574
|
+
}
|
|
575
|
+
let current = options.runState || readRunState(projectRoot, activeSession);
|
|
576
|
+
if (!current) {
|
|
577
|
+
current = compileExecutionGraphFromArtifacts(projectRoot, activeSession).run;
|
|
578
|
+
}
|
|
579
|
+
const runId = options.runId || (current && current.run_id) || null;
|
|
580
|
+
const results = await runtime.runCIChecks({
|
|
581
|
+
projectRoot,
|
|
582
|
+
sessionId: activeSession || null,
|
|
583
|
+
runId,
|
|
584
|
+
});
|
|
585
|
+
const summary = runtime.summarizeCIResults(results);
|
|
586
|
+
const next = writeRunState(projectRoot, activeSession, {
|
|
587
|
+
...(current || {}),
|
|
588
|
+
run_id: runId || makeRunId(),
|
|
589
|
+
status: current && current.status ? current.status : 'planned',
|
|
590
|
+
ci_checks: {
|
|
591
|
+
generated_at: new Date().toISOString(),
|
|
592
|
+
summary,
|
|
593
|
+
results,
|
|
594
|
+
},
|
|
595
|
+
});
|
|
596
|
+
appendEvent(projectRoot, activeSession, {
|
|
597
|
+
type: 'runtime_ci_completed',
|
|
598
|
+
run_id: next.run_id,
|
|
599
|
+
payload: {
|
|
600
|
+
total: summary.total,
|
|
601
|
+
pass: summary.pass,
|
|
602
|
+
fail: summary.fail,
|
|
603
|
+
skip: summary.skip,
|
|
604
|
+
error: summary.error,
|
|
605
|
+
allPassed: summary.allPassed,
|
|
606
|
+
},
|
|
607
|
+
});
|
|
608
|
+
return { run: next, runId: next.run_id, results, summary };
|
|
609
|
+
}
|
|
610
|
+
|
|
73
611
|
function operationalPaths(projectRoot, activeSession) {
|
|
74
612
|
const oxeDir = path.join(projectRoot, '.oxe');
|
|
75
613
|
const scopeRoot = activeSession ? path.join(oxeDir, ...String(activeSession).split('/')) : oxeDir;
|
|
@@ -284,10 +822,14 @@ function appendEvent(projectRoot, activeSession, event = {}) {
|
|
|
284
822
|
type: String(event.type || 'custom'),
|
|
285
823
|
timestamp: event.timestamp || new Date().toISOString(),
|
|
286
824
|
run_id: event.run_id || null,
|
|
287
|
-
session_id: activeSession || null,
|
|
825
|
+
session_id: activeSession || event.session_id || null,
|
|
288
826
|
wave_id: event.wave_id || null,
|
|
289
|
-
task_id: event.task_id || null,
|
|
827
|
+
task_id: event.task_id || event.work_item_id || null,
|
|
828
|
+
work_item_id: event.work_item_id || event.task_id || null,
|
|
829
|
+
attempt_id: event.attempt_id || null,
|
|
290
830
|
agent_id: event.agent_id || null,
|
|
831
|
+
causation_id: event.causation_id || null,
|
|
832
|
+
correlation_id: event.correlation_id || null,
|
|
291
833
|
payload: event.payload && typeof event.payload === 'object' ? event.payload : {},
|
|
292
834
|
};
|
|
293
835
|
fs.appendFileSync(p.events, `${JSON.stringify(entry)}\n`, 'utf8');
|
|
@@ -327,6 +869,7 @@ function summarizeEvents(events) {
|
|
|
327
869
|
function writeRunState(projectRoot, activeSession, runState = {}) {
|
|
328
870
|
const p = operationalPaths(projectRoot, activeSession);
|
|
329
871
|
const runId = String(runState.run_id || makeRunId());
|
|
872
|
+
const canonicalState = runState.canonical_state ? serializeCanonicalState(hydrateCanonicalState(runState.canonical_state)) : null;
|
|
330
873
|
const payload = {
|
|
331
874
|
run_id: runId,
|
|
332
875
|
status: VALID_RUN_STATUSES.has(String(runState.status || 'planned')) ? String(runState.status || 'planned') : 'planned',
|
|
@@ -354,6 +897,18 @@ function writeRunState(projectRoot, activeSession, runState = {}) {
|
|
|
354
897
|
edges: Array.isArray(runState.graph.edges) ? runState.graph.edges : [],
|
|
355
898
|
}
|
|
356
899
|
: { nodes: [], edges: [] },
|
|
900
|
+
compiled_graph: runState.compiled_graph && typeof runState.compiled_graph === 'object'
|
|
901
|
+
? runState.compiled_graph
|
|
902
|
+
: null,
|
|
903
|
+
graph_version: runState.graph_version || null,
|
|
904
|
+
canonical_state: canonicalState,
|
|
905
|
+
verification_suite: runState.verification_suite && typeof runState.verification_suite === 'object'
|
|
906
|
+
? runState.verification_suite
|
|
907
|
+
: null,
|
|
908
|
+
verification_results: Array.isArray(runState.verification_results) ? runState.verification_results : [],
|
|
909
|
+
verification_check_results: Array.isArray(runState.verification_check_results) ? runState.verification_check_results : [],
|
|
910
|
+
ci_checks: runState.ci_checks && typeof runState.ci_checks === 'object' ? runState.ci_checks : null,
|
|
911
|
+
projections: runState.projections && typeof runState.projections === 'object' ? runState.projections : {},
|
|
357
912
|
metrics: runState.metrics && typeof runState.metrics === 'object' ? runState.metrics : {},
|
|
358
913
|
};
|
|
359
914
|
payload.graph = buildOperationalGraph(payload);
|
|
@@ -369,6 +924,9 @@ function writeRunState(projectRoot, activeSession, runState = {}) {
|
|
|
369
924
|
current_wave: payload.current_wave,
|
|
370
925
|
cursor: payload.cursor,
|
|
371
926
|
provider_context: payload.provider_context,
|
|
927
|
+
canonical_state: payload.canonical_state,
|
|
928
|
+
compiled_graph: payload.compiled_graph,
|
|
929
|
+
graph_version: payload.graph_version,
|
|
372
930
|
},
|
|
373
931
|
null,
|
|
374
932
|
2
|
|
@@ -699,7 +1257,7 @@ function replayEvents(projectRoot, activeSession, options = {}) {
|
|
|
699
1257
|
.filter((n) => n != null)
|
|
700
1258
|
)].sort((a, b) => a - b);
|
|
701
1259
|
|
|
702
|
-
const taskSequence = [...new Set(events.filter((e) => e.task_id).map((e) => e.task_id))];
|
|
1260
|
+
const taskSequence = [...new Set(events.filter((e) => e.task_id || e.work_item_id).map((e) => e.task_id || e.work_item_id))];
|
|
703
1261
|
const checkpointSequence = events
|
|
704
1262
|
.filter((e) => String(e.type).includes('checkpoint'))
|
|
705
1263
|
.map((e) => e.event_id);
|
|
@@ -741,7 +1299,7 @@ function replayEvents(projectRoot, activeSession, options = {}) {
|
|
|
741
1299
|
for (let i = 0; i < events.length; i++) {
|
|
742
1300
|
const e = events[i];
|
|
743
1301
|
const delta = i > 0 ? `+${(e._delta_ms / 1000).toFixed(1)}s` : '—';
|
|
744
|
-
lines.push(`| ${i + 1} | ${e.type} | ${e.wave_id || '—'} | ${e.task_id || '—'} | ${delta} | ${e.timestamp} |`);
|
|
1302
|
+
lines.push(`| ${i + 1} | ${e.type} | ${e.wave_id || '—'} | ${e.task_id || e.work_item_id || '—'} | ${delta} | ${e.timestamp} |`);
|
|
745
1303
|
}
|
|
746
1304
|
ensureDirForFile(reportPath);
|
|
747
1305
|
fs.writeFileSync(reportPath, lines.join('\n') + '\n', 'utf8');
|
|
@@ -770,6 +1328,13 @@ module.exports = {
|
|
|
770
1328
|
capabilityCatalogWarnings,
|
|
771
1329
|
buildMemoryLayers,
|
|
772
1330
|
buildOperationalGraph,
|
|
1331
|
+
serializeCanonicalState,
|
|
1332
|
+
hydrateCanonicalState,
|
|
1333
|
+
reduceCanonicalRunState,
|
|
1334
|
+
compileExecutionGraphFromArtifacts,
|
|
1335
|
+
compileVerificationSuiteFromArtifacts,
|
|
1336
|
+
projectRuntimeArtifacts,
|
|
1337
|
+
runRuntimeCiChecks,
|
|
773
1338
|
applyRuntimeAction,
|
|
774
1339
|
replayEvents,
|
|
775
1340
|
};
|