lex-cognitive-tide 0.1.1

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.
@@ -0,0 +1,325 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::CognitiveTide::Helpers::TideEngine do
4
+ let(:engine) { described_class.new }
5
+
6
+ def add_primary(eng = engine, amplitude: 1.0)
7
+ eng.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: amplitude)
8
+ end
9
+
10
+ def add_secondary(eng = engine, amplitude: 0.5)
11
+ eng.add_oscillator(oscillator_type: :secondary, period: 43_200, amplitude: amplitude)
12
+ end
13
+
14
+ describe '#initialize' do
15
+ it 'starts with no oscillators' do
16
+ expect(engine.oscillators).to be_empty
17
+ end
18
+
19
+ it 'starts with no pools' do
20
+ expect(engine.pools).to be_empty
21
+ end
22
+ end
23
+
24
+ describe '#add_oscillator' do
25
+ it 'returns an Oscillator instance' do
26
+ osc = add_primary
27
+ expect(osc).to be_a(Legion::Extensions::CognitiveTide::Helpers::Oscillator)
28
+ end
29
+
30
+ it 'appends to oscillators' do
31
+ add_primary
32
+ expect(engine.oscillators.size).to eq(1)
33
+ end
34
+
35
+ it 'allows multiple oscillators' do
36
+ add_primary
37
+ add_secondary
38
+ expect(engine.oscillators.size).to eq(2)
39
+ end
40
+
41
+ it 'raises ArgumentError for unknown oscillator_type' do
42
+ expect { engine.add_oscillator(oscillator_type: :invalid, period: 3600) }
43
+ .to raise_error(ArgumentError)
44
+ end
45
+ end
46
+
47
+ describe '#composite_tide_level' do
48
+ it 'returns 0.0 with no oscillators' do
49
+ expect(engine.composite_tide_level).to eq(0.0)
50
+ end
51
+
52
+ it 'returns a value in [0, 1]' do
53
+ add_primary
54
+ add_secondary
55
+ level = engine.composite_tide_level
56
+ expect(level).to be >= 0.0
57
+ expect(level).to be <= 1.0
58
+ end
59
+
60
+ it 'is deterministic for the same time' do
61
+ t = Time.utc(2026, 1, 1, 12, 0, 0)
62
+ allow(Time).to receive(:now).and_return(t)
63
+ add_primary
64
+ expect(engine.composite_tide_level).to eq(engine.composite_tide_level)
65
+ end
66
+
67
+ it 'returns 0.0 when all amplitudes are 0' do
68
+ engine.add_oscillator(oscillator_type: :primary, period: 3600, amplitude: 0.0)
69
+ expect(engine.composite_tide_level).to eq(0.0)
70
+ end
71
+
72
+ it 'respects amplitude weighting with a single oscillator' do
73
+ eng = described_class.new
74
+ eng.add_oscillator(oscillator_type: :primary, period: 3600, amplitude: 1.0, phase_offset: 0.0)
75
+ level = eng.composite_tide_level
76
+ expect(level).to be >= 0.0
77
+ expect(level).to be <= 1.0
78
+ end
79
+ end
80
+
81
+ describe '#current_phase' do
82
+ it 'returns one of the four tide phases' do
83
+ add_primary
84
+ expect(Legion::Extensions::CognitiveTide::Helpers::Constants::TIDE_PHASES)
85
+ .to include(engine.current_phase)
86
+ end
87
+
88
+ it 'returns :high_tide when level >= 0.65' do
89
+ # Force high level: sin at peak with phase_offset = PI/2, at t=0
90
+ t = Time.utc(2026, 1, 1)
91
+ allow(Time).to receive(:now).and_return(t)
92
+ # phase_offset = PI/2 means sin = 1.0 at t=0
93
+ engine.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: 1.0,
94
+ phase_offset: Math::PI / 2.0)
95
+ expect(engine.current_phase).to eq(:high_tide)
96
+ end
97
+
98
+ it 'returns :low_tide when level <= 0.35' do
99
+ t = Time.utc(2026, 1, 1)
100
+ allow(Time).to receive(:now).and_return(t)
101
+ # phase_offset = -PI/2 means sin = -1.0 at t=0 → value_at = 0.0
102
+ engine.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: 1.0,
103
+ phase_offset: -Math::PI / 2.0)
104
+ expect(engine.current_phase).to eq(:low_tide)
105
+ end
106
+ end
107
+
108
+ describe '#create_pool' do
109
+ it 'creates a pool for a domain' do
110
+ pool = engine.create_pool(domain: 'philosophy')
111
+ expect(pool).to be_a(Legion::Extensions::CognitiveTide::Helpers::TidalPool)
112
+ expect(pool.domain).to eq('philosophy')
113
+ end
114
+
115
+ it 'appends to pools' do
116
+ engine.create_pool(domain: 'philosophy')
117
+ expect(engine.pools.size).to eq(1)
118
+ end
119
+
120
+ it 'returns existing pool if domain already exists' do
121
+ p1 = engine.create_pool(domain: 'ideas')
122
+ p2 = engine.create_pool(domain: 'ideas')
123
+ expect(p1.id).to eq(p2.id)
124
+ expect(engine.pools.size).to eq(1)
125
+ end
126
+
127
+ it 'returns nil when MAX_POOLS is reached' do
128
+ max = Legion::Extensions::CognitiveTide::Helpers::Constants::MAX_POOLS
129
+ max.times { |i| engine.create_pool(domain: "domain_#{i}") }
130
+ result = engine.create_pool(domain: 'overflow')
131
+ expect(result).to be_nil
132
+ end
133
+
134
+ it 'does not add a pool when at capacity' do
135
+ max = Legion::Extensions::CognitiveTide::Helpers::Constants::MAX_POOLS
136
+ max.times { |i| engine.create_pool(domain: "domain_#{i}") }
137
+ engine.create_pool(domain: 'overflow')
138
+ expect(engine.pools.size).to eq(max)
139
+ end
140
+ end
141
+
142
+ describe '#deposit_to_pool' do
143
+ it 'deposits an item into a new domain pool' do
144
+ result = engine.deposit_to_pool(domain: 'ideas', item: 'refactor this')
145
+ expect(result).to be(true)
146
+ end
147
+
148
+ it 'auto-creates the pool if not present' do
149
+ engine.deposit_to_pool(domain: 'fresh_domain', item: 'test idea')
150
+ expect(engine.pools.size).to eq(1)
151
+ end
152
+
153
+ it 'deposits into existing pool for domain' do
154
+ engine.deposit_to_pool(domain: 'ideas', item: 'idea 1')
155
+ engine.deposit_to_pool(domain: 'ideas', item: 'idea 2')
156
+ pool = engine.pools.first
157
+ expect(pool.size).to eq(2)
158
+ end
159
+
160
+ it 'returns false when MAX_POOLS is reached and domain is new' do
161
+ max = Legion::Extensions::CognitiveTide::Helpers::Constants::MAX_POOLS
162
+ max.times { |i| engine.create_pool(domain: "domain_#{i}") }
163
+ result = engine.deposit_to_pool(domain: 'overflow', item: 'idea')
164
+ expect(result).to be(false)
165
+ end
166
+ end
167
+
168
+ describe '#harvest_pools' do
169
+ before do
170
+ add_primary
171
+ engine.deposit_to_pool(domain: 'ideas', item: 'alpha')
172
+ engine.deposit_to_pool(domain: 'ideas', item: 'beta')
173
+ end
174
+
175
+ it 'returns empty hash when tide is not rising' do
176
+ # Make the engine report non-rising phase
177
+ allow(engine).to receive(:rising?).and_return(false)
178
+ expect(engine.harvest_pools).to eq({})
179
+ end
180
+
181
+ it 'returns harvested items by domain when rising' do
182
+ allow(engine).to receive(:rising?).and_return(true)
183
+ result = engine.harvest_pools
184
+ expect(result).to have_key('ideas')
185
+ expect(result['ideas'].size).to eq(2)
186
+ end
187
+
188
+ it 'clears pools after harvest' do
189
+ allow(engine).to receive(:rising?).and_return(true)
190
+ engine.harvest_pools
191
+ expect(engine.pools.first.size).to eq(0)
192
+ end
193
+
194
+ it 'respects min_depth threshold' do
195
+ allow(engine).to receive(:rising?).and_return(true)
196
+ # Pool has 2 items with capacity 20 → depth = 0.1; skip pools below 0.5
197
+ result = engine.harvest_pools(min_depth: 0.5)
198
+ expect(result).not_to have_key('ideas')
199
+ end
200
+
201
+ it 'skips empty pools' do
202
+ allow(engine).to receive(:rising?).and_return(true)
203
+ engine.create_pool(domain: 'empty_pool')
204
+ result = engine.harvest_pools
205
+ expect(result).not_to have_key('empty_pool')
206
+ end
207
+ end
208
+
209
+ describe '#evaporate_all!' do
210
+ it 'returns total items removed across all pools' do
211
+ 20.times { |i| engine.deposit_to_pool(domain: 'ideas', item: "idea #{i}") }
212
+ removed = engine.evaporate_all!(0.1)
213
+ expect(removed).to be > 0
214
+ end
215
+
216
+ it 'evaporates all pools' do
217
+ engine.deposit_to_pool(domain: 'alpha', item: 'idea a')
218
+ engine.deposit_to_pool(domain: 'beta', item: 'idea b')
219
+ removed = engine.evaporate_all!(1.0)
220
+ expect(removed).to eq(2)
221
+ end
222
+
223
+ it 'returns 0 when no pools' do
224
+ expect(engine.evaporate_all!).to eq(0)
225
+ end
226
+ end
227
+
228
+ describe '#tide_forecast' do
229
+ it 'returns empty array with no oscillators' do
230
+ expect(engine.tide_forecast(3600)).to eq([])
231
+ end
232
+
233
+ it 'returns forecast entries for duration' do
234
+ add_primary
235
+ forecast = engine.tide_forecast(3600)
236
+ expect(forecast).not_to be_empty
237
+ end
238
+
239
+ it 'each entry has time, level, and label' do
240
+ add_primary
241
+ entry = engine.tide_forecast(3600).first
242
+ expect(entry[:time]).to be_a(Time)
243
+ expect(entry[:level]).to be_between(0.0, 1.0)
244
+ expect(entry[:label]).to be_a(String)
245
+ end
246
+
247
+ it 'number of steps is ceil(duration / FORECAST_RESOLUTION)' do
248
+ resolution = Legion::Extensions::CognitiveTide::Helpers::Constants::FORECAST_RESOLUTION
249
+ add_primary
250
+ steps = engine.tide_forecast(resolution * 4).size
251
+ expect(steps).to eq(4)
252
+ end
253
+ end
254
+
255
+ describe '#high_tide?' do
256
+ it 'returns true when level >= 0.65' do
257
+ t = Time.utc(2026, 1, 1)
258
+ allow(Time).to receive(:now).and_return(t)
259
+ engine.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: 1.0,
260
+ phase_offset: Math::PI / 2.0)
261
+ expect(engine.high_tide?).to be(true)
262
+ end
263
+
264
+ it 'returns false when level < 0.65' do
265
+ t = Time.utc(2026, 1, 1)
266
+ allow(Time).to receive(:now).and_return(t)
267
+ engine.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: 1.0,
268
+ phase_offset: -Math::PI / 2.0)
269
+ expect(engine.high_tide?).to be(false)
270
+ end
271
+ end
272
+
273
+ describe '#low_tide?' do
274
+ it 'returns true when level <= 0.35' do
275
+ t = Time.utc(2026, 1, 1)
276
+ allow(Time).to receive(:now).and_return(t)
277
+ engine.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: 1.0,
278
+ phase_offset: -Math::PI / 2.0)
279
+ expect(engine.low_tide?).to be(true)
280
+ end
281
+
282
+ it 'returns false when level > 0.35' do
283
+ t = Time.utc(2026, 1, 1)
284
+ allow(Time).to receive(:now).and_return(t)
285
+ engine.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: 1.0,
286
+ phase_offset: Math::PI / 2.0)
287
+ expect(engine.low_tide?).to be(false)
288
+ end
289
+ end
290
+
291
+ describe '#tide_report' do
292
+ it 'returns a hash with expected keys' do
293
+ add_primary
294
+ report = engine.tide_report
295
+ expect(report.keys).to include(:level, :phase, :label, :oscillator_count, :pool_count,
296
+ :high_tide, :low_tide, :pools, :oscillators)
297
+ end
298
+
299
+ it 'oscillator_count matches registered oscillators' do
300
+ add_primary
301
+ add_secondary
302
+ expect(engine.tide_report[:oscillator_count]).to eq(2)
303
+ end
304
+
305
+ it 'pool_count matches created pools' do
306
+ engine.create_pool(domain: 'alpha')
307
+ engine.create_pool(domain: 'beta')
308
+ expect(engine.tide_report[:pool_count]).to eq(2)
309
+ end
310
+
311
+ it 'pools is an array of pool hashes' do
312
+ engine.create_pool(domain: 'phi')
313
+ pools = engine.tide_report[:pools]
314
+ expect(pools).to be_an(Array)
315
+ expect(pools.first).to be_a(Hash)
316
+ end
317
+
318
+ it 'oscillators is an array of oscillator hashes' do
319
+ add_primary
320
+ osc_list = engine.tide_report[:oscillators]
321
+ expect(osc_list).to be_an(Array)
322
+ expect(osc_list.first).to be_a(Hash)
323
+ end
324
+ end
325
+ end
@@ -0,0 +1,249 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::CognitiveTide::Runners::CognitiveTide do
4
+ let(:engine) { Legion::Extensions::CognitiveTide::Helpers::TideEngine.new }
5
+
6
+ # Use extend self — call module methods directly
7
+ subject(:runner) { described_class }
8
+
9
+ describe '.add_oscillator' do
10
+ it 'returns success: true with oscillator hash' do
11
+ result = runner.add_oscillator(oscillator_type: :primary, period: 86_400, engine: engine)
12
+ expect(result[:success]).to be(true)
13
+ expect(result[:oscillator]).to be_a(Hash)
14
+ end
15
+
16
+ it 'adds the oscillator to the engine' do
17
+ runner.add_oscillator(oscillator_type: :primary, period: 3600, engine: engine)
18
+ expect(engine.oscillators.size).to eq(1)
19
+ end
20
+
21
+ it 'accepts all oscillator_types' do
22
+ %i[primary secondary lunar].each do |type|
23
+ result = runner.add_oscillator(oscillator_type: type, period: 3600, engine: engine)
24
+ expect(result[:success]).to be(true)
25
+ end
26
+ end
27
+
28
+ it 'returns success: false for unknown oscillator_type' do
29
+ result = runner.add_oscillator(oscillator_type: :invalid, period: 3600, engine: engine)
30
+ expect(result[:success]).to be(false)
31
+ expect(result[:error]).to be_a(String)
32
+ end
33
+
34
+ it 'returns success: false for non-positive period' do
35
+ result = runner.add_oscillator(oscillator_type: :primary, period: 0, engine: engine)
36
+ expect(result[:success]).to be(false)
37
+ end
38
+
39
+ it 'accepts amplitude and phase_offset kwargs' do
40
+ result = runner.add_oscillator(oscillator_type: :secondary, period: 43_200,
41
+ amplitude: 0.5, phase_offset: 1.5, engine: engine)
42
+ expect(result[:success]).to be(true)
43
+ expect(result[:oscillator][:amplitude]).to eq(0.5)
44
+ end
45
+
46
+ it 'accepts extra kwargs via ** splat without error' do
47
+ result = runner.add_oscillator(oscillator_type: :primary, period: 3600,
48
+ extra_key: 'ignored', engine: engine)
49
+ expect(result[:success]).to be(true)
50
+ end
51
+ end
52
+
53
+ describe '.check_tide' do
54
+ before { runner.add_oscillator(oscillator_type: :primary, period: 86_400, engine: engine) }
55
+
56
+ it 'returns success: true' do
57
+ expect(runner.check_tide(engine: engine)[:success]).to be(true)
58
+ end
59
+
60
+ it 'returns level in [0, 1]' do
61
+ level = runner.check_tide(engine: engine)[:level]
62
+ expect(level).to be >= 0.0
63
+ expect(level).to be <= 1.0
64
+ end
65
+
66
+ it 'returns a valid phase symbol' do
67
+ phase = runner.check_tide(engine: engine)[:phase]
68
+ expect(Legion::Extensions::CognitiveTide::Helpers::Constants::TIDE_PHASES).to include(phase)
69
+ end
70
+
71
+ it 'returns a string label' do
72
+ expect(runner.check_tide(engine: engine)[:label]).to be_a(String)
73
+ end
74
+
75
+ it 'works with no oscillators (returns 0.0 level)' do
76
+ empty_engine = Legion::Extensions::CognitiveTide::Helpers::TideEngine.new
77
+ result = runner.check_tide(engine: empty_engine)
78
+ expect(result[:success]).to be(true)
79
+ expect(result[:level]).to eq(0.0)
80
+ end
81
+ end
82
+
83
+ describe '.deposit_idea' do
84
+ it 'deposits an idea and returns success: true' do
85
+ result = runner.deposit_idea(domain: 'philosophy', idea: 'consciousness is emergent',
86
+ engine: engine)
87
+ expect(result[:success]).to be(true)
88
+ end
89
+
90
+ it 'returns domain in response' do
91
+ result = runner.deposit_idea(domain: 'test', idea: 'x', engine: engine)
92
+ expect(result[:domain]).to eq('test')
93
+ end
94
+
95
+ it 'skips deposit when tide is above threshold' do
96
+ t = Time.utc(2026, 1, 1)
97
+ allow(Time).to receive(:now).and_return(t)
98
+ engine.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: 1.0,
99
+ phase_offset: Math::PI / 2.0)
100
+ result = runner.deposit_idea(domain: 'ideas', idea: 'blocked', tide_threshold: 0.1, engine: engine)
101
+ expect(result[:success]).to be(false)
102
+ expect(result[:reason]).to eq(:tide_too_high)
103
+ end
104
+
105
+ it 'deposits when tide is below threshold' do
106
+ t = Time.utc(2026, 1, 1)
107
+ allow(Time).to receive(:now).and_return(t)
108
+ engine.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: 1.0,
109
+ phase_offset: -Math::PI / 2.0)
110
+ result = runner.deposit_idea(domain: 'ideas', idea: 'allowed', tide_threshold: 0.5, engine: engine)
111
+ expect(result[:success]).to be(true)
112
+ end
113
+
114
+ it 'skips threshold check when tide_threshold is nil' do
115
+ result = runner.deposit_idea(domain: 'ideas', idea: 'any tide', tide_threshold: nil, engine: engine)
116
+ expect(result[:success]).to be(true)
117
+ end
118
+
119
+ it 'accepts ** splat kwargs' do
120
+ result = runner.deposit_idea(domain: 'ideas', idea: 'test', extra: 'ignored', engine: engine)
121
+ expect(result[:success]).to be(true)
122
+ end
123
+ end
124
+
125
+ describe '.harvest' do
126
+ before do
127
+ engine.add_oscillator(oscillator_type: :primary, period: 86_400, amplitude: 1.0)
128
+ runner.deposit_idea(domain: 'ideas', idea: 'harvest me', engine: engine)
129
+ end
130
+
131
+ it 'returns success: true' do
132
+ result = runner.harvest(engine: engine)
133
+ expect(result[:success]).to be(true)
134
+ end
135
+
136
+ it 'returns harvested hash and total_items count' do
137
+ allow(engine).to receive(:rising?).and_return(true)
138
+ result = runner.harvest(engine: engine)
139
+ expect(result[:harvested]).to be_a(Hash)
140
+ expect(result[:total_items]).to be_a(Integer)
141
+ end
142
+
143
+ it 'returns total_items: 0 when not rising' do
144
+ allow(engine).to receive(:rising?).and_return(false)
145
+ result = runner.harvest(engine: engine)
146
+ expect(result[:total_items]).to eq(0)
147
+ end
148
+
149
+ it 'accepts min_depth kwarg' do
150
+ allow(engine).to receive(:rising?).and_return(true)
151
+ result = runner.harvest(min_depth: 0.99, engine: engine)
152
+ expect(result[:success]).to be(true)
153
+ # pool depth is well below 0.99, so nothing harvested
154
+ expect(result[:total_items]).to eq(0)
155
+ end
156
+
157
+ it 'accepts ** splat kwargs' do
158
+ result = runner.harvest(extra: 'ignored', engine: engine)
159
+ expect(result[:success]).to be(true)
160
+ end
161
+ end
162
+
163
+ describe '.tide_forecast' do
164
+ before { engine.add_oscillator(oscillator_type: :primary, period: 86_400) }
165
+
166
+ it 'returns success: true' do
167
+ result = runner.tide_forecast(duration: 3600, engine: engine)
168
+ expect(result[:success]).to be(true)
169
+ end
170
+
171
+ it 'returns forecast array' do
172
+ result = runner.tide_forecast(duration: 3600, engine: engine)
173
+ expect(result[:forecast]).to be_an(Array)
174
+ end
175
+
176
+ it 'returns correct duration in response' do
177
+ result = runner.tide_forecast(duration: 7200, engine: engine)
178
+ expect(result[:duration]).to eq(7200)
179
+ end
180
+
181
+ it 'returns empty forecast for engine with no oscillators' do
182
+ empty_engine = Legion::Extensions::CognitiveTide::Helpers::TideEngine.new
183
+ result = runner.tide_forecast(duration: 3600, engine: empty_engine)
184
+ expect(result[:forecast]).to eq([])
185
+ end
186
+
187
+ it 'accepts ** splat kwargs' do
188
+ result = runner.tide_forecast(duration: 3600, extra: 'ignored', engine: engine)
189
+ expect(result[:success]).to be(true)
190
+ end
191
+ end
192
+
193
+ describe '.tide_status' do
194
+ before { engine.add_oscillator(oscillator_type: :primary, period: 86_400) }
195
+
196
+ it 'returns success: true' do
197
+ expect(runner.tide_status(engine: engine)[:success]).to be(true)
198
+ end
199
+
200
+ it 'includes tide report fields' do
201
+ result = runner.tide_status(engine: engine)
202
+ expect(result.keys).to include(:level, :phase, :label, :oscillator_count, :pool_count)
203
+ end
204
+
205
+ it 'returns oscillator_count matching registered oscillators' do
206
+ expect(runner.tide_status(engine: engine)[:oscillator_count]).to eq(1)
207
+ end
208
+
209
+ it 'accepts ** splat kwargs' do
210
+ result = runner.tide_status(extra: 'ignored', engine: engine)
211
+ expect(result[:success]).to be(true)
212
+ end
213
+ end
214
+
215
+ describe '.tide_maintenance' do
216
+ before { engine.add_oscillator(oscillator_type: :primary, period: 86_400) }
217
+
218
+ it 'returns pools_maintained, current_phase, and tide_level' do
219
+ result = runner.tide_maintenance(engine: engine)
220
+ expect(result).to include(:pools_maintained, :current_phase, :tide_level)
221
+ end
222
+
223
+ it 'returns pools_maintained as an integer' do
224
+ expect(runner.tide_maintenance(engine: engine)[:pools_maintained]).to be_a(Integer)
225
+ end
226
+
227
+ it 'returns a valid phase symbol' do
228
+ phase = runner.tide_maintenance(engine: engine)[:current_phase]
229
+ expect(Legion::Extensions::CognitiveTide::Helpers::Constants::TIDE_PHASES).to include(phase)
230
+ end
231
+
232
+ it 'returns tide_level in [0, 1]' do
233
+ level = runner.tide_maintenance(engine: engine)[:tide_level]
234
+ expect(level).to be >= 0.0
235
+ expect(level).to be <= 1.0
236
+ end
237
+
238
+ it 'reflects deposited pools in pools_maintained' do
239
+ engine.deposit_to_pool(domain: 'ideas', item: 'test idea')
240
+ result = runner.tide_maintenance(engine: engine)
241
+ expect(result[:pools_maintained]).to eq(1)
242
+ end
243
+
244
+ it 'accepts ** splat kwargs' do
245
+ result = runner.tide_maintenance(extra: 'ignored', engine: engine)
246
+ expect(result).to include(:pools_maintained)
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,27 @@
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
+ end
18
+ end
19
+
20
+ require 'legion/extensions/cognitive_tide'
21
+ require 'legion/extensions/cognitive_tide/client'
22
+
23
+ RSpec.configure do |config|
24
+ config.example_status_persistence_file_path = '.rspec_status'
25
+ config.disable_monkey_patching!
26
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
27
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-cognitive-tide
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
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: Circadian-like cognitive rhythm engine for brain-modeled agentic AI —
27
+ tidal oscillators, composite tide levels, and tidal pool idea accumulation
28
+ email:
29
+ - matthewdiverson@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Gemfile
35
+ - LICENSE
36
+ - README.md
37
+ - lex-cognitive-tide.gemspec
38
+ - lib/legion/extensions/cognitive_tide.rb
39
+ - lib/legion/extensions/cognitive_tide/actors/tide_cycle.rb
40
+ - lib/legion/extensions/cognitive_tide/client.rb
41
+ - lib/legion/extensions/cognitive_tide/helpers/constants.rb
42
+ - lib/legion/extensions/cognitive_tide/helpers/oscillator.rb
43
+ - lib/legion/extensions/cognitive_tide/helpers/tidal_pool.rb
44
+ - lib/legion/extensions/cognitive_tide/helpers/tide_engine.rb
45
+ - lib/legion/extensions/cognitive_tide/runners/cognitive_tide.rb
46
+ - lib/legion/extensions/cognitive_tide/version.rb
47
+ - spec/legion/extensions/cognitive_tide/actors/tide_cycle_spec.rb
48
+ - spec/legion/extensions/cognitive_tide/client_spec.rb
49
+ - spec/legion/extensions/cognitive_tide/helpers/constants_spec.rb
50
+ - spec/legion/extensions/cognitive_tide/helpers/oscillator_spec.rb
51
+ - spec/legion/extensions/cognitive_tide/helpers/tidal_pool_spec.rb
52
+ - spec/legion/extensions/cognitive_tide/helpers/tide_engine_spec.rb
53
+ - spec/legion/extensions/cognitive_tide/runners/cognitive_tide_spec.rb
54
+ - spec/spec_helper.rb
55
+ homepage: https://github.com/LegionIO/lex-cognitive-tide
56
+ licenses:
57
+ - MIT
58
+ metadata:
59
+ homepage_uri: https://github.com/LegionIO/lex-cognitive-tide
60
+ source_code_uri: https://github.com/LegionIO/lex-cognitive-tide
61
+ documentation_uri: https://github.com/LegionIO/lex-cognitive-tide
62
+ changelog_uri: https://github.com/LegionIO/lex-cognitive-tide
63
+ bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-tide/issues
64
+ rubygems_mfa_required: 'true'
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '3.4'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubygems_version: 3.6.9
80
+ specification_version: 4
81
+ summary: LEX CognitiveTide
82
+ test_files: []