lex-mesh 0.4.1 → 0.4.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30d95d61132596e1638e9855fb045f20a7b9b0285c63c35766a9e07c776c78d2
4
- data.tar.gz: 1e8c6704b51f98cc9c768bd5798b3634badb6491e542a022f75c612a5165aa6a
3
+ metadata.gz: edbe1f87a3c1b6cad5d87f2ee8c1b04551b9bbd36804c7d4f71ed18f9833f58e
4
+ data.tar.gz: 50f43be7cffacaa7b23e316d2f69a1763a2b82a7437f7d1e854e4f5cd088bc3e
5
5
  SHA512:
6
- metadata.gz: 7a82cf01be6f79a4c81092f4d5b56fe902e6e6ac933b7dd14fca4b5169ea2aac20a310eb056ced5bc36f0240800ebcc9cfcb5f6d2e6d835606080f969cfb07ca
7
- data.tar.gz: a4d0cffdfc0177c59f7899caa8b65fca7c2359e9085903f3fb60b77eb2d7ee2a690aac20ac1c5a71a0ec072bfa10baf6265c3ea697b78fd6b9a454cd93c007f1
6
+ metadata.gz: d14a5e8b04963df9a79bdc216c27c669330801c2d0677299908a15cbf2abd125b2e841a245a678823c6c9efab9b83c13e7b0d35b230ae0ba13ddbc42c0e152fc
7
+ data.tar.gz: fe99ad0868788b91826c3bfa25dbbaa131e63b471b409e9ae110c4296bb2af8f44a366939331fff63f9358b6d49e1f513bc268aaf3f2c6c00ac530791c4a4060
data/Gemfile CHANGED
@@ -8,3 +8,4 @@ gem 'base64'
8
8
  gem 'ed25519', '~> 1.3'
9
9
  gem 'rspec', '~> 3.13'
10
10
  gem 'rubocop', '~> 1.75', require: false
11
+ gem 'rubocop-legion', '~> 0.1'
@@ -6,7 +6,7 @@ module Legion
6
6
  module Extensions
7
7
  module Mesh
8
8
  module Actor
9
- class Gossip < Legion::Extensions::Actors::Every
9
+ class Gossip < Legion::Extensions::Actors::Every # rubocop:disable Legion/Extension/EveryActorRequiresTime
10
10
  def runner_class
11
11
  Legion::Extensions::Mesh::Runners::Mesh
12
12
  end
@@ -6,7 +6,7 @@ module Legion
6
6
  module Extensions
7
7
  module Mesh
8
8
  module Actor
9
- class Heartbeat < Legion::Extensions::Actors::Every
9
+ class Heartbeat < Legion::Extensions::Actors::Every # rubocop:disable Legion/Extension/EveryActorRequiresTime
10
10
  def runner_class
11
11
  Legion::Extensions::Mesh::Runners::Mesh
12
12
  end
@@ -6,7 +6,7 @@ module Legion
6
6
  module Extensions
7
7
  module Mesh
8
8
  module Actor
9
- class PendingExpiry < Legion::Extensions::Actors::Every
9
+ class PendingExpiry < Legion::Extensions::Actors::Every # rubocop:disable Legion/Extension/EveryActorRequiresTime
10
10
  def runner_class
11
11
  Legion::Extensions::Mesh::Runners::Preferences
12
12
  end
@@ -31,10 +31,10 @@ module Legion
31
31
  Legion::Extensions::Mesh::Transport::Queues::Preference
32
32
  end
33
33
 
34
- def enabled?
34
+ def enabled? # rubocop:disable Legion/Extension/ActorEnabledSideEffects
35
35
  defined?(Legion::Extensions::Mesh::Runners::Preferences) &&
36
- defined?(Legion::Transport)
37
- rescue StandardError
36
+ Legion.const_defined?(:Transport, false)
37
+ rescue StandardError => _e
38
38
  false
39
39
  end
40
40
  end
@@ -6,7 +6,7 @@ module Legion
6
6
  module Extensions
7
7
  module Mesh
8
8
  module Actor
9
- class SilenceWatchdog < Legion::Extensions::Actors::Every
9
+ class SilenceWatchdog < Legion::Extensions::Actors::Every # rubocop:disable Legion/Extension/EveryActorRequiresTime
10
10
  def runner_class
11
11
  Legion::Extensions::Mesh::Runners::Mesh
12
12
  end
@@ -20,7 +20,7 @@ module Legion
20
20
 
21
21
  def initialize(**opts)
22
22
  @opts = opts
23
- @mesh_registry = Helpers::Registry.new
23
+ @mesh_registry = Helpers::Registry.new # rubocop:disable Legion/Singleton/UseInstance
24
24
  end
25
25
 
26
26
  private
@@ -21,21 +21,21 @@ module Legion
21
21
  return { valid: false, org_id: org_id, reason: :unknown_peer } unless peer
22
22
 
23
23
  require 'ed25519'
24
- pub_key_b64 = peer[:public_key].sub(/\Aed25519:/, '')
24
+ pub_key_b64 = peer[:public_key].delete_prefix('ed25519:')
25
25
  verify_key = Ed25519::VerifyKey.new(Base64.strict_decode64(pub_key_b64))
26
26
  signature = Base64.strict_decode64(signed_message[:signature])
27
27
  message_bytes = signed_message[:signed_bytes] || json_dump(signed_message[:payload])
28
28
  verify_key.verify(signature, message_bytes)
29
29
  { valid: true, org_id: org_id }
30
- rescue Ed25519::VerifyError
30
+ rescue Ed25519::VerifyError => _e
31
31
  { valid: false, org_id: org_id, reason: :invalid_signature }
32
32
  rescue StandardError => e
33
33
  { valid: false, org_id: org_id, reason: :error, message: e.message }
34
34
  end
35
35
 
36
36
  def check_rate_limit(org_id)
37
- @counters ||= Hash.new { |h, k| h[k] = { count: 0, window_start: Time.now.utc } }
38
- counter = @counters[org_id]
37
+ @counters ||= Hash.new { |h, k| h[k] = { count: 0, window_start: Time.now.utc } } # rubocop:disable ThreadSafety/ClassInstanceVariable
38
+ counter = @counters[org_id] # rubocop:disable ThreadSafety/ClassInstanceVariable
39
39
  peer = find_peer(org_id)
40
40
  limit = peer&.dig(:rate_limit) || 100
41
41
 
@@ -51,7 +51,7 @@ module Legion
51
51
  end
52
52
 
53
53
  def reset_counters!
54
- @counters = nil
54
+ @counters = nil # rubocop:disable ThreadSafety/ClassInstanceVariable
55
55
  end
56
56
 
57
57
  private
@@ -65,7 +65,7 @@ module Legion
65
65
 
66
66
  def json_dump(data)
67
67
  if defined?(Legion::JSON)
68
- Legion::JSON.dump({ data: data })
68
+ Legion::JSON.dump({ data: data }) # rubocop:disable Legion/HelperMigration/DirectJson
69
69
  else
70
70
  require 'json'
71
71
  ::JSON.dump({ data: data })
@@ -21,7 +21,7 @@ module Legion
21
21
  end
22
22
  end
23
23
 
24
- def resolve(correlation_id:, result:) # rubocop:disable Naming/PredicateMethod
24
+ def resolve(correlation_id:, result:)
25
25
  entry = @mutex.synchronize { @requests.delete(correlation_id) }
26
26
  return false unless entry
27
27
 
@@ -124,8 +124,8 @@ module Legion
124
124
  MESH_CACHE_TTL = 3600 # 1 hour default
125
125
 
126
126
  def store_mesh_profile(agent_id:, profile:, source_agent_id:)
127
- @mesh_cache ||= {}
128
- @mesh_cache[agent_id.to_s] = {
127
+ @mesh_cache ||= {} # rubocop:disable ThreadSafety/ClassInstanceVariable
128
+ @mesh_cache[agent_id.to_s] = { # rubocop:disable ThreadSafety/ClassInstanceVariable
129
129
  profile: profile,
130
130
  source_agent_id: source_agent_id,
131
131
  origin: :mesh_transfer,
@@ -147,26 +147,26 @@ module Legion
147
147
  end
148
148
 
149
149
  def cached_mesh_profile(agent_id:, ttl: MESH_CACHE_TTL)
150
- @mesh_cache ||= {}
151
- entry = @mesh_cache[agent_id.to_s]
150
+ @mesh_cache ||= {} # rubocop:disable ThreadSafety/ClassInstanceVariable
151
+ entry = @mesh_cache[agent_id.to_s] # rubocop:disable ThreadSafety/ClassInstanceVariable
152
152
  return nil unless entry
153
153
 
154
154
  if Time.now - entry[:cached_at] > ttl
155
- @mesh_cache.delete(agent_id.to_s)
155
+ @mesh_cache.delete(agent_id.to_s) # rubocop:disable ThreadSafety/ClassInstanceVariable
156
156
  return nil
157
157
  end
158
158
 
159
159
  entry[:profile]
160
- rescue StandardError
160
+ rescue StandardError => _e
161
161
  nil
162
162
  end
163
163
 
164
164
  def clear_mesh_cache(agent_id: nil)
165
- @mesh_cache ||= {}
165
+ @mesh_cache ||= {} # rubocop:disable ThreadSafety/ClassInstanceVariable
166
166
  if agent_id
167
- @mesh_cache.delete(agent_id.to_s)
167
+ @mesh_cache.delete(agent_id.to_s) # rubocop:disable ThreadSafety/ClassInstanceVariable
168
168
  else
169
- @mesh_cache.clear
169
+ @mesh_cache.clear # rubocop:disable ThreadSafety/ClassInstanceVariable
170
170
  end
171
171
  end
172
172
 
@@ -214,7 +214,7 @@ module Legion
214
214
  traces.select { |t| t[:domain_tags]&.include?('preference') }.filter_map do |trace|
215
215
  parse_preference_trace(trace)
216
216
  end
217
- rescue StandardError
217
+ rescue StandardError => _e
218
218
  []
219
219
  end
220
220
 
@@ -226,7 +226,7 @@ module Legion
226
226
  return nil unless match
227
227
 
228
228
  { domain: match[1], value: match[2], source: match[3], confidence: trace[:confidence] }
229
- rescue StandardError
229
+ rescue StandardError => _e
230
230
  nil
231
231
  end
232
232
 
@@ -239,7 +239,7 @@ module Legion
239
239
  )
240
240
  result = personality_runner.personality_compatibility(other_profile: profile[:personality])
241
241
  { score: result[:compatibility], interpretation: result[:interpretation] }
242
- rescue StandardError
242
+ rescue StandardError => _e
243
243
  nil
244
244
  end
245
245
 
@@ -103,7 +103,7 @@ module Legion
103
103
 
104
104
  def local_node_name
105
105
  Legion::Settings[:client][:name]
106
- rescue StandardError
106
+ rescue StandardError => _e
107
107
  'unknown'
108
108
  end
109
109
  end
@@ -5,8 +5,8 @@ module Legion
5
5
  module Mesh
6
6
  module Runners
7
7
  module Mesh
8
- include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
9
- Legion::Extensions::Helpers.const_defined?(:Lex)
8
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
9
+ Legion::Extensions::Helpers.const_defined?(:Lex, false)
10
10
 
11
11
  def register(agent_id:, capabilities: [], endpoint: nil, **)
12
12
  mesh_registry.register_agent(agent_id, capabilities: capabilities, endpoint: endpoint)
@@ -134,18 +134,18 @@ module Legion
134
134
  def gossip_max_peers
135
135
  settings = Legion::Settings.dig(:mesh, :gossip)
136
136
  (settings.is_a?(Hash) ? settings[:max_peers_per_message] : nil) || 100
137
- rescue StandardError
137
+ rescue StandardError => _e
138
138
  100
139
139
  end
140
140
 
141
141
  def local_node_name
142
142
  Legion::Settings[:client][:name]
143
- rescue StandardError
143
+ rescue StandardError => _e
144
144
  'unknown'
145
145
  end
146
146
 
147
147
  def mesh_registry
148
- @mesh_registry ||= Helpers::Registry.new
148
+ @mesh_registry ||= Helpers::Registry.new # rubocop:disable Legion/Singleton/UseInstance
149
149
  end
150
150
  end
151
151
  end
@@ -7,8 +7,8 @@ module Legion
7
7
  module Mesh
8
8
  module Runners
9
9
  module Preferences
10
- include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
11
- Legion::Extensions::Helpers.const_defined?(:Lex)
10
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
11
+ Legion::Extensions::Helpers.const_defined?(:Lex, false)
12
12
 
13
13
  def query_preferences(target_agent_id:, domains: nil, callback: nil, ttl: 5, **)
14
14
  default_profile = Helpers::PreferenceProfile.resolve(owner_id: target_agent_id)
@@ -96,7 +96,7 @@ module Legion
96
96
  else
97
97
  'unknown'
98
98
  end
99
- rescue StandardError
99
+ rescue StandardError => _e
100
100
  'unknown'
101
101
  end
102
102
 
@@ -110,7 +110,7 @@ module Legion
110
110
  correlation_id: msg[:correlation_id]
111
111
  ).publish
112
112
  rescue StandardError => e
113
- log_debug("[mesh] failed to publish preference response: #{e.message}")
113
+ log.debug("[mesh] failed to publish preference response: #{e.message}")
114
114
  end
115
115
 
116
116
  def publish_preference_query(target_agent_id:, correlation_id:, domains:)
@@ -125,7 +125,7 @@ module Legion
125
125
 
126
126
  def default_preference_callback(target_agent_id:)
127
127
  lambda do |_profile|
128
- log_debug("[mesh] received and cached preferences for #{target_agent_id}")
128
+ log.debug("[mesh] received and cached preferences for #{target_agent_id}")
129
129
  end
130
130
  end
131
131
 
@@ -138,11 +138,11 @@ module Legion
138
138
  evaluator = Object.new.extend(trust_mod)
139
139
  result = evaluator.get_trust(agent_id: agent_id, domain: :general)
140
140
 
141
- return :allowed unless result[:found]
141
+ return :allowed unless result[:found] # rubocop:disable Legion/Extension/RunnerReturnHash
142
142
 
143
143
  composite = result.dig(:trust, :composite) || 0.0
144
144
  composite >= Helpers::Topology::TRUST_CONSIDER_THRESHOLD ? :allowed : :denied
145
- rescue StandardError
145
+ rescue StandardError => _e
146
146
  :allowed
147
147
  end
148
148
 
@@ -10,7 +10,7 @@ module Legion
10
10
  module Extensions
11
11
  module Mesh
12
12
  module Runners
13
- module TaskRequest
13
+ module TaskRequest # rubocop:disable Legion/Extension/RunnerIncludeHelpers
14
14
  include Runners::Mesh
15
15
 
16
16
  DEFAULT_TIMEOUT = 30
@@ -65,10 +65,10 @@ module Legion
65
65
  private
66
66
 
67
67
  def resolve_target(to)
68
- return to if mesh_registry.agents.key?(to)
68
+ return to if mesh_registry.agents.key?(to) # rubocop:disable Legion/Extension/RunnerReturnHash
69
69
 
70
70
  agents = mesh_registry.find_by_capability(to.to_sym)
71
- return nil if agents.empty?
71
+ return nil if agents.empty? # rubocop:disable Legion/Extension/RunnerReturnHash
72
72
 
73
73
  online = agents.select { |a| a[:status] == :online }
74
74
  (online.empty? ? agents : online).sample[:agent_id]
@@ -3,7 +3,7 @@
3
3
  module Legion
4
4
  module Extensions
5
5
  module Mesh
6
- VERSION = '0.4.1'
6
+ VERSION = '0.4.2'
7
7
  end
8
8
  end
9
9
  end
@@ -12,7 +12,7 @@ require 'legion/extensions/mesh/runners/preferences'
12
12
  require 'legion/extensions/mesh/runners/delegation'
13
13
  require 'legion/extensions/mesh/runners/task_request'
14
14
 
15
- if defined?(Legion::Transport)
15
+ if Legion.const_defined?(:Transport, false)
16
16
  require 'legion/extensions/mesh/transport/messages/preference_query'
17
17
  require 'legion/extensions/mesh/transport/messages/preference_response'
18
18
  require 'legion/extensions/mesh/transport/messages/mesh_departure'
@@ -22,7 +22,7 @@ end
22
22
  module Legion
23
23
  module Extensions
24
24
  module Mesh
25
- extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
25
+ extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core, false
26
26
  end
27
27
  end
28
28
  end
@@ -7,7 +7,7 @@ RSpec.describe 'Gossip runner methods' do
7
7
 
8
8
  before do
9
9
  allow(subject).to receive(:mesh_registry).and_return(
10
- Legion::Extensions::Mesh::Helpers::Registry.new
10
+ Legion::Extensions::Mesh::Helpers::Registry.new # rubocop:disable Legion/Singleton/UseInstance
11
11
  )
12
12
  end
13
13
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-mesh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity