@riddledc/riddle-proof 0.8.77 → 0.8.79
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/README.md +65 -3
- package/dist/change-proof.cjs +744 -85
- package/dist/change-proof.d.cts +100 -8
- package/dist/change-proof.d.ts +100 -8
- package/dist/change-proof.js +15 -1
- package/dist/{chunk-B2DP2LET.js → chunk-5IFZSUPF.js} +52 -13
- package/dist/chunk-6VFS2JFR.js +886 -0
- package/dist/{chunk-IY4W6STC.js → chunk-7N6X54WG.js} +116 -17
- package/dist/{chunk-GG2D3MFZ.js → chunk-FCSJZBC5.js} +26 -1
- package/dist/chunk-MEVVL4TI.js +258 -0
- package/dist/{chunk-H25IDX76.js → chunk-NEXWITV4.js} +221 -35
- package/dist/{chunk-UE4I7RTI.js → chunk-RQPCKRKT.js} +1 -1
- package/dist/cli/index.js +7 -6
- package/dist/cli.cjs +2026 -1060
- package/dist/cli.js +7 -6
- package/dist/index.cjs +932 -122
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +42 -14
- package/dist/pr-comment.cjs +416 -17
- package/dist/pr-comment.d.cts +6 -1
- package/dist/pr-comment.d.ts +6 -1
- package/dist/pr-comment.js +6 -1
- package/dist/profile/index.cjs +26 -1
- package/dist/profile/index.js +1 -1
- package/dist/profile-suggestions.js +2 -2
- package/dist/profile.cjs +26 -1
- package/dist/profile.d.cts +7 -0
- package/dist/profile.d.ts +7 -0
- package/dist/profile.js +1 -1
- package/dist/receipts.cjs +286 -0
- package/dist/receipts.d.cts +115 -0
- package/dist/receipts.d.ts +115 -0
- package/dist/receipts.js +15 -0
- package/dist/riddle-client.cjs +98 -13
- package/dist/riddle-client.d.cts +18 -5
- package/dist/riddle-client.d.ts +18 -5
- package/dist/riddle-client.js +4 -1
- package/dist/runtime/index.cjs +98 -13
- package/dist/runtime/index.d.cts +5 -1
- package/dist/runtime/index.d.ts +5 -1
- package/dist/runtime/index.js +4 -1
- package/dist/runtime/riddle-client.cjs +98 -13
- package/dist/runtime/riddle-client.d.cts +5 -1
- package/dist/runtime/riddle-client.d.ts +5 -1
- package/dist/runtime/riddle-client.js +4 -1
- package/package.json +7 -2
- package/dist/chunk-BILL3UC2.js +0 -488
package/dist/pr-comment.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var pr_comment_exports = {};
|
|
22
22
|
__export(pr_comment_exports, {
|
|
23
23
|
RIDDLE_PROOF_PR_COMMENT_MARKER: () => RIDDLE_PROOF_PR_COMMENT_MARKER,
|
|
24
|
+
buildRiddleProofHandoffPrCommentMarkdown: () => buildRiddleProofHandoffPrCommentMarkdown,
|
|
24
25
|
buildRiddleProofPrCommentMarkdown: () => buildRiddleProofPrCommentMarkdown,
|
|
25
26
|
summarizeRiddleProofPrComment: () => summarizeRiddleProofPrComment
|
|
26
27
|
});
|
|
@@ -202,6 +203,313 @@ function summarizeRiddleProofPublicState(input) {
|
|
|
202
203
|
};
|
|
203
204
|
}
|
|
204
205
|
|
|
206
|
+
// src/profile.ts
|
|
207
|
+
var RIDDLE_PROOF_PROFILE_STATUSES = [
|
|
208
|
+
"passed",
|
|
209
|
+
"product_regression",
|
|
210
|
+
"proof_insufficient",
|
|
211
|
+
"environment_blocked",
|
|
212
|
+
"configuration_error",
|
|
213
|
+
"needs_human_review"
|
|
214
|
+
];
|
|
215
|
+
|
|
216
|
+
// src/receipts.ts
|
|
217
|
+
var RIDDLE_PREVIEW_RECEIPT_VERSION = "riddle.preview-receipt.v1";
|
|
218
|
+
var RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION = "riddle-proof.observation-receipt.v1";
|
|
219
|
+
function isRecord(value) {
|
|
220
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
221
|
+
}
|
|
222
|
+
function requiredString(record, key, context) {
|
|
223
|
+
const value = record[key];
|
|
224
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
225
|
+
throw new Error(`${context}.${key} must be a non-empty string.`);
|
|
226
|
+
}
|
|
227
|
+
return value.trim();
|
|
228
|
+
}
|
|
229
|
+
function normalizedSourceIdentity(value) {
|
|
230
|
+
if (!isRecord(value)) return {};
|
|
231
|
+
return {
|
|
232
|
+
git_revision: typeof value.git_revision === "string" && value.git_revision.trim() ? value.git_revision.trim() : void 0,
|
|
233
|
+
repository: typeof value.repository === "string" && value.repository.trim() ? value.repository.trim() : void 0,
|
|
234
|
+
dirty: typeof value.dirty === "boolean" ? value.dirty : void 0,
|
|
235
|
+
label: typeof value.label === "string" && value.label.trim() ? value.label.trim() : void 0
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function parseRiddlePreviewReceipt(value) {
|
|
239
|
+
if (!isRecord(value)) throw new Error("Preview receipt must be an object.");
|
|
240
|
+
if (value.version !== RIDDLE_PREVIEW_RECEIPT_VERSION) {
|
|
241
|
+
throw new Error(`Unsupported Preview receipt version ${String(value.version || "missing")}.`);
|
|
242
|
+
}
|
|
243
|
+
if (!isRecord(value.source)) throw new Error("Preview receipt source must be an object.");
|
|
244
|
+
const expiresAt = requiredString(value, "expires_at", "preview receipt");
|
|
245
|
+
const publishedAt = requiredString(value, "published_at", "preview receipt");
|
|
246
|
+
const contentDigest = requiredString(value, "content_digest", "preview receipt");
|
|
247
|
+
if (!contentDigest.startsWith("sha256:") || contentDigest.length <= "sha256:".length) {
|
|
248
|
+
throw new Error("preview receipt.content_digest must be a sha256 digest.");
|
|
249
|
+
}
|
|
250
|
+
if (!Number.isFinite(Date.parse(expiresAt)) || !Number.isFinite(Date.parse(publishedAt))) {
|
|
251
|
+
throw new Error("Preview receipt timestamps must be valid ISO date strings.");
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
version: RIDDLE_PREVIEW_RECEIPT_VERSION,
|
|
255
|
+
preview_id: requiredString(value, "preview_id", "preview receipt"),
|
|
256
|
+
url: requiredString(value, "url", "preview receipt"),
|
|
257
|
+
expires_at: expiresAt,
|
|
258
|
+
content_digest: contentDigest,
|
|
259
|
+
source: normalizedSourceIdentity(value.source),
|
|
260
|
+
published_at: publishedAt
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function parseRiddleProofObservationReceipt(value) {
|
|
264
|
+
if (!isRecord(value)) throw new Error("Observation receipt must be an object.");
|
|
265
|
+
if (value.version !== RIDDLE_PROOF_OBSERVATION_RECEIPT_VERSION) {
|
|
266
|
+
throw new Error(`Unsupported Observation receipt version ${String(value.version || "missing")}.`);
|
|
267
|
+
}
|
|
268
|
+
if (!isRecord(value.executor)) throw new Error("Observation receipt executor must be an object.");
|
|
269
|
+
if (!isRecord(value.target)) throw new Error("Observation receipt target must be an object.");
|
|
270
|
+
if (!isRecord(value.source)) throw new Error("Observation receipt source must be an object.");
|
|
271
|
+
requiredString(value, "observation_id", "observation receipt");
|
|
272
|
+
requiredString(value, "captured_at", "observation receipt");
|
|
273
|
+
const executorKind = requiredString(value.executor, "kind", "observation receipt executor");
|
|
274
|
+
if (!"local_playwright,riddle_hosted,browser_api,other".split(",").includes(executorKind)) {
|
|
275
|
+
throw new Error(`Unsupported observation executor kind ${executorKind}.`);
|
|
276
|
+
}
|
|
277
|
+
if (value.executor.runner !== void 0) {
|
|
278
|
+
requiredString(value.executor, "runner", "observation receipt executor");
|
|
279
|
+
}
|
|
280
|
+
const role = requiredString(value, "comparison_role", "observation receipt");
|
|
281
|
+
if (!["before", "after", "standalone"].includes(role)) {
|
|
282
|
+
throw new Error(`Unsupported observation comparison role ${role}.`);
|
|
283
|
+
}
|
|
284
|
+
const targetKind = requiredString(value.target, "kind", "observation receipt target");
|
|
285
|
+
if (targetKind !== "url" && targetKind !== "preview") {
|
|
286
|
+
throw new Error(`Unsupported observation target kind ${targetKind}.`);
|
|
287
|
+
}
|
|
288
|
+
requiredString(value.target, "url", "observation receipt target");
|
|
289
|
+
if (targetKind === "preview") {
|
|
290
|
+
if (value.target.preview === void 0) {
|
|
291
|
+
throw new Error("Preview Observation target must include its Preview receipt.");
|
|
292
|
+
}
|
|
293
|
+
parseRiddlePreviewReceipt(value.target.preview);
|
|
294
|
+
}
|
|
295
|
+
if (!Array.isArray(value.artifacts)) throw new Error("Observation receipt artifacts must be an array.");
|
|
296
|
+
const artifactRoles = /* @__PURE__ */ new Set(["canonical_screenshot", "setup_screenshot", "data", "diagnostic", "artifact"]);
|
|
297
|
+
const artifacts = value.artifacts.map((artifact, index) => {
|
|
298
|
+
if (!isRecord(artifact)) throw new Error(`Observation receipt artifact ${index} must be an object.`);
|
|
299
|
+
requiredString(artifact, "name", `observation receipt artifact ${index}`);
|
|
300
|
+
const artifactRole = requiredString(artifact, "role", `observation receipt artifact ${index}`);
|
|
301
|
+
if (!artifactRoles.has(artifactRole)) {
|
|
302
|
+
throw new Error(`Unsupported observation artifact role ${artifactRole}.`);
|
|
303
|
+
}
|
|
304
|
+
return artifact;
|
|
305
|
+
});
|
|
306
|
+
if (value.canonical_screenshot !== void 0) {
|
|
307
|
+
if (!isRecord(value.canonical_screenshot) || value.canonical_screenshot.role !== "canonical_screenshot") {
|
|
308
|
+
throw new Error("Observation canonical_screenshot must have the canonical_screenshot role.");
|
|
309
|
+
}
|
|
310
|
+
const canonical = value.canonical_screenshot;
|
|
311
|
+
const included = artifacts.some((artifact) => artifact.role === "canonical_screenshot" && artifact.name === canonical.name && artifact.url === canonical.url && artifact.path === canonical.path);
|
|
312
|
+
if (!included) {
|
|
313
|
+
throw new Error("Observation canonical_screenshot must reference an artifact in the receipt.");
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return value;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// src/change-proof.ts
|
|
320
|
+
var RIDDLE_PROOF_CHANGE_RECEIPT_V1_VERSION = "riddle-proof.change-receipt.v1";
|
|
321
|
+
var RIDDLE_PROOF_CHANGE_RECEIPT_VERSION = "riddle-proof.change-receipt.v2";
|
|
322
|
+
var RIDDLE_PROOF_HANDOFF_RECEIPT_VERSION = "riddle-proof.handoff-receipt.v1";
|
|
323
|
+
var DEFAULT_BEFORE_STATUSES = ["passed", "product_regression"];
|
|
324
|
+
var DEFAULT_AFTER_STATUSES = ["passed"];
|
|
325
|
+
function changeReceiptVerdict(status) {
|
|
326
|
+
if (status === "passed") return "mergeable";
|
|
327
|
+
if (status === "environment_blocked") return "environment_blocked";
|
|
328
|
+
if (status === "configuration_error") return "configuration_error";
|
|
329
|
+
if (status === "needs_human_review") return "needs_human_review";
|
|
330
|
+
if (status === "proof_insufficient") return "proof_insufficient";
|
|
331
|
+
return "not_mergeable";
|
|
332
|
+
}
|
|
333
|
+
function changeRecommendation(verdict) {
|
|
334
|
+
if (verdict === "mergeable") {
|
|
335
|
+
return {
|
|
336
|
+
merge_recommended: true,
|
|
337
|
+
verdict,
|
|
338
|
+
label: "Merge recommended",
|
|
339
|
+
reason: "The declared before/after delta contract passed with sufficient bound evidence."
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
const reason = verdict === "not_mergeable" ? "The declared change delta did not pass." : verdict === "environment_blocked" ? "The environment blocked reliable evidence collection." : verdict === "needs_human_review" ? "The evidence requires human review." : verdict === "configuration_error" ? "The change contract is invalid." : "The change proof did not produce sufficient bound evidence.";
|
|
343
|
+
return { merge_recommended: false, verdict, label: "Merge not recommended", reason };
|
|
344
|
+
}
|
|
345
|
+
function noShippingAuthorization() {
|
|
346
|
+
return { status: "not_granted", authorized: false, source: "none" };
|
|
347
|
+
}
|
|
348
|
+
function recommendationMatches(actual, expected) {
|
|
349
|
+
return actual?.merge_recommended === expected.merge_recommended && actual.verdict === expected.verdict && actual.label === expected.label && actual.reason === expected.reason;
|
|
350
|
+
}
|
|
351
|
+
function assertShippingAuthorizationConsistent(authorization, receiptName) {
|
|
352
|
+
if (!authorization) throw new Error(`${receiptName} shipping authorization is required.`);
|
|
353
|
+
if (authorization.status !== "not_granted" && authorization.status !== "granted") {
|
|
354
|
+
throw new Error(`${receiptName} shipping authorization status is invalid.`);
|
|
355
|
+
}
|
|
356
|
+
if (authorization.source !== "none" && authorization.source !== "human" && authorization.source !== "automation") {
|
|
357
|
+
throw new Error(`${receiptName} shipping authorization source is invalid.`);
|
|
358
|
+
}
|
|
359
|
+
const granted = authorization.status === "granted";
|
|
360
|
+
if (authorization.authorized !== granted) {
|
|
361
|
+
throw new Error(`${receiptName} shipping authorization status and authorized flag must agree.`);
|
|
362
|
+
}
|
|
363
|
+
if (authorization.source === "none" === granted) {
|
|
364
|
+
throw new Error(`${receiptName} shipping authorization source must identify an authorizer only when granted.`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
function observationArtifactMatches(actual, expected) {
|
|
368
|
+
if (!actual || !expected) return actual === expected;
|
|
369
|
+
return actual.name === expected.name && actual.role === expected.role && actual.url === expected.url && actual.path === expected.path && actual.kind === expected.kind && actual.content_type === expected.content_type && actual.source === expected.source;
|
|
370
|
+
}
|
|
371
|
+
function isRecord2(value) {
|
|
372
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
373
|
+
}
|
|
374
|
+
function migratedObservationFromLegacySide(side, legacy) {
|
|
375
|
+
const legacyArtifacts = legacy.artifacts.map((artifact) => ({
|
|
376
|
+
name: artifact.name,
|
|
377
|
+
url: artifact.url,
|
|
378
|
+
path: artifact.path,
|
|
379
|
+
source: artifact.source,
|
|
380
|
+
kind: artifact.kind,
|
|
381
|
+
role: legacy.screenshots[0] && artifactTarget(artifact) === artifactTarget(legacy.screenshots[0]) ? "canonical_screenshot" : artifact.kind === "image" ? "diagnostic" : artifact.kind === "data" ? "data" : "artifact"
|
|
382
|
+
}));
|
|
383
|
+
const canonicalScreenshot = legacyArtifacts.find((artifact) => artifact.role === "canonical_screenshot");
|
|
384
|
+
return {
|
|
385
|
+
version: "riddle-proof.observation-receipt.v1",
|
|
386
|
+
observation_id: `obs_${side}_migrated`,
|
|
387
|
+
comparison_role: side,
|
|
388
|
+
executor: { kind: "other", runner: "legacy-change-receipt" },
|
|
389
|
+
target: { kind: "url", url: legacy.source },
|
|
390
|
+
source: {},
|
|
391
|
+
captured_at: legacy.captured_at || (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
392
|
+
artifacts: legacyArtifacts,
|
|
393
|
+
canonical_screenshot: canonicalScreenshot,
|
|
394
|
+
profile_summary: {
|
|
395
|
+
profile_name: legacy.profile_name,
|
|
396
|
+
status: legacy.status,
|
|
397
|
+
summary: legacy.summary,
|
|
398
|
+
route: legacy.route,
|
|
399
|
+
checks: legacy.checks
|
|
400
|
+
},
|
|
401
|
+
metadata: { migrated_from: RIDDLE_PROOF_CHANGE_RECEIPT_V1_VERSION }
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
function migrateRiddleProofChangeReceipt(legacy) {
|
|
405
|
+
const recommendation = changeRecommendation(legacy.verdict);
|
|
406
|
+
return {
|
|
407
|
+
version: RIDDLE_PROOF_CHANGE_RECEIPT_VERSION,
|
|
408
|
+
contract_name: legacy.contract_name,
|
|
409
|
+
profile_name: legacy.profile_name,
|
|
410
|
+
status: legacy.status,
|
|
411
|
+
verdict: legacy.verdict,
|
|
412
|
+
summary: legacy.summary,
|
|
413
|
+
before: migratedObservationFromLegacySide("before", legacy.before),
|
|
414
|
+
after: migratedObservationFromLegacySide("after", legacy.after),
|
|
415
|
+
groups: {
|
|
416
|
+
before: {
|
|
417
|
+
side: "before",
|
|
418
|
+
label: "before",
|
|
419
|
+
ok: legacy.before.status === "passed" || legacy.before.status === "product_regression",
|
|
420
|
+
profile_name: legacy.before.profile_name,
|
|
421
|
+
status: legacy.before.status,
|
|
422
|
+
required_status: DEFAULT_BEFORE_STATUSES,
|
|
423
|
+
summary: legacy.before.summary
|
|
424
|
+
},
|
|
425
|
+
after: {
|
|
426
|
+
side: "after",
|
|
427
|
+
label: "after",
|
|
428
|
+
ok: legacy.after.status === "passed",
|
|
429
|
+
profile_name: legacy.after.profile_name,
|
|
430
|
+
status: legacy.after.status,
|
|
431
|
+
required_status: DEFAULT_AFTER_STATUSES,
|
|
432
|
+
summary: legacy.after.summary
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
source_bindings: {
|
|
436
|
+
before: { side: "before", required: false, ok: true, status: "not_required" },
|
|
437
|
+
after: { side: "after", required: false, ok: true, status: "not_required" }
|
|
438
|
+
},
|
|
439
|
+
deltas: legacy.deltas,
|
|
440
|
+
recommendation,
|
|
441
|
+
shipping_authorization: noShippingAuthorization(),
|
|
442
|
+
proves: legacy.proves,
|
|
443
|
+
does_not_prove: legacy.does_not_prove,
|
|
444
|
+
metadata: legacy.metadata
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
function parseRiddleProofChangeReceipt(value) {
|
|
448
|
+
if (!isRecord2(value)) throw new Error("Change receipt must be an object.");
|
|
449
|
+
if (value.version === RIDDLE_PROOF_CHANGE_RECEIPT_V1_VERSION) {
|
|
450
|
+
return migrateRiddleProofChangeReceipt(value);
|
|
451
|
+
}
|
|
452
|
+
if (value.version !== RIDDLE_PROOF_CHANGE_RECEIPT_VERSION) {
|
|
453
|
+
throw new Error(`Unsupported Change receipt version ${String(value.version || "missing")}.`);
|
|
454
|
+
}
|
|
455
|
+
const receipt = value;
|
|
456
|
+
if (!RIDDLE_PROOF_PROFILE_STATUSES.includes(receipt.status)) {
|
|
457
|
+
throw new Error(`Unsupported Change receipt status ${String(receipt.status || "missing")}.`);
|
|
458
|
+
}
|
|
459
|
+
parseRiddleProofObservationReceipt(receipt.before);
|
|
460
|
+
parseRiddleProofObservationReceipt(receipt.after);
|
|
461
|
+
if (receipt.before.comparison_role !== "before" || receipt.after.comparison_role !== "after") {
|
|
462
|
+
throw new Error("Change receipt observations must preserve their before and after comparison roles.");
|
|
463
|
+
}
|
|
464
|
+
const expectedVerdict = changeReceiptVerdict(receipt.status);
|
|
465
|
+
if (receipt.verdict !== expectedVerdict) {
|
|
466
|
+
throw new Error("Change receipt verdict must match its evaluated status.");
|
|
467
|
+
}
|
|
468
|
+
if (!recommendationMatches(receipt.recommendation, changeRecommendation(expectedVerdict))) {
|
|
469
|
+
throw new Error("Change receipt recommendation must be derived from the Change receipt verdict.");
|
|
470
|
+
}
|
|
471
|
+
assertShippingAuthorizationConsistent(receipt.shipping_authorization, "Change receipt");
|
|
472
|
+
return receipt;
|
|
473
|
+
}
|
|
474
|
+
function createRiddleProofHandoffReceipt(changeReceipt, options = {}) {
|
|
475
|
+
const change = parseRiddleProofChangeReceipt(changeReceipt);
|
|
476
|
+
const authorization = options.shipping_authorization || change.shipping_authorization;
|
|
477
|
+
assertShippingAuthorizationConsistent(authorization, "Handoff receipt");
|
|
478
|
+
return {
|
|
479
|
+
version: RIDDLE_PROOF_HANDOFF_RECEIPT_VERSION,
|
|
480
|
+
change,
|
|
481
|
+
verdict: change.verdict,
|
|
482
|
+
recommendation: change.recommendation,
|
|
483
|
+
shipping_authorization: authorization,
|
|
484
|
+
canonical_pair: {
|
|
485
|
+
before: change.before.canonical_screenshot,
|
|
486
|
+
after: change.after.canonical_screenshot
|
|
487
|
+
},
|
|
488
|
+
created_at: options.created_at || (/* @__PURE__ */ new Date()).toISOString()
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
function parseRiddleProofHandoffReceipt(value) {
|
|
492
|
+
if (!isRecord2(value) || value.version !== RIDDLE_PROOF_HANDOFF_RECEIPT_VERSION) {
|
|
493
|
+
throw new Error(`Unsupported Handoff receipt version ${String(isRecord2(value) ? value.version || "missing" : "missing")}.`);
|
|
494
|
+
}
|
|
495
|
+
const receipt = value;
|
|
496
|
+
if (!Number.isFinite(Date.parse(receipt.created_at))) {
|
|
497
|
+
throw new Error("Handoff receipt created_at must be a valid timestamp.");
|
|
498
|
+
}
|
|
499
|
+
const change = parseRiddleProofChangeReceipt(receipt.change);
|
|
500
|
+
if (receipt.verdict !== change.verdict || !recommendationMatches(receipt.recommendation, change.recommendation)) {
|
|
501
|
+
throw new Error("Handoff receipt must preserve the Change receipt verdict and recommendation.");
|
|
502
|
+
}
|
|
503
|
+
if (!observationArtifactMatches(receipt.canonical_pair?.before, change.before.canonical_screenshot) || !observationArtifactMatches(receipt.canonical_pair?.after, change.after.canonical_screenshot)) {
|
|
504
|
+
throw new Error("Handoff receipt canonical pair must project the Change receipt observations.");
|
|
505
|
+
}
|
|
506
|
+
assertShippingAuthorizationConsistent(receipt.shipping_authorization, "Handoff receipt");
|
|
507
|
+
return receipt;
|
|
508
|
+
}
|
|
509
|
+
function artifactTarget(artifact) {
|
|
510
|
+
return artifact.url || artifact.path;
|
|
511
|
+
}
|
|
512
|
+
|
|
205
513
|
// src/pr-comment.ts
|
|
206
514
|
var RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
|
|
207
515
|
function asRecord2(value) {
|
|
@@ -282,9 +590,10 @@ function collectChangeReceiptArtifacts(result) {
|
|
|
282
590
|
const seen = /* @__PURE__ */ new Set();
|
|
283
591
|
const collectSide = (sideName, side) => {
|
|
284
592
|
const candidates = [
|
|
593
|
+
side.canonical_screenshot,
|
|
285
594
|
...asArray(side.screenshots),
|
|
286
595
|
...asArray(side.artifacts)
|
|
287
|
-
];
|
|
596
|
+
].filter(Boolean);
|
|
288
597
|
for (const [index, item] of candidates.entries()) {
|
|
289
598
|
const artifact = asRecord2(item);
|
|
290
599
|
const url = stringValue2(artifact.url) || stringValue2(artifact.path);
|
|
@@ -376,9 +685,10 @@ function changeReceiptPageSummaries(result) {
|
|
|
376
685
|
for (const sideName of ["before", "after"]) {
|
|
377
686
|
const side = asRecord2(result[sideName]);
|
|
378
687
|
if (!Object.keys(side).length) continue;
|
|
379
|
-
const
|
|
688
|
+
const profileSummary = asRecord2(side.profile_summary);
|
|
689
|
+
const checks = Object.keys(asRecord2(side.checks)).length ? asRecord2(side.checks) : asRecord2(profileSummary.checks);
|
|
380
690
|
pages.push({
|
|
381
|
-
route: firstStringValue2(side.source, side.profile_name) || sideName,
|
|
691
|
+
route: firstStringValue2(asRecord2(side.target).url, side.source, profileSummary.profile_name, side.profile_name) || sideName,
|
|
382
692
|
passed: numberValue2(checks.passed) ?? 0,
|
|
383
693
|
failed: numberValue2(checks.failed) ?? 0
|
|
384
694
|
});
|
|
@@ -441,7 +751,11 @@ function isProfileResult(result) {
|
|
|
441
751
|
return version === "riddle-proof.profile-result.v1" || version === "riddle-proof.profile-compact-result.v1";
|
|
442
752
|
}
|
|
443
753
|
function isChangeReceiptResult(result) {
|
|
444
|
-
|
|
754
|
+
const version = stringValue2(result.version);
|
|
755
|
+
return version === RIDDLE_PROOF_CHANGE_RECEIPT_V1_VERSION || version === RIDDLE_PROOF_CHANGE_RECEIPT_VERSION;
|
|
756
|
+
}
|
|
757
|
+
function isHandoffReceiptResult(result) {
|
|
758
|
+
return stringValue2(result.version) === RIDDLE_PROOF_HANDOFF_RECEIPT_VERSION;
|
|
445
759
|
}
|
|
446
760
|
function isChangeResult(result) {
|
|
447
761
|
const version = stringValue2(result.version);
|
|
@@ -449,10 +763,13 @@ function isChangeResult(result) {
|
|
|
449
763
|
}
|
|
450
764
|
function summarizeRiddleProofPrComment(input) {
|
|
451
765
|
const runResponse = asRecord2(input.runResponse);
|
|
452
|
-
const
|
|
766
|
+
const inputResult = asRecord2(input.result);
|
|
767
|
+
const handoffReceipt = isHandoffReceiptResult(inputResult) ? parseRiddleProofHandoffReceipt(inputResult) : void 0;
|
|
768
|
+
const parsedChangeReceipt = handoffReceipt?.change || (isChangeReceiptResult(inputResult) ? parseRiddleProofChangeReceipt(inputResult) : void 0);
|
|
769
|
+
const result = parsedChangeReceipt ? asRecord2(parsedChangeReceipt) : inputResult;
|
|
453
770
|
const proofResult = asRecord2(runResponse.proofResult);
|
|
454
771
|
const profileResult = isProfileResult(result);
|
|
455
|
-
const changeReceiptResult =
|
|
772
|
+
const changeReceiptResult = Boolean(parsedChangeReceipt);
|
|
456
773
|
const changeResult = changeReceiptResult || isChangeResult(result);
|
|
457
774
|
const profileRiddle = asRecord2(result.riddle);
|
|
458
775
|
const preview = asRecord2(runResponse.preview);
|
|
@@ -473,7 +790,7 @@ function summarizeRiddleProofPrComment(input) {
|
|
|
473
790
|
delete checkSource.ok;
|
|
474
791
|
const nestedChecks = summarizeExplicitChecks(checkSource);
|
|
475
792
|
const resultStatus = firstStringValue2(result.status, stopCondition.status);
|
|
476
|
-
const ok = changeResult ? resultStatus === "passed" : booleanValue2(result.ok) ?? booleanValue2(runResponse.ok) ?? null;
|
|
793
|
+
const ok = changeReceiptResult ? parsedChangeReceipt?.recommendation.merge_recommended ?? false : changeResult ? resultStatus === "passed" : booleanValue2(result.ok) ?? booleanValue2(runResponse.ok) ?? null;
|
|
477
794
|
const checkpointSummary = checkpointSummaryFrom2(
|
|
478
795
|
result.checkpoint_summary,
|
|
479
796
|
stopCondition.checkpoint_summary,
|
|
@@ -481,19 +798,19 @@ function summarizeRiddleProofPrComment(input) {
|
|
|
481
798
|
rawDetails.checkpoint_summary,
|
|
482
799
|
proofResult.checkpoint_summary
|
|
483
800
|
);
|
|
484
|
-
const publicState = summarizeRiddleProofPublicState({
|
|
801
|
+
const publicState = changeReceiptResult ? void 0 : summarizeRiddleProofPublicState({
|
|
485
802
|
...result,
|
|
486
803
|
status: resultStatus,
|
|
487
804
|
checkpoint_summary: checkpointSummary || result.checkpoint_summary
|
|
488
805
|
});
|
|
489
|
-
const mergeRecommendation = riddleProofPublicStateMergeRecommendation(
|
|
806
|
+
const mergeRecommendation = publicState ? riddleProofPublicStateMergeRecommendation(
|
|
490
807
|
publicState,
|
|
491
808
|
firstStringValue2(result.merge_recommendation, stopCondition.merge_recommendation, resultRaw.merge_recommendation)
|
|
492
|
-
);
|
|
809
|
+
) : void 0;
|
|
493
810
|
return {
|
|
494
811
|
ok,
|
|
495
812
|
status: firstStringValue2(proofResult.status, profileRiddle.status),
|
|
496
|
-
result_status: changeResult ? resultStatus : publicState
|
|
813
|
+
result_status: changeResult ? resultStatus : publicState?.status,
|
|
497
814
|
job_id: firstStringValue2(proofResult.job_id, profileRiddle.job_id),
|
|
498
815
|
duration_ms: numberValue2(proofResult.duration_ms) ?? numberValue2(profileRiddle.elapsed_ms),
|
|
499
816
|
proof_url: stringValue2(runResponse.proofUrl),
|
|
@@ -501,13 +818,13 @@ function summarizeRiddleProofPrComment(input) {
|
|
|
501
818
|
preview_url: stringValue2(preview.preview_url) || stringValue2(preview.url),
|
|
502
819
|
preview_publish_recovered: booleanValue2(preview.publish_recovered),
|
|
503
820
|
preview_publish_error: stringValue2(preview.publish_error),
|
|
504
|
-
ship_held: publicState
|
|
505
|
-
shipping_disabled: publicState
|
|
506
|
-
ship_authorized: publicState
|
|
507
|
-
merge_ready: publicState
|
|
508
|
-
sync_allowed: publicState
|
|
821
|
+
ship_held: publicState?.ship_held,
|
|
822
|
+
shipping_disabled: publicState?.shipping_disabled,
|
|
823
|
+
ship_authorized: changeReceiptResult ? parsedChangeReceipt?.shipping_authorization.authorized : publicState?.ship_authorized,
|
|
824
|
+
merge_ready: publicState?.merge_ready,
|
|
825
|
+
sync_allowed: publicState?.sync_allowed,
|
|
509
826
|
proof_decision: firstStringValue2(result.proof_decision, stopCondition.proof_decision, resultRaw.proof_decision),
|
|
510
|
-
merge_recommendation: changeReceiptResult
|
|
827
|
+
merge_recommendation: changeReceiptResult ? parsedChangeReceipt?.recommendation.label : mergeRecommendation,
|
|
511
828
|
checkpoint_summary: checkpointSummary,
|
|
512
829
|
public_state: publicState,
|
|
513
830
|
passed_checks: changeChecks?.passed ?? profileChecks?.passed ?? nestedChecks.passed,
|
|
@@ -575,7 +892,88 @@ function checkpointSummaryLine(summary) {
|
|
|
575
892
|
summary.latest_decision ? `latest decision \`${summary.latest_decision}\`` : ""
|
|
576
893
|
].filter(Boolean).join("; ");
|
|
577
894
|
}
|
|
895
|
+
function markdownTableValue(value) {
|
|
896
|
+
return String(value ?? "").replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
897
|
+
}
|
|
898
|
+
function observationArtifactTarget(artifact) {
|
|
899
|
+
return artifact?.url || artifact?.path;
|
|
900
|
+
}
|
|
901
|
+
function canonicalScreenshotCell(artifact, fallback) {
|
|
902
|
+
const target = observationArtifactTarget(artifact);
|
|
903
|
+
if (!artifact || !target) return fallback;
|
|
904
|
+
if (artifact.url) return `![${artifact.name.replace(/\]/g, "\\]")}](${artifact.url})`;
|
|
905
|
+
return markdownTableValue(artifact.path || artifact.name);
|
|
906
|
+
}
|
|
907
|
+
function shortRevision(value) {
|
|
908
|
+
return value ? value.slice(0, 12) : "not recorded";
|
|
909
|
+
}
|
|
910
|
+
function buildRiddleProofHandoffPrCommentMarkdown(handoff, input = {}) {
|
|
911
|
+
const receipt = parseRiddleProofHandoffReceipt(handoff);
|
|
912
|
+
const change = receipt.change;
|
|
913
|
+
const beforeStatus = change.before.profile_summary?.status || "not recorded";
|
|
914
|
+
const afterStatus = change.after.profile_summary?.status || "not recorded";
|
|
915
|
+
const beforeBaseline = change.groups.before.ok ? "matched baseline" : "baseline mismatch";
|
|
916
|
+
const lines = [
|
|
917
|
+
RIDDLE_PROOF_PR_COMMENT_MARKER,
|
|
918
|
+
`## ${input.title?.trim() || "Riddle Change Proof"}`,
|
|
919
|
+
"",
|
|
920
|
+
`**Result:** ${receipt.recommendation.label}`,
|
|
921
|
+
`**Evidence verdict:** \`${receipt.verdict}\``,
|
|
922
|
+
`**Shipping authorization:** ${receipt.shipping_authorization.status}`,
|
|
923
|
+
`**Contract:** ${change.contract_name}`
|
|
924
|
+
];
|
|
925
|
+
if (input.goal?.trim()) lines.push(`**Goal:** ${input.goal.trim()}`);
|
|
926
|
+
if (input.successCriteria?.trim()) lines.push(`**Success criteria:** ${input.successCriteria.trim()}`);
|
|
927
|
+
lines.push("", change.summary, "", "### Canonical Before / After", "");
|
|
928
|
+
lines.push("| Before | After |");
|
|
929
|
+
lines.push("| --- | --- |");
|
|
930
|
+
lines.push(`| ${beforeBaseline}: \`${markdownTableValue(beforeStatus)}\` | \`${markdownTableValue(afterStatus)}\` |`);
|
|
931
|
+
lines.push(`| ${canonicalScreenshotCell(receipt.canonical_pair.before, "No canonical before screenshot")} | ${canonicalScreenshotCell(receipt.canonical_pair.after, "No canonical after screenshot")} |`);
|
|
932
|
+
lines.push("", "### Source Binding", "");
|
|
933
|
+
lines.push("| Side | Target | Git revision | Binding | Preview | Digest |");
|
|
934
|
+
lines.push("| --- | --- | --- | --- | --- | --- |");
|
|
935
|
+
for (const side of ["before", "after"]) {
|
|
936
|
+
const observation = change[side];
|
|
937
|
+
const binding = change.source_bindings[side];
|
|
938
|
+
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")}\` |`);
|
|
939
|
+
}
|
|
940
|
+
lines.push("", "### Declared Delta", "");
|
|
941
|
+
lines.push("| Measurement | Status | Before | After |");
|
|
942
|
+
lines.push("| --- | --- | --- | --- |");
|
|
943
|
+
for (const delta of change.deltas) {
|
|
944
|
+
lines.push(`| ${markdownTableValue(delta.label)} | ${delta.status} | ${markdownTableValue(delta.before_observed)} | ${markdownTableValue(delta.after_observed)} |`);
|
|
945
|
+
}
|
|
946
|
+
if (change.proves.length) {
|
|
947
|
+
lines.push("", "### What This Proves", "");
|
|
948
|
+
for (const claim of change.proves) lines.push(`- ${claim}`);
|
|
949
|
+
}
|
|
950
|
+
if (change.does_not_prove.length) {
|
|
951
|
+
lines.push("", "### Limits", "");
|
|
952
|
+
for (const claim of change.does_not_prove) lines.push(`- ${claim}`);
|
|
953
|
+
}
|
|
954
|
+
const linkedArtifacts = [
|
|
955
|
+
...change.before.artifacts.map((artifact) => ({ side: "before", artifact })),
|
|
956
|
+
...change.after.artifacts.map((artifact) => ({ side: "after", artifact }))
|
|
957
|
+
].filter(({ artifact }) => Boolean(artifact.url));
|
|
958
|
+
if (linkedArtifacts.length) {
|
|
959
|
+
lines.push("", "### Artifacts", "");
|
|
960
|
+
for (const { side, artifact } of linkedArtifacts.slice(0, 24)) {
|
|
961
|
+
lines.push(`- ${side}: ${markdownLink(artifact.name, artifact.url || "")}`);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
lines.push("", input.source?.trim() ? `_Source: ${input.source.trim()}_` : "_Rendered from the Handoff receipt without recomputing its verdict._");
|
|
965
|
+
return `${lines.join("\n").trim()}
|
|
966
|
+
`;
|
|
967
|
+
}
|
|
578
968
|
function buildRiddleProofPrCommentMarkdown(input) {
|
|
969
|
+
const result = asRecord2(input.result);
|
|
970
|
+
if (isHandoffReceiptResult(result)) {
|
|
971
|
+
return buildRiddleProofHandoffPrCommentMarkdown(parseRiddleProofHandoffReceipt(result), input);
|
|
972
|
+
}
|
|
973
|
+
if (isChangeReceiptResult(result)) {
|
|
974
|
+
const handoff = createRiddleProofHandoffReceipt(parseRiddleProofChangeReceipt(result));
|
|
975
|
+
return buildRiddleProofHandoffPrCommentMarkdown(handoff, input);
|
|
976
|
+
}
|
|
579
977
|
const summary = summarizeRiddleProofPrComment(input);
|
|
580
978
|
const title = input.title?.trim() || "Riddle Proof Evidence";
|
|
581
979
|
const lines = [
|
|
@@ -645,6 +1043,7 @@ function buildRiddleProofPrCommentMarkdown(input) {
|
|
|
645
1043
|
// Annotate the CommonJS export names for ESM import in node:
|
|
646
1044
|
0 && (module.exports = {
|
|
647
1045
|
RIDDLE_PROOF_PR_COMMENT_MARKER,
|
|
1046
|
+
buildRiddleProofHandoffPrCommentMarkdown,
|
|
648
1047
|
buildRiddleProofPrCommentMarkdown,
|
|
649
1048
|
summarizeRiddleProofPrComment
|
|
650
1049
|
});
|
package/dist/pr-comment.d.cts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { RiddleProofPublicStateSummary } from './public-state.cjs';
|
|
2
|
+
import { RiddleProofHandoffReceipt } from './change-proof.cjs';
|
|
3
|
+
import './profile.cjs';
|
|
4
|
+
import './types.cjs';
|
|
5
|
+
import './receipts.cjs';
|
|
2
6
|
|
|
3
7
|
declare const RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
|
|
4
8
|
type RiddleProofPrCommentArtifactKind = "image" | "data" | "artifact";
|
|
@@ -58,6 +62,7 @@ interface RiddleProofPrCommentInput {
|
|
|
58
62
|
source?: string;
|
|
59
63
|
}
|
|
60
64
|
declare function summarizeRiddleProofPrComment(input: RiddleProofPrCommentInput): RiddleProofPrCommentSummary;
|
|
65
|
+
declare function buildRiddleProofHandoffPrCommentMarkdown(handoff: RiddleProofHandoffReceipt, input?: Omit<RiddleProofPrCommentInput, "result">): string;
|
|
61
66
|
declare function buildRiddleProofPrCommentMarkdown(input: RiddleProofPrCommentInput): string;
|
|
62
67
|
|
|
63
|
-
export { RIDDLE_PROOF_PR_COMMENT_MARKER, type RiddleProofPrCommentArtifact, type RiddleProofPrCommentArtifactKind, type RiddleProofPrCommentCheckpointSummary, type RiddleProofPrCommentInput, type RiddleProofPrCommentPageSummary, type RiddleProofPrCommentSummary, buildRiddleProofPrCommentMarkdown, summarizeRiddleProofPrComment };
|
|
68
|
+
export { RIDDLE_PROOF_PR_COMMENT_MARKER, type RiddleProofPrCommentArtifact, type RiddleProofPrCommentArtifactKind, type RiddleProofPrCommentCheckpointSummary, type RiddleProofPrCommentInput, type RiddleProofPrCommentPageSummary, type RiddleProofPrCommentSummary, buildRiddleProofHandoffPrCommentMarkdown, buildRiddleProofPrCommentMarkdown, summarizeRiddleProofPrComment };
|
package/dist/pr-comment.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { RiddleProofPublicStateSummary } from './public-state.js';
|
|
2
|
+
import { RiddleProofHandoffReceipt } from './change-proof.js';
|
|
3
|
+
import './profile.js';
|
|
4
|
+
import './types.js';
|
|
5
|
+
import './receipts.js';
|
|
2
6
|
|
|
3
7
|
declare const RIDDLE_PROOF_PR_COMMENT_MARKER = "<!-- riddle-proof:pr-comment:v1 -->";
|
|
4
8
|
type RiddleProofPrCommentArtifactKind = "image" | "data" | "artifact";
|
|
@@ -58,6 +62,7 @@ interface RiddleProofPrCommentInput {
|
|
|
58
62
|
source?: string;
|
|
59
63
|
}
|
|
60
64
|
declare function summarizeRiddleProofPrComment(input: RiddleProofPrCommentInput): RiddleProofPrCommentSummary;
|
|
65
|
+
declare function buildRiddleProofHandoffPrCommentMarkdown(handoff: RiddleProofHandoffReceipt, input?: Omit<RiddleProofPrCommentInput, "result">): string;
|
|
61
66
|
declare function buildRiddleProofPrCommentMarkdown(input: RiddleProofPrCommentInput): string;
|
|
62
67
|
|
|
63
|
-
export { RIDDLE_PROOF_PR_COMMENT_MARKER, type RiddleProofPrCommentArtifact, type RiddleProofPrCommentArtifactKind, type RiddleProofPrCommentCheckpointSummary, type RiddleProofPrCommentInput, type RiddleProofPrCommentPageSummary, type RiddleProofPrCommentSummary, buildRiddleProofPrCommentMarkdown, summarizeRiddleProofPrComment };
|
|
68
|
+
export { RIDDLE_PROOF_PR_COMMENT_MARKER, type RiddleProofPrCommentArtifact, type RiddleProofPrCommentArtifactKind, type RiddleProofPrCommentCheckpointSummary, type RiddleProofPrCommentInput, type RiddleProofPrCommentPageSummary, type RiddleProofPrCommentSummary, buildRiddleProofHandoffPrCommentMarkdown, buildRiddleProofPrCommentMarkdown, summarizeRiddleProofPrComment };
|
package/dist/pr-comment.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RIDDLE_PROOF_PR_COMMENT_MARKER,
|
|
3
|
+
buildRiddleProofHandoffPrCommentMarkdown,
|
|
3
4
|
buildRiddleProofPrCommentMarkdown,
|
|
4
5
|
summarizeRiddleProofPrComment
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-7N6X54WG.js";
|
|
7
|
+
import "./chunk-6VFS2JFR.js";
|
|
8
|
+
import "./chunk-MEVVL4TI.js";
|
|
9
|
+
import "./chunk-FCSJZBC5.js";
|
|
6
10
|
import "./chunk-ZAR7BWMN.js";
|
|
7
11
|
import "./chunk-MLKGABMK.js";
|
|
8
12
|
export {
|
|
9
13
|
RIDDLE_PROOF_PR_COMMENT_MARKER,
|
|
14
|
+
buildRiddleProofHandoffPrCommentMarkdown,
|
|
10
15
|
buildRiddleProofPrCommentMarkdown,
|
|
11
16
|
summarizeRiddleProofPrComment
|
|
12
17
|
};
|
package/dist/profile/index.cjs
CHANGED
|
@@ -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: {
|
|
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,
|
package/dist/profile/index.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
resolveRiddleProofProfileTimeoutSec,
|
|
28
28
|
slugifyRiddleProofProfileName,
|
|
29
29
|
summarizeRiddleProofProfileResult
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-FCSJZBC5.js";
|
|
31
31
|
import "../chunk-MLKGABMK.js";
|
|
32
32
|
export {
|
|
33
33
|
RIDDLE_PROOF_HOSTED_PROFILE_ARTIFACTS,
|