@riddledc/riddle-proof 0.8.76 → 0.8.78

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 (56) hide show
  1. package/README.md +74 -5
  2. package/dist/advanced/index.d.cts +1 -1
  3. package/dist/advanced/index.d.ts +1 -1
  4. package/dist/advanced/proof-run-engine.d.cts +1 -1
  5. package/dist/advanced/proof-run-engine.d.ts +1 -1
  6. package/dist/change-proof.cjs +991 -7
  7. package/dist/change-proof.d.cts +157 -1
  8. package/dist/change-proof.d.ts +157 -1
  9. package/dist/change-proof.js +25 -3
  10. package/dist/{chunk-B2DP2LET.js → chunk-5IFZSUPF.js} +52 -13
  11. package/dist/chunk-6VFS2JFR.js +886 -0
  12. package/dist/{chunk-CWRIXP5H.js → chunk-7N6X54WG.js} +181 -17
  13. package/dist/{chunk-GG2D3MFZ.js → chunk-FCSJZBC5.js} +26 -1
  14. package/dist/{chunk-AK2EPEVO.js → chunk-HSGZV2NK.js} +221 -63
  15. package/dist/chunk-MEVVL4TI.js +258 -0
  16. package/dist/{chunk-UE4I7RTI.js → chunk-RQPCKRKT.js} +1 -1
  17. package/dist/cli/index.js +7 -6
  18. package/dist/cli.cjs +1678 -361
  19. package/dist/cli.js +7 -6
  20. package/dist/index.cjs +1242 -42
  21. package/dist/index.d.cts +4 -3
  22. package/dist/index.d.ts +4 -3
  23. package/dist/index.js +46 -10
  24. package/dist/pr-comment.cjs +481 -17
  25. package/dist/pr-comment.d.cts +6 -1
  26. package/dist/pr-comment.d.ts +6 -1
  27. package/dist/pr-comment.js +6 -1
  28. package/dist/profile/index.cjs +26 -1
  29. package/dist/profile/index.js +1 -1
  30. package/dist/profile-suggestions.js +2 -2
  31. package/dist/profile.cjs +26 -1
  32. package/dist/profile.d.cts +7 -0
  33. package/dist/profile.d.ts +7 -0
  34. package/dist/profile.js +1 -1
  35. package/dist/{proof-run-engine-MiKZt9oY.d.ts → proof-run-engine-CsQshTUX.d.ts} +3 -3
  36. package/dist/{proof-run-engine-Baiv6l3A.d.cts → proof-run-engine-DmUqh7Cw.d.cts} +3 -3
  37. package/dist/proof-run-engine.d.cts +1 -1
  38. package/dist/proof-run-engine.d.ts +1 -1
  39. package/dist/receipts.cjs +286 -0
  40. package/dist/receipts.d.cts +115 -0
  41. package/dist/receipts.d.ts +115 -0
  42. package/dist/receipts.js +15 -0
  43. package/dist/riddle-client.cjs +98 -13
  44. package/dist/riddle-client.d.cts +18 -5
  45. package/dist/riddle-client.d.ts +18 -5
  46. package/dist/riddle-client.js +4 -1
  47. package/dist/runtime/index.cjs +98 -13
  48. package/dist/runtime/index.d.cts +5 -1
  49. package/dist/runtime/index.d.ts +5 -1
  50. package/dist/runtime/index.js +4 -1
  51. package/dist/runtime/riddle-client.cjs +98 -13
  52. package/dist/runtime/riddle-client.d.cts +5 -1
  53. package/dist/runtime/riddle-client.d.ts +5 -1
  54. package/dist/runtime/riddle-client.js +4 -1
  55. package/package.json +7 -2
  56. package/dist/chunk-6S7DZWVC.js +0 -167
@@ -834,6 +834,12 @@ function profileScreenshotLabels(viewports) {
834
834
  }
835
835
  return labels;
836
836
  }
837
+ function profileFinalScreenshotLabels(viewports) {
838
+ return (viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => typeof label === "string" && Boolean(label.trim()));
839
+ }
840
+ function profileAllSetupScreenshotLabels(viewports) {
841
+ return (viewports || []).flatMap((viewport) => profileSetupScreenshotLabels(viewport.setup_action_results || []));
842
+ }
837
843
  function profileSetupSummary(viewports, actionCount, expectedActionCountByViewport, finalScreenshotFullPage) {
838
844
  const normalizedFinalScreenshotFullPage = finalScreenshotFullPage === void 0 ? void 0 : finalScreenshotFullPage !== false;
839
845
  const finalScreenshotCount = viewports.filter((viewport) => typeof viewport.screenshot_label === "string" && viewport.screenshot_label.trim()).length;
@@ -3684,6 +3690,8 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
3684
3690
  const status = profileStatusFromEvidence(profile, evidence, checks);
3685
3691
  const firstViewport = evidence?.viewports?.[0];
3686
3692
  const screenshots = profileScreenshotLabels(evidence?.viewports);
3693
+ const canonicalScreenshots = profileFinalScreenshotLabels(evidence?.viewports);
3694
+ const setupScreenshots = profileAllSetupScreenshotLabels(evidence?.viewports);
3687
3695
  const result = {
3688
3696
  version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
3689
3697
  profile_name: profile.name,
@@ -3693,6 +3701,8 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
3693
3701
  route: routeForViewport(firstViewport, evidence?.target_url),
3694
3702
  artifacts: {
3695
3703
  screenshots,
3704
+ canonical_screenshots: canonicalScreenshots,
3705
+ setup_screenshots: setupScreenshots,
3696
3706
  console: "console.json",
3697
3707
  proof_json: "proof.json",
3698
3708
  dom_summary: "dom-summary.json",
@@ -5011,6 +5021,12 @@ function profileScreenshotLabels(viewports) {
5011
5021
  }
5012
5022
  return labels;
5013
5023
  }
5024
+ function profileFinalScreenshotLabels(viewports) {
5025
+ return (viewports || []).map((viewport) => viewport && viewport.screenshot_label).filter(Boolean);
5026
+ }
5027
+ function profileAllSetupScreenshotLabels(viewports) {
5028
+ return (viewports || []).flatMap((viewport) => profileSetupScreenshotLabels(viewport && viewport.setup_action_results || []));
5029
+ }
5014
5030
  function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewport, finalScreenshotFullPage) {
5015
5031
  const normalizedFinalScreenshotFullPage = finalScreenshotFullPage === undefined
5016
5032
  ? undefined
@@ -5879,6 +5895,8 @@ function assessProfile(profile, evidence) {
5879
5895
  else if (checks.some((check) => check.status === "needs_human_review")) status = "needs_human_review";
5880
5896
  else if (checks.some((check) => check.status === "failed")) status = "product_regression";
5881
5897
  const screenshotLabels = profileScreenshotLabels(viewports);
5898
+ const canonicalScreenshotLabels = profileFinalScreenshotLabels(viewports);
5899
+ const setupScreenshotLabels = profileAllSetupScreenshotLabels(viewports);
5882
5900
  const route = viewports[0] && viewports[0].route ? viewports[0].route : { requested: evidence.target_url, observed: "", matched: false, error: "missing viewport evidence" };
5883
5901
  const passedChecks = checks.filter((check) => check.status === "passed").length;
5884
5902
  const failedChecks = checks.filter((check) => check.status === "failed").length;
@@ -5895,7 +5913,14 @@ function assessProfile(profile, evidence) {
5895
5913
  status,
5896
5914
  baseline_policy: profile.baseline_policy || "invariant_only",
5897
5915
  route,
5898
- artifacts: { screenshots: screenshotLabels, console: "console.json", proof_json: "proof.json", dom_summary: "dom-summary.json" },
5916
+ artifacts: {
5917
+ screenshots: screenshotLabels,
5918
+ canonical_screenshots: canonicalScreenshotLabels,
5919
+ setup_screenshots: setupScreenshotLabels,
5920
+ console: "console.json",
5921
+ proof_json: "proof.json",
5922
+ dom_summary: "dom-summary.json"
5923
+ },
5899
5924
  checks,
5900
5925
  summary,
5901
5926
  captured_at: evidence.captured_at,
@@ -27,7 +27,7 @@ import {
27
27
  resolveRiddleProofProfileTimeoutSec,
28
28
  slugifyRiddleProofProfileName,
29
29
  summarizeRiddleProofProfileResult
30
- } from "../chunk-GG2D3MFZ.js";
30
+ } from "../chunk-FCSJZBC5.js";
31
31
  import "../chunk-MLKGABMK.js";
32
32
  export {
33
33
  RIDDLE_PROOF_HOSTED_PROFILE_ARTIFACTS,
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  RIDDLE_PROOF_PROFILE_SUGGESTIONS_VERSION,
3
3
  suggestRiddleProofProfileChecks
4
- } from "./chunk-UE4I7RTI.js";
5
- import "./chunk-GG2D3MFZ.js";
4
+ } from "./chunk-RQPCKRKT.js";
5
+ import "./chunk-FCSJZBC5.js";
6
6
  import "./chunk-MLKGABMK.js";
7
7
  export {
8
8
  RIDDLE_PROOF_PROFILE_SUGGESTIONS_VERSION,
package/dist/profile.cjs CHANGED
@@ -832,6 +832,12 @@ function profileScreenshotLabels(viewports) {
832
832
  }
833
833
  return labels;
834
834
  }
835
+ function profileFinalScreenshotLabels(viewports) {
836
+ return (viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => typeof label === "string" && Boolean(label.trim()));
837
+ }
838
+ function profileAllSetupScreenshotLabels(viewports) {
839
+ return (viewports || []).flatMap((viewport) => profileSetupScreenshotLabels(viewport.setup_action_results || []));
840
+ }
835
841
  function profileSetupSummary(viewports, actionCount, expectedActionCountByViewport, finalScreenshotFullPage) {
836
842
  const normalizedFinalScreenshotFullPage = finalScreenshotFullPage === void 0 ? void 0 : finalScreenshotFullPage !== false;
837
843
  const finalScreenshotCount = viewports.filter((viewport) => typeof viewport.screenshot_label === "string" && viewport.screenshot_label.trim()).length;
@@ -3682,6 +3688,8 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
3682
3688
  const status = profileStatusFromEvidence(profile, evidence, checks);
3683
3689
  const firstViewport = evidence?.viewports?.[0];
3684
3690
  const screenshots = profileScreenshotLabels(evidence?.viewports);
3691
+ const canonicalScreenshots = profileFinalScreenshotLabels(evidence?.viewports);
3692
+ const setupScreenshots = profileAllSetupScreenshotLabels(evidence?.viewports);
3685
3693
  const result = {
3686
3694
  version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
3687
3695
  profile_name: profile.name,
@@ -3691,6 +3699,8 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
3691
3699
  route: routeForViewport(firstViewport, evidence?.target_url),
3692
3700
  artifacts: {
3693
3701
  screenshots,
3702
+ canonical_screenshots: canonicalScreenshots,
3703
+ setup_screenshots: setupScreenshots,
3694
3704
  console: "console.json",
3695
3705
  proof_json: "proof.json",
3696
3706
  dom_summary: "dom-summary.json",
@@ -5009,6 +5019,12 @@ function profileScreenshotLabels(viewports) {
5009
5019
  }
5010
5020
  return labels;
5011
5021
  }
5022
+ function profileFinalScreenshotLabels(viewports) {
5023
+ return (viewports || []).map((viewport) => viewport && viewport.screenshot_label).filter(Boolean);
5024
+ }
5025
+ function profileAllSetupScreenshotLabels(viewports) {
5026
+ return (viewports || []).flatMap((viewport) => profileSetupScreenshotLabels(viewport && viewport.setup_action_results || []));
5027
+ }
5012
5028
  function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewport, finalScreenshotFullPage) {
5013
5029
  const normalizedFinalScreenshotFullPage = finalScreenshotFullPage === undefined
5014
5030
  ? undefined
@@ -5877,6 +5893,8 @@ function assessProfile(profile, evidence) {
5877
5893
  else if (checks.some((check) => check.status === "needs_human_review")) status = "needs_human_review";
5878
5894
  else if (checks.some((check) => check.status === "failed")) status = "product_regression";
5879
5895
  const screenshotLabels = profileScreenshotLabels(viewports);
5896
+ const canonicalScreenshotLabels = profileFinalScreenshotLabels(viewports);
5897
+ const setupScreenshotLabels = profileAllSetupScreenshotLabels(viewports);
5880
5898
  const route = viewports[0] && viewports[0].route ? viewports[0].route : { requested: evidence.target_url, observed: "", matched: false, error: "missing viewport evidence" };
5881
5899
  const passedChecks = checks.filter((check) => check.status === "passed").length;
5882
5900
  const failedChecks = checks.filter((check) => check.status === "failed").length;
@@ -5893,7 +5911,14 @@ function assessProfile(profile, evidence) {
5893
5911
  status,
5894
5912
  baseline_policy: profile.baseline_policy || "invariant_only",
5895
5913
  route,
5896
- artifacts: { screenshots: screenshotLabels, console: "console.json", proof_json: "proof.json", dom_summary: "dom-summary.json" },
5914
+ artifacts: {
5915
+ screenshots: screenshotLabels,
5916
+ canonical_screenshots: canonicalScreenshotLabels,
5917
+ setup_screenshots: setupScreenshotLabels,
5918
+ console: "console.json",
5919
+ proof_json: "proof.json",
5920
+ dom_summary: "dom-summary.json"
5921
+ },
5897
5922
  checks,
5898
5923
  summary,
5899
5924
  captured_at: evidence.captured_at,
@@ -385,6 +385,8 @@ interface RiddleProofProfileResult {
385
385
  route: RiddleProofProfileRouteEvidence;
386
386
  artifacts: {
387
387
  screenshots: string[];
388
+ canonical_screenshots?: string[];
389
+ setup_screenshots?: string[];
388
390
  console?: string;
389
391
  proof_json?: string;
390
392
  dom_summary?: string;
@@ -401,6 +403,7 @@ interface RiddleProofProfileResult {
401
403
  job_id?: string;
402
404
  job_count?: number;
403
405
  status?: string | null;
406
+ phase?: string | null;
404
407
  terminal?: boolean;
405
408
  created_at?: string | null;
406
409
  submitted_at?: string | null;
@@ -414,10 +417,12 @@ interface RiddleProofProfileResult {
414
417
  retry_count?: number;
415
418
  stale_job_ids?: string[];
416
419
  artifact_recovery?: boolean;
420
+ execution?: Record<string, JsonValue>;
417
421
  split_jobs?: Array<{
418
422
  viewport: string;
419
423
  job_id?: string;
420
424
  status?: string | null;
425
+ phase?: string | null;
421
426
  terminal?: boolean;
422
427
  queue_elapsed_ms?: number | null;
423
428
  pre_submission_elapsed_ms?: number;
@@ -428,6 +433,7 @@ interface RiddleProofProfileResult {
428
433
  retry_count?: number;
429
434
  stale_job_ids?: string[];
430
435
  artifact_recovery?: boolean;
436
+ execution?: Record<string, JsonValue>;
431
437
  }>;
432
438
  };
433
439
  environment_blocker?: Record<string, JsonValue>;
@@ -441,6 +447,7 @@ interface RiddleProofProfileArtifactRef {
441
447
  kind?: string;
442
448
  content_type?: string;
443
449
  source?: string;
450
+ role?: "canonical_screenshot" | "setup_screenshot" | "data" | "diagnostic" | "artifact";
444
451
  }
445
452
  interface NormalizeRiddleProofProfileOptions {
446
453
  url?: string;
package/dist/profile.d.ts CHANGED
@@ -385,6 +385,8 @@ interface RiddleProofProfileResult {
385
385
  route: RiddleProofProfileRouteEvidence;
386
386
  artifacts: {
387
387
  screenshots: string[];
388
+ canonical_screenshots?: string[];
389
+ setup_screenshots?: string[];
388
390
  console?: string;
389
391
  proof_json?: string;
390
392
  dom_summary?: string;
@@ -401,6 +403,7 @@ interface RiddleProofProfileResult {
401
403
  job_id?: string;
402
404
  job_count?: number;
403
405
  status?: string | null;
406
+ phase?: string | null;
404
407
  terminal?: boolean;
405
408
  created_at?: string | null;
406
409
  submitted_at?: string | null;
@@ -414,10 +417,12 @@ interface RiddleProofProfileResult {
414
417
  retry_count?: number;
415
418
  stale_job_ids?: string[];
416
419
  artifact_recovery?: boolean;
420
+ execution?: Record<string, JsonValue>;
417
421
  split_jobs?: Array<{
418
422
  viewport: string;
419
423
  job_id?: string;
420
424
  status?: string | null;
425
+ phase?: string | null;
421
426
  terminal?: boolean;
422
427
  queue_elapsed_ms?: number | null;
423
428
  pre_submission_elapsed_ms?: number;
@@ -428,6 +433,7 @@ interface RiddleProofProfileResult {
428
433
  retry_count?: number;
429
434
  stale_job_ids?: string[];
430
435
  artifact_recovery?: boolean;
436
+ execution?: Record<string, JsonValue>;
431
437
  }>;
432
438
  };
433
439
  environment_blocker?: Record<string, JsonValue>;
@@ -441,6 +447,7 @@ interface RiddleProofProfileArtifactRef {
441
447
  kind?: string;
442
448
  content_type?: string;
443
449
  source?: string;
450
+ role?: "canonical_screenshot" | "setup_screenshot" | "data" | "diagnostic" | "artifact";
444
451
  }
445
452
  interface NormalizeRiddleProofProfileOptions {
446
453
  url?: string;
package/dist/profile.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  resolveRiddleProofProfileTimeoutSec,
28
28
  slugifyRiddleProofProfileName,
29
29
  summarizeRiddleProofProfileResult
30
- } from "./chunk-GG2D3MFZ.js";
30
+ } from "./chunk-FCSJZBC5.js";
31
31
  import "./chunk-MLKGABMK.js";
32
32
  export {
33
33
  RIDDLE_PROOF_HOSTED_PROFILE_ARTIFACTS,
@@ -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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "recon" | "author" | "ship" | "implement" | "verify" | "setup" | "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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "recon" | "author" | "ship" | "implement" | "verify" | "setup" | "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: "setup" | "recon" | "author" | "implement" | "verify" | "ship";
662
+ action: "recon" | "author" | "ship" | "implement" | "verify" | "setup";
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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
295
+ action: "recon" | "author" | "ship" | "implement" | "verify" | "setup" | "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: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
385
+ action: "recon" | "author" | "ship" | "implement" | "verify" | "setup" | "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: "setup" | "recon" | "author" | "implement" | "verify" | "ship";
662
+ action: "recon" | "author" | "ship" | "implement" | "verify" | "setup";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
@@ -1,2 +1,2 @@
1
1
  import './proof-run-core-7Dqm7RKM.cjs';
2
- export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-Baiv6l3A.cjs';
2
+ export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-DmUqh7Cw.cjs';
@@ -1,2 +1,2 @@
1
1
  import './proof-run-core-7Dqm7RKM.js';
2
- export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-MiKZt9oY.js';
2
+ export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-CsQshTUX.js';
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/receipts.ts
21
+ var receipts_exports = {};
22
+ __export(receipts_exports, {
23
+ RIDDLE_PREVIEW_RECEIPT_VERSION: () => RIDDLE_PREVIEW_RECEIPT_VERSION,
24
+ RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION: () => RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION,
25
+ createRiddleProofObservationReceipt: () => createRiddleProofObservationReceipt,
26
+ parseRiddlePreviewReceipt: () => parseRiddlePreviewReceipt,
27
+ parseRiddleProofObservationReceipt: () => parseRiddleProofObservationReceipt
28
+ });
29
+ module.exports = __toCommonJS(receipts_exports);
30
+ var RIDDLE_PREVIEW_RECEIPT_VERSION = "riddle.preview-receipt.v1";
31
+ var RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION = "riddle-proof.observation-receipt.v1";
32
+ function isRecord(value) {
33
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
34
+ }
35
+ function requiredString(record, key, context) {
36
+ const value = record[key];
37
+ if (typeof value !== "string" || !value.trim()) {
38
+ throw new Error(`${context}.${key} must be a non-empty string.`);
39
+ }
40
+ return value.trim();
41
+ }
42
+ function normalizedSourceIdentity(value) {
43
+ if (!isRecord(value)) return {};
44
+ return {
45
+ git_revision: typeof value.git_revision === "string" && value.git_revision.trim() ? value.git_revision.trim() : void 0,
46
+ repository: typeof value.repository === "string" && value.repository.trim() ? value.repository.trim() : void 0,
47
+ dirty: typeof value.dirty === "boolean" ? value.dirty : void 0,
48
+ label: typeof value.label === "string" && value.label.trim() ? value.label.trim() : void 0
49
+ };
50
+ }
51
+ function parseRiddlePreviewReceipt(value) {
52
+ if (!isRecord(value)) throw new Error("Preview receipt must be an object.");
53
+ if (value.version !== RIDDLE_PREVIEW_RECEIPT_VERSION) {
54
+ throw new Error(`Unsupported Preview receipt version ${String(value.version || "missing")}.`);
55
+ }
56
+ if (!isRecord(value.source)) throw new Error("Preview receipt source must be an object.");
57
+ const expiresAt = requiredString(value, "expires_at", "preview receipt");
58
+ const publishedAt = requiredString(value, "published_at", "preview receipt");
59
+ const contentDigest = requiredString(value, "content_digest", "preview receipt");
60
+ if (!contentDigest.startsWith("sha256:") || contentDigest.length <= "sha256:".length) {
61
+ throw new Error("preview receipt.content_digest must be a sha256 digest.");
62
+ }
63
+ if (!Number.isFinite(Date.parse(expiresAt)) || !Number.isFinite(Date.parse(publishedAt))) {
64
+ throw new Error("Preview receipt timestamps must be valid ISO date strings.");
65
+ }
66
+ return {
67
+ version: RIDDLE_PREVIEW_RECEIPT_VERSION,
68
+ preview_id: requiredString(value, "preview_id", "preview receipt"),
69
+ url: requiredString(value, "url", "preview receipt"),
70
+ expires_at: expiresAt,
71
+ content_digest: contentDigest,
72
+ source: normalizedSourceIdentity(value.source),
73
+ published_at: publishedAt
74
+ };
75
+ }
76
+ function comparableArtifactName(value) {
77
+ return (value || "").split(/[/?#]/).pop()?.toLowerCase().replace(/\.(png|jpe?g|gif|webp|avif|svg)$/u, "").replace(/[^a-z0-9_-]+/gu, "-").replace(/^-+|-+$/g, "") || "";
78
+ }
79
+ function artifactMatchesLabel(artifact, label) {
80
+ const expected = comparableArtifactName(label);
81
+ if (!expected) return false;
82
+ return [artifact.name, artifact.url, artifact.path].map(comparableArtifactName).some((name) => name === expected || name.endsWith(`-${expected}`));
83
+ }
84
+ function artifactLooksLikeScreenshot(ref) {
85
+ const text = [ref.name, ref.url, ref.path, ref.kind, ref.content_type].filter(Boolean).join(" ").toLowerCase();
86
+ return /screenshot|\bimage\b/.test(text) || /\.(png|jpe?g|gif|webp|avif|svg)(\?|#|$)/.test(text);
87
+ }
88
+ function finalScreenshotLabels(result) {
89
+ const explicit = result.artifacts.canonical_screenshots || [];
90
+ if (explicit.length) return explicit;
91
+ const fromEvidence = (result.evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => typeof label === "string" && Boolean(label.trim()));
92
+ if (fromEvidence.length) return fromEvidence;
93
+ return (result.artifacts.screenshots || []).slice(0, 1);
94
+ }
95
+ function setupScreenshotLabels(result) {
96
+ const explicit = result.artifacts.setup_screenshots || [];
97
+ if (explicit.length) return explicit;
98
+ return (result.evidence?.viewports || []).flatMap(
99
+ (viewport) => (viewport.setup_action_results || []).filter((action) => action.action === "screenshot" && action.ok !== false && typeof action.screenshot_label === "string").map((action) => String(action.screenshot_label))
100
+ );
101
+ }
102
+ function observationArtifactFromRef(ref, canonicalLabels, setupLabels) {
103
+ const base = {
104
+ name: ref.name,
105
+ role: ref.role || "artifact",
106
+ url: ref.url,
107
+ path: ref.path,
108
+ kind: ref.kind,
109
+ content_type: ref.content_type,
110
+ source: ref.source
111
+ };
112
+ if (!artifactLooksLikeScreenshot(ref)) return base;
113
+ if (canonicalLabels.some((label) => artifactMatchesLabel(base, label))) {
114
+ return { ...base, role: "canonical_screenshot" };
115
+ }
116
+ if (setupLabels.some((label) => artifactMatchesLabel(base, label))) {
117
+ return { ...base, role: "setup_screenshot" };
118
+ }
119
+ return { ...base, role: "diagnostic" };
120
+ }
121
+ function profileObservationArtifacts(result) {
122
+ const canonicalLabels = finalScreenshotLabels(result);
123
+ const setupLabels = setupScreenshotLabels(result);
124
+ const artifacts = [];
125
+ const seen = /* @__PURE__ */ new Set();
126
+ const add = (artifact) => {
127
+ const key = artifact.url || artifact.path || `${artifact.role}:${artifact.name}`;
128
+ if (!artifact.name || seen.has(key)) return;
129
+ seen.add(key);
130
+ artifacts.push(artifact);
131
+ };
132
+ for (const ref of result.artifacts.riddle_artifacts || []) {
133
+ add(observationArtifactFromRef(ref, canonicalLabels, setupLabels));
134
+ }
135
+ for (const label of canonicalLabels) {
136
+ if (!artifacts.some((artifact) => artifactMatchesLabel(artifact, label))) {
137
+ add({ name: label, path: label, role: "canonical_screenshot", kind: "image" });
138
+ }
139
+ }
140
+ for (const label of setupLabels) {
141
+ if (!artifacts.some((artifact) => artifactMatchesLabel(artifact, label))) {
142
+ add({ name: label, path: label, role: "setup_screenshot", kind: "image" });
143
+ }
144
+ }
145
+ for (const label of result.artifacts.screenshots || []) {
146
+ if (!artifacts.some((artifact) => artifactMatchesLabel(artifact, label))) {
147
+ add({ name: label, path: label, role: "diagnostic", kind: "image" });
148
+ }
149
+ }
150
+ return artifacts;
151
+ }
152
+ function mergeObservationArtifacts(profileArtifacts, suppliedArtifacts) {
153
+ const artifacts = [...profileArtifacts];
154
+ for (const supplied of suppliedArtifacts) {
155
+ const suppliedNames = [supplied.name, supplied.url, supplied.path].map(comparableArtifactName).filter(Boolean);
156
+ const existingIndex = artifacts.findIndex((artifact) => {
157
+ if (supplied.url && artifact.url === supplied.url) return true;
158
+ if (supplied.path && artifact.path === supplied.path) return true;
159
+ return [artifact.name, artifact.url, artifact.path].map(comparableArtifactName).some((name) => name && suppliedNames.includes(name));
160
+ });
161
+ if (existingIndex < 0) {
162
+ artifacts.push(supplied);
163
+ continue;
164
+ }
165
+ const existing = artifacts[existingIndex];
166
+ const role = supplied.role === "canonical_screenshot" || supplied.role === "setup_screenshot" ? supplied.role : existing.role === "canonical_screenshot" || existing.role === "setup_screenshot" ? existing.role : supplied.role === "artifact" ? existing.role : supplied.role;
167
+ artifacts[existingIndex] = {
168
+ ...existing,
169
+ ...supplied,
170
+ role
171
+ };
172
+ }
173
+ return artifacts;
174
+ }
175
+ function defaultObservationId(role, capturedAt) {
176
+ return `obs_${role}_${capturedAt.replace(/[^0-9]/g, "").slice(0, 17) || "unknown"}`;
177
+ }
178
+ function profileCheckCounts(result) {
179
+ const counts = { total: result.checks.length, passed: 0, failed: 0, skipped: 0, needs_human_review: 0 };
180
+ for (const check of result.checks) {
181
+ if (check.status === "passed") counts.passed += 1;
182
+ if (check.status === "failed") counts.failed += 1;
183
+ if (check.status === "skipped") counts.skipped += 1;
184
+ if (check.status === "needs_human_review") counts.needs_human_review += 1;
185
+ }
186
+ return counts;
187
+ }
188
+ function createRiddleProofObservationReceipt(input) {
189
+ const capturedAt = input.captured_at || input.profile_result?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
190
+ const profileArtifacts = input.profile_result ? profileObservationArtifacts(input.profile_result) : [];
191
+ const requestedCanonical = input.canonical_screenshot ? { ...input.canonical_screenshot, role: "canonical_screenshot" } : void 0;
192
+ const artifacts = mergeObservationArtifacts(
193
+ profileArtifacts,
194
+ [...input.artifacts || [], ...requestedCanonical ? [requestedCanonical] : []]
195
+ );
196
+ const canonicalScreenshot = requestedCanonical ? artifacts.find((artifact) => artifact.role === "canonical_screenshot" && artifactMatchesLabel(artifact, requestedCanonical.name)) || requestedCanonical : artifacts.find((artifact) => artifact.role === "canonical_screenshot");
197
+ const target = input.target.kind === "preview" && input.target.preview ? { ...input.target, preview: parseRiddlePreviewReceipt(input.target.preview) } : input.target;
198
+ return {
199
+ version: RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION,
200
+ observation_id: input.observation_id || defaultObservationId(input.comparison_role, capturedAt),
201
+ comparison_role: input.comparison_role,
202
+ executor: input.executor,
203
+ target,
204
+ source: normalizedSourceIdentity(input.source || input.target.preview?.source),
205
+ captured_at: capturedAt,
206
+ artifacts,
207
+ canonical_screenshot: canonicalScreenshot,
208
+ profile_summary: input.profile_result ? {
209
+ profile_name: input.profile_result.profile_name,
210
+ status: input.profile_result.status,
211
+ summary: input.profile_result.summary,
212
+ route: input.profile_result.route,
213
+ checks: profileCheckCounts(input.profile_result)
214
+ } : void 0,
215
+ proof: input.profile_result ? {
216
+ profile_name: input.profile_result.profile_name,
217
+ result: input.profile_result
218
+ } : void 0,
219
+ publication: input.publication,
220
+ execution: input.execution,
221
+ metadata: input.metadata
222
+ };
223
+ }
224
+ function parseRiddleProofObservationReceipt(value) {
225
+ if (!isRecord(value)) throw new Error("Observation receipt must be an object.");
226
+ if (value.version !== RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION) {
227
+ throw new Error(`Unsupported Observation receipt version ${String(value.version || "missing")}.`);
228
+ }
229
+ if (!isRecord(value.executor)) throw new Error("Observation receipt executor must be an object.");
230
+ if (!isRecord(value.target)) throw new Error("Observation receipt target must be an object.");
231
+ if (!isRecord(value.source)) throw new Error("Observation receipt source must be an object.");
232
+ requiredString(value, "observation_id", "observation receipt");
233
+ requiredString(value, "captured_at", "observation receipt");
234
+ const executorKind = requiredString(value.executor, "kind", "observation receipt executor");
235
+ if (!"local_playwright,riddle_hosted,browser_api,other".split(",").includes(executorKind)) {
236
+ throw new Error(`Unsupported observation executor kind ${executorKind}.`);
237
+ }
238
+ if (value.executor.runner !== void 0) {
239
+ requiredString(value.executor, "runner", "observation receipt executor");
240
+ }
241
+ const role = requiredString(value, "comparison_role", "observation receipt");
242
+ if (!["before", "after", "standalone"].includes(role)) {
243
+ throw new Error(`Unsupported observation comparison role ${role}.`);
244
+ }
245
+ const targetKind = requiredString(value.target, "kind", "observation receipt target");
246
+ if (targetKind !== "url" && targetKind !== "preview") {
247
+ throw new Error(`Unsupported observation target kind ${targetKind}.`);
248
+ }
249
+ requiredString(value.target, "url", "observation receipt target");
250
+ if (targetKind === "preview") {
251
+ if (value.target.preview === void 0) {
252
+ throw new Error("Preview Observation target must include its Preview receipt.");
253
+ }
254
+ parseRiddlePreviewReceipt(value.target.preview);
255
+ }
256
+ if (!Array.isArray(value.artifacts)) throw new Error("Observation receipt artifacts must be an array.");
257
+ const artifactRoles = /* @__PURE__ */ new Set(["canonical_screenshot", "setup_screenshot", "data", "diagnostic", "artifact"]);
258
+ const artifacts = value.artifacts.map((artifact, index) => {
259
+ if (!isRecord(artifact)) throw new Error(`Observation receipt artifact ${index} must be an object.`);
260
+ requiredString(artifact, "name", `observation receipt artifact ${index}`);
261
+ const artifactRole = requiredString(artifact, "role", `observation receipt artifact ${index}`);
262
+ if (!artifactRoles.has(artifactRole)) {
263
+ throw new Error(`Unsupported observation artifact role ${artifactRole}.`);
264
+ }
265
+ return artifact;
266
+ });
267
+ if (value.canonical_screenshot !== void 0) {
268
+ if (!isRecord(value.canonical_screenshot) || value.canonical_screenshot.role !== "canonical_screenshot") {
269
+ throw new Error("Observation canonical_screenshot must have the canonical_screenshot role.");
270
+ }
271
+ const canonical = value.canonical_screenshot;
272
+ const included = artifacts.some((artifact) => artifact.role === "canonical_screenshot" && artifact.name === canonical.name && artifact.url === canonical.url && artifact.path === canonical.path);
273
+ if (!included) {
274
+ throw new Error("Observation canonical_screenshot must reference an artifact in the receipt.");
275
+ }
276
+ }
277
+ return value;
278
+ }
279
+ // Annotate the CommonJS export names for ESM import in node:
280
+ 0 && (module.exports = {
281
+ RIDDLE_PREVIEW_RECEIPT_VERSION,
282
+ RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION,
283
+ createRiddleProofObservationReceipt,
284
+ parseRiddlePreviewReceipt,
285
+ parseRiddleProofObservationReceipt
286
+ });