@riddledc/riddle-proof 0.8.75 → 0.8.77
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 +15 -4
- package/dist/change-proof.cjs +327 -2
- package/dist/change-proof.d.cts +65 -1
- package/dist/change-proof.d.ts +65 -1
- package/dist/change-proof.js +11 -3
- package/dist/chunk-BILL3UC2.js +488 -0
- package/dist/{chunk-AK2EPEVO.js → chunk-H25IDX76.js} +26 -39
- package/dist/{chunk-CWRIXP5H.js → chunk-IY4W6STC.js} +73 -8
- package/dist/cli/index.js +3 -3
- package/dist/cli.cjs +410 -44
- package/dist/cli.js +3 -3
- package/dist/index.cjs +407 -17
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -3
- package/dist/pr-comment.cjs +73 -8
- package/dist/pr-comment.js +1 -1
- package/examples/change-contracts/hosted-change-proof-preview.json +16 -0
- package/examples/neutral-fixture-site/pass.html +4 -0
- package/examples/neutral-fixture-site/styles.css +1 -1
- package/examples/profiles/hosted-change-proof-preview.json +36 -0
- package/package.json +1 -1
- package/dist/chunk-6S7DZWVC.js +0 -167
package/dist/index.js
CHANGED
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
RIDDLE_PROOF_PR_COMMENT_MARKER,
|
|
62
62
|
buildRiddleProofPrCommentMarkdown,
|
|
63
63
|
summarizeRiddleProofPrComment
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-IY4W6STC.js";
|
|
65
65
|
import {
|
|
66
66
|
RIDDLE_PROOF_PROFILE_SUGGESTIONS_VERSION,
|
|
67
67
|
suggestRiddleProofProfileChecks
|
|
@@ -98,9 +98,13 @@ import {
|
|
|
98
98
|
} from "./chunk-GG2D3MFZ.js";
|
|
99
99
|
import {
|
|
100
100
|
RIDDLE_PROOF_CHANGE_CONTRACT_VERSION,
|
|
101
|
+
RIDDLE_PROOF_CHANGE_RECEIPT_VERSION,
|
|
101
102
|
RIDDLE_PROOF_CHANGE_RESULT_VERSION,
|
|
102
|
-
assessRiddleProofChange
|
|
103
|
-
|
|
103
|
+
assessRiddleProofChange,
|
|
104
|
+
createRiddleProofChangeReceipt,
|
|
105
|
+
riddleProofChangeReceiptHtml,
|
|
106
|
+
riddleProofChangeReceiptMarkdown
|
|
107
|
+
} from "./chunk-BILL3UC2.js";
|
|
104
108
|
import {
|
|
105
109
|
createCodexExecAgentAdapter,
|
|
106
110
|
createCodexExecJsonRunner,
|
|
@@ -193,6 +197,7 @@ export {
|
|
|
193
197
|
RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION,
|
|
194
198
|
RIDDLE_PROOF_CAPTURE_DIAGNOSTIC_VERSION,
|
|
195
199
|
RIDDLE_PROOF_CHANGE_CONTRACT_VERSION,
|
|
200
|
+
RIDDLE_PROOF_CHANGE_RECEIPT_VERSION,
|
|
196
201
|
RIDDLE_PROOF_CHANGE_RESULT_VERSION,
|
|
197
202
|
RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
|
|
198
203
|
RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
|
|
@@ -258,6 +263,7 @@ export {
|
|
|
258
263
|
createCodexExecAgentAdapter as createLocalAgentAdapter,
|
|
259
264
|
createCodexExecJsonRunner as createLocalAgentJsonRunner,
|
|
260
265
|
createRiddleApiClient,
|
|
266
|
+
createRiddleProofChangeReceipt,
|
|
261
267
|
createRiddleProofProfileConfigurationError,
|
|
262
268
|
createRiddleProofProfileEnvironmentBlockedResult,
|
|
263
269
|
createRiddleProofProfileInsufficientResult,
|
|
@@ -303,6 +309,8 @@ export {
|
|
|
303
309
|
resolveRiddleProofProfileRouteUrl,
|
|
304
310
|
resolveRiddleProofProfileTargetUrl,
|
|
305
311
|
resolveRiddleProofProfileTimeoutSec,
|
|
312
|
+
riddleProofChangeReceiptHtml,
|
|
313
|
+
riddleProofChangeReceiptMarkdown,
|
|
306
314
|
riddleProofPublicStateAllowsClaim,
|
|
307
315
|
riddleProofPublicStateAllowsMergeRecommendation,
|
|
308
316
|
riddleProofPublicStateMergeRecommendation,
|
package/dist/pr-comment.cjs
CHANGED
|
@@ -277,6 +277,33 @@ function collectProfileArtifacts(result) {
|
|
|
277
277
|
}
|
|
278
278
|
return artifacts;
|
|
279
279
|
}
|
|
280
|
+
function collectChangeReceiptArtifacts(result) {
|
|
281
|
+
const artifacts = [];
|
|
282
|
+
const seen = /* @__PURE__ */ new Set();
|
|
283
|
+
const collectSide = (sideName, side) => {
|
|
284
|
+
const candidates = [
|
|
285
|
+
...asArray(side.screenshots),
|
|
286
|
+
...asArray(side.artifacts)
|
|
287
|
+
];
|
|
288
|
+
for (const [index, item] of candidates.entries()) {
|
|
289
|
+
const artifact = asRecord2(item);
|
|
290
|
+
const url = stringValue2(artifact.url) || stringValue2(artifact.path);
|
|
291
|
+
if (!url || seen.has(url)) continue;
|
|
292
|
+
seen.add(url);
|
|
293
|
+
const fallbackName = `${sideName}-artifact-${index + 1}`;
|
|
294
|
+
const name = `${sideName}/${artifactDisplayName(artifact.name, fallbackName)}`;
|
|
295
|
+
artifacts.push({
|
|
296
|
+
name,
|
|
297
|
+
url,
|
|
298
|
+
kind: artifactKind(name, url),
|
|
299
|
+
size_bytes: numberValue2(artifact.size_bytes) ?? numberValue2(artifact.size)
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
collectSide("before", asRecord2(result.before));
|
|
304
|
+
collectSide("after", asRecord2(result.after));
|
|
305
|
+
return artifacts;
|
|
306
|
+
}
|
|
280
307
|
function mergeArtifacts(...artifactLists) {
|
|
281
308
|
const artifacts = [];
|
|
282
309
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -332,6 +359,32 @@ function profilePageSummaries(result, counts) {
|
|
|
332
359
|
failed: counts.failed
|
|
333
360
|
}];
|
|
334
361
|
}
|
|
362
|
+
function changeReceiptCheckCounts(result) {
|
|
363
|
+
const deltas = asArray(result.deltas);
|
|
364
|
+
if (!deltas.length) return void 0;
|
|
365
|
+
let passed = 0;
|
|
366
|
+
let failed = 0;
|
|
367
|
+
for (const item of deltas) {
|
|
368
|
+
const status = stringValue2(asRecord2(item).status);
|
|
369
|
+
if (status === "passed") passed += 1;
|
|
370
|
+
if (status === "failed" || status === "proof_insufficient" || status === "configuration_error") failed += 1;
|
|
371
|
+
}
|
|
372
|
+
return { passed, failed };
|
|
373
|
+
}
|
|
374
|
+
function changeReceiptPageSummaries(result) {
|
|
375
|
+
const pages = [];
|
|
376
|
+
for (const sideName of ["before", "after"]) {
|
|
377
|
+
const side = asRecord2(result[sideName]);
|
|
378
|
+
if (!Object.keys(side).length) continue;
|
|
379
|
+
const checks = asRecord2(side.checks);
|
|
380
|
+
pages.push({
|
|
381
|
+
route: firstStringValue2(side.source, side.profile_name) || sideName,
|
|
382
|
+
passed: numberValue2(checks.passed) ?? 0,
|
|
383
|
+
failed: numberValue2(checks.failed) ?? 0
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
return pages;
|
|
387
|
+
}
|
|
335
388
|
function summarizeExplicitChecks(value) {
|
|
336
389
|
let passed = 0;
|
|
337
390
|
let failed = 0;
|
|
@@ -387,11 +440,20 @@ function isProfileResult(result) {
|
|
|
387
440
|
const version = stringValue2(result.version);
|
|
388
441
|
return version === "riddle-proof.profile-result.v1" || version === "riddle-proof.profile-compact-result.v1";
|
|
389
442
|
}
|
|
443
|
+
function isChangeReceiptResult(result) {
|
|
444
|
+
return stringValue2(result.version) === "riddle-proof.change-receipt.v1";
|
|
445
|
+
}
|
|
446
|
+
function isChangeResult(result) {
|
|
447
|
+
const version = stringValue2(result.version);
|
|
448
|
+
return version === "riddle-proof.change-result.v1" || version === "riddle-proof.change-compact-result.v1";
|
|
449
|
+
}
|
|
390
450
|
function summarizeRiddleProofPrComment(input) {
|
|
391
451
|
const runResponse = asRecord2(input.runResponse);
|
|
392
452
|
const result = asRecord2(input.result);
|
|
393
453
|
const proofResult = asRecord2(runResponse.proofResult);
|
|
394
454
|
const profileResult = isProfileResult(result);
|
|
455
|
+
const changeReceiptResult = isChangeReceiptResult(result);
|
|
456
|
+
const changeResult = changeReceiptResult || isChangeResult(result);
|
|
395
457
|
const profileRiddle = asRecord2(result.riddle);
|
|
396
458
|
const preview = asRecord2(runResponse.preview);
|
|
397
459
|
const resultRunCard = asRecord2(result.run_card);
|
|
@@ -400,15 +462,18 @@ function summarizeRiddleProofPrComment(input) {
|
|
|
400
462
|
const resultRaw = asRecord2(result.raw);
|
|
401
463
|
const rawDetails = asRecord2(resultRaw.details);
|
|
402
464
|
const profileChecks = profileResult ? profileCheckCounts(result) : void 0;
|
|
465
|
+
const changeChecks = changeResult ? changeReceiptCheckCounts(result) : void 0;
|
|
403
466
|
const artifacts = mergeArtifacts(
|
|
404
467
|
collectArtifacts(runResponse),
|
|
405
|
-
profileResult ? collectProfileArtifacts(result) : []
|
|
468
|
+
profileResult ? collectProfileArtifacts(result) : [],
|
|
469
|
+
changeReceiptResult ? collectChangeReceiptArtifacts(result) : []
|
|
406
470
|
);
|
|
407
|
-
const pages = profileResult ? profilePageSummaries(result, profileChecks) : pageSummaries(result);
|
|
471
|
+
const pages = changeReceiptResult ? changeReceiptPageSummaries(result) : profileResult ? profilePageSummaries(result, profileChecks) : pageSummaries(result);
|
|
408
472
|
const checkSource = { ...result };
|
|
409
473
|
delete checkSource.ok;
|
|
410
474
|
const nestedChecks = summarizeExplicitChecks(checkSource);
|
|
411
|
-
const
|
|
475
|
+
const resultStatus = firstStringValue2(result.status, stopCondition.status);
|
|
476
|
+
const ok = changeResult ? resultStatus === "passed" : booleanValue2(result.ok) ?? booleanValue2(runResponse.ok) ?? null;
|
|
412
477
|
const checkpointSummary = checkpointSummaryFrom2(
|
|
413
478
|
result.checkpoint_summary,
|
|
414
479
|
stopCondition.checkpoint_summary,
|
|
@@ -418,7 +483,7 @@ function summarizeRiddleProofPrComment(input) {
|
|
|
418
483
|
);
|
|
419
484
|
const publicState = summarizeRiddleProofPublicState({
|
|
420
485
|
...result,
|
|
421
|
-
status:
|
|
486
|
+
status: resultStatus,
|
|
422
487
|
checkpoint_summary: checkpointSummary || result.checkpoint_summary
|
|
423
488
|
});
|
|
424
489
|
const mergeRecommendation = riddleProofPublicStateMergeRecommendation(
|
|
@@ -428,7 +493,7 @@ function summarizeRiddleProofPrComment(input) {
|
|
|
428
493
|
return {
|
|
429
494
|
ok,
|
|
430
495
|
status: firstStringValue2(proofResult.status, profileRiddle.status),
|
|
431
|
-
result_status: publicState.status,
|
|
496
|
+
result_status: changeResult ? resultStatus : publicState.status,
|
|
432
497
|
job_id: firstStringValue2(proofResult.job_id, profileRiddle.job_id),
|
|
433
498
|
duration_ms: numberValue2(proofResult.duration_ms) ?? numberValue2(profileRiddle.elapsed_ms),
|
|
434
499
|
proof_url: stringValue2(runResponse.proofUrl),
|
|
@@ -442,11 +507,11 @@ function summarizeRiddleProofPrComment(input) {
|
|
|
442
507
|
merge_ready: publicState.merge_ready,
|
|
443
508
|
sync_allowed: publicState.sync_allowed,
|
|
444
509
|
proof_decision: firstStringValue2(result.proof_decision, stopCondition.proof_decision, resultRaw.proof_decision),
|
|
445
|
-
merge_recommendation: mergeRecommendation,
|
|
510
|
+
merge_recommendation: changeReceiptResult && resultStatus ? stringValue2(result.verdict) : mergeRecommendation,
|
|
446
511
|
checkpoint_summary: checkpointSummary,
|
|
447
512
|
public_state: publicState,
|
|
448
|
-
passed_checks: profileChecks?.passed ?? nestedChecks.passed,
|
|
449
|
-
failed_checks: profileChecks?.failed ?? nestedChecks.failed,
|
|
513
|
+
passed_checks: changeChecks?.passed ?? profileChecks?.passed ?? nestedChecks.passed,
|
|
514
|
+
failed_checks: changeChecks?.failed ?? profileChecks?.failed ?? nestedChecks.failed,
|
|
450
515
|
pages,
|
|
451
516
|
artifacts,
|
|
452
517
|
primary_image: selectPrimaryImage(artifacts)
|
package/dist/pr-comment.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "riddle-proof.change-contract.v1",
|
|
3
|
+
"name": "Hosted preview marker appears after change",
|
|
4
|
+
"deltas": [
|
|
5
|
+
{
|
|
6
|
+
"type": "check_status_transition",
|
|
7
|
+
"label": "hosted preview marker becomes visible",
|
|
8
|
+
"check_label": "hosted-preview-marker-visible",
|
|
9
|
+
"before_status": "failed",
|
|
10
|
+
"after_status": "passed"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"metadata": {
|
|
14
|
+
"example": "hosted preview before/after proof"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "riddle-proof.profile.v1",
|
|
3
|
+
"name": "hosted-change-proof-preview",
|
|
4
|
+
"target": {
|
|
5
|
+
"route": "/pass.html",
|
|
6
|
+
"viewports": [
|
|
7
|
+
{ "name": "phone", "width": 390, "height": 844 },
|
|
8
|
+
{ "name": "desktop", "width": 1440, "height": 1000 }
|
|
9
|
+
],
|
|
10
|
+
"auth": "none",
|
|
11
|
+
"wait_for_selector": "[data-rp-fixture=\"pass\"]",
|
|
12
|
+
"setup_actions": [
|
|
13
|
+
{ "type": "screenshot", "label": "initial-fixture-state", "full_page": false },
|
|
14
|
+
{ "type": "wait", "ms": 100 }
|
|
15
|
+
],
|
|
16
|
+
"screenshot_full_page": false
|
|
17
|
+
},
|
|
18
|
+
"checks": [
|
|
19
|
+
{ "type": "route_loaded", "expected_path": "/pass.html" },
|
|
20
|
+
{ "type": "selector_visible", "selector": "[data-rp-fixture=\"pass\"]" },
|
|
21
|
+
{
|
|
22
|
+
"type": "selector_text_visible",
|
|
23
|
+
"label": "hosted-preview-marker-visible",
|
|
24
|
+
"selector": "[data-rp-change-proof=\"hosted-preview\"]",
|
|
25
|
+
"text": "hosted preview change proof"
|
|
26
|
+
},
|
|
27
|
+
{ "type": "no_mobile_horizontal_overflow" },
|
|
28
|
+
{ "type": "no_fatal_console_errors" }
|
|
29
|
+
],
|
|
30
|
+
"artifacts": ["screenshot", "console", "dom_summary", "proof_json"],
|
|
31
|
+
"failure_policy": {
|
|
32
|
+
"environment_blocked": "neutral",
|
|
33
|
+
"proof_insufficient": "fail",
|
|
34
|
+
"product_regression": "fail"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/package.json
CHANGED
package/dist/chunk-6S7DZWVC.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
// src/change-proof.ts
|
|
2
|
-
var RIDDLE_PROOF_CHANGE_CONTRACT_VERSION = "riddle-proof.change-contract.v1";
|
|
3
|
-
var RIDDLE_PROOF_CHANGE_RESULT_VERSION = "riddle-proof.change-result.v1";
|
|
4
|
-
var DEFAULT_BEFORE_STATUSES = ["passed", "product_regression"];
|
|
5
|
-
var DEFAULT_AFTER_STATUSES = ["passed"];
|
|
6
|
-
var DEFAULT_PROFILE_STATUS_TRANSITION_BEFORE = ["product_regression"];
|
|
7
|
-
var DEFAULT_PROFILE_STATUS_TRANSITION_AFTER = ["passed"];
|
|
8
|
-
var DEFAULT_CHECK_STATUS_TRANSITION_BEFORE = ["failed"];
|
|
9
|
-
var DEFAULT_CHECK_STATUS_TRANSITION_AFTER = ["passed"];
|
|
10
|
-
function listValue(value, fallback) {
|
|
11
|
-
if (Array.isArray(value)) return value;
|
|
12
|
-
if (value === void 0) return fallback;
|
|
13
|
-
return [value];
|
|
14
|
-
}
|
|
15
|
-
function includesValue(allowed, observed) {
|
|
16
|
-
return observed !== void 0 && allowed.includes(observed);
|
|
17
|
-
}
|
|
18
|
-
function groupResult(side, contract, result) {
|
|
19
|
-
const fallback = side === "before" ? DEFAULT_BEFORE_STATUSES : DEFAULT_AFTER_STATUSES;
|
|
20
|
-
const requiredStatus = listValue(contract?.required_status, fallback);
|
|
21
|
-
const label = contract?.label || side;
|
|
22
|
-
if (!result) {
|
|
23
|
-
return {
|
|
24
|
-
side,
|
|
25
|
-
label,
|
|
26
|
-
ok: false,
|
|
27
|
-
status: "missing",
|
|
28
|
-
required_status: requiredStatus,
|
|
29
|
-
message: `${label} profile result is missing.`
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
const ok = includesValue(requiredStatus, result.status);
|
|
33
|
-
return {
|
|
34
|
-
side,
|
|
35
|
-
label,
|
|
36
|
-
ok,
|
|
37
|
-
profile_name: result.profile_name,
|
|
38
|
-
status: result.status,
|
|
39
|
-
required_status: requiredStatus,
|
|
40
|
-
summary: result.summary,
|
|
41
|
-
message: ok ? void 0 : `${label} profile status ${result.status} did not match required status ${requiredStatus.join(", ")}.`
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function findCheck(result, delta) {
|
|
45
|
-
return result.checks.find((check) => {
|
|
46
|
-
if (delta.check_label && check.label !== delta.check_label) return false;
|
|
47
|
-
if (delta.check_type && check.type !== delta.check_type) return false;
|
|
48
|
-
return Boolean(delta.check_label || delta.check_type);
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
function profileStatusTransitionResult(delta, before, after) {
|
|
52
|
-
const label = delta.label || "profile-status-transition";
|
|
53
|
-
if (!before || !after) {
|
|
54
|
-
return {
|
|
55
|
-
type: delta.type,
|
|
56
|
-
label,
|
|
57
|
-
status: "proof_insufficient",
|
|
58
|
-
before_observed: before?.status,
|
|
59
|
-
after_observed: after?.status,
|
|
60
|
-
message: `${label} needs both before and after profile results.`
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
const beforeAllowed = listValue(delta.before_status, DEFAULT_PROFILE_STATUS_TRANSITION_BEFORE);
|
|
64
|
-
const afterAllowed = listValue(delta.after_status, DEFAULT_PROFILE_STATUS_TRANSITION_AFTER);
|
|
65
|
-
const passed = includesValue(beforeAllowed, before.status) && includesValue(afterAllowed, after.status);
|
|
66
|
-
return {
|
|
67
|
-
type: delta.type,
|
|
68
|
-
label,
|
|
69
|
-
status: passed ? "passed" : "failed",
|
|
70
|
-
before_observed: before.status,
|
|
71
|
-
after_observed: after.status,
|
|
72
|
-
message: passed ? void 0 : `${label} expected before ${beforeAllowed.join(", ")} and after ${afterAllowed.join(", ")}, got ${before.status} -> ${after.status}.`
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function checkStatusTransitionResult(delta, before, after) {
|
|
76
|
-
const label = delta.label || delta.check_label || delta.check_type || "check-status-transition";
|
|
77
|
-
if (!delta.check_label && !delta.check_type) {
|
|
78
|
-
return {
|
|
79
|
-
type: delta.type,
|
|
80
|
-
label,
|
|
81
|
-
status: "configuration_error",
|
|
82
|
-
message: `${label} needs check_label or check_type.`
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
if (!before || !after) {
|
|
86
|
-
return {
|
|
87
|
-
type: delta.type,
|
|
88
|
-
label,
|
|
89
|
-
status: "proof_insufficient",
|
|
90
|
-
before_observed: before?.status,
|
|
91
|
-
after_observed: after?.status,
|
|
92
|
-
message: `${label} needs both before and after profile results.`
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
const beforeCheck = findCheck(before, delta);
|
|
96
|
-
const afterCheck = findCheck(after, delta);
|
|
97
|
-
if (!beforeCheck || !afterCheck) {
|
|
98
|
-
return {
|
|
99
|
-
type: delta.type,
|
|
100
|
-
label,
|
|
101
|
-
status: "proof_insufficient",
|
|
102
|
-
before_observed: beforeCheck?.status,
|
|
103
|
-
after_observed: afterCheck?.status,
|
|
104
|
-
message: `${label} was not present in ${!beforeCheck && !afterCheck ? "before or after" : !beforeCheck ? "before" : "after"} profile checks.`
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
const beforeAllowed = listValue(delta.before_status, DEFAULT_CHECK_STATUS_TRANSITION_BEFORE);
|
|
108
|
-
const afterAllowed = listValue(delta.after_status, DEFAULT_CHECK_STATUS_TRANSITION_AFTER);
|
|
109
|
-
const passed = includesValue(beforeAllowed, beforeCheck.status) && includesValue(afterAllowed, afterCheck.status);
|
|
110
|
-
return {
|
|
111
|
-
type: delta.type,
|
|
112
|
-
label,
|
|
113
|
-
status: passed ? "passed" : "failed",
|
|
114
|
-
before_observed: beforeCheck.status,
|
|
115
|
-
after_observed: afterCheck.status,
|
|
116
|
-
message: passed ? void 0 : `${label} expected before ${beforeAllowed.join(", ")} and after ${afterAllowed.join(", ")}, got ${beforeCheck.status} -> ${afterCheck.status}.`
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
function assessDelta(delta, before, after) {
|
|
120
|
-
if (delta.type === "profile_status_transition") {
|
|
121
|
-
return profileStatusTransitionResult(delta, before, after);
|
|
122
|
-
}
|
|
123
|
-
return checkStatusTransitionResult(delta, before, after);
|
|
124
|
-
}
|
|
125
|
-
function collapsedChangeStatus(groups, deltas) {
|
|
126
|
-
const groupResults = [groups.before, groups.after];
|
|
127
|
-
if (groupResults.some((group) => group.status === "environment_blocked")) return "environment_blocked";
|
|
128
|
-
if (groupResults.some((group) => group.status === "configuration_error")) return "configuration_error";
|
|
129
|
-
if (deltas.some((delta) => delta.status === "configuration_error")) return "configuration_error";
|
|
130
|
-
if (groupResults.some((group) => group.status === "needs_human_review")) return "needs_human_review";
|
|
131
|
-
if (groupResults.some((group) => group.status === "missing" || group.status === "proof_insufficient")) return "proof_insufficient";
|
|
132
|
-
if (!deltas.length || deltas.some((delta) => delta.status === "proof_insufficient")) return "proof_insufficient";
|
|
133
|
-
if (groupResults.some((group) => !group.ok)) return "product_regression";
|
|
134
|
-
if (deltas.some((delta) => delta.status === "failed")) return "product_regression";
|
|
135
|
-
return "passed";
|
|
136
|
-
}
|
|
137
|
-
function changeSummary(name, status, deltas) {
|
|
138
|
-
if (status === "passed") return `${name} passed ${deltas.length} change delta(s).`;
|
|
139
|
-
if (status === "environment_blocked") return `${name} could not compare reliable evidence because an environment was blocked.`;
|
|
140
|
-
if (status === "configuration_error") return `${name} has an invalid change proof contract.`;
|
|
141
|
-
if (status === "needs_human_review") return `${name} needs human review before the change proof can pass.`;
|
|
142
|
-
if (status === "proof_insufficient") return `${name} did not produce enough before/after evidence for a change proof.`;
|
|
143
|
-
return `${name} failed ${deltas.filter((delta) => delta.status === "failed").length} change delta(s).`;
|
|
144
|
-
}
|
|
145
|
-
function assessRiddleProofChange(contract, input) {
|
|
146
|
-
const groups = {
|
|
147
|
-
before: groupResult("before", contract.before, input.before_result),
|
|
148
|
-
after: groupResult("after", contract.after, input.after_result)
|
|
149
|
-
};
|
|
150
|
-
const deltas = (contract.deltas || []).map((delta) => assessDelta(delta, input.before_result, input.after_result));
|
|
151
|
-
const status = collapsedChangeStatus(groups, deltas);
|
|
152
|
-
return {
|
|
153
|
-
version: RIDDLE_PROOF_CHANGE_RESULT_VERSION,
|
|
154
|
-
contract_name: contract.name,
|
|
155
|
-
status,
|
|
156
|
-
groups,
|
|
157
|
-
deltas,
|
|
158
|
-
summary: changeSummary(contract.name, status, deltas),
|
|
159
|
-
metadata: contract.metadata
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export {
|
|
164
|
-
RIDDLE_PROOF_CHANGE_CONTRACT_VERSION,
|
|
165
|
-
RIDDLE_PROOF_CHANGE_RESULT_VERSION,
|
|
166
|
-
assessRiddleProofChange
|
|
167
|
-
};
|