@riddledc/riddle-proof 0.5.26 → 0.5.28
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 +1 -1
- package/runtime/lib/ship.py +26 -8
- package/runtime/lib/util.py +5 -1
- package/runtime/tests/recon_verify_smoke.py +105 -0
package/package.json
CHANGED
package/runtime/lib/ship.py
CHANGED
|
@@ -82,6 +82,24 @@ def git_stdout(args, repo_dir, timeout=30):
|
|
|
82
82
|
return result.stdout.strip()
|
|
83
83
|
|
|
84
84
|
|
|
85
|
+
def git_checked(args, repo_dir, timeout=120):
|
|
86
|
+
result = sp.run(['git'] + args, cwd=repo_dir, capture_output=True, text=True, timeout=timeout)
|
|
87
|
+
if result.returncode != 0:
|
|
88
|
+
raise SystemExit('git ' + ' '.join(args) + ' failed: ' + (result.stderr or result.stdout)[:300])
|
|
89
|
+
return result
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def gh_pr_create_args(title, body, branch):
|
|
93
|
+
return [
|
|
94
|
+
'gh', 'pr', 'create',
|
|
95
|
+
'--draft',
|
|
96
|
+
'--title', str(title or '').strip() or 'Riddle Proof change',
|
|
97
|
+
'--body', str(body or ''),
|
|
98
|
+
'--base', 'main',
|
|
99
|
+
'--head', str(branch or ''),
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
|
|
85
103
|
def remote_branch_head(repo_dir, branch):
|
|
86
104
|
result = sp.run(['git', 'ls-remote', 'origin', 'refs/heads/' + branch], cwd=repo_dir, capture_output=True, text=True, timeout=60)
|
|
87
105
|
if result.returncode != 0:
|
|
@@ -623,11 +641,11 @@ if lines:
|
|
|
623
641
|
print('Only ship-noise paths changed; skipping commit.')
|
|
624
642
|
if s.get('pr_url'):
|
|
625
643
|
if staged_paths:
|
|
626
|
-
|
|
644
|
+
git_checked(['commit', '--amend', '--no-edit'], after_dir)
|
|
627
645
|
push, push_info = push_existing_pr_branch(after_dir, branch, push_target)
|
|
628
646
|
else:
|
|
629
647
|
if staged_paths:
|
|
630
|
-
|
|
648
|
+
git_checked(['commit', '-m', s['commit_message']], after_dir)
|
|
631
649
|
push = sp.run(
|
|
632
650
|
['git', 'push', 'origin', push_target],
|
|
633
651
|
cwd=after_dir,
|
|
@@ -657,8 +675,8 @@ else:
|
|
|
657
675
|
|
|
658
676
|
# Create PR if needed
|
|
659
677
|
if not s.get('pr_url'):
|
|
660
|
-
q = sp.run('gh pr list --head
|
|
661
|
-
|
|
678
|
+
q = sp.run(['gh', 'pr', 'list', '--head', branch, '--json', 'url,number', '-q', '.[0]'],
|
|
679
|
+
cwd=repo_dir, capture_output=True, text=True)
|
|
662
680
|
pr_url = ''
|
|
663
681
|
if q.stdout.strip():
|
|
664
682
|
try:
|
|
@@ -667,10 +685,10 @@ if not s.get('pr_url'):
|
|
|
667
685
|
except:
|
|
668
686
|
pass
|
|
669
687
|
if not pr_url:
|
|
670
|
-
c = sp.run('
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
688
|
+
c = sp.run(gh_pr_create_args(s.get('commit_message', ''), s.get('change_request', ''), branch),
|
|
689
|
+
cwd=repo_dir, capture_output=True, text=True)
|
|
690
|
+
if c.returncode != 0:
|
|
691
|
+
raise SystemExit('Failed to create PR: ' + (c.stderr or c.stdout)[:500])
|
|
674
692
|
pr_url = c.stdout.strip().splitlines()[-1].strip() if c.returncode == 0 else ''
|
|
675
693
|
s['pr_url'] = pr_url
|
|
676
694
|
s['pr_number'] = pr_url.rstrip('/').split('/')[-1] if pr_url else ''
|
package/runtime/lib/util.py
CHANGED
|
@@ -112,8 +112,12 @@ def select_capture_hint(state):
|
|
|
112
112
|
if str(item).strip()
|
|
113
113
|
]
|
|
114
114
|
matched_tokens = [token for token in current_tokens if token in hint_tokens]
|
|
115
|
+
mode_matches = bool(current_mode and hint_mode == current_mode)
|
|
116
|
+
root_hint = server_path == '/'
|
|
117
|
+
if not matched_tokens and mode_matches and not root_hint:
|
|
118
|
+
continue
|
|
115
119
|
score = len(matched_tokens) * 3
|
|
116
|
-
if
|
|
120
|
+
if mode_matches:
|
|
117
121
|
score += 2
|
|
118
122
|
if score <= 0:
|
|
119
123
|
continue
|
|
@@ -957,6 +957,73 @@ def run_recon_prefers_hint_root_over_single_route_literal():
|
|
|
957
957
|
shutil.rmtree(tempdir, ignore_errors=True)
|
|
958
958
|
|
|
959
959
|
|
|
960
|
+
def run_capture_hint_rejects_route_specific_mode_only_match():
|
|
961
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-hint-selection-'))
|
|
962
|
+
try:
|
|
963
|
+
util = load_module('util_hint_selection', UTIL_PATH)
|
|
964
|
+
repo_key = str(tempdir / 'repo')
|
|
965
|
+
state = {
|
|
966
|
+
'repo': repo_key,
|
|
967
|
+
'verification_mode': 'text',
|
|
968
|
+
'change_request': 'Change the Tic Tac Toe reset button label to Reset Board.',
|
|
969
|
+
'success_criteria': 'The Tic Tac Toe page shows Reset Board on /games/tic-tac-toe.',
|
|
970
|
+
}
|
|
971
|
+
_, cache_path = util.load_capture_hint_cache(state)
|
|
972
|
+
cache_file = Path(cache_path)
|
|
973
|
+
cache_file.parent.mkdir(parents=True, exist_ok=True)
|
|
974
|
+
cache_file.write_text(json.dumps({
|
|
975
|
+
'version': util.CAPTURE_HINT_CACHE_VERSION,
|
|
976
|
+
'hints': [
|
|
977
|
+
{
|
|
978
|
+
'saved_at': '2026-04-25T00:00:00Z',
|
|
979
|
+
'verification_mode': 'text',
|
|
980
|
+
'request_tokens': ['sequencer', 'monkberry', 'drum'],
|
|
981
|
+
'server_path': '/games/drum-sequencer',
|
|
982
|
+
'wait_for_selector': '.drum-sequencer h1',
|
|
983
|
+
'observed_path': '/games/drum-sequencer',
|
|
984
|
+
}
|
|
985
|
+
],
|
|
986
|
+
}))
|
|
987
|
+
|
|
988
|
+
selected = util.select_capture_hint(state)
|
|
989
|
+
applied = util.apply_capture_hint(state)
|
|
990
|
+
|
|
991
|
+
assert selected is None, selected
|
|
992
|
+
assert applied is None, applied
|
|
993
|
+
assert 'server_path' not in state, state
|
|
994
|
+
|
|
995
|
+
cache_file.write_text(json.dumps({
|
|
996
|
+
'version': util.CAPTURE_HINT_CACHE_VERSION,
|
|
997
|
+
'hints': [
|
|
998
|
+
{
|
|
999
|
+
'saved_at': '2026-04-25T00:00:00Z',
|
|
1000
|
+
'verification_mode': 'text',
|
|
1001
|
+
'request_tokens': ['homepage', 'hero'],
|
|
1002
|
+
'server_path': '/',
|
|
1003
|
+
'wait_for_selector': '',
|
|
1004
|
+
'observed_path': '/',
|
|
1005
|
+
}
|
|
1006
|
+
],
|
|
1007
|
+
}))
|
|
1008
|
+
|
|
1009
|
+
root_state = {
|
|
1010
|
+
'repo': repo_key,
|
|
1011
|
+
'verification_mode': 'text',
|
|
1012
|
+
'change_request': 'Make a tiny harmless copy tweak.',
|
|
1013
|
+
'success_criteria': 'The changed copy is visible.',
|
|
1014
|
+
}
|
|
1015
|
+
root_applied = util.apply_capture_hint(root_state)
|
|
1016
|
+
assert root_applied is not None, root_applied
|
|
1017
|
+
assert root_state['server_path'] == '/', root_state
|
|
1018
|
+
assert root_state['server_path_source'] == 'hint_cache', root_state
|
|
1019
|
+
|
|
1020
|
+
return {'ok': True, 'route_specific_selected': selected, 'root_server_path': root_state['server_path']}
|
|
1021
|
+
finally:
|
|
1022
|
+
if 'cache_file' in locals():
|
|
1023
|
+
cache_file.unlink(missing_ok=True)
|
|
1024
|
+
shutil.rmtree(tempdir, ignore_errors=True)
|
|
1025
|
+
|
|
1026
|
+
|
|
960
1027
|
def run_author_applies_supervisor_packet():
|
|
961
1028
|
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-supervisor-apply-'))
|
|
962
1029
|
state_path = tempdir / 'state.json'
|
|
@@ -1579,6 +1646,42 @@ def run_ship_filters_tool_noise_when_staging():
|
|
|
1579
1646
|
shutil.rmtree(tempdir, ignore_errors=True)
|
|
1580
1647
|
|
|
1581
1648
|
|
|
1649
|
+
def run_ship_preserves_literal_backticks_in_args():
|
|
1650
|
+
sys.modules.pop('util', None)
|
|
1651
|
+
source = SHIP_PATH.read_text()
|
|
1652
|
+
helpers_source = source.split('\ns = load_state()', 1)[0]
|
|
1653
|
+
namespace = {'__file__': str(SHIP_PATH)}
|
|
1654
|
+
exec(compile(helpers_source, str(SHIP_PATH), 'exec'), namespace)
|
|
1655
|
+
|
|
1656
|
+
title = 'Change button from `Start Run` to `Launch Run`'
|
|
1657
|
+
body = 'Proof request keeps `Start Run` and `Launch Run` literal.'
|
|
1658
|
+
args = namespace['gh_pr_create_args'](title, body, 'agent/test-backticks')
|
|
1659
|
+
assert args[0:3] == ['gh', 'pr', 'create'], args
|
|
1660
|
+
assert args[args.index('--title') + 1] == title, args
|
|
1661
|
+
assert args[args.index('--body') + 1] == body, args
|
|
1662
|
+
|
|
1663
|
+
tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-ship-backticks-'))
|
|
1664
|
+
try:
|
|
1665
|
+
sp.run(['git', 'init', '-b', 'main'], cwd=tempdir, check=True, capture_output=True, text=True)
|
|
1666
|
+
sp.run(['git', 'config', 'user.email', 'test@example.com'], cwd=tempdir, check=True)
|
|
1667
|
+
sp.run(['git', 'config', 'user.name', 'Test User'], cwd=tempdir, check=True)
|
|
1668
|
+
(tempdir / 'tracked.txt').write_text('literal backticks\n')
|
|
1669
|
+
sp.run(['git', 'add', 'tracked.txt'], cwd=tempdir, check=True)
|
|
1670
|
+
|
|
1671
|
+
namespace['git_checked'](['commit', '-m', title], str(tempdir))
|
|
1672
|
+
subject = sp.run(
|
|
1673
|
+
['git', 'log', '-1', '--pretty=%s'],
|
|
1674
|
+
cwd=tempdir,
|
|
1675
|
+
check=True,
|
|
1676
|
+
capture_output=True,
|
|
1677
|
+
text=True,
|
|
1678
|
+
).stdout.strip()
|
|
1679
|
+
assert subject == title, subject
|
|
1680
|
+
return {'ok': True, 'subject': subject}
|
|
1681
|
+
finally:
|
|
1682
|
+
shutil.rmtree(tempdir, ignore_errors=True)
|
|
1683
|
+
|
|
1684
|
+
|
|
1582
1685
|
def run_ship_resolves_real_pr_branch():
|
|
1583
1686
|
sys.modules.pop('util', None)
|
|
1584
1687
|
source = SHIP_PATH.read_text()
|
|
@@ -1648,6 +1751,7 @@ if __name__ == '__main__':
|
|
|
1648
1751
|
'recon_preserves_query_route': run_recon_preserves_query_route(),
|
|
1649
1752
|
'recon_route_literal_preference': run_recon_prefers_route_literals_over_import_paths(),
|
|
1650
1753
|
'recon_hint_root_preference': run_recon_prefers_hint_root_over_single_route_literal(),
|
|
1754
|
+
'capture_hint_rejects_route_specific_mode_only_match': run_capture_hint_rejects_route_specific_mode_only_match(),
|
|
1651
1755
|
'author_applies_supervisor_packet': run_author_applies_supervisor_packet(),
|
|
1652
1756
|
'verify_requests_supervisor_assessment': run_verify_requests_supervisor_assessment(),
|
|
1653
1757
|
'verify_structured_evidence_without_screenshot': run_verify_structured_evidence_without_screenshot(),
|
|
@@ -1660,6 +1764,7 @@ if __name__ == '__main__':
|
|
|
1660
1764
|
'ship_structured_after_evidence': run_ship_accepts_structured_after_evidence(),
|
|
1661
1765
|
'ship_discord_thread_target': run_ship_discord_thread_target(),
|
|
1662
1766
|
'ship_filters_tool_noise_when_staging': run_ship_filters_tool_noise_when_staging(),
|
|
1767
|
+
'ship_preserves_literal_backticks_in_args': run_ship_preserves_literal_backticks_in_args(),
|
|
1663
1768
|
'ship_resolves_real_pr_branch': run_ship_resolves_real_pr_branch(),
|
|
1664
1769
|
}
|
|
1665
1770
|
print(json.dumps(payload, indent=2))
|