lex-cognitive-constellation 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: 420b47a6be614c2a1ab6c4b0f6ca074baac0e63d6fe1791b6845b617261602bc
4
+ data.tar.gz: 7071398b68ea8d56d0b39999a07de7b7c2e49aea66705cf17e8a0f0b370edae6
5
+ SHA512:
6
+ metadata.gz: 3d48b04e425054702f7e0cfa8b83cfb4b676dda3c526afbe9eae74c1d966ef54db35d87c19985601afc7f035c08263fe8e550fcd1c8c61d8c740b5d0183a4fb5
7
+ data.tar.gz: 73de52721a9825aa606982f2770cd83813e0038f58edef196c4c030a317a6c2cdeb6a8f64bbb66d4debef820994c7d4e879863ea016f47a490c3b73340e98c0e
@@ -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,3 @@
1
+ --require spec_helper
2
+ --format documentation
3
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,37 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ TargetRubyVersion: 3.4
4
+
5
+ Style/Documentation:
6
+ Enabled: false
7
+
8
+ Naming/PredicateMethod:
9
+ Enabled: false
10
+
11
+ Naming/PredicatePrefix:
12
+ Enabled: false
13
+
14
+ Metrics/ClassLength:
15
+ Max: 150
16
+
17
+ Metrics/MethodLength:
18
+ Max: 25
19
+
20
+ Metrics/AbcSize:
21
+ Max: 25
22
+
23
+ Metrics/ParameterLists:
24
+ Max: 8
25
+ MaxOptionalParameters: 8
26
+
27
+ Layout/HashAlignment:
28
+ EnforcedColonStyle: table
29
+ EnforcedHashRocketStyle: table
30
+
31
+ Metrics/BlockLength:
32
+ Exclude:
33
+ - 'spec/**/*'
34
+
35
+ Style/OneClassPerFile:
36
+ Exclude:
37
+ - 'spec/spec_helper.rb'
data/CLAUDE.md ADDED
@@ -0,0 +1,75 @@
1
+ # lex-cognitive-constellation
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
+ Maps ideas as stars with magnitude and spectral class, groups them into constellations with pattern types, and enables celestial navigation between related concepts across cognitive domains. Provides a spatial metaphor for knowledge organization and cross-domain traversal.
10
+
11
+ ## Gem Info
12
+
13
+ - **Gem name**: `lex-cognitive-constellation`
14
+ - **Version**: `0.1.0`
15
+ - **Module**: `Legion::Extensions::CognitiveConstellation`
16
+ - **Ruby**: `>= 3.4`
17
+ - **License**: MIT
18
+
19
+ ## File Structure
20
+
21
+ ```
22
+ lib/legion/extensions/cognitive_constellation/
23
+ cognitive_constellation.rb
24
+ version.rb
25
+ client.rb
26
+ helpers/
27
+ constants.rb
28
+ sky_engine.rb
29
+ star.rb
30
+ constellation.rb
31
+ runners/
32
+ cognitive_constellation.rb
33
+ ```
34
+
35
+ ## Key Constants
36
+
37
+ From `helpers/constants.rb`:
38
+
39
+ - `SPECTRAL_CLASSES` — `%i[O B A F G K M]` (hottest to coolest — maps to idea intensity/age)
40
+ - `PATTERN_TYPES` — `%i[linear circular spiral cluster cross arc ring scattered]`
41
+ - `DOMAINS` — `%i[reasoning memory emotion language perception action planning social creativity logic intuition ethics]`
42
+ - `MAX_STARS` = `500`, `MAX_CONSTELLATIONS` = `50`
43
+ - `MAGNITUDE_DECAY` = `0.01`, `MIN_MAGNITUDE` = `0.05`
44
+ - `MAGNITUDE_LABELS` — `0.8+` = `:supergiant`, `0.6` = `:giant`, `0.4` = `:main_sequence`, `0.2` = `:dwarf`, below = `:brown_dwarf`
45
+ - `MATURITY_LABELS` — `0.8+` = `:ancient`, `0.6` = `:established`, `0.4` = `:forming`, `0.2` = `:nascent`, below = `:proto`
46
+
47
+ ## Runners
48
+
49
+ All methods in `Runners::CognitiveConstellation` (`extend self`):
50
+
51
+ - `discover_star(name:, domain:, content:, magnitude: nil, spectral_class: nil)` — registers a new concept as a star; magnitude and spectral class are optional
52
+ - `form_constellation(name:, pattern_type:, star_ids: [])` — groups stars into a named constellation with a pattern type
53
+ - `navigate(from_star_id:, target_domain:)` — finds reachable stars in the target domain starting from the source star
54
+ - `list_stars(domain: nil)` — all stars, optionally filtered by domain
55
+ - `list_constellations` — all constellations
56
+ - `sky_status` — full sky report: star count, constellation count, brightest stars, domain distribution
57
+
58
+ ## Helpers
59
+
60
+ - `SkyEngine` — manages `@stars` and `@constellations`. `navigate` traverses star connections to find domain-adjacent concepts.
61
+ - `Star` — has `name`, `domain`, `content`, `magnitude`, `spectral_class`. `magnitude` decays over time if not reinforced. `magnitude_label` classifies brightness.
62
+ - `Constellation` — named grouping of star IDs with `pattern_type` and maturity score derived from number of member stars and their average magnitude.
63
+
64
+ ## Integration Points
65
+
66
+ - `lex-memory` traces have domains; stars map those domains into a navigable spatial structure — cross-domain navigation via `navigate` mirrors `walk_associations` in `lex-dream`.
67
+ - `lex-cognitive-aurora` detects harmony events across domains; constellations are the structural groupings that make aurora detection meaningful (aurora fires when constellation members align).
68
+ - `MAGNITUDE_DECAY` means unused concepts fade from the sky — magnitude is an attention proxy.
69
+
70
+ ## Development Notes
71
+
72
+ - `discover_star` and `form_constellation` raise `ArgumentError` on invalid inputs; runners catch these and return `{ success: false, error: e.message }`.
73
+ - `navigate` is BFS or similarity-based traversal starting from a known star, targeting a domain. The depth and algorithm are internal to `SkyEngine`.
74
+ - `spectral_class` follows the OBAFGKM Harvard classification, repurposed as an idea intensity/age proxy. `:O` = hot/young/intense; `:M` = cool/old/stable.
75
+ - Constellations do not need member stars at creation time — `star_ids: []` is valid. Stars can be added later.
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :development, :test do
8
+ gem 'rspec', '~> 3.13'
9
+ gem 'rubocop', '~> 1.75'
10
+ gem 'rubocop-rspec'
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-constellation (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-constellation!
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,51 @@
1
+ # lex-cognitive-constellation
2
+
3
+ Cognitive constellation LEX — star-mapping for concepts. Maps ideas as stars with magnitude and spectral class, groups them into constellations with pattern types, and enables celestial navigation between related concepts across cognitive domains.
4
+
5
+ ## What It Does
6
+
7
+ Ideas are stars: some are supergiants (high magnitude, highly salient), others are brown dwarfs (faint, nearly forgotten). Related ideas form constellations — linear, circular, spiral, cluster, cross, arc, ring, or scattered patterns. Navigation between stars enables cross-domain traversal: starting from a known concept and finding related concepts in a target domain.
8
+
9
+ Magnitude decays over time, modeling the natural fading of unused ideas from active consideration.
10
+
11
+ ## Usage
12
+
13
+ ```ruby
14
+ client = Legion::Extensions::CognitiveConstellation::Client.new
15
+
16
+ star1 = client.discover_star(
17
+ name: 'trust_anchoring',
18
+ domain: :reasoning,
19
+ content: 'initial trust scores anchor all subsequent assessments',
20
+ magnitude: 0.8,
21
+ spectral_class: :G
22
+ )
23
+
24
+ star2 = client.discover_star(
25
+ name: 'anchoring_bias',
26
+ domain: :reasoning,
27
+ content: 'first information received disproportionately weights judgment',
28
+ magnitude: 0.7
29
+ )
30
+
31
+ client.form_constellation(
32
+ name: 'anchoring_cluster',
33
+ pattern_type: :cluster,
34
+ star_ids: [star1[:star][:id], star2[:star][:id]]
35
+ )
36
+
37
+ client.navigate(from_star_id: star1[:star][:id], target_domain: :emotion)
38
+ client.sky_status
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,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/cognitive_constellation/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-cognitive-constellation'
7
+ spec.version = Legion::Extensions::CognitiveConstellation::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+ spec.license = 'MIT'
11
+
12
+ spec.summary = 'Cognitive constellation LEX — star-mapping for concepts'
13
+ spec.description = 'Maps ideas as stars with magnitude and spectral class, groups them into ' \
14
+ 'constellations with pattern types, and enables celestial navigation between ' \
15
+ 'related concepts across cognitive domains.'
16
+ spec.homepage = 'https://github.com/LegionIO/lex-cognitive-constellation'
17
+
18
+ spec.required_ruby_version = '>= 3.4'
19
+
20
+ spec.metadata['homepage_uri'] = spec.homepage
21
+ spec.metadata['source_code_uri'] = spec.homepage
22
+ spec.metadata['documentation_uri'] = "#{spec.homepage}#readme"
23
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
24
+ spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/issues"
25
+ spec.metadata['rubygems_mfa_required'] = 'true'
26
+
27
+ spec.files = Dir.chdir(__dir__) do
28
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(test|spec|features)/}) }
29
+ end
30
+
31
+ spec.require_paths = ['lib']
32
+ spec.add_development_dependency 'legion-gaia'
33
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveConstellation
6
+ class Client
7
+ include Runners::CognitiveConstellation
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveConstellation
6
+ module Helpers
7
+ module Constants
8
+ # Star spectral classes (hottest to coolest)
9
+ SPECTRAL_CLASSES = %i[O B A F G K M].freeze
10
+
11
+ # Constellation pattern types
12
+ PATTERN_TYPES = %i[
13
+ linear circular spiral cluster
14
+ cross arc ring scattered
15
+ ].freeze
16
+
17
+ # Star domains
18
+ DOMAINS = %i[
19
+ reasoning memory emotion language
20
+ perception action planning social
21
+ creativity logic intuition ethics
22
+ ].freeze
23
+
24
+ MAX_STARS = 500
25
+ MAX_CONSTELLATIONS = 50
26
+ MAGNITUDE_DECAY = 0.01
27
+ MIN_MAGNITUDE = 0.05
28
+
29
+ # Magnitude labels (higher = brighter = more important)
30
+ MAGNITUDE_LABELS = [
31
+ [(0.8..), :supergiant],
32
+ [(0.6...0.8), :giant],
33
+ [(0.4...0.6), :main_sequence],
34
+ [(0.2...0.4), :dwarf],
35
+ [(..0.2), :brown_dwarf]
36
+ ].freeze
37
+
38
+ # Constellation maturity labels
39
+ MATURITY_LABELS = [
40
+ [(0.8..), :ancient],
41
+ [(0.6...0.8), :established],
42
+ [(0.4...0.6), :forming],
43
+ [(0.2...0.4), :nascent],
44
+ [(..0.2), :proto]
45
+ ].freeze
46
+
47
+ def self.label_for(table, value)
48
+ table.each { |range, label| return label if range.cover?(value) }
49
+ table.last.last
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveConstellation
6
+ module Helpers
7
+ class Constellation
8
+ attr_reader :id, :name, :pattern_type, :star_ids,
9
+ :formed_at
10
+ attr_accessor :maturity
11
+
12
+ def initialize(name:, pattern_type:, maturity: nil)
13
+ validate_pattern!(pattern_type)
14
+ @id = SecureRandom.uuid
15
+ @name = name.to_s
16
+ @pattern_type = pattern_type.to_sym
17
+ @star_ids = []
18
+ @maturity = (maturity || 0.1).to_f.clamp(0.0, 1.0).round(10)
19
+ @formed_at = Time.now.utc
20
+ end
21
+
22
+ def add_star(star_id)
23
+ return false if @star_ids.include?(star_id)
24
+
25
+ @star_ids << star_id
26
+ @maturity = (@maturity + 0.05).clamp(0.0, 1.0).round(10)
27
+ true
28
+ end
29
+
30
+ def remove_star(star_id)
31
+ return false unless @star_ids.include?(star_id)
32
+
33
+ @star_ids.delete(star_id)
34
+ @maturity = (@maturity - 0.05).clamp(0.0, 1.0).round(10)
35
+ true
36
+ end
37
+
38
+ def size
39
+ @star_ids.size
40
+ end
41
+
42
+ def empty?
43
+ @star_ids.empty?
44
+ end
45
+
46
+ def ancient?
47
+ @maturity >= 0.8
48
+ end
49
+
50
+ def nascent?
51
+ @maturity < 0.2
52
+ end
53
+
54
+ def maturity_label
55
+ Constants.label_for(Constants::MATURITY_LABELS, @maturity)
56
+ end
57
+
58
+ def to_h
59
+ {
60
+ id: @id,
61
+ name: @name,
62
+ pattern_type: @pattern_type,
63
+ star_ids: @star_ids.dup,
64
+ size: size,
65
+ maturity: @maturity,
66
+ maturity_label: maturity_label,
67
+ formed_at: @formed_at,
68
+ ancient: ancient?,
69
+ nascent: nascent?
70
+ }
71
+ end
72
+
73
+ private
74
+
75
+ def validate_pattern!(val)
76
+ return if Constants::PATTERN_TYPES.include?(val.to_sym)
77
+
78
+ raise ArgumentError,
79
+ "unknown pattern type: #{val.inspect}; " \
80
+ "must be one of #{Constants::PATTERN_TYPES.inspect}"
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveConstellation
6
+ module Helpers
7
+ class SkyEngine
8
+ def initialize
9
+ @stars = {}
10
+ @constellations = {}
11
+ end
12
+
13
+ def discover_star(name:, domain:, content:, magnitude: nil, spectral_class: nil)
14
+ raise ArgumentError, 'sky catalog full' if @stars.size >= Constants::MAX_STARS
15
+
16
+ star = Star.new(name: name, domain: domain, content: content,
17
+ magnitude: magnitude, spectral_class: spectral_class)
18
+ @stars[star.id] = star
19
+ star
20
+ end
21
+
22
+ def form_constellation(name:, pattern_type:, star_ids: [])
23
+ raise ArgumentError, 'too many constellations' if @constellations.size >= Constants::MAX_CONSTELLATIONS
24
+
25
+ constellation = Constellation.new(name: name, pattern_type: pattern_type)
26
+ @constellations[constellation.id] = constellation
27
+
28
+ star_ids.each { |sid| link_star(star_id: sid, constellation_id: constellation.id) }
29
+ constellation
30
+ end
31
+
32
+ def link_star(star_id:, constellation_id:)
33
+ star = fetch_star(star_id)
34
+ constellation = fetch_constellation(constellation_id)
35
+
36
+ constellation.add_star(star_id)
37
+ star.join_constellation(constellation_id)
38
+ end
39
+
40
+ def brighten_star(star_id:, boost: 0.1)
41
+ fetch_star(star_id).brighten!(boost: boost)
42
+ end
43
+
44
+ def dim_all!(rate: Constants::MAGNITUDE_DECAY)
45
+ @stars.each_value { |s| s.dim!(rate: rate) }
46
+ pruned = @stars.select { |_, s| s.magnitude < Constants::MIN_MAGNITUDE }.keys
47
+ pruned.each { |id| remove_star(id) }
48
+ { remaining: @stars.size, pruned: pruned.size }
49
+ end
50
+
51
+ def navigate(from_star_id:, target_domain:)
52
+ from = fetch_star(from_star_id)
53
+ shared = from.constellation_ids.flat_map do |cid|
54
+ fetch_constellation(cid).star_ids
55
+ end.uniq - [from_star_id]
56
+
57
+ shared.filter_map { |sid| @stars[sid] }
58
+ .select { |s| s.domain == target_domain.to_sym }
59
+ .sort_by { |s| -s.magnitude }
60
+ end
61
+
62
+ def stars_by_domain
63
+ counts = Constants::DOMAINS.to_h { |d| [d, 0] }
64
+ @stars.each_value { |s| counts[s.domain] += 1 }
65
+ counts
66
+ end
67
+
68
+ def brightest(limit: 5)
69
+ @stars.values.sort_by { |s| -s.magnitude }.first(limit)
70
+ end
71
+
72
+ def faintest(limit: 5)
73
+ @stars.values.sort_by(&:magnitude).first(limit)
74
+ end
75
+
76
+ def largest_constellations(limit: 5)
77
+ @constellations.values.sort_by { |c| -c.size }.first(limit)
78
+ end
79
+
80
+ def sky_report
81
+ {
82
+ total_stars: @stars.size,
83
+ total_constellations: @constellations.size,
84
+ by_domain: stars_by_domain,
85
+ supergiants: @stars.count { |_, s| s.supergiant? },
86
+ fading: @stars.count { |_, s| s.fading? },
87
+ avg_magnitude: avg_magnitude
88
+ }
89
+ end
90
+
91
+ def all_stars
92
+ @stars.values
93
+ end
94
+
95
+ def all_constellations
96
+ @constellations.values
97
+ end
98
+
99
+ private
100
+
101
+ def fetch_star(id)
102
+ @stars.fetch(id) { raise ArgumentError, "star not found: #{id}" }
103
+ end
104
+
105
+ def fetch_constellation(id)
106
+ @constellations.fetch(id) { raise ArgumentError, "constellation not found: #{id}" }
107
+ end
108
+
109
+ def remove_star(id)
110
+ star = @stars.delete(id)
111
+ return unless star
112
+
113
+ star.constellation_ids.each do |cid|
114
+ @constellations[cid]&.remove_star(id)
115
+ end
116
+ end
117
+
118
+ def avg_magnitude
119
+ return 0.0 if @stars.empty?
120
+
121
+ (@stars.values.sum(&:magnitude) / @stars.size).round(10)
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveConstellation
6
+ module Helpers
7
+ class Star
8
+ attr_reader :id, :name, :domain, :content, :spectral_class,
9
+ :discovered_at, :constellation_ids
10
+ attr_accessor :magnitude
11
+
12
+ def initialize(name:, domain:, content:,
13
+ magnitude: nil, spectral_class: nil)
14
+ validate_domain!(domain)
15
+ assign_core(name, domain, content)
16
+ assign_metadata(magnitude, spectral_class)
17
+ end
18
+
19
+ def dim!(rate: Constants::MAGNITUDE_DECAY)
20
+ @magnitude = (@magnitude - rate.abs).clamp(0.0, 1.0).round(10)
21
+ self
22
+ end
23
+
24
+ def brighten!(boost: 0.1)
25
+ @magnitude = (@magnitude + boost.abs).clamp(0.0, 1.0).round(10)
26
+ self
27
+ end
28
+
29
+ def supergiant?
30
+ @magnitude >= 0.8
31
+ end
32
+
33
+ def fading?
34
+ @magnitude < 0.2
35
+ end
36
+
37
+ def join_constellation(constellation_id)
38
+ @constellation_ids << constellation_id unless @constellation_ids.include?(constellation_id)
39
+ end
40
+
41
+ def magnitude_label
42
+ Constants.label_for(Constants::MAGNITUDE_LABELS, @magnitude)
43
+ end
44
+
45
+ def to_h
46
+ {
47
+ id: @id,
48
+ name: @name,
49
+ domain: @domain,
50
+ content: @content,
51
+ spectral_class: @spectral_class,
52
+ magnitude: @magnitude,
53
+ magnitude_label: magnitude_label,
54
+ discovered_at: @discovered_at,
55
+ constellation_ids: @constellation_ids,
56
+ supergiant: supergiant?,
57
+ fading: fading?
58
+ }
59
+ end
60
+
61
+ private
62
+
63
+ def assign_core(name, domain, content)
64
+ @id = SecureRandom.uuid
65
+ @name = name.to_s
66
+ @domain = domain.to_sym
67
+ @content = content.to_s
68
+ end
69
+
70
+ def assign_metadata(magnitude, spectral_class)
71
+ @magnitude = (magnitude || 0.5).to_f.clamp(0.0, 1.0).round(10)
72
+ @spectral_class = (spectral_class || Constants::SPECTRAL_CLASSES.sample).to_sym
73
+ @discovered_at = Time.now.utc
74
+ @constellation_ids = []
75
+ end
76
+
77
+ def validate_domain!(val)
78
+ return if Constants::DOMAINS.include?(val.to_sym)
79
+
80
+ raise ArgumentError,
81
+ "unknown domain: #{val.inspect}; " \
82
+ "must be one of #{Constants::DOMAINS.inspect}"
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveConstellation
6
+ module Runners
7
+ module CognitiveConstellation
8
+ extend self
9
+
10
+ def discover_star(name:, domain:, content:,
11
+ magnitude: nil, spectral_class: nil, engine: nil, **)
12
+ eng = resolve_engine(engine)
13
+ star = eng.discover_star(name: name, domain: domain, content: content,
14
+ magnitude: magnitude, spectral_class: spectral_class)
15
+ { success: true, star: star.to_h }
16
+ rescue ArgumentError => e
17
+ { success: false, error: e.message }
18
+ end
19
+
20
+ def form_constellation(name:, pattern_type:, star_ids: [], engine: nil, **)
21
+ eng = resolve_engine(engine)
22
+ con = eng.form_constellation(name: name, pattern_type: pattern_type,
23
+ star_ids: star_ids)
24
+ { success: true, constellation: con.to_h }
25
+ rescue ArgumentError => e
26
+ { success: false, error: e.message }
27
+ end
28
+
29
+ def navigate(from_star_id:, target_domain:, engine: nil, **)
30
+ eng = resolve_engine(engine)
31
+ results = eng.navigate(from_star_id: from_star_id,
32
+ target_domain: target_domain)
33
+ { success: true, stars: results.map(&:to_h), count: results.size }
34
+ rescue ArgumentError => e
35
+ { success: false, error: e.message }
36
+ end
37
+
38
+ def list_stars(engine: nil, domain: nil, **)
39
+ eng = resolve_engine(engine)
40
+ results = eng.all_stars
41
+ results = results.select { |s| s.domain == domain.to_sym } if domain
42
+ { success: true, stars: results.map(&:to_h), count: results.size }
43
+ end
44
+
45
+ def list_constellations(engine: nil, **)
46
+ eng = resolve_engine(engine)
47
+ { success: true,
48
+ constellations: eng.all_constellations.map(&:to_h),
49
+ count: eng.all_constellations.size }
50
+ end
51
+
52
+ def sky_status(engine: nil, **)
53
+ eng = resolve_engine(engine)
54
+ { success: true, report: eng.sky_report }
55
+ end
56
+
57
+ include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
58
+
59
+ private
60
+
61
+ def resolve_engine(engine)
62
+ engine || default_engine
63
+ end
64
+
65
+ def default_engine
66
+ @default_engine ||= Helpers::SkyEngine.new
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveConstellation
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ require_relative 'cognitive_constellation/version'
6
+ require_relative 'cognitive_constellation/helpers/constants'
7
+ require_relative 'cognitive_constellation/helpers/star'
8
+ require_relative 'cognitive_constellation/helpers/constellation'
9
+ require_relative 'cognitive_constellation/helpers/sky_engine'
10
+ require_relative 'cognitive_constellation/runners/cognitive_constellation'
11
+ require_relative 'cognitive_constellation/client'
12
+
13
+ module Legion
14
+ module Extensions
15
+ module CognitiveConstellation
16
+ extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
17
+ end
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-cognitive-constellation
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: Maps ideas as stars with magnitude and spectral class, groups them into
27
+ constellations with pattern types, and enables celestial navigation between related
28
+ concepts across cognitive domains.
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-constellation.gemspec
44
+ - lib/legion/extensions/cognitive_constellation.rb
45
+ - lib/legion/extensions/cognitive_constellation/client.rb
46
+ - lib/legion/extensions/cognitive_constellation/helpers/constants.rb
47
+ - lib/legion/extensions/cognitive_constellation/helpers/constellation.rb
48
+ - lib/legion/extensions/cognitive_constellation/helpers/sky_engine.rb
49
+ - lib/legion/extensions/cognitive_constellation/helpers/star.rb
50
+ - lib/legion/extensions/cognitive_constellation/runners/cognitive_constellation.rb
51
+ - lib/legion/extensions/cognitive_constellation/version.rb
52
+ homepage: https://github.com/LegionIO/lex-cognitive-constellation
53
+ licenses:
54
+ - MIT
55
+ metadata:
56
+ homepage_uri: https://github.com/LegionIO/lex-cognitive-constellation
57
+ source_code_uri: https://github.com/LegionIO/lex-cognitive-constellation
58
+ documentation_uri: https://github.com/LegionIO/lex-cognitive-constellation#readme
59
+ changelog_uri: https://github.com/LegionIO/lex-cognitive-constellation/blob/main/CHANGELOG.md
60
+ bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-constellation/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: Cognitive constellation LEX — star-mapping for concepts
79
+ test_files: []