Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [0.2.12] - 2026-06-01
### Fixed
- Archiver no longer hardcodes `current_protocol_level` to 0; runner passes actual protocol state level
- Client options (`@opts`) now merge into every runner call instead of being silently ignored
- Added `reset!` for test isolation; clarified `extend self` + `include` per-instance state behavior
- README `archive_on_escalate` default aligned with actual code default (`true`)

## [0.2.11] - 2026-04-22
### Fixed
- ProtocolMonitor actor now delegates to runner instead of reimplementing a stub that always returned level 0
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ client.full_termination(
```yaml
extinction:
governance_required: true # check lex-governance before full_termination
archive_on_escalate: false # auto-archive at level >= 3
archive_on_escalate: true # auto-archive at level >= 3
stale_threshold_hours: 24 # hours before monitor reports stale protocol state
monitor_interval: 300 # seconds between background monitor ticks
```
Expand Down
30 changes: 30 additions & 0 deletions lib/legion/extensions/extinction/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ module Legion
module Extensions
module Extinction
class Client
# The runner module uses `extend self` which creates both module functions
# (for the runner framework) and instance methods (copied by this include).
# Instance variables (@protocol_state, @archiver) resolve per-Client instance,
# giving each client its own isolated protocol state.
include Runners::Extinction

def initialize(**opts)
Expand All @@ -15,6 +19,32 @@ def initialize(**opts)
def settings
{ options: @opts }
end

# Override runner methods so that per-instance @opts (e.g. timeout:)
# are threaded through as defaults on every call.
def escalate(**)
super(**@opts, **)
end

def deescalate(**)
super(**@opts, **)
end

def extinction_status(**)
super(**@opts, **)
end

def monitor_protocol(**)
super(**@opts, **)
end

def archive_agent(**)
super(**@opts, **)
end

def full_termination(**)
super(**@opts, **)
end
end
end
end
Expand Down
9 changes: 2 additions & 7 deletions lib/legion/extensions/extinction/helpers/archiver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ def initialize
@archives = []
end

def archive(agent_id:, reason:, metadata: {})
level = current_protocol_level
def archive(agent_id:, reason:, metadata: {}, current_level: 0)
record = {
agent_id: agent_id,
reason: reason,
metadata: metadata,
level: level,
level: current_level,
archived_at: Time.now.utc.iso8601,
state_snapshot: capture_state_snapshot
}
Expand All @@ -30,10 +29,6 @@ def all_archives

private

def current_protocol_level
0
end

def capture_state_snapshot
snapshot = {}
snapshot[:mesh_connected] = true if defined?(Legion::Extensions::Mesh)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module Helpers
class ProtocolState
MAX_HISTORY = 500

attr_reader :history
attr_reader :current_level, :history

def initialize
@current_level = 0
Expand Down
9 changes: 8 additions & 1 deletion lib/legion/extensions/extinction/runners/extinction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ def monitor_protocol(**)
end

def archive_agent(agent_id:, reason:, metadata: {}, **)
record = archiver.archive(agent_id: agent_id, reason: reason, metadata: metadata)
record = archiver.archive(agent_id: agent_id, reason: reason, metadata: metadata,
current_level: protocol_state.current_level)
record_audit(action: :archive, details: { agent_id: agent_id, reason: reason })
{ success: true, archive: record }
end
Expand All @@ -84,6 +85,12 @@ def full_termination(agent_id:, authority:, reason:, **)
{ success: true, agent_id: agent_id, archive: archive_result[:archive], terminated_at: Time.now.utc.iso8601 }
end

# Reset internal state for test isolation
def reset!
@protocol_state = nil
@archiver = nil
end

private

def protocol_state
Expand Down
2 changes: 1 addition & 1 deletion lib/legion/extensions/extinction/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Legion
module Extensions
module Extinction
VERSION = '0.2.11'
VERSION = '0.2.12'
end
end
end
Loading