@riddledc/riddle-proof 0.5.2 → 0.5.4
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-GC7C2NRA.js} +69 -2
- package/dist/engine-harness.cjs +197 -27
- package/dist/engine-harness.js +1 -1
- package/dist/index.cjs +197 -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/lib/workspace-core.mjs +6 -1
- package/package.json +1 -1
- package/runtime/lib/preflight.py +13 -0
- package/runtime/lib/setup.py +68 -5
|
@@ -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;
|
|
@@ -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;
|
package/dist/proof-run-engine.js
CHANGED
|
@@ -95,6 +95,88 @@ function updateState(statePath, mutate) {
|
|
|
95
95
|
writeState(statePath, state);
|
|
96
96
|
return state;
|
|
97
97
|
}
|
|
98
|
+
var RUNTIME_EVENT_LIMIT = 100;
|
|
99
|
+
function nowIso() {
|
|
100
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
101
|
+
}
|
|
102
|
+
function appendRuntimeEventToState(state, event) {
|
|
103
|
+
const events = Array.isArray(state.runtime_events) ? state.runtime_events : [];
|
|
104
|
+
state.runtime_events = [...events, event].slice(-RUNTIME_EVENT_LIMIT);
|
|
105
|
+
state.runtime_updated_at = event.ts;
|
|
106
|
+
}
|
|
107
|
+
function beginRuntimeStep(statePath, action, step, workflowPath) {
|
|
108
|
+
const timer = {
|
|
109
|
+
startedAt: nowIso(),
|
|
110
|
+
startedMs: Date.now()
|
|
111
|
+
};
|
|
112
|
+
updateState(statePath, (state) => {
|
|
113
|
+
const current = {
|
|
114
|
+
step,
|
|
115
|
+
action,
|
|
116
|
+
status: "running",
|
|
117
|
+
started_at: timer.startedAt,
|
|
118
|
+
workflow_file: path.basename(workflowPath)
|
|
119
|
+
};
|
|
120
|
+
state.current_runtime_step = current;
|
|
121
|
+
appendRuntimeEventToState(state, {
|
|
122
|
+
ts: timer.startedAt,
|
|
123
|
+
kind: "workflow.step.started",
|
|
124
|
+
step,
|
|
125
|
+
action,
|
|
126
|
+
summary: `Started ${step} workflow step.`,
|
|
127
|
+
details: {
|
|
128
|
+
workflow_file: path.basename(workflowPath)
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
return timer;
|
|
133
|
+
}
|
|
134
|
+
function finishRuntimeStep(statePath, action, result, timer) {
|
|
135
|
+
const finishedAt = nowIso();
|
|
136
|
+
const durationMs = Date.now() - timer.startedMs;
|
|
137
|
+
const summary = result.haltedForApproval ? `${result.step} halted for approval.` : result.ok ? `Finished ${result.step} workflow step.` : `${result.step} workflow step failed.`;
|
|
138
|
+
updateState(statePath, (state) => {
|
|
139
|
+
const completed = {
|
|
140
|
+
step: result.step,
|
|
141
|
+
action,
|
|
142
|
+
status: result.haltedForApproval ? "approval_required" : result.ok ? "completed" : "failed",
|
|
143
|
+
started_at: timer.startedAt,
|
|
144
|
+
finished_at: finishedAt,
|
|
145
|
+
duration_ms: durationMs,
|
|
146
|
+
ok: result.ok,
|
|
147
|
+
halted_for_approval: result.haltedForApproval || false,
|
|
148
|
+
auto_approved: result.autoApproved || false,
|
|
149
|
+
error: result.error || null
|
|
150
|
+
};
|
|
151
|
+
state.current_runtime_step = null;
|
|
152
|
+
state.last_runtime_step = completed;
|
|
153
|
+
appendRuntimeEventToState(state, {
|
|
154
|
+
ts: finishedAt,
|
|
155
|
+
kind: "workflow.step.finished",
|
|
156
|
+
step: result.step,
|
|
157
|
+
action,
|
|
158
|
+
summary,
|
|
159
|
+
details: completed
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
...result,
|
|
164
|
+
started_at: timer.startedAt,
|
|
165
|
+
finished_at: finishedAt,
|
|
166
|
+
duration_ms: durationMs
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function executedStep(res, extra = {}) {
|
|
170
|
+
const output = {
|
|
171
|
+
step: res.step,
|
|
172
|
+
ok: res.ok,
|
|
173
|
+
haltedForApproval: res.haltedForApproval || false,
|
|
174
|
+
autoApproved: res.autoApproved || false,
|
|
175
|
+
...extra
|
|
176
|
+
};
|
|
177
|
+
if (typeof res.duration_ms === "number") output.duration_ms = res.duration_ms;
|
|
178
|
+
return output;
|
|
179
|
+
}
|
|
98
180
|
function hasSupervisorProofAssessment(state) {
|
|
99
181
|
const proofAssessment = state?.proof_assessment || {};
|
|
100
182
|
const source = String(proofAssessment?.source || state?.proof_assessment_source || "").trim().toLowerCase();
|
|
@@ -557,53 +639,74 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
557
639
|
const lobsterPrefix = process.env.RIDDLE_PROOF_LOBSTER_SCRIPT ? [process.env.RIDDLE_PROOF_LOBSTER_SCRIPT] : [];
|
|
558
640
|
const runOne = (step) => {
|
|
559
641
|
const args = step === "setup" ? buildSetupArgs(params, config) : {};
|
|
642
|
+
const stepWorkflowFile = workflowFile(config.riddleProofDir, step);
|
|
643
|
+
const timer = beginRuntimeStep(config.statePath, action, step, stepWorkflowFile);
|
|
560
644
|
let output;
|
|
561
645
|
try {
|
|
562
646
|
output = JSON.parse(
|
|
563
|
-
execFileSync(lobsterCommand, [...lobsterPrefix, "run", "--file",
|
|
647
|
+
execFileSync(lobsterCommand, [...lobsterPrefix, "run", "--file", stepWorkflowFile, "--args-json", JSON.stringify(args)], {
|
|
564
648
|
encoding: "utf-8",
|
|
565
649
|
env
|
|
566
650
|
})
|
|
567
651
|
);
|
|
568
652
|
} catch (error) {
|
|
569
|
-
return {
|
|
653
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
570
654
|
ok: false,
|
|
571
655
|
step,
|
|
572
656
|
error: error?.message || String(error),
|
|
573
657
|
stdout: String(error?.stdout || ""),
|
|
574
658
|
stderr: String(error?.stderr || "")
|
|
575
|
-
};
|
|
659
|
+
}, timer);
|
|
576
660
|
}
|
|
577
661
|
if (output?.status === "needs_approval") {
|
|
578
662
|
if (!params.auto_approve) {
|
|
579
|
-
return {
|
|
663
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
580
664
|
ok: false,
|
|
581
665
|
haltedForApproval: true,
|
|
582
666
|
step,
|
|
583
667
|
approval: output.requiresApproval || null,
|
|
584
668
|
raw: output
|
|
585
|
-
};
|
|
669
|
+
}, timer);
|
|
586
670
|
}
|
|
587
671
|
const token = output?.requiresApproval?.resumeToken;
|
|
588
|
-
if (!token)
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
672
|
+
if (!token) {
|
|
673
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
674
|
+
ok: false,
|
|
675
|
+
step,
|
|
676
|
+
error: `${step} requested approval without a resume token.`,
|
|
677
|
+
raw: output
|
|
678
|
+
}, timer);
|
|
679
|
+
}
|
|
680
|
+
let resumed;
|
|
681
|
+
try {
|
|
682
|
+
resumed = JSON.parse(
|
|
683
|
+
execFileSync(lobsterCommand, [...lobsterPrefix, "resume", "--token", token, "--approve", "yes"], {
|
|
684
|
+
encoding: "utf-8",
|
|
685
|
+
env
|
|
686
|
+
})
|
|
687
|
+
);
|
|
688
|
+
} catch (error) {
|
|
689
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
690
|
+
ok: false,
|
|
691
|
+
step,
|
|
692
|
+
autoApproved: true,
|
|
693
|
+
error: error?.message || String(error),
|
|
694
|
+
stdout: String(error?.stdout || ""),
|
|
695
|
+
stderr: String(error?.stderr || "")
|
|
696
|
+
}, timer);
|
|
697
|
+
}
|
|
698
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
596
699
|
ok: resumed?.ok !== false,
|
|
597
700
|
step,
|
|
598
701
|
autoApproved: true,
|
|
599
702
|
raw: resumed
|
|
600
|
-
};
|
|
703
|
+
}, timer);
|
|
601
704
|
}
|
|
602
|
-
return {
|
|
705
|
+
return finishRuntimeStep(config.statePath, action, {
|
|
603
706
|
ok: output?.ok !== false,
|
|
604
707
|
step,
|
|
605
708
|
raw: output
|
|
606
|
-
};
|
|
709
|
+
}, timer);
|
|
607
710
|
};
|
|
608
711
|
let effectiveAdvanceStage = params.advance_stage || null;
|
|
609
712
|
const recordAttempt = (stage, status, summary, extra = {}) => {
|
|
@@ -729,7 +832,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
729
832
|
let state = readState(config.statePath);
|
|
730
833
|
if (!state || !state.workspace_ready || params.advance_stage === "setup") {
|
|
731
834
|
const setupRes = runOne("setup");
|
|
732
|
-
executed.push(
|
|
835
|
+
executed.push(executedStep(setupRes));
|
|
733
836
|
if (!setupRes.ok || setupRes.haltedForApproval) {
|
|
734
837
|
return failedRun("setup", setupRes.haltedForApproval ? "setup halted for approval" : "setup failed", setupRes, {
|
|
735
838
|
checkpoint: "setup_blocked"
|
|
@@ -939,7 +1042,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
939
1042
|
}
|
|
940
1043
|
if (!state?.recon_results || state?.stage === "setup" || state?.stage === "preflight" || ["needs_agent_decision", "needs_supervisor_judgment"].includes(state?.recon_status || "") || requestedStage === "recon") {
|
|
941
1044
|
const reconRes = runOne("recon");
|
|
942
|
-
executed.push(
|
|
1045
|
+
executed.push(executedStep(reconRes));
|
|
943
1046
|
if (!reconRes.ok || reconRes.haltedForApproval) {
|
|
944
1047
|
return failedRun("recon", reconRes.haltedForApproval ? "recon halted for approval" : "recon failed", reconRes, {
|
|
945
1048
|
checkpoint: "recon_failed",
|
|
@@ -987,7 +1090,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
987
1090
|
state = readState(config.statePath);
|
|
988
1091
|
if (!authorReady(state) || effectiveAdvanceStage === "author") {
|
|
989
1092
|
const authorRes = runOne("author");
|
|
990
|
-
executed.push(
|
|
1093
|
+
executed.push(executedStep(authorRes));
|
|
991
1094
|
if (!authorRes.ok || authorRes.haltedForApproval) {
|
|
992
1095
|
return failedRun("author", authorRes.haltedForApproval ? "author halted for approval" : "author failed", authorRes, {
|
|
993
1096
|
checkpoint: "author_failed",
|
|
@@ -1102,7 +1205,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1102
1205
|
}
|
|
1103
1206
|
if (effectiveAdvanceStage === "implement") {
|
|
1104
1207
|
const implementRes = runOne("implement");
|
|
1105
|
-
executed.push(
|
|
1208
|
+
executed.push(executedStep(implementRes));
|
|
1106
1209
|
if (implementRes.haltedForApproval) {
|
|
1107
1210
|
return failedRun("implement", "implement halted for approval", implementRes, {
|
|
1108
1211
|
checkpoint: "implement_blocked",
|
|
@@ -1192,7 +1295,7 @@ ${implementRes.stderr || ""}`;
|
|
|
1192
1295
|
let verifyRes = { ok: true, step: "verify", reusedEvidence: canReuseVerifyEvidence };
|
|
1193
1296
|
if (!canReuseVerifyEvidence) {
|
|
1194
1297
|
verifyRes = runOne("verify");
|
|
1195
|
-
executed.push(
|
|
1298
|
+
executed.push(executedStep(verifyRes));
|
|
1196
1299
|
if (!verifyRes.ok || verifyRes.haltedForApproval) {
|
|
1197
1300
|
return failedRun("verify", verifyRes.haltedForApproval ? "verify halted for approval" : "verify failed", verifyRes, {
|
|
1198
1301
|
checkpoint: "verify_failed",
|
|
@@ -1201,7 +1304,7 @@ ${implementRes.stderr || ""}`;
|
|
|
1201
1304
|
});
|
|
1202
1305
|
}
|
|
1203
1306
|
} else {
|
|
1204
|
-
executed.push(
|
|
1307
|
+
executed.push(executedStep(verifyRes, { reusedEvidence: true }));
|
|
1205
1308
|
}
|
|
1206
1309
|
state = readState(config.statePath);
|
|
1207
1310
|
const verifyStatus = state?.verify_status || ((state?.after_cdn || "").trim() ? "evidence_captured" : "capture_incomplete");
|
|
@@ -1338,7 +1441,7 @@ ${implementRes.stderr || ""}`;
|
|
|
1338
1441
|
details: { ...verifyDetails, shipGate }
|
|
1339
1442
|
});
|
|
1340
1443
|
const shipRes = runOne("ship");
|
|
1341
|
-
executed.push(
|
|
1444
|
+
executed.push(executedStep(shipRes));
|
|
1342
1445
|
if (!shipRes.ok || shipRes.haltedForApproval) {
|
|
1343
1446
|
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";
|
|
1344
1447
|
return failedRun("ship", shipRes.haltedForApproval ? "ship halted for approval" : "ship failed", shipRes, {
|
|
@@ -1517,7 +1620,7 @@ ${implementRes.stderr || ""}`;
|
|
|
1517
1620
|
return shipGateBlocked(state, executed, { shipAssessment: shipAssessment.raw });
|
|
1518
1621
|
}
|
|
1519
1622
|
const shipRes = runOne("ship");
|
|
1520
|
-
executed.push(
|
|
1623
|
+
executed.push(executedStep(shipRes));
|
|
1521
1624
|
if (!shipRes.ok || shipRes.haltedForApproval) {
|
|
1522
1625
|
return failedRun("ship", shipRes.haltedForApproval ? "ship halted for approval" : "ship failed", shipRes, {
|
|
1523
1626
|
checkpoint: "ship_failed",
|
package/lib/workspace-core.mjs
CHANGED
|
@@ -318,6 +318,11 @@ function writeDepsManifest(projectDir, fingerprint, installCmd) {
|
|
|
318
318
|
writeFileSync(manifestPath, JSON.stringify({ fingerprint, install_cmd: installCmd }, null, 2));
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
+
function dependencyInstallTimeoutMs() {
|
|
322
|
+
const parsed = Number.parseInt(process.env.RIDDLE_PROOF_INSTALL_TIMEOUT_MS || "", 10);
|
|
323
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 600000;
|
|
324
|
+
}
|
|
325
|
+
|
|
321
326
|
export function ensureDeps({ projectDir, reuseFrom = "" } = {}) {
|
|
322
327
|
const fingerprint = computeDependencyFingerprint(projectDir);
|
|
323
328
|
if (!fingerprint) return "no_package_json";
|
|
@@ -341,7 +346,7 @@ export function ensureDeps({ projectDir, reuseFrom = "" } = {}) {
|
|
|
341
346
|
|
|
342
347
|
const installCmd = detectInstallCommand(projectDir);
|
|
343
348
|
if (!installCmd) return "no_install_command";
|
|
344
|
-
const installResult = runSafe(`${installCmd} 2>&1 | tail -5`, projectDir,
|
|
349
|
+
const installResult = runSafe(`${installCmd} 2>&1 | tail -5`, projectDir, dependencyInstallTimeoutMs());
|
|
345
350
|
if (!installResult.ok) {
|
|
346
351
|
throw new Error(`dependency install failed in ${projectDir}: ${installResult.output.slice(0, 300)}`);
|
|
347
352
|
}
|
package/package.json
CHANGED
package/runtime/lib/preflight.py
CHANGED
|
@@ -239,6 +239,19 @@ if missing:
|
|
|
239
239
|
print('MISSING: ' + ', '.join(missing))
|
|
240
240
|
print('=' * 50)
|
|
241
241
|
|
|
242
|
+
# The TypeScript harness writes runtime observability fields before Lobster
|
|
243
|
+
# starts. Preflight initializes the main state file, so preserve those fields
|
|
244
|
+
# rather than making status polling go blind during setup.
|
|
245
|
+
if os.path.exists(STATE_FILE):
|
|
246
|
+
try:
|
|
247
|
+
with open(STATE_FILE) as existing_state_file:
|
|
248
|
+
existing_state = json.load(existing_state_file)
|
|
249
|
+
except Exception:
|
|
250
|
+
existing_state = {}
|
|
251
|
+
for runtime_key in ('current_runtime_step', 'last_runtime_step', 'runtime_events', 'runtime_updated_at'):
|
|
252
|
+
if runtime_key in existing_state:
|
|
253
|
+
s[runtime_key] = existing_state[runtime_key]
|
|
254
|
+
|
|
242
255
|
save_state(s)
|
|
243
256
|
|
|
244
257
|
if missing:
|
package/runtime/lib/setup.py
CHANGED
|
@@ -6,7 +6,7 @@ workspace root by default:
|
|
|
6
6
|
<workspace>/.riddle-proof-worktrees/riddle-proof-<run_id>-after
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
import json, subprocess as sp, os, sys, shutil
|
|
9
|
+
import json, subprocess as sp, os, sys, shutil, time
|
|
10
10
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
11
11
|
from util import load_state, save_state, git, shell_quote
|
|
12
12
|
|
|
@@ -37,6 +37,15 @@ SKILLS_ROOT = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__fil
|
|
|
37
37
|
WORKSPACE_CORE = os.path.join(SKILLS_ROOT, 'lib', 'workspace-core.mjs')
|
|
38
38
|
|
|
39
39
|
|
|
40
|
+
def dependency_timeout_seconds():
|
|
41
|
+
raw = os.environ.get('RIDDLE_PROOF_INSTALL_TIMEOUT_MS', '').strip()
|
|
42
|
+
try:
|
|
43
|
+
millis = int(raw)
|
|
44
|
+
except Exception:
|
|
45
|
+
millis = 600000
|
|
46
|
+
return max(660, int((millis + 999) / 1000) + 30)
|
|
47
|
+
|
|
48
|
+
|
|
40
49
|
def workspace_core(command, payload, timeout=180):
|
|
41
50
|
if not os.path.exists(WORKSPACE_CORE):
|
|
42
51
|
raise SystemExit('workspace core helper missing: ' + WORKSPACE_CORE)
|
|
@@ -64,10 +73,64 @@ def ensure_deps(project_dir, reuse_from=''):
|
|
|
64
73
|
payload = {'projectDir': project_dir}
|
|
65
74
|
if reuse_from:
|
|
66
75
|
payload['reuseFrom'] = reuse_from
|
|
67
|
-
result = workspace_core('ensure-deps', payload, timeout=
|
|
76
|
+
result = workspace_core('ensure-deps', payload, timeout=dependency_timeout_seconds())
|
|
68
77
|
return result.get('status', '')
|
|
69
78
|
|
|
70
79
|
|
|
80
|
+
def record_setup_phase(phase, status='running', summary=''):
|
|
81
|
+
global s
|
|
82
|
+
ts = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
|
|
83
|
+
try:
|
|
84
|
+
current = load_state()
|
|
85
|
+
except Exception:
|
|
86
|
+
current = dict(s)
|
|
87
|
+
runtime_step = current.get('current_runtime_step') if isinstance(current.get('current_runtime_step'), dict) else {}
|
|
88
|
+
if not runtime_step:
|
|
89
|
+
runtime_step = {
|
|
90
|
+
'step': 'setup',
|
|
91
|
+
'action': 'run',
|
|
92
|
+
'status': 'running',
|
|
93
|
+
'started_at': ts,
|
|
94
|
+
'workflow_file': 'riddle-proof-setup.lobster',
|
|
95
|
+
}
|
|
96
|
+
runtime_step['phase'] = phase
|
|
97
|
+
runtime_step['phase_status'] = status
|
|
98
|
+
if status == 'running':
|
|
99
|
+
runtime_step['phase_started_at'] = ts
|
|
100
|
+
runtime_step.pop('phase_finished_at', None)
|
|
101
|
+
else:
|
|
102
|
+
runtime_step['phase_finished_at'] = ts
|
|
103
|
+
if summary:
|
|
104
|
+
runtime_step['summary'] = summary
|
|
105
|
+
current['current_runtime_step'] = runtime_step
|
|
106
|
+
events = current.get('runtime_events') if isinstance(current.get('runtime_events'), list) else []
|
|
107
|
+
events.append({
|
|
108
|
+
'ts': ts,
|
|
109
|
+
'kind': 'workflow.phase.' + ('started' if status == 'running' else 'finished'),
|
|
110
|
+
'step': 'setup',
|
|
111
|
+
'phase': phase,
|
|
112
|
+
'summary': summary or (phase + ' ' + status),
|
|
113
|
+
'details': {'status': status},
|
|
114
|
+
})
|
|
115
|
+
current['runtime_events'] = events[-100:]
|
|
116
|
+
current['runtime_updated_at'] = ts
|
|
117
|
+
save_state(current)
|
|
118
|
+
for key in ('current_runtime_step', 'runtime_events', 'runtime_updated_at'):
|
|
119
|
+
if key in current:
|
|
120
|
+
s[key] = current[key]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def ensure_deps_phase(phase, project_dir, reuse_from='', summary=''):
|
|
124
|
+
record_setup_phase(phase, 'running', summary)
|
|
125
|
+
try:
|
|
126
|
+
status = ensure_deps(project_dir, reuse_from=reuse_from)
|
|
127
|
+
except BaseException as exc:
|
|
128
|
+
record_setup_phase(phase, 'failed', str(exc)[:300])
|
|
129
|
+
raise
|
|
130
|
+
record_setup_phase(phase, 'completed', status or 'no dependency install needed')
|
|
131
|
+
return status
|
|
132
|
+
|
|
133
|
+
|
|
71
134
|
def resolve_worktree_root(repo_dir):
|
|
72
135
|
configured = (s.get('worktree_root') or os.environ.get('RIDDLE_PROOF_WORKTREE_ROOT') or '').strip()
|
|
73
136
|
if configured:
|
|
@@ -339,16 +402,16 @@ apply_repo_profile(AFTER_DIR)
|
|
|
339
402
|
save_state(s)
|
|
340
403
|
|
|
341
404
|
reuse_source = repo_dir if os.path.exists(os.path.join(repo_dir, 'package.json')) else ''
|
|
342
|
-
shared_status =
|
|
405
|
+
shared_status = ensure_deps_phase('shared_deps', reuse_source, summary='Ensuring shared repository dependencies.') if reuse_source else ''
|
|
343
406
|
if shared_status:
|
|
344
407
|
print('Shared deps status: ' + shared_status)
|
|
345
408
|
|
|
346
409
|
before_dep_status = ''
|
|
347
410
|
if reference in ('before', 'both'):
|
|
348
|
-
before_dep_status =
|
|
411
|
+
before_dep_status = ensure_deps_phase('before_deps', BEFORE_DIR, reuse_from=reuse_source, summary='Ensuring before-worktree dependencies.')
|
|
349
412
|
print('Before deps status: ' + before_dep_status)
|
|
350
413
|
|
|
351
|
-
after_dep_status =
|
|
414
|
+
after_dep_status = ensure_deps_phase('after_deps', AFTER_DIR, reuse_from=reuse_source, summary='Ensuring after-worktree dependencies.')
|
|
352
415
|
print('After deps status: ' + after_dep_status)
|
|
353
416
|
|
|
354
417
|
# Patch Next.js config in after worktree if needed
|