lex-agentic-self 0.1.6 → 0.1.7

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.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/lex-agentic-self.gemspec +1 -0
  4. data/lib/legion/extensions/agentic/self/anosognosia/runners/anosognosia.rb +2 -2
  5. data/lib/legion/extensions/agentic/self/default_mode_network/runners/default_mode_network.rb +2 -2
  6. data/lib/legion/extensions/agentic/self/fingerprint/runners/cognitive_fingerprint.rb +2 -2
  7. data/lib/legion/extensions/agentic/self/identity/actors/credential_refresh.rb +2 -2
  8. data/lib/legion/extensions/agentic/self/identity/actors/orphan_check.rb +2 -2
  9. data/lib/legion/extensions/agentic/self/identity/helpers/fingerprint.rb +5 -5
  10. data/lib/legion/extensions/agentic/self/identity/helpers/vault_secrets.rb +2 -2
  11. data/lib/legion/extensions/agentic/self/identity/runners/entra.rb +2 -2
  12. data/lib/legion/extensions/agentic/self/identity/runners/identity.rb +2 -2
  13. data/lib/legion/extensions/agentic/self/metacognition/helpers/self_model.rb +3 -3
  14. data/lib/legion/extensions/agentic/self/metacognition/runners/metacognition.rb +2 -2
  15. data/lib/legion/extensions/agentic/self/metacognition/runners/registry.rb +2 -2
  16. data/lib/legion/extensions/agentic/self/metacognitive_monitoring/helpers/calibration_tracker.rb +1 -1
  17. data/lib/legion/extensions/agentic/self/metacognitive_monitoring/runners/metacognitive_monitoring.rb +2 -2
  18. data/lib/legion/extensions/agentic/self/narrative_arc/runners/narrative.rb +2 -2
  19. data/lib/legion/extensions/agentic/self/narrative_self/runners/narrative_self.rb +2 -2
  20. data/lib/legion/extensions/agentic/self/personality/helpers/trait_model.rb +1 -1
  21. data/lib/legion/extensions/agentic/self/reflection/helpers/llm_enhancer.rb +4 -4
  22. data/lib/legion/extensions/agentic/self/reflection/runners/reflection.rb +2 -2
  23. data/lib/legion/extensions/agentic/self/self_talk/helpers/llm_enhancer.rb +2 -2
  24. data/lib/legion/extensions/agentic/self/self_talk/runners/self_talk.rb +2 -2
  25. data/lib/legion/extensions/agentic/self/version.rb +1 -1
  26. data/lib/legion/extensions/agentic/self.rb +1 -1
  27. data/spec/legion/extensions/agentic/self/default_mode_network/helpers/dmn_engine_spec.rb +2 -2
  28. data/spec/legion/extensions/agentic/self/metacognition/helpers/registry_store_spec.rb +2 -2
  29. metadata +15 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b1a6259c4a8d39317efcde2411a00f23884be106262ed5f92c354e4598c8d2b
4
- data.tar.gz: d03715d7c3350c7fcbe6320fa1e7695cb9e645a5baa0d936e375380de241fba7
3
+ metadata.gz: a2d4ca650c6d9e1d883d1d059bc26b7bbe0444fbce02dae2088006734fa200fc
4
+ data.tar.gz: 2c58a7bb28ca2b0f5a69a65f3cce6b4d76b472b88414b4c06dde4c369c17b4b8
5
5
  SHA512:
6
- metadata.gz: 8cc4b8d492e1f3fc6ee1ee504016951ee023ddb44917b529b5e1dd42b159e7d197514193d9ec56202d0f785041a336d3dc6bd000f0cb7c92e8c418fed61dd750
7
- data.tar.gz: a6412d86c32ec2cfaa0b2754ca7962afc6fdf32a93ca667351ee79024e8872be9967e36ca64159d3a02ab586142c31eab6e6f24b9d12be7256a092c48bc3cb41
6
+ metadata.gz: e9944a49735cf91c810c59d62233029f47f953714ac9854c18229b85b18f816b8f5dc441024e1c6778e663d3979b7c59afd889535903c1641dbc5b7267b69ffc
7
+ data.tar.gz: 0d6ae8a1aa86bcdf47d015c8174e74c148c15598fdb1fba6b30fe3ca15f1aa2c06620f67477a20aadaa1d37de707feebbb0c857c18e07defe46d7e677aa36557
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.7] - 2026-03-30
4
+
5
+ ### Changed
6
+ - update to rubocop-legion 0.1.7, resolve all offenses
7
+
3
8
  ## [0.1.6] - 2026-03-26
4
9
 
5
10
  ### Changed
@@ -35,5 +35,6 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency 'faraday', '~> 2.0'
36
36
  spec.add_development_dependency 'rspec', '~> 3.13'
37
37
  spec.add_development_dependency 'rubocop', '~> 1.60'
38
+ spec.add_development_dependency 'rubocop-legion', '~> 0.1'
38
39
  spec.add_development_dependency 'rubocop-rspec', '~> 2.26'
39
40
  end
@@ -7,8 +7,8 @@ module Legion
7
7
  module Anosognosia
8
8
  module Runners
9
9
  module Anosognosia
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 register_deficit(domain:, deficit_type:, severity:, acknowledged: false, **)
14
14
  deficit = engine.register_deficit(
@@ -7,8 +7,8 @@ module Legion
7
7
  module DefaultModeNetwork
8
8
  module Runners
9
9
  module DefaultModeNetwork
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 register_external_stimulus(source: nil, **)
14
14
  log.debug "[dmn] register_stimulus: source=#{source}"
@@ -7,8 +7,8 @@ module Legion
7
7
  module Fingerprint
8
8
  module Runners
9
9
  module CognitiveFingerprint
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 record_observation(category:, value:, **)
14
14
  category = category.to_sym
@@ -23,9 +23,9 @@ module Legion
23
23
  CREDENTIAL_REFRESH_INTERVAL
24
24
  end
25
25
 
26
- def enabled?
26
+ def enabled? # rubocop:disable Legion/Extension/ActorEnabledSideEffects
27
27
  defined?(Legion::Data) && Legion::Settings[:data][:connected] != false
28
- rescue StandardError
28
+ rescue StandardError => _e
29
29
  false
30
30
  end
31
31
 
@@ -26,9 +26,9 @@ module Legion
26
26
  ORPHAN_CHECK_INTERVAL
27
27
  end
28
28
 
29
- def enabled?
29
+ def enabled? # rubocop:disable Legion/Extension/ActorEnabledSideEffects
30
30
  defined?(Legion::Data) && Legion::Settings[:data][:connected] != false
31
- rescue StandardError
31
+ rescue StandardError => _e
32
32
  false
33
33
  end
34
34
 
@@ -87,7 +87,7 @@ module Legion
87
87
  def save_to_local
88
88
  return unless local_available?
89
89
 
90
- db = Legion::Data::Local.connection
90
+ db = local_data_connection
91
91
 
92
92
  @model.each do |dimension, data|
93
93
  existing = db[:identity_fingerprint].where(dimension: dimension.to_s).first
@@ -121,14 +121,14 @@ module Legion
121
121
 
122
122
  true
123
123
  rescue StandardError => e
124
- Legion::Logging.warn "lex-identity: save_to_local failed: #{e.message}" if defined?(Legion::Logging)
124
+ Legion::Logging.warn "lex-identity: save_to_local failed: #{e.message}"
125
125
  false
126
126
  end
127
127
 
128
128
  def load_from_local
129
129
  return unless local_available?
130
130
 
131
- db = Legion::Data::Local.connection
131
+ db = local_data_connection
132
132
 
133
133
  db[:identity_fingerprint].each do |row|
134
134
  dim = row[:dimension].to_sym
@@ -152,14 +152,14 @@ module Legion
152
152
 
153
153
  true
154
154
  rescue StandardError => e
155
- Legion::Logging.warn "lex-identity: load_from_local failed: #{e.message}" if defined?(Legion::Logging)
155
+ Legion::Logging.warn "lex-identity: load_from_local failed: #{e.message}"
156
156
  false
157
157
  end
158
158
 
159
159
  private
160
160
 
161
161
  def local_available?
162
- defined?(Legion::Data::Local) && Legion::Data::Local.connected?
162
+ defined?(Legion::Data::Local) && local_data_connected?
163
163
  end
164
164
  end
165
165
  end
@@ -29,7 +29,7 @@ module Legion
29
29
  data = { client_secret: client_secret }
30
30
  data[:entra_app_id] = entra_app_id if entra_app_id
31
31
 
32
- Legion::Crypt.write(path, data)
32
+ vault_write(path, data)
33
33
  Legion::Logging.info "[identity:vault] stored Entra credentials for worker=#{worker_id}"
34
34
  true
35
35
  rescue StandardError => e
@@ -68,7 +68,7 @@ module Legion
68
68
  defined?(Legion::Crypt) &&
69
69
  defined?(Legion::Settings) &&
70
70
  Legion::Settings[:crypt][:vault][:connected] == true
71
- rescue StandardError
71
+ rescue StandardError => _e
72
72
  false
73
73
  end
74
74
  end
@@ -15,7 +15,7 @@ module Legion
15
15
  # - OIDC token validation uses the public JWKS endpoint (no special permission)
16
16
  # - Write operations (transfer ownership, disable apps) update the Legion DB
17
17
  # and emit events; the human completes the Entra side manually
18
- module Entra
18
+ module Entra # rubocop:disable Legion/Extension/RunnerIncludeHelpers
19
19
  GRAPH_API_BASE = 'https://graph.microsoft.com/v1.0'
20
20
  ENTRA_JWKS_URL_TEMPLATE = 'https://login.microsoftonline.com/%<tenant_id>s/discovery/v2.0/keys'
21
21
  ENTRA_ISSUER_TEMPLATE = 'https://login.microsoftonline.com/%<tenant_id>s/v2.0'
@@ -356,7 +356,7 @@ module Legion
356
356
  return nil unless secret && secret[:client_id] && secret[:client_secret]
357
357
 
358
358
  { tenant_id: tenant_id, client_id: secret[:client_id], client_secret: secret[:client_secret] }
359
- rescue StandardError
359
+ rescue StandardError => _e
360
360
  nil
361
361
  end
362
362
 
@@ -7,8 +7,8 @@ module Legion
7
7
  module Identity
8
8
  module Runners
9
9
  module Identity
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 observe_behavior(dimension:, value:, **)
14
14
  fingerprint = identity_fingerprint
@@ -31,7 +31,7 @@ module Legion
31
31
  ns = agentic.const_get(domain, false)
32
32
  ns.is_a?(Module) && ns.const_defined?(ext_sym, false)
33
33
  end
34
- rescue StandardError
34
+ rescue StandardError => _e
35
35
  false
36
36
  end
37
37
 
@@ -39,7 +39,7 @@ module Legion
39
39
  Constants::EXTENSION_CAPABILITIES.each_with_object({}) do |(ext_sym, _cat), acc|
40
40
  acc[ext_sym] = { loaded: extension_loaded?(ext_sym) }
41
41
  end
42
- rescue StandardError
42
+ rescue StandardError => _e
43
43
  {}
44
44
  end
45
45
 
@@ -119,7 +119,7 @@ module Legion
119
119
  volition = tick_results[:action_selection]
120
120
  return [] unless volition.is_a?(Hash) && volition[:intentions].is_a?(Array)
121
121
 
122
- volition[:intentions].first(3).map { |i| i[:drive] }.compact
122
+ volition[:intentions].first(3).filter_map { |i| i[:drive] }
123
123
  end
124
124
 
125
125
  def extract_attention(tick_results)
@@ -7,8 +7,8 @@ module Legion
7
7
  module Metacognition
8
8
  module Runners
9
9
  module Metacognition
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 introspect(tick_results: {}, subsystem_states: {}, **)
14
14
  model = if snapshot_store.stale?
@@ -18,7 +18,7 @@ module Legion
18
18
  store.register(entry)
19
19
  end
20
20
 
21
- Legion::Logging.info "[metacognition:registry] registered #{name} (#{category})" if defined?(Legion::Logging)
21
+ Legion::Logging.info "[metacognition:registry] registered #{name} (#{category})"
22
22
  { success: true, name: name, category: category }
23
23
  rescue ArgumentError => e
24
24
  { success: false, error: e.message }
@@ -132,7 +132,7 @@ module Legion
132
132
 
133
133
  def db_available?
134
134
  defined?(Legion::Data) && Legion::Data.respond_to?(:connection) && Legion::Data.connection
135
- rescue StandardError
135
+ rescue StandardError => _e
136
136
  false
137
137
  end
138
138
 
@@ -48,7 +48,7 @@ module Legion
48
48
  return [] if @points.empty?
49
49
 
50
50
  bin_size = 1.0 / bins
51
- bin_edges = bins.times.map { |i| (i * bin_size).round(10) }
51
+ bin_edges = Array.new(bins) { |i| (i * bin_size).round(10) }
52
52
 
53
53
  bin_edges.map do |edge|
54
54
  upper = (edge + bin_size).round(10)
@@ -9,8 +9,8 @@ module Legion
9
9
  module MetacognitiveMonitoring
10
10
  module Runners
11
11
  module MetacognitiveMonitoring
12
- include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
13
- Legion::Extensions::Helpers.const_defined?(:Lex)
12
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
13
+ Legion::Extensions::Helpers.const_defined?(:Lex, false)
14
14
 
15
15
  def record_judgment(type:, domain:, predicted_confidence: Helpers::DEFAULT_CONFIDENCE,
16
16
  effort: 0.5, engine: nil, **)
@@ -7,8 +7,8 @@ module Legion
7
7
  module NarrativeArc
8
8
  module Runners
9
9
  module Narrative
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 create_arc(title:, domain: :general, initial_tension: Helpers::Constants::DEFAULT_TENSION,
14
14
  engine: nil, **)
@@ -7,8 +7,8 @@ module Legion
7
7
  module NarrativeSelf
8
8
  module Runners
9
9
  module NarrativeSelf
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 record_episode(description:, episode_type: :insight, domain: :general,
14
14
  significance: nil, emotional_valence: 0.0, tags: [], **)
@@ -69,7 +69,7 @@ module Legion
69
69
  variances = Constants::TRAITS.map do |t|
70
70
  values = recent.map { |h| h[:traits][t] }
71
71
  mean = values.sum / values.size.to_f
72
- values.map { |v| (v - mean)**2 }.sum / values.size.to_f
72
+ values.sum { |v| (v - mean)**2 } / values.size.to_f
73
73
  end
74
74
  avg_variance = variances.sum / variances.size.to_f
75
75
  (1.0 - (avg_variance * 10)).clamp(0.0, 1.0)
@@ -30,7 +30,7 @@ module Legion
30
30
 
31
31
  def available?
32
32
  defined?(Legion::LLM) && Legion::LLM.respond_to?(:started?) && Legion::LLM.started?
33
- rescue StandardError
33
+ rescue StandardError => _e
34
34
  false
35
35
  end
36
36
 
@@ -38,7 +38,7 @@ module Legion
38
38
  !!(defined?(Legion::LLM::Pipeline::GaiaCaller) &&
39
39
  Legion::LLM.respond_to?(:pipeline_enabled?) &&
40
40
  Legion::LLM.pipeline_enabled?)
41
- rescue StandardError
41
+ rescue StandardError => _e
42
42
  false
43
43
  end
44
44
 
@@ -165,12 +165,12 @@ module Legion
165
165
  def format_dream_results(dream_results)
166
166
  return 'no results' unless dream_results.is_a?(Hash) && dream_results.any?
167
167
 
168
- dream_results.map do |phase, result|
168
+ dream_results.filter_map do |phase, result|
169
169
  next unless result.is_a?(Hash)
170
170
 
171
171
  summary = result.except(:error).map { |k, v| "#{k}=#{v}" }.first(4).join(', ')
172
172
  "#{phase}: #{summary}"
173
- end.compact.join("\n")
173
+ end.join("\n")
174
174
  end
175
175
  private_class_method :format_dream_results
176
176
 
@@ -7,8 +7,8 @@ module Legion
7
7
  module Reflection
8
8
  module Runners
9
9
  module Reflection
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 reflect(tick_results: {}, **)
14
14
  @metric_history ||= []
@@ -25,7 +25,7 @@ module Legion
25
25
 
26
26
  def available?
27
27
  !!(defined?(Legion::LLM) && Legion::LLM.respond_to?(:started?) && Legion::LLM.started?)
28
- rescue StandardError
28
+ rescue StandardError => _e
29
29
  false
30
30
  end
31
31
 
@@ -70,7 +70,7 @@ module Legion
70
70
  !!(defined?(Legion::LLM::Pipeline::GaiaCaller) &&
71
71
  Legion::LLM.respond_to?(:pipeline_enabled?) &&
72
72
  Legion::LLM.pipeline_enabled?)
73
- rescue StandardError
73
+ rescue StandardError => _e
74
74
  false
75
75
  end
76
76
  private_class_method :pipeline_available?
@@ -7,8 +7,8 @@ module Legion
7
7
  module SelfTalk
8
8
  module Runners
9
9
  module SelfTalk
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 register_voice(name:, voice_type:, volume: Helpers::Constants::DEFAULT_VOLUME,
14
14
  bias_direction: nil, **)
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Self
7
- VERSION = '0.1.6'
7
+ VERSION = '0.1.7'
8
8
  end
9
9
  end
10
10
  end
@@ -22,7 +22,7 @@ module Legion
22
22
  module Extensions
23
23
  module Agentic
24
24
  module Self
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
 
27
27
  def self.remote_invocable?
28
28
  false
@@ -171,8 +171,8 @@ RSpec.describe Legion::Extensions::Agentic::Self::DefaultModeNetwork::Helpers::D
171
171
  end
172
172
 
173
173
  it 'generates higher salience than wandering (on average)' do
174
- plans = 20.times.map { engine.plan_spontaneously }
175
- wanders = 20.times.map { engine.wander }
174
+ plans = Array.new(20) { engine.plan_spontaneously }
175
+ wanders = Array.new(20) { engine.wander }
176
176
  expect(plans.sum(&:salience) / plans.size).to be > wanders.sum(&:salience) / wanders.size
177
177
  end
178
178
  end
@@ -200,7 +200,7 @@ RSpec.describe Legion::Extensions::Agentic::Self::Metacognition::Helpers::Regist
200
200
 
201
201
  describe 'thread safety' do
202
202
  it 'handles concurrent registrations without data corruption' do
203
- threads = 20.times.map do |i|
203
+ threads = Array.new(20) do |i|
204
204
  Thread.new do
205
205
  store.register(entry.merge(name: "lex-thread-#{i}", module_name: "Mod#{i}"))
206
206
  end
@@ -212,7 +212,7 @@ RSpec.describe Legion::Extensions::Agentic::Self::Metacognition::Helpers::Regist
212
212
  it 'handles concurrent reads and writes safely' do
213
213
  store.register(entry)
214
214
  errors = []
215
- threads = 10.times.map do
215
+ threads = Array.new(10) do
216
216
  Thread.new do
217
217
  store.get('lex-memory')
218
218
  store.update('lex-memory', { health_score: rand })
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-self
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -149,6 +149,20 @@ dependencies:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
151
  version: '1.60'
152
+ - !ruby/object:Gem::Dependency
153
+ name: rubocop-legion
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '0.1'
159
+ type: :development
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '0.1'
152
166
  - !ruby/object:Gem::Dependency
153
167
  name: rubocop-rspec
154
168
  requirement: !ruby/object:Gem::Requirement