Class: OllamaAgent::Runtime::RollbackSignals
- Inherits:
-
Object
- Object
- OllamaAgent::Runtime::RollbackSignals
- Defined in:
- lib/ollama_agent/runtime/rollback_signals.rb
Overview
In-memory rolling-window counters for operator rollback heuristics (no persistence).
Constant Summary collapse
- DEFAULT_THRESHOLDS =
{ replay_determinism_violations_per_min: 1, recovery_duplicates_per_min: 1, mutation_failure_rate: 0.1, validator_integrity_mismatches_per_min: 1 }.freeze
- WINDOW_TICKS =
60- VALID_EVENTS =
%i[ replay_determinism_violation recovery_duplicate mutation_failure mutation_success validator_integrity_mismatch ].freeze
Instance Method Summary collapse
-
#initialize(thresholds: {}) ⇒ RollbackSignals
constructor
A new instance of RollbackSignals.
- #record(event:, payload: {}) ⇒ Object
-
#should_rollback? ⇒ Hash
rubocop:disable Naming/PredicateMethod, Metrics/MethodLength, Metrics/AbcSize – operator-facing query name + explicit thresholds.
-
#tick(epoch:) ⇒ Object
Advance logical epoch and evict samples older than the 60-tick window.
Constructor Details
#initialize(thresholds: {}) ⇒ RollbackSignals
Returns a new instance of RollbackSignals.
25 26 27 28 29 30 |
# File 'lib/ollama_agent/runtime/rollback_signals.rb', line 25 def initialize(thresholds: {}) @thresholds = DEFAULT_THRESHOLDS.merge(thresholds.transform_keys(&:to_sym)) @current_epoch = 0 @rows = [] @mutex = Mutex.new end |
Instance Method Details
#record(event:, payload: {}) ⇒ Object
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/ollama_agent/runtime/rollback_signals.rb', line 34 def record(event:, payload: {}) sym = event.to_sym raise ArgumentError, "unknown rollback signal #{sym.inspect}" unless VALID_EVENTS.include?(sym) @mutex.synchronize do epoch = (payload[:epoch] || payload["epoch"] || @current_epoch).to_i @rows << { epoch: epoch, event: sym, ts_wall: Time.now.to_f } prune_unlocked! end end |
#should_rollback? ⇒ Hash
rubocop:disable Naming/PredicateMethod, Metrics/MethodLength, Metrics/AbcSize – operator-facing query name + explicit thresholds
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/ollama_agent/runtime/rollback_signals.rb', line 55 def should_rollback? snap = @mutex.synchronize { @rows.dup } reasons = [] t = @thresholds reasons << "replay_determinism_violation threshold breached" if count_event(snap, :replay_determinism_violation) >= t[:replay_determinism_violations_per_min] reasons << "recovery_duplicate threshold breached" if count_event(snap, :recovery_duplicate) >= t[:recovery_duplicates_per_min] reasons << "validator_integrity_mismatch threshold breached" if count_event(snap, :validator_integrity_mismatch) >= t[:validator_integrity_mismatches_per_min] mf = count_event(snap, :mutation_failure) ms = count_event(snap, :mutation_success) total = mf + ms reasons << "mutation_failure_rate threshold breached" if total.positive? && (mf.to_f / total) >= t[:mutation_failure_rate].to_f { trigger: reasons.any?, reasons: reasons } end |
#tick(epoch:) ⇒ Object
Advance logical epoch and evict samples older than the 60-tick window.
46 47 48 49 50 51 |
# File 'lib/ollama_agent/runtime/rollback_signals.rb', line 46 def tick(epoch:) @mutex.synchronize do @current_epoch = epoch.to_i prune_unlocked! end end |