@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.5.19",
3
+ "version": "0.5.20",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",
@@ -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',