@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
@@ -81,6 +81,11 @@ function ensureAction(action) {
81
81
  function workflowFile(riddleProofDir, action) {
82
82
  return import_node_path.default.join(riddleProofDir, "pipelines", `riddle-proof-${action}.lobster`);
83
83
  }
84
+ function asJsonString(value) {
85
+ if (value === void 0 || value === null || value === "") return "";
86
+ if (typeof value === "string") return value;
87
+ return JSON.stringify(value);
88
+ }
84
89
  function buildSetupArgs(params, config) {
85
90
  if (!params.repo) throw new Error("repo is required for setup/run");
86
91
  if (!params.change_request) throw new Error("change_request is required for setup/run");
@@ -96,8 +101,13 @@ function buildSetupArgs(params, config) {
96
101
  prod_url: params.prod_url || "",
97
102
  capture_script: captureScript,
98
103
  success_criteria: params.success_criteria || "",
99
- assertions_json: params.assertions_json || "",
104
+ assertions_json: params.assertions_json || asJsonString(params.assertions),
100
105
  verification_mode: params.verification_mode || "proof",
106
+ resume_session: params.resume_session || "",
107
+ target_image_url: params.target_image_url || "",
108
+ target_image_hash: params.target_image_hash || "",
109
+ viewport_matrix_json: params.viewport_matrix_json || asJsonString(params.viewport_matrix),
110
+ deterministic_setup_json: params.deterministic_setup_json || asJsonString(params.deterministic_setup),
101
111
  reference: requestedReference,
102
112
  base_branch: params.base_branch || "main",
103
113
  before_ref: params.before_ref || "",
@@ -340,6 +350,44 @@ function normalizedProofAssessment(state = {}) {
340
350
  source: source || null
341
351
  };
342
352
  }
353
+ function objectValue(value) {
354
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
355
+ }
356
+ function normalizedVerificationMode(state = {}) {
357
+ const bundle = objectValue(state?.evidence_bundle);
358
+ const bundleMode = String(bundle.verification_mode || "").trim().toLowerCase();
359
+ if (bundleMode) return bundleMode;
360
+ return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
361
+ }
362
+ function visualDeltaRequiredForState(state = {}) {
363
+ const bundle = objectValue(state?.evidence_bundle);
364
+ const contract = objectValue(bundle.artifact_contract);
365
+ const required = objectValue(contract.required);
366
+ return required.visual_delta === true || VISUAL_FIRST_MODES.has(normalizedVerificationMode(state));
367
+ }
368
+ function visualDeltaForState(state = {}) {
369
+ const bundle = objectValue(state?.evidence_bundle);
370
+ const after = objectValue(bundle.after);
371
+ const afterDelta = objectValue(after.visual_delta);
372
+ if (Object.keys(afterDelta).length) return afterDelta;
373
+ const request = objectValue(state?.proof_assessment_request);
374
+ return objectValue(request.visual_delta);
375
+ }
376
+ function visualDeltaShipGateReason(state = {}) {
377
+ if (!visualDeltaRequiredForState(state)) return null;
378
+ const visualDelta = visualDeltaForState(state);
379
+ if (visualDelta.status === "measured" && visualDelta.passed === true) return null;
380
+ const status = String(visualDelta.status || "missing");
381
+ if (status === "unmeasured") {
382
+ return "visual_delta.status=unmeasured blocks ready_to_ship for visual/UI proof";
383
+ }
384
+ if (status === "measured" && visualDelta.passed === false) {
385
+ return "visual_delta.status=measured but visual_delta.passed=false blocks ready_to_ship for visual/UI proof";
386
+ }
387
+ const reason = String(visualDelta.reason || "").trim();
388
+ if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
389
+ return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
390
+ }
343
391
  function requiredBaselineLabelsForState(state = {}) {
344
392
  const reference = normalizedReference(state);
345
393
  const labels = [];
@@ -355,6 +403,10 @@ function validateShipGate(state = {}) {
355
403
  const afterCdn = String(state?.after_cdn || "").trim();
356
404
  const verifyStatus = String(state?.verify_status || "").trim();
357
405
  const proofAssessment = normalizedProofAssessment(state);
406
+ const verificationMode = normalizedVerificationMode(state);
407
+ const visualDelta = visualDeltaForState(state);
408
+ const visualDeltaRequired = visualDeltaRequiredForState(state);
409
+ const visualDeltaBlocker = visualDeltaShipGateReason(state);
358
410
  const reasons = [];
359
411
  if (!["before", "prod", "both"].includes(reference)) {
360
412
  reasons.push(`reference must be before, prod, or both; got ${reference}`);
@@ -383,19 +435,26 @@ function validateShipGate(state = {}) {
383
435
  if (proofAssessment.decision !== "ready_to_ship") {
384
436
  reasons.push("proof_assessment.decision must be ready_to_ship before ship");
385
437
  }
438
+ if (visualDeltaBlocker) {
439
+ reasons.push(visualDeltaBlocker);
440
+ }
386
441
  return {
387
442
  ok: reasons.length === 0,
388
443
  reasons,
389
444
  required_baselines: requiredBaselines,
390
445
  evidence: {
391
446
  reference,
447
+ verification_mode: verificationMode || null,
392
448
  prod_url: prodUrl || null,
393
449
  before_cdn: beforeCdn || null,
394
450
  prod_cdn: prodCdn || null,
395
451
  after_cdn: afterCdn || null,
396
452
  verify_status: verifyStatus || null,
397
453
  proof_assessment_decision: proofAssessment.decision,
398
- proof_assessment_source: proofAssessment.source
454
+ proof_assessment_source: proofAssessment.source,
455
+ visual_delta_required: visualDeltaRequired,
456
+ visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
457
+ visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
399
458
  }
400
459
  };
401
460
  }
@@ -440,6 +499,11 @@ function mergeStateFromParams(statePath, params) {
440
499
  "success_criteria",
441
500
  "assertions_json",
442
501
  "verification_mode",
502
+ "resume_session",
503
+ "target_image_url",
504
+ "target_image_hash",
505
+ "viewport_matrix_json",
506
+ "deterministic_setup_json",
443
507
  "base_branch",
444
508
  "before_ref",
445
509
  "context",
@@ -541,23 +605,36 @@ function mergeStateFromParams(statePath, params) {
541
605
  state.proof_assessment_source = null;
542
606
  } else {
543
607
  const parsed = JSON.parse(raw);
544
- state.proof_assessment = {
608
+ const assessment = {
545
609
  ...parsed,
546
610
  source: (parsed?.source || "supervising_agent").toString()
547
611
  };
612
+ const readyBlocker = assessment?.decision === "ready_to_ship" ? visualDeltaShipGateReason({ ...state, proof_assessment: assessment, proof_assessment_source: assessment.source }) : null;
613
+ if (readyBlocker) {
614
+ assessment.blocked_decision = assessment.decision;
615
+ assessment.decision = "needs_richer_proof";
616
+ if (assessment.recommended_stage === "ship") assessment.recommended_stage = "verify";
617
+ if (assessment.continue_with_stage === "ship") assessment.continue_with_stage = "verify";
618
+ const blockers = Array.isArray(assessment.blockers) ? assessment.blockers : [];
619
+ assessment.blockers = [...blockers, readyBlocker];
620
+ }
621
+ state.proof_assessment = assessment;
548
622
  state.proof_assessment_source = state.proof_assessment.source;
549
- if (typeof parsed?.decision === "string") {
550
- state.proof_decision = parsed.decision;
623
+ if (typeof state.proof_assessment?.decision === "string") {
624
+ state.proof_decision = state.proof_assessment.decision;
551
625
  }
552
626
  if (typeof parsed?.summary === "string") {
553
627
  state.proof_assessment_summary = normalizeOptionalString(parsed.summary) || null;
554
628
  }
555
- if (parsed?.decision === "ready_to_ship") {
629
+ if (state.proof_assessment?.decision === "ready_to_ship") {
556
630
  state.merge_recommendation = "ready-to-ship";
557
- } else if (typeof parsed?.decision === "string" && parsed.decision.trim()) {
631
+ } else if (typeof state.proof_assessment?.decision === "string" && state.proof_assessment.decision.trim()) {
558
632
  state.merge_recommendation = "do-not-merge";
559
633
  }
560
634
  appendProofSummaryLine(state, `Supervising proof assessment: ${state.proof_assessment.decision || "unknown"}`);
635
+ if (readyBlocker) {
636
+ appendProofSummaryLine(state, `Ready-to-ship assessment blocked: ${readyBlocker}`);
637
+ }
561
638
  if (state.proof_assessment_summary) {
562
639
  appendProofSummaryLine(state, `Assessment summary: ${state.proof_assessment_summary}`);
563
640
  }
@@ -658,7 +735,10 @@ function summarizeState(state) {
658
735
  explicit_stage_gate: Boolean(state.explicit_stage_gate),
659
736
  last_requested_advance_stage: state.last_requested_advance_stage || null,
660
737
  recon_results: state.recon_results || null,
661
- verify_results: state.verify_results || null
738
+ verify_results: state.verify_results || null,
739
+ proof_session: state.proof_session || null,
740
+ parent_proof_session: state.parent_proof_session || null,
741
+ proof_session_artifact_url: state.proof_session_artifact_url || null
662
742
  };
663
743
  const parts = [
664
744
  state.workspace_ready ? "workspace ready" : "workspace not ready",
@@ -679,7 +759,7 @@ function summarizeState(state) {
679
759
  state: selected
680
760
  };
681
761
  }
682
- var import_node_fs, import_node_crypto, import_node_path, import_node_url, import_meta, WORKFLOW_STAGE_ORDER, CHECKPOINT_CONTRACT_VERSION, BUNDLED_RIDDLE_PROOF_DIR, RIDDLE_PROOF_DIR_CANDIDATES, CHECKPOINT_CONTRACT_SPECS;
762
+ var import_node_fs, import_node_crypto, import_node_path, import_node_url, import_meta, WORKFLOW_STAGE_ORDER, CHECKPOINT_CONTRACT_VERSION, BUNDLED_RIDDLE_PROOF_DIR, RIDDLE_PROOF_DIR_CANDIDATES, VISUAL_FIRST_MODES, CHECKPOINT_CONTRACT_SPECS;
683
763
  var init_proof_run_core = __esm({
684
764
  "src/proof-run-core.ts"() {
685
765
  "use strict";
@@ -698,6 +778,16 @@ var init_proof_run_core = __esm({
698
778
  RIDDLE_PROOF_DIR_CANDIDATES = [
699
779
  BUNDLED_RIDDLE_PROOF_DIR
700
780
  ];
781
+ VISUAL_FIRST_MODES = /* @__PURE__ */ new Set([
782
+ "visual",
783
+ "render",
784
+ "interaction",
785
+ "ui",
786
+ "layout",
787
+ "screenshot",
788
+ "canvas",
789
+ "animation"
790
+ ]);
701
791
  CHECKPOINT_CONTRACT_SPECS = {
702
792
  setup_review: {
703
793
  purpose: "Inspect prepared workspace state before moving into recon."
@@ -1624,6 +1714,9 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
1624
1714
  if (reasons.some((reason) => reason.includes("proof_assessment"))) {
1625
1715
  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";
1626
1716
  }
1717
+ if (reasons.some((reason) => reason.includes("visual_delta"))) {
1718
+ return "rerun verify with a measured before/after visual delta, or choose needs_richer_proof instead of ready_to_ship for this visual proof";
1719
+ }
1627
1720
  if (reasons.some((reason) => reason.includes("after_cdn") || reason.includes("verify_status"))) {
1628
1721
  return "rerun verify with stronger proof framing so after evidence is captured before shipping";
1629
1722
  }
@@ -2852,6 +2945,7 @@ function createRunResult(input) {
2852
2945
  merge_recommendation: state.merge_recommendation,
2853
2946
  finalized: state.finalized,
2854
2947
  blocker: state.blocker,
2948
+ proof_session: state.proof_session,
2855
2949
  evidence_bundle: input.evidence_bundle,
2856
2950
  raw: input.raw
2857
2951
  });
@@ -2899,6 +2993,11 @@ function normalizeRunParams(input) {
2899
2993
  success_criteria: input.success_criteria,
2900
2994
  assertions: input.assertions,
2901
2995
  verification_mode: input.verification_mode,
2996
+ resume_session: input.resume_session,
2997
+ target_image_url: input.target_image_url,
2998
+ target_image_hash: input.target_image_hash,
2999
+ viewport_matrix: input.viewport_matrix,
3000
+ deterministic_setup: input.deterministic_setup,
2902
3001
  reference: input.reference,
2903
3002
  base_branch: input.base_branch,
2904
3003
  before_ref: input.before_ref,
@@ -3028,6 +3127,7 @@ function setRunStatus(state, status, at = timestamp()) {
3028
3127
  }
3029
3128
 
3030
3129
  // src/engine-harness.ts
3130
+ init_proof_run_core();
3031
3131
  var DEFAULT_MAX_ITERATIONS = 12;
3032
3132
  var DEFAULT_STAGE_ITERATION_LIMITS = {
3033
3133
  setup: 2,
@@ -3292,6 +3392,26 @@ function proofAssessmentContinuation(result, payload) {
3292
3392
  const proof_assessment_json = jsonParam(payload);
3293
3393
  return { ...baseContinuation(result), proof_assessment_json };
3294
3394
  }
3395
+ function proofAssessmentVisualBlocker(state, payload) {
3396
+ if (!proofAssessmentRequestsShip(payload)) return null;
3397
+ const source = nonEmptyString(payload.source) || "supervising_agent";
3398
+ return visualDeltaShipGateReason({
3399
+ ...state || {},
3400
+ proof_assessment: { ...payload, source },
3401
+ proof_assessment_source: source
3402
+ });
3403
+ }
3404
+ function blockedProofAssessmentPayload(payload, blocker) {
3405
+ const blockers = Array.isArray(payload.blockers) ? payload.blockers.filter((item) => typeof item === "string") : [];
3406
+ return {
3407
+ ...payload,
3408
+ blocked_decision: payload.decision || "ready_to_ship",
3409
+ decision: "needs_richer_proof",
3410
+ recommended_stage: payload.recommended_stage === "ship" ? "verify" : payload.recommended_stage || "verify",
3411
+ continue_with_stage: payload.continue_with_stage === "ship" ? "verify" : payload.continue_with_stage || "verify",
3412
+ blockers: [...blockers, blocker]
3413
+ };
3414
+ }
3295
3415
  function contextFor(request, state, result) {
3296
3416
  return {
3297
3417
  request,
@@ -3661,6 +3781,20 @@ async function routeCheckpoint(request, state, result, agent, input) {
3661
3781
  summary: assessment.summary,
3662
3782
  details: { payload }
3663
3783
  });
3784
+ const visualBlocker = proofAssessmentVisualBlocker({
3785
+ ...context.fullRiddleState || {},
3786
+ verification_mode: context.fullRiddleState?.verification_mode || request.verification_mode
3787
+ }, payload);
3788
+ if (visualBlocker) {
3789
+ recordEvent(state, {
3790
+ kind: "agent.proof_assessment.blocked",
3791
+ checkpoint,
3792
+ stage: "verify",
3793
+ summary: visualBlocker,
3794
+ details: { payload }
3795
+ });
3796
+ return { next: proofAssessmentContinuation(result, blockedProofAssessmentPayload(payload, visualBlocker)) };
3797
+ }
3664
3798
  if (effectiveShipMode(request, input.config) !== "ship" && proofAssessmentRequestsShip(payload)) {
3665
3799
  return {
3666
3800
  terminal: terminalResult(
@@ -2,9 +2,10 @@ import {
2
2
  createDisabledRiddleProofAgentAdapter,
3
3
  readRiddleProofRunStatus,
4
4
  runRiddleProofEngineHarness
5
- } from "./chunk-LIDYNU7Q.js";
6
- import "./chunk-7ZJAUEUN.js";
7
- import "./chunk-TMMKRKY5.js";
5
+ } from "./chunk-7R6ZQE3X.js";
6
+ import "./chunk-OASB3CYU.js";
7
+ import "./chunk-4YCWZVBN.js";
8
+ import "./chunk-J2MERROF.js";
8
9
  export {
9
10
  createDisabledRiddleProofAgentAdapter,
10
11
  readRiddleProofRunStatus,