@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
|
@@ -345,7 +345,12 @@ class FakeRiddle:
|
|
|
345
345
|
'version': 'riddle-proof.interaction.v1',
|
|
346
346
|
'start': {'href': 'https://riddledc.com/'},
|
|
347
347
|
'action': {'type': 'click', 'target': 'Pricing'},
|
|
348
|
-
'terminal': {
|
|
348
|
+
'terminal': {
|
|
349
|
+
'pathname': '/pricing/',
|
|
350
|
+
'search': '?rp_probe=1',
|
|
351
|
+
'hash': '#pricing-probe',
|
|
352
|
+
'href': 'https://riddledc.com/pricing/?rp_probe=1#pricing-probe',
|
|
353
|
+
},
|
|
349
354
|
'afterUrl': 'https://riddledc.com/pricing/?rp_probe=1#pricing-probe',
|
|
350
355
|
'routeMatched': True,
|
|
351
356
|
'assertions': {
|
|
@@ -480,6 +485,36 @@ class FakeRiddle:
|
|
|
480
485
|
'proof.json': {'script_error': message},
|
|
481
486
|
},
|
|
482
487
|
}
|
|
488
|
+
if 'interactionThrownError' in script:
|
|
489
|
+
message = 'Error: intentional-riddle-proof-0811-thrown-error'
|
|
490
|
+
page_state = {
|
|
491
|
+
'bodyTextLength': 180,
|
|
492
|
+
'visibleTextSample': 'Riddle Proof homepage hero Start Free',
|
|
493
|
+
'interactiveElements': 4,
|
|
494
|
+
'visibleInteractiveElements': 4,
|
|
495
|
+
'pathname': '/',
|
|
496
|
+
'search': '',
|
|
497
|
+
'hash': '',
|
|
498
|
+
'title': 'Riddle',
|
|
499
|
+
'buttons': ['Start Free'],
|
|
500
|
+
'headings': ['Riddle Proof'],
|
|
501
|
+
'links': [],
|
|
502
|
+
'canvasCount': 0,
|
|
503
|
+
'largeVisibleElements': [{'tag': 'h1', 'text': 'Riddle Proof'}],
|
|
504
|
+
}
|
|
505
|
+
return {
|
|
506
|
+
'ok': True,
|
|
507
|
+
'screenshots': [{'url': 'https://cdn.example.com/thrown-error.png'}],
|
|
508
|
+
'outputs': [{'name': 'after-thrown-error.png', 'url': 'https://cdn.example.com/thrown-error.png'}],
|
|
509
|
+
'result': {'pageState': page_state},
|
|
510
|
+
'console': [
|
|
511
|
+
'RIDDLE_PROOF_STATE:' + json.dumps(page_state),
|
|
512
|
+
'Uncaught exception: ' + message,
|
|
513
|
+
],
|
|
514
|
+
'_artifact_json': {
|
|
515
|
+
'proof.json': {'script_error': message},
|
|
516
|
+
},
|
|
517
|
+
}
|
|
483
518
|
if 'after-proof' in script:
|
|
484
519
|
after_url = 'https://cdn.example.com/after-artifact' if 'noVisualDelta' in script else 'https://cdn.example.com/after.png'
|
|
485
520
|
outputs = [{'name': 'after.png', 'url': after_url}]
|
|
@@ -2568,6 +2603,58 @@ def run_verify_interaction_terminal_route_from_proof_evidence():
|
|
|
2568
2603
|
shutil.rmtree(tempdir, ignore_errors=True)
|
|
2569
2604
|
|
|
2570
2605
|
|
|
2606
|
+
def run_verify_interaction_proof_evidence_overrides_stale_expected_path():
|
|
2607
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-interaction-stale-route-'))
|
|
2608
|
+
state_path = tempdir / 'state.json'
|
|
2609
|
+
try:
|
|
2610
|
+
state = base_state(tempdir, reference='before')
|
|
2611
|
+
state.update({
|
|
2612
|
+
'recon_status': 'ready_for_proof_plan',
|
|
2613
|
+
'author_status': 'ready',
|
|
2614
|
+
'proof_plan_status': 'ready',
|
|
2615
|
+
'implementation_status': 'changes_detected',
|
|
2616
|
+
'verification_mode': 'interaction',
|
|
2617
|
+
'server_path': '/',
|
|
2618
|
+
'expected_terminal_path': '/state',
|
|
2619
|
+
'before_cdn': 'https://cdn.example.com/before-home.png',
|
|
2620
|
+
'proof_plan': 'Start at /, click Proof, and verify the terminal /proof/ route.',
|
|
2621
|
+
'capture_script': "clickedProofNavigation(); await saveScreenshot('after-proof');",
|
|
2622
|
+
'supervisor_author_packet': {
|
|
2623
|
+
'proof_plan': 'Click Proof and prove the terminal route.',
|
|
2624
|
+
'capture_script': "clickedProofNavigation(); await saveScreenshot('after-proof');",
|
|
2625
|
+
'refined_inputs': {
|
|
2626
|
+
'server_path': '/',
|
|
2627
|
+
'expected_terminal_path': '/state',
|
|
2628
|
+
},
|
|
2629
|
+
},
|
|
2630
|
+
'recon_results': {
|
|
2631
|
+
'baselines': {'before': {'path': '/', 'url': 'https://cdn.example.com/before-home.png'}},
|
|
2632
|
+
},
|
|
2633
|
+
})
|
|
2634
|
+
write_state(state_path, state)
|
|
2635
|
+
os.environ['RIDDLE_PROOF_STATE_FILE'] = str(state_path)
|
|
2636
|
+
|
|
2637
|
+
fake = FakeRiddle()
|
|
2638
|
+
load_util_with_fake(fake)
|
|
2639
|
+
load_module('verify_interaction_stale_route_uses_evidence', VERIFY_PATH)
|
|
2640
|
+
after_verify = json.loads(state_path.read_text())
|
|
2641
|
+
|
|
2642
|
+
assert after_verify['verify_status'] == 'evidence_captured'
|
|
2643
|
+
assert after_verify['route_expectation']['source'] == 'proof_evidence_contract'
|
|
2644
|
+
assert after_verify['route_expectation']['expected_path'] == '/proof'
|
|
2645
|
+
route = after_verify['proof_assessment_request']['semantic_context']['route']
|
|
2646
|
+
assert route['expected_after_path'] == '/proof'
|
|
2647
|
+
assert route['after_observed_path'] == '/proof'
|
|
2648
|
+
assert 'wrong route' not in after_verify['verify_results']['after']['observation']['reason']
|
|
2649
|
+
return {
|
|
2650
|
+
'ok': True,
|
|
2651
|
+
'expected_path': after_verify['route_expectation']['expected_path'],
|
|
2652
|
+
'source': after_verify['route_expectation']['source'],
|
|
2653
|
+
}
|
|
2654
|
+
finally:
|
|
2655
|
+
shutil.rmtree(tempdir, ignore_errors=True)
|
|
2656
|
+
|
|
2657
|
+
|
|
2571
2658
|
def run_verify_interaction_reverse_terminal_route_from_proof_evidence():
|
|
2572
2659
|
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-interaction-reverse-'))
|
|
2573
2660
|
state_path = tempdir / 'state.json'
|
|
@@ -2751,9 +2838,11 @@ def run_verify_interaction_authored_query_hash_mismatch_blocks_with_evidence():
|
|
|
2751
2838
|
assert after_verify['route_expectation']['expected_query'] == 'rp_probe=1'
|
|
2752
2839
|
assert after_verify['route_expectation']['expected_hash'] == '#pricing-probe'
|
|
2753
2840
|
capture_quality = request['capture_quality']
|
|
2754
|
-
assert capture_quality['decision']
|
|
2755
|
-
assert request['recommended_stage']
|
|
2756
|
-
assert request['continue_with_stage']
|
|
2841
|
+
assert capture_quality['decision'] == 'failed_interaction_capture'
|
|
2842
|
+
assert request['recommended_stage'] is None
|
|
2843
|
+
assert request['continue_with_stage'] is None
|
|
2844
|
+
assert capture_quality['blocking'] is True
|
|
2845
|
+
assert capture_quality['terminal_blocker'] is True
|
|
2757
2846
|
quality_text = json.dumps(capture_quality, sort_keys=True)
|
|
2758
2847
|
assert 'page.waitForURL: Timeout 15000ms exceeded' in quality_text
|
|
2759
2848
|
assert after_verify['proof_assessment_request'] == {}
|
|
@@ -2778,6 +2867,7 @@ def run_verify_interaction_authored_query_hash_mismatch_blocks_with_evidence():
|
|
|
2778
2867
|
'ok': True,
|
|
2779
2868
|
'summary': request['summary'],
|
|
2780
2869
|
'recommended_stage': request['recommended_stage'],
|
|
2870
|
+
'blocking': capture_quality['blocking'],
|
|
2781
2871
|
}
|
|
2782
2872
|
finally:
|
|
2783
2873
|
shutil.rmtree(tempdir, ignore_errors=True)
|
|
@@ -2844,6 +2934,64 @@ def run_verify_interaction_query_hash_pass_uses_proof_evidence_route():
|
|
|
2844
2934
|
shutil.rmtree(tempdir, ignore_errors=True)
|
|
2845
2935
|
|
|
2846
2936
|
|
|
2937
|
+
def run_verify_interaction_thrown_error_terminal_blocker():
|
|
2938
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-interaction-thrown-error-'))
|
|
2939
|
+
state_path = tempdir / 'state.json'
|
|
2940
|
+
try:
|
|
2941
|
+
state = base_state(tempdir, reference='before')
|
|
2942
|
+
state.update({
|
|
2943
|
+
'recon_status': 'ready_for_proof_plan',
|
|
2944
|
+
'author_status': 'ready',
|
|
2945
|
+
'proof_plan_status': 'ready',
|
|
2946
|
+
'implementation_status': 'changes_detected',
|
|
2947
|
+
'verification_mode': 'interaction',
|
|
2948
|
+
'server_path': '/',
|
|
2949
|
+
'before_cdn': 'https://cdn.example.com/before-home.png',
|
|
2950
|
+
'proof_plan': 'Run a diagnostic interaction script that intentionally throws.',
|
|
2951
|
+
'capture_script': "interactionThrownError();",
|
|
2952
|
+
'recon_results': {
|
|
2953
|
+
'baselines': {'before': {'path': '/', 'url': 'https://cdn.example.com/before-home.png'}},
|
|
2954
|
+
},
|
|
2955
|
+
})
|
|
2956
|
+
write_state(state_path, state)
|
|
2957
|
+
os.environ['RIDDLE_PROOF_STATE_FILE'] = str(state_path)
|
|
2958
|
+
|
|
2959
|
+
fake = FakeRiddle()
|
|
2960
|
+
load_util_with_fake(fake)
|
|
2961
|
+
load_module('verify_interaction_thrown_error_terminal_blocker', VERIFY_PATH)
|
|
2962
|
+
after_verify = json.loads(state_path.read_text())
|
|
2963
|
+
|
|
2964
|
+
assert after_verify['verify_status'] == 'capture_incomplete'
|
|
2965
|
+
assert after_verify['merge_recommendation'] == 'do-not-merge'
|
|
2966
|
+
assert after_verify['proof_assessment_request'] == {}
|
|
2967
|
+
capture_quality = after_verify['verify_decision_request']['capture_quality']
|
|
2968
|
+
assert capture_quality['decision'] == 'failed_interaction_capture'
|
|
2969
|
+
assert capture_quality['recommended_stage'] is None
|
|
2970
|
+
assert capture_quality['continue_with_stage'] is None
|
|
2971
|
+
assert capture_quality['blocking'] is True
|
|
2972
|
+
assert capture_quality['terminal_blocker'] is True
|
|
2973
|
+
capture_quality_text = json.dumps(capture_quality, sort_keys=True)
|
|
2974
|
+
assert 'intentional-riddle-proof-0811-thrown-error' in capture_quality_text
|
|
2975
|
+
assert after_verify['structured_interaction_capture_failure_summary']
|
|
2976
|
+
evidence = after_verify['evidence_bundle']['proof_evidence']
|
|
2977
|
+
if isinstance(evidence, list):
|
|
2978
|
+
evidence = next(
|
|
2979
|
+
record for record in evidence_records(evidence)
|
|
2980
|
+
if record.get('version') == 'riddle-proof.interaction.capture-failure.v1'
|
|
2981
|
+
)
|
|
2982
|
+
assert evidence['version'] == 'riddle-proof.interaction.capture-failure.v1'
|
|
2983
|
+
assert evidence['checks']['scriptCompleted'] is False
|
|
2984
|
+
assert evidence['checks']['authoredEvidenceReturned'] is False
|
|
2985
|
+
assert 'intentional-riddle-proof-0811-thrown-error' in evidence['capture_error']
|
|
2986
|
+
return {
|
|
2987
|
+
'ok': True,
|
|
2988
|
+
'decision': capture_quality['decision'],
|
|
2989
|
+
'blocking': capture_quality['blocking'],
|
|
2990
|
+
}
|
|
2991
|
+
finally:
|
|
2992
|
+
shutil.rmtree(tempdir, ignore_errors=True)
|
|
2993
|
+
|
|
2994
|
+
|
|
2847
2995
|
def run_verify_capture_retry_surfaces_script_timeout():
|
|
2848
2996
|
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-capture-timeout-'))
|
|
2849
2997
|
state_path = tempdir / 'state.json'
|
|
@@ -3262,11 +3410,13 @@ if __name__ == '__main__':
|
|
|
3262
3410
|
'verify_capture_retry': run_verify_capture_retry(),
|
|
3263
3411
|
'remote_audit_verify_uses_default_capture_script': run_remote_audit_verify_uses_default_capture_script(),
|
|
3264
3412
|
'verify_interaction_terminal_route_from_proof_evidence': run_verify_interaction_terminal_route_from_proof_evidence(),
|
|
3413
|
+
'verify_interaction_proof_evidence_overrides_stale_expected_path': run_verify_interaction_proof_evidence_overrides_stale_expected_path(),
|
|
3265
3414
|
'verify_interaction_reverse_terminal_route_from_proof_evidence': run_verify_interaction_reverse_terminal_route_from_proof_evidence(),
|
|
3266
3415
|
'verify_interaction_prose_route_noise_uses_proof_evidence': run_verify_interaction_prose_route_noise_uses_proof_evidence(),
|
|
3267
3416
|
'verify_interaction_hash_terminal_route_from_proof_evidence': run_verify_interaction_hash_terminal_route_from_proof_evidence(),
|
|
3268
3417
|
'verify_interaction_authored_query_hash_mismatch_blocks_with_evidence': run_verify_interaction_authored_query_hash_mismatch_blocks_with_evidence(),
|
|
3269
3418
|
'verify_interaction_query_hash_pass_uses_proof_evidence_route': run_verify_interaction_query_hash_pass_uses_proof_evidence_route(),
|
|
3419
|
+
'verify_interaction_thrown_error_terminal_blocker': run_verify_interaction_thrown_error_terminal_blocker(),
|
|
3270
3420
|
'verify_capture_retry_surfaces_script_timeout': run_verify_capture_retry_surfaces_script_timeout(),
|
|
3271
3421
|
'missing_baseline_guard': run_verify_missing_baseline(),
|
|
3272
3422
|
'ship_supervisor_gate': run_ship_missing_supervisor_gate(),
|
|
@@ -25,6 +25,12 @@ CASES = [
|
|
|
25
25
|
'function': 'run_verify_interaction_terminal_route_from_proof_evidence',
|
|
26
26
|
'expected_terminal': 'pass',
|
|
27
27
|
},
|
|
28
|
+
{
|
|
29
|
+
'name': 'route-change-retry-state-drift-ignored',
|
|
30
|
+
'covers': ['route-changing interactions', 'proof-evidence-present'],
|
|
31
|
+
'function': 'run_verify_interaction_proof_evidence_overrides_stale_expected_path',
|
|
32
|
+
'expected_terminal': 'pass',
|
|
33
|
+
},
|
|
28
34
|
{
|
|
29
35
|
'name': 'route-change-reverse-pass',
|
|
30
36
|
'covers': ['route-changing interactions'],
|
|
@@ -67,6 +73,12 @@ CASES = [
|
|
|
67
73
|
'function': 'run_verify_preserves_proof_evidence_on_capture_script_error',
|
|
68
74
|
'expected_terminal': 'specific_blocker',
|
|
69
75
|
},
|
|
76
|
+
{
|
|
77
|
+
'name': 'interaction-thrown-error-specific-blocker',
|
|
78
|
+
'covers': ['thrown errors', 'invalid browser evidence'],
|
|
79
|
+
'function': 'run_verify_interaction_thrown_error_terminal_blocker',
|
|
80
|
+
'expected_terminal': 'specific_blocker',
|
|
81
|
+
},
|
|
70
82
|
{
|
|
71
83
|
'name': 'structured-proof-without-screenshot-pass',
|
|
72
84
|
'covers': ['proof-evidence-present'],
|