lex-cognitive-chrysalis 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.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +16 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +4 -0
  5. data/.rubocop.yml +32 -0
  6. data/CLAUDE.md +81 -0
  7. data/Gemfile +10 -0
  8. data/Gemfile.lock +78 -0
  9. data/README.md +42 -0
  10. data/lex-cognitive-chrysalis.gemspec +28 -0
  11. data/lib/legion/extensions/cognitive_chrysalis/client.rb +18 -0
  12. data/lib/legion/extensions/cognitive_chrysalis/helpers/chrysalis.rb +133 -0
  13. data/lib/legion/extensions/cognitive_chrysalis/helpers/cocoon.rb +85 -0
  14. data/lib/legion/extensions/cognitive_chrysalis/helpers/constants.rb +45 -0
  15. data/lib/legion/extensions/cognitive_chrysalis/helpers/metamorphosis_engine.rb +153 -0
  16. data/lib/legion/extensions/cognitive_chrysalis/runners/cognitive_chrysalis.rb +125 -0
  17. data/lib/legion/extensions/cognitive_chrysalis/version.rb +9 -0
  18. data/lib/legion/extensions/cognitive_chrysalis.rb +18 -0
  19. data/spec/legion/extensions/cognitive_chrysalis/client_spec.rb +83 -0
  20. data/spec/legion/extensions/cognitive_chrysalis/helpers/chrysalis_engine_spec.rb +57 -0
  21. data/spec/legion/extensions/cognitive_chrysalis/helpers/chrysalis_spec.rb +305 -0
  22. data/spec/legion/extensions/cognitive_chrysalis/helpers/cocoon_spec.rb +206 -0
  23. data/spec/legion/extensions/cognitive_chrysalis/helpers/constants_spec.rb +109 -0
  24. data/spec/legion/extensions/cognitive_chrysalis/helpers/metamorphic_cycle_spec.rb +76 -0
  25. data/spec/legion/extensions/cognitive_chrysalis/helpers/metamorphosis_engine_spec.rb +247 -0
  26. data/spec/legion/extensions/cognitive_chrysalis/helpers/transformation_phase_spec.rb +98 -0
  27. data/spec/legion/extensions/cognitive_chrysalis/runners/cognitive_chrysalis_spec.rb +180 -0
  28. data/spec/legion/extensions/cognitive_chrysalis/runners/reporting_spec.rb +81 -0
  29. data/spec/legion/extensions/cognitive_chrysalis/runners/transformation_spec.rb +74 -0
  30. data/spec/legion/extensions/cognitive_chrysalis_spec.rb +15 -0
  31. data/spec/spec_helper.rb +20 -0
  32. metadata +91 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c7aed07ab9c483e7513ebc0122e1c571c1d0edc409a568cd929bc3e5d75d6b79
4
+ data.tar.gz: c74edc3c6961ae25718351bebacdd8ed30a5a8964eff553428108292cbc3a0d4
5
+ SHA512:
6
+ metadata.gz: bc485de3f19aef24d91a1ab266e22cc07b22744f58f47f83f6c6ecae8dba9cc05a8fb2068fa04c9f86982c5fb7d32897e77fb365b9c3e30a09b31777d3758c44
7
+ data.tar.gz: ec30ffc37864ca2282108040efbe4eb91113e6455b95584480219f60810894da6f7cc7e064e762693038c8322e7946dfb45c62710cc17065d2da4b8371168167
@@ -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,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --require spec_helper
2
+ --format documentation
3
+ --color
4
+ --order random
data/.rubocop.yml ADDED
@@ -0,0 +1,32 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ TargetRubyVersion: 3.4
4
+ SuggestExtensions: false
5
+ Layout/LineLength:
6
+ Max: 160
7
+ Style/Documentation:
8
+ Enabled: false
9
+ Naming/PredicateMethod:
10
+ Enabled: false
11
+ Naming/PredicatePrefix:
12
+ Enabled: false
13
+ Metrics/ClassLength:
14
+ Max: 150
15
+ Metrics/MethodLength:
16
+ Max: 25
17
+ Metrics/AbcSize:
18
+ Max: 25
19
+ Metrics/ParameterLists:
20
+ Max: 8
21
+ MaxOptionalParameters: 8
22
+ Layout/HashAlignment:
23
+ EnforcedColonStyle: table
24
+ EnforcedHashRocketStyle: table
25
+ Metrics/BlockLength:
26
+ Exclude:
27
+ - 'spec/**/*'
28
+ Style/FrozenStringLiteralComment:
29
+ Enabled: true
30
+ Style/OneClassPerFile:
31
+ Exclude:
32
+ - 'spec/spec_helper.rb'
data/CLAUDE.md ADDED
@@ -0,0 +1,81 @@
1
+ # lex-cognitive-chrysalis
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
+ Metamorphic identity transformation for LegionIO agents. Models structured dissolution and reformation cycles: ideas or identity facets enter a chrysalis, transform through protected incubation, and emerge as something qualitatively different. Premature emergence (forced before transformation is complete) reduces beauty and can produce damaged outputs.
10
+
11
+ ## Gem Info
12
+
13
+ - **Gem name**: `lex-cognitive-chrysalis`
14
+ - **Version**: `0.1.0`
15
+ - **Module**: `Legion::Extensions::CognitiveChrysalis`
16
+ - **Ruby**: `>= 3.4`
17
+ - **License**: MIT
18
+
19
+ ## File Structure
20
+
21
+ ```
22
+ lib/legion/extensions/cognitive_chrysalis/
23
+ cognitive_chrysalis.rb
24
+ version.rb
25
+ client.rb
26
+ helpers/
27
+ constants.rb
28
+ chrysalis.rb
29
+ cocoon.rb
30
+ metamorphosis_engine.rb
31
+ runners/
32
+ cognitive_chrysalis.rb
33
+ ```
34
+
35
+ ## Key Constants
36
+
37
+ From `helpers/constants.rb`:
38
+
39
+ - `LIFE_STAGES` — `%i[larva spinning cocooned transforming emerging butterfly]`
40
+ - `CHRYSALIS_TYPES` — `%i[silk paper bark leaf underground]`
41
+ - `MAX_CHRYSALISES` = `200`, `MAX_BUTTERFLIES` = `500`
42
+ - `TRANSFORMATION_RATE` = `0.08`, `PROTECTION_DECAY` = `0.03`
43
+ - `EMERGENCE_THRESHOLD` = `0.9` (transformation_progress must reach this for natural emergence)
44
+ - `PREMATURE_PENALTY` = `0.4` (beauty penalty for forced emergence before threshold)
45
+ - `STAGE_LABELS` — progress-to-stage mapping: `0.0-0.20` = `:larva`, `0.20-0.40` = `:spinning`, up to `0.90-1.0` = `:butterfly`
46
+ - `BEAUTY_LABELS` — `0.85+` = `:magnificent`, `0.65` = `:beautiful`, `0.40` = `:striking`, `0.20` = `:plain`, below = `:dull`
47
+
48
+ ## Runners
49
+
50
+ All methods in `Runners::CognitiveChrysalis` (`extend self`):
51
+
52
+ - `create_chrysalis(chrysalis_type: :silk, content: '')` — creates a new chrysalis in `:larva` stage
53
+ - `create_cocoon(environment: 'default', temperature: 0.5, humidity: 0.5)` — creates a protective cocoon environment
54
+ - `spin(chrysalis_id:)` — advances chrysalis from `:larva` to `:spinning`; must be in `:larva` state
55
+ - `enclose(chrysalis_id:, cocoon_id:)` — places a chrysalis inside a cocoon
56
+ - `incubate(chrysalis_id:)` — advances transformation progress by `TRANSFORMATION_RATE`
57
+ - `incubate_all` — incubates all eligible (non-butterfly) chrysalises
58
+ - `emerge(chrysalis_id:, force: false)` — natural emergence requires `transformation_progress >= 0.9`; forced emergence applies `PREMATURE_PENALTY` to beauty
59
+ - `disturb(cocoon_id:, force: 0.1)` — degrades cocoon protection; if protection drops to 0 during active transformation, triggers forced emergence
60
+ - `list_chrysalises` — all chrysalises with current state
61
+ - `metamorphosis_status` — aggregate report
62
+
63
+ ## Helpers
64
+
65
+ - `MetamorphosisEngine` — manages chrysalises and cocoons.
66
+ - `Chrysalis` — state machine through `LIFE_STAGES`. `transform!(rate)` advances progress and beauty. `emerge!(force:)` checks threshold; forced emergence sets `@premature = true` and applies beauty penalty. `disturb!(force)` degrades protection.
67
+ - `Cocoon` — protective environment with temperature, humidity, protection score.
68
+
69
+ ## Integration Points
70
+
71
+ - `lex-cognitive-cocoon` is a related but distinct extension — cocoon models the protective encapsulation of fragile ideas; chrysalis models the full metamorphic transformation lifecycle (larva through butterfly). They can compose: a cocoon provides the environment, a chrysalis undergoes the transformation inside it.
72
+ - `lex-memory` can hold chrysalis IDs as pending transformation traces — ideas that are not ready for activation but are undergoing gradual consolidation.
73
+ - `lex-coldstart` imprint window is conceptually similar to the chrysalis state: ideas absorbed during cold start are in a protected transformation phase.
74
+
75
+ ## Development Notes
76
+
77
+ - Stage progression is strictly one-directional: larva -> spinning -> cocooned -> transforming -> emerging -> butterfly. No regression.
78
+ - `spin!` on a non-larva chrysalis raises `ArgumentError`. The runner returns `{ success: false, reason: e.message }`.
79
+ - `transform!` auto-advances stage by comparing current stage rank vs progress-derived stage rank, taking the maximum. This means a chrysalis never regresses stages even if progress somehow decreases.
80
+ - `premature?` convenience predicate: `butterfly? && beauty < 0.5`.
81
+ - `beauty` is computed as `transformation_progress * 0.9` during incubation; full beauty (1.0) only on natural emergence.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+ gem 'rspec', '~> 3.13'
7
+ gem 'rubocop', '~> 1.75'
8
+ gem 'rubocop-rspec'
9
+
10
+ gem 'legion-gaia', path: '../../legion-gaia'
data/Gemfile.lock ADDED
@@ -0,0 +1,78 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lex-cognitive-chrysalis (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-chrysalis!
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,42 @@
1
+ # lex-cognitive-chrysalis
2
+
3
+ Metamorphic identity transformation for LegionIO agents. Models structured dissolution and reformation cycles for the cognitive architecture.
4
+
5
+ ## What It Does
6
+
7
+ Some ideas and identity facets require deep transformation before they are useful — not incremental improvement, but dissolution and reformation into something qualitatively different. This extension models that metamorphic process: a larva enters a protective chrysalis, incubates through multiple transformation stages, and emerges as a butterfly. Emergence quality (beauty) depends on whether the transformation ran to completion or was forced prematurely.
8
+
9
+ Five chrysalis types provide different protection levels: silk (0.6), leaf (protected), bark (0.7), paper, and underground (highest). External disturbances can degrade cocoon protection and trigger premature emergence with a beauty penalty.
10
+
11
+ ## Usage
12
+
13
+ ```ruby
14
+ client = Legion::Extensions::CognitiveChrysalis::Client.new
15
+
16
+ cocoon = client.create_cocoon(environment: 'quiet_space', temperature: 0.6, humidity: 0.5)
17
+
18
+ chrysalis = client.create_chrysalis(
19
+ chrysalis_type: :silk,
20
+ content: 'core identity belief under revision'
21
+ )
22
+
23
+ client.spin(chrysalis_id: chrysalis[:chrysalis][:id])
24
+ client.enclose(chrysalis_id: chrysalis[:chrysalis][:id],
25
+ cocoon_id: cocoon[:cocoon][:id])
26
+
27
+ 10.times { client.incubate(chrysalis_id: chrysalis[:chrysalis][:id]) }
28
+
29
+ client.emerge(chrysalis_id: chrysalis[:chrysalis][:id])
30
+ ```
31
+
32
+ ## Development
33
+
34
+ ```bash
35
+ bundle install
36
+ bundle exec rspec
37
+ bundle exec rubocop
38
+ ```
39
+
40
+ ## License
41
+
42
+ MIT
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/cognitive_chrysalis/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-cognitive-chrysalis'
7
+ spec.version = Legion::Extensions::CognitiveChrysalis::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+
11
+ spec.summary = 'LEX Cognitive Chrysalis'
12
+ spec.description = 'Metamorphic identity transformation for LegionIO agents — structured dissolution and reformation cycles'
13
+ spec.homepage = 'https://github.com/LegionIO/lex-cognitive-chrysalis'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.4'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-cognitive-chrysalis'
19
+ spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-cognitive-chrysalis'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-cognitive-chrysalis'
21
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-cognitive-chrysalis/issues'
22
+ spec.metadata['rubygems_mfa_required'] = 'true'
23
+
24
+ spec.files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") }
25
+
26
+ spec.require_paths = ['lib']
27
+ spec.add_development_dependency 'legion-gaia'
28
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveChrysalis
6
+ class Client
7
+ include Runners::CognitiveChrysalis
8
+
9
+ attr_reader :engine
10
+
11
+ def initialize(**)
12
+ @engine = Helpers::MetamorphosisEngine.new
13
+ @default_engine = @engine
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module CognitiveChrysalis
8
+ module Helpers
9
+ class Chrysalis
10
+ attr_reader :id, :chrysalis_type, :content, :stage,
11
+ :transformation_progress, :protection, :beauty, :created_at
12
+
13
+ def initialize(chrysalis_type:, content:, **)
14
+ @id = SecureRandom.uuid
15
+ @chrysalis_type = chrysalis_type.to_sym
16
+ @content = content.to_s
17
+ @stage = :larva
18
+ @transformation_progress = 0.0
19
+ @protection = 0.8
20
+ @beauty = 0.0
21
+ @created_at = Time.now.utc
22
+ @premature = false
23
+ end
24
+
25
+ def spin!
26
+ raise ArgumentError, "must be :larva to spin, currently #{@stage}" unless @stage == :larva
27
+
28
+ @stage = :spinning
29
+ true
30
+ end
31
+
32
+ def cocoon!
33
+ raise ArgumentError, "must be :spinning to cocoon, currently #{@stage}" unless @stage == :spinning
34
+
35
+ @stage = :cocooned
36
+ true
37
+ end
38
+
39
+ def transform!(rate = Helpers::Constants::TRANSFORMATION_RATE)
40
+ return false if @stage == :butterfly
41
+
42
+ @transformation_progress = (@transformation_progress + rate).clamp(0.0, 1.0).round(10)
43
+ @beauty = (@transformation_progress * 0.9).clamp(0.0, 1.0).round(10)
44
+ update_stage_from_progress!
45
+ true
46
+ end
47
+
48
+ def emerge!(force: false)
49
+ if @transformation_progress >= Helpers::Constants::EMERGENCE_THRESHOLD
50
+ @stage = :butterfly
51
+ @beauty = 1.0
52
+ elsif force
53
+ @premature = true
54
+ @stage = :butterfly
55
+ @beauty = (@beauty - Helpers::Constants::PREMATURE_PENALTY).clamp(0.0, 1.0).round(10)
56
+ else
57
+ return false
58
+ end
59
+ true
60
+ end
61
+
62
+ def decay_protection!
63
+ @protection = (@protection - Helpers::Constants::PROTECTION_DECAY).clamp(0.0, 1.0).round(10)
64
+ end
65
+
66
+ def disturb!(force)
67
+ @protection = (@protection - force.to_f).clamp(0.0, 1.0).round(10)
68
+ emerge!(force: true) if @protection <= 0 && %i[cocooned transforming].include?(@stage)
69
+ end
70
+
71
+ def butterfly?
72
+ @stage == :butterfly
73
+ end
74
+
75
+ def cocooned?
76
+ @stage == :cocooned
77
+ end
78
+
79
+ def transforming?
80
+ @stage == :transforming
81
+ end
82
+
83
+ def premature?
84
+ butterfly? && @beauty < 0.5
85
+ end
86
+
87
+ def stage_label
88
+ Helpers::Constants.label_for(Helpers::Constants::STAGE_LABELS, @transformation_progress)
89
+ end
90
+
91
+ def beauty_label
92
+ Helpers::Constants.label_for(Helpers::Constants::BEAUTY_LABELS, @beauty)
93
+ end
94
+
95
+ def to_h
96
+ {
97
+ id: @id,
98
+ chrysalis_type: @chrysalis_type,
99
+ content: @content,
100
+ stage: @stage,
101
+ transformation_progress: @transformation_progress,
102
+ protection: @protection,
103
+ beauty: @beauty,
104
+ stage_label: stage_label,
105
+ beauty_label: beauty_label,
106
+ premature: @premature,
107
+ created_at: @created_at
108
+ }
109
+ end
110
+
111
+ private
112
+
113
+ def update_stage_from_progress!
114
+ progress_stage = if @transformation_progress >= 0.8
115
+ :emerging
116
+ elsif @transformation_progress >= 0.6
117
+ :transforming
118
+ elsif @transformation_progress >= 0.4
119
+ :cocooned
120
+ elsif @transformation_progress >= 0.2
121
+ :spinning
122
+ else
123
+ :larva
124
+ end
125
+ current_rank = Helpers::Constants::LIFE_STAGES.index(@stage) || 0
126
+ progress_rank = Helpers::Constants::LIFE_STAGES.index(progress_stage) || 0
127
+ @stage = Helpers::Constants::LIFE_STAGES[[current_rank, progress_rank].max]
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module CognitiveChrysalis
8
+ module Helpers
9
+ class Cocoon
10
+ attr_reader :id, :environment, :temperature, :humidity, :chrysalis_ids, :created_at
11
+
12
+ TEMP_ADJUST = 0.05
13
+ HUMID_ADJUST = 0.05
14
+
15
+ def initialize(environment:, temperature: 0.5, humidity: 0.5, **)
16
+ @id = SecureRandom.uuid
17
+ @environment = environment.to_s
18
+ @temperature = temperature.to_f.clamp(0.0, 1.0)
19
+ @humidity = humidity.to_f.clamp(0.0, 1.0)
20
+ @chrysalis_ids = []
21
+ @created_at = Time.now.utc
22
+ end
23
+
24
+ def shelter(chrysalis_id)
25
+ @chrysalis_ids << chrysalis_id unless @chrysalis_ids.include?(chrysalis_id)
26
+ true
27
+ end
28
+
29
+ def expose(chrysalis_id)
30
+ @chrysalis_ids.delete(chrysalis_id)
31
+ true
32
+ end
33
+
34
+ def warm!
35
+ @temperature = (@temperature + TEMP_ADJUST).clamp(0.0, 1.0).round(10)
36
+ end
37
+
38
+ def cool!
39
+ @temperature = (@temperature - TEMP_ADJUST).clamp(0.0, 1.0).round(10)
40
+ end
41
+
42
+ def moisten!
43
+ @humidity = (@humidity + HUMID_ADJUST).clamp(0.0, 1.0).round(10)
44
+ end
45
+
46
+ def dry!
47
+ @humidity = (@humidity - HUMID_ADJUST).clamp(0.0, 1.0).round(10)
48
+ end
49
+
50
+ def ideal?
51
+ @temperature.between?(0.4, 0.7) && @humidity.between?(0.4, 0.7)
52
+ end
53
+
54
+ def hostile?
55
+ @temperature > 0.9 || @humidity < 0.1
56
+ end
57
+
58
+ def growth_modifier
59
+ if ideal?
60
+ 0.1
61
+ elsif hostile?
62
+ -0.05
63
+ else
64
+ 0.0
65
+ end
66
+ end
67
+
68
+ def to_h
69
+ {
70
+ id: @id,
71
+ environment: @environment,
72
+ temperature: @temperature,
73
+ humidity: @humidity,
74
+ chrysalis_ids: @chrysalis_ids.dup,
75
+ ideal: ideal?,
76
+ hostile: hostile?,
77
+ growth_modifier: growth_modifier,
78
+ created_at: @created_at
79
+ }
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveChrysalis
6
+ module Helpers
7
+ module Constants
8
+ LIFE_STAGES = %i[larva spinning cocooned transforming emerging butterfly].freeze
9
+ CHRYSALIS_TYPES = %i[silk paper bark leaf underground].freeze
10
+
11
+ MAX_CHRYSALISES = 200
12
+ MAX_BUTTERFLIES = 500
13
+ TRANSFORMATION_RATE = 0.08
14
+ PROTECTION_DECAY = 0.03
15
+ EMERGENCE_THRESHOLD = 0.9
16
+ PREMATURE_PENALTY = 0.4
17
+
18
+ STAGE_LABELS = {
19
+ (0.0...0.20) => :larva,
20
+ (0.20...0.40) => :spinning,
21
+ (0.40...0.60) => :cocooned,
22
+ (0.60...0.80) => :transforming,
23
+ (0.80...0.90) => :emerging,
24
+ (0.90..1.0) => :butterfly
25
+ }.freeze
26
+
27
+ BEAUTY_LABELS = {
28
+ (0.0...0.20) => :dull,
29
+ (0.20...0.40) => :plain,
30
+ (0.40...0.65) => :striking,
31
+ (0.65...0.85) => :beautiful,
32
+ (0.85..1.0) => :magnificent
33
+ }.freeze
34
+
35
+ def self.label_for(table, value)
36
+ table.each do |range, label|
37
+ return label if range.cover?(value)
38
+ end
39
+ table.values.last
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end