@riddledc/riddle-proof 0.8.41 → 0.8.43
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-DYUu2mqY.d.cts → proof-run-engine-4dM37pEx.d.cts} +3 -3
- package/dist/{proof-run-engine-BmNYuOJ7.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 +19 -10
- 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';
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"public_name": "Riddle Proof OC Flow Regression Pack",
|
|
5
5
|
"description": "Reusable regression pack for the trust boundary between browser evidence, verifier judgment, retry policy, wrapper checkpoint handling, and terminal status.",
|
|
6
6
|
"minimum_versions": {
|
|
7
|
-
"@riddledc/openclaw-riddle-proof": "0.4.
|
|
8
|
-
"@riddledc/riddle-proof": "0.8.
|
|
7
|
+
"@riddledc/openclaw-riddle-proof": "0.4.155",
|
|
8
|
+
"@riddledc/riddle-proof": "0.8.43"
|
|
9
9
|
},
|
|
10
10
|
"runtime_gate": {
|
|
11
11
|
"tool": "riddle_proof_status",
|
|
@@ -287,7 +287,7 @@
|
|
|
287
287
|
"wait for main#main-content",
|
|
288
288
|
"click a visible Proof link whose href includes /proof",
|
|
289
289
|
"wait for terminal URL https://riddledc.com/proof/",
|
|
290
|
-
"return riddle-proof.interaction.v1 evidence with start, action, terminal, assertions, and routeExpectationSource=
|
|
290
|
+
"return riddle-proof.interaction.v1 evidence with start, action, terminal, assertions, and routeExpectationSource=expected_terminal_path",
|
|
291
291
|
"save screenshot after-proof"
|
|
292
292
|
]
|
|
293
293
|
},
|
|
@@ -295,7 +295,7 @@
|
|
|
295
295
|
"terminal_status": "ready_to_ship",
|
|
296
296
|
"terminal_path": "/proof/",
|
|
297
297
|
"proof_evidence_present": true,
|
|
298
|
-
"route_expectation_source": "
|
|
298
|
+
"route_expectation_source": "expected_terminal_path",
|
|
299
299
|
"forbidden_terminal_markers": []
|
|
300
300
|
}
|
|
301
301
|
},
|
|
@@ -321,7 +321,7 @@
|
|
|
321
321
|
"terminal_status": "ready_to_ship",
|
|
322
322
|
"terminal_path": "/",
|
|
323
323
|
"proof_evidence_present": true,
|
|
324
|
-
"route_expectation_source": "
|
|
324
|
+
"route_expectation_source": "expected_terminal_path",
|
|
325
325
|
"forbidden_terminal_markers": []
|
|
326
326
|
}
|
|
327
327
|
},
|
|
@@ -386,9 +386,9 @@
|
|
|
386
386
|
{
|
|
387
387
|
"id": "no-diff-prod-audit-pass",
|
|
388
388
|
"tool": "riddle_proof_change",
|
|
389
|
-
"intent": "Audit the live production home page without implementation or PR handoff, and prove the current target
|
|
389
|
+
"intent": "Audit the live production home page without implementation or PR handoff, and prove the current target visually without any browser interaction.",
|
|
390
390
|
"params": {
|
|
391
|
-
"verification_mode": "
|
|
391
|
+
"verification_mode": "visual",
|
|
392
392
|
"implementation_mode": "none",
|
|
393
393
|
"require_diff": false,
|
|
394
394
|
"allow_code_changes": false,
|
|
@@ -398,15 +398,18 @@
|
|
|
398
398
|
"capture_script_contract": [
|
|
399
399
|
"use the current production target only",
|
|
400
400
|
"do not request implementation or git diff",
|
|
401
|
+
"do not click, type, submit, copy, navigate, or interact with any button or link",
|
|
401
402
|
"prove main#main-content and expected home-page content are visible",
|
|
402
|
-
"
|
|
403
|
+
"save screenshot after-proof and treat this as a passive visual/no-diff audit, not an interaction proof"
|
|
403
404
|
]
|
|
404
405
|
},
|
|
405
406
|
"expect": {
|
|
406
407
|
"terminal_status": "ready_to_ship",
|
|
407
408
|
"ship_handoff": "none",
|
|
408
409
|
"implementation_attempted": false,
|
|
409
|
-
"
|
|
410
|
+
"proof_evidence_required": false,
|
|
411
|
+
"screenshot_required": true,
|
|
412
|
+
"browser_interaction_performed": false,
|
|
410
413
|
"forbidden_terminal_markers": []
|
|
411
414
|
}
|
|
412
415
|
},
|
|
@@ -473,16 +476,22 @@
|
|
|
473
476
|
"verification_mode": "interaction",
|
|
474
477
|
"server_path": "/",
|
|
475
478
|
"wait_for_selector": "main#main-content",
|
|
479
|
+
"expected_terminal_url": "https://riddledc.com/proof/",
|
|
476
480
|
"checkpoint_mode": "terminal_only",
|
|
477
481
|
"report_mode": "terminal_only",
|
|
478
482
|
"capture_script_contract": [
|
|
479
|
-
"complete the Home -> Proof route proof",
|
|
483
|
+
"complete the Home -> Proof route proof by clicking the visible Proof nav link only",
|
|
484
|
+
"do not click Docs, Pricing, MCP, Blog, Playground, Copy, or any other link or button",
|
|
485
|
+
"terminal URL must be https://riddledc.com/proof/ and terminal path must be /proof",
|
|
480
486
|
"terminalize as ready_to_ship before any manual checkpoint injection",
|
|
481
487
|
"record state_path and run_id from riddle_proof_status"
|
|
482
488
|
]
|
|
483
489
|
},
|
|
484
490
|
"expect": {
|
|
485
491
|
"terminal_status": "ready_to_ship",
|
|
492
|
+
"terminal_url": "https://riddledc.com/proof/",
|
|
493
|
+
"terminal_path": "/proof",
|
|
494
|
+
"route_expectation_source": "expected_terminal_path",
|
|
486
495
|
"proof_evidence_present": true
|
|
487
496
|
}
|
|
488
497
|
},
|
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'],
|