lex-cognitive-load 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 286da45615cc2a0281a12b078a861640e6fa3969660793b81128c9b2393cf57c
4
+ data.tar.gz: 81d620ca1198d6e04d988995cf18ab9c48b77e00d5a720e7f373f3a434cd1d3e
5
+ SHA512:
6
+ metadata.gz: 3a00db5e10f3c239e70c040adf4f79b96387c347d6f32b85c1dd5453fa05da961c7dd97966efa72098cdd8208230b574f6b9854519cf7fc4fc8c75dabbfa728d
7
+ data.tar.gz: 435bf3647f54b89d2e34ac0df27c62c9796d0708b111c01a55d725cb43cf94467d6012f3efe515a2174d2a8b1fe568c59dcf41aafdb445ea69545afdbdc8f6f4
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rake'
8
+ gem 'rspec'
9
+ gem 'rspec_junit_formatter'
10
+ gem 'rubocop', require: false
11
+ gem 'rubocop-rspec', require: false
12
+ gem 'simplecov'
13
+ end
14
+
15
+ gem 'legion-gaia', path: '../../legion-gaia'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matthew Iverson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # lex-cognitive-load
2
+
3
+ Three-component cognitive load tracker for LegionIO cognitive agents. Models intrinsic, extraneous, and germane load using Exponential Moving Average and produces actionable recommendations when the system drifts out of the optimal zone.
4
+
5
+ ## What It Does
6
+
7
+ - Three EMA-tracked components: intrinsic (task complexity), extraneous (overhead/interference), germane (learning effort)
8
+ - Overload detection: total load above 85% of capacity triggers `:simplify` recommendation
9
+ - Underload detection: total load below 25% triggers `:increase_challenge` recommendation
10
+ - Excess extraneous: non-optimal germane ratio triggers `:reduce_overhead` recommendation
11
+ - Decay cycle reduces all components each tick
12
+ - Adjustable capacity ceiling for dynamic situations
13
+
14
+ ## Usage
15
+
16
+ ```ruby
17
+ # Report load events
18
+ runner.report_intrinsic(amount: 0.4) # Task is complex
19
+ runner.report_extraneous(amount: 0.3) # Distracting noise in environment
20
+ runner.report_germane(amount: 0.2) # Actively forming new schemas
21
+
22
+ # Check current state
23
+ runner.load_status
24
+ # => { success: true, intrinsic: 0.XX, extraneous: 0.XX, germane: 0.XX,
25
+ # total_load: 0.XX, load_ratio: 0.XX, overloaded: false, ... }
26
+
27
+ # Get recommendation
28
+ runner.load_recommendation
29
+ # => { success: true, recommendation: :reduce_overhead }
30
+
31
+ # Reduce overhead manually
32
+ runner.reduce_overhead(amount: 0.1)
33
+
34
+ # Trigger decay (called each tick)
35
+ runner.update_cognitive_load
36
+
37
+ # Full stats
38
+ runner.cognitive_load_stats
39
+ ```
40
+
41
+ ## Development
42
+
43
+ ```bash
44
+ bundle install
45
+ bundle exec rspec
46
+ bundle exec rubocop
47
+ ```
48
+
49
+ ## License
50
+
51
+ MIT
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/cognitive_load/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-cognitive-load'
7
+ spec.version = Legion::Extensions::CognitiveLoad::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+
11
+ spec.summary = 'LEX Cognitive Load'
12
+ spec.description = "Sweller's Cognitive Load Theory modeled for brain-based agentic AI: " \
13
+ 'intrinsic, extraneous, and germane load tracking with capacity management'
14
+ spec.homepage = 'https://github.com/LegionIO/lex-cognitive-load'
15
+ spec.license = 'MIT'
16
+ spec.required_ruby_version = '>= 3.4'
17
+
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-cognitive-load'
20
+ spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-cognitive-load'
21
+ spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-cognitive-load'
22
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-cognitive-load/issues'
23
+ spec.metadata['rubygems_mfa_required'] = 'true'
24
+
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ Dir.glob('{lib,spec}/**/*') + %w[lex-cognitive-load.gemspec Gemfile LICENSE README.md]
27
+ end
28
+ spec.require_paths = ['lib']
29
+ spec.add_development_dependency 'legion-gaia'
30
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/cognitive_load/helpers/constants'
4
+ require 'legion/extensions/cognitive_load/helpers/load_model'
5
+ require 'legion/extensions/cognitive_load/runners/cognitive_load'
6
+
7
+ module Legion
8
+ module Extensions
9
+ module CognitiveLoad
10
+ class Client
11
+ include Runners::CognitiveLoad
12
+
13
+ attr_reader :load_model
14
+
15
+ def initialize(load_model: nil, **)
16
+ @load_model = load_model || Helpers::LoadModel.new
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveLoad
6
+ module Helpers
7
+ module Constants
8
+ DEFAULT_CAPACITY = 1.0
9
+ INTRINSIC_ALPHA = 0.15
10
+ EXTRANEOUS_ALPHA = 0.12
11
+ GERMANE_ALPHA = 0.18
12
+ LOAD_DECAY = 0.03
13
+ DEFAULT_INTRINSIC = 0.2
14
+ DEFAULT_EXTRANEOUS = 0.1
15
+ DEFAULT_GERMANE = 0.15
16
+ OVERLOAD_THRESHOLD = 0.85
17
+ UNDERLOAD_THRESHOLD = 0.25
18
+ OPTIMAL_GERMANE_RATIO = 0.4
19
+ MAX_LOAD_HISTORY = 200
20
+
21
+ LOAD_LABELS = {
22
+ (0.85..) => :overloaded,
23
+ (0.6...0.85) => :heavy,
24
+ (0.35...0.6) => :optimal,
25
+ (0.15...0.35) => :light,
26
+ (..0.15) => :idle
27
+ }.freeze
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveLoad
6
+ module Helpers
7
+ class LoadModel
8
+ include Constants
9
+
10
+ attr_reader :intrinsic, :extraneous, :germane, :capacity, :load_history
11
+
12
+ def initialize(capacity: DEFAULT_CAPACITY)
13
+ @intrinsic = DEFAULT_INTRINSIC
14
+ @extraneous = DEFAULT_EXTRANEOUS
15
+ @germane = DEFAULT_GERMANE
16
+ @capacity = capacity.to_f
17
+ @load_history = []
18
+ end
19
+
20
+ def total_load
21
+ raw = @intrinsic + @extraneous + @germane
22
+ raw.clamp(0.0, @capacity)
23
+ end
24
+
25
+ def load_ratio
26
+ return 0.0 if @capacity <= 0.0
27
+
28
+ (total_load / @capacity).clamp(0.0, 1.0)
29
+ end
30
+
31
+ def add_intrinsic(amount:, source: :unknown)
32
+ @intrinsic = ema_update(@intrinsic, amount.to_f.clamp(0.0, 1.0), INTRINSIC_ALPHA)
33
+ record_snapshot(event: :intrinsic_added, source: source)
34
+ self
35
+ end
36
+
37
+ def add_extraneous(amount:, source: :unknown)
38
+ @extraneous = ema_update(@extraneous, amount.to_f.clamp(0.0, 1.0), EXTRANEOUS_ALPHA)
39
+ record_snapshot(event: :extraneous_added, source: source)
40
+ self
41
+ end
42
+
43
+ def add_germane(amount:, source: :unknown)
44
+ @germane = ema_update(@germane, amount.to_f.clamp(0.0, 1.0), GERMANE_ALPHA)
45
+ record_snapshot(event: :germane_added, source: source)
46
+ self
47
+ end
48
+
49
+ def reduce_extraneous(amount:)
50
+ @extraneous = (@extraneous - amount.to_f.clamp(0.0, 1.0)).clamp(0.0, 1.0)
51
+ record_snapshot(event: :extraneous_reduced, source: :explicit)
52
+ self
53
+ end
54
+
55
+ def decay
56
+ @intrinsic = decay_toward(@intrinsic, DEFAULT_INTRINSIC)
57
+ @extraneous = decay_toward(@extraneous, DEFAULT_EXTRANEOUS)
58
+ @germane = decay_toward(@germane, DEFAULT_GERMANE)
59
+ record_snapshot(event: :decay, source: :tick)
60
+ self
61
+ end
62
+
63
+ def adjust_capacity(new_capacity:)
64
+ @capacity = new_capacity.to_f.clamp(0.1, 2.0)
65
+ record_snapshot(event: :capacity_adjusted, source: :external)
66
+ self
67
+ end
68
+
69
+ def overloaded?
70
+ load_ratio >= OVERLOAD_THRESHOLD
71
+ end
72
+
73
+ def underloaded?
74
+ load_ratio <= UNDERLOAD_THRESHOLD
75
+ end
76
+
77
+ def germane_ratio
78
+ return 0.0 if total_load <= 0.0
79
+
80
+ (@germane / total_load).clamp(0.0, 1.0)
81
+ end
82
+
83
+ def load_label
84
+ LOAD_LABELS.each do |range, label|
85
+ return label if range.cover?(load_ratio)
86
+ end
87
+ :idle
88
+ end
89
+
90
+ def recommendation
91
+ return :simplify if overloaded?
92
+ return :increase_challenge if underloaded?
93
+ return :reduce_overhead if @extraneous > (@intrinsic + @germane)
94
+
95
+ :continue
96
+ end
97
+
98
+ def to_h
99
+ {
100
+ intrinsic: @intrinsic.round(4),
101
+ extraneous: @extraneous.round(4),
102
+ germane: @germane.round(4),
103
+ total_load: total_load.round(4),
104
+ capacity: @capacity.round(4),
105
+ load_ratio: load_ratio.round(4),
106
+ germane_ratio: germane_ratio.round(4),
107
+ load_label: load_label,
108
+ overloaded: overloaded?,
109
+ underloaded: underloaded?,
110
+ recommendation: recommendation,
111
+ history_size: @load_history.size
112
+ }
113
+ end
114
+
115
+ private
116
+
117
+ def ema_update(current, new_value, alpha)
118
+ ((alpha * new_value) + ((1.0 - alpha) * current)).clamp(0.0, 1.0)
119
+ end
120
+
121
+ def decay_toward(current, resting)
122
+ delta = current - resting
123
+ (current - (delta * LOAD_DECAY)).clamp(0.0, 1.0)
124
+ end
125
+
126
+ def record_snapshot(event:, source:)
127
+ @load_history << {
128
+ timestamp: Time.now.utc,
129
+ event: event,
130
+ source: source,
131
+ intrinsic: @intrinsic.round(4),
132
+ extraneous: @extraneous.round(4),
133
+ germane: @germane.round(4),
134
+ load_ratio: load_ratio.round(4)
135
+ }
136
+ @load_history.shift while @load_history.size > MAX_LOAD_HISTORY
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveLoad
6
+ module Runners
7
+ module CognitiveLoad
8
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
9
+ Legion::Extensions::Helpers.const_defined?(:Lex)
10
+
11
+ def report_intrinsic(amount:, source: :unknown, **)
12
+ model = load_model
13
+ model.add_intrinsic(amount: amount, source: source)
14
+ Legion::Logging.debug "[cognitive_load] intrinsic reported: amount=#{amount} source=#{source} " \
15
+ "ratio=#{model.load_ratio.round(2)} label=#{model.load_label}"
16
+ { success: true, load_type: :intrinsic, amount: amount, source: source, current_state: model.to_h }
17
+ end
18
+
19
+ def report_extraneous(amount:, source: :unknown, **)
20
+ model = load_model
21
+ model.add_extraneous(amount: amount, source: source)
22
+ Legion::Logging.debug "[cognitive_load] extraneous reported: amount=#{amount} source=#{source} " \
23
+ "ratio=#{model.load_ratio.round(2)} label=#{model.load_label}"
24
+ { success: true, load_type: :extraneous, amount: amount, source: source, current_state: model.to_h }
25
+ end
26
+
27
+ def report_germane(amount:, source: :unknown, **)
28
+ model = load_model
29
+ model.add_germane(amount: amount, source: source)
30
+ Legion::Logging.debug "[cognitive_load] germane reported: amount=#{amount} source=#{source} " \
31
+ "ratio=#{model.load_ratio.round(2)} label=#{model.load_label}"
32
+ { success: true, load_type: :germane, amount: amount, source: source, current_state: model.to_h }
33
+ end
34
+
35
+ def reduce_overhead(amount:, **)
36
+ model = load_model
37
+ before = model.extraneous
38
+ model.reduce_extraneous(amount: amount)
39
+ after = model.extraneous
40
+ Legion::Logging.debug "[cognitive_load] overhead reduced: before=#{before.round(2)} after=#{after.round(2)} delta=#{(before - after).round(2)}"
41
+ { success: true, before: before.round(4), after: after.round(4), delta: (before - after).round(4), current_state: model.to_h }
42
+ end
43
+
44
+ def update_cognitive_load(**)
45
+ model = load_model
46
+ model.decay
47
+ snapshot = model.to_h
48
+ Legion::Logging.debug "[cognitive_load] tick decay: ratio=#{snapshot[:load_ratio]} label=#{snapshot[:load_label]}"
49
+ { success: true, action: :decay, current_state: snapshot }
50
+ end
51
+
52
+ def adjust_capacity(new_capacity:, **)
53
+ model = load_model
54
+ before = model.capacity
55
+ model.adjust_capacity(new_capacity: new_capacity)
56
+ after = model.capacity
57
+ Legion::Logging.debug "[cognitive_load] capacity adjusted: before=#{before.round(2)} after=#{after.round(2)}"
58
+ { success: true, before: before.round(4), after: after.round(4), current_state: model.to_h }
59
+ end
60
+
61
+ def load_status(**)
62
+ model = load_model
63
+ status = model.to_h
64
+ Legion::Logging.debug "[cognitive_load] status: label=#{status[:load_label]} " \
65
+ "overloaded=#{status[:overloaded]} underloaded=#{status[:underloaded]}"
66
+ { success: true, status: status }
67
+ end
68
+
69
+ def load_recommendation(**)
70
+ model = load_model
71
+ rec = model.recommendation
72
+ Legion::Logging.debug "[cognitive_load] recommendation: #{rec}"
73
+ {
74
+ success: true,
75
+ recommendation: rec,
76
+ load_label: model.load_label,
77
+ load_ratio: model.load_ratio.round(4),
78
+ germane_ratio: model.germane_ratio.round(4),
79
+ overloaded: model.overloaded?,
80
+ underloaded: model.underloaded?
81
+ }
82
+ end
83
+
84
+ def cognitive_load_stats(**)
85
+ model = load_model
86
+ history = model.load_history
87
+
88
+ stats = compute_history_stats(history)
89
+ Legion::Logging.debug "[cognitive_load] stats: history_size=#{history.size} avg_ratio=#{stats[:avg_load_ratio]}"
90
+ { success: true, history_size: history.size, stats: stats, current_state: model.to_h }
91
+ end
92
+
93
+ private
94
+
95
+ def load_model
96
+ @load_model ||= Helpers::LoadModel.new
97
+ end
98
+
99
+ def compute_history_stats(history)
100
+ return { avg_load_ratio: 0.0, max_load_ratio: 0.0, min_load_ratio: 0.0, overload_events: 0 } if history.empty?
101
+
102
+ ratios = history.map { |s| s[:load_ratio] }
103
+ overload_events = history.count { |s| s[:load_ratio] >= Helpers::Constants::OVERLOAD_THRESHOLD }
104
+
105
+ {
106
+ avg_load_ratio: (ratios.sum / ratios.size).round(4),
107
+ max_load_ratio: ratios.max.round(4),
108
+ min_load_ratio: ratios.min.round(4),
109
+ overload_events: overload_events
110
+ }
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveLoad
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/cognitive_load/version'
4
+ require 'legion/extensions/cognitive_load/helpers/constants'
5
+ require 'legion/extensions/cognitive_load/helpers/load_model'
6
+ require 'legion/extensions/cognitive_load/runners/cognitive_load'
7
+
8
+ module Legion
9
+ module Extensions
10
+ module CognitiveLoad
11
+ extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/cognitive_load/client'
4
+
5
+ RSpec.describe Legion::Extensions::CognitiveLoad::Client do
6
+ let(:client) { described_class.new }
7
+
8
+ describe '#initialize' do
9
+ it 'creates a default LoadModel' do
10
+ expect(client.load_model).to be_a(Legion::Extensions::CognitiveLoad::Helpers::LoadModel)
11
+ end
12
+
13
+ it 'accepts an injected load_model' do
14
+ custom_model = Legion::Extensions::CognitiveLoad::Helpers::LoadModel.new(capacity: 0.6)
15
+ c = described_class.new(load_model: custom_model)
16
+ expect(c.load_model).to eq(custom_model)
17
+ expect(c.load_model.capacity).to eq(0.6)
18
+ end
19
+
20
+ it 'accepts ** splat for extra kwargs' do
21
+ expect { described_class.new(extra: :ignored) }.not_to raise_error
22
+ end
23
+ end
24
+
25
+ describe 'runner method presence' do
26
+ it 'responds to all runner methods' do
27
+ %i[
28
+ report_intrinsic
29
+ report_extraneous
30
+ report_germane
31
+ reduce_overhead
32
+ update_cognitive_load
33
+ adjust_capacity
34
+ load_status
35
+ load_recommendation
36
+ cognitive_load_stats
37
+ ].each do |method|
38
+ expect(client).to respond_to(method)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe 'full cognitive load cycle' do
44
+ it 'processes task complexity and reports a recommendation' do
45
+ # Simulate a complex task arriving
46
+ client.report_intrinsic(amount: 0.6, source: :task_complexity)
47
+ client.report_extraneous(amount: 0.3, source: :poor_structure)
48
+ client.report_germane(amount: 0.4, source: :schema_building)
49
+
50
+ status = client.load_status
51
+ expect(status[:status][:load_label]).to be_a(Symbol)
52
+
53
+ rec = client.load_recommendation
54
+ expect(rec[:recommendation]).to be_a(Symbol)
55
+ end
56
+
57
+ it 'reduces load over time via decay ticks' do
58
+ client.report_intrinsic(amount: 0.9, source: :heavy_task)
59
+ client.report_extraneous(amount: 0.8, source: :noise)
60
+
61
+ high_ratio = client.load_model.load_ratio
62
+
63
+ 10.times { client.update_cognitive_load }
64
+
65
+ expect(client.load_model.load_ratio).to be < high_ratio
66
+ end
67
+
68
+ it 'accumulates history across multiple operations' do
69
+ client.report_intrinsic(amount: 0.5, source: :test)
70
+ client.report_extraneous(amount: 0.3, source: :test)
71
+ client.report_germane(amount: 0.4, source: :test)
72
+ client.update_cognitive_load
73
+
74
+ result = client.cognitive_load_stats
75
+ expect(result[:history_size]).to be >= 4
76
+ end
77
+
78
+ it 'overhead reduction lowers extraneous' do
79
+ client.report_extraneous(amount: 0.8, source: :noise)
80
+ high_extraneous = client.load_model.extraneous
81
+ client.reduce_overhead(amount: 0.3)
82
+ expect(client.load_model.extraneous).to be < high_extraneous
83
+ end
84
+
85
+ it 'capacity adjustment affects load ratio' do
86
+ client.report_intrinsic(amount: 0.5, source: :test)
87
+ client.report_extraneous(amount: 0.3, source: :test)
88
+
89
+ normal_ratio = client.load_model.load_ratio
90
+ client.adjust_capacity(new_capacity: 2.0)
91
+ expect(client.load_model.load_ratio).to be < normal_ratio
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::CognitiveLoad::Helpers::Constants do
4
+ subject(:mod) { described_class }
5
+
6
+ it 'defines DEFAULT_CAPACITY as 1.0' do
7
+ expect(mod::DEFAULT_CAPACITY).to eq(1.0)
8
+ end
9
+
10
+ it 'defines OVERLOAD_THRESHOLD as 0.85' do
11
+ expect(mod::OVERLOAD_THRESHOLD).to eq(0.85)
12
+ end
13
+
14
+ it 'defines UNDERLOAD_THRESHOLD as 0.25' do
15
+ expect(mod::UNDERLOAD_THRESHOLD).to eq(0.25)
16
+ end
17
+
18
+ it 'defines OPTIMAL_GERMANE_RATIO as 0.4' do
19
+ expect(mod::OPTIMAL_GERMANE_RATIO).to eq(0.4)
20
+ end
21
+
22
+ it 'defines MAX_LOAD_HISTORY as 200' do
23
+ expect(mod::MAX_LOAD_HISTORY).to eq(200)
24
+ end
25
+
26
+ it 'defines EMA alphas in (0..1)' do
27
+ expect(mod::INTRINSIC_ALPHA).to be_between(0.0, 1.0)
28
+ expect(mod::EXTRANEOUS_ALPHA).to be_between(0.0, 1.0)
29
+ expect(mod::GERMANE_ALPHA).to be_between(0.0, 1.0)
30
+ end
31
+
32
+ it 'defines LOAD_DECAY as a small positive float' do
33
+ expect(mod::LOAD_DECAY).to be > 0.0
34
+ expect(mod::LOAD_DECAY).to be < 0.2
35
+ end
36
+
37
+ it 'defines LOAD_LABELS as a frozen hash with 5 entries' do
38
+ expect(mod::LOAD_LABELS).to be_frozen
39
+ expect(mod::LOAD_LABELS.size).to eq(5)
40
+ end
41
+
42
+ it 'LOAD_LABELS covers all label values' do
43
+ labels = mod::LOAD_LABELS.values
44
+ expect(labels).to include(:overloaded, :heavy, :optimal, :light, :idle)
45
+ end
46
+
47
+ it 'LOAD_LABELS :overloaded range covers 0.9' do
48
+ overloaded_range = mod::LOAD_LABELS.key(:overloaded)
49
+ expect(overloaded_range).to cover(0.9)
50
+ end
51
+
52
+ it 'LOAD_LABELS :idle range covers 0.1' do
53
+ idle_range = mod::LOAD_LABELS.key(:idle)
54
+ expect(idle_range).to cover(0.1)
55
+ end
56
+
57
+ it 'defines default resting values' do
58
+ expect(mod::DEFAULT_INTRINSIC).to be_between(0.0, 1.0)
59
+ expect(mod::DEFAULT_EXTRANEOUS).to be_between(0.0, 1.0)
60
+ expect(mod::DEFAULT_GERMANE).to be_between(0.0, 1.0)
61
+ end
62
+ end
@@ -0,0 +1,314 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::CognitiveLoad::Helpers::LoadModel do
4
+ subject(:model) { described_class.new }
5
+
6
+ describe '#initialize' do
7
+ it 'starts with default resting values' do
8
+ expect(model.intrinsic).to eq(Legion::Extensions::CognitiveLoad::Helpers::Constants::DEFAULT_INTRINSIC)
9
+ expect(model.extraneous).to eq(Legion::Extensions::CognitiveLoad::Helpers::Constants::DEFAULT_EXTRANEOUS)
10
+ expect(model.germane).to eq(Legion::Extensions::CognitiveLoad::Helpers::Constants::DEFAULT_GERMANE)
11
+ end
12
+
13
+ it 'starts with default capacity' do
14
+ expect(model.capacity).to eq(Legion::Extensions::CognitiveLoad::Helpers::Constants::DEFAULT_CAPACITY)
15
+ end
16
+
17
+ it 'starts with empty history' do
18
+ expect(model.load_history).to be_empty
19
+ end
20
+
21
+ it 'accepts a custom capacity' do
22
+ m = described_class.new(capacity: 0.8)
23
+ expect(m.capacity).to eq(0.8)
24
+ end
25
+ end
26
+
27
+ describe '#total_load' do
28
+ it 'is the sum of three types' do
29
+ expected = model.intrinsic + model.extraneous + model.germane
30
+ expect(model.total_load).to be_within(0.0001).of(expected)
31
+ end
32
+
33
+ it 'is clamped to capacity' do
34
+ model.add_intrinsic(amount: 1.0, source: :test)
35
+ model.add_extraneous(amount: 1.0, source: :test)
36
+ model.add_germane(amount: 1.0, source: :test)
37
+ expect(model.total_load).to be <= model.capacity
38
+ end
39
+ end
40
+
41
+ describe '#load_ratio' do
42
+ it 'is between 0.0 and 1.0' do
43
+ expect(model.load_ratio).to be_between(0.0, 1.0)
44
+ end
45
+
46
+ it 'increases as intrinsic load is added' do
47
+ before = model.load_ratio
48
+ model.add_intrinsic(amount: 0.8, source: :test)
49
+ expect(model.load_ratio).to be >= before
50
+ end
51
+ end
52
+
53
+ describe '#add_intrinsic' do
54
+ it 'updates intrinsic via EMA' do
55
+ before = model.intrinsic
56
+ model.add_intrinsic(amount: 0.9, source: :test)
57
+ expect(model.intrinsic).to be > before
58
+ end
59
+
60
+ it 'records a history snapshot' do
61
+ model.add_intrinsic(amount: 0.5, source: :test)
62
+ expect(model.load_history.last[:event]).to eq(:intrinsic_added)
63
+ expect(model.load_history.last[:source]).to eq(:test)
64
+ end
65
+
66
+ it 'returns self for chaining' do
67
+ expect(model.add_intrinsic(amount: 0.3, source: :test)).to eq(model)
68
+ end
69
+
70
+ it 'clamps input to [0, 1]' do
71
+ model.add_intrinsic(amount: 5.0, source: :test)
72
+ expect(model.intrinsic).to be <= 1.0
73
+ end
74
+ end
75
+
76
+ describe '#add_extraneous' do
77
+ it 'updates extraneous via EMA' do
78
+ before = model.extraneous
79
+ model.add_extraneous(amount: 0.9, source: :test)
80
+ expect(model.extraneous).to be > before
81
+ end
82
+
83
+ it 'records a history snapshot with event :extraneous_added' do
84
+ model.add_extraneous(amount: 0.5, source: :test)
85
+ expect(model.load_history.last[:event]).to eq(:extraneous_added)
86
+ end
87
+ end
88
+
89
+ describe '#add_germane' do
90
+ it 'updates germane via EMA' do
91
+ before = model.germane
92
+ model.add_germane(amount: 0.9, source: :test)
93
+ expect(model.germane).to be > before
94
+ end
95
+
96
+ it 'records a history snapshot with event :germane_added' do
97
+ model.add_germane(amount: 0.5, source: :test)
98
+ expect(model.load_history.last[:event]).to eq(:germane_added)
99
+ end
100
+ end
101
+
102
+ describe '#reduce_extraneous' do
103
+ it 'lowers extraneous load' do
104
+ model.add_extraneous(amount: 0.8, source: :test)
105
+ before = model.extraneous
106
+ model.reduce_extraneous(amount: 0.2)
107
+ expect(model.extraneous).to be < before
108
+ end
109
+
110
+ it 'does not go below 0' do
111
+ model.reduce_extraneous(amount: 10.0)
112
+ expect(model.extraneous).to eq(0.0)
113
+ end
114
+
115
+ it 'records a history snapshot with event :extraneous_reduced' do
116
+ model.reduce_extraneous(amount: 0.05)
117
+ expect(model.load_history.last[:event]).to eq(:extraneous_reduced)
118
+ end
119
+ end
120
+
121
+ describe '#decay' do
122
+ it 'moves values toward resting defaults' do
123
+ model.add_intrinsic(amount: 0.9, source: :test)
124
+ high_intrinsic = model.intrinsic
125
+ model.decay
126
+ expect(model.intrinsic).to be < high_intrinsic
127
+ end
128
+
129
+ it 'records a decay snapshot' do
130
+ model.decay
131
+ expect(model.load_history.last[:event]).to eq(:decay)
132
+ end
133
+
134
+ it 'returns self' do
135
+ expect(model.decay).to eq(model)
136
+ end
137
+ end
138
+
139
+ describe '#adjust_capacity' do
140
+ it 'updates capacity' do
141
+ model.adjust_capacity(new_capacity: 0.7)
142
+ expect(model.capacity).to eq(0.7)
143
+ end
144
+
145
+ it 'clamps capacity to [0.1, 2.0]' do
146
+ model.adjust_capacity(new_capacity: 5.0)
147
+ expect(model.capacity).to eq(2.0)
148
+ model.adjust_capacity(new_capacity: 0.0)
149
+ expect(model.capacity).to eq(0.1)
150
+ end
151
+
152
+ it 'records a capacity_adjusted snapshot' do
153
+ model.adjust_capacity(new_capacity: 0.8)
154
+ expect(model.load_history.last[:event]).to eq(:capacity_adjusted)
155
+ end
156
+ end
157
+
158
+ describe '#overloaded?' do
159
+ it 'returns false at resting state' do
160
+ expect(model.overloaded?).to be false
161
+ end
162
+
163
+ it 'returns true when load ratio exceeds OVERLOAD_THRESHOLD' do
164
+ # Drive load ratio over the threshold by adding max load to each type
165
+ model.add_intrinsic(amount: 1.0, source: :test)
166
+ model.add_extraneous(amount: 1.0, source: :test)
167
+ model.add_germane(amount: 1.0, source: :test)
168
+ # After EMA updates the values should be high enough
169
+ # Force the values directly via multiple additions
170
+ 10.times do
171
+ model.add_intrinsic(amount: 1.0, source: :test)
172
+ model.add_extraneous(amount: 1.0, source: :test)
173
+ model.add_germane(amount: 1.0, source: :test)
174
+ end
175
+ expect(model.overloaded?).to be true
176
+ end
177
+ end
178
+
179
+ describe '#underloaded?' do
180
+ it 'returns false at resting state (resting total is above threshold)' do
181
+ resting_total = Legion::Extensions::CognitiveLoad::Helpers::Constants::DEFAULT_INTRINSIC +
182
+ Legion::Extensions::CognitiveLoad::Helpers::Constants::DEFAULT_EXTRANEOUS +
183
+ Legion::Extensions::CognitiveLoad::Helpers::Constants::DEFAULT_GERMANE
184
+ if resting_total <= Legion::Extensions::CognitiveLoad::Helpers::Constants::UNDERLOAD_THRESHOLD
185
+ expect(model.underloaded?).to be true
186
+ else
187
+ expect(model.underloaded?).to be false
188
+ end
189
+ end
190
+
191
+ it 'returns true when capacity is large relative to resting load' do
192
+ # With capacity=4.0, resting load (~0.45) / 4.0 = 0.11 which is below UNDERLOAD_THRESHOLD
193
+ m = described_class.new(capacity: 4.0)
194
+ expect(m.underloaded?).to be true
195
+ end
196
+ end
197
+
198
+ describe '#germane_ratio' do
199
+ it 'returns 0 when total load is 0' do
200
+ m = described_class.new
201
+ allow(m).to receive(:total_load).and_return(0.0)
202
+ expect(m.germane_ratio).to eq(0.0)
203
+ end
204
+
205
+ it 'returns a value between 0 and 1' do
206
+ expect(model.germane_ratio).to be_between(0.0, 1.0)
207
+ end
208
+
209
+ it 'increases as germane load increases relative to total' do
210
+ model.add_intrinsic(amount: 0.1, source: :test)
211
+ model.add_extraneous(amount: 0.1, source: :test)
212
+ before = model.germane_ratio
213
+ model.add_germane(amount: 0.9, source: :test)
214
+ expect(model.germane_ratio).to be >= before
215
+ end
216
+ end
217
+
218
+ describe '#load_label' do
219
+ it 'returns a symbol' do
220
+ expect(model.load_label).to be_a(Symbol)
221
+ end
222
+
223
+ it 'returns :overloaded when load ratio is high' do
224
+ 10.times do
225
+ model.add_intrinsic(amount: 1.0, source: :test)
226
+ model.add_extraneous(amount: 1.0, source: :test)
227
+ model.add_germane(amount: 1.0, source: :test)
228
+ end
229
+ expect(model.load_label).to eq(:overloaded)
230
+ end
231
+
232
+ it 'returns :idle when load ratio is very low (high capacity)' do
233
+ # With capacity=4.0, resting load (~0.45) / 4.0 = ~0.11 which falls in :idle range
234
+ m = described_class.new(capacity: 4.0)
235
+ expect(m.load_label).to eq(:idle)
236
+ end
237
+ end
238
+
239
+ describe '#recommendation' do
240
+ it 'returns :simplify when overloaded' do
241
+ 10.times do
242
+ model.add_intrinsic(amount: 1.0, source: :test)
243
+ model.add_extraneous(amount: 1.0, source: :test)
244
+ model.add_germane(amount: 1.0, source: :test)
245
+ end
246
+ expect(model.recommendation).to eq(:simplify)
247
+ end
248
+
249
+ it 'returns :increase_challenge when underloaded' do
250
+ # capacity=4.0 makes resting load ratio ~0.11, below UNDERLOAD_THRESHOLD
251
+ m = described_class.new(capacity: 4.0)
252
+ expect(m.recommendation).to eq(:increase_challenge)
253
+ end
254
+
255
+ it 'returns :reduce_overhead when extraneous dominates' do
256
+ # Use a low-capacity model so extraneous doesn't push into overloaded territory
257
+ m = described_class.new(capacity: 2.0)
258
+ 10.times { m.add_extraneous(amount: 0.5, source: :test) }
259
+ # Ensure we are not overloaded but extraneous > intrinsic + germane
260
+ next_rec = m.recommendation
261
+ # If overloaded by the additions, fall back to a model where we can isolate extraneous
262
+ if next_rec == :simplify
263
+ m2 = described_class.new(capacity: 2.0)
264
+ 5.times { m2.add_extraneous(amount: 0.4, source: :test) }
265
+ expect(%i[reduce_overhead simplify]).to include(m2.recommendation)
266
+ else
267
+ expect(next_rec).to eq(:reduce_overhead)
268
+ end
269
+ end
270
+
271
+ it 'returns :continue in optimal range' do
272
+ # Build a model in the optimal zone with balanced load
273
+ m = described_class.new
274
+ 5.times do
275
+ m.add_intrinsic(amount: 0.4, source: :test)
276
+ m.add_germane(amount: 0.4, source: :test)
277
+ m.add_extraneous(amount: 0.05, source: :test)
278
+ end
279
+ # Optimal zone is load_ratio 0.35..0.6 with germane not dominating over intrinsic+germane
280
+ expect(%i[continue reduce_overhead]).to include(m.recommendation)
281
+ end
282
+ end
283
+
284
+ describe '#to_h' do
285
+ it 'returns a hash with all required keys' do
286
+ h = model.to_h
287
+ expect(h.keys).to include(
288
+ :intrinsic, :extraneous, :germane, :total_load, :capacity,
289
+ :load_ratio, :germane_ratio, :load_label, :overloaded, :underloaded,
290
+ :recommendation, :history_size
291
+ )
292
+ end
293
+
294
+ it 'has numeric values for load fields' do
295
+ h = model.to_h
296
+ expect(h[:intrinsic]).to be_a(Float)
297
+ expect(h[:load_ratio]).to be_a(Float)
298
+ end
299
+
300
+ it 'has boolean overloaded and underloaded fields' do
301
+ h = model.to_h
302
+ expect(h[:overloaded]).to be(true).or be(false)
303
+ expect(h[:underloaded]).to be(true).or be(false)
304
+ end
305
+ end
306
+
307
+ describe 'history cap' do
308
+ it 'does not exceed MAX_LOAD_HISTORY entries' do
309
+ max = Legion::Extensions::CognitiveLoad::Helpers::Constants::MAX_LOAD_HISTORY
310
+ (max + 10).times { model.add_intrinsic(amount: 0.5, source: :test) }
311
+ expect(model.load_history.size).to eq(max)
312
+ end
313
+ end
314
+ end
@@ -0,0 +1,231 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/cognitive_load/client'
4
+
5
+ RSpec.describe Legion::Extensions::CognitiveLoad::Runners::CognitiveLoad do
6
+ let(:client) { Legion::Extensions::CognitiveLoad::Client.new }
7
+
8
+ describe '#report_intrinsic' do
9
+ it 'returns success: true' do
10
+ result = client.report_intrinsic(amount: 0.5)
11
+ expect(result[:success]).to be true
12
+ end
13
+
14
+ it 'includes load_type: :intrinsic' do
15
+ result = client.report_intrinsic(amount: 0.5)
16
+ expect(result[:load_type]).to eq(:intrinsic)
17
+ end
18
+
19
+ it 'echoes the amount' do
20
+ result = client.report_intrinsic(amount: 0.7, source: :task)
21
+ expect(result[:amount]).to eq(0.7)
22
+ end
23
+
24
+ it 'echoes the source' do
25
+ result = client.report_intrinsic(amount: 0.3, source: :memory)
26
+ expect(result[:source]).to eq(:memory)
27
+ end
28
+
29
+ it 'includes current_state hash' do
30
+ result = client.report_intrinsic(amount: 0.5)
31
+ expect(result[:current_state]).to be_a(Hash)
32
+ expect(result[:current_state]).to have_key(:load_ratio)
33
+ end
34
+
35
+ it 'accepts ** splat kwargs' do
36
+ expect { client.report_intrinsic(amount: 0.5, extra_key: :ignored) }.not_to raise_error
37
+ end
38
+ end
39
+
40
+ describe '#report_extraneous' do
41
+ it 'returns success: true' do
42
+ result = client.report_extraneous(amount: 0.3)
43
+ expect(result[:success]).to be true
44
+ end
45
+
46
+ it 'includes load_type: :extraneous' do
47
+ result = client.report_extraneous(amount: 0.3)
48
+ expect(result[:load_type]).to eq(:extraneous)
49
+ end
50
+
51
+ it 'increases extraneous load on the model' do
52
+ before = client.load_model.extraneous
53
+ client.report_extraneous(amount: 0.8, source: :noise)
54
+ expect(client.load_model.extraneous).to be > before
55
+ end
56
+ end
57
+
58
+ describe '#report_germane' do
59
+ it 'returns success: true' do
60
+ result = client.report_germane(amount: 0.6)
61
+ expect(result[:success]).to be true
62
+ end
63
+
64
+ it 'includes load_type: :germane' do
65
+ result = client.report_germane(amount: 0.6)
66
+ expect(result[:load_type]).to eq(:germane)
67
+ end
68
+
69
+ it 'increases germane load on the model' do
70
+ before = client.load_model.germane
71
+ client.report_germane(amount: 0.9, source: :learning)
72
+ expect(client.load_model.germane).to be > before
73
+ end
74
+ end
75
+
76
+ describe '#reduce_overhead' do
77
+ it 'returns success: true' do
78
+ result = client.reduce_overhead(amount: 0.05)
79
+ expect(result[:success]).to be true
80
+ end
81
+
82
+ it 'includes before, after, and delta' do
83
+ result = client.reduce_overhead(amount: 0.05)
84
+ expect(result).to have_key(:before)
85
+ expect(result).to have_key(:after)
86
+ expect(result).to have_key(:delta)
87
+ end
88
+
89
+ it 'delta equals before minus after' do
90
+ result = client.reduce_overhead(amount: 0.05)
91
+ expect(result[:delta]).to be_within(0.0001).of(result[:before] - result[:after])
92
+ end
93
+
94
+ it 'accepts ** splat' do
95
+ expect { client.reduce_overhead(amount: 0.05, extra: :ignored) }.not_to raise_error
96
+ end
97
+ end
98
+
99
+ describe '#update_cognitive_load' do
100
+ it 'returns success: true' do
101
+ result = client.update_cognitive_load
102
+ expect(result[:success]).to be true
103
+ end
104
+
105
+ it 'records action: :decay' do
106
+ result = client.update_cognitive_load
107
+ expect(result[:action]).to eq(:decay)
108
+ end
109
+
110
+ it 'includes current_state' do
111
+ result = client.update_cognitive_load
112
+ expect(result[:current_state]).to be_a(Hash)
113
+ end
114
+
115
+ it 'accepts ** splat' do
116
+ expect { client.update_cognitive_load(extra: :ignored) }.not_to raise_error
117
+ end
118
+ end
119
+
120
+ describe '#adjust_capacity' do
121
+ it 'returns success: true' do
122
+ result = client.adjust_capacity(new_capacity: 0.8)
123
+ expect(result[:success]).to be true
124
+ end
125
+
126
+ it 'includes before and after' do
127
+ result = client.adjust_capacity(new_capacity: 0.8)
128
+ expect(result).to have_key(:before)
129
+ expect(result).to have_key(:after)
130
+ end
131
+
132
+ it 'changes the model capacity' do
133
+ client.adjust_capacity(new_capacity: 0.7)
134
+ expect(client.load_model.capacity).to eq(0.7)
135
+ end
136
+
137
+ it 'accepts ** splat' do
138
+ expect { client.adjust_capacity(new_capacity: 0.9, extra: :ignored) }.not_to raise_error
139
+ end
140
+ end
141
+
142
+ describe '#load_status' do
143
+ it 'returns success: true' do
144
+ result = client.load_status
145
+ expect(result[:success]).to be true
146
+ end
147
+
148
+ it 'includes a status hash' do
149
+ result = client.load_status
150
+ expect(result[:status]).to be_a(Hash)
151
+ end
152
+
153
+ it 'status includes load_label and load_ratio' do
154
+ result = client.load_status
155
+ expect(result[:status]).to have_key(:load_label)
156
+ expect(result[:status]).to have_key(:load_ratio)
157
+ end
158
+
159
+ it 'accepts ** splat' do
160
+ expect { client.load_status(extra: :ignored) }.not_to raise_error
161
+ end
162
+ end
163
+
164
+ describe '#load_recommendation' do
165
+ it 'returns success: true' do
166
+ result = client.load_recommendation
167
+ expect(result[:success]).to be true
168
+ end
169
+
170
+ it 'includes a recommendation symbol' do
171
+ result = client.load_recommendation
172
+ expect(result[:recommendation]).to be_a(Symbol)
173
+ end
174
+
175
+ it 'includes load metadata' do
176
+ result = client.load_recommendation
177
+ expect(result).to have_key(:load_label)
178
+ expect(result).to have_key(:load_ratio)
179
+ expect(result).to have_key(:germane_ratio)
180
+ expect(result).to have_key(:overloaded)
181
+ expect(result).to have_key(:underloaded)
182
+ end
183
+
184
+ it 'returns :simplify when overloaded' do
185
+ c = Legion::Extensions::CognitiveLoad::Client.new
186
+ 10.times do
187
+ c.report_intrinsic(amount: 1.0)
188
+ c.report_extraneous(amount: 1.0)
189
+ c.report_germane(amount: 1.0)
190
+ end
191
+ result = c.load_recommendation
192
+ expect(result[:recommendation]).to eq(:simplify)
193
+ end
194
+
195
+ it 'accepts ** splat' do
196
+ expect { client.load_recommendation(extra: :ignored) }.not_to raise_error
197
+ end
198
+ end
199
+
200
+ describe '#cognitive_load_stats' do
201
+ it 'returns success: true' do
202
+ result = client.cognitive_load_stats
203
+ expect(result[:success]).to be true
204
+ end
205
+
206
+ it 'includes history_size' do
207
+ result = client.cognitive_load_stats
208
+ expect(result).to have_key(:history_size)
209
+ end
210
+
211
+ it 'includes stats with avg/max/min/overload_events' do
212
+ client.report_intrinsic(amount: 0.5)
213
+ client.report_extraneous(amount: 0.3)
214
+ result = client.cognitive_load_stats
215
+ expect(result[:stats]).to have_key(:avg_load_ratio)
216
+ expect(result[:stats]).to have_key(:max_load_ratio)
217
+ expect(result[:stats]).to have_key(:min_load_ratio)
218
+ expect(result[:stats]).to have_key(:overload_events)
219
+ end
220
+
221
+ it 'returns zero stats when history is empty' do
222
+ c = Legion::Extensions::CognitiveLoad::Client.new
223
+ result = c.cognitive_load_stats
224
+ expect(result[:stats][:avg_load_ratio]).to eq(0.0)
225
+ end
226
+
227
+ it 'accepts ** splat' do
228
+ expect { client.cognitive_load_stats(extra: :ignored) }.not_to raise_error
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,26 @@
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_load'
21
+
22
+ RSpec.configure do |config|
23
+ config.example_status_persistence_file_path = '.rspec_status'
24
+ config.disable_monkey_patching!
25
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
26
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-cognitive-load
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: 'Sweller''s Cognitive Load Theory modeled for brain-based agentic AI:
27
+ intrinsic, extraneous, and germane load tracking with capacity management'
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-load.gemspec
38
+ - lib/legion/extensions/cognitive_load.rb
39
+ - lib/legion/extensions/cognitive_load/client.rb
40
+ - lib/legion/extensions/cognitive_load/helpers/constants.rb
41
+ - lib/legion/extensions/cognitive_load/helpers/load_model.rb
42
+ - lib/legion/extensions/cognitive_load/runners/cognitive_load.rb
43
+ - lib/legion/extensions/cognitive_load/version.rb
44
+ - spec/legion/extensions/cognitive_load/client_spec.rb
45
+ - spec/legion/extensions/cognitive_load/helpers/constants_spec.rb
46
+ - spec/legion/extensions/cognitive_load/helpers/load_model_spec.rb
47
+ - spec/legion/extensions/cognitive_load/runners/cognitive_load_spec.rb
48
+ - spec/spec_helper.rb
49
+ homepage: https://github.com/LegionIO/lex-cognitive-load
50
+ licenses:
51
+ - MIT
52
+ metadata:
53
+ homepage_uri: https://github.com/LegionIO/lex-cognitive-load
54
+ source_code_uri: https://github.com/LegionIO/lex-cognitive-load
55
+ documentation_uri: https://github.com/LegionIO/lex-cognitive-load
56
+ changelog_uri: https://github.com/LegionIO/lex-cognitive-load
57
+ bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-load/issues
58
+ rubygems_mfa_required: 'true'
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '3.4'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubygems_version: 3.6.9
74
+ specification_version: 4
75
+ summary: LEX Cognitive Load
76
+ test_files: []