Class: KairosMcp::Daemon::WalPhaseRecorder
- Inherits:
-
Object
- Object
- KairosMcp::Daemon::WalPhaseRecorder
- Defined in:
- lib/kairos_mcp/daemon/wal_phase_recorder.rb
Overview
WalPhaseRecorder — around_phase callback for CognitiveLoop.
Design (v0.2 P3.0):
CognitiveLoop exposes an `around_phase` callback hook. This
recorder records the executing→completed transition in the WAL
around each phase, so a crash anywhere inside the phase leaves
the WAL with a recoverable "executing" marker.
Ordering invariant:
wal.mark_executing(step_id, pre_hash:) # before phase body
result = yield # phase body
wal.mark_completed(step_id, post_hash:, # after phase body
result_hash:)
On exception, the phase is recorded as failed (error_class, error_msg), and the exception is re-raised. Recovery treats failed steps as final (no retry) — a higher-level retry policy is CognitiveLoop’s concern, not the recorder’s.
Step id derivation:
format('%s_%03d', phase, cycle) — mirrors Planner.step_id_for.
Kept duplicated here (not require'd from Planner) to avoid a
runtime dep between recorder and planner: each can be exercised
alone in tests.
Instance Attribute Summary collapse
-
#cycle ⇒ Object
readonly
Returns the value of attribute cycle.
Instance Method Summary collapse
-
#around_phase(phase) ⇒ Object
Wrap a phase body.
-
#initialize(wal:, cycle: 1) ⇒ WalPhaseRecorder
constructor
A new instance of WalPhaseRecorder.
-
#step_id_for(phase) ⇒ Object
Expose step-id derivation so tests can verify recorded ids.
Constructor Details
#initialize(wal:, cycle: 1) ⇒ WalPhaseRecorder
Returns a new instance of WalPhaseRecorder.
32 33 34 35 36 37 |
# File 'lib/kairos_mcp/daemon/wal_phase_recorder.rb', line 32 def initialize(wal:, cycle: 1) raise ArgumentError, 'wal is required' if wal.nil? @wal = wal @cycle = Integer(cycle) end |
Instance Attribute Details
#cycle ⇒ Object (readonly)
Returns the value of attribute cycle.
39 40 41 |
# File 'lib/kairos_mcp/daemon/wal_phase_recorder.rb', line 39 def cycle @cycle end |
Instance Method Details
#around_phase(phase) ⇒ Object
Wrap a phase body. ‘phase` is a Symbol or String (:observe/:orient/:decide/:act/:reflect). Returns the block’s return value on success; re-raises on failure.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/kairos_mcp/daemon/wal_phase_recorder.rb', line 44 def around_phase(phase) step_id = step_id_for(phase) pre_hash = Canonical.sha256_json(marker(phase, 'pre')) @wal.mark_executing(step_id, pre_hash: pre_hash) begin result = block_given? ? yield : nil rescue StandardError => e @wal.mark_failed(step_id, error_class: e.class.name, error_msg: e..to_s) raise end post_hash = Canonical.sha256_json(marker(phase, 'post')) result_hash = Canonical.sha256_json(safe_result(result)) @wal.mark_completed(step_id, post_hash: post_hash, result_hash: result_hash) result end |
#step_id_for(phase) ⇒ Object
Expose step-id derivation so tests can verify recorded ids.
67 68 69 |
# File 'lib/kairos_mcp/daemon/wal_phase_recorder.rb', line 67 def step_id_for(phase) format('%s_%03d', phase.to_s, @cycle) end |