Module: Legion::Gaia::BondRegistry

Extended by:
Logging::Helper
Defined in:
lib/legion/gaia/bond_registry.rb

Class Method Summary collapse

Class Method Details

.all_bondsObject



69
70
71
# File 'lib/legion/gaia/bond_registry.rb', line 69

def all_bonds
  @bonds.values
end

.bond(identity) ⇒ Object



45
46
47
48
# File 'lib/legion/gaia/bond_registry.rb', line 45

def bond(identity)
  entry = @bonds[identity.to_s]
  entry ? entry[:bond] : :unknown
end

.channel_identity(identity) ⇒ Object

Returns the channel-native identity for the given principal identity. Falls back to the principal identity itself when no channel_identity was stored. Proactive delivery paths MUST use this method to avoid sending messages to a UUID that channel APIs (Teams, Slack) do not recognize.



58
59
60
61
62
63
# File 'lib/legion/gaia/bond_registry.rb', line 58

def channel_identity(identity)
  entry = @bonds[identity.to_s]
  return nil unless entry

  entry[:channel_identity] || entry[:identity]
end

.hydrate_from_apollo(store: nil) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/legion/gaia/bond_registry.rb', line 104

def hydrate_from_apollo(store: nil)
  return unless store

  result = store.query(text: 'partner', tags: %w[self-knowledge])
  return unless result.is_a?(Hash) && result[:success] && result[:results]&.any?

  result[:results].each do |entry|
    content = entry[:content].to_s
    next unless content.match?(/partner/i)

    identities = extract_identity_keys(content)
    priority = content.match?(/primary/i) ? :primary : :normal
    channel_identity = extract_channel_identity(content)
    preferred_channel = extract_channel(content, 'preferred')
    last_channel = extract_channel(content, 'last')

    identities.each do |id|
      register(id, bond: :partner, priority: priority, channel_identity: channel_identity,
                   preferred_channel: preferred_channel, last_channel: last_channel)
    end
  end
  log.info("BondRegistry hydrated entries=#{result[:results].size}")
rescue StandardError => e
  handle_exception(e, level: :warn, operation: 'gaia.bond_registry.hydrate_from_apollo')
end

.partner?(identity) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/legion/gaia/bond_registry.rb', line 65

def partner?(identity)
  bond(identity) == :partner
end

.partner_entryObject

Returns the single best partner bond entry using deterministic selection:

1. Prefer entries that have an explicit channel_identity stored (ยง9.6 guarantee)
2. Then prefer entries with priority: :primary
3. Otherwise return the earliest-registered entry (sort by :since, then :identity)

Sorting by :since then :identity ensures a stable result regardless of Concurrent::Hash enumeration order, which is not guaranteed.



94
95
96
97
98
99
100
101
102
# File 'lib/legion/gaia/bond_registry.rb', line 94

def partner_entry
  partners = @bonds.values.select { |b| b[:bond] == :partner }
  return nil if partners.empty?

  sorted = partners.sort_by { |b| [b[:since], b[:identity]] }
  sorted.find { |b| b[:channel_identity] } ||
    sorted.find { |b| b[:priority] == :primary } ||
    sorted.first
end

.record_channel(identity, channel_id:, channel_identity: nil) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/legion/gaia/bond_registry.rb', line 73

def record_channel(identity, channel_id:, channel_identity: nil)
  @mutex.synchronize do
    entry = @bonds[identity.to_s]
    return nil unless entry

    channel = channel_id&.to_sym
    updated = entry.merge(
      last_channel: channel || entry[:last_channel],
      preferred_channel: entry[:preferred_channel] || channel,
      channel_identity: entry[:channel_identity] || channel_identity&.to_s
    )
    @bonds[identity.to_s] = updated
  end
end

.register(identity, bond: nil, role: nil, priority: :normal, channel_identity: nil, preferred_channel: nil, last_channel: nil) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/legion/gaia/bond_registry.rb', line 16

def register(identity, bond: nil, role: nil, priority: :normal, channel_identity: nil,
             preferred_channel: nil, last_channel: nil)
  effective_bond = (bond || role || :unknown).to_sym
  @mutex.synchronize do
    @bonds[identity.to_s] = build_entry(
      identity,
      bond: effective_bond,
      priority: priority,
      channel_identity: channel_identity,
      preferred_channel: preferred_channel,
      last_channel: last_channel
    )
  end
  log.info("BondRegistry registered identity=#{identity} bond=#{effective_bond} priority=#{priority}")
end

.reset!Object



130
131
132
133
# File 'lib/legion/gaia/bond_registry.rb', line 130

def reset!
  @mutex.synchronize { @bonds = Concurrent::Hash.new }
  log.debug('BondRegistry reset')
end

.role(identity) ⇒ Object



50
51
52
# File 'lib/legion/gaia/bond_registry.rb', line 50

def role(identity)
  bond(identity)
end