@riddledc/riddle-proof 0.8.11 → 0.8.13

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 (44) hide show
  1. package/dist/advanced/engine-harness.cjs +97 -12
  2. package/dist/advanced/engine-harness.js +2 -2
  3. package/dist/advanced/index.cjs +98 -12
  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 +31 -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 +3 -1
  11. package/dist/advanced/proof-run-engine.cjs +46 -12
  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-5N5QFI2S.js → chunk-7GZY5PLT.js} +31 -1
  17. package/dist/{chunk-46DDSZJR.js → chunk-JBY2SU5U.js} +18 -12
  18. package/dist/{chunk-5N6MQCLC.js → chunk-NGX4SUQN.js} +1 -1
  19. package/dist/{chunk-BBUO7HM4.js → chunk-RTLA6CPP.js} +53 -1
  20. package/dist/{chunk-2PXL3RDB.js → chunk-SZUC4MDN.js} +1 -1
  21. package/dist/cli/index.js +3 -3
  22. package/dist/cli.cjs +97 -12
  23. package/dist/cli.js +3 -3
  24. package/dist/engine-harness.cjs +97 -12
  25. package/dist/engine-harness.js +2 -2
  26. package/dist/index.cjs +97 -12
  27. package/dist/index.js +3 -3
  28. package/dist/{proof-run-core-CE0jx7wL.d.cts → proof-run-core-C8FDUhle.d.cts} +5 -2
  29. package/dist/{proof-run-core-CE0jx7wL.d.ts → proof-run-core-C8FDUhle.d.ts} +5 -2
  30. package/dist/proof-run-core.cjs +31 -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 +3 -1
  34. package/dist/{proof-run-engine-BomAcXhA.d.ts → proof-run-engine-By7oLsF-.d.ts} +1 -1
  35. package/dist/{proof-run-engine-B7DCPzpK.d.cts → proof-run-engine-D80hVFMf.d.cts} +1 -1
  36. package/dist/proof-run-engine.cjs +46 -12
  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/package.json +1 -1
  42. package/runtime/lib/verify.py +266 -22
  43. package/runtime/tests/recon_verify_smoke.py +291 -4
  44. package/runtime/tests/trust_boundary_regression.py +18 -0
@@ -471,6 +471,25 @@ function visualDeltaShipGateReason(state = {}) {
471
471
  if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
472
472
  return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
473
473
  }
474
+ function proofAssessmentHardBlockersForState(state = {}) {
475
+ const request = objectValue(state?.proof_assessment_request);
476
+ const blockers = [];
477
+ const add = (value) => {
478
+ if (typeof value !== "string") return;
479
+ const trimmed = value.trim();
480
+ if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
481
+ };
482
+ if (Array.isArray(request.hard_blockers)) {
483
+ for (const blocker of request.hard_blockers) add(blocker);
484
+ }
485
+ add(state?.structured_interaction_capture_failure_summary);
486
+ add(state?.structured_interaction_failure_summary);
487
+ const mergeRecommendation = String(state?.merge_recommendation || "").trim();
488
+ if (mergeRecommendation === "do-not-merge" && blockers.length) {
489
+ add("merge_recommendation=do-not-merge because the proof bundle contains hard blockers.");
490
+ }
491
+ return blockers;
492
+ }
474
493
  function visualDeltaEvidenceIssueCode(state = {}, blocker = "") {
475
494
  const visualDelta = visualDeltaForState(state || {});
476
495
  const status = String(visualDelta.status || "").trim();
@@ -505,6 +524,7 @@ function validateShipGate(state = {}) {
505
524
  const visualDelta = visualDeltaForState(state);
506
525
  const visualDeltaRequired = visualDeltaRequiredForState(state);
507
526
  const visualDeltaBlocker = visualDeltaShipGateReason(state);
527
+ const hardBlockers = proofAssessmentHardBlockersForState(state);
508
528
  const reasons = [];
509
529
  if (!["before", "prod", "both"].includes(reference)) {
510
530
  reasons.push(`reference must be before, prod, or both; got ${reference}`);
@@ -536,6 +556,9 @@ function validateShipGate(state = {}) {
536
556
  if (visualDeltaBlocker) {
537
557
  reasons.push(visualDeltaBlocker);
538
558
  }
559
+ for (const blocker of hardBlockers) {
560
+ reasons.push(`proof hard blocker prevents ready_to_ship: ${blocker}`);
561
+ }
539
562
  return {
540
563
  ok: reasons.length === 0,
541
564
  reasons,
@@ -552,7 +575,8 @@ function validateShipGate(state = {}) {
552
575
  proof_assessment_source: proofAssessment.source,
553
576
  visual_delta_required: visualDeltaRequired,
554
577
  visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
555
- visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
578
+ visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null,
579
+ hard_blockers: hardBlockers
556
580
  }
557
581
  };
558
582
  }
@@ -1038,6 +1062,10 @@ var init_proof_run_core = __esm({
1038
1062
  }],
1039
1063
  required_state: ["verify_decision_request"]
1040
1064
  },
1065
+ verify_capture_blocked: {
1066
+ purpose: "Verify capture produced conclusive failed browser evidence and should stop instead of retrying proof authoring.",
1067
+ required_state: ["verify_decision_request"]
1068
+ },
1041
1069
  verify_supervisor_judgment: {
1042
1070
  purpose: "Supervising agent judges whether captured evidence proves the change is ready to ship.",
1043
1071
  accepted_inputs: [{
@@ -1286,14 +1314,18 @@ function verifyAssessment(state) {
1286
1314
  };
1287
1315
  }
1288
1316
  if (state?.verify_status === "capture_incomplete") {
1317
+ const captureQuality = verifyDecision?.capture_quality || {};
1318
+ const terminalBlocker = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
1319
+ const recommendedStage = terminalBlocker ? null : verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author";
1320
+ const continueWithStage = terminalBlocker ? null : verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author";
1289
1321
  return {
1290
- decision: verifyDecision?.capture_quality?.decision || "revise_capture",
1322
+ decision: captureQuality?.decision || "revise_capture",
1291
1323
  summary: verifyDecision?.summary || "Verify needs another internal capture iteration before the evidence can be judged.",
1292
- recommendedStage: verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author",
1293
- continueWithStage: verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author",
1324
+ recommendedStage,
1325
+ continueWithStage,
1294
1326
  escalationTarget: "agent",
1295
- reasons: Array.isArray(verifyDecision?.capture_quality?.reasons) ? verifyDecision.capture_quality.reasons : [],
1296
- raw: verifyDecision?.capture_quality || verifyDecision,
1327
+ reasons: Array.isArray(captureQuality?.reasons) ? captureQuality.reasons : [],
1328
+ raw: captureQuality || verifyDecision,
1297
1329
  source: "workflow_capture"
1298
1330
  };
1299
1331
  }
@@ -2513,7 +2545,9 @@ ${implementRes.stderr || ""}`;
2513
2545
  convergenceSignals
2514
2546
  };
2515
2547
  if (verifyStatus !== "evidence_captured") {
2516
- if ((verifyContinueWithStage || verifyRecommendedStage || "author") === "author") {
2548
+ const captureQuality = verifyDecisionRequest?.capture_quality || {};
2549
+ const captureTerminalBlocker = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
2550
+ if (!captureTerminalBlocker && (verifyContinueWithStage || verifyRecommendedStage || "author") === "author") {
2517
2551
  updateState(config.statePath, (currentState) => {
2518
2552
  currentState.author_status = "needs_authoring";
2519
2553
  currentState.proof_plan_status = "needs_authoring";
@@ -2521,7 +2555,7 @@ ${implementRes.stderr || ""}`;
2521
2555
  });
2522
2556
  state = readState(config.statePath);
2523
2557
  }
2524
- const checkpointName = "verify_capture_retry";
2558
+ const checkpointName = captureTerminalBlocker ? "verify_capture_blocked" : "verify_capture_retry";
2525
2559
  const summary = stringValue(proofAssessment.summary) || "Verify ran, but the proof packet still needs internal capture-plan work before it should ship.";
2526
2560
  recordAttempt("verify", "checkpoint", summary, {
2527
2561
  autoApproved: verifyRes.autoApproved || false,
@@ -2534,11 +2568,11 @@ ${implementRes.stderr || ""}`;
2534
2568
  summary,
2535
2569
  {
2536
2570
  ok: true,
2537
- nextActions: ["inspect_after_capture", "continue_internal_loop_with_checkpoint", "return_to_recon_if_baseline_is_wrong"],
2571
+ 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"],
2538
2572
  advanceOptions: verifyLoopAdvanceOptions,
2539
- recommendedAdvanceStage: verifyRecommendedStage || "author",
2540
- continueWithStage: verifyContinueWithStage || "author",
2541
- blocking: false,
2573
+ recommendedAdvanceStage: captureTerminalBlocker ? null : verifyRecommendedStage || "author",
2574
+ continueWithStage: captureTerminalBlocker ? null : verifyContinueWithStage || "author",
2575
+ blocking: captureTerminalBlocker,
2542
2576
  details: verifyDetails,
2543
2577
  verifyStatus,
2544
2578
  verifySummary,
@@ -4604,6 +4638,17 @@ function proofAssessmentRequestsShip(payload) {
4604
4638
  const continueStage = String(payload.continue_with_stage || "");
4605
4639
  return decision === "ready_to_ship" || recommendedStage === "ship" || continueStage === "ship";
4606
4640
  }
4641
+ function proofAssessmentHardBlockers(state, payload) {
4642
+ const blockers = proofAssessmentHardBlockersForState(state || {});
4643
+ if (Array.isArray(payload.hard_blockers)) {
4644
+ for (const blocker of payload.hard_blockers) {
4645
+ if (typeof blocker !== "string") continue;
4646
+ const trimmed = blocker.trim();
4647
+ if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
4648
+ }
4649
+ }
4650
+ return blockers;
4651
+ }
4607
4652
  function proofAssessmentContinuation(result, payload) {
4608
4653
  const proof_assessment_json = jsonParam(payload);
4609
4654
  return { ...baseContinuation(result), proof_assessment_json };
@@ -5543,6 +5588,33 @@ async function routeCheckpoint(request, state, result, agent, input) {
5543
5588
  adapter_details: assessment.details || null
5544
5589
  })
5545
5590
  });
5591
+ const hardBlockers = proofAssessmentHardBlockers(context.fullRiddleState || {}, payload);
5592
+ if (proofAssessmentRequestsShip(payload) && hardBlockers.length) {
5593
+ const summary = hardBlockers[0];
5594
+ recordEvent(state, {
5595
+ kind: "agent.proof_assessment.hard_blocked",
5596
+ checkpoint,
5597
+ stage: "verify",
5598
+ summary,
5599
+ details: compactRecord({
5600
+ hard_blockers: hardBlockers,
5601
+ proof_assessment: payload,
5602
+ agent_duration_ms: durationMs
5603
+ })
5604
+ });
5605
+ return {
5606
+ blocker: {
5607
+ code: "proof_hard_blocker",
5608
+ checkpoint,
5609
+ message: "Riddle Proof cannot mark ready_to_ship while the proof bundle contains a hard blocker: " + summary,
5610
+ details: compactRecord({
5611
+ hard_blockers: hardBlockers,
5612
+ proofAssessment: payload,
5613
+ verifyDecisionRequest: context.fullRiddleState?.verify_decision_request || result.verifyDecisionRequest || result.checkpointContract?.verify_decision_request || null
5614
+ })
5615
+ }
5616
+ };
5617
+ }
5546
5618
  const visualBlocker = proofAssessmentVisualBlocker({
5547
5619
  ...context.fullRiddleState || {},
5548
5620
  verification_mode: context.fullRiddleState?.verification_mode || request.verification_mode
@@ -5600,6 +5672,19 @@ async function routeCheckpoint(request, state, result, agent, input) {
5600
5672
  }
5601
5673
  };
5602
5674
  }
5675
+ if (checkpoint === "verify_capture_blocked") {
5676
+ return {
5677
+ blocker: {
5678
+ code: "verify_capture_blocked",
5679
+ checkpoint,
5680
+ message: result.summary || "Verify captured conclusive failed browser evidence and stopped instead of retrying proof authoring.",
5681
+ details: compactRecord({
5682
+ verifyDecisionRequest: result.verifyDecisionRequest || result.checkpointContract?.verify_decision_request || null,
5683
+ checkpointContract: result.checkpointContract || null
5684
+ })
5685
+ }
5686
+ };
5687
+ }
5603
5688
  if (checkpoint === "awaiting_stage_advance") {
5604
5689
  const next = recommendedContinuation(result) || defaultAwaitingStageContinuation(result);
5605
5690
  if (next) {
@@ -2,10 +2,10 @@ import {
2
2
  createDisabledRiddleProofAgentAdapter,
3
3
  readRiddleProofRunStatus,
4
4
  runRiddleProofEngineHarness
5
- } from "../chunk-BBUO7HM4.js";
5
+ } from "../chunk-RTLA6CPP.js";
6
6
  import "../chunk-YZUVEJ5B.js";
7
7
  import "../chunk-FMOYUYH2.js";
8
- import "../chunk-5N5QFI2S.js";
8
+ import "../chunk-7GZY5PLT.js";
9
9
  import "../chunk-4FOHZ7JG.js";
10
10
  import "../chunk-VY4Y5U57.js";
11
11
  import "../chunk-MLKGABMK.js";
@@ -47,6 +47,7 @@ __export(proof_run_core_exports, {
47
47
  mergeStateFromParams: () => mergeStateFromParams,
48
48
  noImplementationModeFor: () => noImplementationModeFor,
49
49
  previewModeFromWorkflowMode: () => previewModeFromWorkflowMode,
50
+ proofAssessmentHardBlockersForState: () => proofAssessmentHardBlockersForState,
50
51
  readState: () => readState,
51
52
  recordStageAttempt: () => recordStageAttempt,
52
53
  requiredBaselineLabelsForState: () => requiredBaselineLabelsForState,
@@ -501,6 +502,25 @@ function visualDeltaShipGateReason(state = {}) {
501
502
  if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
502
503
  return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
503
504
  }
505
+ function proofAssessmentHardBlockersForState(state = {}) {
506
+ const request = objectValue(state?.proof_assessment_request);
507
+ const blockers = [];
508
+ const add = (value) => {
509
+ if (typeof value !== "string") return;
510
+ const trimmed = value.trim();
511
+ if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
512
+ };
513
+ if (Array.isArray(request.hard_blockers)) {
514
+ for (const blocker of request.hard_blockers) add(blocker);
515
+ }
516
+ add(state?.structured_interaction_capture_failure_summary);
517
+ add(state?.structured_interaction_failure_summary);
518
+ const mergeRecommendation = String(state?.merge_recommendation || "").trim();
519
+ if (mergeRecommendation === "do-not-merge" && blockers.length) {
520
+ add("merge_recommendation=do-not-merge because the proof bundle contains hard blockers.");
521
+ }
522
+ return blockers;
523
+ }
504
524
  function visualDeltaEvidenceIssueCode(state = {}, blocker = "") {
505
525
  const visualDelta = visualDeltaForState(state || {});
506
526
  const status = String(visualDelta.status || "").trim();
@@ -535,6 +555,7 @@ function validateShipGate(state = {}) {
535
555
  const visualDelta = visualDeltaForState(state);
536
556
  const visualDeltaRequired = visualDeltaRequiredForState(state);
537
557
  const visualDeltaBlocker = visualDeltaShipGateReason(state);
558
+ const hardBlockers = proofAssessmentHardBlockersForState(state);
538
559
  const reasons = [];
539
560
  if (!["before", "prod", "both"].includes(reference)) {
540
561
  reasons.push(`reference must be before, prod, or both; got ${reference}`);
@@ -566,6 +587,9 @@ function validateShipGate(state = {}) {
566
587
  if (visualDeltaBlocker) {
567
588
  reasons.push(visualDeltaBlocker);
568
589
  }
590
+ for (const blocker of hardBlockers) {
591
+ reasons.push(`proof hard blocker prevents ready_to_ship: ${blocker}`);
592
+ }
569
593
  return {
570
594
  ok: reasons.length === 0,
571
595
  reasons,
@@ -582,7 +606,8 @@ function validateShipGate(state = {}) {
582
606
  proof_assessment_source: proofAssessment.source,
583
607
  visual_delta_required: visualDeltaRequired,
584
608
  visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
585
- visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
609
+ visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null,
610
+ hard_blockers: hardBlockers
586
611
  }
587
612
  };
588
613
  }
@@ -1068,6 +1093,10 @@ var init_proof_run_core = __esm({
1068
1093
  }],
1069
1094
  required_state: ["verify_decision_request"]
1070
1095
  },
1096
+ verify_capture_blocked: {
1097
+ purpose: "Verify capture produced conclusive failed browser evidence and should stop instead of retrying proof authoring.",
1098
+ required_state: ["verify_decision_request"]
1099
+ },
1071
1100
  verify_supervisor_judgment: {
1072
1101
  purpose: "Supervising agent judges whether captured evidence proves the change is ready to ship.",
1073
1102
  accepted_inputs: [{
@@ -1316,14 +1345,18 @@ function verifyAssessment(state) {
1316
1345
  };
1317
1346
  }
1318
1347
  if (state?.verify_status === "capture_incomplete") {
1348
+ const captureQuality = verifyDecision?.capture_quality || {};
1349
+ const terminalBlocker = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
1350
+ const recommendedStage = terminalBlocker ? null : verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author";
1351
+ const continueWithStage = terminalBlocker ? null : verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author";
1319
1352
  return {
1320
- decision: verifyDecision?.capture_quality?.decision || "revise_capture",
1353
+ decision: captureQuality?.decision || "revise_capture",
1321
1354
  summary: verifyDecision?.summary || "Verify needs another internal capture iteration before the evidence can be judged.",
1322
- recommendedStage: verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author",
1323
- continueWithStage: verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author",
1355
+ recommendedStage,
1356
+ continueWithStage,
1324
1357
  escalationTarget: "agent",
1325
- reasons: Array.isArray(verifyDecision?.capture_quality?.reasons) ? verifyDecision.capture_quality.reasons : [],
1326
- raw: verifyDecision?.capture_quality || verifyDecision,
1358
+ reasons: Array.isArray(captureQuality?.reasons) ? captureQuality.reasons : [],
1359
+ raw: captureQuality || verifyDecision,
1327
1360
  source: "workflow_capture"
1328
1361
  };
1329
1362
  }
@@ -2543,7 +2576,9 @@ ${implementRes.stderr || ""}`;
2543
2576
  convergenceSignals
2544
2577
  };
2545
2578
  if (verifyStatus !== "evidence_captured") {
2546
- if ((verifyContinueWithStage || verifyRecommendedStage || "author") === "author") {
2579
+ const captureQuality = verifyDecisionRequest?.capture_quality || {};
2580
+ const captureTerminalBlocker = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
2581
+ if (!captureTerminalBlocker && (verifyContinueWithStage || verifyRecommendedStage || "author") === "author") {
2547
2582
  updateState(config.statePath, (currentState) => {
2548
2583
  currentState.author_status = "needs_authoring";
2549
2584
  currentState.proof_plan_status = "needs_authoring";
@@ -2551,7 +2586,7 @@ ${implementRes.stderr || ""}`;
2551
2586
  });
2552
2587
  state = readState(config.statePath);
2553
2588
  }
2554
- const checkpointName = "verify_capture_retry";
2589
+ const checkpointName = captureTerminalBlocker ? "verify_capture_blocked" : "verify_capture_retry";
2555
2590
  const summary = stringValue(proofAssessment.summary) || "Verify ran, but the proof packet still needs internal capture-plan work before it should ship.";
2556
2591
  recordAttempt("verify", "checkpoint", summary, {
2557
2592
  autoApproved: verifyRes.autoApproved || false,
@@ -2564,11 +2599,11 @@ ${implementRes.stderr || ""}`;
2564
2599
  summary,
2565
2600
  {
2566
2601
  ok: true,
2567
- nextActions: ["inspect_after_capture", "continue_internal_loop_with_checkpoint", "return_to_recon_if_baseline_is_wrong"],
2602
+ 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"],
2568
2603
  advanceOptions: verifyLoopAdvanceOptions,
2569
- recommendedAdvanceStage: verifyRecommendedStage || "author",
2570
- continueWithStage: verifyContinueWithStage || "author",
2571
- blocking: false,
2604
+ recommendedAdvanceStage: captureTerminalBlocker ? null : verifyRecommendedStage || "author",
2605
+ continueWithStage: captureTerminalBlocker ? null : verifyContinueWithStage || "author",
2606
+ blocking: captureTerminalBlocker,
2572
2607
  details: verifyDetails,
2573
2608
  verifyStatus,
2574
2609
  verifySummary,
@@ -5140,6 +5175,17 @@ function proofAssessmentRequestsShip(payload) {
5140
5175
  const continueStage = String(payload.continue_with_stage || "");
5141
5176
  return decision === "ready_to_ship" || recommendedStage === "ship" || continueStage === "ship";
5142
5177
  }
5178
+ function proofAssessmentHardBlockers(state, payload) {
5179
+ const blockers = proofAssessmentHardBlockersForState(state || {});
5180
+ if (Array.isArray(payload.hard_blockers)) {
5181
+ for (const blocker of payload.hard_blockers) {
5182
+ if (typeof blocker !== "string") continue;
5183
+ const trimmed = blocker.trim();
5184
+ if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
5185
+ }
5186
+ }
5187
+ return blockers;
5188
+ }
5143
5189
  function proofAssessmentContinuation(result, payload) {
5144
5190
  const proof_assessment_json = jsonParam(payload);
5145
5191
  return { ...baseContinuation(result), proof_assessment_json };
@@ -6079,6 +6125,33 @@ async function routeCheckpoint(request, state, result, agent, input) {
6079
6125
  adapter_details: assessment.details || null
6080
6126
  })
6081
6127
  });
6128
+ const hardBlockers = proofAssessmentHardBlockers(context.fullRiddleState || {}, payload);
6129
+ if (proofAssessmentRequestsShip(payload) && hardBlockers.length) {
6130
+ const summary = hardBlockers[0];
6131
+ recordEvent(state, {
6132
+ kind: "agent.proof_assessment.hard_blocked",
6133
+ checkpoint,
6134
+ stage: "verify",
6135
+ summary,
6136
+ details: compactRecord({
6137
+ hard_blockers: hardBlockers,
6138
+ proof_assessment: payload,
6139
+ agent_duration_ms: durationMs
6140
+ })
6141
+ });
6142
+ return {
6143
+ blocker: {
6144
+ code: "proof_hard_blocker",
6145
+ checkpoint,
6146
+ message: "Riddle Proof cannot mark ready_to_ship while the proof bundle contains a hard blocker: " + summary,
6147
+ details: compactRecord({
6148
+ hard_blockers: hardBlockers,
6149
+ proofAssessment: payload,
6150
+ verifyDecisionRequest: context.fullRiddleState?.verify_decision_request || result.verifyDecisionRequest || result.checkpointContract?.verify_decision_request || null
6151
+ })
6152
+ }
6153
+ };
6154
+ }
6082
6155
  const visualBlocker = proofAssessmentVisualBlocker({
6083
6156
  ...context.fullRiddleState || {},
6084
6157
  verification_mode: context.fullRiddleState?.verification_mode || request.verification_mode
@@ -6136,6 +6209,19 @@ async function routeCheckpoint(request, state, result, agent, input) {
6136
6209
  }
6137
6210
  };
6138
6211
  }
6212
+ if (checkpoint === "verify_capture_blocked") {
6213
+ return {
6214
+ blocker: {
6215
+ code: "verify_capture_blocked",
6216
+ checkpoint,
6217
+ message: result.summary || "Verify captured conclusive failed browser evidence and stopped instead of retrying proof authoring.",
6218
+ details: compactRecord({
6219
+ verifyDecisionRequest: result.verifyDecisionRequest || result.checkpointContract?.verify_decision_request || null,
6220
+ checkpointContract: result.checkpointContract || null
6221
+ })
6222
+ }
6223
+ };
6224
+ }
6139
6225
  if (checkpoint === "awaiting_stage_advance") {
6140
6226
  const next = recommendedContinuation(result) || defaultAwaitingStageContinuation(result);
6141
6227
  if (next) {
@@ -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-CE0jx7wL.cjs';
4
- export { p as proofRunEngine } from '../proof-run-engine-B7DCPzpK.cjs';
3
+ export { p as proofRunCore } from '../proof-run-core-C8FDUhle.cjs';
4
+ export { p as proofRunEngine } from '../proof-run-engine-D80hVFMf.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-CE0jx7wL.js';
4
- export { p as proofRunEngine } from '../proof-run-engine-BomAcXhA.js';
3
+ export { p as proofRunCore } from '../proof-run-core-C8FDUhle.js';
4
+ export { p as proofRunEngine } from '../proof-run-engine-By7oLsF-.js';
5
5
  import '../types.js';
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  proof_run_engine_exports
3
- } from "../chunk-46DDSZJR.js";
3
+ } from "../chunk-JBY2SU5U.js";
4
4
  import {
5
5
  runner_exports
6
- } from "../chunk-5N6MQCLC.js";
6
+ } from "../chunk-NGX4SUQN.js";
7
7
  import {
8
8
  engine_harness_exports
9
- } from "../chunk-BBUO7HM4.js";
9
+ } from "../chunk-RTLA6CPP.js";
10
10
  import "../chunk-YZUVEJ5B.js";
11
11
  import "../chunk-FMOYUYH2.js";
12
12
  import {
13
13
  proof_run_core_exports
14
- } from "../chunk-5N5QFI2S.js";
14
+ } from "../chunk-7GZY5PLT.js";
15
15
  import "../chunk-4FOHZ7JG.js";
16
16
  import "../chunk-VY4Y5U57.js";
17
17
  import "../chunk-MLKGABMK.js";
@@ -44,6 +44,7 @@ __export(proof_run_core_exports, {
44
44
  mergeStateFromParams: () => mergeStateFromParams,
45
45
  noImplementationModeFor: () => noImplementationModeFor,
46
46
  previewModeFromWorkflowMode: () => previewModeFromWorkflowMode,
47
+ proofAssessmentHardBlockersForState: () => proofAssessmentHardBlockersForState,
47
48
  readState: () => readState,
48
49
  recordStageAttempt: () => recordStageAttempt,
49
50
  requiredBaselineLabelsForState: () => requiredBaselineLabelsForState,
@@ -527,6 +528,25 @@ function visualDeltaShipGateReason(state = {}) {
527
528
  if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
528
529
  return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
529
530
  }
531
+ function proofAssessmentHardBlockersForState(state = {}) {
532
+ const request = objectValue(state?.proof_assessment_request);
533
+ const blockers = [];
534
+ const add = (value) => {
535
+ if (typeof value !== "string") return;
536
+ const trimmed = value.trim();
537
+ if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
538
+ };
539
+ if (Array.isArray(request.hard_blockers)) {
540
+ for (const blocker of request.hard_blockers) add(blocker);
541
+ }
542
+ add(state?.structured_interaction_capture_failure_summary);
543
+ add(state?.structured_interaction_failure_summary);
544
+ const mergeRecommendation = String(state?.merge_recommendation || "").trim();
545
+ if (mergeRecommendation === "do-not-merge" && blockers.length) {
546
+ add("merge_recommendation=do-not-merge because the proof bundle contains hard blockers.");
547
+ }
548
+ return blockers;
549
+ }
530
550
  function visualDeltaEvidenceIssueCode(state = {}, blocker = "") {
531
551
  const visualDelta = visualDeltaForState(state || {});
532
552
  const status = String(visualDelta.status || "").trim();
@@ -561,6 +581,7 @@ function validateShipGate(state = {}) {
561
581
  const visualDelta = visualDeltaForState(state);
562
582
  const visualDeltaRequired = visualDeltaRequiredForState(state);
563
583
  const visualDeltaBlocker = visualDeltaShipGateReason(state);
584
+ const hardBlockers = proofAssessmentHardBlockersForState(state);
564
585
  const reasons = [];
565
586
  if (!["before", "prod", "both"].includes(reference)) {
566
587
  reasons.push(`reference must be before, prod, or both; got ${reference}`);
@@ -592,6 +613,9 @@ function validateShipGate(state = {}) {
592
613
  if (visualDeltaBlocker) {
593
614
  reasons.push(visualDeltaBlocker);
594
615
  }
616
+ for (const blocker of hardBlockers) {
617
+ reasons.push(`proof hard blocker prevents ready_to_ship: ${blocker}`);
618
+ }
595
619
  return {
596
620
  ok: reasons.length === 0,
597
621
  reasons,
@@ -608,7 +632,8 @@ function validateShipGate(state = {}) {
608
632
  proof_assessment_source: proofAssessment.source,
609
633
  visual_delta_required: visualDeltaRequired,
610
634
  visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
611
- visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
635
+ visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null,
636
+ hard_blockers: hardBlockers
612
637
  }
613
638
  };
614
639
  }
@@ -722,6 +747,10 @@ var CHECKPOINT_CONTRACT_SPECS = {
722
747
  }],
723
748
  required_state: ["verify_decision_request"]
724
749
  },
750
+ verify_capture_blocked: {
751
+ purpose: "Verify capture produced conclusive failed browser evidence and should stop instead of retrying proof authoring.",
752
+ required_state: ["verify_decision_request"]
753
+ },
725
754
  verify_supervisor_judgment: {
726
755
  purpose: "Supervising agent judges whether captured evidence proves the change is ready to ship.",
727
756
  accepted_inputs: [{
@@ -1138,6 +1167,7 @@ function summarizeState(state) {
1138
1167
  mergeStateFromParams,
1139
1168
  noImplementationModeFor,
1140
1169
  previewModeFromWorkflowMode,
1170
+ proofAssessmentHardBlockersForState,
1141
1171
  readState,
1142
1172
  recordStageAttempt,
1143
1173
  requiredBaselineLabelsForState,
@@ -1 +1 @@
1
- export { B as BUNDLED_RIDDLE_PROOF_DIR, C as CHECKPOINT_CONTRACT_VERSION, b as CheckpointInputContract, P as PluginConfig, R as RIDDLE_PROOF_DIR_CANDIDATES, S as ShipGateValidation, c as WORKFLOW_STAGE_ORDER, d as WorkflowAction, W as WorkflowParams, a as WorkflowStage, e as buildCheckpointContract, f as buildSetupArgs, g as checkpointContinueStage, h as clearStageDecisionRequest, i as ensureAction, j as ensureStageLoopState, k as invalidateVerifyEvidence, m as mergeStateFromParams, n as noImplementationModeFor, l as previewModeFromWorkflowMode, o as readState, q as recordStageAttempt, s as requiredBaselineLabelsForState, r as resolveConfig, t as resolveRiddleProofDir, u as setStageDecisionRequest, v as summarizeState, w as validateShipGate, x as visualDeltaForState, y as visualDeltaRequiredForState, z as visualDeltaShipGateReason, A as workflowFile, D as writeState } from '../proof-run-core-CE0jx7wL.cjs';
1
+ export { B as BUNDLED_RIDDLE_PROOF_DIR, C as CHECKPOINT_CONTRACT_VERSION, b as CheckpointInputContract, P as PluginConfig, R as RIDDLE_PROOF_DIR_CANDIDATES, S as ShipGateValidation, c as WORKFLOW_STAGE_ORDER, d as WorkflowAction, W as WorkflowParams, a as WorkflowStage, e as buildCheckpointContract, f as buildSetupArgs, g as checkpointContinueStage, h as clearStageDecisionRequest, i as ensureAction, j as ensureStageLoopState, k as invalidateVerifyEvidence, m as mergeStateFromParams, n as noImplementationModeFor, l as previewModeFromWorkflowMode, o as proofAssessmentHardBlockersForState, q as readState, s as recordStageAttempt, t as requiredBaselineLabelsForState, r as resolveConfig, u as resolveRiddleProofDir, v as setStageDecisionRequest, w as summarizeState, x as validateShipGate, y as visualDeltaForState, z as visualDeltaRequiredForState, A as visualDeltaShipGateReason, D as workflowFile, E as writeState } from '../proof-run-core-C8FDUhle.cjs';
@@ -1 +1 @@
1
- export { B as BUNDLED_RIDDLE_PROOF_DIR, C as CHECKPOINT_CONTRACT_VERSION, b as CheckpointInputContract, P as PluginConfig, R as RIDDLE_PROOF_DIR_CANDIDATES, S as ShipGateValidation, c as WORKFLOW_STAGE_ORDER, d as WorkflowAction, W as WorkflowParams, a as WorkflowStage, e as buildCheckpointContract, f as buildSetupArgs, g as checkpointContinueStage, h as clearStageDecisionRequest, i as ensureAction, j as ensureStageLoopState, k as invalidateVerifyEvidence, m as mergeStateFromParams, n as noImplementationModeFor, l as previewModeFromWorkflowMode, o as readState, q as recordStageAttempt, s as requiredBaselineLabelsForState, r as resolveConfig, t as resolveRiddleProofDir, u as setStageDecisionRequest, v as summarizeState, w as validateShipGate, x as visualDeltaForState, y as visualDeltaRequiredForState, z as visualDeltaShipGateReason, A as workflowFile, D as writeState } from '../proof-run-core-CE0jx7wL.js';
1
+ export { B as BUNDLED_RIDDLE_PROOF_DIR, C as CHECKPOINT_CONTRACT_VERSION, b as CheckpointInputContract, P as PluginConfig, R as RIDDLE_PROOF_DIR_CANDIDATES, S as ShipGateValidation, c as WORKFLOW_STAGE_ORDER, d as WorkflowAction, W as WorkflowParams, a as WorkflowStage, e as buildCheckpointContract, f as buildSetupArgs, g as checkpointContinueStage, h as clearStageDecisionRequest, i as ensureAction, j as ensureStageLoopState, k as invalidateVerifyEvidence, m as mergeStateFromParams, n as noImplementationModeFor, l as previewModeFromWorkflowMode, o as proofAssessmentHardBlockersForState, q as readState, s as recordStageAttempt, t as requiredBaselineLabelsForState, r as resolveConfig, u as resolveRiddleProofDir, v as setStageDecisionRequest, w as summarizeState, x as validateShipGate, y as visualDeltaForState, z as visualDeltaRequiredForState, A as visualDeltaShipGateReason, D as workflowFile, E as writeState } from '../proof-run-core-C8FDUhle.js';
@@ -13,6 +13,7 @@ import {
13
13
  mergeStateFromParams,
14
14
  noImplementationModeFor,
15
15
  previewModeFromWorkflowMode,
16
+ proofAssessmentHardBlockersForState,
16
17
  readState,
17
18
  recordStageAttempt,
18
19
  requiredBaselineLabelsForState,
@@ -26,7 +27,7 @@ import {
26
27
  visualDeltaShipGateReason,
27
28
  workflowFile,
28
29
  writeState
29
- } from "../chunk-5N5QFI2S.js";
30
+ } from "../chunk-7GZY5PLT.js";
30
31
  import "../chunk-MLKGABMK.js";
31
32
  export {
32
33
  BUNDLED_RIDDLE_PROOF_DIR,
@@ -43,6 +44,7 @@ export {
43
44
  mergeStateFromParams,
44
45
  noImplementationModeFor,
45
46
  previewModeFromWorkflowMode,
47
+ proofAssessmentHardBlockersForState,
46
48
  readState,
47
49
  recordStageAttempt,
48
50
  requiredBaselineLabelsForState,