@riddledc/riddle-proof 0.5.30 → 0.5.31
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/package.json
CHANGED
package/runtime/lib/util.py
CHANGED
|
@@ -67,6 +67,47 @@ def request_shape_tokens(state, limit=8):
|
|
|
67
67
|
return tokens
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
def normalize_browser_path(value):
|
|
71
|
+
value = str(value or '').strip()
|
|
72
|
+
if not value.startswith('/'):
|
|
73
|
+
return ''
|
|
74
|
+
value = value.split('#', 1)[0].split('?', 1)[0]
|
|
75
|
+
value = value.rstrip('.,;:)]}')
|
|
76
|
+
if not value.startswith('/'):
|
|
77
|
+
return ''
|
|
78
|
+
value = re.sub(r'/+', '/', value)
|
|
79
|
+
if len(value) > 1:
|
|
80
|
+
value = value.rstrip('/')
|
|
81
|
+
return value.lower() or '/'
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def extract_browser_paths(text):
|
|
85
|
+
paths = []
|
|
86
|
+
for match in re.findall(r'/(?:[A-Za-z0-9._~%!$&\'()*+,;=:@-]+/?)+(?:\?[A-Za-z0-9._~%!$&\'()*+,;=:@/?-]*)?', str(text or '')):
|
|
87
|
+
normalized = normalize_browser_path(match)
|
|
88
|
+
if normalized and normalized not in paths:
|
|
89
|
+
paths.append(normalized)
|
|
90
|
+
return paths
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def explicit_request_paths(state):
|
|
94
|
+
source_groups = [
|
|
95
|
+
[state.get('server_path'), state.get('expected_path'), state.get('target_path')],
|
|
96
|
+
[state.get('change_request')],
|
|
97
|
+
[state.get('context')],
|
|
98
|
+
[state.get('success_criteria')],
|
|
99
|
+
]
|
|
100
|
+
for group in source_groups:
|
|
101
|
+
paths = []
|
|
102
|
+
for value in group:
|
|
103
|
+
for path in extract_browser_paths(value):
|
|
104
|
+
if path not in paths:
|
|
105
|
+
paths.append(path)
|
|
106
|
+
if paths:
|
|
107
|
+
return paths
|
|
108
|
+
return []
|
|
109
|
+
|
|
110
|
+
|
|
70
111
|
def capture_hint_cache_path(state):
|
|
71
112
|
repo_key = str(state.get('repo') or state.get('repo_dir') or '').strip()
|
|
72
113
|
if not repo_key:
|
|
@@ -96,6 +137,7 @@ def select_capture_hint(state):
|
|
|
96
137
|
payload, cache_path = load_capture_hint_cache(state)
|
|
97
138
|
hints = payload.get('hints') or []
|
|
98
139
|
current_tokens = request_shape_tokens(state)
|
|
140
|
+
requested_paths = explicit_request_paths(state)
|
|
99
141
|
current_mode = str(state.get('verification_mode') or '').strip().lower()
|
|
100
142
|
scored = []
|
|
101
143
|
for hint in hints:
|
|
@@ -105,6 +147,9 @@ def select_capture_hint(state):
|
|
|
105
147
|
wait_for_selector = str(hint.get('wait_for_selector') or '').strip()
|
|
106
148
|
if not server_path and not wait_for_selector:
|
|
107
149
|
continue
|
|
150
|
+
hint_path = normalize_browser_path(server_path)
|
|
151
|
+
if requested_paths and hint_path and hint_path not in requested_paths:
|
|
152
|
+
continue
|
|
108
153
|
hint_mode = str(hint.get('verification_mode') or '').strip().lower()
|
|
109
154
|
hint_tokens = [
|
|
110
155
|
str(item).strip().lower()
|
|
@@ -1036,6 +1036,29 @@ def run_capture_hint_rejects_route_specific_mode_only_match():
|
|
|
1036
1036
|
assert applied is None, applied
|
|
1037
1037
|
assert 'server_path' not in state, state
|
|
1038
1038
|
|
|
1039
|
+
cache_file.write_text(json.dumps({
|
|
1040
|
+
'version': util.CAPTURE_HINT_CACHE_VERSION,
|
|
1041
|
+
'hints': [
|
|
1042
|
+
{
|
|
1043
|
+
'saved_at': '2026-04-25T00:00:00Z',
|
|
1044
|
+
'verification_mode': 'text',
|
|
1045
|
+
'request_tokens': ['games', 'reset', 'board'],
|
|
1046
|
+
'server_path': '/games/drum-sequencer',
|
|
1047
|
+
'wait_for_selector': '.drum-sequencer h1',
|
|
1048
|
+
'observed_path': '/games/drum-sequencer',
|
|
1049
|
+
}
|
|
1050
|
+
],
|
|
1051
|
+
}))
|
|
1052
|
+
|
|
1053
|
+
weak_token_state = dict(state)
|
|
1054
|
+
weak_token_state['success_criteria'] = 'Stale profile text says Neon Step Sequencer on /games/drum-sequencer.'
|
|
1055
|
+
weak_token_selected = util.select_capture_hint(weak_token_state)
|
|
1056
|
+
weak_token_applied = util.apply_capture_hint(weak_token_state)
|
|
1057
|
+
|
|
1058
|
+
assert weak_token_selected is None, weak_token_selected
|
|
1059
|
+
assert weak_token_applied is None, weak_token_applied
|
|
1060
|
+
assert 'server_path' not in weak_token_state, weak_token_state
|
|
1061
|
+
|
|
1039
1062
|
cache_file.write_text(json.dumps({
|
|
1040
1063
|
'version': util.CAPTURE_HINT_CACHE_VERSION,
|
|
1041
1064
|
'hints': [
|