@riddledc/riddle-proof 0.8.29 → 0.8.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/advanced/engine-harness.cjs +188 -11
  2. package/dist/advanced/engine-harness.js +2 -2
  3. package/dist/advanced/index.cjs +188 -11
  4. package/dist/advanced/index.d.cts +2 -2
  5. package/dist/advanced/index.d.ts +2 -2
  6. package/dist/advanced/index.js +4 -4
  7. package/dist/advanced/proof-run-core.cjs +3 -1
  8. package/dist/advanced/proof-run-core.d.cts +1 -1
  9. package/dist/advanced/proof-run-core.d.ts +1 -1
  10. package/dist/advanced/proof-run-core.js +1 -1
  11. package/dist/advanced/proof-run-engine.cjs +136 -2
  12. package/dist/advanced/proof-run-engine.d.cts +2 -2
  13. package/dist/advanced/proof-run-engine.d.ts +2 -2
  14. package/dist/advanced/proof-run-engine.js +2 -2
  15. package/dist/advanced/runner.js +2 -2
  16. package/dist/{chunk-3OTO7IDH.js → chunk-C2NHHBFV.js} +1 -1
  17. package/dist/{chunk-YC77HZVF.js → chunk-IOI6QR3B.js} +134 -2
  18. package/dist/{chunk-FJPZZ4JO.js → chunk-U73JPBZW.js} +1 -1
  19. package/dist/{chunk-K6HZUSHH.js → chunk-X7SQTCIQ.js} +3 -1
  20. package/dist/{chunk-AM3K5FPW.js → chunk-ZREWMTFA.js} +53 -10
  21. package/dist/cli/index.js +3 -3
  22. package/dist/cli.cjs +188 -11
  23. package/dist/cli.js +3 -3
  24. package/dist/engine-harness.cjs +188 -11
  25. package/dist/engine-harness.js +2 -2
  26. package/dist/index.cjs +188 -11
  27. package/dist/index.js +3 -3
  28. package/dist/{proof-run-core-C8FDUhle.d.cts → proof-run-core-B1GeqkR8.d.cts} +2 -0
  29. package/dist/{proof-run-core-C8FDUhle.d.ts → proof-run-core-B1GeqkR8.d.ts} +2 -0
  30. package/dist/proof-run-core.cjs +3 -1
  31. package/dist/proof-run-core.d.cts +1 -1
  32. package/dist/proof-run-core.d.ts +1 -1
  33. package/dist/proof-run-core.js +1 -1
  34. package/dist/{proof-run-engine-D80hVFMf.d.cts → proof-run-engine-4dM37pEx.d.cts} +1 -1
  35. package/dist/{proof-run-engine-By7oLsF-.d.ts → proof-run-engine-BqaeqAze.d.ts} +1 -1
  36. package/dist/proof-run-engine.cjs +136 -2
  37. package/dist/proof-run-engine.d.cts +2 -2
  38. package/dist/proof-run-engine.d.ts +2 -2
  39. package/dist/proof-run-engine.js +2 -2
  40. package/dist/runner.js +2 -2
  41. package/lib/workspace-core.mjs +62 -7
  42. package/package.json +2 -2
  43. package/runtime/lib/riddle_core_call.mjs +662 -40
  44. package/runtime/lib/util.py +117 -40
  45. package/runtime/lib/verify.py +17 -4
  46. package/runtime/tests/recon_verify_smoke.py +137 -1
@@ -157,6 +157,7 @@ function buildSetupArgs(params, config) {
157
157
  discord_thread_id: params.discord_thread_id || "",
158
158
  discord_message_id: params.discord_message_id || "",
159
159
  discord_source_url: params.discord_source_url || "",
160
+ ship_mode: params.ship_mode || "",
160
161
  leave_draft: params.leave_draft ? "true" : ""
161
162
  };
162
163
  }
@@ -746,7 +747,8 @@ function mergeStateFromParams(statePath, params) {
746
747
  "auth_headers_json",
747
748
  "proof_plan",
748
749
  "implementation_notes",
749
- "implementation_mode"
750
+ "implementation_mode",
751
+ "ship_mode"
750
752
  ];
751
753
  for (const field of stringFields) {
752
754
  if (params[field] !== void 0) {
@@ -1365,6 +1367,72 @@ function updateState(statePath, mutate) {
1365
1367
  function nowIso() {
1366
1368
  return (/* @__PURE__ */ new Date()).toISOString();
1367
1369
  }
1370
+ function missingExecutableError(error) {
1371
+ return error?.code === "ENOENT" || /\bENOENT\b/.test(String(error?.message || error || ""));
1372
+ }
1373
+ function pythonScriptsForBundledStage(step) {
1374
+ if (step === "setup") return ["preflight.py", "setup.py"];
1375
+ if (step === "recon") return ["recon.py"];
1376
+ if (step === "author") return ["author.py"];
1377
+ if (step === "implement") return ["implement.py"];
1378
+ if (step === "verify") return ["verify.py"];
1379
+ if (step === "ship") return ["ship.py"];
1380
+ return [];
1381
+ }
1382
+ function runBundledPythonStage(step, runtimeDir, env) {
1383
+ const scripts = pythonScriptsForBundledStage(step);
1384
+ if (!scripts.length) {
1385
+ return {
1386
+ ok: false,
1387
+ error: `No bundled Python fallback is defined for ${step}.`
1388
+ };
1389
+ }
1390
+ const pythonCommand = process.env.RIDDLE_PROOF_PYTHON_COMMAND || "python3";
1391
+ const libDir = import_node_path2.default.join(runtimeDir, "lib");
1392
+ const stdout = [];
1393
+ const stderr = [];
1394
+ const executed = [];
1395
+ try {
1396
+ for (const script of scripts) {
1397
+ const scriptPath = import_node_path2.default.join(libDir, script);
1398
+ if (!(0, import_node_fs2.existsSync)(scriptPath)) {
1399
+ return {
1400
+ ok: false,
1401
+ stdout: stdout.join(""),
1402
+ stderr: stderr.join(""),
1403
+ error: `Riddle Proof bundled Python fallback missing ${scriptPath}`
1404
+ };
1405
+ }
1406
+ executed.push(script);
1407
+ stdout.push((0, import_node_child_process.execFileSync)(pythonCommand, [scriptPath], {
1408
+ encoding: "utf-8",
1409
+ env,
1410
+ stdio: ["ignore", "pipe", "pipe"]
1411
+ }));
1412
+ }
1413
+ } catch (error) {
1414
+ return {
1415
+ ok: false,
1416
+ stdout: `${stdout.join("")}${String(error?.stdout || "")}`,
1417
+ stderr: `${stderr.join("")}${String(error?.stderr || "")}`,
1418
+ error: error?.message || String(error),
1419
+ raw: {
1420
+ runner: "bundled_python_fallback",
1421
+ scripts: executed
1422
+ }
1423
+ };
1424
+ }
1425
+ return {
1426
+ ok: true,
1427
+ stdout: stdout.join(""),
1428
+ stderr: stderr.join(""),
1429
+ raw: {
1430
+ ok: true,
1431
+ runner: "bundled_python_fallback",
1432
+ scripts: executed
1433
+ }
1434
+ };
1435
+ }
1368
1436
  function appendRuntimeEventToState(state, event) {
1369
1437
  const events = Array.isArray(state.runtime_events) ? state.runtime_events : [];
1370
1438
  state.runtime_events = [...events, event].slice(-RUNTIME_EVENT_LIMIT);
@@ -1931,6 +1999,17 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
1931
1999
  })
1932
2000
  );
1933
2001
  } catch (error) {
2002
+ if (!process.env.RIDDLE_PROOF_LOBSTER_SCRIPT && missingExecutableError(error)) {
2003
+ const fallback = runBundledPythonStage(step, config.riddleProofDir, env);
2004
+ return finishRuntimeStep(config.statePath, action, {
2005
+ ok: fallback.ok,
2006
+ step,
2007
+ raw: fallback.raw,
2008
+ stdout: fallback.stdout,
2009
+ stderr: fallback.stderr,
2010
+ error: fallback.error
2011
+ }, timer);
2012
+ }
1934
2013
  return finishRuntimeStep(config.statePath, action, {
1935
2014
  ok: false,
1936
2015
  step,
@@ -2684,6 +2763,60 @@ ${implementRes.stderr || ""}`;
2684
2763
  verifyRes = runOne("verify");
2685
2764
  executed.push(executedStep(verifyRes));
2686
2765
  if (!verifyRes.ok || verifyRes.haltedForApproval) {
2766
+ const failedVerifyState = readState(config.statePath);
2767
+ const failedVerifyStatus = failedVerifyState?.verify_status || "";
2768
+ if (!verifyRes.haltedForApproval && (failedVerifyStatus === "capture_incomplete" || failedVerifyStatus === "capture_error")) {
2769
+ const verifyDecisionRequest2 = failedVerifyState?.verify_decision_request || null;
2770
+ const captureQuality = verifyDecisionRequest2?.capture_quality || {};
2771
+ const conclusiveVerifyBlockers2 = proofAssessmentHardBlockersForState({
2772
+ ...failedVerifyState,
2773
+ structured_interaction_capture_failure_summary: stringValue(verifyDecisionRequest2?.structured_interaction_capture_failure_summary) || stringValue(failedVerifyState?.structured_interaction_capture_failure_summary) || void 0,
2774
+ structured_interaction_failure_summary: stringValue(verifyDecisionRequest2?.structured_interaction_failure_summary) || stringValue(failedVerifyState?.structured_interaction_failure_summary) || void 0
2775
+ });
2776
+ const structuredInteractionFailureSummary2 = stringValue(verifyDecisionRequest2?.structured_interaction_capture_failure_summary) || stringValue(verifyDecisionRequest2?.structured_interaction_failure_summary) || stringValue(failedVerifyState?.structured_interaction_capture_failure_summary) || stringValue(failedVerifyState?.structured_interaction_failure_summary) || stringValue(conclusiveVerifyBlockers2[0]);
2777
+ const captureTerminalBlocker = failedVerifyStatus === "capture_error" || conclusiveVerifyBlockers2.length > 0 || Boolean(structuredInteractionFailureSummary2) || captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
2778
+ const terminalCaptureQualitySummary = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true ? stringValue(captureQuality?.summary) : "";
2779
+ const checkpointName = captureTerminalBlocker ? "verify_capture_blocked" : "verify_capture_retry";
2780
+ const summary = terminalCaptureQualitySummary || structuredInteractionFailureSummary2 || stringValue(verifyDecisionRequest2?.summary) || stringValue(failedVerifyState?.verify_summary) || stringValue(failedVerifyState?.proof_summary) || stringValue(verifyRes.error) || "Verify capture failed before the evidence could be judged.";
2781
+ const failedVerifyDetails = {
2782
+ executed,
2783
+ verifyStatus: failedVerifyStatus,
2784
+ verifySummary: failedVerifyState?.verify_summary || failedVerifyState?.proof_summary || null,
2785
+ afterCdn: failedVerifyState?.after_cdn || null,
2786
+ mergeRecommendation: failedVerifyState?.merge_recommendation || null,
2787
+ verifyDecisionRequest: verifyDecisionRequest2,
2788
+ conclusiveVerifyBlockers: conclusiveVerifyBlockers2,
2789
+ verifyError: verifyRes.error || null,
2790
+ verifyStdout: verifyRes.stdout || "",
2791
+ verifyStderr: verifyRes.stderr || ""
2792
+ };
2793
+ recordAttempt("verify", "checkpoint", summary, {
2794
+ autoApproved: verifyRes.autoApproved || false,
2795
+ checkpoint: checkpointName,
2796
+ error: verifyRes.error || null,
2797
+ details: failedVerifyDetails
2798
+ });
2799
+ return checkpoint(
2800
+ "verify",
2801
+ checkpointName,
2802
+ summary,
2803
+ {
2804
+ ok: true,
2805
+ nextActions: captureTerminalBlocker ? ["inspect_after_capture", "report_specific_browser_evidence_blocker", "start_a_new_run_after_the_product_or_script_is_fixed"] : ["inspect_after_capture", "continue_internal_loop_with_checkpoint", "return_to_recon_if_baseline_is_wrong"],
2806
+ advanceOptions: needsImplementation ? ["author", "implement", "ship", "verify", "recon"] : ["author", "verify", "recon"],
2807
+ recommendedAdvanceStage: captureTerminalBlocker ? null : verifyDecisionRequest2?.recommended_stage || verifyDecisionRequest2?.continue_with_stage || "author",
2808
+ continueWithStage: captureTerminalBlocker ? null : verifyDecisionRequest2?.continue_with_stage || verifyDecisionRequest2?.recommended_stage || "author",
2809
+ blocking: captureTerminalBlocker,
2810
+ details: failedVerifyDetails,
2811
+ verifyStatus: failedVerifyStatus,
2812
+ verifySummary: failedVerifyDetails.verifySummary,
2813
+ afterCdn: failedVerifyState?.after_cdn || null,
2814
+ mergeRecommendation: failedVerifyState?.merge_recommendation || null,
2815
+ verifyDecisionRequest: verifyDecisionRequest2,
2816
+ executed
2817
+ }
2818
+ );
2819
+ }
2687
2820
  return failedRun("verify", verifyRes.haltedForApproval ? "verify halted for approval" : "verify failed", verifyRes, {
2688
2821
  checkpoint: "verify_failed",
2689
2822
  details: { executed },
@@ -2737,8 +2870,9 @@ ${implementRes.stderr || ""}`;
2737
2870
  });
2738
2871
  state = readState(config.statePath);
2739
2872
  }
2873
+ const terminalCaptureQualitySummary = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true ? stringValue(captureQuality?.summary) : "";
2740
2874
  const checkpointName = captureTerminalBlocker ? "verify_capture_blocked" : "verify_capture_retry";
2741
- const summary = structuredInteractionFailureSummary || stringValue(proofAssessment.summary) || "Verify ran, but the proof packet still needs internal capture-plan work before it should ship.";
2875
+ const summary = terminalCaptureQualitySummary || structuredInteractionFailureSummary || stringValue(proofAssessment.summary) || "Verify ran, but the proof packet still needs internal capture-plan work before it should ship.";
2742
2876
  recordAttempt("verify", "checkpoint", summary, {
2743
2877
  autoApproved: verifyRes.autoApproved || false,
2744
2878
  checkpoint: checkpointName,
@@ -4794,6 +4928,7 @@ function initialRunParams(request, input, state) {
4794
4928
  auth_headers_json: request.auth_headers_json,
4795
4929
  color_scheme: request.color_scheme,
4796
4930
  wait_for_selector: request.wait_for_selector,
4931
+ ship_mode: request.ship_mode,
4797
4932
  leave_draft: request.leave_draft || void 0,
4798
4933
  discord_channel: request.integration_context?.channel_id,
4799
4934
  discord_thread_id: request.integration_context?.thread_id,
@@ -4806,6 +4941,18 @@ function initialRunParams(request, input, state) {
4806
4941
  function effectiveShipMode(request, config) {
4807
4942
  return request.ship_mode || config?.defaultShipMode || "ship";
4808
4943
  }
4944
+ function continuationRequestsShip(next) {
4945
+ return Boolean(next && (next.advance_stage === "ship" || next.ship_after_verify === true));
4946
+ }
4947
+ function shipHeldTerminal(state, result) {
4948
+ return terminalResult(
4949
+ state,
4950
+ "ready_to_ship",
4951
+ result,
4952
+ result.summary || "Riddle Proof evidence is approved, but ship_mode=none is holding before PR/ship.",
4953
+ { ship_held: true }
4954
+ );
4955
+ }
4809
4956
  function checkpointContinueStage2(result) {
4810
4957
  const resume = recordValue(result.checkpointContract?.resume);
4811
4958
  return nonEmptyString(resume?.continue_with_stage);
@@ -5330,6 +5477,28 @@ function checkpointResponseContinuation(state, value) {
5330
5477
  const assessment = proofAssessmentPayloadFromCheckpointResponse(response);
5331
5478
  if (assessment) {
5332
5479
  appendCheckpointResponse(state, response);
5480
+ if (state.request.ship_mode !== "ship" && proofAssessmentRequestsShip(assessment)) {
5481
+ const result = {
5482
+ ok: true,
5483
+ state_path: state.request.engine_state_path || packet.state_path || "",
5484
+ checkpoint: packet.checkpoint,
5485
+ stage: packet.stage,
5486
+ summary: response.summary,
5487
+ checkpointContract: checkpointContractFromPacket(packet) || null
5488
+ };
5489
+ return {
5490
+ terminal: terminalResult(
5491
+ state,
5492
+ "ready_to_ship",
5493
+ result,
5494
+ response.summary || "Riddle Proof evidence is approved, but ship_mode=none is holding before PR/ship.",
5495
+ {
5496
+ ship_held: true,
5497
+ proof_assessment: assessment
5498
+ }
5499
+ )
5500
+ };
5501
+ }
5333
5502
  return { next: { ...base, proof_assessment_json: jsonParam(assessment) } };
5334
5503
  }
5335
5504
  if (response.decision === "blocked" || response.decision === "human_review") {
@@ -5580,6 +5749,9 @@ async function routeCheckpoint(request, state, result, agent, input) {
5580
5749
  }
5581
5750
  const next = stageCheckpointContinuation(result);
5582
5751
  if (next) {
5752
+ if (continuationRequestsShip(next) && effectiveShipMode(request, input.config) !== "ship") {
5753
+ return { terminal: shipHeldTerminal(state, result) };
5754
+ }
5583
5755
  recordEvent(state, {
5584
5756
  kind: "checkpoint.recovery_continuation",
5585
5757
  checkpoint,
@@ -5611,6 +5783,9 @@ async function routeCheckpoint(request, state, result, agent, input) {
5611
5783
  };
5612
5784
  }
5613
5785
  if (checkpoint === "ship_review") {
5786
+ if (effectiveShipMode(request, input.config) !== "ship") {
5787
+ return { terminal: shipHeldTerminal(state, result) };
5788
+ }
5614
5789
  return {
5615
5790
  terminal: terminalResult(state, "shipped", result, result.summary || "Riddle Proof shipped.")
5616
5791
  };
@@ -5646,9 +5821,7 @@ async function routeCheckpoint(request, state, result, agent, input) {
5646
5821
  return { next: { ...baseContinuation(result), ship_after_verify: true } };
5647
5822
  }
5648
5823
  return {
5649
- terminal: terminalResult(state, "ready_to_ship", result, result.summary || "Riddle Proof evidence is approved, but ship_mode=none is holding before PR/ship.", {
5650
- ship_held: true
5651
- })
5824
+ terminal: shipHeldTerminal(state, result)
5652
5825
  };
5653
5826
  }
5654
5827
  if (checkpoint === "verify_audit_complete") {
@@ -5939,18 +6112,19 @@ async function routeCheckpoint(request, state, result, agent, input) {
5939
6112
  const next = recommendedContinuation(result) || defaultAwaitingStageContinuation(result);
5940
6113
  if (next) {
5941
6114
  if (String(next.advance_stage || "") === "ship" && effectiveShipMode(request, input.config) !== "ship") {
5942
- return {
5943
- terminal: terminalResult(state, "ready_to_ship", result, result.summary || "Riddle Proof evidence is approved, but ship_mode=none is holding before PR/ship.", {
5944
- ship_held: true
5945
- })
5946
- };
6115
+ return { terminal: shipHeldTerminal(state, result) };
5947
6116
  }
5948
6117
  return { next };
5949
6118
  }
5950
6119
  }
5951
6120
  if (checkpoint.endsWith("_review")) {
5952
6121
  const next = recommendedContinuation(result);
5953
- if (next) return { next };
6122
+ if (next) {
6123
+ if (continuationRequestsShip(next) && effectiveShipMode(request, input.config) !== "ship") {
6124
+ return { terminal: shipHeldTerminal(state, result) };
6125
+ }
6126
+ return { next };
6127
+ }
5954
6128
  }
5955
6129
  return {
5956
6130
  blocker: {
@@ -5976,6 +6150,9 @@ async function runRiddleProofEngineHarness(input) {
5976
6150
  if (checkpointContinuation.blocker) {
5977
6151
  return blockerResult(state, null, checkpointContinuation.blocker);
5978
6152
  }
6153
+ if (checkpointContinuation.terminal) {
6154
+ return checkpointContinuation.terminal;
6155
+ }
5979
6156
  const request = state.request;
5980
6157
  const agent = input.agent || createDisabledRiddleProofAgentAdapter();
5981
6158
  const maxIterations = Math.max(
@@ -2,10 +2,10 @@ import {
2
2
  createDisabledRiddleProofAgentAdapter,
3
3
  readRiddleProofRunStatus,
4
4
  runRiddleProofEngineHarness
5
- } from "../chunk-AM3K5FPW.js";
5
+ } from "../chunk-ZREWMTFA.js";
6
6
  import "../chunk-ZQWVXQKJ.js";
7
7
  import "../chunk-RDPG554T.js";
8
- import "../chunk-K6HZUSHH.js";
8
+ import "../chunk-X7SQTCIQ.js";
9
9
  import "../chunk-OILKSY5J.js";
10
10
  import "../chunk-VY4Y5U57.js";
11
11
  import "../chunk-MLKGABMK.js";
@@ -188,6 +188,7 @@ function buildSetupArgs(params, config) {
188
188
  discord_thread_id: params.discord_thread_id || "",
189
189
  discord_message_id: params.discord_message_id || "",
190
190
  discord_source_url: params.discord_source_url || "",
191
+ ship_mode: params.ship_mode || "",
191
192
  leave_draft: params.leave_draft ? "true" : ""
192
193
  };
193
194
  }
@@ -777,7 +778,8 @@ function mergeStateFromParams(statePath, params) {
777
778
  "auth_headers_json",
778
779
  "proof_plan",
779
780
  "implementation_notes",
780
- "implementation_mode"
781
+ "implementation_mode",
782
+ "ship_mode"
781
783
  ];
782
784
  for (const field of stringFields) {
783
785
  if (params[field] !== void 0) {
@@ -1396,6 +1398,72 @@ function updateState(statePath, mutate) {
1396
1398
  function nowIso() {
1397
1399
  return (/* @__PURE__ */ new Date()).toISOString();
1398
1400
  }
1401
+ function missingExecutableError(error) {
1402
+ return error?.code === "ENOENT" || /\bENOENT\b/.test(String(error?.message || error || ""));
1403
+ }
1404
+ function pythonScriptsForBundledStage(step) {
1405
+ if (step === "setup") return ["preflight.py", "setup.py"];
1406
+ if (step === "recon") return ["recon.py"];
1407
+ if (step === "author") return ["author.py"];
1408
+ if (step === "implement") return ["implement.py"];
1409
+ if (step === "verify") return ["verify.py"];
1410
+ if (step === "ship") return ["ship.py"];
1411
+ return [];
1412
+ }
1413
+ function runBundledPythonStage(step, runtimeDir, env) {
1414
+ const scripts = pythonScriptsForBundledStage(step);
1415
+ if (!scripts.length) {
1416
+ return {
1417
+ ok: false,
1418
+ error: `No bundled Python fallback is defined for ${step}.`
1419
+ };
1420
+ }
1421
+ const pythonCommand = process.env.RIDDLE_PROOF_PYTHON_COMMAND || "python3";
1422
+ const libDir = import_node_path2.default.join(runtimeDir, "lib");
1423
+ const stdout = [];
1424
+ const stderr = [];
1425
+ const executed = [];
1426
+ try {
1427
+ for (const script of scripts) {
1428
+ const scriptPath = import_node_path2.default.join(libDir, script);
1429
+ if (!(0, import_node_fs2.existsSync)(scriptPath)) {
1430
+ return {
1431
+ ok: false,
1432
+ stdout: stdout.join(""),
1433
+ stderr: stderr.join(""),
1434
+ error: `Riddle Proof bundled Python fallback missing ${scriptPath}`
1435
+ };
1436
+ }
1437
+ executed.push(script);
1438
+ stdout.push((0, import_node_child_process.execFileSync)(pythonCommand, [scriptPath], {
1439
+ encoding: "utf-8",
1440
+ env,
1441
+ stdio: ["ignore", "pipe", "pipe"]
1442
+ }));
1443
+ }
1444
+ } catch (error) {
1445
+ return {
1446
+ ok: false,
1447
+ stdout: `${stdout.join("")}${String(error?.stdout || "")}`,
1448
+ stderr: `${stderr.join("")}${String(error?.stderr || "")}`,
1449
+ error: error?.message || String(error),
1450
+ raw: {
1451
+ runner: "bundled_python_fallback",
1452
+ scripts: executed
1453
+ }
1454
+ };
1455
+ }
1456
+ return {
1457
+ ok: true,
1458
+ stdout: stdout.join(""),
1459
+ stderr: stderr.join(""),
1460
+ raw: {
1461
+ ok: true,
1462
+ runner: "bundled_python_fallback",
1463
+ scripts: executed
1464
+ }
1465
+ };
1466
+ }
1399
1467
  function appendRuntimeEventToState(state, event) {
1400
1468
  const events = Array.isArray(state.runtime_events) ? state.runtime_events : [];
1401
1469
  state.runtime_events = [...events, event].slice(-RUNTIME_EVENT_LIMIT);
@@ -1962,6 +2030,17 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
1962
2030
  })
1963
2031
  );
1964
2032
  } catch (error) {
2033
+ if (!process.env.RIDDLE_PROOF_LOBSTER_SCRIPT && missingExecutableError(error)) {
2034
+ const fallback = runBundledPythonStage(step, config.riddleProofDir, env);
2035
+ return finishRuntimeStep(config.statePath, action, {
2036
+ ok: fallback.ok,
2037
+ step,
2038
+ raw: fallback.raw,
2039
+ stdout: fallback.stdout,
2040
+ stderr: fallback.stderr,
2041
+ error: fallback.error
2042
+ }, timer);
2043
+ }
1965
2044
  return finishRuntimeStep(config.statePath, action, {
1966
2045
  ok: false,
1967
2046
  step,
@@ -2715,6 +2794,60 @@ ${implementRes.stderr || ""}`;
2715
2794
  verifyRes = runOne("verify");
2716
2795
  executed.push(executedStep(verifyRes));
2717
2796
  if (!verifyRes.ok || verifyRes.haltedForApproval) {
2797
+ const failedVerifyState = readState(config.statePath);
2798
+ const failedVerifyStatus = failedVerifyState?.verify_status || "";
2799
+ if (!verifyRes.haltedForApproval && (failedVerifyStatus === "capture_incomplete" || failedVerifyStatus === "capture_error")) {
2800
+ const verifyDecisionRequest2 = failedVerifyState?.verify_decision_request || null;
2801
+ const captureQuality = verifyDecisionRequest2?.capture_quality || {};
2802
+ const conclusiveVerifyBlockers2 = proofAssessmentHardBlockersForState({
2803
+ ...failedVerifyState,
2804
+ structured_interaction_capture_failure_summary: stringValue(verifyDecisionRequest2?.structured_interaction_capture_failure_summary) || stringValue(failedVerifyState?.structured_interaction_capture_failure_summary) || void 0,
2805
+ structured_interaction_failure_summary: stringValue(verifyDecisionRequest2?.structured_interaction_failure_summary) || stringValue(failedVerifyState?.structured_interaction_failure_summary) || void 0
2806
+ });
2807
+ const structuredInteractionFailureSummary2 = stringValue(verifyDecisionRequest2?.structured_interaction_capture_failure_summary) || stringValue(verifyDecisionRequest2?.structured_interaction_failure_summary) || stringValue(failedVerifyState?.structured_interaction_capture_failure_summary) || stringValue(failedVerifyState?.structured_interaction_failure_summary) || stringValue(conclusiveVerifyBlockers2[0]);
2808
+ const captureTerminalBlocker = failedVerifyStatus === "capture_error" || conclusiveVerifyBlockers2.length > 0 || Boolean(structuredInteractionFailureSummary2) || captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
2809
+ const terminalCaptureQualitySummary = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true ? stringValue(captureQuality?.summary) : "";
2810
+ const checkpointName = captureTerminalBlocker ? "verify_capture_blocked" : "verify_capture_retry";
2811
+ const summary = terminalCaptureQualitySummary || structuredInteractionFailureSummary2 || stringValue(verifyDecisionRequest2?.summary) || stringValue(failedVerifyState?.verify_summary) || stringValue(failedVerifyState?.proof_summary) || stringValue(verifyRes.error) || "Verify capture failed before the evidence could be judged.";
2812
+ const failedVerifyDetails = {
2813
+ executed,
2814
+ verifyStatus: failedVerifyStatus,
2815
+ verifySummary: failedVerifyState?.verify_summary || failedVerifyState?.proof_summary || null,
2816
+ afterCdn: failedVerifyState?.after_cdn || null,
2817
+ mergeRecommendation: failedVerifyState?.merge_recommendation || null,
2818
+ verifyDecisionRequest: verifyDecisionRequest2,
2819
+ conclusiveVerifyBlockers: conclusiveVerifyBlockers2,
2820
+ verifyError: verifyRes.error || null,
2821
+ verifyStdout: verifyRes.stdout || "",
2822
+ verifyStderr: verifyRes.stderr || ""
2823
+ };
2824
+ recordAttempt("verify", "checkpoint", summary, {
2825
+ autoApproved: verifyRes.autoApproved || false,
2826
+ checkpoint: checkpointName,
2827
+ error: verifyRes.error || null,
2828
+ details: failedVerifyDetails
2829
+ });
2830
+ return checkpoint(
2831
+ "verify",
2832
+ checkpointName,
2833
+ summary,
2834
+ {
2835
+ ok: true,
2836
+ nextActions: captureTerminalBlocker ? ["inspect_after_capture", "report_specific_browser_evidence_blocker", "start_a_new_run_after_the_product_or_script_is_fixed"] : ["inspect_after_capture", "continue_internal_loop_with_checkpoint", "return_to_recon_if_baseline_is_wrong"],
2837
+ advanceOptions: needsImplementation ? ["author", "implement", "ship", "verify", "recon"] : ["author", "verify", "recon"],
2838
+ recommendedAdvanceStage: captureTerminalBlocker ? null : verifyDecisionRequest2?.recommended_stage || verifyDecisionRequest2?.continue_with_stage || "author",
2839
+ continueWithStage: captureTerminalBlocker ? null : verifyDecisionRequest2?.continue_with_stage || verifyDecisionRequest2?.recommended_stage || "author",
2840
+ blocking: captureTerminalBlocker,
2841
+ details: failedVerifyDetails,
2842
+ verifyStatus: failedVerifyStatus,
2843
+ verifySummary: failedVerifyDetails.verifySummary,
2844
+ afterCdn: failedVerifyState?.after_cdn || null,
2845
+ mergeRecommendation: failedVerifyState?.merge_recommendation || null,
2846
+ verifyDecisionRequest: verifyDecisionRequest2,
2847
+ executed
2848
+ }
2849
+ );
2850
+ }
2718
2851
  return failedRun("verify", verifyRes.haltedForApproval ? "verify halted for approval" : "verify failed", verifyRes, {
2719
2852
  checkpoint: "verify_failed",
2720
2853
  details: { executed },
@@ -2768,8 +2901,9 @@ ${implementRes.stderr || ""}`;
2768
2901
  });
2769
2902
  state = readState(config.statePath);
2770
2903
  }
2904
+ const terminalCaptureQualitySummary = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true ? stringValue(captureQuality?.summary) : "";
2771
2905
  const checkpointName = captureTerminalBlocker ? "verify_capture_blocked" : "verify_capture_retry";
2772
- const summary = structuredInteractionFailureSummary || stringValue(proofAssessment.summary) || "Verify ran, but the proof packet still needs internal capture-plan work before it should ship.";
2906
+ const summary = terminalCaptureQualitySummary || structuredInteractionFailureSummary || stringValue(proofAssessment.summary) || "Verify ran, but the proof packet still needs internal capture-plan work before it should ship.";
2773
2907
  recordAttempt("verify", "checkpoint", summary, {
2774
2908
  autoApproved: verifyRes.autoApproved || false,
2775
2909
  checkpoint: checkpointName,
@@ -5331,6 +5465,7 @@ function initialRunParams(request, input, state) {
5331
5465
  auth_headers_json: request.auth_headers_json,
5332
5466
  color_scheme: request.color_scheme,
5333
5467
  wait_for_selector: request.wait_for_selector,
5468
+ ship_mode: request.ship_mode,
5334
5469
  leave_draft: request.leave_draft || void 0,
5335
5470
  discord_channel: request.integration_context?.channel_id,
5336
5471
  discord_thread_id: request.integration_context?.thread_id,
@@ -5343,6 +5478,18 @@ function initialRunParams(request, input, state) {
5343
5478
  function effectiveShipMode(request, config) {
5344
5479
  return request.ship_mode || config?.defaultShipMode || "ship";
5345
5480
  }
5481
+ function continuationRequestsShip(next) {
5482
+ return Boolean(next && (next.advance_stage === "ship" || next.ship_after_verify === true));
5483
+ }
5484
+ function shipHeldTerminal(state, result) {
5485
+ return terminalResult(
5486
+ state,
5487
+ "ready_to_ship",
5488
+ result,
5489
+ result.summary || "Riddle Proof evidence is approved, but ship_mode=none is holding before PR/ship.",
5490
+ { ship_held: true }
5491
+ );
5492
+ }
5346
5493
  function checkpointContinueStage2(result) {
5347
5494
  const resume = recordValue(result.checkpointContract?.resume);
5348
5495
  return nonEmptyString(resume?.continue_with_stage);
@@ -5867,6 +6014,28 @@ function checkpointResponseContinuation(state, value) {
5867
6014
  const assessment = proofAssessmentPayloadFromCheckpointResponse(response);
5868
6015
  if (assessment) {
5869
6016
  appendCheckpointResponse(state, response);
6017
+ if (state.request.ship_mode !== "ship" && proofAssessmentRequestsShip(assessment)) {
6018
+ const result = {
6019
+ ok: true,
6020
+ state_path: state.request.engine_state_path || packet.state_path || "",
6021
+ checkpoint: packet.checkpoint,
6022
+ stage: packet.stage,
6023
+ summary: response.summary,
6024
+ checkpointContract: checkpointContractFromPacket(packet) || null
6025
+ };
6026
+ return {
6027
+ terminal: terminalResult(
6028
+ state,
6029
+ "ready_to_ship",
6030
+ result,
6031
+ response.summary || "Riddle Proof evidence is approved, but ship_mode=none is holding before PR/ship.",
6032
+ {
6033
+ ship_held: true,
6034
+ proof_assessment: assessment
6035
+ }
6036
+ )
6037
+ };
6038
+ }
5870
6039
  return { next: { ...base, proof_assessment_json: jsonParam(assessment) } };
5871
6040
  }
5872
6041
  if (response.decision === "blocked" || response.decision === "human_review") {
@@ -6117,6 +6286,9 @@ async function routeCheckpoint(request, state, result, agent, input) {
6117
6286
  }
6118
6287
  const next = stageCheckpointContinuation(result);
6119
6288
  if (next) {
6289
+ if (continuationRequestsShip(next) && effectiveShipMode(request, input.config) !== "ship") {
6290
+ return { terminal: shipHeldTerminal(state, result) };
6291
+ }
6120
6292
  recordEvent(state, {
6121
6293
  kind: "checkpoint.recovery_continuation",
6122
6294
  checkpoint,
@@ -6148,6 +6320,9 @@ async function routeCheckpoint(request, state, result, agent, input) {
6148
6320
  };
6149
6321
  }
6150
6322
  if (checkpoint === "ship_review") {
6323
+ if (effectiveShipMode(request, input.config) !== "ship") {
6324
+ return { terminal: shipHeldTerminal(state, result) };
6325
+ }
6151
6326
  return {
6152
6327
  terminal: terminalResult(state, "shipped", result, result.summary || "Riddle Proof shipped.")
6153
6328
  };
@@ -6183,9 +6358,7 @@ async function routeCheckpoint(request, state, result, agent, input) {
6183
6358
  return { next: { ...baseContinuation(result), ship_after_verify: true } };
6184
6359
  }
6185
6360
  return {
6186
- terminal: terminalResult(state, "ready_to_ship", result, result.summary || "Riddle Proof evidence is approved, but ship_mode=none is holding before PR/ship.", {
6187
- ship_held: true
6188
- })
6361
+ terminal: shipHeldTerminal(state, result)
6189
6362
  };
6190
6363
  }
6191
6364
  if (checkpoint === "verify_audit_complete") {
@@ -6476,18 +6649,19 @@ async function routeCheckpoint(request, state, result, agent, input) {
6476
6649
  const next = recommendedContinuation(result) || defaultAwaitingStageContinuation(result);
6477
6650
  if (next) {
6478
6651
  if (String(next.advance_stage || "") === "ship" && effectiveShipMode(request, input.config) !== "ship") {
6479
- return {
6480
- terminal: terminalResult(state, "ready_to_ship", result, result.summary || "Riddle Proof evidence is approved, but ship_mode=none is holding before PR/ship.", {
6481
- ship_held: true
6482
- })
6483
- };
6652
+ return { terminal: shipHeldTerminal(state, result) };
6484
6653
  }
6485
6654
  return { next };
6486
6655
  }
6487
6656
  }
6488
6657
  if (checkpoint.endsWith("_review")) {
6489
6658
  const next = recommendedContinuation(result);
6490
- if (next) return { next };
6659
+ if (next) {
6660
+ if (continuationRequestsShip(next) && effectiveShipMode(request, input.config) !== "ship") {
6661
+ return { terminal: shipHeldTerminal(state, result) };
6662
+ }
6663
+ return { next };
6664
+ }
6491
6665
  }
6492
6666
  return {
6493
6667
  blocker: {
@@ -6513,6 +6687,9 @@ async function runRiddleProofEngineHarness(input) {
6513
6687
  if (checkpointContinuation.blocker) {
6514
6688
  return blockerResult(state, null, checkpointContinuation.blocker);
6515
6689
  }
6690
+ if (checkpointContinuation.terminal) {
6691
+ return checkpointContinuation.terminal;
6692
+ }
6516
6693
  const request = state.request;
6517
6694
  const agent = input.agent || createDisabledRiddleProofAgentAdapter();
6518
6695
  const maxIterations = Math.max(
@@ -1,5 +1,5 @@
1
1
  export { b as runner } from '../runner-4LJ5z0D-.cjs';
2
2
  export { l as engineHarness } from '../engine-harness-LBfqbFSe.cjs';
3
- export { p as proofRunCore } from '../proof-run-core-C8FDUhle.cjs';
4
- export { p as proofRunEngine } from '../proof-run-engine-D80hVFMf.cjs';
3
+ export { p as proofRunCore } from '../proof-run-core-B1GeqkR8.cjs';
4
+ export { p as proofRunEngine } from '../proof-run-engine-4dM37pEx.cjs';
5
5
  import '../types.cjs';
@@ -1,5 +1,5 @@
1
1
  export { b as runner } from '../runner-BdQpOkZD.js';
2
2
  export { l as engineHarness } from '../engine-harness-CMACHP6A.js';
3
- export { p as proofRunCore } from '../proof-run-core-C8FDUhle.js';
4
- export { p as proofRunEngine } from '../proof-run-engine-By7oLsF-.js';
3
+ export { p as proofRunCore } from '../proof-run-core-B1GeqkR8.js';
4
+ export { p as proofRunEngine } from '../proof-run-engine-BqaeqAze.js';
5
5
  import '../types.js';
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  proof_run_engine_exports
3
- } from "../chunk-YC77HZVF.js";
3
+ } from "../chunk-IOI6QR3B.js";
4
4
  import {
5
5
  runner_exports
6
- } from "../chunk-3OTO7IDH.js";
6
+ } from "../chunk-C2NHHBFV.js";
7
7
  import {
8
8
  engine_harness_exports
9
- } from "../chunk-AM3K5FPW.js";
9
+ } from "../chunk-ZREWMTFA.js";
10
10
  import "../chunk-ZQWVXQKJ.js";
11
11
  import "../chunk-RDPG554T.js";
12
12
  import {
13
13
  proof_run_core_exports
14
- } from "../chunk-K6HZUSHH.js";
14
+ } from "../chunk-X7SQTCIQ.js";
15
15
  import "../chunk-OILKSY5J.js";
16
16
  import "../chunk-VY4Y5U57.js";
17
17
  import "../chunk-MLKGABMK.js";
@@ -203,6 +203,7 @@ function buildSetupArgs(params, config) {
203
203
  discord_thread_id: params.discord_thread_id || "",
204
204
  discord_message_id: params.discord_message_id || "",
205
205
  discord_source_url: params.discord_source_url || "",
206
+ ship_mode: params.ship_mode || "",
206
207
  leave_draft: params.leave_draft ? "true" : ""
207
208
  };
208
209
  }
@@ -974,7 +975,8 @@ function mergeStateFromParams(statePath, params) {
974
975
  "auth_headers_json",
975
976
  "proof_plan",
976
977
  "implementation_notes",
977
- "implementation_mode"
978
+ "implementation_mode",
979
+ "ship_mode"
978
980
  ];
979
981
  for (const field of stringFields) {
980
982
  if (params[field] !== void 0) {