@riddledc/riddle-proof 0.8.77 → 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 +65 -3
  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 +744 -85
  7. package/dist/change-proof.d.cts +100 -8
  8. package/dist/change-proof.d.ts +100 -8
  9. package/dist/change-proof.js +15 -1
  10. package/dist/{chunk-B2DP2LET.js → chunk-5IFZSUPF.js} +52 -13
  11. package/dist/chunk-6VFS2JFR.js +886 -0
  12. package/dist/{chunk-IY4W6STC.js → chunk-7N6X54WG.js} +116 -17
  13. package/dist/{chunk-GG2D3MFZ.js → chunk-FCSJZBC5.js} +26 -1
  14. package/dist/{chunk-H25IDX76.js → chunk-HSGZV2NK.js} +206 -35
  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 +2009 -1058
  19. package/dist/cli.js +7 -6
  20. package/dist/index.cjs +932 -122
  21. package/dist/index.d.cts +4 -3
  22. package/dist/index.d.ts +4 -3
  23. package/dist/index.js +42 -14
  24. package/dist/pr-comment.cjs +416 -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-BILL3UC2.js +0 -488
@@ -1,3 +1,11 @@
1
+ import {
2
+ RIDDLE_PROOF_CHANGE_RECEIPT_V1_VERSION,
3
+ RIDDLE_PROOF_CHANGE_RECEIPT_VERSION,
4
+ RIDDLE_PROOF_HANDOFF_RECEIPT_VERSION,
5
+ createRiddleProofHandoffReceipt,
6
+ parseRiddleProofChangeReceipt,
7
+ parseRiddleProofHandoffReceipt
8
+ } from "./chunk-6VFS2JFR.js";
1
9
  import {
2
10
  riddleProofPublicStateAllowsMergeRecommendation,
3
11
  riddleProofPublicStateMergeRecommendation,
@@ -84,9 +92,10 @@ function collectChangeReceiptArtifacts(result) {
84
92
  const seen = /* @__PURE__ */ new Set();
85
93
  const collectSide = (sideName, side) => {
86
94
  const candidates = [
95
+ side.canonical_screenshot,
87
96
  ...asArray(side.screenshots),
88
97
  ...asArray(side.artifacts)
89
- ];
98
+ ].filter(Boolean);
90
99
  for (const [index, item] of candidates.entries()) {
91
100
  const artifact = asRecord(item);
92
101
  const url = stringValue(artifact.url) || stringValue(artifact.path);
@@ -178,9 +187,10 @@ function changeReceiptPageSummaries(result) {
178
187
  for (const sideName of ["before", "after"]) {
179
188
  const side = asRecord(result[sideName]);
180
189
  if (!Object.keys(side).length) continue;
181
- const checks = asRecord(side.checks);
190
+ const profileSummary = asRecord(side.profile_summary);
191
+ const checks = Object.keys(asRecord(side.checks)).length ? asRecord(side.checks) : asRecord(profileSummary.checks);
182
192
  pages.push({
183
- route: firstStringValue(side.source, side.profile_name) || sideName,
193
+ route: firstStringValue(asRecord(side.target).url, side.source, profileSummary.profile_name, side.profile_name) || sideName,
184
194
  passed: numberValue(checks.passed) ?? 0,
185
195
  failed: numberValue(checks.failed) ?? 0
186
196
  });
@@ -243,7 +253,11 @@ function isProfileResult(result) {
243
253
  return version === "riddle-proof.profile-result.v1" || version === "riddle-proof.profile-compact-result.v1";
244
254
  }
245
255
  function isChangeReceiptResult(result) {
246
- return stringValue(result.version) === "riddle-proof.change-receipt.v1";
256
+ const version = stringValue(result.version);
257
+ return version === RIDDLE_PROOF_CHANGE_RECEIPT_V1_VERSION || version === RIDDLE_PROOF_CHANGE_RECEIPT_VERSION;
258
+ }
259
+ function isHandoffReceiptResult(result) {
260
+ return stringValue(result.version) === RIDDLE_PROOF_HANDOFF_RECEIPT_VERSION;
247
261
  }
248
262
  function isChangeResult(result) {
249
263
  const version = stringValue(result.version);
@@ -251,10 +265,13 @@ function isChangeResult(result) {
251
265
  }
252
266
  function summarizeRiddleProofPrComment(input) {
253
267
  const runResponse = asRecord(input.runResponse);
254
- const result = asRecord(input.result);
268
+ const inputResult = asRecord(input.result);
269
+ const handoffReceipt = isHandoffReceiptResult(inputResult) ? parseRiddleProofHandoffReceipt(inputResult) : void 0;
270
+ const parsedChangeReceipt = handoffReceipt?.change || (isChangeReceiptResult(inputResult) ? parseRiddleProofChangeReceipt(inputResult) : void 0);
271
+ const result = parsedChangeReceipt ? asRecord(parsedChangeReceipt) : inputResult;
255
272
  const proofResult = asRecord(runResponse.proofResult);
256
273
  const profileResult = isProfileResult(result);
257
- const changeReceiptResult = isChangeReceiptResult(result);
274
+ const changeReceiptResult = Boolean(parsedChangeReceipt);
258
275
  const changeResult = changeReceiptResult || isChangeResult(result);
259
276
  const profileRiddle = asRecord(result.riddle);
260
277
  const preview = asRecord(runResponse.preview);
@@ -275,7 +292,7 @@ function summarizeRiddleProofPrComment(input) {
275
292
  delete checkSource.ok;
276
293
  const nestedChecks = summarizeExplicitChecks(checkSource);
277
294
  const resultStatus = firstStringValue(result.status, stopCondition.status);
278
- const ok = changeResult ? resultStatus === "passed" : booleanValue(result.ok) ?? booleanValue(runResponse.ok) ?? null;
295
+ const ok = changeReceiptResult ? parsedChangeReceipt?.recommendation.merge_recommended ?? false : changeResult ? resultStatus === "passed" : booleanValue(result.ok) ?? booleanValue(runResponse.ok) ?? null;
279
296
  const checkpointSummary = checkpointSummaryFrom(
280
297
  result.checkpoint_summary,
281
298
  stopCondition.checkpoint_summary,
@@ -283,19 +300,19 @@ function summarizeRiddleProofPrComment(input) {
283
300
  rawDetails.checkpoint_summary,
284
301
  proofResult.checkpoint_summary
285
302
  );
286
- const publicState = summarizeRiddleProofPublicState({
303
+ const publicState = changeReceiptResult ? void 0 : summarizeRiddleProofPublicState({
287
304
  ...result,
288
305
  status: resultStatus,
289
306
  checkpoint_summary: checkpointSummary || result.checkpoint_summary
290
307
  });
291
- const mergeRecommendation = riddleProofPublicStateMergeRecommendation(
308
+ const mergeRecommendation = publicState ? riddleProofPublicStateMergeRecommendation(
292
309
  publicState,
293
310
  firstStringValue(result.merge_recommendation, stopCondition.merge_recommendation, resultRaw.merge_recommendation)
294
- );
311
+ ) : void 0;
295
312
  return {
296
313
  ok,
297
314
  status: firstStringValue(proofResult.status, profileRiddle.status),
298
- result_status: changeResult ? resultStatus : publicState.status,
315
+ result_status: changeResult ? resultStatus : publicState?.status,
299
316
  job_id: firstStringValue(proofResult.job_id, profileRiddle.job_id),
300
317
  duration_ms: numberValue(proofResult.duration_ms) ?? numberValue(profileRiddle.elapsed_ms),
301
318
  proof_url: stringValue(runResponse.proofUrl),
@@ -303,13 +320,13 @@ function summarizeRiddleProofPrComment(input) {
303
320
  preview_url: stringValue(preview.preview_url) || stringValue(preview.url),
304
321
  preview_publish_recovered: booleanValue(preview.publish_recovered),
305
322
  preview_publish_error: stringValue(preview.publish_error),
306
- ship_held: publicState.ship_held,
307
- shipping_disabled: publicState.shipping_disabled,
308
- ship_authorized: publicState.ship_authorized,
309
- merge_ready: publicState.merge_ready,
310
- sync_allowed: publicState.sync_allowed,
323
+ ship_held: publicState?.ship_held,
324
+ shipping_disabled: publicState?.shipping_disabled,
325
+ ship_authorized: changeReceiptResult ? parsedChangeReceipt?.shipping_authorization.authorized : publicState?.ship_authorized,
326
+ merge_ready: publicState?.merge_ready,
327
+ sync_allowed: publicState?.sync_allowed,
311
328
  proof_decision: firstStringValue(result.proof_decision, stopCondition.proof_decision, resultRaw.proof_decision),
312
- merge_recommendation: changeReceiptResult && resultStatus ? stringValue(result.verdict) : mergeRecommendation,
329
+ merge_recommendation: changeReceiptResult ? parsedChangeReceipt?.recommendation.label : mergeRecommendation,
313
330
  checkpoint_summary: checkpointSummary,
314
331
  public_state: publicState,
315
332
  passed_checks: changeChecks?.passed ?? profileChecks?.passed ?? nestedChecks.passed,
@@ -377,7 +394,88 @@ function checkpointSummaryLine(summary) {
377
394
  summary.latest_decision ? `latest decision \`${summary.latest_decision}\`` : ""
378
395
  ].filter(Boolean).join("; ");
379
396
  }
397
+ function markdownTableValue(value) {
398
+ return String(value ?? "").replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
399
+ }
400
+ function observationArtifactTarget(artifact) {
401
+ return artifact?.url || artifact?.path;
402
+ }
403
+ function canonicalScreenshotCell(artifact, fallback) {
404
+ const target = observationArtifactTarget(artifact);
405
+ if (!artifact || !target) return fallback;
406
+ if (artifact.url) return `![${artifact.name.replace(/\]/g, "\\]")}](${artifact.url})`;
407
+ return markdownTableValue(artifact.path || artifact.name);
408
+ }
409
+ function shortRevision(value) {
410
+ return value ? value.slice(0, 12) : "not recorded";
411
+ }
412
+ function buildRiddleProofHandoffPrCommentMarkdown(handoff, input = {}) {
413
+ const receipt = parseRiddleProofHandoffReceipt(handoff);
414
+ const change = receipt.change;
415
+ const beforeStatus = change.before.profile_summary?.status || "not recorded";
416
+ const afterStatus = change.after.profile_summary?.status || "not recorded";
417
+ const beforeBaseline = change.groups.before.ok ? "matched baseline" : "baseline mismatch";
418
+ const lines = [
419
+ RIDDLE_PROOF_PR_COMMENT_MARKER,
420
+ `## ${input.title?.trim() || "Riddle Change Proof"}`,
421
+ "",
422
+ `**Result:** ${receipt.recommendation.label}`,
423
+ `**Evidence verdict:** \`${receipt.verdict}\``,
424
+ `**Shipping authorization:** ${receipt.shipping_authorization.status}`,
425
+ `**Contract:** ${change.contract_name}`
426
+ ];
427
+ if (input.goal?.trim()) lines.push(`**Goal:** ${input.goal.trim()}`);
428
+ if (input.successCriteria?.trim()) lines.push(`**Success criteria:** ${input.successCriteria.trim()}`);
429
+ lines.push("", change.summary, "", "### Canonical Before / After", "");
430
+ lines.push("| Before | After |");
431
+ lines.push("| --- | --- |");
432
+ lines.push(`| ${beforeBaseline}: \`${markdownTableValue(beforeStatus)}\` | \`${markdownTableValue(afterStatus)}\` |`);
433
+ lines.push(`| ${canonicalScreenshotCell(receipt.canonical_pair.before, "No canonical before screenshot")} | ${canonicalScreenshotCell(receipt.canonical_pair.after, "No canonical after screenshot")} |`);
434
+ lines.push("", "### Source Binding", "");
435
+ lines.push("| Side | Target | Git revision | Binding | Preview | Digest |");
436
+ lines.push("| --- | --- | --- | --- | --- | --- |");
437
+ for (const side of ["before", "after"]) {
438
+ const observation = change[side];
439
+ const binding = change.source_bindings[side];
440
+ lines.push(`| ${side} | ${markdownTableValue(observation.target.url)} | \`${shortRevision(binding.observed_git_revision || observation.source.git_revision)}\` | ${binding.status} | ${markdownTableValue(binding.preview_id || observation.target.preview?.preview_id || "not required")} | \`${markdownTableValue(binding.content_digest || observation.target.preview?.content_digest || "not required")}\` |`);
441
+ }
442
+ lines.push("", "### Declared Delta", "");
443
+ lines.push("| Measurement | Status | Before | After |");
444
+ lines.push("| --- | --- | --- | --- |");
445
+ for (const delta of change.deltas) {
446
+ lines.push(`| ${markdownTableValue(delta.label)} | ${delta.status} | ${markdownTableValue(delta.before_observed)} | ${markdownTableValue(delta.after_observed)} |`);
447
+ }
448
+ if (change.proves.length) {
449
+ lines.push("", "### What This Proves", "");
450
+ for (const claim of change.proves) lines.push(`- ${claim}`);
451
+ }
452
+ if (change.does_not_prove.length) {
453
+ lines.push("", "### Limits", "");
454
+ for (const claim of change.does_not_prove) lines.push(`- ${claim}`);
455
+ }
456
+ const linkedArtifacts = [
457
+ ...change.before.artifacts.map((artifact) => ({ side: "before", artifact })),
458
+ ...change.after.artifacts.map((artifact) => ({ side: "after", artifact }))
459
+ ].filter(({ artifact }) => Boolean(artifact.url));
460
+ if (linkedArtifacts.length) {
461
+ lines.push("", "### Artifacts", "");
462
+ for (const { side, artifact } of linkedArtifacts.slice(0, 24)) {
463
+ lines.push(`- ${side}: ${markdownLink(artifact.name, artifact.url || "")}`);
464
+ }
465
+ }
466
+ lines.push("", input.source?.trim() ? `_Source: ${input.source.trim()}_` : "_Rendered from the Handoff receipt without recomputing its verdict._");
467
+ return `${lines.join("\n").trim()}
468
+ `;
469
+ }
380
470
  function buildRiddleProofPrCommentMarkdown(input) {
471
+ const result = asRecord(input.result);
472
+ if (isHandoffReceiptResult(result)) {
473
+ return buildRiddleProofHandoffPrCommentMarkdown(parseRiddleProofHandoffReceipt(result), input);
474
+ }
475
+ if (isChangeReceiptResult(result)) {
476
+ const handoff = createRiddleProofHandoffReceipt(parseRiddleProofChangeReceipt(result));
477
+ return buildRiddleProofHandoffPrCommentMarkdown(handoff, input);
478
+ }
381
479
  const summary = summarizeRiddleProofPrComment(input);
382
480
  const title = input.title?.trim() || "Riddle Proof Evidence";
383
481
  const lines = [
@@ -448,5 +546,6 @@ function buildRiddleProofPrCommentMarkdown(input) {
448
546
  export {
449
547
  RIDDLE_PROOF_PR_COMMENT_MARKER,
450
548
  summarizeRiddleProofPrComment,
549
+ buildRiddleProofHandoffPrCommentMarkdown,
451
550
  buildRiddleProofPrCommentMarkdown
452
551
  };
@@ -781,6 +781,12 @@ function profileScreenshotLabels(viewports) {
781
781
  }
782
782
  return labels;
783
783
  }
784
+ function profileFinalScreenshotLabels(viewports) {
785
+ return (viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => typeof label === "string" && Boolean(label.trim()));
786
+ }
787
+ function profileAllSetupScreenshotLabels(viewports) {
788
+ return (viewports || []).flatMap((viewport) => profileSetupScreenshotLabels(viewport.setup_action_results || []));
789
+ }
784
790
  function profileSetupSummary(viewports, actionCount, expectedActionCountByViewport, finalScreenshotFullPage) {
785
791
  const normalizedFinalScreenshotFullPage = finalScreenshotFullPage === void 0 ? void 0 : finalScreenshotFullPage !== false;
786
792
  const finalScreenshotCount = viewports.filter((viewport) => typeof viewport.screenshot_label === "string" && viewport.screenshot_label.trim()).length;
@@ -3631,6 +3637,8 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
3631
3637
  const status = profileStatusFromEvidence(profile, evidence, checks);
3632
3638
  const firstViewport = evidence?.viewports?.[0];
3633
3639
  const screenshots = profileScreenshotLabels(evidence?.viewports);
3640
+ const canonicalScreenshots = profileFinalScreenshotLabels(evidence?.viewports);
3641
+ const setupScreenshots = profileAllSetupScreenshotLabels(evidence?.viewports);
3634
3642
  const result = {
3635
3643
  version: RIDDLE_PROOF_PROFILE_RESULT_VERSION,
3636
3644
  profile_name: profile.name,
@@ -3640,6 +3648,8 @@ function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
3640
3648
  route: routeForViewport(firstViewport, evidence?.target_url),
3641
3649
  artifacts: {
3642
3650
  screenshots,
3651
+ canonical_screenshots: canonicalScreenshots,
3652
+ setup_screenshots: setupScreenshots,
3643
3653
  console: "console.json",
3644
3654
  proof_json: "proof.json",
3645
3655
  dom_summary: "dom-summary.json",
@@ -4958,6 +4968,12 @@ function profileScreenshotLabels(viewports) {
4958
4968
  }
4959
4969
  return labels;
4960
4970
  }
4971
+ function profileFinalScreenshotLabels(viewports) {
4972
+ return (viewports || []).map((viewport) => viewport && viewport.screenshot_label).filter(Boolean);
4973
+ }
4974
+ function profileAllSetupScreenshotLabels(viewports) {
4975
+ return (viewports || []).flatMap((viewport) => profileSetupScreenshotLabels(viewport && viewport.setup_action_results || []));
4976
+ }
4961
4977
  function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewport, finalScreenshotFullPage) {
4962
4978
  const normalizedFinalScreenshotFullPage = finalScreenshotFullPage === undefined
4963
4979
  ? undefined
@@ -5826,6 +5842,8 @@ function assessProfile(profile, evidence) {
5826
5842
  else if (checks.some((check) => check.status === "needs_human_review")) status = "needs_human_review";
5827
5843
  else if (checks.some((check) => check.status === "failed")) status = "product_regression";
5828
5844
  const screenshotLabels = profileScreenshotLabels(viewports);
5845
+ const canonicalScreenshotLabels = profileFinalScreenshotLabels(viewports);
5846
+ const setupScreenshotLabels = profileAllSetupScreenshotLabels(viewports);
5829
5847
  const route = viewports[0] && viewports[0].route ? viewports[0].route : { requested: evidence.target_url, observed: "", matched: false, error: "missing viewport evidence" };
5830
5848
  const passedChecks = checks.filter((check) => check.status === "passed").length;
5831
5849
  const failedChecks = checks.filter((check) => check.status === "failed").length;
@@ -5842,7 +5860,14 @@ function assessProfile(profile, evidence) {
5842
5860
  status,
5843
5861
  baseline_policy: profile.baseline_policy || "invariant_only",
5844
5862
  route,
5845
- artifacts: { screenshots: screenshotLabels, console: "console.json", proof_json: "proof.json", dom_summary: "dom-summary.json" },
5863
+ artifacts: {
5864
+ screenshots: screenshotLabels,
5865
+ canonical_screenshots: canonicalScreenshotLabels,
5866
+ setup_screenshots: setupScreenshotLabels,
5867
+ console: "console.json",
5868
+ proof_json: "proof.json",
5869
+ dom_summary: "dom-summary.json"
5870
+ },
5846
5871
  checks,
5847
5872
  summary,
5848
5873
  captured_at: evidence.captured_at,