@riddledc/riddle-proof 0.5.18 → 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.
@@ -420,8 +420,31 @@ async function handleImplementation(request, state, result, agent) {
420
420
  }
421
421
  };
422
422
  }
423
+ recordEvent(state, {
424
+ kind: "agent.implementation.started",
425
+ checkpoint: result.checkpoint || null,
426
+ stage: "implement",
427
+ summary: "Implementation agent started working in the after worktree.",
428
+ details: {
429
+ worktree_path: workdir || null
430
+ }
431
+ });
423
432
  const implementation = await agent.implementChange({ ...context, workdir });
424
433
  if (implementation.blocker || implementation.ok === false) {
434
+ recordEvent(state, {
435
+ kind: "agent.implementation.blocked",
436
+ checkpoint: result.checkpoint || null,
437
+ stage: "implement",
438
+ summary: implementation.summary || implementation.blocker?.message || "Implementation adapter reported a blocker.",
439
+ details: compactRecord({
440
+ worktree_path: workdir || null,
441
+ changed_files: implementation.changedFiles || [],
442
+ tests_run: implementation.testsRun || [],
443
+ implementation_notes: implementation.implementationNotes || null,
444
+ blocker: implementation.blocker || null,
445
+ adapter_details: implementation.details || null
446
+ })
447
+ });
425
448
  return {
426
449
  blocker: implementation.blocker || {
427
450
  code: "implementation_blocked",
@@ -433,12 +456,31 @@ async function handleImplementation(request, state, result, agent) {
433
456
  const cleanedArtifacts = removeEmptyToolArtifacts(workdir);
434
457
  const diffDetected = implementation.diffDetected === true || hasGitDiff(workdir);
435
458
  if (!diffDetected) {
459
+ recordEvent(state, {
460
+ kind: "agent.implementation.no_diff",
461
+ checkpoint: result.checkpoint || null,
462
+ stage: "implement",
463
+ summary: implementation.summary || "Implementation adapter returned without leaving a detectable git diff.",
464
+ details: compactRecord({
465
+ worktree_path: workdir || null,
466
+ changed_files: implementation.changedFiles || [],
467
+ tests_run: implementation.testsRun || [],
468
+ implementation_notes: implementation.implementationNotes || null,
469
+ adapter_details: implementation.details || null
470
+ })
471
+ });
436
472
  return {
437
473
  blocker: {
438
474
  code: "implementation_diff_missing",
439
475
  checkpoint: result.checkpoint || null,
440
476
  message: "The implementation adapter returned, but the after worktree has no detectable git diff. The harness will not advance to verify.",
441
- details: { worktree_path: workdir || null }
477
+ details: compactRecord({
478
+ worktree_path: workdir || null,
479
+ changed_files: implementation.changedFiles || [],
480
+ tests_run: implementation.testsRun || [],
481
+ implementation_notes: implementation.implementationNotes || null,
482
+ adapter_details: implementation.details || null
483
+ })
442
484
  }
443
485
  };
444
486
  }
@@ -451,6 +493,9 @@ async function handleImplementation(request, state, result, agent) {
451
493
  worktree_path: workdir || null,
452
494
  diffDetected,
453
495
  changed_files: implementation.changedFiles || [],
496
+ tests_run: implementation.testsRun || [],
497
+ implementation_notes: implementation.implementationNotes || null,
498
+ adapter_details: implementation.details || null,
454
499
  cleaned_artifacts: cleanedArtifacts
455
500
  }
456
501
  });
@@ -3422,8 +3422,31 @@ async function handleImplementation(request, state, result, agent) {
3422
3422
  }
3423
3423
  };
3424
3424
  }
3425
+ recordEvent(state, {
3426
+ kind: "agent.implementation.started",
3427
+ checkpoint: result.checkpoint || null,
3428
+ stage: "implement",
3429
+ summary: "Implementation agent started working in the after worktree.",
3430
+ details: {
3431
+ worktree_path: workdir || null
3432
+ }
3433
+ });
3425
3434
  const implementation = await agent.implementChange({ ...context, workdir });
3426
3435
  if (implementation.blocker || implementation.ok === false) {
3436
+ recordEvent(state, {
3437
+ kind: "agent.implementation.blocked",
3438
+ checkpoint: result.checkpoint || null,
3439
+ stage: "implement",
3440
+ summary: implementation.summary || implementation.blocker?.message || "Implementation adapter reported a blocker.",
3441
+ details: compactRecord({
3442
+ worktree_path: workdir || null,
3443
+ changed_files: implementation.changedFiles || [],
3444
+ tests_run: implementation.testsRun || [],
3445
+ implementation_notes: implementation.implementationNotes || null,
3446
+ blocker: implementation.blocker || null,
3447
+ adapter_details: implementation.details || null
3448
+ })
3449
+ });
3427
3450
  return {
3428
3451
  blocker: implementation.blocker || {
3429
3452
  code: "implementation_blocked",
@@ -3435,12 +3458,31 @@ async function handleImplementation(request, state, result, agent) {
3435
3458
  const cleanedArtifacts = removeEmptyToolArtifacts(workdir);
3436
3459
  const diffDetected = implementation.diffDetected === true || hasGitDiff(workdir);
3437
3460
  if (!diffDetected) {
3461
+ recordEvent(state, {
3462
+ kind: "agent.implementation.no_diff",
3463
+ checkpoint: result.checkpoint || null,
3464
+ stage: "implement",
3465
+ summary: implementation.summary || "Implementation adapter returned without leaving a detectable git diff.",
3466
+ details: compactRecord({
3467
+ worktree_path: workdir || null,
3468
+ changed_files: implementation.changedFiles || [],
3469
+ tests_run: implementation.testsRun || [],
3470
+ implementation_notes: implementation.implementationNotes || null,
3471
+ adapter_details: implementation.details || null
3472
+ })
3473
+ });
3438
3474
  return {
3439
3475
  blocker: {
3440
3476
  code: "implementation_diff_missing",
3441
3477
  checkpoint: result.checkpoint || null,
3442
3478
  message: "The implementation adapter returned, but the after worktree has no detectable git diff. The harness will not advance to verify.",
3443
- details: { worktree_path: workdir || null }
3479
+ details: compactRecord({
3480
+ worktree_path: workdir || null,
3481
+ changed_files: implementation.changedFiles || [],
3482
+ tests_run: implementation.testsRun || [],
3483
+ implementation_notes: implementation.implementationNotes || null,
3484
+ adapter_details: implementation.details || null
3485
+ })
3444
3486
  }
3445
3487
  };
3446
3488
  }
@@ -3453,6 +3495,9 @@ async function handleImplementation(request, state, result, agent) {
3453
3495
  worktree_path: workdir || null,
3454
3496
  diffDetected,
3455
3497
  changed_files: implementation.changedFiles || [],
3498
+ tests_run: implementation.testsRun || [],
3499
+ implementation_notes: implementation.implementationNotes || null,
3500
+ adapter_details: implementation.details || null,
3456
3501
  cleaned_artifacts: cleanedArtifacts
3457
3502
  }
3458
3503
  });
@@ -37,7 +37,9 @@ interface RiddleProofAgentPayload {
37
37
  blocker?: RiddleProofBlocker;
38
38
  diffDetected?: boolean;
39
39
  changedFiles?: string[];
40
+ testsRun?: string[];
40
41
  implementationNotes?: string;
42
+ details?: Record<string, unknown>;
41
43
  }
42
44
  interface RiddleProofEngineHarnessContext {
43
45
  request: RiddleProofRunParams;
@@ -37,7 +37,9 @@ interface RiddleProofAgentPayload {
37
37
  blocker?: RiddleProofBlocker;
38
38
  diffDetected?: boolean;
39
39
  changedFiles?: string[];
40
+ testsRun?: string[];
40
41
  implementationNotes?: string;
42
+ details?: Record<string, unknown>;
41
43
  }
42
44
  interface RiddleProofEngineHarnessContext {
43
45
  request: RiddleProofRunParams;
@@ -2,7 +2,7 @@ import {
2
2
  createDisabledRiddleProofAgentAdapter,
3
3
  readRiddleProofRunStatus,
4
4
  runRiddleProofEngineHarness
5
- } from "./chunk-FVPNG3BA.js";
5
+ } from "./chunk-PJ3RTT5D.js";
6
6
  import "./chunk-7ZJAUEUN.js";
7
7
  import "./chunk-TMMKRKY5.js";
8
8
  export {
package/dist/index.cjs CHANGED
@@ -3978,8 +3978,31 @@ async function handleImplementation(request, state, result, agent) {
3978
3978
  }
3979
3979
  };
3980
3980
  }
3981
+ recordEvent(state, {
3982
+ kind: "agent.implementation.started",
3983
+ checkpoint: result.checkpoint || null,
3984
+ stage: "implement",
3985
+ summary: "Implementation agent started working in the after worktree.",
3986
+ details: {
3987
+ worktree_path: workdir || null
3988
+ }
3989
+ });
3981
3990
  const implementation = await agent.implementChange({ ...context, workdir });
3982
3991
  if (implementation.blocker || implementation.ok === false) {
3992
+ recordEvent(state, {
3993
+ kind: "agent.implementation.blocked",
3994
+ checkpoint: result.checkpoint || null,
3995
+ stage: "implement",
3996
+ summary: implementation.summary || implementation.blocker?.message || "Implementation adapter reported a blocker.",
3997
+ details: compactRecord({
3998
+ worktree_path: workdir || null,
3999
+ changed_files: implementation.changedFiles || [],
4000
+ tests_run: implementation.testsRun || [],
4001
+ implementation_notes: implementation.implementationNotes || null,
4002
+ blocker: implementation.blocker || null,
4003
+ adapter_details: implementation.details || null
4004
+ })
4005
+ });
3983
4006
  return {
3984
4007
  blocker: implementation.blocker || {
3985
4008
  code: "implementation_blocked",
@@ -3991,12 +4014,31 @@ async function handleImplementation(request, state, result, agent) {
3991
4014
  const cleanedArtifacts = removeEmptyToolArtifacts(workdir);
3992
4015
  const diffDetected = implementation.diffDetected === true || hasGitDiff(workdir);
3993
4016
  if (!diffDetected) {
4017
+ recordEvent(state, {
4018
+ kind: "agent.implementation.no_diff",
4019
+ checkpoint: result.checkpoint || null,
4020
+ stage: "implement",
4021
+ summary: implementation.summary || "Implementation adapter returned without leaving a detectable git diff.",
4022
+ details: compactRecord({
4023
+ worktree_path: workdir || null,
4024
+ changed_files: implementation.changedFiles || [],
4025
+ tests_run: implementation.testsRun || [],
4026
+ implementation_notes: implementation.implementationNotes || null,
4027
+ adapter_details: implementation.details || null
4028
+ })
4029
+ });
3994
4030
  return {
3995
4031
  blocker: {
3996
4032
  code: "implementation_diff_missing",
3997
4033
  checkpoint: result.checkpoint || null,
3998
4034
  message: "The implementation adapter returned, but the after worktree has no detectable git diff. The harness will not advance to verify.",
3999
- details: { worktree_path: workdir || null }
4035
+ details: compactRecord({
4036
+ worktree_path: workdir || null,
4037
+ changed_files: implementation.changedFiles || [],
4038
+ tests_run: implementation.testsRun || [],
4039
+ implementation_notes: implementation.implementationNotes || null,
4040
+ adapter_details: implementation.details || null
4041
+ })
4000
4042
  }
4001
4043
  };
4002
4044
  }
@@ -4009,6 +4051,9 @@ async function handleImplementation(request, state, result, agent) {
4009
4051
  worktree_path: workdir || null,
4010
4052
  diffDetected,
4011
4053
  changed_files: implementation.changedFiles || [],
4054
+ tests_run: implementation.testsRun || [],
4055
+ implementation_notes: implementation.implementationNotes || null,
4056
+ adapter_details: implementation.details || null,
4012
4057
  cleaned_artifacts: cleanedArtifacts
4013
4058
  }
4014
4059
  });
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  createDisabledRiddleProofAgentAdapter,
14
14
  readRiddleProofRunStatus,
15
15
  runRiddleProofEngineHarness
16
- } from "./chunk-FVPNG3BA.js";
16
+ } from "./chunk-PJ3RTT5D.js";
17
17
  import {
18
18
  runRiddleProof
19
19
  } from "./chunk-F6VFKS7K.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.5.18",
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',