lex-agentic-self 0.1.10 → 0.1.11
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile +2 -0
- data/lex-agentic-self.gemspec +3 -3
- data/lib/legion/extensions/agentic/self/identity/runners/entra.rb +5 -2
- data/lib/legion/extensions/agentic/self/relationship_arc/helpers/arc_engine.rb +16 -3
- data/lib/legion/extensions/agentic/self/self_talk/runners/self_talk.rb +43 -5
- data/lib/legion/extensions/agentic/self/version.rb +1 -1
- data/spec/legion/extensions/agentic/self/identity/runners/entra_spec.rb +53 -0
- data/spec/legion/extensions/agentic/self/relationship_arc/helpers/arc_engine_spec.rb +41 -0
- data/spec/legion/extensions/agentic/self/self_talk/runners/self_talk_llm_spec.rb +2 -2
- data/spec/legion/extensions/agentic/self/self_talk/runners/self_talk_spec.rb +60 -0
- metadata +13 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aa196a32fb12a9051c899a77c904db1b019bcf20fa722522f4560aa06325c1c5
|
|
4
|
+
data.tar.gz: 21ea04fbbd1a0bb7ccbaf1baeb93c062c036818cecd316f907d82ba4607fc640
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2e5f6191d0093ad34c915a5368d71b1457f9774e393fff5f9d0424784ca38c250ce3c3ae3c3be6c0fc4c9b4a43ac8b2148bd3917b3ed37e102181aa2beae1e1a
|
|
7
|
+
data.tar.gz: 2bc178f3bfc1001ccc64af277a3e9fac685fea350964107883b6d001a4fe8da31fd3287b18e3a4b6838bd293798737c1c8eeb9fac3c77d44010be734e97279d0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.11] - 2026-03-31
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- `ArcEngine#to_h` now returns the last computed `relationship_health` score instead of always nil; `relationship_health()` caches result in `@last_health`
|
|
7
|
+
- `ArcEngine#arc_state_hash` now includes `milestones_today` key (milestones with `created_at` matching today in local time)
|
|
8
|
+
- `SelfTalk::Runners::SelfTalk#stub_turn_content` replaced by `mechanical_turn_content` backed by `VOICE_BANK` — produces real, meaningful content for critic/advocate/explorer/pragmatist voices; unknown types fall back to `VOICE_BANK_GENERIC`
|
|
9
|
+
- `SelfTalk::Runners::SelfTalk#generate_summary_for_dialogue` replaces static "Dialogue concluded" fallback with `mechanical_summary` — includes turn count, voices, and dominant position
|
|
10
|
+
- `Identity::Runners::Entra#rotate_client_secret` now emits a `Legion::Logging.warn` when `rotation_enabled: true` but Graph API rotation is not yet implemented, and returns `action_required` with instructions instead of a silent error
|
|
11
|
+
|
|
3
12
|
## [0.1.10] - 2026-03-31
|
|
4
13
|
|
|
5
14
|
### Added
|
data/Gemfile
CHANGED
data/lex-agentic-self.gemspec
CHANGED
|
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
|
|
|
34
34
|
|
|
35
35
|
spec.add_development_dependency 'faraday', '~> 2.0'
|
|
36
36
|
spec.add_development_dependency 'rspec', '~> 3.13'
|
|
37
|
-
spec.add_development_dependency 'rubocop'
|
|
38
|
-
spec.add_development_dependency 'rubocop-legion'
|
|
39
|
-
spec.add_development_dependency 'rubocop-rspec'
|
|
37
|
+
spec.add_development_dependency 'rubocop'
|
|
38
|
+
spec.add_development_dependency 'rubocop-legion'
|
|
39
|
+
spec.add_development_dependency 'rubocop-rspec'
|
|
40
40
|
end
|
|
@@ -293,8 +293,11 @@ module Legion
|
|
|
293
293
|
|
|
294
294
|
return { rotated: false, worker_id: worker_id, dry_run: true, would_rotate: true } if dry_run
|
|
295
295
|
|
|
296
|
-
# Graph API rotation
|
|
297
|
-
|
|
296
|
+
# Graph API rotation is blocked on Azure Application.ReadWrite.All permission.
|
|
297
|
+
# Emit a loud warning so callers are never silently misled.
|
|
298
|
+
Legion::Logging.warn "[identity:entra] Client secret rotation is enabled but Graph API rotation is not yet implemented. Worker: #{worker_id}"
|
|
299
|
+
{ rotated: false, worker_id: worker_id, error: 'graph_api_rotation_not_implemented',
|
|
300
|
+
action_required: 'Manual rotation needed — Graph API write permission not yet granted' }
|
|
298
301
|
end
|
|
299
302
|
|
|
300
303
|
def credential_refresh_cycle(**)
|
|
@@ -41,7 +41,7 @@ module Legion
|
|
|
41
41
|
score = (attachment_strength.to_f * w[:attachment_strength]) +
|
|
42
42
|
(reciprocity_balance.to_f * w[:reciprocity_balance]) +
|
|
43
43
|
(communication_consistency.to_f * w[:communication_consistency])
|
|
44
|
-
score.clamp(0.0, 1.0)
|
|
44
|
+
@last_health = score.clamp(0.0, 1.0)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def dirty?
|
|
@@ -77,14 +77,27 @@ module Legion
|
|
|
77
77
|
def to_h
|
|
78
78
|
{ agent_id: @agent_id, current_chapter: @current_chapter,
|
|
79
79
|
milestones: @milestones.map(&:to_h),
|
|
80
|
-
relationship_health:
|
|
80
|
+
relationship_health: @last_health, milestone_count: @milestones.size }
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
private
|
|
84
84
|
|
|
85
85
|
def arc_state_hash
|
|
86
86
|
{ agent_id: @agent_id, current_chapter: @current_chapter,
|
|
87
|
-
milestones: @milestones.map(&:to_h)
|
|
87
|
+
milestones: @milestones.map(&:to_h),
|
|
88
|
+
milestones_today: @milestones.select { |m| milestone_today?(m) }.map(&:to_h) }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def milestone_today?(milestone)
|
|
92
|
+
ts = milestone.respond_to?(:created_at) ? milestone.created_at : milestone[:created_at]
|
|
93
|
+
return false unless ts
|
|
94
|
+
|
|
95
|
+
today = ::Time.now
|
|
96
|
+
t = ts.is_a?(::Time) ? ts.localtime : ::Time.parse(ts.to_s)
|
|
97
|
+
t.year == today.year && t.mon == today.mon && t.mday == today.mday
|
|
98
|
+
rescue StandardError => e
|
|
99
|
+
warn "[arc_engine] milestone_today? error: #{e.message}"
|
|
100
|
+
false
|
|
88
101
|
end
|
|
89
102
|
|
|
90
103
|
def derive_chapter(bond_stage)
|
|
@@ -104,6 +104,35 @@ module Legion
|
|
|
104
104
|
{ decayed: decayed, voices: voice_list }
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
+
VOICE_BANK = {
|
|
108
|
+
critic: [
|
|
109
|
+
{ content: 'What could go wrong with this approach?', position: :challenge },
|
|
110
|
+
{ content: 'Are we overlooking any risks here?', position: :challenge },
|
|
111
|
+
{ content: 'This needs more careful consideration.', position: :caution }
|
|
112
|
+
],
|
|
113
|
+
advocate: [
|
|
114
|
+
{ content: 'This aligns with our core values.', position: :support },
|
|
115
|
+
{ content: 'The potential benefits outweigh the risks.', position: :support },
|
|
116
|
+
{ content: 'We should move forward with this.', position: :affirm }
|
|
117
|
+
],
|
|
118
|
+
explorer: [
|
|
119
|
+
{ content: 'What alternatives have we not considered?', position: :explore },
|
|
120
|
+
{ content: 'There may be an unconventional approach here.', position: :explore },
|
|
121
|
+
{ content: 'Let us examine this from another angle.', position: :clarify }
|
|
122
|
+
],
|
|
123
|
+
pragmatist: [
|
|
124
|
+
{ content: 'What is the simplest path forward?', position: :simplify },
|
|
125
|
+
{ content: 'Focus on what is actionable now.', position: :prioritize },
|
|
126
|
+
{ content: 'We need concrete next steps.', position: :clarify }
|
|
127
|
+
]
|
|
128
|
+
}.freeze
|
|
129
|
+
|
|
130
|
+
VOICE_BANK_GENERIC = [
|
|
131
|
+
{ content: 'Let us think this through carefully.', position: :clarify },
|
|
132
|
+
{ content: 'More reflection is needed on this topic.', position: :clarify },
|
|
133
|
+
{ content: 'What do we know for certain here?', position: :clarify }
|
|
134
|
+
].freeze
|
|
135
|
+
|
|
107
136
|
private
|
|
108
137
|
|
|
109
138
|
def engine
|
|
@@ -124,7 +153,7 @@ module Legion
|
|
|
124
153
|
)
|
|
125
154
|
return [llm_result, :llm] if llm_result
|
|
126
155
|
end
|
|
127
|
-
[
|
|
156
|
+
[mechanical_turn_content(voice_data.voice_type, dialogue_data.topic), :mechanical]
|
|
128
157
|
end
|
|
129
158
|
|
|
130
159
|
def build_prior_turns(dialogue_data)
|
|
@@ -135,13 +164,14 @@ module Legion
|
|
|
135
164
|
end
|
|
136
165
|
end
|
|
137
166
|
|
|
138
|
-
def
|
|
139
|
-
|
|
167
|
+
def mechanical_turn_content(voice_type, _topic)
|
|
168
|
+
bank = VOICE_BANK.fetch(voice_type.to_sym, VOICE_BANK_GENERIC)
|
|
169
|
+
bank.sample
|
|
140
170
|
end
|
|
141
171
|
|
|
142
172
|
def generate_summary_for_dialogue(dialogue_id)
|
|
143
173
|
dialogue_data = engine.dialogues[dialogue_id]
|
|
144
|
-
return
|
|
174
|
+
return mechanical_summary(nil) unless dialogue_data
|
|
145
175
|
|
|
146
176
|
if Helpers::LlmEnhancer.available?
|
|
147
177
|
turns = dialogue_data.turns.map do |t|
|
|
@@ -161,7 +191,15 @@ module Legion
|
|
|
161
191
|
return llm_result[:summary] if llm_result
|
|
162
192
|
end
|
|
163
193
|
|
|
164
|
-
|
|
194
|
+
mechanical_summary(dialogue_data)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def mechanical_summary(dialogue_data)
|
|
198
|
+
turns = dialogue_data&.turns || []
|
|
199
|
+
voices = turns.filter_map { |t| t.respond_to?(:voice_id) ? engine.voices[t.voice_id]&.name || t.voice_id : t[:voice_id] }.uniq
|
|
200
|
+
positions = turns.filter_map { |t| t.respond_to?(:position) ? t.position : t[:position] }.tally
|
|
201
|
+
dominant = positions.max_by { |_, count| count }&.first
|
|
202
|
+
"#{turns.size} turns across #{voices.join(', ')} voices. Dominant position: #{dominant || 'none'}."
|
|
165
203
|
end
|
|
166
204
|
end
|
|
167
205
|
end
|
|
@@ -338,6 +338,59 @@ RSpec.describe Legion::Extensions::Agentic::Self::Identity::Runners::Entra do
|
|
|
338
338
|
expect(result[:action_required]).to be false
|
|
339
339
|
expect(result[:days_remaining]).to be > 30
|
|
340
340
|
end
|
|
341
|
+
|
|
342
|
+
context 'when rotation_enabled is true and secret is expiring (fix 5)' do
|
|
343
|
+
before do
|
|
344
|
+
stub_const('Legion::Settings', Class.new do
|
|
345
|
+
def self.dig(*keys)
|
|
346
|
+
map = {
|
|
347
|
+
%i[identity entra rotation_enabled] => true,
|
|
348
|
+
%i[identity entra rotation_buffer_days] => 30
|
|
349
|
+
}
|
|
350
|
+
map[keys]
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def self.[](_key) = {}
|
|
354
|
+
end)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
it 'emits a warning log when graph api rotation is not implemented' do
|
|
358
|
+
vault_mod = Module.new do
|
|
359
|
+
def self.read_client_secret(**)
|
|
360
|
+
{ client_secret: 'val', client_secret_expires_at: (Time.now + (86_400 * 10)).iso8601 }
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
stub_const('Legion::Extensions::Agentic::Self::Identity::Helpers::VaultSecrets', vault_mod)
|
|
364
|
+
|
|
365
|
+
warned = false
|
|
366
|
+
allow(Legion::Logging).to receive(:warn) do |msg|
|
|
367
|
+
warned = true if msg.include?('graph_api_rotation_not_implemented') ||
|
|
368
|
+
msg.include?('Graph API rotation is not yet implemented')
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
result = client.rotate_client_secret(worker_id: 'w1')
|
|
372
|
+
|
|
373
|
+
expect(warned).to be true
|
|
374
|
+
expect(result[:rotated]).to be false
|
|
375
|
+
expect(result[:error]).to eq('graph_api_rotation_not_implemented')
|
|
376
|
+
expect(result[:action_required]).to include('Manual rotation needed')
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
it 'returns dry_run result without warning when dry_run: true' do
|
|
380
|
+
vault_mod = Module.new do
|
|
381
|
+
def self.read_client_secret(**)
|
|
382
|
+
{ client_secret: 'val', client_secret_expires_at: (Time.now + (86_400 * 10)).iso8601 }
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
stub_const('Legion::Extensions::Agentic::Self::Identity::Helpers::VaultSecrets', vault_mod)
|
|
386
|
+
|
|
387
|
+
expect(Legion::Logging).not_to receive(:warn).with(a_string_including('not yet implemented'))
|
|
388
|
+
|
|
389
|
+
result = client.rotate_client_secret(worker_id: 'w1', dry_run: true)
|
|
390
|
+
expect(result[:dry_run]).to be true
|
|
391
|
+
expect(result[:would_rotate]).to be true
|
|
392
|
+
end
|
|
393
|
+
end
|
|
341
394
|
end
|
|
342
395
|
|
|
343
396
|
# ---------------------------------------------------------------------------
|
|
@@ -120,5 +120,46 @@ RSpec.describe Legion::Extensions::Agentic::Self::RelationshipArc::Helpers::ArcE
|
|
|
120
120
|
h = engine.to_h
|
|
121
121
|
expect(h).to include(:agent_id, :current_chapter, :milestones, :relationship_health)
|
|
122
122
|
end
|
|
123
|
+
|
|
124
|
+
it 'relationship_health is nil before relationship_health() is called' do
|
|
125
|
+
expect(engine.to_h[:relationship_health]).to be_nil
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it 'relationship_health reflects the last computed value' do
|
|
129
|
+
engine.relationship_health(
|
|
130
|
+
attachment_strength: 0.8,
|
|
131
|
+
reciprocity_balance: 0.6,
|
|
132
|
+
communication_consistency: 0.7
|
|
133
|
+
)
|
|
134
|
+
h = engine.to_h
|
|
135
|
+
expected = (0.8 * 0.4) + (0.6 * 0.3) + (0.7 * 0.3)
|
|
136
|
+
expect(h[:relationship_health]).to be_within(0.01).of(expected)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'includes milestone_count' do
|
|
140
|
+
engine.add_milestone(type: :first_interaction, description: 'x', significance: 0.5)
|
|
141
|
+
expect(engine.to_h[:milestone_count]).to eq(1)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
describe '#arc_state_hash (via to_apollo_entries)' do
|
|
146
|
+
it 'includes milestones_today for milestones added today' do
|
|
147
|
+
engine.add_milestone(type: :first_interaction, description: 'today', significance: 0.9)
|
|
148
|
+
entries = engine.to_apollo_entries
|
|
149
|
+
parsed = JSON.parse(entries.first[:content], symbolize_names: true)
|
|
150
|
+
expect(parsed).to have_key(:milestones_today)
|
|
151
|
+
expect(parsed[:milestones_today].size).to eq(1)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'milestones_today is empty when milestones have old timestamps' do
|
|
155
|
+
ms = Legion::Extensions::Agentic::Self::RelationshipArc::Helpers::Milestone.new(
|
|
156
|
+
type: :first_interaction, description: 'old', significance: 0.5,
|
|
157
|
+
created_at: Time.now.utc - (2 * 86_400)
|
|
158
|
+
)
|
|
159
|
+
engine.instance_variable_get(:@milestones) << ms
|
|
160
|
+
entries = engine.to_apollo_entries
|
|
161
|
+
parsed = JSON.parse(entries.first[:content], symbolize_names: true)
|
|
162
|
+
expect(parsed[:milestones_today]).to eq([])
|
|
163
|
+
end
|
|
123
164
|
end
|
|
124
165
|
end
|
|
@@ -137,7 +137,7 @@ RSpec.describe Legion::Extensions::Agentic::Self::SelfTalk::Runners::SelfTalk, '
|
|
|
137
137
|
result = client.conclude_dialogue(dialogue_id: did)
|
|
138
138
|
expect(result[:concluded]).to be true
|
|
139
139
|
report = client.dialogue_report(dialogue_id: did)
|
|
140
|
-
expect(report[:dialogue][:conclusion]).to
|
|
140
|
+
expect(report[:dialogue][:conclusion]).to match(/turns across .* voices\. Dominant position:/)
|
|
141
141
|
end
|
|
142
142
|
end
|
|
143
143
|
|
|
@@ -151,7 +151,7 @@ RSpec.describe Legion::Extensions::Agentic::Self::SelfTalk::Runners::SelfTalk, '
|
|
|
151
151
|
result = client.conclude_dialogue(dialogue_id: did)
|
|
152
152
|
expect(result[:concluded]).to be true
|
|
153
153
|
report = client.dialogue_report(dialogue_id: did)
|
|
154
|
-
expect(report[:dialogue][:conclusion]).to
|
|
154
|
+
expect(report[:dialogue][:conclusion]).to match(/turns across .* voices\. Dominant position:/)
|
|
155
155
|
end
|
|
156
156
|
end
|
|
157
157
|
|
|
@@ -193,4 +193,64 @@ RSpec.describe Legion::Extensions::Agentic::Self::SelfTalk::Runners::SelfTalk do
|
|
|
193
193
|
expect(voice[:name]).to eq('Critic')
|
|
194
194
|
end
|
|
195
195
|
end
|
|
196
|
+
|
|
197
|
+
describe 'mechanical voice bank (fix 3)' do
|
|
198
|
+
let(:runner_class) do
|
|
199
|
+
Class.new do
|
|
200
|
+
include Legion::Extensions::Agentic::Self::SelfTalk::Runners::SelfTalk
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
let(:runner) { runner_class.new }
|
|
204
|
+
|
|
205
|
+
it 'produces real content for known voice types' do
|
|
206
|
+
%i[critic advocate explorer pragmatist].each do |type|
|
|
207
|
+
result = runner.send(:mechanical_turn_content, type, 'test topic')
|
|
208
|
+
expect(result[:content]).not_to be_empty
|
|
209
|
+
expect(result[:content]).not_to match(/\A\[/)
|
|
210
|
+
expect(result[:position]).not_to be_nil
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it 'falls back to generic bank for unknown voice types' do
|
|
215
|
+
result = runner.send(:mechanical_turn_content, :unknown_voice, 'some topic')
|
|
216
|
+
expect(result[:content]).not_to be_empty
|
|
217
|
+
expect(result[:position]).not_to be_nil
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it 'VOICE_BANK covers critic, advocate, explorer, pragmatist' do
|
|
221
|
+
bank = Legion::Extensions::Agentic::Self::SelfTalk::Runners::SelfTalk::VOICE_BANK
|
|
222
|
+
expect(bank.keys).to include(:critic, :advocate, :explorer, :pragmatist)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
describe 'mechanical summary (fix 4)' do
|
|
227
|
+
let(:runner_class) do
|
|
228
|
+
Class.new do
|
|
229
|
+
include Legion::Extensions::Agentic::Self::SelfTalk::Runners::SelfTalk
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
let(:runner) { runner_class.new }
|
|
233
|
+
|
|
234
|
+
it 'produces a non-empty summary when dialogue_data is nil' do
|
|
235
|
+
summary = runner.send(:mechanical_summary, nil)
|
|
236
|
+
expect(summary).to be_a(String)
|
|
237
|
+
expect(summary).not_to be_empty
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it 'includes turn count in summary' do
|
|
241
|
+
did = start_dialogue(topic: 'summary test')
|
|
242
|
+
vid = register_voice(name: 'Critic', type: :critic)
|
|
243
|
+
client.add_turn(dialogue_id: did, voice_id: vid, content: 'Point one', position: :challenge)
|
|
244
|
+
client.add_turn(dialogue_id: did, voice_id: vid, content: 'Point two', position: :challenge)
|
|
245
|
+
|
|
246
|
+
result = client.conclude_dialogue(dialogue_id: did)
|
|
247
|
+
expect(result[:concluded]).to be true
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it 'conclude_dialogue without summary uses mechanical_summary' do
|
|
251
|
+
did = start_dialogue(topic: 'no summary')
|
|
252
|
+
result = client.conclude_dialogue(dialogue_id: did)
|
|
253
|
+
expect(result[:concluded]).to be true
|
|
254
|
+
end
|
|
255
|
+
end
|
|
196
256
|
end
|
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.
|
|
4
|
+
version: 0.1.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -139,44 +139,44 @@ dependencies:
|
|
|
139
139
|
name: rubocop
|
|
140
140
|
requirement: !ruby/object:Gem::Requirement
|
|
141
141
|
requirements:
|
|
142
|
-
- - "
|
|
142
|
+
- - ">="
|
|
143
143
|
- !ruby/object:Gem::Version
|
|
144
|
-
version: '
|
|
144
|
+
version: '0'
|
|
145
145
|
type: :development
|
|
146
146
|
prerelease: false
|
|
147
147
|
version_requirements: !ruby/object:Gem::Requirement
|
|
148
148
|
requirements:
|
|
149
|
-
- - "
|
|
149
|
+
- - ">="
|
|
150
150
|
- !ruby/object:Gem::Version
|
|
151
|
-
version: '
|
|
151
|
+
version: '0'
|
|
152
152
|
- !ruby/object:Gem::Dependency
|
|
153
153
|
name: rubocop-legion
|
|
154
154
|
requirement: !ruby/object:Gem::Requirement
|
|
155
155
|
requirements:
|
|
156
|
-
- - "
|
|
156
|
+
- - ">="
|
|
157
157
|
- !ruby/object:Gem::Version
|
|
158
|
-
version: '0
|
|
158
|
+
version: '0'
|
|
159
159
|
type: :development
|
|
160
160
|
prerelease: false
|
|
161
161
|
version_requirements: !ruby/object:Gem::Requirement
|
|
162
162
|
requirements:
|
|
163
|
-
- - "
|
|
163
|
+
- - ">="
|
|
164
164
|
- !ruby/object:Gem::Version
|
|
165
|
-
version: '0
|
|
165
|
+
version: '0'
|
|
166
166
|
- !ruby/object:Gem::Dependency
|
|
167
167
|
name: rubocop-rspec
|
|
168
168
|
requirement: !ruby/object:Gem::Requirement
|
|
169
169
|
requirements:
|
|
170
|
-
- - "
|
|
170
|
+
- - ">="
|
|
171
171
|
- !ruby/object:Gem::Version
|
|
172
|
-
version: '
|
|
172
|
+
version: '0'
|
|
173
173
|
type: :development
|
|
174
174
|
prerelease: false
|
|
175
175
|
version_requirements: !ruby/object:Gem::Requirement
|
|
176
176
|
requirements:
|
|
177
|
-
- - "
|
|
177
|
+
- - ">="
|
|
178
178
|
- !ruby/object:Gem::Version
|
|
179
|
-
version: '
|
|
179
|
+
version: '0'
|
|
180
180
|
description: 'LEX agentic self domain: identity, metacognition, self-model'
|
|
181
181
|
email:
|
|
182
182
|
- matthewdiverson@gmail.com
|