@riddledc/riddle-proof 0.5.2 → 0.5.3
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/dist/{chunk-5GZZZ6JA.js → chunk-MLJJIKTP.js} +51 -2
- package/dist/engine-harness.cjs +179 -27
- package/dist/engine-harness.js +1 -1
- package/dist/index.cjs +179 -27
- package/dist/index.js +1 -1
- package/dist/proof-run-engine.cjs +127 -24
- package/dist/proof-run-engine.d.cts +3 -3
- package/dist/proof-run-engine.d.ts +3 -3
- package/dist/proof-run-engine.js +127 -24
- package/package.json +1 -1
- package/runtime/lib/preflight.py +13 -0
package/dist/index.cjs
CHANGED
|
@@ -947,6 +947,87 @@ function updateState(statePath, mutate) {
|
|
|
947
947
|
writeState(statePath, state);
|
|
948
948
|
return state;
|
|
949
949
|
}
|
|
950
|
+
function nowIso() {
|
|
951
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
952
|
+
}
|
|
953
|
+
function appendRuntimeEventToState(state, event) {
|
|
954
|
+
const events = Array.isArray(state.runtime_events) ? state.runtime_events : [];
|
|
955
|
+
state.runtime_events = [...events, event].slice(-RUNTIME_EVENT_LIMIT);
|
|
956
|
+
state.runtime_updated_at = event.ts;
|
|
957
|
+
}
|
|
958
|
+
function beginRuntimeStep(statePath, action, step, workflowPath) {
|
|
959
|
+
const timer = {
|
|
960
|
+
startedAt: nowIso(),
|
|
961
|
+
startedMs: Date.now()
|
|
962
|
+
};
|
|
963
|
+
updateState(statePath, (state) => {
|
|
964
|
+
const current = {
|
|
965
|
+
step,
|
|
966
|
+
action,
|
|
967
|
+
status: "running",
|
|
968
|
+
started_at: timer.startedAt,
|
|
969
|
+
workflow_file: import_node_path2.default.basename(workflowPath)
|
|
970
|
+
};
|
|
971
|
+
state.current_runtime_step = current;
|
|
972
|
+
appendRuntimeEventToState(state, {
|
|
973
|
+
ts: timer.startedAt,
|
|
974
|
+
kind: "workflow.step.started",
|
|
975
|
+
step,
|
|
976
|
+
action,
|
|
977
|
+
summary: `Started ${step} workflow step.`,
|
|
978
|
+
details: {
|
|
979
|
+
workflow_file: import_node_path2.default.basename(workflowPath)
|
|
980
|
+
}
|
|
981
|
+
});
|
|
982
|
+
});
|
|
983
|
+
return timer;
|
|
984
|
+
}
|
|
985
|
+
function finishRuntimeStep(statePath, action, result, timer) {
|
|
986
|
+
const finishedAt = nowIso();
|
|
987
|
+
const durationMs = Date.now() - timer.startedMs;
|
|
988
|
+
const summary = result.haltedForApproval ? `${result.step} halted for approval.` : result.ok ? `Finished ${result.step} workflow step.` : `${result.step} workflow step failed.`;
|
|
989
|
+
updateState(statePath, (state) => {
|
|
990
|
+
const completed = {
|
|
991
|
+
step: result.step,
|
|
992
|
+
action,
|
|
993
|
+
status: result.haltedForApproval ? "approval_required" : result.ok ? "completed" : "failed",
|
|
994
|
+
started_at: timer.startedAt,
|
|
995
|
+
finished_at: finishedAt,
|
|
996
|
+
duration_ms: durationMs,
|
|
997
|
+
ok: result.ok,
|
|
998
|
+
halted_for_approval: result.haltedForApproval || false,
|
|
999
|
+
auto_approved: result.autoApproved || false,
|
|
1000
|
+
error: result.error || null
|
|
1001
|
+
};
|
|
1002
|
+
state.current_runtime_step = null;
|
|
1003
|
+
state.last_runtime_step = completed;
|
|
1004
|
+
appendRuntimeEventToState(state, {
|
|
1005
|
+
ts: finishedAt,
|
|
1006
|
+
kind: "workflow.step.finished",
|
|
1007
|
+
step: result.step,
|
|
1008
|
+
action,
|
|
1009
|
+
summary,
|
|
1010
|
+
details: completed
|
|
1011
|
+
});
|
|
1012
|
+
});
|
|
1013
|
+
return {
|
|
1014
|
+
...result,
|
|
1015
|
+
started_at: timer.startedAt,
|
|
1016
|
+
finished_at: finishedAt,
|
|
1017
|
+
duration_ms: durationMs
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
function executedStep(res, extra = {}) {
|
|
1021
|
+
const output = {
|
|
1022
|
+
step: res.step,
|
|
1023
|
+
ok: res.ok,
|
|
1024
|
+
haltedForApproval: res.haltedForApproval || false,
|
|
1025
|
+
autoApproved: res.autoApproved || false,
|
|
1026
|
+
...extra
|
|
1027
|
+
};
|
|
1028
|
+
if (typeof res.duration_ms === "number") output.duration_ms = res.duration_ms;
|
|
1029
|
+
return output;
|
|
1030
|
+
}
|
|
950
1031
|
function hasSupervisorProofAssessment(state) {
|
|
951
1032
|
const proofAssessment = state?.proof_assessment || {};
|
|
952
1033
|
const source = String(proofAssessment?.source || state?.proof_assessment_source || "").trim().toLowerCase();
|
|
@@ -1409,53 +1490,74 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1409
1490
|
const lobsterPrefix = process.env.RIDDLE_PROOF_LOBSTER_SCRIPT ? [process.env.RIDDLE_PROOF_LOBSTER_SCRIPT] : [];
|
|
1410
1491
|
const runOne = (step) => {
|
|
1411
1492
|
const args = step === "setup" ? buildSetupArgs(params, config) : {};
|
|
1493
|
+
const stepWorkflowFile = workflowFile(config.riddleProofDir, step);
|
|
1494
|
+
const timer = beginRuntimeStep(config.statePath, action, step, stepWorkflowFile);
|
|
1412
1495
|
let output;
|
|
1413
1496
|
try {
|
|
1414
1497
|
output = JSON.parse(
|
|
1415
|
-
(0, import_node_child_process.execFileSync)(lobsterCommand, [...lobsterPrefix, "run", "--file",
|
|
1498
|
+
(0, import_node_child_process.execFileSync)(lobsterCommand, [...lobsterPrefix, "run", "--file", stepWorkflowFile, "--args-json", JSON.stringify(args)], {
|
|
1416
1499
|
encoding: "utf-8",
|
|
1417
1500
|
env
|
|
1418
1501
|
})
|
|
1419
1502
|
);
|
|
1420
1503
|
} catch (error) {
|
|
1421
|
-
return {
|
|
1504
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1422
1505
|
ok: false,
|
|
1423
1506
|
step,
|
|
1424
1507
|
error: error?.message || String(error),
|
|
1425
1508
|
stdout: String(error?.stdout || ""),
|
|
1426
1509
|
stderr: String(error?.stderr || "")
|
|
1427
|
-
};
|
|
1510
|
+
}, timer);
|
|
1428
1511
|
}
|
|
1429
1512
|
if (output?.status === "needs_approval") {
|
|
1430
1513
|
if (!params.auto_approve) {
|
|
1431
|
-
return {
|
|
1514
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1432
1515
|
ok: false,
|
|
1433
1516
|
haltedForApproval: true,
|
|
1434
1517
|
step,
|
|
1435
1518
|
approval: output.requiresApproval || null,
|
|
1436
1519
|
raw: output
|
|
1437
|
-
};
|
|
1520
|
+
}, timer);
|
|
1438
1521
|
}
|
|
1439
1522
|
const token = output?.requiresApproval?.resumeToken;
|
|
1440
|
-
if (!token)
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1523
|
+
if (!token) {
|
|
1524
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1525
|
+
ok: false,
|
|
1526
|
+
step,
|
|
1527
|
+
error: `${step} requested approval without a resume token.`,
|
|
1528
|
+
raw: output
|
|
1529
|
+
}, timer);
|
|
1530
|
+
}
|
|
1531
|
+
let resumed;
|
|
1532
|
+
try {
|
|
1533
|
+
resumed = JSON.parse(
|
|
1534
|
+
(0, import_node_child_process.execFileSync)(lobsterCommand, [...lobsterPrefix, "resume", "--token", token, "--approve", "yes"], {
|
|
1535
|
+
encoding: "utf-8",
|
|
1536
|
+
env
|
|
1537
|
+
})
|
|
1538
|
+
);
|
|
1539
|
+
} catch (error) {
|
|
1540
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1541
|
+
ok: false,
|
|
1542
|
+
step,
|
|
1543
|
+
autoApproved: true,
|
|
1544
|
+
error: error?.message || String(error),
|
|
1545
|
+
stdout: String(error?.stdout || ""),
|
|
1546
|
+
stderr: String(error?.stderr || "")
|
|
1547
|
+
}, timer);
|
|
1548
|
+
}
|
|
1549
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1448
1550
|
ok: resumed?.ok !== false,
|
|
1449
1551
|
step,
|
|
1450
1552
|
autoApproved: true,
|
|
1451
1553
|
raw: resumed
|
|
1452
|
-
};
|
|
1554
|
+
}, timer);
|
|
1453
1555
|
}
|
|
1454
|
-
return {
|
|
1556
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1455
1557
|
ok: output?.ok !== false,
|
|
1456
1558
|
step,
|
|
1457
1559
|
raw: output
|
|
1458
|
-
};
|
|
1560
|
+
}, timer);
|
|
1459
1561
|
};
|
|
1460
1562
|
let effectiveAdvanceStage = params.advance_stage || null;
|
|
1461
1563
|
const recordAttempt = (stage, status, summary, extra = {}) => {
|
|
@@ -1581,7 +1683,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1581
1683
|
let state = readState(config.statePath);
|
|
1582
1684
|
if (!state || !state.workspace_ready || params.advance_stage === "setup") {
|
|
1583
1685
|
const setupRes = runOne("setup");
|
|
1584
|
-
executed.push(
|
|
1686
|
+
executed.push(executedStep(setupRes));
|
|
1585
1687
|
if (!setupRes.ok || setupRes.haltedForApproval) {
|
|
1586
1688
|
return failedRun("setup", setupRes.haltedForApproval ? "setup halted for approval" : "setup failed", setupRes, {
|
|
1587
1689
|
checkpoint: "setup_blocked"
|
|
@@ -1791,7 +1893,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1791
1893
|
}
|
|
1792
1894
|
if (!state?.recon_results || state?.stage === "setup" || state?.stage === "preflight" || ["needs_agent_decision", "needs_supervisor_judgment"].includes(state?.recon_status || "") || requestedStage === "recon") {
|
|
1793
1895
|
const reconRes = runOne("recon");
|
|
1794
|
-
executed.push(
|
|
1896
|
+
executed.push(executedStep(reconRes));
|
|
1795
1897
|
if (!reconRes.ok || reconRes.haltedForApproval) {
|
|
1796
1898
|
return failedRun("recon", reconRes.haltedForApproval ? "recon halted for approval" : "recon failed", reconRes, {
|
|
1797
1899
|
checkpoint: "recon_failed",
|
|
@@ -1839,7 +1941,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1839
1941
|
state = readState(config.statePath);
|
|
1840
1942
|
if (!authorReady(state) || effectiveAdvanceStage === "author") {
|
|
1841
1943
|
const authorRes = runOne("author");
|
|
1842
|
-
executed.push(
|
|
1944
|
+
executed.push(executedStep(authorRes));
|
|
1843
1945
|
if (!authorRes.ok || authorRes.haltedForApproval) {
|
|
1844
1946
|
return failedRun("author", authorRes.haltedForApproval ? "author halted for approval" : "author failed", authorRes, {
|
|
1845
1947
|
checkpoint: "author_failed",
|
|
@@ -1954,7 +2056,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1954
2056
|
}
|
|
1955
2057
|
if (effectiveAdvanceStage === "implement") {
|
|
1956
2058
|
const implementRes = runOne("implement");
|
|
1957
|
-
executed.push(
|
|
2059
|
+
executed.push(executedStep(implementRes));
|
|
1958
2060
|
if (implementRes.haltedForApproval) {
|
|
1959
2061
|
return failedRun("implement", "implement halted for approval", implementRes, {
|
|
1960
2062
|
checkpoint: "implement_blocked",
|
|
@@ -2044,7 +2146,7 @@ ${implementRes.stderr || ""}`;
|
|
|
2044
2146
|
let verifyRes = { ok: true, step: "verify", reusedEvidence: canReuseVerifyEvidence };
|
|
2045
2147
|
if (!canReuseVerifyEvidence) {
|
|
2046
2148
|
verifyRes = runOne("verify");
|
|
2047
|
-
executed.push(
|
|
2149
|
+
executed.push(executedStep(verifyRes));
|
|
2048
2150
|
if (!verifyRes.ok || verifyRes.haltedForApproval) {
|
|
2049
2151
|
return failedRun("verify", verifyRes.haltedForApproval ? "verify halted for approval" : "verify failed", verifyRes, {
|
|
2050
2152
|
checkpoint: "verify_failed",
|
|
@@ -2053,7 +2155,7 @@ ${implementRes.stderr || ""}`;
|
|
|
2053
2155
|
});
|
|
2054
2156
|
}
|
|
2055
2157
|
} else {
|
|
2056
|
-
executed.push(
|
|
2158
|
+
executed.push(executedStep(verifyRes, { reusedEvidence: true }));
|
|
2057
2159
|
}
|
|
2058
2160
|
state = readState(config.statePath);
|
|
2059
2161
|
const verifyStatus = state?.verify_status || ((state?.after_cdn || "").trim() ? "evidence_captured" : "capture_incomplete");
|
|
@@ -2190,7 +2292,7 @@ ${implementRes.stderr || ""}`;
|
|
|
2190
2292
|
details: { ...verifyDetails, shipGate }
|
|
2191
2293
|
});
|
|
2192
2294
|
const shipRes = runOne("ship");
|
|
2193
|
-
executed.push(
|
|
2295
|
+
executed.push(executedStep(shipRes));
|
|
2194
2296
|
if (!shipRes.ok || shipRes.haltedForApproval) {
|
|
2195
2297
|
const shipNextAction = shipRes?.error && String(shipRes.error).includes("temporary proof branch") ? "product bug: ship resolved a temporary proof branch; resolve the PR head branch before retrying ship" : "inspect the ship error, confirm the PR head branch and verified commit, then retry ship";
|
|
2196
2298
|
return failedRun("ship", shipRes.haltedForApproval ? "ship halted for approval" : "ship failed", shipRes, {
|
|
@@ -2369,7 +2471,7 @@ ${implementRes.stderr || ""}`;
|
|
|
2369
2471
|
return shipGateBlocked(state, executed, { shipAssessment: shipAssessment.raw });
|
|
2370
2472
|
}
|
|
2371
2473
|
const shipRes = runOne("ship");
|
|
2372
|
-
executed.push(
|
|
2474
|
+
executed.push(executedStep(shipRes));
|
|
2373
2475
|
if (!shipRes.ok || shipRes.haltedForApproval) {
|
|
2374
2476
|
return failedRun("ship", shipRes.haltedForApproval ? "ship halted for approval" : "ship failed", shipRes, {
|
|
2375
2477
|
checkpoint: "ship_failed",
|
|
@@ -2495,7 +2597,7 @@ function createRiddleProofEngine(pluginConfig = {}) {
|
|
|
2495
2597
|
}
|
|
2496
2598
|
};
|
|
2497
2599
|
}
|
|
2498
|
-
var import_node_child_process, import_node_fs2, import_node_path2;
|
|
2600
|
+
var import_node_child_process, import_node_fs2, import_node_path2, RUNTIME_EVENT_LIMIT;
|
|
2499
2601
|
var init_proof_run_engine = __esm({
|
|
2500
2602
|
"src/proof-run-engine.ts"() {
|
|
2501
2603
|
"use strict";
|
|
@@ -2503,6 +2605,7 @@ var init_proof_run_engine = __esm({
|
|
|
2503
2605
|
import_node_fs2 = require("fs");
|
|
2504
2606
|
import_node_path2 = __toESM(require("path"), 1);
|
|
2505
2607
|
init_proof_run_core();
|
|
2608
|
+
RUNTIME_EVENT_LIMIT = 100;
|
|
2506
2609
|
}
|
|
2507
2610
|
});
|
|
2508
2611
|
|
|
@@ -3460,6 +3563,22 @@ function createHarnessStatePath(stateDir) {
|
|
|
3460
3563
|
const stamp = timestamp2().replace(/\D/g, "").slice(0, 14) || "unknown";
|
|
3461
3564
|
return import_node_path3.default.join(stateDir, `riddle-proof-run-${stamp}-${import_node_crypto2.default.randomUUID().slice(0, 8)}.json`);
|
|
3462
3565
|
}
|
|
3566
|
+
function createEngineStatePath(state, config) {
|
|
3567
|
+
const existing = nonEmptyString(state.request.engine_state_path);
|
|
3568
|
+
if (existing) return existing;
|
|
3569
|
+
const harnessStatePath = nonEmptyString(state.state_path);
|
|
3570
|
+
if (harnessStatePath) {
|
|
3571
|
+
const dir = import_node_path3.default.dirname(harnessStatePath);
|
|
3572
|
+
const base = import_node_path3.default.basename(harnessStatePath);
|
|
3573
|
+
if (base.startsWith("riddle-proof-run-")) {
|
|
3574
|
+
return import_node_path3.default.join(dir, base.replace("riddle-proof-run-", "riddle-proof-state-"));
|
|
3575
|
+
}
|
|
3576
|
+
return import_node_path3.default.join(dir, `${base}.engine-state.json`);
|
|
3577
|
+
}
|
|
3578
|
+
const stateDir = config?.stateDir || "/tmp";
|
|
3579
|
+
const stamp = timestamp2().replace(/\D/g, "").slice(0, 14) || "unknown";
|
|
3580
|
+
return import_node_path3.default.join(stateDir, `riddle-proof-state-${stamp}-${import_node_crypto2.default.randomUUID().slice(0, 8)}.json`);
|
|
3581
|
+
}
|
|
3463
3582
|
function ensureParent(filePath) {
|
|
3464
3583
|
(0, import_node_fs3.mkdirSync)(import_node_path3.default.dirname(filePath), { recursive: true });
|
|
3465
3584
|
}
|
|
@@ -3502,6 +3621,18 @@ function heartbeat(state, input) {
|
|
|
3502
3621
|
function jsonParam(payload) {
|
|
3503
3622
|
return JSON.stringify(payload);
|
|
3504
3623
|
}
|
|
3624
|
+
function redactedWorkflowParams(params) {
|
|
3625
|
+
const secretKeys = /* @__PURE__ */ new Set([
|
|
3626
|
+
"auth_localStorage_json",
|
|
3627
|
+
"auth_cookies_json",
|
|
3628
|
+
"auth_headers_json"
|
|
3629
|
+
]);
|
|
3630
|
+
const output = {};
|
|
3631
|
+
for (const [key, value] of Object.entries(params)) {
|
|
3632
|
+
output[key] = secretKeys.has(key) && value ? "[redacted]" : value;
|
|
3633
|
+
}
|
|
3634
|
+
return output;
|
|
3635
|
+
}
|
|
3505
3636
|
function engineStatePath(result, state) {
|
|
3506
3637
|
return nonEmptyString(result.state_path) || nonEmptyString(state.request.engine_state_path);
|
|
3507
3638
|
}
|
|
@@ -4008,6 +4139,7 @@ function readRiddleProofRunStatus(state_path) {
|
|
|
4008
4139
|
async function runRiddleProofEngineHarness(input) {
|
|
4009
4140
|
const state = loadRunState(input);
|
|
4010
4141
|
state.request = normalizeRunParams({ ...state.request, ...input.request });
|
|
4142
|
+
state.request.engine_state_path = nonEmptyString(input.resume_params?.state_path) || nonEmptyString(state.request.engine_state_path) || createEngineStatePath(state, input.config);
|
|
4011
4143
|
const request = state.request;
|
|
4012
4144
|
const agent = input.agent || createDisabledRiddleProofAgentAdapter();
|
|
4013
4145
|
const maxIterations = Math.max(
|
|
@@ -4063,24 +4195,41 @@ async function runRiddleProofEngineHarness(input) {
|
|
|
4063
4195
|
branch: state.branch || null
|
|
4064
4196
|
}
|
|
4065
4197
|
});
|
|
4198
|
+
const engineCallStartedAt = timestamp2();
|
|
4199
|
+
const engineCallStartedMs = Date.now();
|
|
4066
4200
|
recordEvent(state, {
|
|
4067
4201
|
kind: "engine.call",
|
|
4068
4202
|
checkpoint: "engine_call",
|
|
4069
4203
|
stage,
|
|
4070
4204
|
summary: "Calling Riddle Proof engine.",
|
|
4071
|
-
details: {
|
|
4205
|
+
details: {
|
|
4206
|
+
params: redactedWorkflowParams(nextParams),
|
|
4207
|
+
started_at: engineCallStartedAt
|
|
4208
|
+
}
|
|
4072
4209
|
});
|
|
4073
4210
|
let result;
|
|
4074
4211
|
try {
|
|
4075
4212
|
result = await engine.execute(nextParams);
|
|
4076
4213
|
} catch (error) {
|
|
4077
4214
|
const message = error instanceof Error ? error.message : String(error);
|
|
4215
|
+
recordEvent(state, {
|
|
4216
|
+
kind: "engine.exception",
|
|
4217
|
+
checkpoint: "engine_call_failed",
|
|
4218
|
+
stage,
|
|
4219
|
+
summary: message,
|
|
4220
|
+
details: {
|
|
4221
|
+
duration_ms: Date.now() - engineCallStartedMs,
|
|
4222
|
+
started_at: engineCallStartedAt,
|
|
4223
|
+
finished_at: timestamp2()
|
|
4224
|
+
}
|
|
4225
|
+
});
|
|
4078
4226
|
return blockerResult(state, lastResult, {
|
|
4079
4227
|
code: "riddle_engine_exception",
|
|
4080
4228
|
checkpoint: "engine_call_failed",
|
|
4081
4229
|
message
|
|
4082
4230
|
});
|
|
4083
4231
|
}
|
|
4232
|
+
const engineCallDurationMs = Date.now() - engineCallStartedMs;
|
|
4084
4233
|
lastResult = result;
|
|
4085
4234
|
const engineState = engineStatePath(result, state);
|
|
4086
4235
|
if (engineState) state.request.engine_state_path = engineState;
|
|
@@ -4105,7 +4254,10 @@ async function runRiddleProofEngineHarness(input) {
|
|
|
4105
4254
|
details: {
|
|
4106
4255
|
ok: result.ok ?? null,
|
|
4107
4256
|
engine_state_path: engineState || null,
|
|
4108
|
-
checkpoint: result.checkpoint || null
|
|
4257
|
+
checkpoint: result.checkpoint || null,
|
|
4258
|
+
duration_ms: engineCallDurationMs,
|
|
4259
|
+
started_at: engineCallStartedAt,
|
|
4260
|
+
finished_at: timestamp2()
|
|
4109
4261
|
}
|
|
4110
4262
|
});
|
|
4111
4263
|
const routed = await routeCheckpoint(request, state, result, agent, input);
|
package/dist/index.js
CHANGED
|
@@ -944,6 +944,88 @@ function updateState(statePath, mutate) {
|
|
|
944
944
|
writeState(statePath, state);
|
|
945
945
|
return state;
|
|
946
946
|
}
|
|
947
|
+
var RUNTIME_EVENT_LIMIT = 100;
|
|
948
|
+
function nowIso() {
|
|
949
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
950
|
+
}
|
|
951
|
+
function appendRuntimeEventToState(state, event) {
|
|
952
|
+
const events = Array.isArray(state.runtime_events) ? state.runtime_events : [];
|
|
953
|
+
state.runtime_events = [...events, event].slice(-RUNTIME_EVENT_LIMIT);
|
|
954
|
+
state.runtime_updated_at = event.ts;
|
|
955
|
+
}
|
|
956
|
+
function beginRuntimeStep(statePath, action, step, workflowPath) {
|
|
957
|
+
const timer = {
|
|
958
|
+
startedAt: nowIso(),
|
|
959
|
+
startedMs: Date.now()
|
|
960
|
+
};
|
|
961
|
+
updateState(statePath, (state) => {
|
|
962
|
+
const current = {
|
|
963
|
+
step,
|
|
964
|
+
action,
|
|
965
|
+
status: "running",
|
|
966
|
+
started_at: timer.startedAt,
|
|
967
|
+
workflow_file: import_node_path2.default.basename(workflowPath)
|
|
968
|
+
};
|
|
969
|
+
state.current_runtime_step = current;
|
|
970
|
+
appendRuntimeEventToState(state, {
|
|
971
|
+
ts: timer.startedAt,
|
|
972
|
+
kind: "workflow.step.started",
|
|
973
|
+
step,
|
|
974
|
+
action,
|
|
975
|
+
summary: `Started ${step} workflow step.`,
|
|
976
|
+
details: {
|
|
977
|
+
workflow_file: import_node_path2.default.basename(workflowPath)
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
});
|
|
981
|
+
return timer;
|
|
982
|
+
}
|
|
983
|
+
function finishRuntimeStep(statePath, action, result, timer) {
|
|
984
|
+
const finishedAt = nowIso();
|
|
985
|
+
const durationMs = Date.now() - timer.startedMs;
|
|
986
|
+
const summary = result.haltedForApproval ? `${result.step} halted for approval.` : result.ok ? `Finished ${result.step} workflow step.` : `${result.step} workflow step failed.`;
|
|
987
|
+
updateState(statePath, (state) => {
|
|
988
|
+
const completed = {
|
|
989
|
+
step: result.step,
|
|
990
|
+
action,
|
|
991
|
+
status: result.haltedForApproval ? "approval_required" : result.ok ? "completed" : "failed",
|
|
992
|
+
started_at: timer.startedAt,
|
|
993
|
+
finished_at: finishedAt,
|
|
994
|
+
duration_ms: durationMs,
|
|
995
|
+
ok: result.ok,
|
|
996
|
+
halted_for_approval: result.haltedForApproval || false,
|
|
997
|
+
auto_approved: result.autoApproved || false,
|
|
998
|
+
error: result.error || null
|
|
999
|
+
};
|
|
1000
|
+
state.current_runtime_step = null;
|
|
1001
|
+
state.last_runtime_step = completed;
|
|
1002
|
+
appendRuntimeEventToState(state, {
|
|
1003
|
+
ts: finishedAt,
|
|
1004
|
+
kind: "workflow.step.finished",
|
|
1005
|
+
step: result.step,
|
|
1006
|
+
action,
|
|
1007
|
+
summary,
|
|
1008
|
+
details: completed
|
|
1009
|
+
});
|
|
1010
|
+
});
|
|
1011
|
+
return {
|
|
1012
|
+
...result,
|
|
1013
|
+
started_at: timer.startedAt,
|
|
1014
|
+
finished_at: finishedAt,
|
|
1015
|
+
duration_ms: durationMs
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
function executedStep(res, extra = {}) {
|
|
1019
|
+
const output = {
|
|
1020
|
+
step: res.step,
|
|
1021
|
+
ok: res.ok,
|
|
1022
|
+
haltedForApproval: res.haltedForApproval || false,
|
|
1023
|
+
autoApproved: res.autoApproved || false,
|
|
1024
|
+
...extra
|
|
1025
|
+
};
|
|
1026
|
+
if (typeof res.duration_ms === "number") output.duration_ms = res.duration_ms;
|
|
1027
|
+
return output;
|
|
1028
|
+
}
|
|
947
1029
|
function hasSupervisorProofAssessment(state) {
|
|
948
1030
|
const proofAssessment = state?.proof_assessment || {};
|
|
949
1031
|
const source = String(proofAssessment?.source || state?.proof_assessment_source || "").trim().toLowerCase();
|
|
@@ -1406,53 +1488,74 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1406
1488
|
const lobsterPrefix = process.env.RIDDLE_PROOF_LOBSTER_SCRIPT ? [process.env.RIDDLE_PROOF_LOBSTER_SCRIPT] : [];
|
|
1407
1489
|
const runOne = (step) => {
|
|
1408
1490
|
const args = step === "setup" ? buildSetupArgs(params, config) : {};
|
|
1491
|
+
const stepWorkflowFile = workflowFile(config.riddleProofDir, step);
|
|
1492
|
+
const timer = beginRuntimeStep(config.statePath, action, step, stepWorkflowFile);
|
|
1409
1493
|
let output;
|
|
1410
1494
|
try {
|
|
1411
1495
|
output = JSON.parse(
|
|
1412
|
-
(0, import_node_child_process.execFileSync)(lobsterCommand, [...lobsterPrefix, "run", "--file",
|
|
1496
|
+
(0, import_node_child_process.execFileSync)(lobsterCommand, [...lobsterPrefix, "run", "--file", stepWorkflowFile, "--args-json", JSON.stringify(args)], {
|
|
1413
1497
|
encoding: "utf-8",
|
|
1414
1498
|
env
|
|
1415
1499
|
})
|
|
1416
1500
|
);
|
|
1417
1501
|
} catch (error) {
|
|
1418
|
-
return {
|
|
1502
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1419
1503
|
ok: false,
|
|
1420
1504
|
step,
|
|
1421
1505
|
error: error?.message || String(error),
|
|
1422
1506
|
stdout: String(error?.stdout || ""),
|
|
1423
1507
|
stderr: String(error?.stderr || "")
|
|
1424
|
-
};
|
|
1508
|
+
}, timer);
|
|
1425
1509
|
}
|
|
1426
1510
|
if (output?.status === "needs_approval") {
|
|
1427
1511
|
if (!params.auto_approve) {
|
|
1428
|
-
return {
|
|
1512
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1429
1513
|
ok: false,
|
|
1430
1514
|
haltedForApproval: true,
|
|
1431
1515
|
step,
|
|
1432
1516
|
approval: output.requiresApproval || null,
|
|
1433
1517
|
raw: output
|
|
1434
|
-
};
|
|
1518
|
+
}, timer);
|
|
1435
1519
|
}
|
|
1436
1520
|
const token = output?.requiresApproval?.resumeToken;
|
|
1437
|
-
if (!token)
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1521
|
+
if (!token) {
|
|
1522
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1523
|
+
ok: false,
|
|
1524
|
+
step,
|
|
1525
|
+
error: `${step} requested approval without a resume token.`,
|
|
1526
|
+
raw: output
|
|
1527
|
+
}, timer);
|
|
1528
|
+
}
|
|
1529
|
+
let resumed;
|
|
1530
|
+
try {
|
|
1531
|
+
resumed = JSON.parse(
|
|
1532
|
+
(0, import_node_child_process.execFileSync)(lobsterCommand, [...lobsterPrefix, "resume", "--token", token, "--approve", "yes"], {
|
|
1533
|
+
encoding: "utf-8",
|
|
1534
|
+
env
|
|
1535
|
+
})
|
|
1536
|
+
);
|
|
1537
|
+
} catch (error) {
|
|
1538
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1539
|
+
ok: false,
|
|
1540
|
+
step,
|
|
1541
|
+
autoApproved: true,
|
|
1542
|
+
error: error?.message || String(error),
|
|
1543
|
+
stdout: String(error?.stdout || ""),
|
|
1544
|
+
stderr: String(error?.stderr || "")
|
|
1545
|
+
}, timer);
|
|
1546
|
+
}
|
|
1547
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1445
1548
|
ok: resumed?.ok !== false,
|
|
1446
1549
|
step,
|
|
1447
1550
|
autoApproved: true,
|
|
1448
1551
|
raw: resumed
|
|
1449
|
-
};
|
|
1552
|
+
}, timer);
|
|
1450
1553
|
}
|
|
1451
|
-
return {
|
|
1554
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
1452
1555
|
ok: output?.ok !== false,
|
|
1453
1556
|
step,
|
|
1454
1557
|
raw: output
|
|
1455
|
-
};
|
|
1558
|
+
}, timer);
|
|
1456
1559
|
};
|
|
1457
1560
|
let effectiveAdvanceStage = params.advance_stage || null;
|
|
1458
1561
|
const recordAttempt = (stage, status, summary, extra = {}) => {
|
|
@@ -1578,7 +1681,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1578
1681
|
let state = readState(config.statePath);
|
|
1579
1682
|
if (!state || !state.workspace_ready || params.advance_stage === "setup") {
|
|
1580
1683
|
const setupRes = runOne("setup");
|
|
1581
|
-
executed.push(
|
|
1684
|
+
executed.push(executedStep(setupRes));
|
|
1582
1685
|
if (!setupRes.ok || setupRes.haltedForApproval) {
|
|
1583
1686
|
return failedRun("setup", setupRes.haltedForApproval ? "setup halted for approval" : "setup failed", setupRes, {
|
|
1584
1687
|
checkpoint: "setup_blocked"
|
|
@@ -1788,7 +1891,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1788
1891
|
}
|
|
1789
1892
|
if (!state?.recon_results || state?.stage === "setup" || state?.stage === "preflight" || ["needs_agent_decision", "needs_supervisor_judgment"].includes(state?.recon_status || "") || requestedStage === "recon") {
|
|
1790
1893
|
const reconRes = runOne("recon");
|
|
1791
|
-
executed.push(
|
|
1894
|
+
executed.push(executedStep(reconRes));
|
|
1792
1895
|
if (!reconRes.ok || reconRes.haltedForApproval) {
|
|
1793
1896
|
return failedRun("recon", reconRes.haltedForApproval ? "recon halted for approval" : "recon failed", reconRes, {
|
|
1794
1897
|
checkpoint: "recon_failed",
|
|
@@ -1836,7 +1939,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1836
1939
|
state = readState(config.statePath);
|
|
1837
1940
|
if (!authorReady(state) || effectiveAdvanceStage === "author") {
|
|
1838
1941
|
const authorRes = runOne("author");
|
|
1839
|
-
executed.push(
|
|
1942
|
+
executed.push(executedStep(authorRes));
|
|
1840
1943
|
if (!authorRes.ok || authorRes.haltedForApproval) {
|
|
1841
1944
|
return failedRun("author", authorRes.haltedForApproval ? "author halted for approval" : "author failed", authorRes, {
|
|
1842
1945
|
checkpoint: "author_failed",
|
|
@@ -1951,7 +2054,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1951
2054
|
}
|
|
1952
2055
|
if (effectiveAdvanceStage === "implement") {
|
|
1953
2056
|
const implementRes = runOne("implement");
|
|
1954
|
-
executed.push(
|
|
2057
|
+
executed.push(executedStep(implementRes));
|
|
1955
2058
|
if (implementRes.haltedForApproval) {
|
|
1956
2059
|
return failedRun("implement", "implement halted for approval", implementRes, {
|
|
1957
2060
|
checkpoint: "implement_blocked",
|
|
@@ -2041,7 +2144,7 @@ ${implementRes.stderr || ""}`;
|
|
|
2041
2144
|
let verifyRes = { ok: true, step: "verify", reusedEvidence: canReuseVerifyEvidence };
|
|
2042
2145
|
if (!canReuseVerifyEvidence) {
|
|
2043
2146
|
verifyRes = runOne("verify");
|
|
2044
|
-
executed.push(
|
|
2147
|
+
executed.push(executedStep(verifyRes));
|
|
2045
2148
|
if (!verifyRes.ok || verifyRes.haltedForApproval) {
|
|
2046
2149
|
return failedRun("verify", verifyRes.haltedForApproval ? "verify halted for approval" : "verify failed", verifyRes, {
|
|
2047
2150
|
checkpoint: "verify_failed",
|
|
@@ -2050,7 +2153,7 @@ ${implementRes.stderr || ""}`;
|
|
|
2050
2153
|
});
|
|
2051
2154
|
}
|
|
2052
2155
|
} else {
|
|
2053
|
-
executed.push(
|
|
2156
|
+
executed.push(executedStep(verifyRes, { reusedEvidence: true }));
|
|
2054
2157
|
}
|
|
2055
2158
|
state = readState(config.statePath);
|
|
2056
2159
|
const verifyStatus = state?.verify_status || ((state?.after_cdn || "").trim() ? "evidence_captured" : "capture_incomplete");
|
|
@@ -2187,7 +2290,7 @@ ${implementRes.stderr || ""}`;
|
|
|
2187
2290
|
details: { ...verifyDetails, shipGate }
|
|
2188
2291
|
});
|
|
2189
2292
|
const shipRes = runOne("ship");
|
|
2190
|
-
executed.push(
|
|
2293
|
+
executed.push(executedStep(shipRes));
|
|
2191
2294
|
if (!shipRes.ok || shipRes.haltedForApproval) {
|
|
2192
2295
|
const shipNextAction = shipRes?.error && String(shipRes.error).includes("temporary proof branch") ? "product bug: ship resolved a temporary proof branch; resolve the PR head branch before retrying ship" : "inspect the ship error, confirm the PR head branch and verified commit, then retry ship";
|
|
2193
2296
|
return failedRun("ship", shipRes.haltedForApproval ? "ship halted for approval" : "ship failed", shipRes, {
|
|
@@ -2366,7 +2469,7 @@ ${implementRes.stderr || ""}`;
|
|
|
2366
2469
|
return shipGateBlocked(state, executed, { shipAssessment: shipAssessment.raw });
|
|
2367
2470
|
}
|
|
2368
2471
|
const shipRes = runOne("ship");
|
|
2369
|
-
executed.push(
|
|
2472
|
+
executed.push(executedStep(shipRes));
|
|
2370
2473
|
if (!shipRes.ok || shipRes.haltedForApproval) {
|
|
2371
2474
|
return failedRun("ship", shipRes.haltedForApproval ? "ship halted for approval" : "ship failed", shipRes, {
|
|
2372
2475
|
checkpoint: "ship_failed",
|
|
@@ -262,7 +262,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
262
262
|
blocking?: boolean;
|
|
263
263
|
details?: Record<string, unknown>;
|
|
264
264
|
ok: boolean;
|
|
265
|
-
action: "setup" | "recon" | "author" | "implement" | "verify" | "
|
|
265
|
+
action: "ship" | "setup" | "recon" | "author" | "implement" | "verify" | "run";
|
|
266
266
|
state_path: string;
|
|
267
267
|
stage: any;
|
|
268
268
|
summary: string;
|
|
@@ -342,7 +342,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
342
342
|
continueWithStage?: WorkflowStage | null;
|
|
343
343
|
blocking?: boolean;
|
|
344
344
|
details?: Record<string, unknown>;
|
|
345
|
-
action: "setup" | "recon" | "author" | "implement" | "verify" | "
|
|
345
|
+
action: "ship" | "setup" | "recon" | "author" | "implement" | "verify" | "run";
|
|
346
346
|
state_path: string;
|
|
347
347
|
stage: any;
|
|
348
348
|
checkpoint: string;
|
|
@@ -589,7 +589,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
589
589
|
error?: undefined;
|
|
590
590
|
} | {
|
|
591
591
|
ok: boolean;
|
|
592
|
-
action: "setup" | "recon" | "author" | "implement" | "verify" | "
|
|
592
|
+
action: "ship" | "setup" | "recon" | "author" | "implement" | "verify" | "run";
|
|
593
593
|
state_path: string;
|
|
594
594
|
stage: any;
|
|
595
595
|
summary: string;
|