@riddledc/riddle-proof 0.5.32 → 0.5.34

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 (40) hide show
  1. package/dist/{chunk-R4BPJNAM.js → chunk-4YCWZVBN.js} +101 -8
  2. package/dist/{chunk-LIDYNU7Q.js → chunk-7R6ZQE3X.js} +39 -2
  3. package/dist/{chunk-TMMKRKY5.js → chunk-J2MERROF.js} +1 -0
  4. package/dist/{chunk-F6VFKS7K.js → chunk-MQ2BHHLX.js} +2 -2
  5. package/dist/{chunk-7ZJAUEUN.js → chunk-OASB3CYU.js} +6 -1
  6. package/dist/chunk-ODORKNSO.js +121 -0
  7. package/dist/engine-harness.cjs +143 -9
  8. package/dist/engine-harness.js +4 -3
  9. package/dist/index.cjs +271 -11
  10. package/dist/index.d.cts +2 -1
  11. package/dist/index.d.ts +2 -1
  12. package/dist/index.js +24 -7
  13. package/dist/openclaw.cjs +5 -0
  14. package/dist/openclaw.js +2 -2
  15. package/dist/proof-run-core.cjs +104 -8
  16. package/dist/proof-run-core.d.cts +24 -1
  17. package/dist/proof-run-core.d.ts +24 -1
  18. package/dist/proof-run-core.js +7 -1
  19. package/dist/proof-run-engine.cjs +101 -8
  20. package/dist/proof-run-engine.d.cts +24 -0
  21. package/dist/proof-run-engine.d.ts +24 -0
  22. package/dist/proof-run-engine.js +4 -1
  23. package/dist/proof-session.cjs +151 -0
  24. package/dist/proof-session.d.cts +37 -0
  25. package/dist/proof-session.d.ts +37 -0
  26. package/dist/proof-session.js +18 -0
  27. package/dist/result.cjs +1 -0
  28. package/dist/result.js +1 -1
  29. package/dist/runner.cjs +6 -0
  30. package/dist/runner.js +3 -3
  31. package/dist/state.cjs +5 -0
  32. package/dist/state.js +2 -2
  33. package/dist/types.d.cts +67 -1
  34. package/dist/types.d.ts +67 -1
  35. package/package.json +7 -2
  36. package/runtime/lib/preflight.py +42 -2
  37. package/runtime/lib/ship.py +55 -1
  38. package/runtime/lib/util.py +237 -0
  39. package/runtime/lib/verify.py +93 -6
  40. package/runtime/tests/recon_verify_smoke.py +181 -3
@@ -50,6 +50,9 @@ __export(proof_run_core_exports, {
50
50
  setStageDecisionRequest: () => setStageDecisionRequest,
51
51
  summarizeState: () => summarizeState,
52
52
  validateShipGate: () => validateShipGate,
53
+ visualDeltaForState: () => visualDeltaForState,
54
+ visualDeltaRequiredForState: () => visualDeltaRequiredForState,
55
+ visualDeltaShipGateReason: () => visualDeltaShipGateReason,
53
56
  workflowFile: () => workflowFile,
54
57
  writeState: () => writeState
55
58
  });
@@ -119,6 +122,11 @@ function ensureAction(action) {
119
122
  function workflowFile(riddleProofDir, action) {
120
123
  return import_node_path.default.join(riddleProofDir, "pipelines", `riddle-proof-${action}.lobster`);
121
124
  }
125
+ function asJsonString(value) {
126
+ if (value === void 0 || value === null || value === "") return "";
127
+ if (typeof value === "string") return value;
128
+ return JSON.stringify(value);
129
+ }
122
130
  function buildSetupArgs(params, config) {
123
131
  if (!params.repo) throw new Error("repo is required for setup/run");
124
132
  if (!params.change_request) throw new Error("change_request is required for setup/run");
@@ -134,8 +142,13 @@ function buildSetupArgs(params, config) {
134
142
  prod_url: params.prod_url || "",
135
143
  capture_script: captureScript,
136
144
  success_criteria: params.success_criteria || "",
137
- assertions_json: params.assertions_json || "",
145
+ assertions_json: params.assertions_json || asJsonString(params.assertions),
138
146
  verification_mode: params.verification_mode || "proof",
147
+ resume_session: params.resume_session || "",
148
+ target_image_url: params.target_image_url || "",
149
+ target_image_hash: params.target_image_hash || "",
150
+ viewport_matrix_json: params.viewport_matrix_json || asJsonString(params.viewport_matrix),
151
+ deterministic_setup_json: params.deterministic_setup_json || asJsonString(params.deterministic_setup),
139
152
  reference: requestedReference,
140
153
  base_branch: params.base_branch || "main",
141
154
  before_ref: params.before_ref || "",
@@ -378,6 +391,54 @@ function normalizedProofAssessment(state = {}) {
378
391
  source: source || null
379
392
  };
380
393
  }
394
+ var VISUAL_FIRST_MODES = /* @__PURE__ */ new Set([
395
+ "visual",
396
+ "render",
397
+ "interaction",
398
+ "ui",
399
+ "layout",
400
+ "screenshot",
401
+ "canvas",
402
+ "animation"
403
+ ]);
404
+ function objectValue(value) {
405
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
406
+ }
407
+ function normalizedVerificationMode(state = {}) {
408
+ const bundle = objectValue(state?.evidence_bundle);
409
+ const bundleMode = String(bundle.verification_mode || "").trim().toLowerCase();
410
+ if (bundleMode) return bundleMode;
411
+ return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
412
+ }
413
+ function visualDeltaRequiredForState(state = {}) {
414
+ const bundle = objectValue(state?.evidence_bundle);
415
+ const contract = objectValue(bundle.artifact_contract);
416
+ const required = objectValue(contract.required);
417
+ return required.visual_delta === true || VISUAL_FIRST_MODES.has(normalizedVerificationMode(state));
418
+ }
419
+ function visualDeltaForState(state = {}) {
420
+ const bundle = objectValue(state?.evidence_bundle);
421
+ const after = objectValue(bundle.after);
422
+ const afterDelta = objectValue(after.visual_delta);
423
+ if (Object.keys(afterDelta).length) return afterDelta;
424
+ const request = objectValue(state?.proof_assessment_request);
425
+ return objectValue(request.visual_delta);
426
+ }
427
+ function visualDeltaShipGateReason(state = {}) {
428
+ if (!visualDeltaRequiredForState(state)) return null;
429
+ const visualDelta = visualDeltaForState(state);
430
+ if (visualDelta.status === "measured" && visualDelta.passed === true) return null;
431
+ const status = String(visualDelta.status || "missing");
432
+ if (status === "unmeasured") {
433
+ return "visual_delta.status=unmeasured blocks ready_to_ship for visual/UI proof";
434
+ }
435
+ if (status === "measured" && visualDelta.passed === false) {
436
+ return "visual_delta.status=measured but visual_delta.passed=false blocks ready_to_ship for visual/UI proof";
437
+ }
438
+ const reason = String(visualDelta.reason || "").trim();
439
+ if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
440
+ return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
441
+ }
381
442
  function requiredBaselineLabelsForState(state = {}) {
382
443
  const reference = normalizedReference(state);
383
444
  const labels = [];
@@ -393,6 +454,10 @@ function validateShipGate(state = {}) {
393
454
  const afterCdn = String(state?.after_cdn || "").trim();
394
455
  const verifyStatus = String(state?.verify_status || "").trim();
395
456
  const proofAssessment = normalizedProofAssessment(state);
457
+ const verificationMode = normalizedVerificationMode(state);
458
+ const visualDelta = visualDeltaForState(state);
459
+ const visualDeltaRequired = visualDeltaRequiredForState(state);
460
+ const visualDeltaBlocker = visualDeltaShipGateReason(state);
396
461
  const reasons = [];
397
462
  if (!["before", "prod", "both"].includes(reference)) {
398
463
  reasons.push(`reference must be before, prod, or both; got ${reference}`);
@@ -421,19 +486,26 @@ function validateShipGate(state = {}) {
421
486
  if (proofAssessment.decision !== "ready_to_ship") {
422
487
  reasons.push("proof_assessment.decision must be ready_to_ship before ship");
423
488
  }
489
+ if (visualDeltaBlocker) {
490
+ reasons.push(visualDeltaBlocker);
491
+ }
424
492
  return {
425
493
  ok: reasons.length === 0,
426
494
  reasons,
427
495
  required_baselines: requiredBaselines,
428
496
  evidence: {
429
497
  reference,
498
+ verification_mode: verificationMode || null,
430
499
  prod_url: prodUrl || null,
431
500
  before_cdn: beforeCdn || null,
432
501
  prod_cdn: prodCdn || null,
433
502
  after_cdn: afterCdn || null,
434
503
  verify_status: verifyStatus || null,
435
504
  proof_assessment_decision: proofAssessment.decision,
436
- proof_assessment_source: proofAssessment.source
505
+ proof_assessment_source: proofAssessment.source,
506
+ visual_delta_required: visualDeltaRequired,
507
+ visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
508
+ visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
437
509
  }
438
510
  };
439
511
  }
@@ -646,6 +718,11 @@ function mergeStateFromParams(statePath, params) {
646
718
  "success_criteria",
647
719
  "assertions_json",
648
720
  "verification_mode",
721
+ "resume_session",
722
+ "target_image_url",
723
+ "target_image_hash",
724
+ "viewport_matrix_json",
725
+ "deterministic_setup_json",
649
726
  "base_branch",
650
727
  "before_ref",
651
728
  "context",
@@ -747,23 +824,36 @@ function mergeStateFromParams(statePath, params) {
747
824
  state.proof_assessment_source = null;
748
825
  } else {
749
826
  const parsed = JSON.parse(raw);
750
- state.proof_assessment = {
827
+ const assessment = {
751
828
  ...parsed,
752
829
  source: (parsed?.source || "supervising_agent").toString()
753
830
  };
831
+ const readyBlocker = assessment?.decision === "ready_to_ship" ? visualDeltaShipGateReason({ ...state, proof_assessment: assessment, proof_assessment_source: assessment.source }) : null;
832
+ if (readyBlocker) {
833
+ assessment.blocked_decision = assessment.decision;
834
+ assessment.decision = "needs_richer_proof";
835
+ if (assessment.recommended_stage === "ship") assessment.recommended_stage = "verify";
836
+ if (assessment.continue_with_stage === "ship") assessment.continue_with_stage = "verify";
837
+ const blockers = Array.isArray(assessment.blockers) ? assessment.blockers : [];
838
+ assessment.blockers = [...blockers, readyBlocker];
839
+ }
840
+ state.proof_assessment = assessment;
754
841
  state.proof_assessment_source = state.proof_assessment.source;
755
- if (typeof parsed?.decision === "string") {
756
- state.proof_decision = parsed.decision;
842
+ if (typeof state.proof_assessment?.decision === "string") {
843
+ state.proof_decision = state.proof_assessment.decision;
757
844
  }
758
845
  if (typeof parsed?.summary === "string") {
759
846
  state.proof_assessment_summary = normalizeOptionalString(parsed.summary) || null;
760
847
  }
761
- if (parsed?.decision === "ready_to_ship") {
848
+ if (state.proof_assessment?.decision === "ready_to_ship") {
762
849
  state.merge_recommendation = "ready-to-ship";
763
- } else if (typeof parsed?.decision === "string" && parsed.decision.trim()) {
850
+ } else if (typeof state.proof_assessment?.decision === "string" && state.proof_assessment.decision.trim()) {
764
851
  state.merge_recommendation = "do-not-merge";
765
852
  }
766
853
  appendProofSummaryLine(state, `Supervising proof assessment: ${state.proof_assessment.decision || "unknown"}`);
854
+ if (readyBlocker) {
855
+ appendProofSummaryLine(state, `Ready-to-ship assessment blocked: ${readyBlocker}`);
856
+ }
767
857
  if (state.proof_assessment_summary) {
768
858
  appendProofSummaryLine(state, `Assessment summary: ${state.proof_assessment_summary}`);
769
859
  }
@@ -864,7 +954,10 @@ function summarizeState(state) {
864
954
  explicit_stage_gate: Boolean(state.explicit_stage_gate),
865
955
  last_requested_advance_stage: state.last_requested_advance_stage || null,
866
956
  recon_results: state.recon_results || null,
867
- verify_results: state.verify_results || null
957
+ verify_results: state.verify_results || null,
958
+ proof_session: state.proof_session || null,
959
+ parent_proof_session: state.parent_proof_session || null,
960
+ proof_session_artifact_url: state.proof_session_artifact_url || null
868
961
  };
869
962
  const parts = [
870
963
  state.workspace_ready ? "workspace ready" : "workspace not ready",
@@ -907,6 +1000,9 @@ function summarizeState(state) {
907
1000
  setStageDecisionRequest,
908
1001
  summarizeState,
909
1002
  validateShipGate,
1003
+ visualDeltaForState,
1004
+ visualDeltaRequiredForState,
1005
+ visualDeltaShipGateReason,
910
1006
  workflowFile,
911
1007
  writeState
912
1008
  });
@@ -10,8 +10,16 @@ interface WorkflowParams {
10
10
  prod_url?: string;
11
11
  capture_script?: string;
12
12
  success_criteria?: string;
13
+ assertions?: unknown;
13
14
  assertions_json?: string;
14
15
  verification_mode?: string;
16
+ resume_session?: string;
17
+ target_image_url?: string;
18
+ target_image_hash?: string;
19
+ viewport_matrix?: unknown;
20
+ viewport_matrix_json?: string;
21
+ deterministic_setup?: unknown;
22
+ deterministic_setup_json?: string;
15
23
  reference?: "prod" | "before" | "both";
16
24
  base_branch?: string;
17
25
  before_ref?: string;
@@ -70,6 +78,7 @@ interface ShipGateValidation {
70
78
  required_baselines: string[];
71
79
  evidence: {
72
80
  reference: string;
81
+ verification_mode: string | null;
73
82
  prod_url: string | null;
74
83
  before_cdn: string | null;
75
84
  prod_cdn: string | null;
@@ -77,6 +86,9 @@ interface ShipGateValidation {
77
86
  verify_status: string | null;
78
87
  proof_assessment_decision: string | null;
79
88
  proof_assessment_source: string | null;
89
+ visual_delta_required: boolean;
90
+ visual_delta_status: string | null;
91
+ visual_delta_passed: boolean | null;
80
92
  };
81
93
  }
82
94
  declare function resolveRiddleProofDir(config?: PluginConfig): string;
@@ -98,6 +110,11 @@ declare function buildSetupArgs(params: WorkflowParams, config: ReturnType<typeo
98
110
  success_criteria: string;
99
111
  assertions_json: string;
100
112
  verification_mode: string;
113
+ resume_session: string;
114
+ target_image_url: string;
115
+ target_image_hash: string;
116
+ viewport_matrix_json: string;
117
+ deterministic_setup_json: string;
101
118
  reference: "prod" | "before" | "both";
102
119
  base_branch: string;
103
120
  before_ref: string;
@@ -192,6 +209,9 @@ declare function invalidateVerifyEvidence(state?: any): {
192
209
  hadProofAssessment: boolean;
193
210
  hadProofAssessmentRequest: boolean;
194
211
  };
212
+ declare function visualDeltaRequiredForState(state?: any): boolean;
213
+ declare function visualDeltaForState(state?: any): Record<string, any>;
214
+ declare function visualDeltaShipGateReason(state?: any): string | null;
195
215
  declare function requiredBaselineLabelsForState(state?: any): string[];
196
216
  declare function validateShipGate(state?: any): ShipGateValidation;
197
217
  declare function buildCheckpointContract(state: any, request: {
@@ -280,7 +300,10 @@ declare function summarizeState(state: any): {
280
300
  last_requested_advance_stage: any;
281
301
  recon_results: any;
282
302
  verify_results: any;
303
+ proof_session: any;
304
+ parent_proof_session: any;
305
+ proof_session_artifact_url: any;
283
306
  };
284
307
  };
285
308
 
286
- export { BUNDLED_RIDDLE_PROOF_DIR, CHECKPOINT_CONTRACT_VERSION, type CheckpointInputContract, type PluginConfig, RIDDLE_PROOF_DIR_CANDIDATES, type ShipGateValidation, WORKFLOW_STAGE_ORDER, type WorkflowAction, type WorkflowParams, type WorkflowStage, buildCheckpointContract, buildSetupArgs, checkpointContinueStage, clearStageDecisionRequest, ensureAction, ensureStageLoopState, invalidateVerifyEvidence, mergeStateFromParams, readState, recordStageAttempt, requiredBaselineLabelsForState, resolveConfig, resolveRiddleProofDir, setStageDecisionRequest, summarizeState, validateShipGate, workflowFile, writeState };
309
+ export { BUNDLED_RIDDLE_PROOF_DIR, CHECKPOINT_CONTRACT_VERSION, type CheckpointInputContract, type PluginConfig, RIDDLE_PROOF_DIR_CANDIDATES, type ShipGateValidation, WORKFLOW_STAGE_ORDER, type WorkflowAction, type WorkflowParams, type WorkflowStage, buildCheckpointContract, buildSetupArgs, checkpointContinueStage, clearStageDecisionRequest, ensureAction, ensureStageLoopState, invalidateVerifyEvidence, mergeStateFromParams, readState, recordStageAttempt, requiredBaselineLabelsForState, resolveConfig, resolveRiddleProofDir, setStageDecisionRequest, summarizeState, validateShipGate, visualDeltaForState, visualDeltaRequiredForState, visualDeltaShipGateReason, workflowFile, writeState };
@@ -10,8 +10,16 @@ interface WorkflowParams {
10
10
  prod_url?: string;
11
11
  capture_script?: string;
12
12
  success_criteria?: string;
13
+ assertions?: unknown;
13
14
  assertions_json?: string;
14
15
  verification_mode?: string;
16
+ resume_session?: string;
17
+ target_image_url?: string;
18
+ target_image_hash?: string;
19
+ viewport_matrix?: unknown;
20
+ viewport_matrix_json?: string;
21
+ deterministic_setup?: unknown;
22
+ deterministic_setup_json?: string;
15
23
  reference?: "prod" | "before" | "both";
16
24
  base_branch?: string;
17
25
  before_ref?: string;
@@ -70,6 +78,7 @@ interface ShipGateValidation {
70
78
  required_baselines: string[];
71
79
  evidence: {
72
80
  reference: string;
81
+ verification_mode: string | null;
73
82
  prod_url: string | null;
74
83
  before_cdn: string | null;
75
84
  prod_cdn: string | null;
@@ -77,6 +86,9 @@ interface ShipGateValidation {
77
86
  verify_status: string | null;
78
87
  proof_assessment_decision: string | null;
79
88
  proof_assessment_source: string | null;
89
+ visual_delta_required: boolean;
90
+ visual_delta_status: string | null;
91
+ visual_delta_passed: boolean | null;
80
92
  };
81
93
  }
82
94
  declare function resolveRiddleProofDir(config?: PluginConfig): string;
@@ -98,6 +110,11 @@ declare function buildSetupArgs(params: WorkflowParams, config: ReturnType<typeo
98
110
  success_criteria: string;
99
111
  assertions_json: string;
100
112
  verification_mode: string;
113
+ resume_session: string;
114
+ target_image_url: string;
115
+ target_image_hash: string;
116
+ viewport_matrix_json: string;
117
+ deterministic_setup_json: string;
101
118
  reference: "prod" | "before" | "both";
102
119
  base_branch: string;
103
120
  before_ref: string;
@@ -192,6 +209,9 @@ declare function invalidateVerifyEvidence(state?: any): {
192
209
  hadProofAssessment: boolean;
193
210
  hadProofAssessmentRequest: boolean;
194
211
  };
212
+ declare function visualDeltaRequiredForState(state?: any): boolean;
213
+ declare function visualDeltaForState(state?: any): Record<string, any>;
214
+ declare function visualDeltaShipGateReason(state?: any): string | null;
195
215
  declare function requiredBaselineLabelsForState(state?: any): string[];
196
216
  declare function validateShipGate(state?: any): ShipGateValidation;
197
217
  declare function buildCheckpointContract(state: any, request: {
@@ -280,7 +300,10 @@ declare function summarizeState(state: any): {
280
300
  last_requested_advance_stage: any;
281
301
  recon_results: any;
282
302
  verify_results: any;
303
+ proof_session: any;
304
+ parent_proof_session: any;
305
+ proof_session_artifact_url: any;
283
306
  };
284
307
  };
285
308
 
286
- export { BUNDLED_RIDDLE_PROOF_DIR, CHECKPOINT_CONTRACT_VERSION, type CheckpointInputContract, type PluginConfig, RIDDLE_PROOF_DIR_CANDIDATES, type ShipGateValidation, WORKFLOW_STAGE_ORDER, type WorkflowAction, type WorkflowParams, type WorkflowStage, buildCheckpointContract, buildSetupArgs, checkpointContinueStage, clearStageDecisionRequest, ensureAction, ensureStageLoopState, invalidateVerifyEvidence, mergeStateFromParams, readState, recordStageAttempt, requiredBaselineLabelsForState, resolveConfig, resolveRiddleProofDir, setStageDecisionRequest, summarizeState, validateShipGate, workflowFile, writeState };
309
+ export { BUNDLED_RIDDLE_PROOF_DIR, CHECKPOINT_CONTRACT_VERSION, type CheckpointInputContract, type PluginConfig, RIDDLE_PROOF_DIR_CANDIDATES, type ShipGateValidation, WORKFLOW_STAGE_ORDER, type WorkflowAction, type WorkflowParams, type WorkflowStage, buildCheckpointContract, buildSetupArgs, checkpointContinueStage, clearStageDecisionRequest, ensureAction, ensureStageLoopState, invalidateVerifyEvidence, mergeStateFromParams, readState, recordStageAttempt, requiredBaselineLabelsForState, resolveConfig, resolveRiddleProofDir, setStageDecisionRequest, summarizeState, validateShipGate, visualDeltaForState, visualDeltaRequiredForState, visualDeltaShipGateReason, workflowFile, writeState };
@@ -19,9 +19,12 @@ import {
19
19
  setStageDecisionRequest,
20
20
  summarizeState,
21
21
  validateShipGate,
22
+ visualDeltaForState,
23
+ visualDeltaRequiredForState,
24
+ visualDeltaShipGateReason,
22
25
  workflowFile,
23
26
  writeState
24
- } from "./chunk-R4BPJNAM.js";
27
+ } from "./chunk-4YCWZVBN.js";
25
28
  export {
26
29
  BUNDLED_RIDDLE_PROOF_DIR,
27
30
  CHECKPOINT_CONTRACT_VERSION,
@@ -43,6 +46,9 @@ export {
43
46
  setStageDecisionRequest,
44
47
  summarizeState,
45
48
  validateShipGate,
49
+ visualDeltaForState,
50
+ visualDeltaRequiredForState,
51
+ visualDeltaShipGateReason,
46
52
  workflowFile,
47
53
  writeState
48
54
  };
@@ -104,6 +104,11 @@ function ensureAction(action) {
104
104
  function workflowFile(riddleProofDir, action) {
105
105
  return import_node_path.default.join(riddleProofDir, "pipelines", `riddle-proof-${action}.lobster`);
106
106
  }
107
+ function asJsonString(value) {
108
+ if (value === void 0 || value === null || value === "") return "";
109
+ if (typeof value === "string") return value;
110
+ return JSON.stringify(value);
111
+ }
107
112
  function buildSetupArgs(params, config) {
108
113
  if (!params.repo) throw new Error("repo is required for setup/run");
109
114
  if (!params.change_request) throw new Error("change_request is required for setup/run");
@@ -119,8 +124,13 @@ function buildSetupArgs(params, config) {
119
124
  prod_url: params.prod_url || "",
120
125
  capture_script: captureScript,
121
126
  success_criteria: params.success_criteria || "",
122
- assertions_json: params.assertions_json || "",
127
+ assertions_json: params.assertions_json || asJsonString(params.assertions),
123
128
  verification_mode: params.verification_mode || "proof",
129
+ resume_session: params.resume_session || "",
130
+ target_image_url: params.target_image_url || "",
131
+ target_image_hash: params.target_image_hash || "",
132
+ viewport_matrix_json: params.viewport_matrix_json || asJsonString(params.viewport_matrix),
133
+ deterministic_setup_json: params.deterministic_setup_json || asJsonString(params.deterministic_setup),
124
134
  reference: requestedReference,
125
135
  base_branch: params.base_branch || "main",
126
136
  before_ref: params.before_ref || "",
@@ -363,6 +373,54 @@ function normalizedProofAssessment(state = {}) {
363
373
  source: source || null
364
374
  };
365
375
  }
376
+ var VISUAL_FIRST_MODES = /* @__PURE__ */ new Set([
377
+ "visual",
378
+ "render",
379
+ "interaction",
380
+ "ui",
381
+ "layout",
382
+ "screenshot",
383
+ "canvas",
384
+ "animation"
385
+ ]);
386
+ function objectValue(value) {
387
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
388
+ }
389
+ function normalizedVerificationMode(state = {}) {
390
+ const bundle = objectValue(state?.evidence_bundle);
391
+ const bundleMode = String(bundle.verification_mode || "").trim().toLowerCase();
392
+ if (bundleMode) return bundleMode;
393
+ return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
394
+ }
395
+ function visualDeltaRequiredForState(state = {}) {
396
+ const bundle = objectValue(state?.evidence_bundle);
397
+ const contract = objectValue(bundle.artifact_contract);
398
+ const required = objectValue(contract.required);
399
+ return required.visual_delta === true || VISUAL_FIRST_MODES.has(normalizedVerificationMode(state));
400
+ }
401
+ function visualDeltaForState(state = {}) {
402
+ const bundle = objectValue(state?.evidence_bundle);
403
+ const after = objectValue(bundle.after);
404
+ const afterDelta = objectValue(after.visual_delta);
405
+ if (Object.keys(afterDelta).length) return afterDelta;
406
+ const request = objectValue(state?.proof_assessment_request);
407
+ return objectValue(request.visual_delta);
408
+ }
409
+ function visualDeltaShipGateReason(state = {}) {
410
+ if (!visualDeltaRequiredForState(state)) return null;
411
+ const visualDelta = visualDeltaForState(state);
412
+ if (visualDelta.status === "measured" && visualDelta.passed === true) return null;
413
+ const status = String(visualDelta.status || "missing");
414
+ if (status === "unmeasured") {
415
+ return "visual_delta.status=unmeasured blocks ready_to_ship for visual/UI proof";
416
+ }
417
+ if (status === "measured" && visualDelta.passed === false) {
418
+ return "visual_delta.status=measured but visual_delta.passed=false blocks ready_to_ship for visual/UI proof";
419
+ }
420
+ const reason = String(visualDelta.reason || "").trim();
421
+ if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
422
+ return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
423
+ }
366
424
  function requiredBaselineLabelsForState(state = {}) {
367
425
  const reference = normalizedReference(state);
368
426
  const labels = [];
@@ -378,6 +436,10 @@ function validateShipGate(state = {}) {
378
436
  const afterCdn = String(state?.after_cdn || "").trim();
379
437
  const verifyStatus = String(state?.verify_status || "").trim();
380
438
  const proofAssessment = normalizedProofAssessment(state);
439
+ const verificationMode = normalizedVerificationMode(state);
440
+ const visualDelta = visualDeltaForState(state);
441
+ const visualDeltaRequired = visualDeltaRequiredForState(state);
442
+ const visualDeltaBlocker = visualDeltaShipGateReason(state);
381
443
  const reasons = [];
382
444
  if (!["before", "prod", "both"].includes(reference)) {
383
445
  reasons.push(`reference must be before, prod, or both; got ${reference}`);
@@ -406,19 +468,26 @@ function validateShipGate(state = {}) {
406
468
  if (proofAssessment.decision !== "ready_to_ship") {
407
469
  reasons.push("proof_assessment.decision must be ready_to_ship before ship");
408
470
  }
471
+ if (visualDeltaBlocker) {
472
+ reasons.push(visualDeltaBlocker);
473
+ }
409
474
  return {
410
475
  ok: reasons.length === 0,
411
476
  reasons,
412
477
  required_baselines: requiredBaselines,
413
478
  evidence: {
414
479
  reference,
480
+ verification_mode: verificationMode || null,
415
481
  prod_url: prodUrl || null,
416
482
  before_cdn: beforeCdn || null,
417
483
  prod_cdn: prodCdn || null,
418
484
  after_cdn: afterCdn || null,
419
485
  verify_status: verifyStatus || null,
420
486
  proof_assessment_decision: proofAssessment.decision,
421
- proof_assessment_source: proofAssessment.source
487
+ proof_assessment_source: proofAssessment.source,
488
+ visual_delta_required: visualDeltaRequired,
489
+ visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
490
+ visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
422
491
  }
423
492
  };
424
493
  }
@@ -631,6 +700,11 @@ function mergeStateFromParams(statePath, params) {
631
700
  "success_criteria",
632
701
  "assertions_json",
633
702
  "verification_mode",
703
+ "resume_session",
704
+ "target_image_url",
705
+ "target_image_hash",
706
+ "viewport_matrix_json",
707
+ "deterministic_setup_json",
634
708
  "base_branch",
635
709
  "before_ref",
636
710
  "context",
@@ -732,23 +806,36 @@ function mergeStateFromParams(statePath, params) {
732
806
  state.proof_assessment_source = null;
733
807
  } else {
734
808
  const parsed = JSON.parse(raw);
735
- state.proof_assessment = {
809
+ const assessment = {
736
810
  ...parsed,
737
811
  source: (parsed?.source || "supervising_agent").toString()
738
812
  };
813
+ const readyBlocker = assessment?.decision === "ready_to_ship" ? visualDeltaShipGateReason({ ...state, proof_assessment: assessment, proof_assessment_source: assessment.source }) : null;
814
+ if (readyBlocker) {
815
+ assessment.blocked_decision = assessment.decision;
816
+ assessment.decision = "needs_richer_proof";
817
+ if (assessment.recommended_stage === "ship") assessment.recommended_stage = "verify";
818
+ if (assessment.continue_with_stage === "ship") assessment.continue_with_stage = "verify";
819
+ const blockers = Array.isArray(assessment.blockers) ? assessment.blockers : [];
820
+ assessment.blockers = [...blockers, readyBlocker];
821
+ }
822
+ state.proof_assessment = assessment;
739
823
  state.proof_assessment_source = state.proof_assessment.source;
740
- if (typeof parsed?.decision === "string") {
741
- state.proof_decision = parsed.decision;
824
+ if (typeof state.proof_assessment?.decision === "string") {
825
+ state.proof_decision = state.proof_assessment.decision;
742
826
  }
743
827
  if (typeof parsed?.summary === "string") {
744
828
  state.proof_assessment_summary = normalizeOptionalString(parsed.summary) || null;
745
829
  }
746
- if (parsed?.decision === "ready_to_ship") {
830
+ if (state.proof_assessment?.decision === "ready_to_ship") {
747
831
  state.merge_recommendation = "ready-to-ship";
748
- } else if (typeof parsed?.decision === "string" && parsed.decision.trim()) {
832
+ } else if (typeof state.proof_assessment?.decision === "string" && state.proof_assessment.decision.trim()) {
749
833
  state.merge_recommendation = "do-not-merge";
750
834
  }
751
835
  appendProofSummaryLine(state, `Supervising proof assessment: ${state.proof_assessment.decision || "unknown"}`);
836
+ if (readyBlocker) {
837
+ appendProofSummaryLine(state, `Ready-to-ship assessment blocked: ${readyBlocker}`);
838
+ }
752
839
  if (state.proof_assessment_summary) {
753
840
  appendProofSummaryLine(state, `Assessment summary: ${state.proof_assessment_summary}`);
754
841
  }
@@ -849,7 +936,10 @@ function summarizeState(state) {
849
936
  explicit_stage_gate: Boolean(state.explicit_stage_gate),
850
937
  last_requested_advance_stage: state.last_requested_advance_stage || null,
851
938
  recon_results: state.recon_results || null,
852
- verify_results: state.verify_results || null
939
+ verify_results: state.verify_results || null,
940
+ proof_session: state.proof_session || null,
941
+ parent_proof_session: state.parent_proof_session || null,
942
+ proof_session_artifact_url: state.proof_session_artifact_url || null
853
943
  };
854
944
  const parts = [
855
945
  state.workspace_ready ? "workspace ready" : "workspace not ready",
@@ -1622,6 +1712,9 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
1622
1712
  if (reasons.some((reason) => reason.includes("proof_assessment"))) {
1623
1713
  return "resume with riddle_proof_review using decision=ready_to_ship only after the screenshots and semantic evidence visibly prove the request; otherwise choose needs_implementation or needs_richer_proof";
1624
1714
  }
1715
+ if (reasons.some((reason) => reason.includes("visual_delta"))) {
1716
+ return "rerun verify with a measured before/after visual delta, or choose needs_richer_proof instead of ready_to_ship for this visual proof";
1717
+ }
1625
1718
  if (reasons.some((reason) => reason.includes("after_cdn") || reason.includes("verify_status"))) {
1626
1719
  return "rerun verify with stronger proof framing so after evidence is captured before shipping";
1627
1720
  }
@@ -83,6 +83,9 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
83
83
  last_requested_advance_stage: any;
84
84
  recon_results: any;
85
85
  verify_results: any;
86
+ proof_session: any;
87
+ parent_proof_session: any;
88
+ proof_session_artifact_url: any;
86
89
  } | null;
87
90
  pr_state: {
88
91
  status: string;
@@ -172,6 +175,9 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
172
175
  last_requested_advance_stage: any;
173
176
  recon_results: any;
174
177
  verify_results: any;
178
+ proof_session: any;
179
+ parent_proof_session: any;
180
+ proof_session_artifact_url: any;
175
181
  } | null;
176
182
  pr_state: {
177
183
  status: string;
@@ -259,6 +265,9 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
259
265
  last_requested_advance_stage: any;
260
266
  recon_results: any;
261
267
  verify_results: any;
268
+ proof_session: any;
269
+ parent_proof_session: any;
270
+ proof_session_artifact_url: any;
262
271
  } | null;
263
272
  pr_state: any;
264
273
  cleanup: Record<string, unknown> | null;
@@ -339,6 +348,9 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
339
348
  last_requested_advance_stage: any;
340
349
  recon_results: any;
341
350
  verify_results: any;
351
+ proof_session: any;
352
+ parent_proof_session: any;
353
+ proof_session_artifact_url: any;
342
354
  } | null;
343
355
  approval: any;
344
356
  error: any;
@@ -422,6 +434,9 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
422
434
  last_requested_advance_stage: any;
423
435
  recon_results: any;
424
436
  verify_results: any;
437
+ proof_session: any;
438
+ parent_proof_session: any;
439
+ proof_session_artifact_url: any;
425
440
  } | null;
426
441
  decisionRequest: any;
427
442
  checkpointContract: any;
@@ -509,6 +524,9 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
509
524
  last_requested_advance_stage: any;
510
525
  recon_results: any;
511
526
  verify_results: any;
527
+ proof_session: any;
528
+ parent_proof_session: any;
529
+ proof_session_artifact_url: any;
512
530
  };
513
531
  state_path: string;
514
532
  ok?: undefined;
@@ -594,6 +612,9 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
594
612
  last_requested_advance_stage: any;
595
613
  recon_results: any;
596
614
  verify_results: any;
615
+ proof_session: any;
616
+ parent_proof_session: any;
617
+ proof_session_artifact_url: any;
597
618
  } | null;
598
619
  shipReport: any;
599
620
  checkpointContract: Record<string, unknown>;
@@ -674,6 +695,9 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
674
695
  last_requested_advance_stage: any;
675
696
  recon_results: any;
676
697
  verify_results: any;
698
+ proof_session: any;
699
+ parent_proof_session: any;
700
+ proof_session_artifact_url: any;
677
701
  } | null;
678
702
  approval: null;
679
703
  autoApproved: any;