@riddledc/riddle-proof 0.8.11 → 0.8.12

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-CrpYH-qH.d.cts} +6 -3
  29. package/dist/{proof-run-core-CE0jx7wL.d.ts → proof-run-core-CrpYH-qH.d.ts} +6 -3
  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-B7DCPzpK.d.cts → proof-run-engine-C6vYAZd8.d.cts} +4 -4
  35. package/dist/{proof-run-engine-BomAcXhA.d.ts → proof-run-engine-h9C1lC0w.d.ts} +4 -4
  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 +97 -11
  43. package/runtime/tests/recon_verify_smoke.py +154 -4
  44. package/runtime/tests/trust_boundary_regression.py +12 -0
@@ -507,6 +507,25 @@ function visualDeltaShipGateReason(state = {}) {
507
507
  if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
508
508
  return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
509
509
  }
510
+ function proofAssessmentHardBlockersForState(state = {}) {
511
+ const request = objectValue(state?.proof_assessment_request);
512
+ const blockers = [];
513
+ const add = (value) => {
514
+ if (typeof value !== "string") return;
515
+ const trimmed = value.trim();
516
+ if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
517
+ };
518
+ if (Array.isArray(request.hard_blockers)) {
519
+ for (const blocker of request.hard_blockers) add(blocker);
520
+ }
521
+ add(state?.structured_interaction_capture_failure_summary);
522
+ add(state?.structured_interaction_failure_summary);
523
+ const mergeRecommendation = String(state?.merge_recommendation || "").trim();
524
+ if (mergeRecommendation === "do-not-merge" && blockers.length) {
525
+ add("merge_recommendation=do-not-merge because the proof bundle contains hard blockers.");
526
+ }
527
+ return blockers;
528
+ }
510
529
  function visualDeltaEvidenceIssueCode(state = {}, blocker = "") {
511
530
  const visualDelta = visualDeltaForState(state || {});
512
531
  const status = String(visualDelta.status || "").trim();
@@ -541,6 +560,7 @@ function validateShipGate(state = {}) {
541
560
  const visualDelta = visualDeltaForState(state);
542
561
  const visualDeltaRequired = visualDeltaRequiredForState(state);
543
562
  const visualDeltaBlocker = visualDeltaShipGateReason(state);
563
+ const hardBlockers = proofAssessmentHardBlockersForState(state);
544
564
  const reasons = [];
545
565
  if (!["before", "prod", "both"].includes(reference)) {
546
566
  reasons.push(`reference must be before, prod, or both; got ${reference}`);
@@ -572,6 +592,9 @@ function validateShipGate(state = {}) {
572
592
  if (visualDeltaBlocker) {
573
593
  reasons.push(visualDeltaBlocker);
574
594
  }
595
+ for (const blocker of hardBlockers) {
596
+ reasons.push(`proof hard blocker prevents ready_to_ship: ${blocker}`);
597
+ }
575
598
  return {
576
599
  ok: reasons.length === 0,
577
600
  reasons,
@@ -588,7 +611,8 @@ function validateShipGate(state = {}) {
588
611
  proof_assessment_source: proofAssessment.source,
589
612
  visual_delta_required: visualDeltaRequired,
590
613
  visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
591
- visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
614
+ visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null,
615
+ hard_blockers: hardBlockers
592
616
  }
593
617
  };
594
618
  }
@@ -702,6 +726,10 @@ var CHECKPOINT_CONTRACT_SPECS = {
702
726
  }],
703
727
  required_state: ["verify_decision_request"]
704
728
  },
729
+ verify_capture_blocked: {
730
+ purpose: "Verify capture produced conclusive failed browser evidence and should stop instead of retrying proof authoring.",
731
+ required_state: ["verify_decision_request"]
732
+ },
705
733
  verify_supervisor_judgment: {
706
734
  purpose: "Supervising agent judges whether captured evidence proves the change is ready to ship.",
707
735
  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,
@@ -1,2 +1,2 @@
1
- export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-B7DCPzpK.cjs';
2
- import '../proof-run-core-CE0jx7wL.cjs';
1
+ export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-C6vYAZd8.cjs';
2
+ import '../proof-run-core-CrpYH-qH.cjs';
@@ -1,2 +1,2 @@
1
- export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-BomAcXhA.js';
2
- import '../proof-run-core-CE0jx7wL.js';
1
+ export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-h9C1lC0w.js';
2
+ import '../proof-run-core-CrpYH-qH.js';
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createRiddleProofEngine,
3
3
  executeWorkflow
4
- } from "../chunk-46DDSZJR.js";
5
- import "../chunk-5N5QFI2S.js";
4
+ } from "../chunk-JBY2SU5U.js";
5
+ import "../chunk-7GZY5PLT.js";
6
6
  import "../chunk-MLKGABMK.js";
7
7
  export {
8
8
  createRiddleProofEngine,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runRiddleProof
3
- } from "../chunk-5N6MQCLC.js";
3
+ } from "../chunk-NGX4SUQN.js";
4
4
  import "../chunk-YZUVEJ5B.js";
5
5
  import "../chunk-FMOYUYH2.js";
6
- import "../chunk-5N5QFI2S.js";
6
+ import "../chunk-7GZY5PLT.js";
7
7
  import "../chunk-4FOHZ7JG.js";
8
8
  import "../chunk-VY4Y5U57.js";
9
9
  import "../chunk-MLKGABMK.js";
@@ -19,6 +19,7 @@ __export(proof_run_core_exports, {
19
19
  mergeStateFromParams: () => mergeStateFromParams,
20
20
  noImplementationModeFor: () => noImplementationModeFor,
21
21
  previewModeFromWorkflowMode: () => previewModeFromWorkflowMode,
22
+ proofAssessmentHardBlockersForState: () => proofAssessmentHardBlockersForState,
22
23
  readState: () => readState,
23
24
  recordStageAttempt: () => recordStageAttempt,
24
25
  requiredBaselineLabelsForState: () => requiredBaselineLabelsForState,
@@ -498,6 +499,25 @@ function visualDeltaShipGateReason(state = {}) {
498
499
  if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
499
500
  return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
500
501
  }
502
+ function proofAssessmentHardBlockersForState(state = {}) {
503
+ const request = objectValue(state?.proof_assessment_request);
504
+ const blockers = [];
505
+ const add = (value) => {
506
+ if (typeof value !== "string") return;
507
+ const trimmed = value.trim();
508
+ if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
509
+ };
510
+ if (Array.isArray(request.hard_blockers)) {
511
+ for (const blocker of request.hard_blockers) add(blocker);
512
+ }
513
+ add(state?.structured_interaction_capture_failure_summary);
514
+ add(state?.structured_interaction_failure_summary);
515
+ const mergeRecommendation = String(state?.merge_recommendation || "").trim();
516
+ if (mergeRecommendation === "do-not-merge" && blockers.length) {
517
+ add("merge_recommendation=do-not-merge because the proof bundle contains hard blockers.");
518
+ }
519
+ return blockers;
520
+ }
501
521
  function visualDeltaEvidenceIssueCode(state = {}, blocker = "") {
502
522
  const visualDelta = visualDeltaForState(state || {});
503
523
  const status = String(visualDelta.status || "").trim();
@@ -532,6 +552,7 @@ function validateShipGate(state = {}) {
532
552
  const visualDelta = visualDeltaForState(state);
533
553
  const visualDeltaRequired = visualDeltaRequiredForState(state);
534
554
  const visualDeltaBlocker = visualDeltaShipGateReason(state);
555
+ const hardBlockers = proofAssessmentHardBlockersForState(state);
535
556
  const reasons = [];
536
557
  if (!["before", "prod", "both"].includes(reference)) {
537
558
  reasons.push(`reference must be before, prod, or both; got ${reference}`);
@@ -563,6 +584,9 @@ function validateShipGate(state = {}) {
563
584
  if (visualDeltaBlocker) {
564
585
  reasons.push(visualDeltaBlocker);
565
586
  }
587
+ for (const blocker of hardBlockers) {
588
+ reasons.push(`proof hard blocker prevents ready_to_ship: ${blocker}`);
589
+ }
566
590
  return {
567
591
  ok: reasons.length === 0,
568
592
  reasons,
@@ -579,7 +603,8 @@ function validateShipGate(state = {}) {
579
603
  proof_assessment_source: proofAssessment.source,
580
604
  visual_delta_required: visualDeltaRequired,
581
605
  visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
582
- visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
606
+ visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null,
607
+ hard_blockers: hardBlockers
583
608
  }
584
609
  };
585
610
  }
@@ -693,6 +718,10 @@ var CHECKPOINT_CONTRACT_SPECS = {
693
718
  }],
694
719
  required_state: ["verify_decision_request"]
695
720
  },
721
+ verify_capture_blocked: {
722
+ purpose: "Verify capture produced conclusive failed browser evidence and should stop instead of retrying proof authoring.",
723
+ required_state: ["verify_decision_request"]
724
+ },
696
725
  verify_supervisor_judgment: {
697
726
  purpose: "Supervising agent judges whether captured evidence proves the change is ready to ship.",
698
727
  accepted_inputs: [{
@@ -1117,6 +1146,7 @@ export {
1117
1146
  visualDeltaRequiredForState,
1118
1147
  visualDeltaForState,
1119
1148
  visualDeltaShipGateReason,
1149
+ proofAssessmentHardBlockersForState,
1120
1150
  requiredBaselineLabelsForState,
1121
1151
  validateShipGate,
1122
1152
  buildCheckpointContract,
@@ -15,7 +15,7 @@ import {
15
15
  validateShipGate,
16
16
  workflowFile,
17
17
  writeState
18
- } from "./chunk-5N5QFI2S.js";
18
+ } from "./chunk-7GZY5PLT.js";
19
19
  import {
20
20
  __export
21
21
  } from "./chunk-MLKGABMK.js";
@@ -211,14 +211,18 @@ function verifyAssessment(state) {
211
211
  };
212
212
  }
213
213
  if (state?.verify_status === "capture_incomplete") {
214
+ const captureQuality = verifyDecision?.capture_quality || {};
215
+ const terminalBlocker = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
216
+ const recommendedStage = terminalBlocker ? null : verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author";
217
+ const continueWithStage = terminalBlocker ? null : verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author";
214
218
  return {
215
- decision: verifyDecision?.capture_quality?.decision || "revise_capture",
219
+ decision: captureQuality?.decision || "revise_capture",
216
220
  summary: verifyDecision?.summary || "Verify needs another internal capture iteration before the evidence can be judged.",
217
- recommendedStage: verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author",
218
- continueWithStage: verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author",
221
+ recommendedStage,
222
+ continueWithStage,
219
223
  escalationTarget: "agent",
220
- reasons: Array.isArray(verifyDecision?.capture_quality?.reasons) ? verifyDecision.capture_quality.reasons : [],
221
- raw: verifyDecision?.capture_quality || verifyDecision,
224
+ reasons: Array.isArray(captureQuality?.reasons) ? captureQuality.reasons : [],
225
+ raw: captureQuality || verifyDecision,
222
226
  source: "workflow_capture"
223
227
  };
224
228
  }
@@ -1438,7 +1442,9 @@ ${implementRes.stderr || ""}`;
1438
1442
  convergenceSignals
1439
1443
  };
1440
1444
  if (verifyStatus !== "evidence_captured") {
1441
- if ((verifyContinueWithStage || verifyRecommendedStage || "author") === "author") {
1445
+ const captureQuality = verifyDecisionRequest?.capture_quality || {};
1446
+ const captureTerminalBlocker = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
1447
+ if (!captureTerminalBlocker && (verifyContinueWithStage || verifyRecommendedStage || "author") === "author") {
1442
1448
  updateState(config.statePath, (currentState) => {
1443
1449
  currentState.author_status = "needs_authoring";
1444
1450
  currentState.proof_plan_status = "needs_authoring";
@@ -1446,7 +1452,7 @@ ${implementRes.stderr || ""}`;
1446
1452
  });
1447
1453
  state = readState(config.statePath);
1448
1454
  }
1449
- const checkpointName = "verify_capture_retry";
1455
+ const checkpointName = captureTerminalBlocker ? "verify_capture_blocked" : "verify_capture_retry";
1450
1456
  const summary = stringValue(proofAssessment.summary) || "Verify ran, but the proof packet still needs internal capture-plan work before it should ship.";
1451
1457
  recordAttempt("verify", "checkpoint", summary, {
1452
1458
  autoApproved: verifyRes.autoApproved || false,
@@ -1459,11 +1465,11 @@ ${implementRes.stderr || ""}`;
1459
1465
  summary,
1460
1466
  {
1461
1467
  ok: true,
1462
- nextActions: ["inspect_after_capture", "continue_internal_loop_with_checkpoint", "return_to_recon_if_baseline_is_wrong"],
1468
+ 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"],
1463
1469
  advanceOptions: verifyLoopAdvanceOptions,
1464
- recommendedAdvanceStage: verifyRecommendedStage || "author",
1465
- continueWithStage: verifyContinueWithStage || "author",
1466
- blocking: false,
1470
+ recommendedAdvanceStage: captureTerminalBlocker ? null : verifyRecommendedStage || "author",
1471
+ continueWithStage: captureTerminalBlocker ? null : verifyContinueWithStage || "author",
1472
+ blocking: captureTerminalBlocker,
1467
1473
  details: verifyDetails,
1468
1474
  verifyStatus,
1469
1475
  verifySummary,
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-YZUVEJ5B.js";
7
7
  import {
8
8
  noImplementationModeFor
9
- } from "./chunk-5N5QFI2S.js";
9
+ } from "./chunk-7GZY5PLT.js";
10
10
  import {
11
11
  createRunResult
12
12
  } from "./chunk-VY4Y5U57.js";
@@ -11,10 +11,11 @@ import {
11
11
  } from "./chunk-FMOYUYH2.js";
12
12
  import {
13
13
  noImplementationModeFor,
14
+ proofAssessmentHardBlockersForState,
14
15
  visualDeltaForState,
15
16
  visualDeltaRequiredForState,
16
17
  visualDeltaShipGateReason
17
- } from "./chunk-5N5QFI2S.js";
18
+ } from "./chunk-7GZY5PLT.js";
18
19
  import {
19
20
  authorPacketPayloadFromCheckpointResponse,
20
21
  buildCheckpointPacketForEngineResult,
@@ -348,6 +349,17 @@ function proofAssessmentRequestsShip(payload) {
348
349
  const continueStage = String(payload.continue_with_stage || "");
349
350
  return decision === "ready_to_ship" || recommendedStage === "ship" || continueStage === "ship";
350
351
  }
352
+ function proofAssessmentHardBlockers(state, payload) {
353
+ const blockers = proofAssessmentHardBlockersForState(state || {});
354
+ if (Array.isArray(payload.hard_blockers)) {
355
+ for (const blocker of payload.hard_blockers) {
356
+ if (typeof blocker !== "string") continue;
357
+ const trimmed = blocker.trim();
358
+ if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
359
+ }
360
+ }
361
+ return blockers;
362
+ }
351
363
  function proofAssessmentContinuation(result, payload) {
352
364
  const proof_assessment_json = jsonParam(payload);
353
365
  return { ...baseContinuation(result), proof_assessment_json };
@@ -1287,6 +1299,33 @@ async function routeCheckpoint(request, state, result, agent, input) {
1287
1299
  adapter_details: assessment.details || null
1288
1300
  })
1289
1301
  });
1302
+ const hardBlockers = proofAssessmentHardBlockers(context.fullRiddleState || {}, payload);
1303
+ if (proofAssessmentRequestsShip(payload) && hardBlockers.length) {
1304
+ const summary = hardBlockers[0];
1305
+ recordEvent(state, {
1306
+ kind: "agent.proof_assessment.hard_blocked",
1307
+ checkpoint,
1308
+ stage: "verify",
1309
+ summary,
1310
+ details: compactRecord({
1311
+ hard_blockers: hardBlockers,
1312
+ proof_assessment: payload,
1313
+ agent_duration_ms: durationMs
1314
+ })
1315
+ });
1316
+ return {
1317
+ blocker: {
1318
+ code: "proof_hard_blocker",
1319
+ checkpoint,
1320
+ message: "Riddle Proof cannot mark ready_to_ship while the proof bundle contains a hard blocker: " + summary,
1321
+ details: compactRecord({
1322
+ hard_blockers: hardBlockers,
1323
+ proofAssessment: payload,
1324
+ verifyDecisionRequest: context.fullRiddleState?.verify_decision_request || result.verifyDecisionRequest || result.checkpointContract?.verify_decision_request || null
1325
+ })
1326
+ }
1327
+ };
1328
+ }
1290
1329
  const visualBlocker = proofAssessmentVisualBlocker({
1291
1330
  ...context.fullRiddleState || {},
1292
1331
  verification_mode: context.fullRiddleState?.verification_mode || request.verification_mode
@@ -1344,6 +1383,19 @@ async function routeCheckpoint(request, state, result, agent, input) {
1344
1383
  }
1345
1384
  };
1346
1385
  }
1386
+ if (checkpoint === "verify_capture_blocked") {
1387
+ return {
1388
+ blocker: {
1389
+ code: "verify_capture_blocked",
1390
+ checkpoint,
1391
+ message: result.summary || "Verify captured conclusive failed browser evidence and stopped instead of retrying proof authoring.",
1392
+ details: compactRecord({
1393
+ verifyDecisionRequest: result.verifyDecisionRequest || result.checkpointContract?.verify_decision_request || null,
1394
+ checkpointContract: result.checkpointContract || null
1395
+ })
1396
+ }
1397
+ };
1398
+ }
1347
1399
  if (checkpoint === "awaiting_stage_advance") {
1348
1400
  const next = recommendedContinuation(result) || defaultAwaitingStageContinuation(result);
1349
1401
  if (next) {
@@ -22,7 +22,7 @@ import {
22
22
  createDisabledRiddleProofAgentAdapter,
23
23
  readRiddleProofRunStatus,
24
24
  runRiddleProofEngineHarness
25
- } from "./chunk-BBUO7HM4.js";
25
+ } from "./chunk-RTLA6CPP.js";
26
26
  import {
27
27
  createCheckpointResponseTemplate
28
28
  } from "./chunk-4FOHZ7JG.js";
package/dist/cli/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import "../chunk-2PXL3RDB.js";
1
+ import "../chunk-SZUC4MDN.js";
2
2
  import "../chunk-PEWAIEER.js";
3
3
  import "../chunk-TWTEUS7R.js";
4
- import "../chunk-BBUO7HM4.js";
4
+ import "../chunk-RTLA6CPP.js";
5
5
  import "../chunk-YZUVEJ5B.js";
6
6
  import "../chunk-FMOYUYH2.js";
7
- import "../chunk-5N5QFI2S.js";
7
+ import "../chunk-7GZY5PLT.js";
8
8
  import "../chunk-4FOHZ7JG.js";
9
9
  import "../chunk-JFQXAJH2.js";
10
10
  import "../chunk-EEIYUZXE.js";
package/dist/cli.cjs CHANGED
@@ -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,
@@ -4673,6 +4707,17 @@ function proofAssessmentRequestsShip(payload) {
4673
4707
  const continueStage = String(payload.continue_with_stage || "");
4674
4708
  return decision === "ready_to_ship" || recommendedStage === "ship" || continueStage === "ship";
4675
4709
  }
4710
+ function proofAssessmentHardBlockers(state, payload) {
4711
+ const blockers = proofAssessmentHardBlockersForState(state || {});
4712
+ if (Array.isArray(payload.hard_blockers)) {
4713
+ for (const blocker of payload.hard_blockers) {
4714
+ if (typeof blocker !== "string") continue;
4715
+ const trimmed = blocker.trim();
4716
+ if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
4717
+ }
4718
+ }
4719
+ return blockers;
4720
+ }
4676
4721
  function proofAssessmentContinuation(result, payload) {
4677
4722
  const proof_assessment_json = jsonParam(payload);
4678
4723
  return { ...baseContinuation(result), proof_assessment_json };
@@ -5612,6 +5657,33 @@ async function routeCheckpoint(request, state, result, agent, input) {
5612
5657
  adapter_details: assessment.details || null
5613
5658
  })
5614
5659
  });
5660
+ const hardBlockers = proofAssessmentHardBlockers(context.fullRiddleState || {}, payload);
5661
+ if (proofAssessmentRequestsShip(payload) && hardBlockers.length) {
5662
+ const summary = hardBlockers[0];
5663
+ recordEvent(state, {
5664
+ kind: "agent.proof_assessment.hard_blocked",
5665
+ checkpoint,
5666
+ stage: "verify",
5667
+ summary,
5668
+ details: compactRecord({
5669
+ hard_blockers: hardBlockers,
5670
+ proof_assessment: payload,
5671
+ agent_duration_ms: durationMs
5672
+ })
5673
+ });
5674
+ return {
5675
+ blocker: {
5676
+ code: "proof_hard_blocker",
5677
+ checkpoint,
5678
+ message: "Riddle Proof cannot mark ready_to_ship while the proof bundle contains a hard blocker: " + summary,
5679
+ details: compactRecord({
5680
+ hard_blockers: hardBlockers,
5681
+ proofAssessment: payload,
5682
+ verifyDecisionRequest: context.fullRiddleState?.verify_decision_request || result.verifyDecisionRequest || result.checkpointContract?.verify_decision_request || null
5683
+ })
5684
+ }
5685
+ };
5686
+ }
5615
5687
  const visualBlocker = proofAssessmentVisualBlocker({
5616
5688
  ...context.fullRiddleState || {},
5617
5689
  verification_mode: context.fullRiddleState?.verification_mode || request.verification_mode
@@ -5669,6 +5741,19 @@ async function routeCheckpoint(request, state, result, agent, input) {
5669
5741
  }
5670
5742
  };
5671
5743
  }
5744
+ if (checkpoint === "verify_capture_blocked") {
5745
+ return {
5746
+ blocker: {
5747
+ code: "verify_capture_blocked",
5748
+ checkpoint,
5749
+ message: result.summary || "Verify captured conclusive failed browser evidence and stopped instead of retrying proof authoring.",
5750
+ details: compactRecord({
5751
+ verifyDecisionRequest: result.verifyDecisionRequest || result.checkpointContract?.verify_decision_request || null,
5752
+ checkpointContract: result.checkpointContract || null
5753
+ })
5754
+ }
5755
+ };
5756
+ }
5672
5757
  if (checkpoint === "awaiting_stage_advance") {
5673
5758
  const next = recommendedContinuation(result) || defaultAwaitingStageContinuation(result);
5674
5759
  if (next) {
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-2PXL3RDB.js";
2
+ import "./chunk-SZUC4MDN.js";
3
3
  import "./chunk-PEWAIEER.js";
4
4
  import "./chunk-TWTEUS7R.js";
5
- import "./chunk-BBUO7HM4.js";
5
+ import "./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-JFQXAJH2.js";
11
11
  import "./chunk-EEIYUZXE.js";