lex-dissonance 0.1.0
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 +7 -0
- data/Gemfile +10 -0
- data/lex-dissonance.gemspec +29 -0
- data/lib/legion/extensions/dissonance/client.rb +28 -0
- data/lib/legion/extensions/dissonance/helpers/belief.rb +42 -0
- data/lib/legion/extensions/dissonance/helpers/constants.rb +23 -0
- data/lib/legion/extensions/dissonance/helpers/dissonance_event.rb +48 -0
- data/lib/legion/extensions/dissonance/helpers/dissonance_model.rb +155 -0
- data/lib/legion/extensions/dissonance/runners/dissonance.rb +159 -0
- data/lib/legion/extensions/dissonance/version.rb +9 -0
- data/lib/legion/extensions/dissonance.rb +16 -0
- data/spec/legion/extensions/dissonance/client_spec.rb +51 -0
- data/spec/legion/extensions/dissonance/helpers/belief_spec.rb +103 -0
- data/spec/legion/extensions/dissonance/helpers/constants_spec.rb +60 -0
- data/spec/legion/extensions/dissonance/helpers/dissonance_event_spec.rb +113 -0
- data/spec/legion/extensions/dissonance/helpers/dissonance_model_spec.rb +252 -0
- data/spec/legion/extensions/dissonance/runners/dissonance_spec.rb +323 -0
- data/spec/spec_helper.rb +28 -0
- metadata +78 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/dissonance/client'
|
|
4
|
+
|
|
5
|
+
RSpec.describe Legion::Extensions::Dissonance::Runners::Dissonance do
|
|
6
|
+
let(:client) { Legion::Extensions::Dissonance::Client.new }
|
|
7
|
+
|
|
8
|
+
describe '#add_belief' do
|
|
9
|
+
it 'returns success true with a belief_id' do
|
|
10
|
+
result = client.add_belief(domain: 'ethics', content: 'honesty is required')
|
|
11
|
+
expect(result[:success]).to be true
|
|
12
|
+
expect(result[:belief_id]).to match(/\A[0-9a-f-]{36}\z/)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'returns the domain' do
|
|
16
|
+
result = client.add_belief(domain: 'ethics', content: 'test')
|
|
17
|
+
expect(result[:domain]).to eq('ethics')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'returns empty new_dissonance_events for first belief in domain' do
|
|
21
|
+
result = client.add_belief(domain: 'ethics', content: 'honesty is required')
|
|
22
|
+
expect(result[:new_dissonance_events]).to be_empty
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'returns dissonance events when contradiction detected' do
|
|
26
|
+
client.add_belief(domain: 'safety', content: 'always ask permission')
|
|
27
|
+
result = client.add_belief(domain: 'safety', content: 'act without asking')
|
|
28
|
+
expect(result[:new_dissonance_events].size).to eq(1)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'sets dissonance_triggered when magnitude >= threshold' do
|
|
32
|
+
client.add_belief(domain: 'ethics', content: 'tell the truth', confidence: 1.0, importance: :core)
|
|
33
|
+
result = client.add_belief(domain: 'ethics', content: 'lie when convenient', confidence: 1.0, importance: :core)
|
|
34
|
+
expect(result[:dissonance_triggered]).to be true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'returns success false for invalid importance' do
|
|
38
|
+
result = client.add_belief(domain: 'ethics', content: 'test', importance: :invalid)
|
|
39
|
+
expect(result[:success]).to be false
|
|
40
|
+
expect(result[:error]).to eq(:invalid_importance)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'returns valid importance levels on error' do
|
|
44
|
+
result = client.add_belief(domain: 'ethics', content: 'test', importance: :invalid)
|
|
45
|
+
expect(result[:valid]).to contain_exactly(:core, :significant, :moderate, :peripheral)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'accepts all valid importance levels' do
|
|
49
|
+
%i[core significant moderate peripheral].each do |imp|
|
|
50
|
+
result = client.add_belief(domain: 'test', content: "content_#{imp}", importance: imp)
|
|
51
|
+
expect(result[:success]).to be true
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe '#update_dissonance' do
|
|
57
|
+
it 'returns success true' do
|
|
58
|
+
result = client.update_dissonance
|
|
59
|
+
expect(result[:success]).to be true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'returns current stress' do
|
|
63
|
+
result = client.update_dissonance
|
|
64
|
+
expect(result[:stress]).to be_a(Float)
|
|
65
|
+
expect(result[:stress]).to be_between(0.0, 1.0)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'returns unresolved_count' do
|
|
69
|
+
result = client.update_dissonance
|
|
70
|
+
expect(result[:unresolved_count]).to eq(0)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'above_threshold is false when no unresolved events' do
|
|
74
|
+
result = client.update_dissonance
|
|
75
|
+
expect(result[:above_threshold]).to be false
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'above_threshold is true when high-magnitude unresolved events exist' do
|
|
79
|
+
client.add_belief(domain: 'x', content: 'a', confidence: 1.0, importance: :core)
|
|
80
|
+
client.add_belief(domain: 'x', content: 'b', confidence: 1.0, importance: :core)
|
|
81
|
+
result = client.update_dissonance
|
|
82
|
+
expect(result[:above_threshold]).to be true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'increases unresolved_count after adding contradictions' do
|
|
86
|
+
client.add_belief(domain: 'y', content: 'claim1')
|
|
87
|
+
client.add_belief(domain: 'y', content: 'claim2')
|
|
88
|
+
result = client.update_dissonance
|
|
89
|
+
expect(result[:unresolved_count]).to eq(1)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe '#resolve_dissonance' do
|
|
94
|
+
let(:event_id) do
|
|
95
|
+
client.add_belief(domain: 'ethics', content: 'be honest')
|
|
96
|
+
result = client.add_belief(domain: 'ethics', content: 'deceive when convenient')
|
|
97
|
+
result[:new_dissonance_events].first[:id]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'returns success true on valid resolution' do
|
|
101
|
+
result = client.resolve_dissonance(event_id: event_id, strategy: :belief_revision)
|
|
102
|
+
expect(result[:success]).to be true
|
|
103
|
+
expect(result[:resolved]).to be true
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'returns the strategy used' do
|
|
107
|
+
result = client.resolve_dissonance(event_id: event_id, strategy: :rationalization)
|
|
108
|
+
expect(result[:strategy]).to eq(:rationalization)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'returns the event hash' do
|
|
112
|
+
result = client.resolve_dissonance(event_id: event_id, strategy: :belief_revision)
|
|
113
|
+
expect(result[:event]).to be_a(Hash)
|
|
114
|
+
expect(result[:event][:resolved]).to be true
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'returns success false for invalid strategy' do
|
|
118
|
+
result = client.resolve_dissonance(event_id: event_id, strategy: :magic)
|
|
119
|
+
expect(result[:success]).to be false
|
|
120
|
+
expect(result[:error]).to eq(:invalid_strategy)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it 'returns valid strategies on invalid strategy error' do
|
|
124
|
+
result = client.resolve_dissonance(event_id: event_id, strategy: :magic)
|
|
125
|
+
expect(result[:valid]).to eq(Legion::Extensions::Dissonance::Helpers::Constants::RESOLUTION_STRATEGIES)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it 'returns success false for unknown event_id' do
|
|
129
|
+
result = client.resolve_dissonance(event_id: 'no-such-id', strategy: :belief_revision)
|
|
130
|
+
expect(result[:success]).to be false
|
|
131
|
+
expect(result[:error]).to eq(:not_found_or_already_resolved)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'returns success false when event already resolved' do
|
|
135
|
+
client.resolve_dissonance(event_id: event_id, strategy: :belief_revision)
|
|
136
|
+
result = client.resolve_dissonance(event_id: event_id, strategy: :rationalization)
|
|
137
|
+
expect(result[:success]).to be false
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'defaults strategy to belief_revision' do
|
|
141
|
+
result = client.resolve_dissonance(event_id: event_id)
|
|
142
|
+
expect(result[:strategy]).to eq(:belief_revision)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it 'works with all three resolution strategies' do
|
|
146
|
+
%i[belief_revision rationalization avoidance].each_with_index do |strategy, i|
|
|
147
|
+
c = Legion::Extensions::Dissonance::Client.new
|
|
148
|
+
c.add_belief(domain: 'domain', content: "a#{i}")
|
|
149
|
+
inner_result = c.add_belief(domain: 'domain', content: "b#{i}")
|
|
150
|
+
ev_id = inner_result[:new_dissonance_events].first[:id]
|
|
151
|
+
result = c.resolve_dissonance(event_id: ev_id, strategy: strategy)
|
|
152
|
+
expect(result[:success]).to be true
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
describe '#dissonance_status' do
|
|
158
|
+
it 'returns success true' do
|
|
159
|
+
result = client.dissonance_status
|
|
160
|
+
expect(result[:success]).to be true
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it 'returns stress value' do
|
|
164
|
+
result = client.dissonance_status
|
|
165
|
+
expect(result[:stress]).to be_a(Float)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it 'returns total_beliefs count' do
|
|
169
|
+
client.add_belief(domain: 'x', content: 'test')
|
|
170
|
+
result = client.dissonance_status
|
|
171
|
+
expect(result[:total_beliefs]).to eq(1)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it 'returns total_events count' do
|
|
175
|
+
client.add_belief(domain: 'x', content: 'a')
|
|
176
|
+
client.add_belief(domain: 'x', content: 'b')
|
|
177
|
+
result = client.dissonance_status
|
|
178
|
+
expect(result[:total_events]).to eq(1)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it 'returns unresolved_count' do
|
|
182
|
+
result = client.dissonance_status
|
|
183
|
+
expect(result[:unresolved_count]).to eq(0)
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
describe '#domain_dissonance' do
|
|
188
|
+
it 'returns success true' do
|
|
189
|
+
result = client.domain_dissonance(domain: 'ethics')
|
|
190
|
+
expect(result[:success]).to be true
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it 'returns the domain' do
|
|
194
|
+
result = client.domain_dissonance(domain: 'ethics')
|
|
195
|
+
expect(result[:domain]).to eq('ethics')
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it 'returns 0.0 stress for domain with no beliefs' do
|
|
199
|
+
result = client.domain_dissonance(domain: 'ethics')
|
|
200
|
+
expect(result[:stress]).to eq(0.0)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it 'returns positive stress for domain with contradictions' do
|
|
204
|
+
client.add_belief(domain: 'ethics', content: 'be honest')
|
|
205
|
+
client.add_belief(domain: 'ethics', content: 'hide truth')
|
|
206
|
+
result = client.domain_dissonance(domain: 'ethics')
|
|
207
|
+
expect(result[:stress]).to be > 0.0
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
it 'returns unresolved events for the domain' do
|
|
211
|
+
client.add_belief(domain: 'ethics', content: 'be honest')
|
|
212
|
+
client.add_belief(domain: 'ethics', content: 'hide truth')
|
|
213
|
+
result = client.domain_dissonance(domain: 'ethics')
|
|
214
|
+
expect(result[:events].size).to eq(1)
|
|
215
|
+
expect(result[:events].first[:domain]).to eq('ethics')
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it 'does not include events from other domains' do
|
|
219
|
+
client.add_belief(domain: 'ethics', content: 'be honest')
|
|
220
|
+
client.add_belief(domain: 'ethics', content: 'hide truth')
|
|
221
|
+
client.add_belief(domain: 'safety', content: 'claim x')
|
|
222
|
+
client.add_belief(domain: 'safety', content: 'claim y')
|
|
223
|
+
result = client.domain_dissonance(domain: 'ethics')
|
|
224
|
+
expect(result[:events].all? { |ev| ev[:domain] == 'ethics' }).to be true
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
describe '#beliefs_for' do
|
|
229
|
+
it 'returns success true' do
|
|
230
|
+
result = client.beliefs_for(domain: 'ethics')
|
|
231
|
+
expect(result[:success]).to be true
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it 'returns empty beliefs for unknown domain' do
|
|
235
|
+
result = client.beliefs_for(domain: 'unknown')
|
|
236
|
+
expect(result[:beliefs]).to be_empty
|
|
237
|
+
expect(result[:count]).to eq(0)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it 'returns beliefs for a domain' do
|
|
241
|
+
client.add_belief(domain: 'ethics', content: 'test belief')
|
|
242
|
+
result = client.beliefs_for(domain: 'ethics')
|
|
243
|
+
expect(result[:count]).to eq(1)
|
|
244
|
+
expect(result[:beliefs].first[:content]).to eq('test belief')
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
it 'does not include beliefs from other domains' do
|
|
248
|
+
client.add_belief(domain: 'ethics', content: 'ethics belief')
|
|
249
|
+
client.add_belief(domain: 'safety', content: 'safety belief')
|
|
250
|
+
result = client.beliefs_for(domain: 'ethics')
|
|
251
|
+
expect(result[:count]).to eq(1)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it 'returns the domain in the result' do
|
|
255
|
+
result = client.beliefs_for(domain: 'ethics')
|
|
256
|
+
expect(result[:domain]).to eq('ethics')
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
describe '#unresolved' do
|
|
261
|
+
it 'returns success true' do
|
|
262
|
+
result = client.unresolved
|
|
263
|
+
expect(result[:success]).to be true
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it 'returns empty events initially' do
|
|
267
|
+
result = client.unresolved
|
|
268
|
+
expect(result[:events]).to be_empty
|
|
269
|
+
expect(result[:count]).to eq(0)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it 'returns unresolved events after contradiction' do
|
|
273
|
+
client.add_belief(domain: 'x', content: 'claim a')
|
|
274
|
+
client.add_belief(domain: 'x', content: 'claim b')
|
|
275
|
+
result = client.unresolved
|
|
276
|
+
expect(result[:count]).to eq(1)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
it 'does not include resolved events' do
|
|
280
|
+
client.add_belief(domain: 'x', content: 'claim a')
|
|
281
|
+
inner_result = client.add_belief(domain: 'x', content: 'claim b')
|
|
282
|
+
ev_id = inner_result[:new_dissonance_events].first[:id]
|
|
283
|
+
client.resolve_dissonance(event_id: ev_id, strategy: :belief_revision)
|
|
284
|
+
result = client.unresolved
|
|
285
|
+
expect(result[:count]).to eq(0)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
describe '#dissonance_stats' do
|
|
290
|
+
it 'returns success true' do
|
|
291
|
+
result = client.dissonance_stats
|
|
292
|
+
expect(result[:success]).to be true
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
it 'returns comprehensive stats hash' do
|
|
296
|
+
result = client.dissonance_stats
|
|
297
|
+
expect(result).to include(:stress, :total_beliefs, :total_events, :unresolved_count,
|
|
298
|
+
:resolved_count, :domain_stresses, :resolution_breakdown, :above_threshold)
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it 'resolution_breakdown contains all three strategies' do
|
|
302
|
+
result = client.dissonance_stats
|
|
303
|
+
expect(result[:resolution_breakdown].keys).to contain_exactly(:belief_revision, :rationalization, :avoidance)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
it 'counts resolved events by strategy' do
|
|
307
|
+
client.add_belief(domain: 'x', content: 'a')
|
|
308
|
+
inner_result = client.add_belief(domain: 'x', content: 'b')
|
|
309
|
+
ev_id = inner_result[:new_dissonance_events].first[:id]
|
|
310
|
+
client.resolve_dissonance(event_id: ev_id, strategy: :rationalization)
|
|
311
|
+
result = client.dissonance_stats
|
|
312
|
+
expect(result[:resolution_breakdown][:rationalization]).to eq(1)
|
|
313
|
+
expect(result[:resolved_count]).to eq(1)
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
it 'domain_stresses includes all domains with beliefs' do
|
|
317
|
+
client.add_belief(domain: 'domain_a', content: 'alpha')
|
|
318
|
+
client.add_belief(domain: 'domain_b', content: 'beta')
|
|
319
|
+
result = client.dissonance_stats
|
|
320
|
+
expect(result[:domain_stresses].keys).to include('domain_a', 'domain_b')
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Logging
|
|
7
|
+
def self.debug(_msg); end
|
|
8
|
+
def self.info(_msg); end
|
|
9
|
+
def self.warn(_msg); end
|
|
10
|
+
def self.error(_msg); end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module Extensions
|
|
14
|
+
module Helpers
|
|
15
|
+
module Lex; end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module Core; end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
require 'legion/extensions/dissonance'
|
|
23
|
+
|
|
24
|
+
RSpec.configure do |config|
|
|
25
|
+
config.example_status_persistence_file_path = '.rspec_status'
|
|
26
|
+
config.disable_monkey_patching!
|
|
27
|
+
config.expect_with(:rspec) { |c| c.syntax = :expect }
|
|
28
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lex-dissonance
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Esity
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: legion-gaia
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
description: Cognitive dissonance modeling — contradiction detection, belief tracking,
|
|
27
|
+
and resolution strategies for brain-modeled agentic AI
|
|
28
|
+
email:
|
|
29
|
+
- matthewdiverson@gmail.com
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- Gemfile
|
|
35
|
+
- lex-dissonance.gemspec
|
|
36
|
+
- lib/legion/extensions/dissonance.rb
|
|
37
|
+
- lib/legion/extensions/dissonance/client.rb
|
|
38
|
+
- lib/legion/extensions/dissonance/helpers/belief.rb
|
|
39
|
+
- lib/legion/extensions/dissonance/helpers/constants.rb
|
|
40
|
+
- lib/legion/extensions/dissonance/helpers/dissonance_event.rb
|
|
41
|
+
- lib/legion/extensions/dissonance/helpers/dissonance_model.rb
|
|
42
|
+
- lib/legion/extensions/dissonance/runners/dissonance.rb
|
|
43
|
+
- lib/legion/extensions/dissonance/version.rb
|
|
44
|
+
- spec/legion/extensions/dissonance/client_spec.rb
|
|
45
|
+
- spec/legion/extensions/dissonance/helpers/belief_spec.rb
|
|
46
|
+
- spec/legion/extensions/dissonance/helpers/constants_spec.rb
|
|
47
|
+
- spec/legion/extensions/dissonance/helpers/dissonance_event_spec.rb
|
|
48
|
+
- spec/legion/extensions/dissonance/helpers/dissonance_model_spec.rb
|
|
49
|
+
- spec/legion/extensions/dissonance/runners/dissonance_spec.rb
|
|
50
|
+
- spec/spec_helper.rb
|
|
51
|
+
homepage: https://github.com/LegionIO/lex-dissonance
|
|
52
|
+
licenses:
|
|
53
|
+
- MIT
|
|
54
|
+
metadata:
|
|
55
|
+
homepage_uri: https://github.com/LegionIO/lex-dissonance
|
|
56
|
+
source_code_uri: https://github.com/LegionIO/lex-dissonance
|
|
57
|
+
documentation_uri: https://github.com/LegionIO/lex-dissonance
|
|
58
|
+
changelog_uri: https://github.com/LegionIO/lex-dissonance
|
|
59
|
+
bug_tracker_uri: https://github.com/LegionIO/lex-dissonance/issues
|
|
60
|
+
rubygems_mfa_required: 'true'
|
|
61
|
+
rdoc_options: []
|
|
62
|
+
require_paths:
|
|
63
|
+
- lib
|
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.4'
|
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
requirements: []
|
|
75
|
+
rubygems_version: 3.6.9
|
|
76
|
+
specification_version: 4
|
|
77
|
+
summary: LEX Dissonance
|
|
78
|
+
test_files: []
|