@riddledc/riddle-proof 0.8.40 → 0.8.42
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/index.d.cts +1 -1
- package/dist/advanced/index.d.ts +1 -1
- package/dist/advanced/proof-run-engine.d.cts +1 -1
- package/dist/advanced/proof-run-engine.d.ts +1 -1
- package/dist/{proof-run-engine-DeHxtGnW.d.cts → proof-run-engine-4dM37pEx.d.cts} +3 -3
- package/dist/{proof-run-engine-DYfmd8d7.d.ts → proof-run-engine-BqaeqAze.d.ts} +3 -3
- package/dist/proof-run-engine.d.cts +1 -1
- package/dist/proof-run-engine.d.ts +1 -1
- package/examples/regression-packs/oc-flow-regression.json +1 -0
- package/package.json +1 -1
- package/runtime/lib/recon.py +18 -3
- package/runtime/lib/util.py +39 -1
- package/runtime/tests/recon_verify_smoke.py +29 -0
- package/runtime/tests/trust_boundary_regression.py +6 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { b as runner } from '../runner-4LJ5z0D-.cjs';
|
|
2
2
|
export { l as engineHarness } from '../engine-harness-LBfqbFSe.cjs';
|
|
3
3
|
export { p as proofRunCore } from '../proof-run-core-B1GeqkR8.cjs';
|
|
4
|
-
export { p as proofRunEngine } from '../proof-run-engine-
|
|
4
|
+
export { p as proofRunEngine } from '../proof-run-engine-4dM37pEx.cjs';
|
|
5
5
|
import '../types.cjs';
|
package/dist/advanced/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { b as runner } from '../runner-BdQpOkZD.js';
|
|
2
2
|
export { l as engineHarness } from '../engine-harness-CMACHP6A.js';
|
|
3
3
|
export { p as proofRunCore } from '../proof-run-core-B1GeqkR8.js';
|
|
4
|
-
export { p as proofRunEngine } from '../proof-run-engine-
|
|
4
|
+
export { p as proofRunEngine } from '../proof-run-engine-BqaeqAze.js';
|
|
5
5
|
import '../types.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-
|
|
1
|
+
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-4dM37pEx.cjs';
|
|
2
2
|
import '../proof-run-core-B1GeqkR8.cjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-
|
|
1
|
+
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from '../proof-run-engine-BqaeqAze.js';
|
|
2
2
|
import '../proof-run-core-B1GeqkR8.js';
|
|
@@ -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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "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: "author" | "recon" | "ship" | "implement" | "verify" | "setup";
|
|
663
663
|
state_path: string;
|
|
664
664
|
stage: any;
|
|
665
665
|
summary: string;
|
|
@@ -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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "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: "author" | "recon" | "ship" | "implement" | "verify" | "setup";
|
|
663
663
|
state_path: string;
|
|
664
664
|
stage: any;
|
|
665
665
|
summary: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import './proof-run-core-B1GeqkR8.cjs';
|
|
2
|
-
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-
|
|
2
|
+
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-4dM37pEx.cjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import './proof-run-core-B1GeqkR8.js';
|
|
2
|
-
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-
|
|
2
|
+
export { R as RiddleProofEngine, c as createRiddleProofEngine, e as executeWorkflow } from './proof-run-engine-BqaeqAze.js';
|
|
@@ -444,6 +444,7 @@
|
|
|
444
444
|
"verification_mode": "interaction",
|
|
445
445
|
"server_path": "/",
|
|
446
446
|
"wait_for_selector": "main#main-content",
|
|
447
|
+
"max_iterations": 6,
|
|
447
448
|
"capture_script_contract": [
|
|
448
449
|
"throw intentional-riddle-proof-regression-thrown-error from the capture script",
|
|
449
450
|
"preserve the exact marker in terminal evidence",
|
package/package.json
CHANGED
package/runtime/lib/recon.py
CHANGED
|
@@ -20,6 +20,7 @@ from util import ( # noqa: E402
|
|
|
20
20
|
build_capture_script,
|
|
21
21
|
capture_static_preview,
|
|
22
22
|
capture_viewport_matrix_status,
|
|
23
|
+
compose_remote_capture_url,
|
|
23
24
|
enrich_capture_payload,
|
|
24
25
|
has_auth_context,
|
|
25
26
|
invoke_retry,
|
|
@@ -41,6 +42,7 @@ MIN_CANVAS_AREA = 50000
|
|
|
41
42
|
HYDRATION_WAIT_MS = 1500
|
|
42
43
|
PAGE_STATE_PREFIX = 'RIDDLE_PROOF_STATE:'
|
|
43
44
|
PROOF_EVIDENCE_PREFIX = 'RIDDLE_PROOF_EVIDENCE:'
|
|
45
|
+
INTERACTION_VERIFICATION_MODES = {'interaction', 'flow', 'browser_interaction'}
|
|
44
46
|
|
|
45
47
|
s = load_state()
|
|
46
48
|
after_dir = (s.get('after_worktree') or '').strip()
|
|
@@ -808,7 +810,7 @@ def capture_workspace_baseline(project_dir, label, plan, capture_script=''):
|
|
|
808
810
|
|
|
809
811
|
|
|
810
812
|
def capture_prod_baseline(prod_url, plan, capture_script=''):
|
|
811
|
-
target_url = (prod_url
|
|
813
|
+
target_url = prod_capture_target_url(prod_url, plan)
|
|
812
814
|
if not target_url:
|
|
813
815
|
raise SystemExit('Requested prod baseline in recon, but prod_url is missing.')
|
|
814
816
|
wait_for_selector = (plan.get('wait_for_selector') or '').strip()
|
|
@@ -821,7 +823,7 @@ def capture_prod_baseline(prod_url, plan, capture_script=''):
|
|
|
821
823
|
append_capture_diagnostic(s, 'prod', 'riddle_script', args, shot)
|
|
822
824
|
record_recon_phase('prod_capture', 'completed', 'Production recon baseline capture completed.')
|
|
823
825
|
return {
|
|
824
|
-
'source': 'prod_url',
|
|
826
|
+
'source': 'prod_url_with_target_path' if target_url != (prod_url or '').strip() else 'prod_url',
|
|
825
827
|
'mode': 'remote',
|
|
826
828
|
'path': normalize_observed_path(target_url) or (plan.get('target_path') or '/'),
|
|
827
829
|
'capture_url': target_url,
|
|
@@ -831,6 +833,19 @@ def capture_prod_baseline(prod_url, plan, capture_script=''):
|
|
|
831
833
|
}
|
|
832
834
|
|
|
833
835
|
|
|
836
|
+
def interaction_verification_mode():
|
|
837
|
+
return str(s.get('verification_mode') or '').strip().lower() in INTERACTION_VERIFICATION_MODES
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
def prod_capture_target_url(prod_url, plan):
|
|
841
|
+
target_path = str((plan or {}).get('target_path') or '').strip()
|
|
842
|
+
has_explicit_start_route = bool(
|
|
843
|
+
str(s.get('server_path') or s.get('expected_start_path') or '').strip()
|
|
844
|
+
and (str(s.get('server_path_source') or '').strip() or interaction_verification_mode())
|
|
845
|
+
)
|
|
846
|
+
return compose_remote_capture_url(prod_url, target_path, explicit_target=has_explicit_start_route)
|
|
847
|
+
|
|
848
|
+
|
|
834
849
|
def baseline_record(capture, observation):
|
|
835
850
|
return {
|
|
836
851
|
'source': capture.get('source'),
|
|
@@ -1066,7 +1081,7 @@ for label in required_baselines:
|
|
|
1066
1081
|
expected_path = current_plan['target_path']
|
|
1067
1082
|
else:
|
|
1068
1083
|
capture = capture_prod_baseline(s.get('prod_url', ''), current_plan, capture_script='')
|
|
1069
|
-
expected_path =
|
|
1084
|
+
expected_path = normalize_observed_path(capture.get('capture_url')) or current_plan['target_path']
|
|
1070
1085
|
observation = build_observation_packet(label, expected_path, capture=capture)
|
|
1071
1086
|
except SystemExit:
|
|
1072
1087
|
raise
|
package/runtime/lib/util.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Shared helpers for Riddle Proof pipeline."""
|
|
2
2
|
|
|
3
3
|
import hashlib, json, os, re, shlex, subprocess as sp, tempfile, time
|
|
4
|
-
from urllib.parse import urljoin
|
|
4
|
+
from urllib.parse import urljoin, urlparse, urlunparse
|
|
5
5
|
from urllib.request import urlopen
|
|
6
6
|
|
|
7
7
|
STATE_FILE = os.environ.get('RIDDLE_PROOF_STATE_FILE', '/tmp/riddle-proof-state.json')
|
|
@@ -86,6 +86,44 @@ def normalize_browser_path(value):
|
|
|
86
86
|
return value.lower() or '/'
|
|
87
87
|
|
|
88
88
|
|
|
89
|
+
def compose_remote_capture_url(base_url, target_path='', explicit_target=False):
|
|
90
|
+
"""Resolve a remote capture URL against an explicit browser route.
|
|
91
|
+
|
|
92
|
+
prod_url identifies the deployed origin, but interaction proofs may start on
|
|
93
|
+
a route such as /proof/ before navigating elsewhere. In that case recon must
|
|
94
|
+
capture the start route, not merely the prod_url root.
|
|
95
|
+
"""
|
|
96
|
+
base = str(base_url or '').strip()
|
|
97
|
+
target = str(target_path or '').strip()
|
|
98
|
+
if not base or not target.startswith('/'):
|
|
99
|
+
return base
|
|
100
|
+
|
|
101
|
+
parsed_base = urlparse(base)
|
|
102
|
+
if not parsed_base.scheme or not parsed_base.netloc:
|
|
103
|
+
return base
|
|
104
|
+
|
|
105
|
+
parsed_target = urlparse(target)
|
|
106
|
+
target_browser_path = parsed_target.path or '/'
|
|
107
|
+
if not target_browser_path.startswith('/'):
|
|
108
|
+
target_browser_path = '/' + target_browser_path.lstrip('/')
|
|
109
|
+
|
|
110
|
+
if not explicit_target:
|
|
111
|
+
base_browser_path = parsed_base.path or '/'
|
|
112
|
+
if normalize_browser_path(target_browser_path) in ('', '/') and normalize_browser_path(base_browser_path) != '/':
|
|
113
|
+
return base
|
|
114
|
+
if normalize_browser_path(target_browser_path) == normalize_browser_path(base_browser_path):
|
|
115
|
+
return base
|
|
116
|
+
|
|
117
|
+
return urlunparse((
|
|
118
|
+
parsed_base.scheme,
|
|
119
|
+
parsed_base.netloc,
|
|
120
|
+
target_browser_path,
|
|
121
|
+
'',
|
|
122
|
+
parsed_target.query,
|
|
123
|
+
parsed_target.fragment,
|
|
124
|
+
))
|
|
125
|
+
|
|
126
|
+
|
|
89
127
|
def extract_browser_paths(text):
|
|
90
128
|
paths = []
|
|
91
129
|
for match in re.findall(r'/(?:[A-Za-z0-9._~%!$&\'()*+,;=:@-]+/?)+(?:\?[A-Za-z0-9._~%!$&\'()*+,;=:@/?-]*)?', str(text or '')):
|
|
@@ -70,6 +70,35 @@ def load_module(name: str, path: Path):
|
|
|
70
70
|
return module
|
|
71
71
|
|
|
72
72
|
|
|
73
|
+
def run_recon_remote_prod_capture_uses_interaction_start_route():
|
|
74
|
+
util = load_module('riddle_proof_util_route_target_smoke', UTIL_PATH)
|
|
75
|
+
cases = [
|
|
76
|
+
(
|
|
77
|
+
util.compose_remote_capture_url('https://riddledc.com/', '/proof/', explicit_target=True),
|
|
78
|
+
'https://riddledc.com/proof/',
|
|
79
|
+
),
|
|
80
|
+
(
|
|
81
|
+
util.compose_remote_capture_url('https://riddledc.com/', '/pricing/?rp_probe=1#pricing-probe', explicit_target=True),
|
|
82
|
+
'https://riddledc.com/pricing/?rp_probe=1#pricing-probe',
|
|
83
|
+
),
|
|
84
|
+
(
|
|
85
|
+
util.compose_remote_capture_url('https://riddledc.com/proof/', '/', explicit_target=True),
|
|
86
|
+
'https://riddledc.com/',
|
|
87
|
+
),
|
|
88
|
+
(
|
|
89
|
+
util.compose_remote_capture_url('https://riddledc.com/proof/', '/', explicit_target=False),
|
|
90
|
+
'https://riddledc.com/proof/',
|
|
91
|
+
),
|
|
92
|
+
]
|
|
93
|
+
for observed, expected in cases:
|
|
94
|
+
assert observed == expected, f'expected {expected}, got {observed}'
|
|
95
|
+
return {
|
|
96
|
+
'ok': True,
|
|
97
|
+
'remote_start_route': 'https://riddledc.com/proof/',
|
|
98
|
+
'query_hash_route': 'https://riddledc.com/pricing/?rp_probe=1#pricing-probe',
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
73
102
|
class FakeRiddle:
|
|
74
103
|
def __init__(self):
|
|
75
104
|
self.calls = []
|
|
@@ -19,6 +19,12 @@ def load_smoke_module():
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
CASES = [
|
|
22
|
+
{
|
|
23
|
+
'name': 'recon-remote-prod-captures-interaction-start-route',
|
|
24
|
+
'covers': ['route-changing interactions', 'no-diff prod audits'],
|
|
25
|
+
'function': 'run_recon_remote_prod_capture_uses_interaction_start_route',
|
|
26
|
+
'expected_terminal': 'pass',
|
|
27
|
+
},
|
|
22
28
|
{
|
|
23
29
|
'name': 'route-change-forward-pass',
|
|
24
30
|
'covers': ['route-changing interactions', 'proof-evidence-present'],
|