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 +7 -0
- data/.github/workflows/ci.yml +16 -0
- data/.gitignore +2 -0
- data/.rspec +3 -0
- data/.rubocop.yml +37 -0
- data/CLAUDE.md +75 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +78 -0
- data/README.md +51 -0
- data/lex-cognitive-constellation.gemspec +33 -0
- data/lib/legion/extensions/cognitive_constellation/client.rb +11 -0
- data/lib/legion/extensions/cognitive_constellation/helpers/constants.rb +55 -0
- data/lib/legion/extensions/cognitive_constellation/helpers/constellation.rb +86 -0
- data/lib/legion/extensions/cognitive_constellation/helpers/sky_engine.rb +127 -0
- data/lib/legion/extensions/cognitive_constellation/helpers/star.rb +88 -0
- data/lib/legion/extensions/cognitive_constellation/runners/cognitive_constellation.rb +72 -0
- data/lib/legion/extensions/cognitive_constellation/version.rb +9 -0
- data/lib/legion/extensions/cognitive_constellation.rb +19 -0
- metadata +79 -0
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
data/.rspec
ADDED
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
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,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,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: []
|