@riddledc/riddle-proof 0.5.31 → 0.5.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-R4BPJNAM.js → chunk-A5AWVY5A.js} +81 -6
- package/dist/{chunk-A3H7GU7H.js → chunk-CHKYSZLU.js} +39 -1
- package/dist/engine-harness.cjs +120 -9
- package/dist/engine-harness.js +2 -1
- package/dist/index.cjs +120 -9
- package/dist/index.js +2 -1
- package/dist/proof-run-core.cjs +84 -6
- package/dist/proof-run-core.d.cts +8 -1
- package/dist/proof-run-core.d.ts +8 -1
- package/dist/proof-run-core.js +7 -1
- package/dist/proof-run-engine.cjs +82 -7
- package/dist/proof-run-engine.js +5 -2
- package/package.json +1 -1
- package/runtime/lib/ship.py +55 -1
- package/runtime/lib/verify.py +38 -4
- package/runtime/tests/recon_verify_smoke.py +61 -2
package/dist/index.cjs
CHANGED
|
@@ -340,6 +340,44 @@ function normalizedProofAssessment(state = {}) {
|
|
|
340
340
|
source: source || null
|
|
341
341
|
};
|
|
342
342
|
}
|
|
343
|
+
function objectValue(value) {
|
|
344
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
345
|
+
}
|
|
346
|
+
function normalizedVerificationMode(state = {}) {
|
|
347
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
348
|
+
const bundleMode = String(bundle.verification_mode || "").trim().toLowerCase();
|
|
349
|
+
if (bundleMode) return bundleMode;
|
|
350
|
+
return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
|
|
351
|
+
}
|
|
352
|
+
function visualDeltaRequiredForState(state = {}) {
|
|
353
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
354
|
+
const contract = objectValue(bundle.artifact_contract);
|
|
355
|
+
const required = objectValue(contract.required);
|
|
356
|
+
return required.visual_delta === true || VISUAL_FIRST_MODES.has(normalizedVerificationMode(state));
|
|
357
|
+
}
|
|
358
|
+
function visualDeltaForState(state = {}) {
|
|
359
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
360
|
+
const after = objectValue(bundle.after);
|
|
361
|
+
const afterDelta = objectValue(after.visual_delta);
|
|
362
|
+
if (Object.keys(afterDelta).length) return afterDelta;
|
|
363
|
+
const request = objectValue(state?.proof_assessment_request);
|
|
364
|
+
return objectValue(request.visual_delta);
|
|
365
|
+
}
|
|
366
|
+
function visualDeltaShipGateReason(state = {}) {
|
|
367
|
+
if (!visualDeltaRequiredForState(state)) return null;
|
|
368
|
+
const visualDelta = visualDeltaForState(state);
|
|
369
|
+
if (visualDelta.status === "measured" && visualDelta.passed === true) return null;
|
|
370
|
+
const status = String(visualDelta.status || "missing");
|
|
371
|
+
if (status === "unmeasured") {
|
|
372
|
+
return "visual_delta.status=unmeasured blocks ready_to_ship for visual/UI proof";
|
|
373
|
+
}
|
|
374
|
+
if (status === "measured" && visualDelta.passed === false) {
|
|
375
|
+
return "visual_delta.status=measured but visual_delta.passed=false blocks ready_to_ship for visual/UI proof";
|
|
376
|
+
}
|
|
377
|
+
const reason = String(visualDelta.reason || "").trim();
|
|
378
|
+
if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
|
|
379
|
+
return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
|
|
380
|
+
}
|
|
343
381
|
function requiredBaselineLabelsForState(state = {}) {
|
|
344
382
|
const reference = normalizedReference(state);
|
|
345
383
|
const labels = [];
|
|
@@ -355,6 +393,10 @@ function validateShipGate(state = {}) {
|
|
|
355
393
|
const afterCdn = String(state?.after_cdn || "").trim();
|
|
356
394
|
const verifyStatus = String(state?.verify_status || "").trim();
|
|
357
395
|
const proofAssessment = normalizedProofAssessment(state);
|
|
396
|
+
const verificationMode = normalizedVerificationMode(state);
|
|
397
|
+
const visualDelta = visualDeltaForState(state);
|
|
398
|
+
const visualDeltaRequired = visualDeltaRequiredForState(state);
|
|
399
|
+
const visualDeltaBlocker = visualDeltaShipGateReason(state);
|
|
358
400
|
const reasons = [];
|
|
359
401
|
if (!["before", "prod", "both"].includes(reference)) {
|
|
360
402
|
reasons.push(`reference must be before, prod, or both; got ${reference}`);
|
|
@@ -383,19 +425,26 @@ function validateShipGate(state = {}) {
|
|
|
383
425
|
if (proofAssessment.decision !== "ready_to_ship") {
|
|
384
426
|
reasons.push("proof_assessment.decision must be ready_to_ship before ship");
|
|
385
427
|
}
|
|
428
|
+
if (visualDeltaBlocker) {
|
|
429
|
+
reasons.push(visualDeltaBlocker);
|
|
430
|
+
}
|
|
386
431
|
return {
|
|
387
432
|
ok: reasons.length === 0,
|
|
388
433
|
reasons,
|
|
389
434
|
required_baselines: requiredBaselines,
|
|
390
435
|
evidence: {
|
|
391
436
|
reference,
|
|
437
|
+
verification_mode: verificationMode || null,
|
|
392
438
|
prod_url: prodUrl || null,
|
|
393
439
|
before_cdn: beforeCdn || null,
|
|
394
440
|
prod_cdn: prodCdn || null,
|
|
395
441
|
after_cdn: afterCdn || null,
|
|
396
442
|
verify_status: verifyStatus || null,
|
|
397
443
|
proof_assessment_decision: proofAssessment.decision,
|
|
398
|
-
proof_assessment_source: proofAssessment.source
|
|
444
|
+
proof_assessment_source: proofAssessment.source,
|
|
445
|
+
visual_delta_required: visualDeltaRequired,
|
|
446
|
+
visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
|
|
447
|
+
visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
|
|
399
448
|
}
|
|
400
449
|
};
|
|
401
450
|
}
|
|
@@ -541,23 +590,36 @@ function mergeStateFromParams(statePath, params) {
|
|
|
541
590
|
state.proof_assessment_source = null;
|
|
542
591
|
} else {
|
|
543
592
|
const parsed = JSON.parse(raw);
|
|
544
|
-
|
|
593
|
+
const assessment = {
|
|
545
594
|
...parsed,
|
|
546
595
|
source: (parsed?.source || "supervising_agent").toString()
|
|
547
596
|
};
|
|
597
|
+
const readyBlocker = assessment?.decision === "ready_to_ship" ? visualDeltaShipGateReason({ ...state, proof_assessment: assessment, proof_assessment_source: assessment.source }) : null;
|
|
598
|
+
if (readyBlocker) {
|
|
599
|
+
assessment.blocked_decision = assessment.decision;
|
|
600
|
+
assessment.decision = "needs_richer_proof";
|
|
601
|
+
if (assessment.recommended_stage === "ship") assessment.recommended_stage = "verify";
|
|
602
|
+
if (assessment.continue_with_stage === "ship") assessment.continue_with_stage = "verify";
|
|
603
|
+
const blockers = Array.isArray(assessment.blockers) ? assessment.blockers : [];
|
|
604
|
+
assessment.blockers = [...blockers, readyBlocker];
|
|
605
|
+
}
|
|
606
|
+
state.proof_assessment = assessment;
|
|
548
607
|
state.proof_assessment_source = state.proof_assessment.source;
|
|
549
|
-
if (typeof
|
|
550
|
-
state.proof_decision =
|
|
608
|
+
if (typeof state.proof_assessment?.decision === "string") {
|
|
609
|
+
state.proof_decision = state.proof_assessment.decision;
|
|
551
610
|
}
|
|
552
611
|
if (typeof parsed?.summary === "string") {
|
|
553
612
|
state.proof_assessment_summary = normalizeOptionalString(parsed.summary) || null;
|
|
554
613
|
}
|
|
555
|
-
if (
|
|
614
|
+
if (state.proof_assessment?.decision === "ready_to_ship") {
|
|
556
615
|
state.merge_recommendation = "ready-to-ship";
|
|
557
|
-
} else if (typeof
|
|
616
|
+
} else if (typeof state.proof_assessment?.decision === "string" && state.proof_assessment.decision.trim()) {
|
|
558
617
|
state.merge_recommendation = "do-not-merge";
|
|
559
618
|
}
|
|
560
619
|
appendProofSummaryLine(state, `Supervising proof assessment: ${state.proof_assessment.decision || "unknown"}`);
|
|
620
|
+
if (readyBlocker) {
|
|
621
|
+
appendProofSummaryLine(state, `Ready-to-ship assessment blocked: ${readyBlocker}`);
|
|
622
|
+
}
|
|
561
623
|
if (state.proof_assessment_summary) {
|
|
562
624
|
appendProofSummaryLine(state, `Assessment summary: ${state.proof_assessment_summary}`);
|
|
563
625
|
}
|
|
@@ -679,7 +741,7 @@ function summarizeState(state) {
|
|
|
679
741
|
state: selected
|
|
680
742
|
};
|
|
681
743
|
}
|
|
682
|
-
var import_node_fs, import_node_crypto, import_node_path, import_node_url, import_meta, WORKFLOW_STAGE_ORDER, CHECKPOINT_CONTRACT_VERSION, BUNDLED_RIDDLE_PROOF_DIR, RIDDLE_PROOF_DIR_CANDIDATES, CHECKPOINT_CONTRACT_SPECS;
|
|
744
|
+
var import_node_fs, import_node_crypto, import_node_path, import_node_url, import_meta, WORKFLOW_STAGE_ORDER, CHECKPOINT_CONTRACT_VERSION, BUNDLED_RIDDLE_PROOF_DIR, RIDDLE_PROOF_DIR_CANDIDATES, VISUAL_FIRST_MODES, CHECKPOINT_CONTRACT_SPECS;
|
|
683
745
|
var init_proof_run_core = __esm({
|
|
684
746
|
"src/proof-run-core.ts"() {
|
|
685
747
|
"use strict";
|
|
@@ -698,6 +760,16 @@ var init_proof_run_core = __esm({
|
|
|
698
760
|
RIDDLE_PROOF_DIR_CANDIDATES = [
|
|
699
761
|
BUNDLED_RIDDLE_PROOF_DIR
|
|
700
762
|
];
|
|
763
|
+
VISUAL_FIRST_MODES = /* @__PURE__ */ new Set([
|
|
764
|
+
"visual",
|
|
765
|
+
"render",
|
|
766
|
+
"interaction",
|
|
767
|
+
"ui",
|
|
768
|
+
"layout",
|
|
769
|
+
"screenshot",
|
|
770
|
+
"canvas",
|
|
771
|
+
"animation"
|
|
772
|
+
]);
|
|
701
773
|
CHECKPOINT_CONTRACT_SPECS = {
|
|
702
774
|
setup_review: {
|
|
703
775
|
purpose: "Inspect prepared workspace state before moving into recon."
|
|
@@ -1624,6 +1696,9 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1624
1696
|
if (reasons.some((reason) => reason.includes("proof_assessment"))) {
|
|
1625
1697
|
return "resume with riddle_proof_review using decision=ready_to_ship only after the screenshots and semantic evidence visibly prove the request; otherwise choose needs_implementation or needs_richer_proof";
|
|
1626
1698
|
}
|
|
1699
|
+
if (reasons.some((reason) => reason.includes("visual_delta"))) {
|
|
1700
|
+
return "rerun verify with a measured before/after visual delta, or choose needs_richer_proof instead of ready_to_ship for this visual proof";
|
|
1701
|
+
}
|
|
1627
1702
|
if (reasons.some((reason) => reason.includes("after_cdn") || reason.includes("verify_status"))) {
|
|
1628
1703
|
return "rerun verify with stronger proof framing so after evidence is captured before shipping";
|
|
1629
1704
|
}
|
|
@@ -1716,7 +1791,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1716
1791
|
}
|
|
1717
1792
|
state = readState(config.statePath);
|
|
1718
1793
|
const continuedStage = params.continue_from_checkpoint ? checkpointContinueStage(state) : null;
|
|
1719
|
-
if (params.continue_from_checkpoint && !continuedStage) {
|
|
1794
|
+
if (params.continue_from_checkpoint && !params.advance_stage && !continuedStage) {
|
|
1720
1795
|
const recommended = recommendedAdvanceStage(state);
|
|
1721
1796
|
return checkpoint(
|
|
1722
1797
|
state?.active_checkpoint_stage || recommended || "recon",
|
|
@@ -3584,6 +3659,7 @@ var import_node_child_process2 = require("child_process");
|
|
|
3584
3659
|
var import_node_fs3 = require("fs");
|
|
3585
3660
|
var import_node_path3 = __toESM(require("path"), 1);
|
|
3586
3661
|
var import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
3662
|
+
init_proof_run_core();
|
|
3587
3663
|
var DEFAULT_MAX_ITERATIONS = 12;
|
|
3588
3664
|
var DEFAULT_STAGE_ITERATION_LIMITS = {
|
|
3589
3665
|
setup: 2,
|
|
@@ -3848,6 +3924,26 @@ function proofAssessmentContinuation(result, payload) {
|
|
|
3848
3924
|
const proof_assessment_json = jsonParam(payload);
|
|
3849
3925
|
return { ...baseContinuation(result), proof_assessment_json };
|
|
3850
3926
|
}
|
|
3927
|
+
function proofAssessmentVisualBlocker(state, payload) {
|
|
3928
|
+
if (!proofAssessmentRequestsShip(payload)) return null;
|
|
3929
|
+
const source = nonEmptyString(payload.source) || "supervising_agent";
|
|
3930
|
+
return visualDeltaShipGateReason({
|
|
3931
|
+
...state || {},
|
|
3932
|
+
proof_assessment: { ...payload, source },
|
|
3933
|
+
proof_assessment_source: source
|
|
3934
|
+
});
|
|
3935
|
+
}
|
|
3936
|
+
function blockedProofAssessmentPayload(payload, blocker) {
|
|
3937
|
+
const blockers = Array.isArray(payload.blockers) ? payload.blockers.filter((item) => typeof item === "string") : [];
|
|
3938
|
+
return {
|
|
3939
|
+
...payload,
|
|
3940
|
+
blocked_decision: payload.decision || "ready_to_ship",
|
|
3941
|
+
decision: "needs_richer_proof",
|
|
3942
|
+
recommended_stage: payload.recommended_stage === "ship" ? "verify" : payload.recommended_stage || "verify",
|
|
3943
|
+
continue_with_stage: payload.continue_with_stage === "ship" ? "verify" : payload.continue_with_stage || "verify",
|
|
3944
|
+
blockers: [...blockers, blocker]
|
|
3945
|
+
};
|
|
3946
|
+
}
|
|
3851
3947
|
function contextFor(request, state, result) {
|
|
3852
3948
|
return {
|
|
3853
3949
|
request,
|
|
@@ -4081,7 +4177,8 @@ async function handleImplementation(request, state, result, agent) {
|
|
|
4081
4177
|
});
|
|
4082
4178
|
return {
|
|
4083
4179
|
next: compactRecord({
|
|
4084
|
-
|
|
4180
|
+
action: "run",
|
|
4181
|
+
state_path: String(result.state_path || ""),
|
|
4085
4182
|
advance_stage: "implement",
|
|
4086
4183
|
implementation_notes: implementation.implementationNotes || implementation.summary
|
|
4087
4184
|
})
|
|
@@ -4216,6 +4313,20 @@ async function routeCheckpoint(request, state, result, agent, input) {
|
|
|
4216
4313
|
summary: assessment.summary,
|
|
4217
4314
|
details: { payload }
|
|
4218
4315
|
});
|
|
4316
|
+
const visualBlocker = proofAssessmentVisualBlocker({
|
|
4317
|
+
...context.fullRiddleState || {},
|
|
4318
|
+
verification_mode: context.fullRiddleState?.verification_mode || request.verification_mode
|
|
4319
|
+
}, payload);
|
|
4320
|
+
if (visualBlocker) {
|
|
4321
|
+
recordEvent(state, {
|
|
4322
|
+
kind: "agent.proof_assessment.blocked",
|
|
4323
|
+
checkpoint,
|
|
4324
|
+
stage: "verify",
|
|
4325
|
+
summary: visualBlocker,
|
|
4326
|
+
details: { payload }
|
|
4327
|
+
});
|
|
4328
|
+
return { next: proofAssessmentContinuation(result, blockedProofAssessmentPayload(payload, visualBlocker)) };
|
|
4329
|
+
}
|
|
4219
4330
|
if (effectiveShipMode(request, input.config) !== "ship" && proofAssessmentRequestsShip(payload)) {
|
|
4220
4331
|
return {
|
|
4221
4332
|
terminal: terminalResult(
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
createDisabledRiddleProofAgentAdapter,
|
|
14
14
|
readRiddleProofRunStatus,
|
|
15
15
|
runRiddleProofEngineHarness
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CHKYSZLU.js";
|
|
17
|
+
import "./chunk-A5AWVY5A.js";
|
|
17
18
|
import {
|
|
18
19
|
runRiddleProof
|
|
19
20
|
} from "./chunk-F6VFKS7K.js";
|
package/dist/proof-run-core.cjs
CHANGED
|
@@ -50,6 +50,9 @@ __export(proof_run_core_exports, {
|
|
|
50
50
|
setStageDecisionRequest: () => setStageDecisionRequest,
|
|
51
51
|
summarizeState: () => summarizeState,
|
|
52
52
|
validateShipGate: () => validateShipGate,
|
|
53
|
+
visualDeltaForState: () => visualDeltaForState,
|
|
54
|
+
visualDeltaRequiredForState: () => visualDeltaRequiredForState,
|
|
55
|
+
visualDeltaShipGateReason: () => visualDeltaShipGateReason,
|
|
53
56
|
workflowFile: () => workflowFile,
|
|
54
57
|
writeState: () => writeState
|
|
55
58
|
});
|
|
@@ -378,6 +381,54 @@ function normalizedProofAssessment(state = {}) {
|
|
|
378
381
|
source: source || null
|
|
379
382
|
};
|
|
380
383
|
}
|
|
384
|
+
var VISUAL_FIRST_MODES = /* @__PURE__ */ new Set([
|
|
385
|
+
"visual",
|
|
386
|
+
"render",
|
|
387
|
+
"interaction",
|
|
388
|
+
"ui",
|
|
389
|
+
"layout",
|
|
390
|
+
"screenshot",
|
|
391
|
+
"canvas",
|
|
392
|
+
"animation"
|
|
393
|
+
]);
|
|
394
|
+
function objectValue(value) {
|
|
395
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
396
|
+
}
|
|
397
|
+
function normalizedVerificationMode(state = {}) {
|
|
398
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
399
|
+
const bundleMode = String(bundle.verification_mode || "").trim().toLowerCase();
|
|
400
|
+
if (bundleMode) return bundleMode;
|
|
401
|
+
return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
|
|
402
|
+
}
|
|
403
|
+
function visualDeltaRequiredForState(state = {}) {
|
|
404
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
405
|
+
const contract = objectValue(bundle.artifact_contract);
|
|
406
|
+
const required = objectValue(contract.required);
|
|
407
|
+
return required.visual_delta === true || VISUAL_FIRST_MODES.has(normalizedVerificationMode(state));
|
|
408
|
+
}
|
|
409
|
+
function visualDeltaForState(state = {}) {
|
|
410
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
411
|
+
const after = objectValue(bundle.after);
|
|
412
|
+
const afterDelta = objectValue(after.visual_delta);
|
|
413
|
+
if (Object.keys(afterDelta).length) return afterDelta;
|
|
414
|
+
const request = objectValue(state?.proof_assessment_request);
|
|
415
|
+
return objectValue(request.visual_delta);
|
|
416
|
+
}
|
|
417
|
+
function visualDeltaShipGateReason(state = {}) {
|
|
418
|
+
if (!visualDeltaRequiredForState(state)) return null;
|
|
419
|
+
const visualDelta = visualDeltaForState(state);
|
|
420
|
+
if (visualDelta.status === "measured" && visualDelta.passed === true) return null;
|
|
421
|
+
const status = String(visualDelta.status || "missing");
|
|
422
|
+
if (status === "unmeasured") {
|
|
423
|
+
return "visual_delta.status=unmeasured blocks ready_to_ship for visual/UI proof";
|
|
424
|
+
}
|
|
425
|
+
if (status === "measured" && visualDelta.passed === false) {
|
|
426
|
+
return "visual_delta.status=measured but visual_delta.passed=false blocks ready_to_ship for visual/UI proof";
|
|
427
|
+
}
|
|
428
|
+
const reason = String(visualDelta.reason || "").trim();
|
|
429
|
+
if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
|
|
430
|
+
return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
|
|
431
|
+
}
|
|
381
432
|
function requiredBaselineLabelsForState(state = {}) {
|
|
382
433
|
const reference = normalizedReference(state);
|
|
383
434
|
const labels = [];
|
|
@@ -393,6 +444,10 @@ function validateShipGate(state = {}) {
|
|
|
393
444
|
const afterCdn = String(state?.after_cdn || "").trim();
|
|
394
445
|
const verifyStatus = String(state?.verify_status || "").trim();
|
|
395
446
|
const proofAssessment = normalizedProofAssessment(state);
|
|
447
|
+
const verificationMode = normalizedVerificationMode(state);
|
|
448
|
+
const visualDelta = visualDeltaForState(state);
|
|
449
|
+
const visualDeltaRequired = visualDeltaRequiredForState(state);
|
|
450
|
+
const visualDeltaBlocker = visualDeltaShipGateReason(state);
|
|
396
451
|
const reasons = [];
|
|
397
452
|
if (!["before", "prod", "both"].includes(reference)) {
|
|
398
453
|
reasons.push(`reference must be before, prod, or both; got ${reference}`);
|
|
@@ -421,19 +476,26 @@ function validateShipGate(state = {}) {
|
|
|
421
476
|
if (proofAssessment.decision !== "ready_to_ship") {
|
|
422
477
|
reasons.push("proof_assessment.decision must be ready_to_ship before ship");
|
|
423
478
|
}
|
|
479
|
+
if (visualDeltaBlocker) {
|
|
480
|
+
reasons.push(visualDeltaBlocker);
|
|
481
|
+
}
|
|
424
482
|
return {
|
|
425
483
|
ok: reasons.length === 0,
|
|
426
484
|
reasons,
|
|
427
485
|
required_baselines: requiredBaselines,
|
|
428
486
|
evidence: {
|
|
429
487
|
reference,
|
|
488
|
+
verification_mode: verificationMode || null,
|
|
430
489
|
prod_url: prodUrl || null,
|
|
431
490
|
before_cdn: beforeCdn || null,
|
|
432
491
|
prod_cdn: prodCdn || null,
|
|
433
492
|
after_cdn: afterCdn || null,
|
|
434
493
|
verify_status: verifyStatus || null,
|
|
435
494
|
proof_assessment_decision: proofAssessment.decision,
|
|
436
|
-
proof_assessment_source: proofAssessment.source
|
|
495
|
+
proof_assessment_source: proofAssessment.source,
|
|
496
|
+
visual_delta_required: visualDeltaRequired,
|
|
497
|
+
visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
|
|
498
|
+
visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
|
|
437
499
|
}
|
|
438
500
|
};
|
|
439
501
|
}
|
|
@@ -747,23 +809,36 @@ function mergeStateFromParams(statePath, params) {
|
|
|
747
809
|
state.proof_assessment_source = null;
|
|
748
810
|
} else {
|
|
749
811
|
const parsed = JSON.parse(raw);
|
|
750
|
-
|
|
812
|
+
const assessment = {
|
|
751
813
|
...parsed,
|
|
752
814
|
source: (parsed?.source || "supervising_agent").toString()
|
|
753
815
|
};
|
|
816
|
+
const readyBlocker = assessment?.decision === "ready_to_ship" ? visualDeltaShipGateReason({ ...state, proof_assessment: assessment, proof_assessment_source: assessment.source }) : null;
|
|
817
|
+
if (readyBlocker) {
|
|
818
|
+
assessment.blocked_decision = assessment.decision;
|
|
819
|
+
assessment.decision = "needs_richer_proof";
|
|
820
|
+
if (assessment.recommended_stage === "ship") assessment.recommended_stage = "verify";
|
|
821
|
+
if (assessment.continue_with_stage === "ship") assessment.continue_with_stage = "verify";
|
|
822
|
+
const blockers = Array.isArray(assessment.blockers) ? assessment.blockers : [];
|
|
823
|
+
assessment.blockers = [...blockers, readyBlocker];
|
|
824
|
+
}
|
|
825
|
+
state.proof_assessment = assessment;
|
|
754
826
|
state.proof_assessment_source = state.proof_assessment.source;
|
|
755
|
-
if (typeof
|
|
756
|
-
state.proof_decision =
|
|
827
|
+
if (typeof state.proof_assessment?.decision === "string") {
|
|
828
|
+
state.proof_decision = state.proof_assessment.decision;
|
|
757
829
|
}
|
|
758
830
|
if (typeof parsed?.summary === "string") {
|
|
759
831
|
state.proof_assessment_summary = normalizeOptionalString(parsed.summary) || null;
|
|
760
832
|
}
|
|
761
|
-
if (
|
|
833
|
+
if (state.proof_assessment?.decision === "ready_to_ship") {
|
|
762
834
|
state.merge_recommendation = "ready-to-ship";
|
|
763
|
-
} else if (typeof
|
|
835
|
+
} else if (typeof state.proof_assessment?.decision === "string" && state.proof_assessment.decision.trim()) {
|
|
764
836
|
state.merge_recommendation = "do-not-merge";
|
|
765
837
|
}
|
|
766
838
|
appendProofSummaryLine(state, `Supervising proof assessment: ${state.proof_assessment.decision || "unknown"}`);
|
|
839
|
+
if (readyBlocker) {
|
|
840
|
+
appendProofSummaryLine(state, `Ready-to-ship assessment blocked: ${readyBlocker}`);
|
|
841
|
+
}
|
|
767
842
|
if (state.proof_assessment_summary) {
|
|
768
843
|
appendProofSummaryLine(state, `Assessment summary: ${state.proof_assessment_summary}`);
|
|
769
844
|
}
|
|
@@ -907,6 +982,9 @@ function summarizeState(state) {
|
|
|
907
982
|
setStageDecisionRequest,
|
|
908
983
|
summarizeState,
|
|
909
984
|
validateShipGate,
|
|
985
|
+
visualDeltaForState,
|
|
986
|
+
visualDeltaRequiredForState,
|
|
987
|
+
visualDeltaShipGateReason,
|
|
910
988
|
workflowFile,
|
|
911
989
|
writeState
|
|
912
990
|
});
|
|
@@ -70,6 +70,7 @@ interface ShipGateValidation {
|
|
|
70
70
|
required_baselines: string[];
|
|
71
71
|
evidence: {
|
|
72
72
|
reference: string;
|
|
73
|
+
verification_mode: string | null;
|
|
73
74
|
prod_url: string | null;
|
|
74
75
|
before_cdn: string | null;
|
|
75
76
|
prod_cdn: string | null;
|
|
@@ -77,6 +78,9 @@ interface ShipGateValidation {
|
|
|
77
78
|
verify_status: string | null;
|
|
78
79
|
proof_assessment_decision: string | null;
|
|
79
80
|
proof_assessment_source: string | null;
|
|
81
|
+
visual_delta_required: boolean;
|
|
82
|
+
visual_delta_status: string | null;
|
|
83
|
+
visual_delta_passed: boolean | null;
|
|
80
84
|
};
|
|
81
85
|
}
|
|
82
86
|
declare function resolveRiddleProofDir(config?: PluginConfig): string;
|
|
@@ -192,6 +196,9 @@ declare function invalidateVerifyEvidence(state?: any): {
|
|
|
192
196
|
hadProofAssessment: boolean;
|
|
193
197
|
hadProofAssessmentRequest: boolean;
|
|
194
198
|
};
|
|
199
|
+
declare function visualDeltaRequiredForState(state?: any): boolean;
|
|
200
|
+
declare function visualDeltaForState(state?: any): Record<string, any>;
|
|
201
|
+
declare function visualDeltaShipGateReason(state?: any): string | null;
|
|
195
202
|
declare function requiredBaselineLabelsForState(state?: any): string[];
|
|
196
203
|
declare function validateShipGate(state?: any): ShipGateValidation;
|
|
197
204
|
declare function buildCheckpointContract(state: any, request: {
|
|
@@ -283,4 +290,4 @@ declare function summarizeState(state: any): {
|
|
|
283
290
|
};
|
|
284
291
|
};
|
|
285
292
|
|
|
286
|
-
export { BUNDLED_RIDDLE_PROOF_DIR, CHECKPOINT_CONTRACT_VERSION, type CheckpointInputContract, type PluginConfig, RIDDLE_PROOF_DIR_CANDIDATES, type ShipGateValidation, WORKFLOW_STAGE_ORDER, type WorkflowAction, type WorkflowParams, type WorkflowStage, buildCheckpointContract, buildSetupArgs, checkpointContinueStage, clearStageDecisionRequest, ensureAction, ensureStageLoopState, invalidateVerifyEvidence, mergeStateFromParams, readState, recordStageAttempt, requiredBaselineLabelsForState, resolveConfig, resolveRiddleProofDir, setStageDecisionRequest, summarizeState, validateShipGate, workflowFile, writeState };
|
|
293
|
+
export { BUNDLED_RIDDLE_PROOF_DIR, CHECKPOINT_CONTRACT_VERSION, type CheckpointInputContract, type PluginConfig, RIDDLE_PROOF_DIR_CANDIDATES, type ShipGateValidation, WORKFLOW_STAGE_ORDER, type WorkflowAction, type WorkflowParams, type WorkflowStage, buildCheckpointContract, buildSetupArgs, checkpointContinueStage, clearStageDecisionRequest, ensureAction, ensureStageLoopState, invalidateVerifyEvidence, mergeStateFromParams, readState, recordStageAttempt, requiredBaselineLabelsForState, resolveConfig, resolveRiddleProofDir, setStageDecisionRequest, summarizeState, validateShipGate, visualDeltaForState, visualDeltaRequiredForState, visualDeltaShipGateReason, workflowFile, writeState };
|
package/dist/proof-run-core.d.ts
CHANGED
|
@@ -70,6 +70,7 @@ interface ShipGateValidation {
|
|
|
70
70
|
required_baselines: string[];
|
|
71
71
|
evidence: {
|
|
72
72
|
reference: string;
|
|
73
|
+
verification_mode: string | null;
|
|
73
74
|
prod_url: string | null;
|
|
74
75
|
before_cdn: string | null;
|
|
75
76
|
prod_cdn: string | null;
|
|
@@ -77,6 +78,9 @@ interface ShipGateValidation {
|
|
|
77
78
|
verify_status: string | null;
|
|
78
79
|
proof_assessment_decision: string | null;
|
|
79
80
|
proof_assessment_source: string | null;
|
|
81
|
+
visual_delta_required: boolean;
|
|
82
|
+
visual_delta_status: string | null;
|
|
83
|
+
visual_delta_passed: boolean | null;
|
|
80
84
|
};
|
|
81
85
|
}
|
|
82
86
|
declare function resolveRiddleProofDir(config?: PluginConfig): string;
|
|
@@ -192,6 +196,9 @@ declare function invalidateVerifyEvidence(state?: any): {
|
|
|
192
196
|
hadProofAssessment: boolean;
|
|
193
197
|
hadProofAssessmentRequest: boolean;
|
|
194
198
|
};
|
|
199
|
+
declare function visualDeltaRequiredForState(state?: any): boolean;
|
|
200
|
+
declare function visualDeltaForState(state?: any): Record<string, any>;
|
|
201
|
+
declare function visualDeltaShipGateReason(state?: any): string | null;
|
|
195
202
|
declare function requiredBaselineLabelsForState(state?: any): string[];
|
|
196
203
|
declare function validateShipGate(state?: any): ShipGateValidation;
|
|
197
204
|
declare function buildCheckpointContract(state: any, request: {
|
|
@@ -283,4 +290,4 @@ declare function summarizeState(state: any): {
|
|
|
283
290
|
};
|
|
284
291
|
};
|
|
285
292
|
|
|
286
|
-
export { BUNDLED_RIDDLE_PROOF_DIR, CHECKPOINT_CONTRACT_VERSION, type CheckpointInputContract, type PluginConfig, RIDDLE_PROOF_DIR_CANDIDATES, type ShipGateValidation, WORKFLOW_STAGE_ORDER, type WorkflowAction, type WorkflowParams, type WorkflowStage, buildCheckpointContract, buildSetupArgs, checkpointContinueStage, clearStageDecisionRequest, ensureAction, ensureStageLoopState, invalidateVerifyEvidence, mergeStateFromParams, readState, recordStageAttempt, requiredBaselineLabelsForState, resolveConfig, resolveRiddleProofDir, setStageDecisionRequest, summarizeState, validateShipGate, workflowFile, writeState };
|
|
293
|
+
export { BUNDLED_RIDDLE_PROOF_DIR, CHECKPOINT_CONTRACT_VERSION, type CheckpointInputContract, type PluginConfig, RIDDLE_PROOF_DIR_CANDIDATES, type ShipGateValidation, WORKFLOW_STAGE_ORDER, type WorkflowAction, type WorkflowParams, type WorkflowStage, buildCheckpointContract, buildSetupArgs, checkpointContinueStage, clearStageDecisionRequest, ensureAction, ensureStageLoopState, invalidateVerifyEvidence, mergeStateFromParams, readState, recordStageAttempt, requiredBaselineLabelsForState, resolveConfig, resolveRiddleProofDir, setStageDecisionRequest, summarizeState, validateShipGate, visualDeltaForState, visualDeltaRequiredForState, visualDeltaShipGateReason, workflowFile, writeState };
|
package/dist/proof-run-core.js
CHANGED
|
@@ -19,9 +19,12 @@ import {
|
|
|
19
19
|
setStageDecisionRequest,
|
|
20
20
|
summarizeState,
|
|
21
21
|
validateShipGate,
|
|
22
|
+
visualDeltaForState,
|
|
23
|
+
visualDeltaRequiredForState,
|
|
24
|
+
visualDeltaShipGateReason,
|
|
22
25
|
workflowFile,
|
|
23
26
|
writeState
|
|
24
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-A5AWVY5A.js";
|
|
25
28
|
export {
|
|
26
29
|
BUNDLED_RIDDLE_PROOF_DIR,
|
|
27
30
|
CHECKPOINT_CONTRACT_VERSION,
|
|
@@ -43,6 +46,9 @@ export {
|
|
|
43
46
|
setStageDecisionRequest,
|
|
44
47
|
summarizeState,
|
|
45
48
|
validateShipGate,
|
|
49
|
+
visualDeltaForState,
|
|
50
|
+
visualDeltaRequiredForState,
|
|
51
|
+
visualDeltaShipGateReason,
|
|
46
52
|
workflowFile,
|
|
47
53
|
writeState
|
|
48
54
|
};
|
|
@@ -363,6 +363,54 @@ function normalizedProofAssessment(state = {}) {
|
|
|
363
363
|
source: source || null
|
|
364
364
|
};
|
|
365
365
|
}
|
|
366
|
+
var VISUAL_FIRST_MODES = /* @__PURE__ */ new Set([
|
|
367
|
+
"visual",
|
|
368
|
+
"render",
|
|
369
|
+
"interaction",
|
|
370
|
+
"ui",
|
|
371
|
+
"layout",
|
|
372
|
+
"screenshot",
|
|
373
|
+
"canvas",
|
|
374
|
+
"animation"
|
|
375
|
+
]);
|
|
376
|
+
function objectValue(value) {
|
|
377
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
378
|
+
}
|
|
379
|
+
function normalizedVerificationMode(state = {}) {
|
|
380
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
381
|
+
const bundleMode = String(bundle.verification_mode || "").trim().toLowerCase();
|
|
382
|
+
if (bundleMode) return bundleMode;
|
|
383
|
+
return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
|
|
384
|
+
}
|
|
385
|
+
function visualDeltaRequiredForState(state = {}) {
|
|
386
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
387
|
+
const contract = objectValue(bundle.artifact_contract);
|
|
388
|
+
const required = objectValue(contract.required);
|
|
389
|
+
return required.visual_delta === true || VISUAL_FIRST_MODES.has(normalizedVerificationMode(state));
|
|
390
|
+
}
|
|
391
|
+
function visualDeltaForState(state = {}) {
|
|
392
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
393
|
+
const after = objectValue(bundle.after);
|
|
394
|
+
const afterDelta = objectValue(after.visual_delta);
|
|
395
|
+
if (Object.keys(afterDelta).length) return afterDelta;
|
|
396
|
+
const request = objectValue(state?.proof_assessment_request);
|
|
397
|
+
return objectValue(request.visual_delta);
|
|
398
|
+
}
|
|
399
|
+
function visualDeltaShipGateReason(state = {}) {
|
|
400
|
+
if (!visualDeltaRequiredForState(state)) return null;
|
|
401
|
+
const visualDelta = visualDeltaForState(state);
|
|
402
|
+
if (visualDelta.status === "measured" && visualDelta.passed === true) return null;
|
|
403
|
+
const status = String(visualDelta.status || "missing");
|
|
404
|
+
if (status === "unmeasured") {
|
|
405
|
+
return "visual_delta.status=unmeasured blocks ready_to_ship for visual/UI proof";
|
|
406
|
+
}
|
|
407
|
+
if (status === "measured" && visualDelta.passed === false) {
|
|
408
|
+
return "visual_delta.status=measured but visual_delta.passed=false blocks ready_to_ship for visual/UI proof";
|
|
409
|
+
}
|
|
410
|
+
const reason = String(visualDelta.reason || "").trim();
|
|
411
|
+
if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
|
|
412
|
+
return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
|
|
413
|
+
}
|
|
366
414
|
function requiredBaselineLabelsForState(state = {}) {
|
|
367
415
|
const reference = normalizedReference(state);
|
|
368
416
|
const labels = [];
|
|
@@ -378,6 +426,10 @@ function validateShipGate(state = {}) {
|
|
|
378
426
|
const afterCdn = String(state?.after_cdn || "").trim();
|
|
379
427
|
const verifyStatus = String(state?.verify_status || "").trim();
|
|
380
428
|
const proofAssessment = normalizedProofAssessment(state);
|
|
429
|
+
const verificationMode = normalizedVerificationMode(state);
|
|
430
|
+
const visualDelta = visualDeltaForState(state);
|
|
431
|
+
const visualDeltaRequired = visualDeltaRequiredForState(state);
|
|
432
|
+
const visualDeltaBlocker = visualDeltaShipGateReason(state);
|
|
381
433
|
const reasons = [];
|
|
382
434
|
if (!["before", "prod", "both"].includes(reference)) {
|
|
383
435
|
reasons.push(`reference must be before, prod, or both; got ${reference}`);
|
|
@@ -406,19 +458,26 @@ function validateShipGate(state = {}) {
|
|
|
406
458
|
if (proofAssessment.decision !== "ready_to_ship") {
|
|
407
459
|
reasons.push("proof_assessment.decision must be ready_to_ship before ship");
|
|
408
460
|
}
|
|
461
|
+
if (visualDeltaBlocker) {
|
|
462
|
+
reasons.push(visualDeltaBlocker);
|
|
463
|
+
}
|
|
409
464
|
return {
|
|
410
465
|
ok: reasons.length === 0,
|
|
411
466
|
reasons,
|
|
412
467
|
required_baselines: requiredBaselines,
|
|
413
468
|
evidence: {
|
|
414
469
|
reference,
|
|
470
|
+
verification_mode: verificationMode || null,
|
|
415
471
|
prod_url: prodUrl || null,
|
|
416
472
|
before_cdn: beforeCdn || null,
|
|
417
473
|
prod_cdn: prodCdn || null,
|
|
418
474
|
after_cdn: afterCdn || null,
|
|
419
475
|
verify_status: verifyStatus || null,
|
|
420
476
|
proof_assessment_decision: proofAssessment.decision,
|
|
421
|
-
proof_assessment_source: proofAssessment.source
|
|
477
|
+
proof_assessment_source: proofAssessment.source,
|
|
478
|
+
visual_delta_required: visualDeltaRequired,
|
|
479
|
+
visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
|
|
480
|
+
visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
|
|
422
481
|
}
|
|
423
482
|
};
|
|
424
483
|
}
|
|
@@ -732,23 +791,36 @@ function mergeStateFromParams(statePath, params) {
|
|
|
732
791
|
state.proof_assessment_source = null;
|
|
733
792
|
} else {
|
|
734
793
|
const parsed = JSON.parse(raw);
|
|
735
|
-
|
|
794
|
+
const assessment = {
|
|
736
795
|
...parsed,
|
|
737
796
|
source: (parsed?.source || "supervising_agent").toString()
|
|
738
797
|
};
|
|
798
|
+
const readyBlocker = assessment?.decision === "ready_to_ship" ? visualDeltaShipGateReason({ ...state, proof_assessment: assessment, proof_assessment_source: assessment.source }) : null;
|
|
799
|
+
if (readyBlocker) {
|
|
800
|
+
assessment.blocked_decision = assessment.decision;
|
|
801
|
+
assessment.decision = "needs_richer_proof";
|
|
802
|
+
if (assessment.recommended_stage === "ship") assessment.recommended_stage = "verify";
|
|
803
|
+
if (assessment.continue_with_stage === "ship") assessment.continue_with_stage = "verify";
|
|
804
|
+
const blockers = Array.isArray(assessment.blockers) ? assessment.blockers : [];
|
|
805
|
+
assessment.blockers = [...blockers, readyBlocker];
|
|
806
|
+
}
|
|
807
|
+
state.proof_assessment = assessment;
|
|
739
808
|
state.proof_assessment_source = state.proof_assessment.source;
|
|
740
|
-
if (typeof
|
|
741
|
-
state.proof_decision =
|
|
809
|
+
if (typeof state.proof_assessment?.decision === "string") {
|
|
810
|
+
state.proof_decision = state.proof_assessment.decision;
|
|
742
811
|
}
|
|
743
812
|
if (typeof parsed?.summary === "string") {
|
|
744
813
|
state.proof_assessment_summary = normalizeOptionalString(parsed.summary) || null;
|
|
745
814
|
}
|
|
746
|
-
if (
|
|
815
|
+
if (state.proof_assessment?.decision === "ready_to_ship") {
|
|
747
816
|
state.merge_recommendation = "ready-to-ship";
|
|
748
|
-
} else if (typeof
|
|
817
|
+
} else if (typeof state.proof_assessment?.decision === "string" && state.proof_assessment.decision.trim()) {
|
|
749
818
|
state.merge_recommendation = "do-not-merge";
|
|
750
819
|
}
|
|
751
820
|
appendProofSummaryLine(state, `Supervising proof assessment: ${state.proof_assessment.decision || "unknown"}`);
|
|
821
|
+
if (readyBlocker) {
|
|
822
|
+
appendProofSummaryLine(state, `Ready-to-ship assessment blocked: ${readyBlocker}`);
|
|
823
|
+
}
|
|
752
824
|
if (state.proof_assessment_summary) {
|
|
753
825
|
appendProofSummaryLine(state, `Assessment summary: ${state.proof_assessment_summary}`);
|
|
754
826
|
}
|
|
@@ -1622,6 +1694,9 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1622
1694
|
if (reasons.some((reason) => reason.includes("proof_assessment"))) {
|
|
1623
1695
|
return "resume with riddle_proof_review using decision=ready_to_ship only after the screenshots and semantic evidence visibly prove the request; otherwise choose needs_implementation or needs_richer_proof";
|
|
1624
1696
|
}
|
|
1697
|
+
if (reasons.some((reason) => reason.includes("visual_delta"))) {
|
|
1698
|
+
return "rerun verify with a measured before/after visual delta, or choose needs_richer_proof instead of ready_to_ship for this visual proof";
|
|
1699
|
+
}
|
|
1625
1700
|
if (reasons.some((reason) => reason.includes("after_cdn") || reason.includes("verify_status"))) {
|
|
1626
1701
|
return "rerun verify with stronger proof framing so after evidence is captured before shipping";
|
|
1627
1702
|
}
|
|
@@ -1714,7 +1789,7 @@ async function executeWorkflow(params, pluginConfig, resolvedConfig) {
|
|
|
1714
1789
|
}
|
|
1715
1790
|
state = readState(config.statePath);
|
|
1716
1791
|
const continuedStage = params.continue_from_checkpoint ? checkpointContinueStage(state) : null;
|
|
1717
|
-
if (params.continue_from_checkpoint && !continuedStage) {
|
|
1792
|
+
if (params.continue_from_checkpoint && !params.advance_stage && !continuedStage) {
|
|
1718
1793
|
const recommended = recommendedAdvanceStage(state);
|
|
1719
1794
|
return checkpoint(
|
|
1720
1795
|
state?.active_checkpoint_stage || recommended || "recon",
|