@riddledc/riddle-proof 0.7.159 → 0.7.161

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.
package/dist/profile.cjs CHANGED
@@ -96,6 +96,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
96
96
  "fill",
97
97
  "set_input_value",
98
98
  "set_range_value",
99
+ "canvas_signature",
99
100
  "assert_text_visible",
100
101
  "assert_text_absent",
101
102
  "assert_selector_count",
@@ -597,6 +598,26 @@ function profileSetupRangeValueReceipts(results) {
597
598
  reason: result.reason ?? result.error ?? null
598
599
  }));
599
600
  }
601
+ function profileSetupCanvasSignatureReceipts(results) {
602
+ return results.filter((result) => profileSetupResultAction(result) === "canvas_signature").map((result) => ({
603
+ ordinal: result.ordinal ?? null,
604
+ ok: result.ok !== false,
605
+ selector: result.selector ?? null,
606
+ frame_selector: result.frame_selector ?? null,
607
+ label: result.label ?? null,
608
+ hash: result.hash ?? null,
609
+ data_length: result.data_length ?? null,
610
+ width: result.width ?? null,
611
+ height: result.height ?? null,
612
+ css_width: result.css_width ?? null,
613
+ css_height: result.css_height ?? null,
614
+ compare_to: result.compare_to ?? null,
615
+ previous_hash: result.previous_hash ?? null,
616
+ changed: result.changed ?? null,
617
+ return_stored_to: result.return_stored_to ?? null,
618
+ reason: result.reason ?? result.error ?? null
619
+ }));
620
+ }
600
621
  function sampleProfileSetupSummaryItems(items, limit) {
601
622
  if (items.length <= limit) return items;
602
623
  const firstCount = Math.floor(limit / 2);
@@ -641,6 +662,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
641
662
  const sampledWindowEvalReceipts = sampleProfileSetupSummaryItems(windowEvalReceipts, 8);
642
663
  const rangeValueReceipts = profileSetupRangeValueReceipts(results);
643
664
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
665
+ const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
666
+ const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
644
667
  const clickedItems = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => {
645
668
  const clickCount = typeof result.click_count === "number" && Number.isFinite(result.click_count) && result.click_count > 1 ? result.click_count : void 0;
646
669
  return {
@@ -692,6 +715,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
692
715
  set_range_value_total: rangeValueReceipts.length,
693
716
  set_range_value_truncated: rangeValueReceipts.length > sampledRangeValueReceipts.length,
694
717
  set_range_value: sampledRangeValueReceipts,
718
+ canvas_signature_total: canvasSignatureReceipts.length,
719
+ canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
720
+ canvas_signature: sampledCanvasSignatureReceipts,
695
721
  clicked,
696
722
  text_samples,
697
723
  failed: failed.map((result) => ({
@@ -744,7 +770,7 @@ function isSupportedCheckType(value) {
744
770
  }
745
771
  function normalizeSetupActionType(value, index) {
746
772
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
747
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
773
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
748
774
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
749
775
  return normalized;
750
776
  }
@@ -873,7 +899,7 @@ function normalizeSetupAction(input, index) {
873
899
  if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
874
900
  throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
875
901
  }
876
- if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "set_range_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
902
+ if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "set_range_value" || type === "canvas_signature" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
877
903
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
878
904
  }
879
905
  const fromX = numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
@@ -967,7 +993,11 @@ function normalizeSetupAction(input, index) {
967
993
  "assign_return_to",
968
994
  "assignReturnTo",
969
995
  "return_state_path",
970
- "returnStatePath"
996
+ "returnStatePath",
997
+ "store_signature_to",
998
+ "storeSignatureTo",
999
+ "signature_path",
1000
+ "signaturePath"
971
1001
  );
972
1002
  const captureReturn = input.capture_return === false || input.captureReturn === false || input.include_return === false || input.includeReturn === false || input.omit_return === true || input.omitReturn === true ? false : void 0;
973
1003
  const untilPath = stringFromOwn(input, "until_path", "untilPath", "until_state_path", "untilStatePath", "until_window_path", "untilWindowPath", "until");
@@ -1019,6 +1049,8 @@ function normalizeSetupAction(input, index) {
1019
1049
  store_return_to: storeReturnTo,
1020
1050
  capture_return: captureReturn,
1021
1051
  return_summary_fields: normalizeReturnSummaryFields(input, index),
1052
+ compare_to: stringFromOwn(input, "compare_to", "compareTo", "previous_signature_path", "previousSignaturePath", "previous_path", "previousPath", "changed_from", "changedFrom"),
1053
+ expect_changed: booleanValue(valueFromOwn(input, "expect_changed", "expectChanged", "should_change", "shouldChange", "changed")),
1022
1054
  until_path: untilPath,
1023
1055
  until_expected_value: hasUntilExpectedValue ? toJsonValue(valueFromOwn(input, "until_expected_value", "untilExpectedValue", "until_expected", "untilExpected", "until_value", "untilValue", "expected_value", "expectedValue", "expected")) : void 0,
1024
1056
  max_calls: maxCalls,
@@ -4145,6 +4177,28 @@ function profileSetupRangeValueReceipts(results) {
4145
4177
  reason: result.reason || result.error || null,
4146
4178
  }));
4147
4179
  }
4180
+ function profileSetupCanvasSignatureReceipts(results) {
4181
+ return (results || [])
4182
+ .filter((result) => result && profileSetupResultAction(result) === "canvas_signature")
4183
+ .map((result) => ({
4184
+ ordinal: result.ordinal ?? null,
4185
+ ok: result.ok !== false,
4186
+ selector: result.selector ?? null,
4187
+ frame_selector: result.frame_selector ?? null,
4188
+ label: result.label ?? null,
4189
+ hash: result.hash ?? null,
4190
+ data_length: result.data_length ?? null,
4191
+ width: result.width ?? null,
4192
+ height: result.height ?? null,
4193
+ css_width: result.css_width ?? null,
4194
+ css_height: result.css_height ?? null,
4195
+ compare_to: result.compare_to ?? null,
4196
+ previous_hash: result.previous_hash ?? null,
4197
+ changed: result.changed ?? null,
4198
+ return_stored_to: result.return_stored_to ?? null,
4199
+ reason: result.reason || result.error || null,
4200
+ }));
4201
+ }
4148
4202
  function sampleProfileSetupSummaryItems(items, limit) {
4149
4203
  if ((items || []).length <= limit) return items || [];
4150
4204
  const firstCount = Math.floor(limit / 2);
@@ -4203,6 +4257,8 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4203
4257
  const sampledWindowEvalReceipts = sampleProfileSetupSummaryItems(windowEvalReceipts, 8);
4204
4258
  const rangeValueReceipts = profileSetupRangeValueReceipts(results);
4205
4259
  const sampledRangeValueReceipts = sampleProfileSetupSummaryItems(rangeValueReceipts, 8);
4260
+ const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
4261
+ const sampledCanvasSignatureReceipts = sampleProfileSetupSummaryItems(canvasSignatureReceipts, 8);
4206
4262
  const clickedItems = results
4207
4263
  .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
4208
4264
  .map((result) => {
@@ -4264,6 +4320,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
4264
4320
  set_range_value_total: rangeValueReceipts.length,
4265
4321
  set_range_value_truncated: rangeValueReceipts.length > sampledRangeValueReceipts.length,
4266
4322
  set_range_value: sampledRangeValueReceipts,
4323
+ canvas_signature_total: canvasSignatureReceipts.length,
4324
+ canvas_signature_truncated: canvasSignatureReceipts.length > sampledCanvasSignatureReceipts.length,
4325
+ canvas_signature: sampledCanvasSignatureReceipts,
4267
4326
  clicked,
4268
4327
  text_samples: textSamples,
4269
4328
  failed: failed.map((result) => ({
@@ -5738,6 +5797,54 @@ async function executeSetupAction(action, ordinal, viewport) {
5738
5797
  const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5739
5798
  const rect = element.getBoundingClientRect();
5740
5799
  const pointerId = payload.pointerType === "touch" ? 11 : 12;
5800
+ const capturedPointers = new Set();
5801
+ const originalOwnSetPointerCapture = Object.getOwnPropertyDescriptor(element, "setPointerCapture");
5802
+ const originalOwnReleasePointerCapture = Object.getOwnPropertyDescriptor(element, "releasePointerCapture");
5803
+ const originalOwnHasPointerCapture = Object.getOwnPropertyDescriptor(element, "hasPointerCapture");
5804
+ const originalSetPointerCapture = typeof element.setPointerCapture === "function" ? element.setPointerCapture.bind(element) : undefined;
5805
+ const originalReleasePointerCapture = typeof element.releasePointerCapture === "function" ? element.releasePointerCapture.bind(element) : undefined;
5806
+ const originalHasPointerCapture = typeof element.hasPointerCapture === "function" ? element.hasPointerCapture.bind(element) : undefined;
5807
+ const restorePointerCapture = () => {
5808
+ if (originalOwnSetPointerCapture) Object.defineProperty(element, "setPointerCapture", originalOwnSetPointerCapture);
5809
+ else delete (element as any).setPointerCapture;
5810
+ if (originalOwnReleasePointerCapture) Object.defineProperty(element, "releasePointerCapture", originalOwnReleasePointerCapture);
5811
+ else delete (element as any).releasePointerCapture;
5812
+ if (originalOwnHasPointerCapture) Object.defineProperty(element, "hasPointerCapture", originalOwnHasPointerCapture);
5813
+ else delete (element as any).hasPointerCapture;
5814
+ };
5815
+ Object.defineProperty(element, "setPointerCapture", {
5816
+ configurable: true,
5817
+ value: (activePointerId) => {
5818
+ capturedPointers.add(activePointerId);
5819
+ try {
5820
+ return originalSetPointerCapture?.(activePointerId);
5821
+ } catch {
5822
+ return undefined;
5823
+ }
5824
+ },
5825
+ });
5826
+ Object.defineProperty(element, "releasePointerCapture", {
5827
+ configurable: true,
5828
+ value: (activePointerId) => {
5829
+ capturedPointers.delete(activePointerId);
5830
+ try {
5831
+ return originalReleasePointerCapture?.(activePointerId);
5832
+ } catch {
5833
+ return undefined;
5834
+ }
5835
+ },
5836
+ });
5837
+ Object.defineProperty(element, "hasPointerCapture", {
5838
+ configurable: true,
5839
+ value: (activePointerId) => {
5840
+ if (capturedPointers.has(activePointerId)) return true;
5841
+ try {
5842
+ return Boolean(originalHasPointerCapture?.(activePointerId));
5843
+ } catch {
5844
+ return false;
5845
+ }
5846
+ },
5847
+ });
5741
5848
  const point = (progress) => ({
5742
5849
  clientX: rect.left + payload.start.x + (payload.end.x - payload.start.x) * progress,
5743
5850
  clientY: rect.top + payload.start.y + (payload.end.y - payload.start.y) * progress,
@@ -5757,16 +5864,20 @@ async function executeSetupAction(action, ordinal, viewport) {
5757
5864
  clientY: coords.clientY,
5758
5865
  }));
5759
5866
  };
5760
- dispatch("pointerover", 0);
5761
- dispatch("pointerenter", 0);
5762
- dispatch("pointerdown", 0);
5763
- for (let step = 1; step <= payload.steps; step += 1) {
5764
- dispatch("pointermove", step / payload.steps);
5765
- if (payload.durationMs && payload.steps > 1) await wait(payload.durationMs / payload.steps);
5867
+ try {
5868
+ dispatch("pointerover", 0);
5869
+ dispatch("pointerenter", 0);
5870
+ dispatch("pointerdown", 0);
5871
+ for (let step = 1; step <= payload.steps; step += 1) {
5872
+ dispatch("pointermove", step / payload.steps);
5873
+ if (payload.durationMs && payload.steps > 1) await wait(payload.durationMs / payload.steps);
5874
+ }
5875
+ dispatch("pointerup", 1);
5876
+ dispatch("pointerout", 1);
5877
+ dispatch("pointerleave", 1);
5878
+ } finally {
5879
+ restorePointerCapture();
5766
5880
  }
5767
- dispatch("pointerup", 1);
5768
- dispatch("pointerout", 1);
5769
- dispatch("pointerleave", 1);
5770
5881
  }, {
5771
5882
  pointerType,
5772
5883
  start: localStart,
@@ -5806,6 +5917,7 @@ async function executeSetupAction(action, ordinal, viewport) {
5806
5917
  to_x: toX,
5807
5918
  to_y: toY,
5808
5919
  pointer_type: pointerType,
5920
+ pointer_capture_polyfill: pointerType === "touch" || pointerType === "pen" ? true : undefined,
5809
5921
  steps,
5810
5922
  duration_ms: durationMs || undefined,
5811
5923
  };
@@ -6279,6 +6391,156 @@ async function executeSetupAction(action, ordinal, viewport) {
6279
6391
  reason: rangeResult && rangeResult.ok === true ? undefined : rangeResult?.reason || "range_value_not_set",
6280
6392
  };
6281
6393
  }
6394
+ if (type === "canvas_signature") {
6395
+ const scope = await setupActionScope(action, timeout);
6396
+ if (!scope.ok) return setupScopeFailure(base, scope);
6397
+ const locator = scope.context.locator(action.selector);
6398
+ const count = await locator.count();
6399
+ if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
6400
+ const targetIndex = Number.isInteger(action.index) ? action.index : 0;
6401
+ if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
6402
+ const target = locator.nth(targetIndex);
6403
+ await target.waitFor({ state: "visible", timeout });
6404
+ const storeReturnTo = String(action.store_return_to || action.storeReturnTo || action.save_return_to || action.saveReturnTo || action.store_signature_to || action.storeSignatureTo || action.signature_path || action.signaturePath || "").trim();
6405
+ const compareTo = String(action.compare_to || action.compareTo || action.previous_signature_path || action.previousSignaturePath || action.previous_path || action.previousPath || action.changed_from || action.changedFrom || "").trim();
6406
+ const expectChanged = action.expect_changed === true || action.expectChanged === true || action.should_change === true || action.shouldChange === true || action.changed === true
6407
+ ? true
6408
+ : action.expect_changed === false || action.expectChanged === false || action.should_change === false || action.shouldChange === false || action.changed === false
6409
+ ? false
6410
+ : undefined;
6411
+ const signatureResult = await target.evaluate((element, payload) => {
6412
+ const toJsonValue = (value) => {
6413
+ if (value === null || value === undefined) return null;
6414
+ if (typeof value === "string" || typeof value === "boolean") return value;
6415
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
6416
+ if (Array.isArray(value)) return value.map(toJsonValue);
6417
+ if (typeof value === "object") {
6418
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
6419
+ }
6420
+ return String(value);
6421
+ };
6422
+ const pathParts = (path) => String(path || "").split(".").map((part) => part.trim()).filter(Boolean);
6423
+ const readWindowPath = (path) => {
6424
+ const parts = pathParts(path);
6425
+ if (parts[0] === "window") parts.shift();
6426
+ if (!parts.length) return { ok: false, reason: "missing_path" };
6427
+ let current = window;
6428
+ for (const part of parts) {
6429
+ if (current === null || current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
6430
+ current = current[part];
6431
+ if (current === undefined) return { ok: false, reason: "path_not_found", missing_part: part };
6432
+ }
6433
+ return { ok: true, value: toJsonValue(current) };
6434
+ };
6435
+ const storeWindowValue = (path, value) => {
6436
+ const parts = pathParts(path);
6437
+ if (parts[0] === "window") parts.shift();
6438
+ if (!parts.length) return { ok: false, reason: "missing_store_path" };
6439
+ let target = window;
6440
+ for (let index = 0; index < parts.length - 1; index += 1) {
6441
+ const part = parts[index];
6442
+ if (target[part] === null || typeof target[part] !== "object") target[part] = {};
6443
+ target = target[part];
6444
+ }
6445
+ target[parts[parts.length - 1]] = value;
6446
+ return { ok: true, path: parts.join(".") };
6447
+ };
6448
+ const hashText = (text) => {
6449
+ let hash = 2166136261;
6450
+ const step = Math.max(1, Math.floor((text.length || 1) / 4000));
6451
+ for (let index = 0; index < text.length; index += step) {
6452
+ hash ^= text.charCodeAt(index);
6453
+ hash = Math.imul(hash, 16777619) >>> 0;
6454
+ }
6455
+ return String(hash);
6456
+ };
6457
+ const tag = String(element && element.tagName ? element.tagName : "").toLowerCase();
6458
+ if (tag !== "canvas") return { ok: false, reason: "not_canvas_element", tag };
6459
+ const rect = element.getBoundingClientRect();
6460
+ let data = "";
6461
+ try {
6462
+ data = element.toDataURL("image/png");
6463
+ } catch (error) {
6464
+ return {
6465
+ ok: false,
6466
+ reason: "canvas_read_failed",
6467
+ error: String(error && error.message ? error.message : error).slice(0, 1000),
6468
+ width: element.width || 0,
6469
+ height: element.height || 0,
6470
+ css_width: Math.round(rect.width || 0),
6471
+ css_height: Math.round(rect.height || 0),
6472
+ };
6473
+ }
6474
+ const result = {
6475
+ ok: Boolean(element.width > 0 && element.height > 0 && data.length > 0),
6476
+ reason: element.width > 0 && element.height > 0 && data.length > 0 ? undefined : "empty_canvas_signature",
6477
+ hash: hashText(data),
6478
+ data_length: data.length,
6479
+ width: element.width || 0,
6480
+ height: element.height || 0,
6481
+ css_width: Math.round(rect.width || 0),
6482
+ css_height: Math.round(rect.height || 0),
6483
+ compare_to: payload.compareTo || undefined,
6484
+ previous_hash: null,
6485
+ changed: null,
6486
+ };
6487
+ if (payload.compareTo) {
6488
+ const previous = readWindowPath(payload.compareTo);
6489
+ if (!previous.ok) {
6490
+ result.ok = false;
6491
+ result.reason = previous.reason || "compare_path_not_found";
6492
+ result.missing_part = previous.missing_part || undefined;
6493
+ } else {
6494
+ const previousValue = previous.value;
6495
+ const previousHash = previousValue && typeof previousValue === "object" && !Array.isArray(previousValue)
6496
+ ? previousValue.hash || previousValue.signature || previousValue.canvas_hash || null
6497
+ : typeof previousValue === "string"
6498
+ ? previousValue
6499
+ : null;
6500
+ result.previous_hash = previousHash === null || previousHash === undefined ? null : String(previousHash);
6501
+ result.changed = result.previous_hash === null ? null : result.previous_hash !== result.hash;
6502
+ if (payload.expectChanged === true && result.changed !== true) {
6503
+ result.ok = false;
6504
+ result.reason = "canvas_signature_unchanged";
6505
+ } else if (payload.expectChanged === false && result.changed !== false) {
6506
+ result.ok = false;
6507
+ result.reason = "canvas_signature_changed";
6508
+ }
6509
+ }
6510
+ }
6511
+ if (payload.storeReturnTo) {
6512
+ const stored = storeWindowValue(payload.storeReturnTo, result);
6513
+ if (!stored.ok) {
6514
+ return { ...result, ok: false, reason: "signature_store_failed", store_reason: stored.reason };
6515
+ }
6516
+ return { ...result, return_stored_to: stored.path };
6517
+ }
6518
+ return result;
6519
+ }, { compareTo, expectChanged, storeReturnTo });
6520
+ return {
6521
+ ...base,
6522
+ ...setupScopeEvidence(scope),
6523
+ ok: signatureResult && signatureResult.ok === true,
6524
+ count,
6525
+ target_index: targetIndex,
6526
+ label: action.label || action.name || undefined,
6527
+ hash: signatureResult?.hash,
6528
+ data_length: signatureResult?.data_length,
6529
+ width: signatureResult?.width,
6530
+ height: signatureResult?.height,
6531
+ css_width: signatureResult?.css_width,
6532
+ css_height: signatureResult?.css_height,
6533
+ compare_to: signatureResult?.compare_to || compareTo || undefined,
6534
+ previous_hash: signatureResult?.previous_hash,
6535
+ changed: signatureResult?.changed,
6536
+ return_stored_to: signatureResult?.return_stored_to || storeReturnTo || undefined,
6537
+ missing_part: signatureResult?.missing_part || undefined,
6538
+ store_reason: signatureResult?.store_reason || undefined,
6539
+ tag: signatureResult?.tag,
6540
+ reason: signatureResult && signatureResult.ok === true ? undefined : signatureResult?.reason || "canvas_signature_failed",
6541
+ error: signatureResult?.error || undefined,
6542
+ };
6543
+ }
6282
6544
  if (type === "assert_selector_count") {
6283
6545
  const scope = await setupActionScope(action, timeout);
6284
6546
  if (!scope.ok) return setupScopeFailure(base, scope);
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
7
  declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "observe_within", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
8
- declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "set_range_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
8
+ declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "set_range_value", "canvas_signature", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
11
11
  type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
@@ -134,6 +134,8 @@ interface RiddleProofProfileSetupAction {
134
134
  store_return_to?: string;
135
135
  capture_return?: boolean;
136
136
  return_summary_fields?: RiddleProofProfileReturnSummaryField[];
137
+ compare_to?: string;
138
+ expect_changed?: boolean;
137
139
  until_path?: string;
138
140
  until_expected_value?: JsonValue;
139
141
  max_calls?: number;
package/dist/profile.d.ts CHANGED
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
5
5
  declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
6
6
  declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
7
7
  declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "observe_within", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
8
- declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "set_range_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
8
+ declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "set_range_value", "canvas_signature", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_eval", "window_call", "window_call_until"];
9
9
  type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
10
10
  type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
11
11
  type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
@@ -134,6 +134,8 @@ interface RiddleProofProfileSetupAction {
134
134
  store_return_to?: string;
135
135
  capture_return?: boolean;
136
136
  return_summary_fields?: RiddleProofProfileReturnSummaryField[];
137
+ compare_to?: string;
138
+ expect_changed?: boolean;
137
139
  until_path?: string;
138
140
  until_expected_value?: JsonValue;
139
141
  max_calls?: number;
package/dist/profile.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  resolveRiddleProofProfileTimeoutSec,
24
24
  slugifyRiddleProofProfileName,
25
25
  summarizeRiddleProofProfileResult
26
- } from "./chunk-TBTMD5WV.js";
26
+ } from "./chunk-ZE2U5EML.js";
27
27
  export {
28
28
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,
29
29
  RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
295
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
385
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
662
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
292
292
  blocking?: boolean;
293
293
  details?: Record<string, unknown>;
294
294
  ok: boolean;
295
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
295
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
296
296
  state_path: string;
297
297
  stage: any;
298
298
  summary: string;
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
382
382
  continueWithStage?: WorkflowStage | null;
383
383
  blocking?: boolean;
384
384
  details?: Record<string, unknown>;
385
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
385
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
386
386
  state_path: string;
387
387
  stage: any;
388
388
  checkpoint: string;
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
659
659
  error?: undefined;
660
660
  } | {
661
661
  ok: boolean;
662
- action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
662
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.159",
3
+ "version": "0.7.161",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",