lex-cognitive-genesis 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 +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +68 -0
- data/CLAUDE.md +129 -0
- data/Gemfile +13 -0
- data/README.md +50 -0
- data/lex-cognitive-genesis.gemspec +30 -0
- data/lib/legion/extensions/cognitive_genesis/client.rb +23 -0
- data/lib/legion/extensions/cognitive_genesis/helpers/concept.rb +82 -0
- data/lib/legion/extensions/cognitive_genesis/helpers/constants.rb +128 -0
- data/lib/legion/extensions/cognitive_genesis/helpers/genesis_engine.rb +247 -0
- data/lib/legion/extensions/cognitive_genesis/helpers/seed.rb +66 -0
- data/lib/legion/extensions/cognitive_genesis/runners/genesis.rb +101 -0
- data/lib/legion/extensions/cognitive_genesis/version.rb +9 -0
- data/lib/legion/extensions/cognitive_genesis.rb +17 -0
- metadata +78 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 51c3c248b9445d32001938679a1f261a013b248e3cfc00d6622a695ac78911ed
|
|
4
|
+
data.tar.gz: 8a2d4dd89cbf10fdd33cc35c61df22e384f1c5de3fd96c1c754bab5c42b098df
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: bc41eb3e37f5d57373c4c4e3369033d22b1daaa95de9e3f324db16eefbe94b2e590c3d1161470ba4cbecc92703f25216f2b4f6d3d731de1ef2fa111d88b2ef6f
|
|
7
|
+
data.tar.gz: b1aa1db38cc13a7d2373b7b0144fc6bd834de39217a4acbbe6b35bad135f4b1cd203588a859649b547fb05df625ad94ff5ad74516dd5a7fabe1a9c654b7eeb31
|
|
@@ -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,68 @@
|
|
|
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/MethodLength:
|
|
17
|
+
Max: 25
|
|
18
|
+
|
|
19
|
+
Metrics/ClassLength:
|
|
20
|
+
Max: 200
|
|
21
|
+
|
|
22
|
+
Metrics/ModuleLength:
|
|
23
|
+
Max: 200
|
|
24
|
+
|
|
25
|
+
Metrics/BlockLength:
|
|
26
|
+
Max: 40
|
|
27
|
+
Exclude:
|
|
28
|
+
- 'spec/**/*'
|
|
29
|
+
|
|
30
|
+
Metrics/AbcSize:
|
|
31
|
+
Max: 30
|
|
32
|
+
|
|
33
|
+
Metrics/CyclomaticComplexity:
|
|
34
|
+
Max: 15
|
|
35
|
+
|
|
36
|
+
Metrics/PerceivedComplexity:
|
|
37
|
+
Max: 17
|
|
38
|
+
|
|
39
|
+
Metrics/ParameterLists:
|
|
40
|
+
Max: 8
|
|
41
|
+
MaxOptionalParameters: 8
|
|
42
|
+
|
|
43
|
+
Style/Documentation:
|
|
44
|
+
Enabled: false
|
|
45
|
+
|
|
46
|
+
Style/SymbolArray:
|
|
47
|
+
Enabled: true
|
|
48
|
+
|
|
49
|
+
Style/FrozenStringLiteralComment:
|
|
50
|
+
Enabled: true
|
|
51
|
+
EnforcedStyle: always
|
|
52
|
+
|
|
53
|
+
Style/OneClassPerFile:
|
|
54
|
+
Exclude:
|
|
55
|
+
- 'spec/spec_helper.rb'
|
|
56
|
+
|
|
57
|
+
Naming/FileName:
|
|
58
|
+
Enabled: false
|
|
59
|
+
|
|
60
|
+
Naming/PredicateMethod:
|
|
61
|
+
Enabled: false
|
|
62
|
+
|
|
63
|
+
Naming/PredicatePrefix:
|
|
64
|
+
Enabled: false
|
|
65
|
+
|
|
66
|
+
Naming/MethodParameterName:
|
|
67
|
+
Exclude:
|
|
68
|
+
- 'spec/**/*'
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# lex-cognitive-genesis
|
|
2
|
+
|
|
3
|
+
**Level 3 Leaf Documentation**
|
|
4
|
+
- **Parent**: `/Users/miverso2/rubymine/legion/extensions-agentic/CLAUDE.md`
|
|
5
|
+
- **Gem**: `lex-cognitive-genesis`
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Models the emergence of new cognitive concepts from seeds. Seeds are planted with a germination potential; once potential exceeds the germination threshold they can be germinated. Germinated seeds become concepts only when they meet three simultaneous criteria: viability (fitness >= VIABILITY_THRESHOLD), novelty (novelty >= NOVELTY_THRESHOLD), and readiness (maturity stage). Concepts can be nurtured to increase fitness, pruned if stale, cross-pollinated to produce hybrid seeds, or adopted from external sources. Tracks genesis rate and novelty landscape across domains.
|
|
10
|
+
|
|
11
|
+
## Gem Info
|
|
12
|
+
|
|
13
|
+
| Field | Value |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Gem name | `lex-cognitive-genesis` |
|
|
16
|
+
| Version | `0.1.0` |
|
|
17
|
+
| Namespace | `Legion::Extensions::CognitiveGenesis` |
|
|
18
|
+
| Ruby | `>= 3.4` |
|
|
19
|
+
| License | MIT |
|
|
20
|
+
| GitHub | https://github.com/LegionIO/lex-cognitive-genesis |
|
|
21
|
+
|
|
22
|
+
## File Structure
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
lib/legion/extensions/cognitive_genesis/
|
|
26
|
+
cognitive_genesis.rb # Top-level require
|
|
27
|
+
version.rb # VERSION = '0.1.0'
|
|
28
|
+
client.rb # Client class
|
|
29
|
+
helpers/
|
|
30
|
+
constants.rb # Concept types, domains, stages, thresholds, 6 label hashes
|
|
31
|
+
seed.rb # Seed value object
|
|
32
|
+
concept.rb # Concept value object
|
|
33
|
+
genesis_engine.rb # Engine: seeds, concepts, germination, fitness, novelty
|
|
34
|
+
runners/
|
|
35
|
+
genesis.rb # Runner module
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Key Constants
|
|
39
|
+
|
|
40
|
+
| Constant | Value | Meaning |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `CONCEPT_TYPES` | array | `[:idea, :theory, :hypothesis, :belief, :intention, :memory, :insight, :fantasy, :archetype, :symbol]` |
|
|
43
|
+
| `SOURCE_DOMAINS` | array | `[:experience, :observation, :inference, :intuition, :analogy, :synthesis, :dream, :external]` |
|
|
44
|
+
| `MATURITY_STAGES` | array | `[:nascent, :developing, :mature, :crystallized, :transcendent]` |
|
|
45
|
+
| `SEED_DOMAINS` | array | Various cognitive domains |
|
|
46
|
+
| `GERMINATION_THRESHOLD` | 0.7 | Minimum potential to attempt germination |
|
|
47
|
+
| `NOVELTY_THRESHOLD` | 0.5 | Minimum novelty for concept birth |
|
|
48
|
+
| `VIABILITY_THRESHOLD` | 0.4 | Minimum fitness for concept birth |
|
|
49
|
+
| `GENESIS_RATE_WINDOW` | last N | Rolling window for genesis rate calculation |
|
|
50
|
+
|
|
51
|
+
Label hashes: `MATURITY_LABELS`, `FITNESS_LABELS`, `NOVELTY_LABELS`, `POTENTIAL_LABELS`, `GENESIS_LABELS`, `ADOPTION_LABELS`.
|
|
52
|
+
|
|
53
|
+
## Helpers
|
|
54
|
+
|
|
55
|
+
### `Seed`
|
|
56
|
+
|
|
57
|
+
Pre-concept cognitive material awaiting germination.
|
|
58
|
+
|
|
59
|
+
- `initialize(domain:, source:, content:, potential: 0.5, seed_id: nil)`
|
|
60
|
+
- `potential`, `germinated?`, `germinate!` — marks as germinated
|
|
61
|
+
- `boost!(amount)` — increases potential, capped at 1.0
|
|
62
|
+
- `to_h`
|
|
63
|
+
|
|
64
|
+
### `Concept`
|
|
65
|
+
|
|
66
|
+
A birthed cognitive entity with fitness, novelty, and maturity tracking.
|
|
67
|
+
|
|
68
|
+
- `initialize(concept_type:, domain:, content:, fitness: 0.5, novelty: 0.5, seed_id: nil, concept_id: nil)`
|
|
69
|
+
- `nurture!(amount)` — increases fitness
|
|
70
|
+
- `viable?` — fitness >= `VIABILITY_THRESHOLD`
|
|
71
|
+
- `novel?` — novelty >= `NOVELTY_THRESHOLD`
|
|
72
|
+
- `maturity_label`, `fitness_label`, `novelty_label`
|
|
73
|
+
- `to_h`
|
|
74
|
+
|
|
75
|
+
### `GenesisEngine`
|
|
76
|
+
|
|
77
|
+
- `plant(domain:, source:, content:, potential: 0.5)` — creates Seed; returns `{ planted:, seed_id:, seed: }`
|
|
78
|
+
- `germinate(seed_id:)` — requires potential >= GERMINATION_THRESHOLD; returns Concept candidate or `{ germinated: false, reason: }`
|
|
79
|
+
- `birth(seed_id:)` — requires viable + novel + ready (germinated); stores in concept map; returns `{ born:, concept_id:, concept: }` or rejection
|
|
80
|
+
- `nurture(concept_id:, amount: 0.1)` — increases concept fitness
|
|
81
|
+
- `prune(seed_id:)` — removes seed from store
|
|
82
|
+
- `cross_pollinate(seed_a_id:, seed_b_id:)` — creates new seed combining domains and averaging potential
|
|
83
|
+
- `adopt_concept(concept_type:, domain:, content:, fitness: 0.5, novelty: 0.5)` — imports concept from external source
|
|
84
|
+
- `concept_fitness(concept_id:)` — returns fitness + label
|
|
85
|
+
- `novelty_landscape` — domain -> mean novelty map
|
|
86
|
+
- `genesis_rate` — concepts born per time window
|
|
87
|
+
- `most_adopted(limit: 10)`, `orphan_concepts(limit: 10)`
|
|
88
|
+
- `genesis_report` — full stats
|
|
89
|
+
|
|
90
|
+
## Runners
|
|
91
|
+
|
|
92
|
+
**Module**: `Legion::Extensions::CognitiveGenesis::Runners::Genesis`
|
|
93
|
+
|
|
94
|
+
| Method | Key Args | Returns |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `plant_seed` | `domain:`, `source:`, `content:`, `potential: 0.5` | `{ success:, seed_id:, seed: }` |
|
|
97
|
+
| `germinate_seed` | `seed_id:` | `{ success:, concept: }` or `{ success: false, reason: }` |
|
|
98
|
+
| `birth_concept` | `seed_id:` | `{ success:, concept_id:, concept: }` |
|
|
99
|
+
| `nurture_concept` | `concept_id:`, `amount: 0.1` | `{ success:, concept: }` |
|
|
100
|
+
| `prune_seed` | `seed_id:` | `{ success:, pruned: }` |
|
|
101
|
+
| `cross_pollinate` | `seed_a_id:`, `seed_b_id:` | `{ success:, seed_id:, seed: }` |
|
|
102
|
+
| `adopt_concept` | `concept_type:`, `domain:`, `content:` | `{ success:, concept_id:, concept: }` |
|
|
103
|
+
| `concept_fitness` | `concept_id:` | `{ success:, fitness:, label: }` |
|
|
104
|
+
| `novelty_landscape` | — | `{ success:, landscape: }` |
|
|
105
|
+
| `genesis_rate` | — | `{ success:, rate: }` |
|
|
106
|
+
| `most_adopted` | `limit: 10` | `{ success:, concepts: }` |
|
|
107
|
+
| `orphan_concepts` | `limit: 10` | `{ success:, concepts: }` |
|
|
108
|
+
| `genesis_report` | — | Full report hash |
|
|
109
|
+
|
|
110
|
+
Private: `genesis_engine` — memoized `GenesisEngine`. Logs via `log_debug` helper.
|
|
111
|
+
|
|
112
|
+
## Integration Points
|
|
113
|
+
|
|
114
|
+
- **`lex-cognitive-furnace`**: Smelted alloys (insight, wisdom, synthesis) feed genesis as seeds or direct concept inputs. The furnace produces refined material; genesis turns that material into new concepts.
|
|
115
|
+
- **`lex-cognitive-garden`**: Mature, flowering garden plants are candidates for genesis seed planting or cross-pollination.
|
|
116
|
+
- **`lex-memory`**: Born concepts should be stored as semantic traces in lex-memory. `adopt_concept` is the primary path for ingesting concepts from external sources or other agents.
|
|
117
|
+
- **`lex-dream`**: Dream cycle outputs (agenda items, resolved contradictions) can be adopted as concepts via `adopt_concept`.
|
|
118
|
+
|
|
119
|
+
## Development Notes
|
|
120
|
+
|
|
121
|
+
- `birth` is the gating step: a germinated seed's concept candidate must independently pass both viability (`fitness >= 0.4`) and novelty (`novelty >= 0.5`) checks. Germination alone is not sufficient.
|
|
122
|
+
- `cross_pollinate` does not consume source seeds; both remain in the store after producing a child seed.
|
|
123
|
+
- `orphan_concepts` returns concepts whose originating seed has been pruned.
|
|
124
|
+
- `genesis_rate` uses a rolling window; a cold engine with no births returns 0.0.
|
|
125
|
+
- In-memory only.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
**Maintained By**: Matthew Iverson (@Esity)
|
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/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# lex-cognitive-genesis
|
|
2
|
+
|
|
3
|
+
Cognitive concept emergence engine for brain-modeled agentic AI in the LegionIO ecosystem.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
Models how new cognitive concepts emerge from raw seeds. Seeds are planted with a germination potential; once potential exceeds the threshold (0.7), germination produces a concept candidate. That candidate only achieves full birth if it simultaneously passes viability (fitness >= 0.4) and novelty (>= 0.5) checks. Born concepts can be nurtured to increase fitness, cross-pollinated to produce hybrid seeds, or pruned. External concepts can be adopted directly. The engine tracks novelty distribution across domains and genesis rate over time.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
require 'legion/extensions/cognitive_genesis'
|
|
13
|
+
|
|
14
|
+
client = Legion::Extensions::CognitiveGenesis::Client.new
|
|
15
|
+
|
|
16
|
+
# Plant a seed
|
|
17
|
+
result = client.plant_seed(domain: :engineering, source: :experience, content: 'fault-tolerant retry pattern', potential: 0.8)
|
|
18
|
+
seed_id = result[:seed_id]
|
|
19
|
+
|
|
20
|
+
# Germinate when potential is sufficient
|
|
21
|
+
germination = client.germinate_seed(seed_id: seed_id)
|
|
22
|
+
# => { success: true, concept: { fitness: 0.5, novelty: 0.6, ... } }
|
|
23
|
+
|
|
24
|
+
# Birth the concept if viable and novel
|
|
25
|
+
concept = client.birth_concept(seed_id: seed_id)
|
|
26
|
+
# => { success: true, concept_id: "...", concept: { ... } }
|
|
27
|
+
|
|
28
|
+
# Nurture to increase fitness
|
|
29
|
+
client.nurture_concept(concept_id: concept[:concept_id], amount: 0.15)
|
|
30
|
+
|
|
31
|
+
# Check novelty across domains
|
|
32
|
+
client.novelty_landscape
|
|
33
|
+
# => { success: true, landscape: { engineering: 0.6, ... } }
|
|
34
|
+
|
|
35
|
+
# Full genesis report
|
|
36
|
+
client.genesis_report
|
|
37
|
+
# => { success: true, report: { seed_count: 0, concept_count: 1, genesis_rate: 0.1, ... } }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Development
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bundle install
|
|
44
|
+
bundle exec rspec
|
|
45
|
+
bundle exec rubocop
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## License
|
|
49
|
+
|
|
50
|
+
MIT
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/legion/extensions/cognitive_genesis/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'lex-cognitive-genesis'
|
|
7
|
+
spec.version = Legion::Extensions::CognitiveGenesis::VERSION
|
|
8
|
+
spec.authors = ['Esity']
|
|
9
|
+
spec.email = ['matthewdiverson@gmail.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'LEX Cognitive Genesis'
|
|
12
|
+
spec.description = 'De novo concept creation for brain-modeled agentic AI — the 200th LegionIO cognitive extension. ' \
|
|
13
|
+
'Seeds proto-concepts, germinates them into novel cognitive categories, and tracks their adoption.'
|
|
14
|
+
spec.homepage = 'https://github.com/LegionIO/lex-cognitive-genesis'
|
|
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-genesis'
|
|
20
|
+
spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-cognitive-genesis'
|
|
21
|
+
spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-cognitive-genesis'
|
|
22
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-cognitive-genesis/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,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveGenesis
|
|
6
|
+
class Client
|
|
7
|
+
include Runners::Genesis
|
|
8
|
+
|
|
9
|
+
attr_reader :engine
|
|
10
|
+
|
|
11
|
+
def initialize(engine: nil, **)
|
|
12
|
+
@engine = engine || Helpers::GenesisEngine.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def default_engine
|
|
18
|
+
@engine
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module CognitiveGenesis
|
|
8
|
+
module Helpers
|
|
9
|
+
class Concept
|
|
10
|
+
attr_reader :concept_id, :name, :definition, :parent_seed_id, :domain, :born_at
|
|
11
|
+
attr_accessor :maturity, :connections, :utility_score, :adoption_count
|
|
12
|
+
|
|
13
|
+
def initialize(name:, definition:, parent_seed_id:, domain:,
|
|
14
|
+
maturity: 0.0, connections: [], utility_score: 0.0, adoption_count: 0)
|
|
15
|
+
unless Constants::SEED_DOMAINS.include?(domain.to_sym)
|
|
16
|
+
raise ArgumentError, "invalid domain: #{domain.inspect}; must be one of #{Constants::SEED_DOMAINS.inspect}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
@concept_id = SecureRandom.uuid
|
|
20
|
+
@name = name.to_s.freeze
|
|
21
|
+
@definition = definition.to_s.freeze
|
|
22
|
+
@parent_seed_id = parent_seed_id.to_s.freeze
|
|
23
|
+
@domain = domain.to_sym
|
|
24
|
+
@maturity = maturity.clamp(0.0, 1.0).round(10)
|
|
25
|
+
@connections = Array(connections).dup
|
|
26
|
+
@utility_score = utility_score.clamp(0.0, 1.0).round(10)
|
|
27
|
+
@adoption_count = adoption_count.to_i
|
|
28
|
+
@born_at = Time.now.utc
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def maturity_label
|
|
32
|
+
Constants.label_for(Constants::MATURITY_LABELS, maturity)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def fitness_label
|
|
36
|
+
Constants.label_for(Constants::FITNESS_LABELS, utility_score)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def adopt!
|
|
40
|
+
@adoption_count += 1
|
|
41
|
+
@utility_score = (@utility_score + Constants::ADOPTION_BONUS).clamp(0.0, 1.0).round(10)
|
|
42
|
+
@maturity = (@maturity + Constants::MATURITY_BOOST).clamp(0.0, 1.0).round(10)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def nurture!(boost: Constants::MATURITY_BOOST)
|
|
46
|
+
@maturity = (@maturity + boost).clamp(0.0, 1.0).round(10)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def decay!(rate: Constants::MATURITY_DECAY)
|
|
50
|
+
@maturity = (@maturity - rate).clamp(0.0, 1.0).round(10)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def connect_to(concept_id)
|
|
54
|
+
@connections << concept_id unless @connections.include?(concept_id)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def orphan?
|
|
58
|
+
adoption_count.zero?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def to_h
|
|
62
|
+
{
|
|
63
|
+
concept_id: concept_id,
|
|
64
|
+
name: name,
|
|
65
|
+
definition: definition,
|
|
66
|
+
parent_seed_id: parent_seed_id,
|
|
67
|
+
domain: domain,
|
|
68
|
+
maturity: maturity,
|
|
69
|
+
maturity_label: maturity_label,
|
|
70
|
+
connections: connections,
|
|
71
|
+
utility_score: utility_score,
|
|
72
|
+
fitness_label: fitness_label,
|
|
73
|
+
adoption_count: adoption_count,
|
|
74
|
+
orphan: orphan?,
|
|
75
|
+
born_at: born_at
|
|
76
|
+
}
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveGenesis
|
|
6
|
+
module Helpers
|
|
7
|
+
module Constants
|
|
8
|
+
MAX_SEEDS = 200
|
|
9
|
+
MAX_CONCEPTS = 100
|
|
10
|
+
|
|
11
|
+
DEFAULT_GERMINATION = 0.3
|
|
12
|
+
GERMINATION_BOOST = 0.1
|
|
13
|
+
GERMINATION_THRESHOLD = 0.7
|
|
14
|
+
|
|
15
|
+
DEFAULT_NOVELTY = 0.5
|
|
16
|
+
NOVELTY_THRESHOLD = 0.5
|
|
17
|
+
VIABILITY_THRESHOLD = 0.4
|
|
18
|
+
|
|
19
|
+
MATURATION_RATE = 0.08
|
|
20
|
+
NOVELTY_DECAY = 0.02
|
|
21
|
+
SYNTHESIS_BONUS = 0.15
|
|
22
|
+
MATURITY_BOOST = 0.08
|
|
23
|
+
MATURITY_DECAY = 0.02
|
|
24
|
+
ADOPTION_BONUS = 0.05
|
|
25
|
+
|
|
26
|
+
CONCEPT_TYPES = %i[
|
|
27
|
+
fusion
|
|
28
|
+
abstraction
|
|
29
|
+
analogy
|
|
30
|
+
inversion
|
|
31
|
+
extrapolation
|
|
32
|
+
mutation
|
|
33
|
+
emergence
|
|
34
|
+
transcendence
|
|
35
|
+
].freeze
|
|
36
|
+
|
|
37
|
+
SOURCE_DOMAINS = %i[
|
|
38
|
+
perception
|
|
39
|
+
memory
|
|
40
|
+
language
|
|
41
|
+
reasoning
|
|
42
|
+
emotion
|
|
43
|
+
social
|
|
44
|
+
embodiment
|
|
45
|
+
imagination
|
|
46
|
+
].freeze
|
|
47
|
+
|
|
48
|
+
MATURITY_STAGES = %i[
|
|
49
|
+
germinal
|
|
50
|
+
embryonic
|
|
51
|
+
nascent
|
|
52
|
+
developing
|
|
53
|
+
viable
|
|
54
|
+
mature
|
|
55
|
+
crystallized
|
|
56
|
+
].freeze
|
|
57
|
+
|
|
58
|
+
SEED_DOMAINS = %i[
|
|
59
|
+
linguistic
|
|
60
|
+
spatial
|
|
61
|
+
logical
|
|
62
|
+
interpersonal
|
|
63
|
+
aesthetic
|
|
64
|
+
procedural
|
|
65
|
+
abstract
|
|
66
|
+
emergent
|
|
67
|
+
].freeze
|
|
68
|
+
|
|
69
|
+
GERMINATION_LABELS = {
|
|
70
|
+
(0.0...0.2) => :dormant,
|
|
71
|
+
(0.2...0.4) => :stirring,
|
|
72
|
+
(0.4...0.6) => :awakening,
|
|
73
|
+
(0.6...0.8) => :developing,
|
|
74
|
+
(0.8..1.0) => :ready
|
|
75
|
+
}.freeze
|
|
76
|
+
|
|
77
|
+
NOVELTY_LABELS = {
|
|
78
|
+
(0.0...0.2) => :derivative,
|
|
79
|
+
(0.2...0.4) => :recombinant,
|
|
80
|
+
(0.4..0.6) => :emergent,
|
|
81
|
+
(0.6...0.8) => :novel,
|
|
82
|
+
(0.8..1.0) => :unprecedented
|
|
83
|
+
}.freeze
|
|
84
|
+
|
|
85
|
+
MATURITY_LABELS = {
|
|
86
|
+
(0.0...0.2) => :nascent,
|
|
87
|
+
(0.2...0.4) => :fragile,
|
|
88
|
+
(0.4...0.6) => :establishing,
|
|
89
|
+
(0.6...0.8) => :stable,
|
|
90
|
+
(0.8..1.0) => :foundational
|
|
91
|
+
}.freeze
|
|
92
|
+
|
|
93
|
+
FITNESS_LABELS = {
|
|
94
|
+
(0.0...0.2) => :untested,
|
|
95
|
+
(0.2...0.4) => :experimental,
|
|
96
|
+
(0.4...0.6) => :promising,
|
|
97
|
+
(0.6...0.8) => :proven,
|
|
98
|
+
(0.8..1.0) => :essential
|
|
99
|
+
}.freeze
|
|
100
|
+
|
|
101
|
+
VIABILITY_LABELS = {
|
|
102
|
+
(0.8..1.0) => :strongly_viable,
|
|
103
|
+
(0.6...0.8) => :viable,
|
|
104
|
+
(0.4...0.6) => :marginal,
|
|
105
|
+
(0.2...0.4) => :tenuous,
|
|
106
|
+
(0.0...0.2) => :non_viable
|
|
107
|
+
}.freeze
|
|
108
|
+
|
|
109
|
+
FERTILITY_LABELS = {
|
|
110
|
+
(0.8..1.0) => :prolific,
|
|
111
|
+
(0.6...0.8) => :fertile,
|
|
112
|
+
(0.4...0.6) => :moderate,
|
|
113
|
+
(0.2...0.4) => :sparse,
|
|
114
|
+
(0.0...0.2) => :barren
|
|
115
|
+
}.freeze
|
|
116
|
+
|
|
117
|
+
def self.label_for(labels_hash, value)
|
|
118
|
+
clamped = value.clamp(0.0, 1.0)
|
|
119
|
+
labels_hash.each do |range, label|
|
|
120
|
+
return label if range.cover?(clamped)
|
|
121
|
+
end
|
|
122
|
+
labels_hash.values.last
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveGenesis
|
|
6
|
+
module Helpers
|
|
7
|
+
class GenesisEngine
|
|
8
|
+
include Constants
|
|
9
|
+
|
|
10
|
+
attr_reader :seeds, :concepts, :genesis_events
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@seeds = {}
|
|
14
|
+
@concepts = {}
|
|
15
|
+
@genesis_events = []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def plant(raw_material:, domain:, germination_potential: DEFAULT_GERMINATION,
|
|
19
|
+
novelty_score: 0.0, viability: 0.0, **)
|
|
20
|
+
return { planted: false, reason: :capacity_exceeded } if @seeds.size >= MAX_SEEDS
|
|
21
|
+
|
|
22
|
+
seed = Seed.new(
|
|
23
|
+
raw_material: raw_material,
|
|
24
|
+
domain: domain,
|
|
25
|
+
germination_potential: germination_potential,
|
|
26
|
+
novelty_score: novelty_score,
|
|
27
|
+
viability: viability
|
|
28
|
+
)
|
|
29
|
+
@seeds[seed.seed_id] = seed
|
|
30
|
+
Legion::Logging.debug "[cognitive_genesis] planted seed #{seed.seed_id[0..7]} " \
|
|
31
|
+
"domain=#{domain} novelty=#{novelty_score.round(3)}"
|
|
32
|
+
{ planted: true, seed_id: seed.seed_id, seed: seed.to_h }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def germinate(seed_id:, boost: GERMINATION_BOOST, **)
|
|
36
|
+
seed = @seeds[seed_id]
|
|
37
|
+
return { germinated: false, reason: :not_found } unless seed
|
|
38
|
+
|
|
39
|
+
seed.germination_potential = (seed.germination_potential + boost).clamp(0.0, 1.0).round(10)
|
|
40
|
+
seed.viability = compute_viability(seed)
|
|
41
|
+
|
|
42
|
+
Legion::Logging.debug "[cognitive_genesis] germinated #{seed_id[0..7]} " \
|
|
43
|
+
"potential=#{seed.germination_potential.round(3)}"
|
|
44
|
+
{ germinated: true, seed_id: seed_id,
|
|
45
|
+
germination_potential: seed.germination_potential,
|
|
46
|
+
viability: seed.viability,
|
|
47
|
+
label: seed.germination_label }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def birth(seed_id:, name:, definition:, **)
|
|
51
|
+
seed = @seeds[seed_id]
|
|
52
|
+
return { birthed: false, reason: :not_found } unless seed
|
|
53
|
+
return { birthed: false, reason: :not_viable } unless seed.viable?
|
|
54
|
+
return { birthed: false, reason: :not_novel } unless seed.novel?
|
|
55
|
+
return { birthed: false, reason: :not_ready } unless seed.ready_to_birth?
|
|
56
|
+
return { birthed: false, reason: :concept_capacity_exceeded } if @concepts.size >= MAX_CONCEPTS
|
|
57
|
+
|
|
58
|
+
concept = Concept.new(
|
|
59
|
+
name: name,
|
|
60
|
+
definition: definition,
|
|
61
|
+
parent_seed_id: seed_id,
|
|
62
|
+
domain: seed.domain
|
|
63
|
+
)
|
|
64
|
+
@concepts[concept.concept_id] = concept
|
|
65
|
+
@seeds.delete(seed_id)
|
|
66
|
+
record_genesis_event(concept: concept, seed: seed)
|
|
67
|
+
|
|
68
|
+
Legion::Logging.info "[cognitive_genesis] concept born: \"#{name}\" " \
|
|
69
|
+
"(#{concept.concept_id[0..7]}) domain=#{seed.domain}"
|
|
70
|
+
{ birthed: true, concept_id: concept.concept_id, concept: concept.to_h }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def nurture(concept_id:, boost: MATURITY_BOOST, **)
|
|
74
|
+
concept = @concepts[concept_id]
|
|
75
|
+
return { nurtured: false, reason: :not_found } unless concept
|
|
76
|
+
|
|
77
|
+
concept.nurture!(boost: boost)
|
|
78
|
+
Legion::Logging.debug "[cognitive_genesis] nurtured #{concept_id[0..7]} " \
|
|
79
|
+
"maturity=#{concept.maturity.round(3)}"
|
|
80
|
+
{ nurtured: true, concept_id: concept_id,
|
|
81
|
+
maturity: concept.maturity, label: concept.maturity_label }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def prune(seed_id:, **)
|
|
85
|
+
seed = @seeds.delete(seed_id)
|
|
86
|
+
return { pruned: false, reason: :not_found } unless seed
|
|
87
|
+
|
|
88
|
+
Legion::Logging.debug "[cognitive_genesis] pruned seed #{seed_id[0..7]}"
|
|
89
|
+
{ pruned: true, seed_id: seed_id }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def cross_pollinate(seed_id_a:, seed_id_b:, **)
|
|
93
|
+
guard = cross_pollinate_guard(seed_id_a, seed_id_b)
|
|
94
|
+
return guard if guard
|
|
95
|
+
|
|
96
|
+
seed_a = @seeds[seed_id_a]
|
|
97
|
+
seed_b = @seeds[seed_id_b]
|
|
98
|
+
child_novelty = cross_novelty(seed_a.novelty_score, seed_b.novelty_score)
|
|
99
|
+
result = plant_cross_child(seed_a, seed_b, child_novelty)
|
|
100
|
+
|
|
101
|
+
Legion::Logging.debug '[cognitive_genesis] cross_pollinated ' \
|
|
102
|
+
"#{seed_id_a[0..7]}+#{seed_id_b[0..7]} -> #{result[:seed_id]&.slice(0, 8)}"
|
|
103
|
+
result.merge(cross_pollinated: true, parent_seed_ids: [seed_id_a, seed_id_b])
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def adopt_concept(concept_id:, **)
|
|
107
|
+
concept = @concepts[concept_id]
|
|
108
|
+
return { adopted: false, reason: :not_found } unless concept
|
|
109
|
+
|
|
110
|
+
concept.adopt!
|
|
111
|
+
Legion::Logging.debug "[cognitive_genesis] adopted #{concept_id[0..7]} " \
|
|
112
|
+
"count=#{concept.adoption_count}"
|
|
113
|
+
{ adopted: true, concept_id: concept_id,
|
|
114
|
+
adoption_count: concept.adoption_count,
|
|
115
|
+
utility_score: concept.utility_score,
|
|
116
|
+
maturity: concept.maturity }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def concept_fitness(concept_id:, **)
|
|
120
|
+
concept = @concepts[concept_id]
|
|
121
|
+
return { found: false } unless concept
|
|
122
|
+
|
|
123
|
+
{ found: true,
|
|
124
|
+
concept_id: concept_id,
|
|
125
|
+
utility_score: concept.utility_score,
|
|
126
|
+
fitness_label: concept.fitness_label,
|
|
127
|
+
adoption_count: concept.adoption_count,
|
|
128
|
+
maturity: concept.maturity }
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def novelty_landscape(**)
|
|
132
|
+
seeds_map = @seeds.values.map do |s|
|
|
133
|
+
{ id: s.seed_id, type: :seed, score: s.novelty_score,
|
|
134
|
+
label: s.novelty_label, domain: s.domain }
|
|
135
|
+
end
|
|
136
|
+
concepts_map = @concepts.values.map do |c|
|
|
137
|
+
{ id: c.concept_id, type: :concept, score: 0.0, label: :n_a, domain: c.domain }
|
|
138
|
+
end
|
|
139
|
+
{
|
|
140
|
+
seeds: seeds_map,
|
|
141
|
+
concepts: concepts_map,
|
|
142
|
+
avg_seed_novelty: avg_values(@seeds.values.map(&:novelty_score)),
|
|
143
|
+
high_novelty_seeds: @seeds.values.count(&:novel?)
|
|
144
|
+
}
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def genesis_rate(**)
|
|
148
|
+
return { rate: 0.0, total_events: 0 } if @genesis_events.empty?
|
|
149
|
+
|
|
150
|
+
oldest = @genesis_events.min_by { |e| e[:born_at] }[:born_at]
|
|
151
|
+
elapsed_hours = [(Time.now.utc - oldest) / 3600.0, 1.0].max
|
|
152
|
+
rate = @genesis_events.size / elapsed_hours
|
|
153
|
+
{ rate: rate.round(10),
|
|
154
|
+
total_events: @genesis_events.size,
|
|
155
|
+
elapsed_hours: elapsed_hours.round(4) }
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def most_adopted(**)
|
|
159
|
+
return nil if @concepts.empty?
|
|
160
|
+
|
|
161
|
+
@concepts.values.max_by(&:adoption_count)&.to_h
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def orphan_concepts(**)
|
|
165
|
+
@concepts.values.select(&:orphan?).map(&:to_h)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def genesis_report(**)
|
|
169
|
+
{
|
|
170
|
+
seeds: @seeds.size,
|
|
171
|
+
concepts: @concepts.size,
|
|
172
|
+
genesis_events: @genesis_events.size,
|
|
173
|
+
genesis_rate: genesis_rate,
|
|
174
|
+
orphan_count: orphan_concepts.size,
|
|
175
|
+
most_adopted: most_adopted,
|
|
176
|
+
avg_seed_novelty: avg_values(@seeds.values.map(&:novelty_score)),
|
|
177
|
+
avg_concept_maturity: avg_values(@concepts.values.map(&:maturity)),
|
|
178
|
+
domains_active: active_domains
|
|
179
|
+
}
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
private
|
|
183
|
+
|
|
184
|
+
def cross_pollinate_guard(seed_id_a, seed_id_b)
|
|
185
|
+
return { cross_pollinated: false, reason: :seed_a_not_found } unless @seeds[seed_id_a]
|
|
186
|
+
return { cross_pollinated: false, reason: :seed_b_not_found } unless @seeds[seed_id_b]
|
|
187
|
+
return { cross_pollinated: false, reason: :capacity_exceeded } if @seeds.size >= MAX_SEEDS
|
|
188
|
+
|
|
189
|
+
nil
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def plant_cross_child(seed_a, seed_b, child_novelty)
|
|
193
|
+
combined_viability = ((seed_a.viability + seed_b.viability) / 2.0).round(10)
|
|
194
|
+
plant(
|
|
195
|
+
raw_material: (seed_a.raw_material + seed_b.raw_material).uniq,
|
|
196
|
+
domain: pick_domain(seed_a.domain, seed_b.domain, child_novelty),
|
|
197
|
+
germination_potential: DEFAULT_GERMINATION + GERMINATION_BOOST,
|
|
198
|
+
novelty_score: child_novelty,
|
|
199
|
+
viability: combined_viability
|
|
200
|
+
)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def compute_viability(seed)
|
|
204
|
+
material_factor = [seed.raw_material.size / 5.0, 1.0].min
|
|
205
|
+
novelty_factor = seed.novelty_score
|
|
206
|
+
potential_factor = seed.germination_potential
|
|
207
|
+
((material_factor * 0.3) + (novelty_factor * 0.4) + (potential_factor * 0.3)).clamp(0.0, 1.0).round(10)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def cross_novelty(score_a, score_b)
|
|
211
|
+
base = [score_a, score_b].max
|
|
212
|
+
synergy = (score_a - score_b).abs * 0.5
|
|
213
|
+
(base + synergy + GERMINATION_BOOST).clamp(0.0, 1.0).round(10)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def pick_domain(domain_a, domain_b, novelty)
|
|
217
|
+
return :emergent if novelty >= 0.8
|
|
218
|
+
return domain_a if domain_a == domain_b
|
|
219
|
+
|
|
220
|
+
novelty >= 0.6 ? :abstract : domain_a
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def avg_values(values)
|
|
224
|
+
return 0.0 if values.empty?
|
|
225
|
+
|
|
226
|
+
(values.sum / values.size.to_f).round(10)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def active_domains
|
|
230
|
+
all_domains = @seeds.values.map(&:domain) + @concepts.values.map(&:domain)
|
|
231
|
+
all_domains.tally
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def record_genesis_event(concept:, seed:)
|
|
235
|
+
@genesis_events << {
|
|
236
|
+
concept_id: concept.concept_id,
|
|
237
|
+
name: concept.name,
|
|
238
|
+
domain: concept.domain,
|
|
239
|
+
seed_id: seed.seed_id,
|
|
240
|
+
born_at: concept.born_at
|
|
241
|
+
}
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module CognitiveGenesis
|
|
8
|
+
module Helpers
|
|
9
|
+
class Seed
|
|
10
|
+
attr_reader :seed_id, :raw_material, :domain, :created_at
|
|
11
|
+
attr_accessor :germination_potential, :novelty_score, :viability
|
|
12
|
+
|
|
13
|
+
def initialize(raw_material:, domain:, germination_potential: Constants::DEFAULT_GERMINATION,
|
|
14
|
+
novelty_score: 0.0, viability: 0.0)
|
|
15
|
+
unless Constants::SEED_DOMAINS.include?(domain.to_sym)
|
|
16
|
+
raise ArgumentError, "invalid domain: #{domain.inspect}; must be one of #{Constants::SEED_DOMAINS.inspect}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
@seed_id = SecureRandom.uuid
|
|
20
|
+
@raw_material = Array(raw_material).freeze
|
|
21
|
+
@domain = domain.to_sym
|
|
22
|
+
@germination_potential = germination_potential.clamp(0.0, 1.0).round(10)
|
|
23
|
+
@novelty_score = novelty_score.clamp(0.0, 1.0).round(10)
|
|
24
|
+
@viability = viability.clamp(0.0, 1.0).round(10)
|
|
25
|
+
@created_at = Time.now.utc
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def germination_label
|
|
29
|
+
Constants.label_for(Constants::GERMINATION_LABELS, germination_potential)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def novelty_label
|
|
33
|
+
Constants.label_for(Constants::NOVELTY_LABELS, novelty_score)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def viable?
|
|
37
|
+
viability >= Constants::VIABILITY_THRESHOLD
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def novel?
|
|
41
|
+
novelty_score >= Constants::NOVELTY_THRESHOLD
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def ready_to_birth?
|
|
45
|
+
germination_potential >= Constants::GERMINATION_THRESHOLD && viable? && novel?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def to_h
|
|
49
|
+
{
|
|
50
|
+
seed_id: seed_id,
|
|
51
|
+
raw_material: raw_material,
|
|
52
|
+
domain: domain,
|
|
53
|
+
germination_potential: germination_potential,
|
|
54
|
+
novelty_score: novelty_score,
|
|
55
|
+
viability: viability,
|
|
56
|
+
germination_label: germination_label,
|
|
57
|
+
novelty_label: novelty_label,
|
|
58
|
+
ready_to_birth: ready_to_birth?,
|
|
59
|
+
created_at: created_at
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveGenesis
|
|
6
|
+
module Runners
|
|
7
|
+
module Genesis
|
|
8
|
+
def plant_seed(raw_material:, domain:, engine: nil,
|
|
9
|
+
germination_potential: Helpers::Constants::DEFAULT_GERMINATION,
|
|
10
|
+
novelty_score: 0.0, viability: 0.0, **)
|
|
11
|
+
e = engine || default_engine
|
|
12
|
+
result = e.plant(raw_material: raw_material, domain: domain,
|
|
13
|
+
germination_potential: germination_potential,
|
|
14
|
+
novelty_score: novelty_score, viability: viability)
|
|
15
|
+
{ success: result[:planted], **result }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def germinate_seed(seed_id:, engine: nil, boost: Helpers::Constants::GERMINATION_BOOST, **)
|
|
19
|
+
e = engine || default_engine
|
|
20
|
+
result = e.germinate(seed_id: seed_id, boost: boost)
|
|
21
|
+
{ success: result[:germinated], **result }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def birth_concept(seed_id:, name:, definition:, engine: nil, **)
|
|
25
|
+
e = engine || default_engine
|
|
26
|
+
result = e.birth(seed_id: seed_id, name: name, definition: definition)
|
|
27
|
+
{ success: result[:birthed], **result }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def nurture_concept(concept_id:, engine: nil, boost: Helpers::Constants::MATURITY_BOOST, **)
|
|
31
|
+
e = engine || default_engine
|
|
32
|
+
result = e.nurture(concept_id: concept_id, boost: boost)
|
|
33
|
+
{ success: result[:nurtured], **result }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def prune_seed(seed_id:, engine: nil, **)
|
|
37
|
+
e = engine || default_engine
|
|
38
|
+
result = e.prune(seed_id: seed_id)
|
|
39
|
+
{ success: result[:pruned], **result }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def cross_pollinate(seed_id_a:, seed_id_b:, engine: nil, **)
|
|
43
|
+
e = engine || default_engine
|
|
44
|
+
result = e.cross_pollinate(seed_id_a: seed_id_a, seed_id_b: seed_id_b)
|
|
45
|
+
{ success: result[:cross_pollinated], **result }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def adopt_concept(concept_id:, engine: nil, **)
|
|
49
|
+
e = engine || default_engine
|
|
50
|
+
result = e.adopt_concept(concept_id: concept_id)
|
|
51
|
+
{ success: result[:adopted], **result }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def concept_fitness(concept_id:, engine: nil, **)
|
|
55
|
+
e = engine || default_engine
|
|
56
|
+
result = e.concept_fitness(concept_id: concept_id)
|
|
57
|
+
{ success: result[:found], **result }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def novelty_landscape(engine: nil, **)
|
|
61
|
+
e = engine || default_engine
|
|
62
|
+
landscape = e.novelty_landscape
|
|
63
|
+
{ success: true, **landscape }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def genesis_rate(engine: nil, **)
|
|
67
|
+
e = engine || default_engine
|
|
68
|
+
result = e.genesis_rate
|
|
69
|
+
{ success: true, **result }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def most_adopted(engine: nil, **)
|
|
73
|
+
e = engine || default_engine
|
|
74
|
+
concept = e.most_adopted
|
|
75
|
+
{ success: true, concept: concept }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def orphan_concepts(engine: nil, **)
|
|
79
|
+
e = engine || default_engine
|
|
80
|
+
orphans = e.orphan_concepts
|
|
81
|
+
{ success: true, orphans: orphans, count: orphans.size }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def genesis_report(engine: nil, **)
|
|
85
|
+
e = engine || default_engine
|
|
86
|
+
report = e.genesis_report
|
|
87
|
+
{ success: true, **report }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
def default_engine
|
|
95
|
+
@default_engine ||= Helpers::GenesisEngine.new
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/cognitive_genesis/version'
|
|
4
|
+
require 'legion/extensions/cognitive_genesis/helpers/constants'
|
|
5
|
+
require 'legion/extensions/cognitive_genesis/helpers/seed'
|
|
6
|
+
require 'legion/extensions/cognitive_genesis/helpers/concept'
|
|
7
|
+
require 'legion/extensions/cognitive_genesis/helpers/genesis_engine'
|
|
8
|
+
require 'legion/extensions/cognitive_genesis/runners/genesis'
|
|
9
|
+
require 'legion/extensions/cognitive_genesis/client'
|
|
10
|
+
|
|
11
|
+
module Legion
|
|
12
|
+
module Extensions
|
|
13
|
+
module CognitiveGenesis
|
|
14
|
+
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lex-cognitive-genesis
|
|
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: De novo concept creation for brain-modeled agentic AI — the 200th LegionIO
|
|
27
|
+
cognitive extension. Seeds proto-concepts, germinates them into novel cognitive
|
|
28
|
+
categories, and tracks their adoption.
|
|
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
|
+
- README.md
|
|
42
|
+
- lex-cognitive-genesis.gemspec
|
|
43
|
+
- lib/legion/extensions/cognitive_genesis.rb
|
|
44
|
+
- lib/legion/extensions/cognitive_genesis/client.rb
|
|
45
|
+
- lib/legion/extensions/cognitive_genesis/helpers/concept.rb
|
|
46
|
+
- lib/legion/extensions/cognitive_genesis/helpers/constants.rb
|
|
47
|
+
- lib/legion/extensions/cognitive_genesis/helpers/genesis_engine.rb
|
|
48
|
+
- lib/legion/extensions/cognitive_genesis/helpers/seed.rb
|
|
49
|
+
- lib/legion/extensions/cognitive_genesis/runners/genesis.rb
|
|
50
|
+
- lib/legion/extensions/cognitive_genesis/version.rb
|
|
51
|
+
homepage: https://github.com/LegionIO/lex-cognitive-genesis
|
|
52
|
+
licenses:
|
|
53
|
+
- MIT
|
|
54
|
+
metadata:
|
|
55
|
+
homepage_uri: https://github.com/LegionIO/lex-cognitive-genesis
|
|
56
|
+
source_code_uri: https://github.com/LegionIO/lex-cognitive-genesis
|
|
57
|
+
documentation_uri: https://github.com/LegionIO/lex-cognitive-genesis
|
|
58
|
+
changelog_uri: https://github.com/LegionIO/lex-cognitive-genesis
|
|
59
|
+
bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-genesis/issues
|
|
60
|
+
rubygems_mfa_required: 'true'
|
|
61
|
+
rdoc_options: []
|
|
62
|
+
require_paths:
|
|
63
|
+
- lib
|
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.4'
|
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
requirements: []
|
|
75
|
+
rubygems_version: 3.6.9
|
|
76
|
+
specification_version: 4
|
|
77
|
+
summary: LEX Cognitive Genesis
|
|
78
|
+
test_files: []
|