@riddledc/riddle-proof 0.8.11 → 0.8.12
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/advanced/engine-harness.cjs +97 -12
- package/dist/advanced/engine-harness.js +2 -2
- package/dist/advanced/index.cjs +98 -12
- package/dist/advanced/index.d.cts +2 -2
- package/dist/advanced/index.d.ts +2 -2
- package/dist/advanced/index.js +4 -4
- package/dist/advanced/proof-run-core.cjs +31 -1
- package/dist/advanced/proof-run-core.d.cts +1 -1
- package/dist/advanced/proof-run-core.d.ts +1 -1
- package/dist/advanced/proof-run-core.js +3 -1
- package/dist/advanced/proof-run-engine.cjs +46 -12
- package/dist/advanced/proof-run-engine.d.cts +2 -2
- package/dist/advanced/proof-run-engine.d.ts +2 -2
- package/dist/advanced/proof-run-engine.js +2 -2
- package/dist/advanced/runner.js +2 -2
- package/dist/{chunk-5N5QFI2S.js → chunk-7GZY5PLT.js} +31 -1
- package/dist/{chunk-46DDSZJR.js → chunk-JBY2SU5U.js} +18 -12
- package/dist/{chunk-5N6MQCLC.js → chunk-NGX4SUQN.js} +1 -1
- package/dist/{chunk-BBUO7HM4.js → chunk-RTLA6CPP.js} +53 -1
- package/dist/{chunk-2PXL3RDB.js → chunk-SZUC4MDN.js} +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/cli.cjs +97 -12
- package/dist/cli.js +3 -3
- package/dist/engine-harness.cjs +97 -12
- package/dist/engine-harness.js +2 -2
- package/dist/index.cjs +97 -12
- package/dist/index.js +3 -3
- package/dist/{proof-run-core-CE0jx7wL.d.cts → proof-run-core-CrpYH-qH.d.cts} +6 -3
- package/dist/{proof-run-core-CE0jx7wL.d.ts → proof-run-core-CrpYH-qH.d.ts} +6 -3
- package/dist/proof-run-core.cjs +31 -1
- package/dist/proof-run-core.d.cts +1 -1
- package/dist/proof-run-core.d.ts +1 -1
- package/dist/proof-run-core.js +3 -1
- package/dist/{proof-run-engine-B7DCPzpK.d.cts → proof-run-engine-C6vYAZd8.d.cts} +4 -4
- package/dist/{proof-run-engine-BomAcXhA.d.ts → proof-run-engine-h9C1lC0w.d.ts} +4 -4
- package/dist/proof-run-engine.cjs +46 -12
- package/dist/proof-run-engine.d.cts +2 -2
- package/dist/proof-run-engine.d.ts +2 -2
- package/dist/proof-run-engine.js +2 -2
- package/dist/runner.js +2 -2
- package/package.json +1 -1
- package/runtime/lib/verify.py +97 -11
- package/runtime/tests/recon_verify_smoke.py +154 -4
- package/runtime/tests/trust_boundary_regression.py +12 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { W as WorkflowParams, r as resolveConfig, P as PluginConfig, a as WorkflowStage } from './proof-run-core-
|
|
1
|
+
import { W as WorkflowParams, r as resolveConfig, P as PluginConfig, a as WorkflowStage } from './proof-run-core-CrpYH-qH.cjs';
|
|
2
2
|
|
|
3
3
|
declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, resolvedConfig?: ReturnType<typeof resolveConfig>): Promise<{
|
|
4
4
|
ok: boolean;
|
|
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
292
292
|
blocking?: boolean;
|
|
293
293
|
details?: Record<string, unknown>;
|
|
294
294
|
ok: boolean;
|
|
295
|
-
action: "
|
|
295
|
+
action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
|
|
296
296
|
state_path: string;
|
|
297
297
|
stage: any;
|
|
298
298
|
summary: string;
|
|
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
382
382
|
continueWithStage?: WorkflowStage | null;
|
|
383
383
|
blocking?: boolean;
|
|
384
384
|
details?: Record<string, unknown>;
|
|
385
|
-
action: "
|
|
385
|
+
action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
|
|
386
386
|
state_path: string;
|
|
387
387
|
stage: any;
|
|
388
388
|
checkpoint: string;
|
|
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
659
659
|
error?: undefined;
|
|
660
660
|
} | {
|
|
661
661
|
ok: boolean;
|
|
662
|
-
action: "
|
|
662
|
+
action: "setup" | "recon" | "author" | "implement" | "verify" | "ship";
|
|
663
663
|
state_path: string;
|
|
664
664
|
stage: any;
|
|
665
665
|
summary: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { W as WorkflowParams, r as resolveConfig, P as PluginConfig, a as WorkflowStage } from './proof-run-core-
|
|
1
|
+
import { W as WorkflowParams, r as resolveConfig, P as PluginConfig, a as WorkflowStage } from './proof-run-core-CrpYH-qH.js';
|
|
2
2
|
|
|
3
3
|
declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, resolvedConfig?: ReturnType<typeof resolveConfig>): Promise<{
|
|
4
4
|
ok: boolean;
|
|
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
292
292
|
blocking?: boolean;
|
|
293
293
|
details?: Record<string, unknown>;
|
|
294
294
|
ok: boolean;
|
|
295
|
-
action: "
|
|
295
|
+
action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
|
|
296
296
|
state_path: string;
|
|
297
297
|
stage: any;
|
|
298
298
|
summary: string;
|
|
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
382
382
|
continueWithStage?: WorkflowStage | null;
|
|
383
383
|
blocking?: boolean;
|
|
384
384
|
details?: Record<string, unknown>;
|
|
385
|
-
action: "
|
|
385
|
+
action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
|
|
386
386
|
state_path: string;
|
|
387
387
|
stage: any;
|
|
388
388
|
checkpoint: string;
|
|
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
659
659
|
error?: undefined;
|
|
660
660
|
} | {
|
|
661
661
|
ok: boolean;
|
|
662
|
-
action: "
|
|
662
|
+
action: "setup" | "recon" | "author" | "implement" | "verify" | "ship";
|
|
663
663
|
state_path: string;
|
|
664
664
|
stage: any;
|
|
665
665
|
summary: string;
|
|
@@ -505,6 +505,25 @@ function visualDeltaShipGateReason(state = {}) {
|
|
|
505
505
|
if (reason) return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof: ${reason}`;
|
|
506
506
|
return `visual_delta.status=${status} blocks ready_to_ship for visual/UI proof`;
|
|
507
507
|
}
|
|
508
|
+
function proofAssessmentHardBlockersForState(state = {}) {
|
|
509
|
+
const request = objectValue(state?.proof_assessment_request);
|
|
510
|
+
const blockers = [];
|
|
511
|
+
const add = (value) => {
|
|
512
|
+
if (typeof value !== "string") return;
|
|
513
|
+
const trimmed = value.trim();
|
|
514
|
+
if (trimmed && !blockers.includes(trimmed)) blockers.push(trimmed);
|
|
515
|
+
};
|
|
516
|
+
if (Array.isArray(request.hard_blockers)) {
|
|
517
|
+
for (const blocker of request.hard_blockers) add(blocker);
|
|
518
|
+
}
|
|
519
|
+
add(state?.structured_interaction_capture_failure_summary);
|
|
520
|
+
add(state?.structured_interaction_failure_summary);
|
|
521
|
+
const mergeRecommendation = String(state?.merge_recommendation || "").trim();
|
|
522
|
+
if (mergeRecommendation === "do-not-merge" && blockers.length) {
|
|
523
|
+
add("merge_recommendation=do-not-merge because the proof bundle contains hard blockers.");
|
|
524
|
+
}
|
|
525
|
+
return blockers;
|
|
526
|
+
}
|
|
508
527
|
function visualDeltaEvidenceIssueCode(state = {}, blocker = "") {
|
|
509
528
|
const visualDelta = visualDeltaForState(state || {});
|
|
510
529
|
const status = String(visualDelta.status || "").trim();
|
|
@@ -539,6 +558,7 @@ function validateShipGate(state = {}) {
|
|
|
539
558
|
const visualDelta = visualDeltaForState(state);
|
|
540
559
|
const visualDeltaRequired = visualDeltaRequiredForState(state);
|
|
541
560
|
const visualDeltaBlocker = visualDeltaShipGateReason(state);
|
|
561
|
+
const hardBlockers = proofAssessmentHardBlockersForState(state);
|
|
542
562
|
const reasons = [];
|
|
543
563
|
if (!["before", "prod", "both"].includes(reference)) {
|
|
544
564
|
reasons.push(`reference must be before, prod, or both; got ${reference}`);
|
|
@@ -570,6 +590,9 @@ function validateShipGate(state = {}) {
|
|
|
570
590
|
if (visualDeltaBlocker) {
|
|
571
591
|
reasons.push(visualDeltaBlocker);
|
|
572
592
|
}
|
|
593
|
+
for (const blocker of hardBlockers) {
|
|
594
|
+
reasons.push(`proof hard blocker prevents ready_to_ship: ${blocker}`);
|
|
595
|
+
}
|
|
573
596
|
return {
|
|
574
597
|
ok: reasons.length === 0,
|
|
575
598
|
reasons,
|
|
@@ -586,7 +609,8 @@ function validateShipGate(state = {}) {
|
|
|
586
609
|
proof_assessment_source: proofAssessment.source,
|
|
587
610
|
visual_delta_required: visualDeltaRequired,
|
|
588
611
|
visual_delta_status: typeof visualDelta.status === "string" ? visualDelta.status : null,
|
|
589
|
-
visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null
|
|
612
|
+
visual_delta_passed: typeof visualDelta.passed === "boolean" ? visualDelta.passed : null,
|
|
613
|
+
hard_blockers: hardBlockers
|
|
590
614
|
}
|
|
591
615
|
};
|
|
592
616
|
}
|
|
@@ -700,6 +724,10 @@ var CHECKPOINT_CONTRACT_SPECS = {
|
|
|
700
724
|
}],
|
|
701
725
|
required_state: ["verify_decision_request"]
|
|
702
726
|
},
|
|
727
|
+
verify_capture_blocked: {
|
|
728
|
+
purpose: "Verify capture produced conclusive failed browser evidence and should stop instead of retrying proof authoring.",
|
|
729
|
+
required_state: ["verify_decision_request"]
|
|
730
|
+
},
|
|
703
731
|
verify_supervisor_judgment: {
|
|
704
732
|
purpose: "Supervising agent judges whether captured evidence proves the change is ready to ship.",
|
|
705
733
|
accepted_inputs: [{
|
|
@@ -1284,14 +1312,18 @@ function verifyAssessment(state) {
|
|
|
1284
1312
|
};
|
|
1285
1313
|
}
|
|
1286
1314
|
if (state?.verify_status === "capture_incomplete") {
|
|
1315
|
+
const captureQuality = verifyDecision?.capture_quality || {};
|
|
1316
|
+
const terminalBlocker = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
|
|
1317
|
+
const recommendedStage = terminalBlocker ? null : verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author";
|
|
1318
|
+
const continueWithStage = terminalBlocker ? null : verifyDecision?.continue_with_stage || verifyDecision?.recommended_stage || "author";
|
|
1287
1319
|
return {
|
|
1288
|
-
decision:
|
|
1320
|
+
decision: captureQuality?.decision || "revise_capture",
|
|
1289
1321
|
summary: verifyDecision?.summary || "Verify needs another internal capture iteration before the evidence can be judged.",
|
|
1290
|
-
recommendedStage
|
|
1291
|
-
continueWithStage
|
|
1322
|
+
recommendedStage,
|
|
1323
|
+
continueWithStage,
|
|
1292
1324
|
escalationTarget: "agent",
|
|
1293
|
-
reasons: Array.isArray(
|
|
1294
|
-
raw:
|
|
1325
|
+
reasons: Array.isArray(captureQuality?.reasons) ? captureQuality.reasons : [],
|
|
1326
|
+
raw: captureQuality || verifyDecision,
|
|
1295
1327
|
source: "workflow_capture"
|
|
1296
1328
|
};
|
|
1297
1329
|
}
|
|
@@ -2511,7 +2543,9 @@ ${implementRes.stderr || ""}`;
|
|
|
2511
2543
|
convergenceSignals
|
|
2512
2544
|
};
|
|
2513
2545
|
if (verifyStatus !== "evidence_captured") {
|
|
2514
|
-
|
|
2546
|
+
const captureQuality = verifyDecisionRequest?.capture_quality || {};
|
|
2547
|
+
const captureTerminalBlocker = captureQuality?.terminal_blocker === true || captureQuality?.blocking === true;
|
|
2548
|
+
if (!captureTerminalBlocker && (verifyContinueWithStage || verifyRecommendedStage || "author") === "author") {
|
|
2515
2549
|
updateState(config.statePath, (currentState) => {
|
|
2516
2550
|
currentState.author_status = "needs_authoring";
|
|
2517
2551
|
currentState.proof_plan_status = "needs_authoring";
|
|
@@ -2519,7 +2553,7 @@ ${implementRes.stderr || ""}`;
|
|
|
2519
2553
|
});
|
|
2520
2554
|
state = readState(config.statePath);
|
|
2521
2555
|
}
|
|
2522
|
-
const checkpointName = "verify_capture_retry";
|
|
2556
|
+
const checkpointName = captureTerminalBlocker ? "verify_capture_blocked" : "verify_capture_retry";
|
|
2523
2557
|
const summary = stringValue(proofAssessment.summary) || "Verify ran, but the proof packet still needs internal capture-plan work before it should ship.";
|
|
2524
2558
|
recordAttempt("verify", "checkpoint", summary, {
|
|
2525
2559
|
autoApproved: verifyRes.autoApproved || false,
|
|
@@ -2532,11 +2566,11 @@ ${implementRes.stderr || ""}`;
|
|
|
2532
2566
|
summary,
|
|
2533
2567
|
{
|
|
2534
2568
|
ok: true,
|
|
2535
|
-
nextActions: ["inspect_after_capture", "continue_internal_loop_with_checkpoint", "return_to_recon_if_baseline_is_wrong"],
|
|
2569
|
+
nextActions: captureTerminalBlocker ? ["inspect_after_capture", "report_specific_browser_evidence_blocker", "start_a_new_run_after_the_product_or_script_is_fixed"] : ["inspect_after_capture", "continue_internal_loop_with_checkpoint", "return_to_recon_if_baseline_is_wrong"],
|
|
2536
2570
|
advanceOptions: verifyLoopAdvanceOptions,
|
|
2537
|
-
recommendedAdvanceStage: verifyRecommendedStage || "author",
|
|
2538
|
-
continueWithStage: verifyContinueWithStage || "author",
|
|
2539
|
-
blocking:
|
|
2571
|
+
recommendedAdvanceStage: captureTerminalBlocker ? null : verifyRecommendedStage || "author",
|
|
2572
|
+
continueWithStage: captureTerminalBlocker ? null : verifyContinueWithStage || "author",
|
|
2573
|
+
blocking: captureTerminalBlocker,
|
|
2540
2574
|
details: verifyDetails,
|
|
2541
2575
|
verifyStatus,
|
|
2542
2576
|
verifySummary,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import './proof-run-core-
|
|
2
|
-
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-
|
|
1
|
+
import './proof-run-core-CrpYH-qH.cjs';
|
|
2
|
+
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-C6vYAZd8.cjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import './proof-run-core-
|
|
2
|
-
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-
|
|
1
|
+
import './proof-run-core-CrpYH-qH.js';
|
|
2
|
+
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-h9C1lC0w.js';
|
package/dist/proof-run-engine.js
CHANGED
package/dist/runner.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runRiddleProof
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NGX4SUQN.js";
|
|
4
4
|
import "./chunk-YZUVEJ5B.js";
|
|
5
5
|
import "./chunk-FMOYUYH2.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-7GZY5PLT.js";
|
|
7
7
|
import "./chunk-4FOHZ7JG.js";
|
|
8
8
|
import "./chunk-VY4Y5U57.js";
|
|
9
9
|
import "./chunk-MLKGABMK.js";
|
package/package.json
CHANGED
package/runtime/lib/verify.py
CHANGED
|
@@ -2061,7 +2061,24 @@ EXPLICIT_TERMINAL_PATH_KEYS = (
|
|
|
2061
2061
|
'final_url', 'finalUrl',
|
|
2062
2062
|
'final_route', 'finalRoute',
|
|
2063
2063
|
)
|
|
2064
|
-
|
|
2064
|
+
FULL_LOCATION_PATH_KEYS = (
|
|
2065
|
+
'url', 'href',
|
|
2066
|
+
'hrefNormalized', 'href_normalized',
|
|
2067
|
+
'terminalUrl', 'terminal_url',
|
|
2068
|
+
'afterUrl', 'after_url',
|
|
2069
|
+
'finalUrl', 'final_url',
|
|
2070
|
+
'currentUrl', 'current_url',
|
|
2071
|
+
'pathWithSearchAndHash', 'path_with_search_and_hash',
|
|
2072
|
+
'fullPath', 'full_path',
|
|
2073
|
+
)
|
|
2074
|
+
PARTIAL_LOCATION_PATH_KEYS = (
|
|
2075
|
+
'route',
|
|
2076
|
+
'path',
|
|
2077
|
+
'pathname',
|
|
2078
|
+
'normalizedPath', 'normalized_path',
|
|
2079
|
+
'rawPath', 'raw_path',
|
|
2080
|
+
)
|
|
2081
|
+
LOCATION_PATH_KEYS = FULL_LOCATION_PATH_KEYS + PARTIAL_LOCATION_PATH_KEYS
|
|
2065
2082
|
AFTER_STATE_KEYS = (
|
|
2066
2083
|
'after', 'after_state', 'afterState',
|
|
2067
2084
|
'expected_after', 'expectedAfter',
|
|
@@ -2383,6 +2400,25 @@ def failed_interaction_evidence_summary(proof_evidence):
|
|
|
2383
2400
|
return summary
|
|
2384
2401
|
|
|
2385
2402
|
|
|
2403
|
+
def interaction_capture_failure_evidence_summary(proof_evidence):
|
|
2404
|
+
for record in proof_evidence_records_deep(proof_evidence):
|
|
2405
|
+
if not isinstance(record, dict):
|
|
2406
|
+
continue
|
|
2407
|
+
version = str(record.get('version') or '').strip()
|
|
2408
|
+
source = str(record.get('source') or '').strip()
|
|
2409
|
+
if version != 'riddle-proof.interaction.capture-failure.v1' and source != 'verify_capture_failure':
|
|
2410
|
+
continue
|
|
2411
|
+
summary = str(record.get('evidence_summary') or '').strip() or 'Interaction capture failed before usable authored proof evidence was emitted.'
|
|
2412
|
+
failures = collect_interaction_failed_assertions(record)
|
|
2413
|
+
if failures:
|
|
2414
|
+
summary += ' Failed checks: ' + ', '.join(failures[:8]) + '.'
|
|
2415
|
+
error = str(record.get('capture_error') or record.get('error') or '').strip()
|
|
2416
|
+
if error:
|
|
2417
|
+
summary += ' Capture script error: ' + error[:300]
|
|
2418
|
+
return summary
|
|
2419
|
+
return ''
|
|
2420
|
+
|
|
2421
|
+
|
|
2386
2422
|
def interaction_terminal_path_from_evidence(proof_evidence):
|
|
2387
2423
|
for record in proof_evidence_records(proof_evidence):
|
|
2388
2424
|
candidate = terminal_path_from_record(record)
|
|
@@ -2428,6 +2464,23 @@ def interaction_terminal_path_from_state(state):
|
|
|
2428
2464
|
return '', ''
|
|
2429
2465
|
|
|
2430
2466
|
|
|
2467
|
+
def proof_evidence_should_override_state_terminal_path(state_candidate, evidence_candidate, proof_evidence):
|
|
2468
|
+
if not evidence_candidate:
|
|
2469
|
+
return False
|
|
2470
|
+
if not state_candidate:
|
|
2471
|
+
return True
|
|
2472
|
+
if route_matches_expected(state_candidate, evidence_candidate):
|
|
2473
|
+
return False
|
|
2474
|
+
if interaction_assertions_pass(proof_evidence):
|
|
2475
|
+
return True
|
|
2476
|
+
for record in proof_evidence_records_deep(proof_evidence):
|
|
2477
|
+
if interaction_assertions_pass(record):
|
|
2478
|
+
return True
|
|
2479
|
+
if explicit_route_match_flag(record) is True:
|
|
2480
|
+
return True
|
|
2481
|
+
return False
|
|
2482
|
+
|
|
2483
|
+
|
|
2431
2484
|
def expected_path_for_verify(state, start_path, proof_evidence):
|
|
2432
2485
|
mode = normalized_verification_mode(state.get('verification_mode'))
|
|
2433
2486
|
normalized_start = normalize_observed_path(start_path) or '/'
|
|
@@ -2445,9 +2498,14 @@ def expected_path_for_verify(state, start_path, proof_evidence):
|
|
|
2445
2498
|
'expected_query': start_parts['query'],
|
|
2446
2499
|
'expected_hash': start_parts['hash'],
|
|
2447
2500
|
}
|
|
2448
|
-
|
|
2501
|
+
state_candidate, state_source = interaction_terminal_path_from_state(state)
|
|
2502
|
+
evidence_candidate, evidence_source = interaction_terminal_path_from_evidence(proof_evidence)
|
|
2503
|
+
if proof_evidence_should_override_state_terminal_path(state_candidate, evidence_candidate, proof_evidence):
|
|
2504
|
+
candidate, source = evidence_candidate, evidence_source
|
|
2505
|
+
else:
|
|
2506
|
+
candidate, source = state_candidate, state_source
|
|
2449
2507
|
if not candidate:
|
|
2450
|
-
candidate, source =
|
|
2508
|
+
candidate, source = evidence_candidate, evidence_source
|
|
2451
2509
|
expected = candidate or normalized_start
|
|
2452
2510
|
expected_parts = route_parts(expected)
|
|
2453
2511
|
return expected, {
|
|
@@ -2838,10 +2896,17 @@ def build_capture_retry_decision(after_observation, required_baseline_present, p
|
|
|
2838
2896
|
|
|
2839
2897
|
if proof_evidence_blocker:
|
|
2840
2898
|
reasons.append(proof_evidence_blocker)
|
|
2841
|
-
|
|
2899
|
+
interaction_capture_blocker = (
|
|
2900
|
+
proof_evidence_blocker.startswith('Interaction capture ')
|
|
2901
|
+
or 'Interaction capture failed before usable authored proof evidence was emitted' in proof_evidence_blocker
|
|
2902
|
+
or 'Interaction capture reached a different terminal route' in proof_evidence_blocker
|
|
2903
|
+
)
|
|
2904
|
+
decision = 'failed_interaction_capture' if interaction_capture_blocker else 'missing_proof_evidence'
|
|
2842
2905
|
if 'proof_evidence_present=false' in proof_evidence_blocker:
|
|
2843
2906
|
decision = 'failed_proof_evidence'
|
|
2844
2907
|
reasons.append('The capture reached usable page context, but the proof evidence explicitly failed its own required audio gate.')
|
|
2908
|
+
elif interaction_capture_blocker:
|
|
2909
|
+
reasons.append('The capture produced conclusive structured interaction-failure evidence, so this run should block with that specific browser evidence instead of re-authoring in a loop.')
|
|
2845
2910
|
else:
|
|
2846
2911
|
reasons.append('The capture reached usable page context, but the proof script did not emit the structured evidence required for this verification mode.')
|
|
2847
2912
|
if route_mismatch:
|
|
@@ -2852,7 +2917,10 @@ def build_capture_retry_decision(after_observation, required_baseline_present, p
|
|
|
2852
2917
|
(route_mismatch.get('observed_after_path') or '(unknown)') +
|
|
2853
2918
|
'.'
|
|
2854
2919
|
)
|
|
2855
|
-
|
|
2920
|
+
if interaction_capture_blocker:
|
|
2921
|
+
reasons.append('Do not ask the authoring loop to infer a new route; the captured browser evidence is the terminal blocker.')
|
|
2922
|
+
else:
|
|
2923
|
+
reasons.append('Return to author so the capture script can expose passing proof evidence before verify asks for a supervising-agent judgment.')
|
|
2856
2924
|
summary = proof_evidence_blocker
|
|
2857
2925
|
if route_mismatch:
|
|
2858
2926
|
summary += (
|
|
@@ -2868,8 +2936,10 @@ def build_capture_retry_decision(after_observation, required_baseline_present, p
|
|
|
2868
2936
|
return {
|
|
2869
2937
|
'decision': decision,
|
|
2870
2938
|
'summary': summary,
|
|
2871
|
-
'recommended_stage': 'author',
|
|
2872
|
-
'continue_with_stage': 'author',
|
|
2939
|
+
'recommended_stage': None if interaction_capture_blocker else 'author',
|
|
2940
|
+
'continue_with_stage': None if interaction_capture_blocker else 'author',
|
|
2941
|
+
'blocking': bool(interaction_capture_blocker),
|
|
2942
|
+
'terminal_blocker': bool(interaction_capture_blocker),
|
|
2873
2943
|
'reasons': reasons,
|
|
2874
2944
|
'mismatch': route_mismatch,
|
|
2875
2945
|
}
|
|
@@ -3645,12 +3715,17 @@ if proof_evidence_required_for_mode(s.get('verification_mode')):
|
|
|
3645
3715
|
summary_lines.append('Structured proof evidence gate: ' + proof_evidence_blocker)
|
|
3646
3716
|
|
|
3647
3717
|
structured_interaction_failure_summary = ''
|
|
3718
|
+
structured_interaction_capture_failure_summary = ''
|
|
3648
3719
|
proof_evidence = evidence_bundle.get('proof_evidence')
|
|
3649
3720
|
if verification_mode in INTERACTION_MODES and proof_evidence is not None:
|
|
3650
3721
|
structured_interaction_failure_summary = failed_interaction_evidence_summary(proof_evidence)
|
|
3722
|
+
structured_interaction_capture_failure_summary = interaction_capture_failure_evidence_summary(proof_evidence)
|
|
3651
3723
|
if structured_interaction_failure_summary:
|
|
3652
3724
|
summary_lines.append('Structured interaction evidence gate: ' + structured_interaction_failure_summary)
|
|
3725
|
+
if structured_interaction_capture_failure_summary:
|
|
3726
|
+
summary_lines.append('Structured interaction capture blocker: ' + structured_interaction_capture_failure_summary)
|
|
3653
3727
|
s['structured_interaction_failure_summary'] = structured_interaction_failure_summary
|
|
3728
|
+
s['structured_interaction_capture_failure_summary'] = structured_interaction_capture_failure_summary
|
|
3654
3729
|
|
|
3655
3730
|
visual_delta_recovery = build_visual_delta_recovery_decision(
|
|
3656
3731
|
s.get('verification_mode'),
|
|
@@ -3662,6 +3737,7 @@ if visual_delta_recovery:
|
|
|
3662
3737
|
|
|
3663
3738
|
has_judgable_failed_interaction_evidence = (
|
|
3664
3739
|
bool(structured_interaction_failure_summary)
|
|
3740
|
+
and not structured_interaction_capture_failure_summary
|
|
3665
3741
|
and required_baseline_present
|
|
3666
3742
|
and not proof_evidence_blocker
|
|
3667
3743
|
and not visual_delta_recovery
|
|
@@ -3670,6 +3746,7 @@ has_good_evidence = (
|
|
|
3670
3746
|
required_baseline_present
|
|
3671
3747
|
and (after_observation.get('valid') or has_judgable_failed_interaction_evidence)
|
|
3672
3748
|
and not proof_evidence_blocker
|
|
3749
|
+
and not structured_interaction_capture_failure_summary
|
|
3673
3750
|
and not visual_delta_recovery
|
|
3674
3751
|
)
|
|
3675
3752
|
|
|
@@ -3726,7 +3803,12 @@ if has_good_evidence:
|
|
|
3726
3803
|
summary_lines.append('Proof assessment: awaiting supervising agent judgment')
|
|
3727
3804
|
summary_lines.append('Proof next stage: supervising agent decides after reviewing the evidence packet')
|
|
3728
3805
|
else:
|
|
3729
|
-
capture_retry = build_capture_retry_decision(
|
|
3806
|
+
capture_retry = build_capture_retry_decision(
|
|
3807
|
+
after_observation,
|
|
3808
|
+
required_baseline_present,
|
|
3809
|
+
proof_evidence_blocker or structured_interaction_capture_failure_summary,
|
|
3810
|
+
s.get('route_expectation') or {},
|
|
3811
|
+
)
|
|
3730
3812
|
if visual_delta_recovery:
|
|
3731
3813
|
observation_reason = str(after_observation.get('reason') or '')
|
|
3732
3814
|
observation_details = after_observation.get('details') if isinstance(after_observation.get('details'), dict) else {}
|
|
@@ -3735,6 +3817,7 @@ else:
|
|
|
3735
3817
|
or 'console/runtime errors' in observation_reason
|
|
3736
3818
|
or (observation_details.get('capture_error_messages') or [])
|
|
3737
3819
|
or proof_evidence_blocker
|
|
3820
|
+
or structured_interaction_capture_failure_summary
|
|
3738
3821
|
)
|
|
3739
3822
|
if has_primary_capture_failure:
|
|
3740
3823
|
capture_retry['visual_delta_recovery'] = visual_delta_recovery
|
|
@@ -3742,6 +3825,9 @@ else:
|
|
|
3742
3825
|
else:
|
|
3743
3826
|
capture_retry = visual_delta_recovery
|
|
3744
3827
|
next_stage_options = ['author', 'verify', 'recon'] if no_implementation_mode else ['author', 'verify', 'implement', 'recon']
|
|
3828
|
+
capture_terminal_blocker = bool(capture_retry.get('terminal_blocker') or capture_retry.get('blocking'))
|
|
3829
|
+
recommended_stage = None if capture_terminal_blocker else (capture_retry.get('recommended_stage') or 'author')
|
|
3830
|
+
continue_with_stage = None if capture_terminal_blocker else (capture_retry.get('continue_with_stage') or 'author')
|
|
3745
3831
|
s['verify_status'] = 'capture_incomplete'
|
|
3746
3832
|
s['merge_recommendation'] = 'do-not-merge'
|
|
3747
3833
|
s['proof_assessment'] = {}
|
|
@@ -3756,8 +3842,8 @@ else:
|
|
|
3756
3842
|
'latest_observation': after_observation,
|
|
3757
3843
|
'capture_quality': capture_retry,
|
|
3758
3844
|
'next_stage_options': next_stage_options,
|
|
3759
|
-
'recommended_stage':
|
|
3760
|
-
'continue_with_stage':
|
|
3845
|
+
'recommended_stage': recommended_stage,
|
|
3846
|
+
'continue_with_stage': continue_with_stage,
|
|
3761
3847
|
'fields_agent_may_update': ['capture_script', 'server_path', 'wait_for_selector', 'proof_plan'],
|
|
3762
3848
|
'instructions': [
|
|
3763
3849
|
'The after-proof evidence packet is incomplete, so use the recommended stage before proof review.',
|
|
@@ -3767,7 +3853,7 @@ else:
|
|
|
3767
3853
|
],
|
|
3768
3854
|
}
|
|
3769
3855
|
summary_lines.append('Proof assessment: not yet possible because the after capture is still incomplete')
|
|
3770
|
-
summary_lines.append('Proof next stage: ' + str(
|
|
3856
|
+
summary_lines.append('Proof next stage: blocked' if capture_terminal_blocker else 'Proof next stage: ' + str(recommended_stage or 'author'))
|
|
3771
3857
|
|
|
3772
3858
|
s['verify_summary'] = '\n'.join(summary_lines)
|
|
3773
3859
|
s['proof_summary'] = s['verify_summary']
|