lex-cognitive-architecture 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: '092043a1bda6a7ef72fdfa70981dcbfa1804327a1271a1c6f688f9336af261ab'
4
+ data.tar.gz: 4aff5efd3be134b77150e1389f8a730c7eb14d3f1601de4457bc393db27f64d3
5
+ SHA512:
6
+ metadata.gz: 875b1f19bd4883428b0f63ed0226b8f3646909700292b28c3ab8c7b5b93b09f2c3025347bf006ce5fea7fa9ed45d210f47d0a5a419ea289edbaf3aa49b5d6358
7
+ data.tar.gz: b4867d3611de73f06bcf81c99b3ade4e5f818fdcd53bc245a5f3d696b4bfde8c01b89830cbe929a1f0a121186d5752b89c493ef3f1d5459df5785090f0fc49d9
@@ -0,0 +1,16 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+
7
+ jobs:
8
+ ci:
9
+ uses: LegionIO/.github/.github/workflows/ci.yml@main
10
+
11
+ release:
12
+ needs: ci
13
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
14
+ uses: LegionIO/.github/.github/workflows/release.yml@main
15
+ secrets:
16
+ rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .rspec_status
2
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ --format documentation
data/.rubocop.yml ADDED
@@ -0,0 +1,48 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.4
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+
6
+ Layout/LineLength:
7
+ Max: 160
8
+
9
+ Layout/SpaceAroundEqualsInParameterDefault:
10
+ EnforcedStyle: space
11
+
12
+ Layout/HashAlignment:
13
+ EnforcedHashRocketStyle: table
14
+ EnforcedColonStyle: table
15
+
16
+ Metrics/ClassLength:
17
+ Max: 150
18
+
19
+ Metrics/MethodLength:
20
+ Max: 25
21
+
22
+ Metrics/AbcSize:
23
+ Max: 25
24
+
25
+ Metrics/ParameterLists:
26
+ Max: 8
27
+ MaxOptionalParameters: 8
28
+
29
+ Metrics/BlockLength:
30
+ Exclude:
31
+ - 'spec/**/*'
32
+
33
+ Style/Documentation:
34
+ Enabled: false
35
+
36
+ Style/FrozenStringLiteralComment:
37
+ Enabled: true
38
+ EnforcedStyle: always
39
+
40
+ Style/OneClassPerFile:
41
+ Exclude:
42
+ - 'spec/spec_helper.rb'
43
+
44
+ Naming/FileName:
45
+ Enabled: false
46
+
47
+ Naming/PredicateMethod:
48
+ Enabled: false
data/CLAUDE.md ADDED
@@ -0,0 +1,81 @@
1
+ # lex-cognitive-architecture
2
+
3
+ **Level 3 Documentation**
4
+ - **Parent**: `/Users/miverso2/rubymine/legion/extensions-agentic/CLAUDE.md`
5
+ - **Grandparent**: `/Users/miverso2/rubymine/legion/CLAUDE.md`
6
+
7
+ ## Purpose
8
+
9
+ Meta-extension that models the agent cognitive architecture as a graph of subsystems, connections, and information flows — enabling self-awareness of its own architecture. Provides health monitoring, bottleneck detection, and downstream traversal across named subsystems.
10
+
11
+ ## Gem Info
12
+
13
+ - **Gem name**: `lex-cognitive-architecture`
14
+ - **Version**: `0.1.0`
15
+ - **Module**: `Legion::Extensions::CognitiveArchitecture`
16
+ - **Ruby**: `>= 3.4`
17
+ - **License**: MIT
18
+
19
+ ## File Structure
20
+
21
+ ```
22
+ lib/legion/extensions/cognitive_architecture/
23
+ cognitive_architecture.rb # top-level require
24
+ version.rb
25
+ client.rb
26
+ helpers/
27
+ constants.rb
28
+ subsystem.rb
29
+ connection.rb
30
+ architecture_engine.rb
31
+ runners/
32
+ cognitive_architecture.rb
33
+ ```
34
+
35
+ ## Key Constants
36
+
37
+ From `helpers/constants.rb`:
38
+
39
+ - `SUBSYSTEM_TYPES` — `%i[perception cognition memory motivation safety communication introspection coordination]`
40
+ - `CONNECTION_TYPES` — `%i[excitatory inhibitory modulatory informational]`
41
+ - `STATUS_LEVELS` — `%i[active idle degraded offline]`
42
+ - `HEALTH_LABELS` — range map: `0.8+` = `:excellent`, `0.6` = `:good`, `0.4` = `:fair`, `0.2` = `:degraded`, below = `:critical`
43
+ - `BOTTLENECK_THRESHOLD` = `0.3` (load > threshold AND health < 0.5)
44
+ - `MAX_SUBSYSTEMS` = `200`, `MAX_CONNECTIONS` = `1000`, `MAX_HISTORY` = `500`
45
+ - `DEFAULT_HEALTH` = `0.8`, `HEALTH_DECAY` = `0.01`, `HEALTH_BOOST` = `0.05`
46
+
47
+ ## Runners
48
+
49
+ All methods in `Runners::CognitiveArchitecture` (`extend self`):
50
+
51
+ - `register_architecture_subsystem(name:, subsystem_type:, health: DEFAULT_HEALTH)` — registers a new named subsystem; raises on duplicate or capacity exceeded
52
+ - `create_architecture_connection(source_name:, target_name:, connection_type: :informational, weight: 0.5)` — creates a directed connection between two subsystems
53
+ - `activate_architecture_subsystem(name:)` — activates subsystem and propagates activation to excitatory targets
54
+ - `degrade_architecture_subsystem(name:)` — applies health decay; marks `:degraded` when health < 0.4
55
+ - `subsystem_status_report(name:)` — returns full `to_h` for a named subsystem
56
+ - `bottleneck_report` — returns all subsystems where load > 0.3 AND health < 0.5
57
+ - `architecture_health_report` — average health across all subsystems + active count
58
+ - `architecture_graph_report` — full `{ nodes:, edges: }` graph
59
+ - `downstream_subsystems(name:, max_depth: 5)` — BFS traversal of reachable subsystems
60
+ - `update_cognitive_architecture` — runs `decay_all` (decrements health by `HEALTH_DECAY` on all)
61
+ - `cognitive_architecture_stats` — summary hash: counts, health, bottleneck count
62
+
63
+ ## Helpers
64
+
65
+ - `ArchitectureEngine` — in-memory store of `Subsystem` and `Connection` objects. BFS traversal via `downstream`. Excitatory connections propagate activation.
66
+ - `Subsystem` — has `id`, `name`, `subsystem_type`, `health`, `status`, `load`, `activation_count`. Methods: `activate!`, `degrade!(amount)`, `recover!(amount)`, `bottlenecked?`, `health_label`.
67
+ - `Connection` — directed edge with `source_id`, `target_id`, `connection_type`, `weight`, `active`. Methods: `strengthen!`, `weaken!`, `toggle!`.
68
+
69
+ ## Integration Points
70
+
71
+ - No direct dependencies on other agentic LEXs. This extension is a meta-layer: any other extension can register its processing subsystem here to make the architecture graph self-aware.
72
+ - `lex-cortex` is the natural caller: wiring `lex-cognitive-architecture` into the tick cycle allows the agent to model its own cognitive topology during introspection phases.
73
+ - `activate_architecture_subsystem` propagates through excitatory connections, modeling cascading activation across cognitive subsystems.
74
+
75
+ ## Development Notes
76
+
77
+ - `ArchitectureEngine` state is per-`RunnerHost` instance (in-memory only; resets on restart).
78
+ - `decay_all` runs `degrade!(HEALTH_DECAY)` on every subsystem — intended to be called periodically (e.g., `update_cognitive_architecture` runner).
79
+ - Subsystem names are coerced to symbols on registration; duplicate names raise `ArgumentError`.
80
+ - Bottleneck detection requires both high load (`@load > BOTTLENECK_THRESHOLD`) and low health (`@health < 0.5`). `@load` is set externally — the engine does not auto-compute it.
81
+ - BFS depth limit (`max_depth: 5`) prevents runaway traversal in dense graphs.
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :test do
8
+ gem 'rspec', '~> 3.13'
9
+ gem 'rubocop', '~> 1.75', require: false
10
+ gem 'rubocop-rspec', require: false
11
+ end
12
+
13
+ gem 'legion-gaia', path: '../../legion-gaia'
data/Gemfile.lock ADDED
@@ -0,0 +1,78 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lex-cognitive-architecture (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ addressable (2.8.9)
10
+ public_suffix (>= 2.0.2, < 8.0)
11
+ ast (2.4.3)
12
+ bigdecimal (4.0.1)
13
+ diff-lcs (1.6.2)
14
+ json (2.19.1)
15
+ json-schema (6.2.0)
16
+ addressable (~> 2.8)
17
+ bigdecimal (>= 3.1, < 5)
18
+ language_server-protocol (3.17.0.5)
19
+ lint_roller (1.1.0)
20
+ mcp (0.8.0)
21
+ json-schema (>= 4.1)
22
+ parallel (1.27.0)
23
+ parser (3.3.10.2)
24
+ ast (~> 2.4.1)
25
+ racc
26
+ prism (1.9.0)
27
+ public_suffix (7.0.5)
28
+ racc (1.8.1)
29
+ rainbow (3.1.1)
30
+ regexp_parser (2.11.3)
31
+ rspec (3.13.2)
32
+ rspec-core (~> 3.13.0)
33
+ rspec-expectations (~> 3.13.0)
34
+ rspec-mocks (~> 3.13.0)
35
+ rspec-core (3.13.6)
36
+ rspec-support (~> 3.13.0)
37
+ rspec-expectations (3.13.5)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.13.0)
40
+ rspec-mocks (3.13.8)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.13.0)
43
+ rspec-support (3.13.7)
44
+ rubocop (1.85.1)
45
+ json (~> 2.3)
46
+ language_server-protocol (~> 3.17.0.2)
47
+ lint_roller (~> 1.1.0)
48
+ mcp (~> 0.6)
49
+ parallel (~> 1.10)
50
+ parser (>= 3.3.0.2)
51
+ rainbow (>= 2.2.2, < 4.0)
52
+ regexp_parser (>= 2.9.3, < 3.0)
53
+ rubocop-ast (>= 1.49.0, < 2.0)
54
+ ruby-progressbar (~> 1.7)
55
+ unicode-display_width (>= 2.4.0, < 4.0)
56
+ rubocop-ast (1.49.1)
57
+ parser (>= 3.3.7.2)
58
+ prism (~> 1.7)
59
+ rubocop-rspec (3.9.0)
60
+ lint_roller (~> 1.1)
61
+ rubocop (~> 1.81)
62
+ ruby-progressbar (1.13.0)
63
+ unicode-display_width (3.2.0)
64
+ unicode-emoji (~> 4.1)
65
+ unicode-emoji (4.2.0)
66
+
67
+ PLATFORMS
68
+ arm64-darwin-25
69
+ ruby
70
+
71
+ DEPENDENCIES
72
+ lex-cognitive-architecture!
73
+ rspec (~> 3.13)
74
+ rubocop (~> 1.75)
75
+ rubocop-rspec
76
+
77
+ BUNDLED WITH
78
+ 2.6.9
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # lex-cognitive-architecture
2
+
3
+ Meta-extension that models the agent cognitive architecture as a graph of subsystems, connections, and information flows — enabling self-awareness of its own architecture.
4
+
5
+ ## What It Does
6
+
7
+ Provides a self-model of the agent's cognitive topology. Subsystems (perception, memory, motivation, safety, etc.) are registered as graph nodes with health scores and load tracking. Directed connections between subsystems have types (excitatory, inhibitory, modulatory, informational) and weights. The engine supports:
8
+
9
+ - Health decay and activation propagation across connected subsystems
10
+ - Bottleneck detection (high load + low health)
11
+ - BFS downstream traversal to find all reachable subsystems from a source
12
+ - Architecture-wide health scoring and graph export
13
+
14
+ ## Usage
15
+
16
+ ```ruby
17
+ client = Legion::Extensions::CognitiveArchitecture::Client.new
18
+
19
+ client.register_architecture_subsystem(name: :memory, subsystem_type: :memory)
20
+ client.register_architecture_subsystem(name: :emotion, subsystem_type: :cognition)
21
+ client.create_architecture_connection(
22
+ source_name: :emotion,
23
+ target_name: :memory,
24
+ connection_type: :excitatory,
25
+ weight: 0.8
26
+ )
27
+
28
+ client.activate_architecture_subsystem(name: :emotion)
29
+ client.architecture_health_report
30
+ client.bottleneck_report
31
+ client.architecture_graph_report
32
+ ```
33
+
34
+ ## Development
35
+
36
+ ```bash
37
+ bundle install
38
+ bundle exec rspec
39
+ bundle exec rubocop
40
+ ```
41
+
42
+ ## License
43
+
44
+ MIT
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/cognitive_architecture/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-cognitive-architecture'
7
+ spec.version = Legion::Extensions::CognitiveArchitecture::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+
11
+ spec.summary = 'LEX Cognitive Architecture'
12
+ spec.description = 'Meta-extension that models the agent cognitive architecture as a graph of subsystems, ' \
13
+ 'connections, and information flows — enabling self-awareness of its own architecture'
14
+ spec.homepage = 'https://github.com/LegionIO/lex-cognitive-architecture'
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-architecture'
20
+ spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-cognitive-architecture'
21
+ spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-cognitive-architecture'
22
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-cognitive-architecture/issues'
23
+ spec.metadata['rubygems_mfa_required'] = 'true'
24
+
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ end
28
+ spec.require_paths = ['lib']
29
+ spec.add_development_dependency 'legion-gaia'
30
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveArchitecture
6
+ class Client
7
+ include Runners::CognitiveArchitecture
8
+
9
+ def initialize(**)
10
+ @engine = Helpers::ArchitectureEngine.new
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveArchitecture
6
+ module Helpers
7
+ class ArchitectureEngine
8
+ include Constants
9
+
10
+ def initialize
11
+ @subsystems = {}
12
+ @connections = {}
13
+ end
14
+
15
+ def register_subsystem(name:, subsystem_type:, health: Constants::DEFAULT_HEALTH)
16
+ raise ArgumentError, "subsystem '#{name}' already registered" if @subsystems.key?(name.to_sym)
17
+ raise ArgumentError, "max subsystems (#{Constants::MAX_SUBSYSTEMS}) reached" if @subsystems.size >= Constants::MAX_SUBSYSTEMS
18
+
19
+ subsystem = Subsystem.new(name: name, subsystem_type: subsystem_type, health: health)
20
+ @subsystems[subsystem.name] = subsystem
21
+ subsystem
22
+ end
23
+
24
+ def create_connection(source_name:, target_name:, connection_type: :informational, weight: 0.5)
25
+ raise ArgumentError, "max connections (#{Constants::MAX_CONNECTIONS}) reached" if @connections.size >= Constants::MAX_CONNECTIONS
26
+
27
+ source = find_subsystem!(source_name)
28
+ target = find_subsystem!(target_name)
29
+
30
+ conn = Connection.new(
31
+ source_id: source.id,
32
+ target_id: target.id,
33
+ connection_type: connection_type,
34
+ weight: weight
35
+ )
36
+ @connections[conn.id] = conn
37
+ conn
38
+ end
39
+
40
+ def activate_subsystem(name:)
41
+ subsystem = find_subsystem!(name)
42
+ subsystem.activate!
43
+
44
+ excitatory_connections_from(subsystem.id).each do |conn|
45
+ target = subsystem_by_id(conn.target_id)
46
+ target&.activate!
47
+ end
48
+
49
+ { name: subsystem.name, status: subsystem.status, health: subsystem.health }
50
+ end
51
+
52
+ def degrade_subsystem(name:)
53
+ subsystem = find_subsystem!(name)
54
+ subsystem.degrade!
55
+ { name: subsystem.name, status: subsystem.status, health: subsystem.health }
56
+ end
57
+
58
+ def recover_subsystem(name:)
59
+ subsystem = find_subsystem!(name)
60
+ subsystem.recover!
61
+ { name: subsystem.name, status: subsystem.status, health: subsystem.health }
62
+ end
63
+
64
+ def subsystem_status(name:)
65
+ find_subsystem!(name).to_h
66
+ end
67
+
68
+ def active_subsystems
69
+ @subsystems.values.select { |s| s.status == :active }
70
+ end
71
+
72
+ def bottlenecked_subsystems
73
+ @subsystems.values.select(&:bottlenecked?)
74
+ end
75
+
76
+ def connections_for(name:)
77
+ subsystem = find_subsystem!(name)
78
+ @connections.values.select do |c|
79
+ c.source_id == subsystem.id || c.target_id == subsystem.id
80
+ end
81
+ end
82
+
83
+ def downstream(name:, max_depth: 5)
84
+ start = find_subsystem!(name)
85
+ visited = bfs_visited(start.id, max_depth)
86
+ visited.keys.filter_map { |sid| subsystem_by_id(sid) }.reject { |s| s.id == start.id }
87
+ end
88
+
89
+ def architecture_health
90
+ return 0.0 if @subsystems.empty?
91
+
92
+ total = @subsystems.values.sum(&:health)
93
+ total / @subsystems.size
94
+ end
95
+
96
+ def architecture_graph
97
+ {
98
+ nodes: @subsystems.values.map(&:to_h),
99
+ edges: @connections.values.map(&:to_h)
100
+ }
101
+ end
102
+
103
+ def decay_all
104
+ @subsystems.each_value { |s| s.degrade!(Constants::HEALTH_DECAY) }
105
+ { decayed: @subsystems.size }
106
+ end
107
+
108
+ def to_h
109
+ {
110
+ subsystem_count: @subsystems.size,
111
+ connection_count: @connections.size,
112
+ active_count: active_subsystems.size,
113
+ bottlenecked_count: bottlenecked_subsystems.size,
114
+ architecture_health: architecture_health
115
+ }
116
+ end
117
+
118
+ private
119
+
120
+ def find_subsystem!(name)
121
+ @subsystems.fetch(name.to_sym) do
122
+ raise ArgumentError, "subsystem '#{name}' not found"
123
+ end
124
+ end
125
+
126
+ def subsystem_by_id(id)
127
+ @subsystems.values.find { |s| s.id == id }
128
+ end
129
+
130
+ def excitatory_connections_from(source_id)
131
+ @connections.values.select do |c|
132
+ c.source_id == source_id && c.connection_type == :excitatory && c.active
133
+ end
134
+ end
135
+
136
+ def bfs_visited(start_id, max_depth)
137
+ visited = {}
138
+ queue = [[start_id, 0]]
139
+
140
+ until queue.empty?
141
+ current_id, depth = queue.shift
142
+ next if visited.key?(current_id)
143
+
144
+ visited[current_id] = depth
145
+ enqueue_neighbors(current_id, depth, visited, queue) if depth < max_depth
146
+ end
147
+
148
+ visited
149
+ end
150
+
151
+ def enqueue_neighbors(current_id, depth, visited, queue)
152
+ @connections.each_value do |conn|
153
+ next unless conn.source_id == current_id && conn.active
154
+ next if visited.key?(conn.target_id)
155
+
156
+ queue << [conn.target_id, depth + 1]
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module CognitiveArchitecture
8
+ module Helpers
9
+ class Connection
10
+ attr_reader :id, :source_id, :target_id, :connection_type, :created_at
11
+ attr_accessor :weight, :active
12
+
13
+ def initialize(source_id:, target_id:, connection_type: :informational, weight: 0.5)
14
+ @id = SecureRandom.uuid
15
+ @source_id = source_id
16
+ @target_id = target_id
17
+ @connection_type = connection_type.to_sym
18
+ @weight = weight.clamp(0.0, 1.0)
19
+ @active = true
20
+ @created_at = Time.now.utc
21
+ end
22
+
23
+ def strengthen!(amount = 0.05)
24
+ @weight = (@weight + amount).clamp(0.0, 1.0)
25
+ self
26
+ end
27
+
28
+ def weaken!(amount = 0.05)
29
+ @weight = (@weight - amount).clamp(0.0, 1.0)
30
+ self
31
+ end
32
+
33
+ def toggle!
34
+ @active = !@active
35
+ self
36
+ end
37
+
38
+ def to_h
39
+ {
40
+ id: @id,
41
+ source_id: @source_id,
42
+ target_id: @target_id,
43
+ connection_type: @connection_type,
44
+ weight: @weight,
45
+ active: @active,
46
+ created_at: @created_at
47
+ }
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveArchitecture
6
+ module Helpers
7
+ module Constants
8
+ SUBSYSTEM_TYPES = %i[perception cognition memory motivation safety communication introspection coordination].freeze
9
+ CONNECTION_TYPES = %i[excitatory inhibitory modulatory informational].freeze
10
+ STATUS_LEVELS = %i[active idle degraded offline].freeze
11
+
12
+ HEALTH_LABELS = {
13
+ (0.8..) => :excellent,
14
+ (0.6...0.8) => :good,
15
+ (0.4...0.6) => :fair,
16
+ (0.2...0.4) => :degraded,
17
+ (..0.2) => :critical
18
+ }.freeze
19
+
20
+ BOTTLENECK_THRESHOLD = 0.3
21
+
22
+ MAX_SUBSYSTEMS = 200
23
+ MAX_CONNECTIONS = 1000
24
+ MAX_HISTORY = 500
25
+
26
+ DEFAULT_HEALTH = 0.8
27
+ HEALTH_DECAY = 0.01
28
+ HEALTH_BOOST = 0.05
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module CognitiveArchitecture
8
+ module Helpers
9
+ class Subsystem
10
+ include Constants
11
+
12
+ attr_reader :id, :name, :subsystem_type, :activation_count, :last_activated_at, :created_at
13
+ attr_accessor :health, :status, :load
14
+
15
+ def initialize(name:, subsystem_type:, health: Constants::DEFAULT_HEALTH)
16
+ @id = SecureRandom.uuid
17
+ @name = name.to_sym
18
+ @subsystem_type = subsystem_type.to_sym
19
+ @health = health.clamp(0.0, 1.0)
20
+ @status = :active
21
+ @load = 0.0
22
+ @activation_count = 0
23
+ @last_activated_at = nil
24
+ @created_at = Time.now.utc
25
+ end
26
+
27
+ def activate!
28
+ @activation_count += 1
29
+ @last_activated_at = Time.now.utc
30
+ @health = (@health + Constants::HEALTH_BOOST).clamp(0.0, 1.0)
31
+ self
32
+ end
33
+
34
+ def degrade!(amount = Constants::HEALTH_DECAY)
35
+ @health = (@health - amount).clamp(0.0, 1.0)
36
+ @status = :degraded if @health < 0.4
37
+ self
38
+ end
39
+
40
+ def recover!(amount = Constants::HEALTH_BOOST)
41
+ @health = (@health + amount).clamp(0.0, 1.0)
42
+ @status = :active if @health >= 0.4
43
+ self
44
+ end
45
+
46
+ def bottlenecked?
47
+ @load > Constants::BOTTLENECK_THRESHOLD && @health < 0.5
48
+ end
49
+
50
+ def health_label
51
+ Constants::HEALTH_LABELS.each do |range, label|
52
+ return label if range.cover?(@health)
53
+ end
54
+ :critical
55
+ end
56
+
57
+ def to_h
58
+ {
59
+ id: @id,
60
+ name: @name,
61
+ subsystem_type: @subsystem_type,
62
+ health: @health,
63
+ health_label: health_label,
64
+ status: @status,
65
+ load: @load,
66
+ activation_count: @activation_count,
67
+ last_activated_at: @last_activated_at,
68
+ created_at: @created_at,
69
+ bottlenecked: bottlenecked?
70
+ }
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveArchitecture
6
+ module Runners
7
+ module CognitiveArchitecture
8
+ extend self
9
+
10
+ def register_architecture_subsystem(name:, subsystem_type:, health: Helpers::Constants::DEFAULT_HEALTH, **)
11
+ Legion::Logging.debug "[cognitive_architecture] registering subsystem: #{name} (#{subsystem_type})"
12
+ subsystem = engine.register_subsystem(name: name, subsystem_type: subsystem_type, health: health)
13
+ { status: :registered, subsystem: subsystem.to_h }
14
+ rescue ArgumentError => e
15
+ Legion::Logging.warn "[cognitive_architecture] register_subsystem failed: #{e.message}"
16
+ { status: :error, message: e.message }
17
+ end
18
+
19
+ def create_architecture_connection(source_name:, target_name:,
20
+ connection_type: :informational, weight: 0.5, **)
21
+ Legion::Logging.debug "[cognitive_architecture] creating connection: #{source_name} -> #{target_name} (#{connection_type})"
22
+ conn = engine.create_connection(
23
+ source_name: source_name,
24
+ target_name: target_name,
25
+ connection_type: connection_type,
26
+ weight: weight
27
+ )
28
+ { status: :created, connection: conn.to_h }
29
+ rescue ArgumentError => e
30
+ Legion::Logging.warn "[cognitive_architecture] create_connection failed: #{e.message}"
31
+ { status: :error, message: e.message }
32
+ end
33
+
34
+ def activate_architecture_subsystem(name:, **)
35
+ Legion::Logging.debug "[cognitive_architecture] activating subsystem: #{name}"
36
+ result = engine.activate_subsystem(name: name)
37
+ { status: :activated, name: result[:name], health: result[:health], subsystem_status: result[:status] }
38
+ rescue ArgumentError => e
39
+ Legion::Logging.warn "[cognitive_architecture] activate_subsystem failed: #{e.message}"
40
+ { status: :error, message: e.message }
41
+ end
42
+
43
+ def degrade_architecture_subsystem(name:, **)
44
+ Legion::Logging.debug "[cognitive_architecture] degrading subsystem: #{name}"
45
+ result = engine.degrade_subsystem(name: name)
46
+ { status: :degraded, name: result[:name], health: result[:health], subsystem_status: result[:status] }
47
+ rescue ArgumentError => e
48
+ Legion::Logging.warn "[cognitive_architecture] degrade_subsystem failed: #{e.message}"
49
+ { status: :error, message: e.message }
50
+ end
51
+
52
+ def subsystem_status_report(name:, **)
53
+ Legion::Logging.debug "[cognitive_architecture] status report for: #{name}"
54
+ engine.subsystem_status(name: name)
55
+ rescue ArgumentError => e
56
+ { status: :error, message: e.message }
57
+ end
58
+
59
+ def bottleneck_report(**)
60
+ bottlenecked = engine.bottlenecked_subsystems
61
+ Legion::Logging.debug "[cognitive_architecture] bottleneck_report: #{bottlenecked.size} bottlenecked"
62
+ {
63
+ bottlenecked_count: bottlenecked.size,
64
+ subsystems: bottlenecked.map(&:to_h)
65
+ }
66
+ end
67
+
68
+ def architecture_health_report(**)
69
+ health = engine.architecture_health
70
+ Legion::Logging.debug "[cognitive_architecture] architecture_health: #{health.round(3)}"
71
+ {
72
+ health: health,
73
+ health_label: label_for_health(health),
74
+ active_count: engine.active_subsystems.size
75
+ }
76
+ end
77
+
78
+ def architecture_graph_report(**)
79
+ Legion::Logging.debug '[cognitive_architecture] building architecture_graph'
80
+ engine.architecture_graph
81
+ end
82
+
83
+ def downstream_subsystems(name:, max_depth: 5, **)
84
+ Legion::Logging.debug "[cognitive_architecture] downstream traversal from: #{name} (max_depth=#{max_depth})"
85
+ reachable = engine.downstream(name: name, max_depth: max_depth)
86
+ {
87
+ source: name,
88
+ reachable: reachable.map(&:to_h),
89
+ count: reachable.size
90
+ }
91
+ rescue ArgumentError => e
92
+ { status: :error, message: e.message }
93
+ end
94
+
95
+ def update_cognitive_architecture(**)
96
+ Legion::Logging.debug '[cognitive_architecture] running decay cycle'
97
+ result = engine.decay_all
98
+ { status: :updated, decayed: result[:decayed] }
99
+ end
100
+
101
+ def cognitive_architecture_stats(**)
102
+ engine.to_h
103
+ end
104
+
105
+ private
106
+
107
+ def engine
108
+ @engine ||= Helpers::ArchitectureEngine.new
109
+ end
110
+
111
+ def label_for_health(health)
112
+ Helpers::Constants::HEALTH_LABELS.each do |range, label|
113
+ return label if range.cover?(health)
114
+ end
115
+ :critical
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveArchitecture
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/cognitive_architecture/version'
4
+ require 'legion/extensions/cognitive_architecture/helpers/constants'
5
+ require 'legion/extensions/cognitive_architecture/helpers/subsystem'
6
+ require 'legion/extensions/cognitive_architecture/helpers/connection'
7
+ require 'legion/extensions/cognitive_architecture/helpers/architecture_engine'
8
+ require 'legion/extensions/cognitive_architecture/runners/cognitive_architecture'
9
+ require 'legion/extensions/cognitive_architecture/client'
10
+
11
+ module Legion
12
+ module Extensions
13
+ module CognitiveArchitecture
14
+ extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
15
+ end
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-cognitive-architecture
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: Meta-extension that models the agent cognitive architecture as a graph
27
+ of subsystems, connections, and information flows — enabling self-awareness of its
28
+ own architecture
29
+ email:
30
+ - matthewdiverson@gmail.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".github/workflows/ci.yml"
36
+ - ".gitignore"
37
+ - ".rspec"
38
+ - ".rubocop.yml"
39
+ - CLAUDE.md
40
+ - Gemfile
41
+ - Gemfile.lock
42
+ - README.md
43
+ - lex-cognitive-architecture.gemspec
44
+ - lib/legion/extensions/cognitive_architecture.rb
45
+ - lib/legion/extensions/cognitive_architecture/client.rb
46
+ - lib/legion/extensions/cognitive_architecture/helpers/architecture_engine.rb
47
+ - lib/legion/extensions/cognitive_architecture/helpers/connection.rb
48
+ - lib/legion/extensions/cognitive_architecture/helpers/constants.rb
49
+ - lib/legion/extensions/cognitive_architecture/helpers/subsystem.rb
50
+ - lib/legion/extensions/cognitive_architecture/runners/cognitive_architecture.rb
51
+ - lib/legion/extensions/cognitive_architecture/version.rb
52
+ homepage: https://github.com/LegionIO/lex-cognitive-architecture
53
+ licenses:
54
+ - MIT
55
+ metadata:
56
+ homepage_uri: https://github.com/LegionIO/lex-cognitive-architecture
57
+ source_code_uri: https://github.com/LegionIO/lex-cognitive-architecture
58
+ documentation_uri: https://github.com/LegionIO/lex-cognitive-architecture
59
+ changelog_uri: https://github.com/LegionIO/lex-cognitive-architecture
60
+ bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-architecture/issues
61
+ rubygems_mfa_required: 'true'
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '3.4'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubygems_version: 3.6.9
77
+ specification_version: 4
78
+ summary: LEX Cognitive Architecture
79
+ test_files: []