@riddledc/riddle-proof 0.5.19 → 0.5.20
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/recon.py +60 -1
package/package.json
CHANGED
package/runtime/lib/recon.py
CHANGED
|
@@ -10,7 +10,7 @@ The calling agent owns the planner step between attempts by resuming the workflo
|
|
|
10
10
|
with updated state inputs such as server_path or wait_for_selector.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
import json, os, re, sys
|
|
13
|
+
import json, os, re, sys, time
|
|
14
14
|
from urllib.parse import urlparse
|
|
15
15
|
|
|
16
16
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
@@ -44,6 +44,53 @@ if not after_dir or not os.path.exists(after_dir):
|
|
|
44
44
|
raise SystemExit('after_worktree not found. Run setup first.')
|
|
45
45
|
|
|
46
46
|
|
|
47
|
+
def record_recon_phase(phase, status='running', summary=''):
|
|
48
|
+
global s
|
|
49
|
+
ts = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
|
|
50
|
+
try:
|
|
51
|
+
current = load_state()
|
|
52
|
+
except Exception:
|
|
53
|
+
current = dict(s)
|
|
54
|
+
runtime_step = current.get('current_runtime_step') if isinstance(current.get('current_runtime_step'), dict) else {}
|
|
55
|
+
if not runtime_step:
|
|
56
|
+
runtime_step = {
|
|
57
|
+
'step': 'recon',
|
|
58
|
+
'action': 'run',
|
|
59
|
+
'status': 'running',
|
|
60
|
+
'started_at': ts,
|
|
61
|
+
'workflow_file': 'riddle-proof-recon.lobster',
|
|
62
|
+
}
|
|
63
|
+
runtime_step['step'] = 'recon'
|
|
64
|
+
runtime_step['action'] = 'run'
|
|
65
|
+
runtime_step['status'] = 'running'
|
|
66
|
+
runtime_step['workflow_file'] = 'riddle-proof-recon.lobster'
|
|
67
|
+
runtime_step['phase'] = phase
|
|
68
|
+
runtime_step['phase_status'] = status
|
|
69
|
+
if status == 'running':
|
|
70
|
+
runtime_step['phase_started_at'] = ts
|
|
71
|
+
runtime_step.pop('phase_finished_at', None)
|
|
72
|
+
else:
|
|
73
|
+
runtime_step['phase_finished_at'] = ts
|
|
74
|
+
if summary:
|
|
75
|
+
runtime_step['summary'] = summary
|
|
76
|
+
current['current_runtime_step'] = runtime_step
|
|
77
|
+
events = current.get('runtime_events') if isinstance(current.get('runtime_events'), list) else []
|
|
78
|
+
events.append({
|
|
79
|
+
'ts': ts,
|
|
80
|
+
'kind': 'workflow.phase.' + ('started' if status == 'running' else 'finished'),
|
|
81
|
+
'step': 'recon',
|
|
82
|
+
'phase': phase,
|
|
83
|
+
'summary': summary or (phase + ' ' + status),
|
|
84
|
+
'details': {'status': status},
|
|
85
|
+
})
|
|
86
|
+
current['runtime_events'] = events[-100:]
|
|
87
|
+
current['runtime_updated_at'] = ts
|
|
88
|
+
save_state(current)
|
|
89
|
+
for key in ('current_runtime_step', 'runtime_events', 'runtime_updated_at'):
|
|
90
|
+
if key in current:
|
|
91
|
+
s[key] = current[key]
|
|
92
|
+
|
|
93
|
+
|
|
47
94
|
def run(cmd, cwd, timeout=30):
|
|
48
95
|
return sp.run(cmd, shell=True, cwd=cwd, capture_output=True, text=True, timeout=timeout)
|
|
49
96
|
|
|
@@ -549,10 +596,14 @@ def clean_next_cache(project_dir):
|
|
|
549
596
|
|
|
550
597
|
def build_project(project_dir, label):
|
|
551
598
|
build_cmd = s.get('build_command', 'npm run build')
|
|
599
|
+
phase = label + '_build'
|
|
600
|
+
record_recon_phase(phase, 'running', 'Building ' + label + ' workspace for recon capture.')
|
|
552
601
|
print('Building ' + label + ' workspace...')
|
|
553
602
|
result = sp.run(build_cmd, shell=True, cwd=project_dir, capture_output=True, text=True, timeout=600)
|
|
554
603
|
if result.returncode != 0:
|
|
604
|
+
record_recon_phase(phase, 'failed', label.capitalize() + ' build failed during recon.')
|
|
555
605
|
raise SystemExit(label.capitalize() + ' build failed during recon: ' + result.stderr[:500])
|
|
606
|
+
record_recon_phase(phase, 'completed', label.capitalize() + ' workspace build completed for recon.')
|
|
556
607
|
return {
|
|
557
608
|
'stdout': result.stdout[-500:],
|
|
558
609
|
'stderr': result.stderr[-500:],
|
|
@@ -589,8 +640,11 @@ def capture_workspace_baseline(project_dir, label, plan, capture_script=''):
|
|
|
589
640
|
server_args['wait_for_selector'] = wait_for_selector
|
|
590
641
|
apply_auth_context(s, server_args)
|
|
591
642
|
|
|
643
|
+
capture_phase = label + '_capture'
|
|
644
|
+
record_recon_phase(capture_phase, 'running', 'Capturing ' + label + ' recon baseline evidence.')
|
|
592
645
|
shot = invoke_retry('riddle_server_preview', server_args, retries=2, timeout=420)
|
|
593
646
|
append_capture_diagnostic(s, label, 'riddle_server_preview', server_args, shot)
|
|
647
|
+
record_recon_phase(capture_phase, 'completed', label.capitalize() + ' recon baseline capture completed.')
|
|
594
648
|
return {
|
|
595
649
|
'source': label + '_worktree',
|
|
596
650
|
'mode': 'server',
|
|
@@ -606,6 +660,8 @@ def capture_workspace_baseline(project_dir, label, plan, capture_script=''):
|
|
|
606
660
|
state_for_capture['wait_for_selector'] = wait_for_selector
|
|
607
661
|
if static_reason:
|
|
608
662
|
print('Recon capture (' + label + ') using static preview fallback: ' + static_reason)
|
|
663
|
+
capture_phase = label + '_capture'
|
|
664
|
+
record_recon_phase(capture_phase, 'running', 'Capturing ' + label + ' recon baseline evidence.')
|
|
609
665
|
capture = capture_static_preview(state_for_capture, project_dir, label, build_probe_capture_script(capture_script, label), timeout=300, target_path=target_path)
|
|
610
666
|
raw = (capture.get('raw') or {}).get('capture') or {}
|
|
611
667
|
append_capture_diagnostic(
|
|
@@ -615,6 +671,7 @@ def capture_workspace_baseline(project_dir, label, plan, capture_script=''):
|
|
|
615
671
|
{'target_path': target_path, 'static_fallback_reason': static_reason},
|
|
616
672
|
raw,
|
|
617
673
|
)
|
|
674
|
+
record_recon_phase(capture_phase, 'completed', label.capitalize() + ' recon baseline capture completed.')
|
|
618
675
|
preview_id_key = label + '_preview_id'
|
|
619
676
|
if capture.get('preview_id'):
|
|
620
677
|
s[preview_id_key] = capture.get('preview_id', '')
|
|
@@ -639,8 +696,10 @@ def capture_prod_baseline(prod_url, plan, capture_script=''):
|
|
|
639
696
|
args = {'script': script, 'timeout_sec': 60}
|
|
640
697
|
apply_auth_context(s, args)
|
|
641
698
|
print('Recon capture (prod) at ' + target_url)
|
|
699
|
+
record_recon_phase('prod_capture', 'running', 'Capturing production recon baseline evidence.')
|
|
642
700
|
shot = invoke_retry('riddle_script', args, retries=3, timeout=180)
|
|
643
701
|
append_capture_diagnostic(s, 'prod', 'riddle_script', args, shot)
|
|
702
|
+
record_recon_phase('prod_capture', 'completed', 'Production recon baseline capture completed.')
|
|
644
703
|
return {
|
|
645
704
|
'source': 'prod_url',
|
|
646
705
|
'mode': 'remote',
|