lex-agentic-executive 0.1.0 → 0.1.4

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 (27) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +50 -3
  4. data/lib/legion/extensions/agentic/executive/chunking/helpers/constants.rb +1 -1
  5. data/lib/legion/extensions/agentic/executive/disengagement/helpers/disengagement_engine.rb +5 -0
  6. data/lib/legion/extensions/agentic/executive/disengagement/version.rb +1 -1
  7. data/lib/legion/extensions/agentic/executive/dissonance_resolution/helpers/resolution_engine.rb +2 -0
  8. data/lib/legion/extensions/agentic/executive/dissonance_resolution/version.rb +1 -1
  9. data/lib/legion/extensions/agentic/executive/dual_process/helpers/dual_process_engine.rb +2 -0
  10. data/lib/legion/extensions/agentic/executive/dual_process/version.rb +1 -1
  11. data/lib/legion/extensions/agentic/executive/inhibition/helpers/inhibition_store.rb +2 -0
  12. data/lib/legion/extensions/agentic/executive/inhibition/version.rb +1 -1
  13. data/lib/legion/extensions/agentic/executive/version.rb +1 -1
  14. data/lib/legion/extensions/agentic/executive/volition/runners/volition.rb +32 -0
  15. data/lib/legion/extensions/agentic/executive/working_memory/helpers/constants.rb +1 -1
  16. data/lib/legion/extensions/agentic/executive/working_memory/version.rb +1 -1
  17. data/spec/legion/extensions/agentic/executive/chunking/helpers/chunking_engine_spec.rb +1 -1
  18. data/spec/legion/extensions/agentic/executive/chunking/helpers/constants_spec.rb +2 -2
  19. data/spec/legion/extensions/agentic/executive/chunking/runners/cognitive_chunking_spec.rb +1 -1
  20. data/spec/legion/extensions/agentic/executive/disengagement/helpers/disengagement_engine_spec.rb +13 -0
  21. data/spec/legion/extensions/agentic/executive/dissonance_resolution/helpers/resolution_engine_spec.rb +13 -0
  22. data/spec/legion/extensions/agentic/executive/dual_process/helpers/dual_process_engine_spec.rb +15 -0
  23. data/spec/legion/extensions/agentic/executive/inhibition/helpers/inhibition_store_spec.rb +12 -0
  24. data/spec/legion/extensions/agentic/executive/volition/runners/volition_spec.rb +55 -0
  25. data/spec/legion/extensions/agentic/executive/working_memory/client_spec.rb +3 -3
  26. data/spec/legion/extensions/agentic/executive/working_memory/helpers/constants_spec.rb +2 -2
  27. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d156eef0f39f669acfc3f33e496196921f1b34e882c810d1416740349fc4fb84
4
- data.tar.gz: 97171fb40218dca7e06373731545b30e6eadc36a51c649b3e68e75d7e067e509
3
+ metadata.gz: 23b732c1b95a31e26ca8ac967dc4c6902ab7164afdd5756f8e61ddb9306c86b8
4
+ data.tar.gz: 2c0de464889108f22b0602433f7d1903a9f46523733e1dc3a644126a34ba70f3
5
5
  SHA512:
6
- metadata.gz: 97708ee5421c6401db3bd4899e1c0c6f62e059dfe6687d9524327e52b0b7c07ebcae937e8f5da1312467e082d8a56c5123064a0390b696cbbcb2de3b4adbbc72
7
- data.tar.gz: 77360d4645be017e164d28feb1420890e990661091261a6dcc0bc15b84f169af3346a3e63af38e71162c079513357d780dffd7b073a43fd0015aa5dc79bc07ea
6
+ metadata.gz: e5f64ae22b38be241957bfc1fe828ec2060ab4241765e8927353123bfb6af4042997f885ee8a831ffce3680a0f29715859a8509c96d8a853461acc18892c18bd
7
+ data.tar.gz: 5bc0e25e7e2c76c4ff513337288d47a88b2ef02bc5a5ccdee24f4b2569700b3555b6c1c19a4024656cccfac9d1ceceaa1adccef5fe976f379c69c2dd5a3e62d9
data/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.1.3] - 2026-03-21
6
+
7
+ ### Changed
8
+ - Working memory CAPACITY reduced from 7 to 4 (Cowan 2001)
9
+ - Chunking WORKING_MEMORY_CAPACITY updated from 7 to 4
10
+ - Effective max remains 7 via CHUNK_BONUS (4 base + 3 bonus)
11
+
12
+ ## [0.1.1] - 2026-03-18
13
+
14
+ ### Changed
15
+ - Enforce IMPULSE_TYPES validation in InhibitionStore#create_impulse (returns nil for invalid type)
16
+ - Enforce STRATEGIES validation in ResolutionEngine#apply_strategy (returns nil for invalid strategy)
17
+ - Enforce DISENGAGE_REASONS validation in DisengagementEngine#disengage_goal (raises ArgumentError)
18
+ - Enforce DECISION_OUTCOMES validation in DualProcessEngine#record_outcome (returns failure hash)
19
+
5
20
  ## [0.1.0] - 2026-03-18
6
21
 
7
22
  ### Added
data/README.md CHANGED
@@ -1,13 +1,60 @@
1
1
  # lex-agentic-executive
2
2
 
3
- LEX agentic executive domain: planning, working memory, cognitive control
3
+ Domain consolidation gem for executive function, goal management, planning, and cognitive control. Bundles 23 source extensions into one loadable unit under `Legion::Extensions::Agentic::Executive`.
4
4
 
5
- ## Sub-modules
5
+ ## Overview
6
6
 
7
- *(populated as extensions are consolidated)*
7
+ **Gem**: `lex-agentic-executive`
8
+ **Version**: 0.1.1
9
+ **Namespace**: `Legion::Extensions::Agentic::Executive`
10
+
11
+ ## Sub-Modules
12
+
13
+ | Sub-Module | Source Gem | Purpose |
14
+ |---|---|---|
15
+ | `Executive::Control` | `lex-cognitive-control` | Conflict monitoring, error detection, adaptive control signals |
16
+ | `Executive::ExecutiveFunction` | `lex-executive-function` | Miyake three-factor model: updating, flexibility, inhibition |
17
+ | `Executive::GoalManagement` | `lex-goal-management` | Hierarchical goal registry — decomposition, priority, lifecycle |
18
+ | `Executive::Inhibition` | `lex-inhibition` | Stop-signal model, prepotent response suppression |
19
+ | `Executive::Planning` | `lex-planning` | Goal-directed plan management — dependency graphs, replan limit |
20
+ | `Executive::Volition` | `lex-volition` | Five drives synthesized into intention stack — maps to `action_selection` tick phase |
21
+ | `Executive::WorkingMemory` | `lex-working-memory` | Baddeley & Hitch — capacity-limited buffer, verbal/spatial/episodic channels |
22
+ | `Executive::Flexibility` | `lex-cognitive-flexibility` | Cognitive flexibility — task switching, mental set shifting |
23
+ | `Executive::FlexibilityTraining` | `lex-cognitive-flexibility-training` | Structured training for cognitive flexibility improvement |
24
+ | `Executive::Load` | `lex-cognitive-load` | Sweller three-component model — intrinsic/extraneous/germane load |
25
+ | `Executive::LoadBalancing` | `lex-cognitive-load-balancing` | Load distribution across cognitive resources |
26
+ | `Executive::Disengagement` | `lex-cognitive-disengagement` | Controlled disengagement from tasks or mental sets |
27
+ | `Executive::Triage` | `lex-cognitive-triage` | Priority-based task selection under resource constraints |
28
+ | `Executive::Chunking` | `lex-cognitive-chunking` | Information compression into manageable units |
29
+ | `Executive::Inertia` | `lex-cognitive-inertia` | Resistance to switching — persistence in current cognitive mode |
30
+ | `Executive::Dwell` | `lex-cognitive-dwell` | Sustained focus on a single topic or problem |
31
+ | `Executive::Autopilot` | `lex-cognitive-autopilot` | Habitual/automatic processing mode |
32
+ | `Executive::DissonanceResolution` | `lex-cognitive-dissonance-resolution` | Resolution strategies for cognitive dissonance |
33
+ | `Executive::Compass` | `lex-cognitive-compass` | Goal-direction and navigation toward targets |
34
+ | `Executive::DecisionFatigue` | `lex-decision-fatigue` | Decision quality degradation after sustained choices |
35
+ | `Executive::DualProcess` | `lex-dual-process` | Kahneman System 1/System 2 routing |
36
+ | `Executive::ProspectiveMemory` | `lex-prospective-memory` | Memory for future intentions — reminder management |
37
+ | `Executive::CognitiveDebt` | `lex-cognitive-debt` | Accumulated cognitive obligations and deferred processing |
38
+
39
+ ## Actors
40
+
41
+ - `Executive::ExecutiveFunction::Actors::Recovery` — interval actor, runs executive function recovery cycle
42
+ - `Executive::Flexibility::Actors::Tick` — interval actor, processes cognitive flexibility tick
8
43
 
9
44
  ## Installation
10
45
 
11
46
  ```ruby
12
47
  gem 'lex-agentic-executive'
13
48
  ```
49
+
50
+ ## Development
51
+
52
+ ```bash
53
+ bundle install
54
+ bundle exec rspec # 2067 examples, 0 failures
55
+ bundle exec rubocop # 0 offenses
56
+ ```
57
+
58
+ ## License
59
+
60
+ MIT
@@ -9,7 +9,7 @@ module Legion
9
9
  module Constants
10
10
  MAX_ITEMS = 500
11
11
  MAX_CHUNKS = 200
12
- WORKING_MEMORY_CAPACITY = 7 # Miller's magic number
12
+ WORKING_MEMORY_CAPACITY = 4 # Cowan (2001) core capacity
13
13
  CAPACITY_VARIANCE = 2 # +/- 2
14
14
  DEFAULT_COHERENCE = 0.5
15
15
  COHERENCE_BOOST = 0.08
@@ -42,6 +42,11 @@ module Legion
42
42
  end
43
43
 
44
44
  def disengage_goal(goal_id:, reason:)
45
+ unless Constants::DISENGAGE_REASONS.include?(reason.to_sym)
46
+ raise ArgumentError,
47
+ "invalid reason: #{reason.inspect}, must be one of #{Constants::DISENGAGE_REASONS}"
48
+ end
49
+
45
50
  goal = fetch_goal!(goal_id)
46
51
  goal.disengage!(reason: reason)
47
52
  goal
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Executive
7
7
  module Disengagement
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -32,6 +32,8 @@ module Legion
32
32
  return nil unless conflict
33
33
 
34
34
  strat = strategy.to_sym
35
+ return nil unless STRATEGIES.include?(strat)
36
+
35
37
  @strategy_history[strat] += 1
36
38
  conflict.apply_strategy!(strategy: strat, effectiveness: effectiveness)
37
39
  @strategy_successes[strat] += 1 if conflict.resolved?
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Executive
7
7
  module DissonanceResolution
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -92,6 +92,8 @@ module Legion
92
92
  end
93
93
 
94
94
  def record_outcome(decision_id:, outcome:)
95
+ return { success: false, reason: :invalid_outcome } unless Constants::DECISION_OUTCOMES.include?(outcome)
96
+
95
97
  decision = @decisions.find { |d| d.id == decision_id }
96
98
  return { success: false, reason: :not_found } unless decision
97
99
 
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Executive
7
7
  module DualProcess
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -15,6 +15,8 @@ module Legion
15
15
  end
16
16
 
17
17
  def create_impulse(type:, action:, strength:, source: nil, context: {})
18
+ return nil unless Constants::IMPULSE_TYPES.include?(type.to_sym)
19
+
18
20
  resolved_strength = resolve_strength(strength)
19
21
 
20
22
  impulse = Impulse.new(
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Executive
7
7
  module Inhibition
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Executive
7
- VERSION = '0.1.0'
7
+ VERSION = '0.1.4'
8
8
  end
9
9
  end
10
10
  end
@@ -76,6 +76,38 @@ module Legion
76
76
  { status: result, intention_id: intention_id }
77
77
  end
78
78
 
79
+ def form_absorption_intention(domains_at_risk:, neighboring_agents: [], severity: :warning, **)
80
+ domains = Array(domains_at_risk)
81
+ neighbors = Array(neighboring_agents)
82
+
83
+ return { success: false, reason: :no_domains } if domains.empty?
84
+
85
+ base_salience = severity.to_sym == :critical ? 0.85 : 0.55
86
+ salience = [base_salience + (domains.size * 0.05), 1.0].min
87
+
88
+ intention = Helpers::Intention.new_intention(
89
+ drive: :epistemic,
90
+ domain: :knowledge,
91
+ goal: "absorb knowledge for domains: #{domains.join(', ')}",
92
+ salience: salience,
93
+ context: { domains_at_risk: domains, target_agents: neighbors, severity: severity,
94
+ triggered_by: :knowledge_vulnerability }
95
+ )
96
+
97
+ result = intention_stack.push(intention)
98
+ Legion::Logging.info "[volition] absorption intention formed: domains=#{domains.join(',')} " \
99
+ "neighbors=#{neighbors.size} salience=#{salience.round(2)} result=#{result}"
100
+
101
+ {
102
+ success: %i[pushed duplicate].include?(result),
103
+ result: result,
104
+ intention_id: intention[:intention_id],
105
+ salience: salience,
106
+ domains: domains,
107
+ targets: neighbors
108
+ }
109
+ end
110
+
79
111
  def volition_status(**)
80
112
  stats = intention_stack.stats
81
113
  drives = Helpers::DriveSynthesizer.synthesize(tick_results: {}, cognitive_state: {})
@@ -7,7 +7,7 @@ module Legion
7
7
  module WorkingMemory
8
8
  module Helpers
9
9
  module Constants
10
- CAPACITY = 7
10
+ CAPACITY = 4
11
11
 
12
12
  CHUNK_BONUS = 3
13
13
 
@@ -5,7 +5,7 @@ module Legion
5
5
  module Agentic
6
6
  module Executive
7
7
  module WorkingMemory
8
- VERSION = '0.1.0'
8
+ VERSION = '0.1.1'
9
9
  end
10
10
  end
11
11
  end
@@ -174,7 +174,7 @@ RSpec.describe Legion::Extensions::Agentic::Executive::Chunking::Helpers::Chunki
174
174
  id = engine.add_item(content: 'x')[:item_id]
175
175
  cid = engine.create_chunk(label: 'x', item_ids: [id])[:chunk_id]
176
176
  engine.load_to_working_memory(chunk_id: cid)
177
- expected = (1.0 / 7).round(10)
177
+ expected = (1.0 / 4).round(10)
178
178
  expect(engine.working_memory_load).to be_within(0.0001).of(expected)
179
179
  end
180
180
  end
@@ -10,8 +10,8 @@ RSpec.describe Legion::Extensions::Agentic::Executive::Chunking::Helpers::Consta
10
10
  expect(described_class::MAX_CHUNKS).to eq(200)
11
11
  end
12
12
 
13
- it 'defines WORKING_MEMORY_CAPACITY as 7' do
14
- expect(described_class::WORKING_MEMORY_CAPACITY).to eq(7)
13
+ it 'defines WORKING_MEMORY_CAPACITY as 4' do
14
+ expect(described_class::WORKING_MEMORY_CAPACITY).to eq(4)
15
15
  end
16
16
 
17
17
  it 'defines CAPACITY_VARIANCE as 2' do
@@ -97,7 +97,7 @@ RSpec.describe Legion::Extensions::Agentic::Executive::Chunking::Runners::Cognit
97
97
  it 'returns success with capacity info' do
98
98
  result = client.working_memory_status(engine: engine)
99
99
  expect(result[:success]).to be true
100
- expect(result[:capacity]).to eq(7)
100
+ expect(result[:capacity]).to eq(4)
101
101
  end
102
102
 
103
103
  it 'returns a capacity label' do
@@ -77,6 +77,19 @@ RSpec.describe Legion::Extensions::Agentic::Executive::Disengagement::Helpers::D
77
77
  expect { engine.disengage_goal(goal_id: 'nope', reason: :sunk_cost) }
78
78
  .to raise_error(ArgumentError)
79
79
  end
80
+
81
+ it 'raises ArgumentError for invalid reason' do
82
+ expect { engine.disengage_goal(goal_id: goal.id, reason: :boredom) }
83
+ .to raise_error(ArgumentError, /invalid reason/)
84
+ end
85
+
86
+ it 'accepts all valid DISENGAGE_REASONS' do
87
+ constants = Legion::Extensions::Agentic::Executive::Disengagement::Helpers::Constants
88
+ constants::DISENGAGE_REASONS.each do |reason|
89
+ g = engine.create_goal(label: "goal_#{reason}", domain: :test)
90
+ expect { engine.disengage_goal(goal_id: g.id, reason: reason) }.not_to raise_error
91
+ end
92
+ end
80
93
  end
81
94
 
82
95
  describe '#stalled_goals' do
@@ -29,6 +29,19 @@ RSpec.describe Legion::Extensions::Agentic::Executive::DissonanceResolution::Hel
29
29
  reframe = report.find { |s| s[:strategy] == :reframe }
30
30
  expect(reframe[:uses]).to eq(1)
31
31
  end
32
+
33
+ it 'rejects invalid strategy' do
34
+ expect(engine.apply_strategy(conflict_id: conflict.id, strategy: :magic)).to be_nil
35
+ end
36
+
37
+ it 'accepts all valid STRATEGIES' do
38
+ constants = Legion::Extensions::Agentic::Executive::DissonanceResolution::Helpers::Constants
39
+ constants::STRATEGIES.each do |strat|
40
+ c = engine.create_conflict(belief_a: 'a', belief_b: 'b')
41
+ result = engine.apply_strategy(conflict_id: c.id, strategy: strat)
42
+ expect(result).not_to be_nil
43
+ end
44
+ end
32
45
  end
33
46
 
34
47
  describe '#escalate_conflict' do
@@ -165,6 +165,21 @@ RSpec.describe Legion::Extensions::Agentic::Executive::DualProcess::Helpers::Dua
165
165
  expect(result[:success]).to be false
166
166
  expect(result[:reason]).to eq(:not_found)
167
167
  end
168
+
169
+ it 'rejects invalid outcome' do
170
+ result = engine.record_outcome(decision_id: decision_id, outcome: :maybe)
171
+ expect(result[:success]).to be false
172
+ expect(result[:reason]).to eq(:invalid_outcome)
173
+ end
174
+
175
+ it 'accepts all valid DECISION_OUTCOMES' do
176
+ constants = Legion::Extensions::Agentic::Executive::DualProcess::Helpers::Constants
177
+ constants::DECISION_OUTCOMES.each do |out|
178
+ did = engine.execute_system_one(query: "test_#{out}", domain: :work)[:decision_id]
179
+ result = engine.record_outcome(decision_id: did, outcome: out)
180
+ expect(result[:success]).to be true
181
+ end
182
+ end
168
183
  end
169
184
 
170
185
  describe '#effort_level' do
@@ -55,6 +55,18 @@ RSpec.describe Legion::Extensions::Agentic::Executive::Inhibition::Helpers::Inhi
55
55
  impulse = store.create_impulse(type: :reactive, action: :act, strength: :unknown_level)
56
56
  expect(impulse.strength).to eq(Legion::Extensions::Agentic::Executive::Inhibition::Helpers::Constants::IMPULSE_STRENGTHS[:moderate])
57
57
  end
58
+
59
+ it 'rejects invalid impulse type' do
60
+ expect(store.create_impulse(type: :telepathic, action: :act, strength: :moderate)).to be_nil
61
+ end
62
+
63
+ it 'accepts all valid IMPULSE_TYPES' do
64
+ constants = Legion::Extensions::Agentic::Executive::Inhibition::Helpers::Constants
65
+ constants::IMPULSE_TYPES.each do |itype|
66
+ result = store.create_impulse(type: itype, action: :act, strength: :moderate)
67
+ expect(result).not_to be_nil
68
+ end
69
+ end
58
70
  end
59
71
 
60
72
  describe '#evaluate_and_apply' do
@@ -132,4 +132,59 @@ RSpec.describe Legion::Extensions::Agentic::Executive::Volition::Runners::Voliti
132
132
  expect(result[:count]).to be >= 1
133
133
  end
134
134
  end
135
+
136
+ describe '#form_absorption_intention' do
137
+ it 'returns success false when no domains provided' do
138
+ result = client.form_absorption_intention(domains_at_risk: [])
139
+ expect(result[:success]).to be false
140
+ expect(result[:reason]).to eq(:no_domains)
141
+ end
142
+
143
+ it 'pushes an epistemic absorption intention onto the stack' do
144
+ result = client.form_absorption_intention(
145
+ domains_at_risk: %w[pki dns],
146
+ neighboring_agents: %w[agent-b agent-c]
147
+ )
148
+ expect(result[:success]).to be true
149
+ expect(result[:result]).to eq(:pushed)
150
+ expect(result[:domains]).to eq(%w[pki dns])
151
+ expect(result[:targets]).to eq(%w[agent-b agent-c])
152
+ end
153
+
154
+ it 'returns the intention_id' do
155
+ result = client.form_absorption_intention(domains_at_risk: ['vault'])
156
+ expect(result[:intention_id]).to be_a(String)
157
+ end
158
+
159
+ it 'assigns higher salience for critical severity' do
160
+ warning = client.form_absorption_intention(
161
+ domains_at_risk: ['pki'], severity: :warning
162
+ )
163
+ critical_client = Legion::Extensions::Agentic::Executive::Volition::Client.new
164
+ critical = critical_client.form_absorption_intention(
165
+ domains_at_risk: ['pki'], severity: :critical
166
+ )
167
+ expect(critical[:salience]).to be > warning[:salience]
168
+ end
169
+
170
+ it 'scales salience with number of at-risk domains' do
171
+ few = client.form_absorption_intention(domains_at_risk: ['pki'])
172
+ many_client = Legion::Extensions::Agentic::Executive::Volition::Client.new
173
+ many = many_client.form_absorption_intention(domains_at_risk: %w[pki dns vault ssh consul nomad])
174
+ expect(many[:salience]).to be >= few[:salience]
175
+ end
176
+
177
+ it 'stores knowledge_vulnerability trigger context' do
178
+ result = client.form_absorption_intention(domains_at_risk: ['pki'])
179
+ intention = client.intention_stack.find(result[:intention_id])
180
+ expect(intention[:context][:triggered_by]).to eq(:knowledge_vulnerability)
181
+ end
182
+
183
+ it 'returns :duplicate on second call for same domains (capacity protection)' do
184
+ client.form_absorption_intention(domains_at_risk: ['pki'])
185
+ second = client.form_absorption_intention(domains_at_risk: ['pki'])
186
+ # Either duplicate (same drive/domain/goal match) or pushed — both acceptable
187
+ expect(%i[pushed duplicate]).to include(second[:result])
188
+ end
189
+ end
135
190
  end
@@ -71,10 +71,10 @@ RSpec.describe Legion::Extensions::Agentic::Executive::WorkingMemory::Client do
71
71
  expect(client.working_memory_stats[:size]).to eq(0)
72
72
  end
73
73
 
74
- it 'models the 7 plus-or-minus 2 capacity limit' do
74
+ it 'models the 4 plus-or-minus 2 capacity limit' do
75
75
  # Fill to base capacity
76
- 7.times { |i| client.store_item(content: "item #{i}", priority: :normal) }
77
- expect(client.buffer.size).to eq(7)
76
+ 4.times { |i| client.store_item(content: "item #{i}", priority: :normal) }
77
+ expect(client.buffer.size).to eq(4)
78
78
 
79
79
  # Without chunking, adding more evicts lowest activation
80
80
  3.times { |i| client.store_item(content: "overflow #{i}", priority: :high) }
@@ -4,8 +4,8 @@ require 'spec_helper'
4
4
 
5
5
  RSpec.describe Legion::Extensions::Agentic::Executive::WorkingMemory::Helpers::Constants do
6
6
  describe 'CAPACITY' do
7
- it 'is 7 (Miller\'s Law)' do
8
- expect(described_class::CAPACITY).to eq(7)
7
+ it 'is 4 (Cowan 2001)' do
8
+ expect(described_class::CAPACITY).to eq(4)
9
9
  end
10
10
  end
11
11
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-executive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity