lex-cognitive-alchemy 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 +87 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +78 -0
- data/README.md +60 -0
- data/lex-cognitive-alchemy.gemspec +33 -0
- data/lib/legion/extensions/cognitive_alchemy/client.rb +11 -0
- data/lib/legion/extensions/cognitive_alchemy/helpers/alchemy_engine.rb +136 -0
- data/lib/legion/extensions/cognitive_alchemy/helpers/constants.rb +72 -0
- data/lib/legion/extensions/cognitive_alchemy/helpers/crucible.rb +76 -0
- data/lib/legion/extensions/cognitive_alchemy/helpers/substance.rb +114 -0
- data/lib/legion/extensions/cognitive_alchemy/runners/cognitive_alchemy.rb +84 -0
- data/lib/legion/extensions/cognitive_alchemy/version.rb +9 -0
- data/lib/legion/extensions/cognitive_alchemy.rb +19 -0
- metadata +79 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 51513cbacc1a1f0aecbdd72f1b383e406941930fe87cbe1ecc56c956f8fab8eb
|
|
4
|
+
data.tar.gz: c1e9114adbc5ccaeade7e72c6f0f5d565028bf2d0d642e3d9e12ff81fdd71ddb
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 062f264dfbfc751c3f8224b5b124ad599058705308e626c8d87ed0c672171c161d56d74dddf53a67cc9d9366c819863edaddbe417f5f1eaa14462871766048be
|
|
7
|
+
data.tar.gz: 3785118d7f7c03f2ea41a6da09c27c18bae76580cb99cc6590f5cc30eef1f1c7e09a985d9580b7876780681fd5fb91b17264ce9da2d6382157dea3736d234321
|
|
@@ -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,87 @@
|
|
|
1
|
+
# lex-cognitive-alchemy
|
|
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
|
+
Alchemical metaphor for cognitive transformation — substances move through four Jungian stages (nigredo, albedo, citrinitas, rubedo) via reactions and catalysts, modeling irreversible knowledge refinement and insight synthesis.
|
|
10
|
+
|
|
11
|
+
## Gem Info
|
|
12
|
+
|
|
13
|
+
- **Gem name**: `lex-cognitive-alchemy`
|
|
14
|
+
- **Version**: `0.1.0`
|
|
15
|
+
- **Module**: `Legion::Extensions::CognitiveAlchemy`
|
|
16
|
+
- **Ruby**: `>= 3.4`
|
|
17
|
+
- **License**: MIT
|
|
18
|
+
|
|
19
|
+
## File Structure
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
lib/legion/extensions/cognitive_alchemy/
|
|
23
|
+
cognitive_alchemy.rb # Main extension module
|
|
24
|
+
version.rb # VERSION = '0.1.0'
|
|
25
|
+
client.rb # Client wrapper
|
|
26
|
+
helpers/
|
|
27
|
+
constants.rb # Stages, element types, reaction types, multipliers, labels
|
|
28
|
+
substance.rb # Substance value object (stage, purity, potency, element_type)
|
|
29
|
+
alchemy_engine.rb # AlchemyEngine — manages substances, reactions, stage progression
|
|
30
|
+
runners/
|
|
31
|
+
cognitive_alchemy.rb # Runner module (extend self) with 7 public methods
|
|
32
|
+
spec/
|
|
33
|
+
(spec files)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Key Constants
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
STAGES = %i[nigredo albedo citrinitas rubedo]
|
|
40
|
+
ELEMENT_TYPES = %i[fire water earth air aether]
|
|
41
|
+
REACTION_TYPES = %i[synthesis decomposition transmutation catalysis dissolution]
|
|
42
|
+
CATALYST_MULTIPLIER = 3.0 # catalyst reactions multiply purity/potency gain by 3x
|
|
43
|
+
PURITY_LABELS = {
|
|
44
|
+
(0.9..) => :refined, (0.7...0.9) => :purified, (0.5...0.7) => :mixed,
|
|
45
|
+
(0.3...0.5) => :impure, (..0.3) => :crude
|
|
46
|
+
}
|
|
47
|
+
POTENCY_LABELS = {
|
|
48
|
+
(0.85..) => :transcendent, (0.65...0.85) => :potent, (0.45...0.65) => :moderate,
|
|
49
|
+
(0.25...0.45) => :weak, (..0.25) => :inert
|
|
50
|
+
}
|
|
51
|
+
STAGE_LABELS = {
|
|
52
|
+
nigredo: :decomposition, albedo: :purification,
|
|
53
|
+
citrinitas: :illumination, rubedo: :completion
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Runners
|
|
58
|
+
|
|
59
|
+
### `Runners::CognitiveAlchemy`
|
|
60
|
+
|
|
61
|
+
Uses `extend self` — methods are module-level, not instance-delegating. Delegates to a per-call `engine` (parameter-injected `Helpers::AlchemyEngine` instance via `engine:` keyword, defaulting to a shared `@engine ||=`).
|
|
62
|
+
|
|
63
|
+
- `create_substance(name:, element_type:, domain: :general, engine: @engine)` — create a new alchemical substance at `:nigredo` stage with default purity/potency
|
|
64
|
+
- `advance_stage(substance_id:, engine: @engine)` — move substance to the next STAGES entry; no-op at `:rubedo`
|
|
65
|
+
- `catalyze(substance_id:, catalyst:, engine: @engine)` — apply a catalyst to a substance, multiplying its purity and potency gain by `CATALYST_MULTIPLIER`
|
|
66
|
+
- `react(substance_id:, reagent_id:, reaction_type:, engine: @engine)` — apply a typed reaction between two substances; returns reaction outcome hash
|
|
67
|
+
- `list_substances(engine: @engine)` — all substances as array of hashes
|
|
68
|
+
- `alchemy_status(engine: @engine)` — summary stats: substance count, stage distribution, average purity/potency
|
|
69
|
+
|
|
70
|
+
## Helpers
|
|
71
|
+
|
|
72
|
+
### `Helpers::AlchemyEngine`
|
|
73
|
+
Core engine managing `@substances` hash keyed by ID. `advance_stage` cycles through `STAGES` array index. `catalyze` applies `CATALYST_MULTIPLIER` to substance attribute update. `react` looks up both substances, applies reaction effects based on `reaction_type`, and returns outcome. `substance_list` returns all substances as serialized hashes.
|
|
74
|
+
|
|
75
|
+
### `Helpers::Substance`
|
|
76
|
+
Value object: name, element_type, domain, stage (starts at `:nigredo`), purity (0.0–1.0), potency (0.0–1.0), reaction_count. `advance!` bumps stage via STAGES index. `refine!(amount)` increases purity clamped to 1.0. `empower!(amount)` increases potency clamped to 1.0. `purity_label` and `potency_label` map to human-readable labels.
|
|
77
|
+
|
|
78
|
+
## Integration Points
|
|
79
|
+
|
|
80
|
+
No actor defined — no automatic decay or scanning. This is a transformation metaphor: raw observations enter at `:nigredo` and move through stages as evidence accumulates. Pairs with lex-causal-reasoning (causal chains can trigger stage advancement) and lex-abductive-reasoning (best explanations emerge at `:rubedo`). The CATALYST_MULTIPLIER (3x) models insight events — moments where a catalyst dramatically accelerates refinement.
|
|
81
|
+
|
|
82
|
+
## Development Notes
|
|
83
|
+
|
|
84
|
+
- `extend self` pattern means the runner is a module with module-level methods — no `@engine` instance variable in a class; shared state lives in the module's singleton
|
|
85
|
+
- `advance_stage` is a no-op when substance is already at `:rubedo` — callers should check stage before calling
|
|
86
|
+
- `CATALYST_MULTIPLIER = 3.0` is the only numeric constant that differs from the standard 0.1/0.15 rates used by other extensions
|
|
87
|
+
- Stage ordering is fixed by the `STAGES` array index; array order defines the progression
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
lex-cognitive-alchemy (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-alchemy!
|
|
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,60 @@
|
|
|
1
|
+
# lex-cognitive-alchemy
|
|
2
|
+
|
|
3
|
+
Alchemical metaphor for cognitive transformation — substances move through Jungian stages via reactions and catalysts.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
Models knowledge refinement as an alchemical process. Cognitive substances (ideas, insights, hypotheses) are created at the crude `:nigredo` stage and purified through four stages: nigredo (decomposition), albedo (purification), citrinitas (illumination), rubedo (completion). Reactions between substances transform them; catalysts multiply the gain by 3x.
|
|
8
|
+
|
|
9
|
+
## Core Concept: Stage Progression
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
nigredo -> albedo -> citrinitas -> rubedo
|
|
13
|
+
(crude) (purified) (illuminated) (complete)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Each substance has `purity` (0.0–1.0, crude to refined) and `potency` (0.0–1.0, inert to transcendent). Stage advancement and reactions increase both.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
client = Legion::Extensions::CognitiveAlchemy::Client.new
|
|
22
|
+
|
|
23
|
+
# Create substances from raw observations
|
|
24
|
+
idea = client.create_substance(name: :cache_invalidation_theory, element_type: :fire, domain: :infrastructure)
|
|
25
|
+
evidence = client.create_substance(name: :production_trace_data, element_type: :earth, domain: :infrastructure)
|
|
26
|
+
|
|
27
|
+
# Apply a reaction between substances
|
|
28
|
+
client.react(
|
|
29
|
+
substance_id: idea[:substance][:id],
|
|
30
|
+
reagent_id: evidence[:substance][:id],
|
|
31
|
+
reaction_type: :synthesis
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# A breakthrough insight acts as a catalyst (3x multiplier)
|
|
35
|
+
client.catalyze(substance_id: idea[:substance][:id], catalyst: :root_cause_confirmed)
|
|
36
|
+
|
|
37
|
+
# Advance to next stage when ready
|
|
38
|
+
client.advance_stage(substance_id: idea[:substance][:id])
|
|
39
|
+
# substance moves from :nigredo -> :albedo
|
|
40
|
+
|
|
41
|
+
# Check overall transformation progress
|
|
42
|
+
client.alchemy_status
|
|
43
|
+
# => { substance_count: 2, stage_distribution: { nigredo: 1, albedo: 1, ... }, avg_purity: 0.62 }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Integration
|
|
47
|
+
|
|
48
|
+
Pairs with lex-causal-reasoning (causal chains can trigger stage advancement as evidence accumulates) and lex-abductive-reasoning (best explanations correspond to `:rubedo` substances — fully refined and potent).
|
|
49
|
+
|
|
50
|
+
## Development
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
bundle install
|
|
54
|
+
bundle exec rspec
|
|
55
|
+
bundle exec rubocop
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
|
|
60
|
+
MIT
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/legion/extensions/cognitive_alchemy/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'lex-cognitive-alchemy'
|
|
7
|
+
spec.version = Legion::Extensions::CognitiveAlchemy::VERSION
|
|
8
|
+
spec.authors = ['Esity']
|
|
9
|
+
spec.email = ['matthewdiverson@gmail.com']
|
|
10
|
+
spec.license = 'MIT'
|
|
11
|
+
|
|
12
|
+
spec.summary = 'Cognitive alchemy LEX — transmutation of ideas through alchemical stages'
|
|
13
|
+
spec.description = 'Models the Magnum Opus of idea transmutation: substances pass through ' \
|
|
14
|
+
'nigredo/albedo/citrinitas/rubedo stages, crucible reactions combine elements ' \
|
|
15
|
+
'under heat and pressure, and philosopher stone catalysis accelerates breakthroughs.'
|
|
16
|
+
spec.homepage = 'https://github.com/LegionIO/lex-cognitive-alchemy'
|
|
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,136 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveAlchemy
|
|
6
|
+
module Helpers
|
|
7
|
+
class AlchemyEngine
|
|
8
|
+
def initialize
|
|
9
|
+
@substances = {}
|
|
10
|
+
@reactions = {}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create_substance(element_type:, domain:, content:, purity: nil, potency: nil)
|
|
14
|
+
raise ArgumentError, 'athanor full' if @substances.size >= Constants::MAX_SUBSTANCES
|
|
15
|
+
|
|
16
|
+
sub = Substance.new(element_type: element_type, domain: domain,
|
|
17
|
+
content: content, purity: purity, potency: potency)
|
|
18
|
+
@substances[sub.id] = sub
|
|
19
|
+
sub
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def advance_stage(substance_id:)
|
|
23
|
+
fetch_substance(substance_id).advance_stage!
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def catalyze(substance_id:, multiplier: Constants::CATALYST_MULTIPLIER)
|
|
27
|
+
fetch_substance(substance_id).catalyze!(multiplier: multiplier)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def react(reaction_type:, input_ids:, heat: 0.5, pressure: 0.5)
|
|
31
|
+
raise ArgumentError, 'too many reactions' if @reactions.size >= Constants::MAX_REACTIONS
|
|
32
|
+
|
|
33
|
+
inputs = input_ids.map { |id| fetch_substance(id) }
|
|
34
|
+
crucible = Crucible.new(reaction_type: reaction_type, input_ids: input_ids,
|
|
35
|
+
heat: heat, pressure: pressure)
|
|
36
|
+
|
|
37
|
+
output = synthesize(inputs, crucible)
|
|
38
|
+
@substances[output.id] = output
|
|
39
|
+
crucible.complete!(output.id)
|
|
40
|
+
@reactions[crucible.id] = crucible
|
|
41
|
+
|
|
42
|
+
{ crucible: crucible, output: output }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def decay_all!(rate: Constants::SUBSTANCE_DECAY)
|
|
46
|
+
@substances.each_value { |s| s.decay!(rate: rate) }
|
|
47
|
+
pruned = @substances.select { |_, s| s.inert? }.keys
|
|
48
|
+
pruned.each { |id| @substances.delete(id) }
|
|
49
|
+
{ decayed: @substances.size, pruned: pruned.size }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def substances_by_stage
|
|
53
|
+
counts = Constants::STAGES.to_h { |s| [s, 0] }
|
|
54
|
+
@substances.each_value { |s| counts[s.stage] += 1 }
|
|
55
|
+
counts
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def substances_by_type
|
|
59
|
+
counts = Constants::ELEMENT_TYPES.to_h { |t| [t, 0] }
|
|
60
|
+
@substances.each_value { |s| counts[s.element_type] += 1 }
|
|
61
|
+
counts
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def gold_count
|
|
65
|
+
@substances.count { |_, s| s.gold? }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def prima_materia_count
|
|
69
|
+
@substances.count { |_, s| s.prima_materia? }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def purest(limit: 5)
|
|
73
|
+
@substances.values.sort_by { |s| -s.purity }.first(limit)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def most_potent(limit: 5)
|
|
77
|
+
@substances.values.sort_by { |s| -s.potency }.first(limit)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def alchemy_report
|
|
81
|
+
{
|
|
82
|
+
total_substances: @substances.size,
|
|
83
|
+
total_reactions: @reactions.size,
|
|
84
|
+
by_stage: substances_by_stage,
|
|
85
|
+
by_type: substances_by_type,
|
|
86
|
+
gold_count: gold_count,
|
|
87
|
+
prima_materia: prima_materia_count,
|
|
88
|
+
avg_purity: avg_metric(:purity),
|
|
89
|
+
avg_potency: avg_metric(:potency)
|
|
90
|
+
}
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def all_substances
|
|
94
|
+
@substances.values
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def all_reactions
|
|
98
|
+
@reactions.values
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
def fetch_substance(id)
|
|
104
|
+
@substances.fetch(id) do
|
|
105
|
+
raise ArgumentError, "substance not found: #{id}"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def synthesize(inputs, crucible)
|
|
110
|
+
avg_purity = inputs.sum(&:purity) / inputs.size
|
|
111
|
+
avg_potency = inputs.sum(&:potency) / inputs.size
|
|
112
|
+
boost = crucible.intensity * Constants::TRANSMUTATION_RATE
|
|
113
|
+
|
|
114
|
+
create_substance(
|
|
115
|
+
element_type: inputs.first.element_type,
|
|
116
|
+
domain: inputs.first.domain,
|
|
117
|
+
content: "synthesis(#{inputs.map(&:content).join(' + ')})",
|
|
118
|
+
purity: (avg_purity + boost).clamp(0.0, 1.0),
|
|
119
|
+
potency: (avg_potency + (boost * 0.5)).clamp(0.0, 1.0)
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def avg_metric(attr)
|
|
124
|
+
return 0.0 if @substances.empty?
|
|
125
|
+
|
|
126
|
+
(substances_metric_sum(attr) / @substances.size).round(10)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def substances_metric_sum(attr)
|
|
130
|
+
@substances.values.sum(&attr)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveAlchemy
|
|
6
|
+
module Helpers
|
|
7
|
+
module Constants
|
|
8
|
+
# Alchemical stages (Magnum Opus)
|
|
9
|
+
STAGES = %i[nigredo albedo citrinitas rubedo].freeze
|
|
10
|
+
|
|
11
|
+
# Transmutation element types
|
|
12
|
+
ELEMENT_TYPES = %i[
|
|
13
|
+
concept belief skill memory emotion
|
|
14
|
+
pattern habit intuition hypothesis
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
# Crucible reaction types
|
|
18
|
+
REACTION_TYPES = %i[
|
|
19
|
+
calcination dissolution separation conjunction
|
|
20
|
+
fermentation distillation coagulation
|
|
21
|
+
].freeze
|
|
22
|
+
|
|
23
|
+
# Maximum substances in the athanor
|
|
24
|
+
MAX_SUBSTANCES = 200
|
|
25
|
+
|
|
26
|
+
# Maximum crucible reactions
|
|
27
|
+
MAX_REACTIONS = 100
|
|
28
|
+
|
|
29
|
+
# Base transmutation rate per stage advance
|
|
30
|
+
TRANSMUTATION_RATE = 0.15
|
|
31
|
+
|
|
32
|
+
# Decay rate for unreacted substances
|
|
33
|
+
SUBSTANCE_DECAY = 0.02
|
|
34
|
+
|
|
35
|
+
# Philosopher's stone catalyst multiplier
|
|
36
|
+
CATALYST_MULTIPLIER = 3.0
|
|
37
|
+
|
|
38
|
+
# Stage labels
|
|
39
|
+
STAGE_LABELS = {
|
|
40
|
+
nigredo: 'Blackening — decomposition of raw material',
|
|
41
|
+
albedo: 'Whitening — purification and washing',
|
|
42
|
+
citrinitas: 'Yellowing — solar awakening',
|
|
43
|
+
rubedo: 'Reddening — final integration and gold'
|
|
44
|
+
}.freeze
|
|
45
|
+
|
|
46
|
+
# Purity labels (range-based)
|
|
47
|
+
PURITY_LABELS = [
|
|
48
|
+
[(0.8..), :aurum],
|
|
49
|
+
[(0.6...0.8), :argentum],
|
|
50
|
+
[(0.4...0.6), :cuprum],
|
|
51
|
+
[(0.2...0.4), :ferrum],
|
|
52
|
+
[(..0.2), :plumbum]
|
|
53
|
+
].freeze
|
|
54
|
+
|
|
55
|
+
# Potency labels
|
|
56
|
+
POTENCY_LABELS = [
|
|
57
|
+
[(0.8..), :transcendent],
|
|
58
|
+
[(0.6...0.8), :potent],
|
|
59
|
+
[(0.4...0.6), :moderate],
|
|
60
|
+
[(0.2...0.4), :weak],
|
|
61
|
+
[(..0.2), :inert]
|
|
62
|
+
].freeze
|
|
63
|
+
|
|
64
|
+
def self.label_for(table, value)
|
|
65
|
+
table.each { |range, label| return label if range.cover?(value) }
|
|
66
|
+
table.last.last
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveAlchemy
|
|
6
|
+
module Helpers
|
|
7
|
+
class Crucible
|
|
8
|
+
attr_reader :id, :reaction_type, :input_ids, :output_id,
|
|
9
|
+
:heat, :pressure, :started_at, :completed_at
|
|
10
|
+
|
|
11
|
+
def initialize(reaction_type:, input_ids:,
|
|
12
|
+
heat: 0.5, pressure: 0.5)
|
|
13
|
+
validate_reaction!(reaction_type)
|
|
14
|
+
@id = SecureRandom.uuid
|
|
15
|
+
@reaction_type = reaction_type.to_sym
|
|
16
|
+
@input_ids = Array(input_ids).dup
|
|
17
|
+
@output_id = nil
|
|
18
|
+
@heat = heat.to_f.clamp(0.0, 1.0).round(10)
|
|
19
|
+
@pressure = pressure.to_f.clamp(0.0, 1.0).round(10)
|
|
20
|
+
@started_at = Time.now.utc
|
|
21
|
+
@completed_at = nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def complete!(output_id)
|
|
25
|
+
@output_id = output_id
|
|
26
|
+
@completed_at = Time.now.utc
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def completed?
|
|
31
|
+
!@completed_at.nil?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def intensity
|
|
35
|
+
((@heat + @pressure) / 2.0).round(10)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def volatile?
|
|
39
|
+
@heat > 0.8 && @pressure > 0.8
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def mild?
|
|
43
|
+
intensity < 0.3
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_h
|
|
47
|
+
{
|
|
48
|
+
id: @id,
|
|
49
|
+
reaction_type: @reaction_type,
|
|
50
|
+
input_ids: @input_ids,
|
|
51
|
+
output_id: @output_id,
|
|
52
|
+
heat: @heat,
|
|
53
|
+
pressure: @pressure,
|
|
54
|
+
intensity: intensity,
|
|
55
|
+
volatile: volatile?,
|
|
56
|
+
mild: mild?,
|
|
57
|
+
started_at: @started_at,
|
|
58
|
+
completed_at: @completed_at,
|
|
59
|
+
completed: completed?
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def validate_reaction!(val)
|
|
66
|
+
return if Constants::REACTION_TYPES.include?(val.to_sym)
|
|
67
|
+
|
|
68
|
+
raise ArgumentError,
|
|
69
|
+
"unknown reaction type: #{val.inspect}; " \
|
|
70
|
+
"must be one of #{Constants::REACTION_TYPES.inspect}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveAlchemy
|
|
6
|
+
module Helpers
|
|
7
|
+
class Substance
|
|
8
|
+
attr_reader :id, :element_type, :domain, :content,
|
|
9
|
+
:stage, :discovered_at, :transmutation_count
|
|
10
|
+
attr_accessor :purity, :potency
|
|
11
|
+
|
|
12
|
+
def initialize(element_type:, domain:, content:,
|
|
13
|
+
purity: nil, potency: nil)
|
|
14
|
+
validate_type!(element_type)
|
|
15
|
+
assign_core(element_type, domain, content)
|
|
16
|
+
assign_metadata(purity, potency)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def advance_stage!
|
|
20
|
+
idx = Constants::STAGES.index(@stage)
|
|
21
|
+
return self if idx >= Constants::STAGES.size - 1
|
|
22
|
+
|
|
23
|
+
@stage = Constants::STAGES[idx + 1]
|
|
24
|
+
@purity = (@purity + Constants::TRANSMUTATION_RATE).clamp(0.0, 1.0).round(10)
|
|
25
|
+
@transmutation_count += 1
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def decay!(rate: Constants::SUBSTANCE_DECAY)
|
|
30
|
+
@potency = (@potency - rate.abs).clamp(0.0, 1.0).round(10)
|
|
31
|
+
self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def catalyze!(multiplier: Constants::CATALYST_MULTIPLIER)
|
|
35
|
+
boost = Constants::TRANSMUTATION_RATE * multiplier
|
|
36
|
+
@purity = (@purity + boost).clamp(0.0, 1.0).round(10)
|
|
37
|
+
@potency = (@potency + (boost * 0.5)).clamp(0.0, 1.0).round(10)
|
|
38
|
+
@transmutation_count += 1
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def prima_materia?
|
|
43
|
+
@stage == :nigredo && @purity < 0.2
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def gold?
|
|
47
|
+
@stage == :rubedo && @purity >= 0.8
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def inert?
|
|
51
|
+
@potency < 0.1
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def purity_label
|
|
55
|
+
Constants.label_for(Constants::PURITY_LABELS, @purity)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def potency_label
|
|
59
|
+
Constants.label_for(Constants::POTENCY_LABELS, @potency)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def stage_label
|
|
63
|
+
Constants::STAGE_LABELS.fetch(@stage, 'unknown')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def to_h
|
|
67
|
+
{
|
|
68
|
+
id: @id,
|
|
69
|
+
element_type: @element_type,
|
|
70
|
+
domain: @domain,
|
|
71
|
+
content: @content,
|
|
72
|
+
stage: @stage,
|
|
73
|
+
stage_label: stage_label,
|
|
74
|
+
purity: @purity,
|
|
75
|
+
purity_label: purity_label,
|
|
76
|
+
potency: @potency,
|
|
77
|
+
potency_label: potency_label,
|
|
78
|
+
transmutation_count: @transmutation_count,
|
|
79
|
+
discovered_at: @discovered_at,
|
|
80
|
+
prima_materia: prima_materia?,
|
|
81
|
+
gold: gold?,
|
|
82
|
+
inert: inert?
|
|
83
|
+
}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def assign_core(element_type, domain, content)
|
|
89
|
+
@id = SecureRandom.uuid
|
|
90
|
+
@element_type = element_type.to_sym
|
|
91
|
+
@domain = domain.to_sym
|
|
92
|
+
@content = content.to_s
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def assign_metadata(purity, potency)
|
|
96
|
+
@stage = :nigredo
|
|
97
|
+
@purity = (purity || 0.1).to_f.clamp(0.0, 1.0).round(10)
|
|
98
|
+
@potency = (potency || 0.5).to_f.clamp(0.0, 1.0).round(10)
|
|
99
|
+
@transmutation_count = 0
|
|
100
|
+
@discovered_at = Time.now.utc
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def validate_type!(val)
|
|
104
|
+
return if Constants::ELEMENT_TYPES.include?(val.to_sym)
|
|
105
|
+
|
|
106
|
+
raise ArgumentError,
|
|
107
|
+
"unknown element type: #{val.inspect}; " \
|
|
108
|
+
"must be one of #{Constants::ELEMENT_TYPES.inspect}"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module CognitiveAlchemy
|
|
6
|
+
module Runners
|
|
7
|
+
module CognitiveAlchemy
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
def create_substance(element_type:, domain:, content:,
|
|
11
|
+
purity: nil, potency: nil, engine: nil, **)
|
|
12
|
+
eng = resolve_engine(engine)
|
|
13
|
+
sub = eng.create_substance(element_type: element_type, domain: domain,
|
|
14
|
+
content: content, purity: purity, potency: potency)
|
|
15
|
+
{ success: true, substance: sub.to_h }
|
|
16
|
+
rescue ArgumentError => e
|
|
17
|
+
{ success: false, error: e.message }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def advance_stage(substance_id:, engine: nil, **)
|
|
21
|
+
eng = resolve_engine(engine)
|
|
22
|
+
sub = eng.advance_stage(substance_id: substance_id)
|
|
23
|
+
{ success: true, substance: sub.to_h }
|
|
24
|
+
rescue ArgumentError => e
|
|
25
|
+
{ success: false, error: e.message }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def catalyze(substance_id:, multiplier: nil, engine: nil, **)
|
|
29
|
+
eng = resolve_engine(engine)
|
|
30
|
+
opts = { substance_id: substance_id }
|
|
31
|
+
opts[:multiplier] = multiplier if multiplier
|
|
32
|
+
sub = eng.catalyze(**opts)
|
|
33
|
+
{ success: true, substance: sub.to_h }
|
|
34
|
+
rescue ArgumentError => e
|
|
35
|
+
{ success: false, error: e.message }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def react(reaction_type:, input_ids:, heat: 0.5,
|
|
39
|
+
pressure: 0.5, engine: nil, **)
|
|
40
|
+
eng = resolve_engine(engine)
|
|
41
|
+
result = eng.react(reaction_type: reaction_type, input_ids: input_ids,
|
|
42
|
+
heat: heat, pressure: pressure)
|
|
43
|
+
{ success: true, crucible: result[:crucible].to_h,
|
|
44
|
+
output: result[:output].to_h }
|
|
45
|
+
rescue ArgumentError => e
|
|
46
|
+
{ success: false, error: e.message }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def list_substances(engine: nil, stage: nil, element_type: nil, **)
|
|
50
|
+
eng = resolve_engine(engine)
|
|
51
|
+
results = filter_substances(eng.all_substances,
|
|
52
|
+
stage: stage, element_type: element_type)
|
|
53
|
+
{ success: true, substances: results.map(&:to_h),
|
|
54
|
+
count: results.size }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def alchemy_status(engine: nil, **)
|
|
58
|
+
eng = resolve_engine(engine)
|
|
59
|
+
{ success: true, report: eng.alchemy_report }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def filter_substances(substances, stage:, element_type:)
|
|
67
|
+
r = substances
|
|
68
|
+
r = r.select { |s| s.stage == stage.to_sym } if stage
|
|
69
|
+
r = r.select { |s| s.element_type == element_type.to_sym } if element_type
|
|
70
|
+
r
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def resolve_engine(engine)
|
|
74
|
+
engine || default_engine
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def default_engine
|
|
78
|
+
@default_engine ||= Helpers::AlchemyEngine.new
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
require_relative 'cognitive_alchemy/version'
|
|
6
|
+
require_relative 'cognitive_alchemy/helpers/constants'
|
|
7
|
+
require_relative 'cognitive_alchemy/helpers/substance'
|
|
8
|
+
require_relative 'cognitive_alchemy/helpers/crucible'
|
|
9
|
+
require_relative 'cognitive_alchemy/helpers/alchemy_engine'
|
|
10
|
+
require_relative 'cognitive_alchemy/runners/cognitive_alchemy'
|
|
11
|
+
require_relative 'cognitive_alchemy/client'
|
|
12
|
+
|
|
13
|
+
module Legion
|
|
14
|
+
module Extensions
|
|
15
|
+
module CognitiveAlchemy
|
|
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-alchemy
|
|
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: 'Models the Magnum Opus of idea transmutation: substances pass through
|
|
27
|
+
nigredo/albedo/citrinitas/rubedo stages, crucible reactions combine elements under
|
|
28
|
+
heat and pressure, and philosopher stone catalysis accelerates breakthroughs.'
|
|
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-alchemy.gemspec
|
|
44
|
+
- lib/legion/extensions/cognitive_alchemy.rb
|
|
45
|
+
- lib/legion/extensions/cognitive_alchemy/client.rb
|
|
46
|
+
- lib/legion/extensions/cognitive_alchemy/helpers/alchemy_engine.rb
|
|
47
|
+
- lib/legion/extensions/cognitive_alchemy/helpers/constants.rb
|
|
48
|
+
- lib/legion/extensions/cognitive_alchemy/helpers/crucible.rb
|
|
49
|
+
- lib/legion/extensions/cognitive_alchemy/helpers/substance.rb
|
|
50
|
+
- lib/legion/extensions/cognitive_alchemy/runners/cognitive_alchemy.rb
|
|
51
|
+
- lib/legion/extensions/cognitive_alchemy/version.rb
|
|
52
|
+
homepage: https://github.com/LegionIO/lex-cognitive-alchemy
|
|
53
|
+
licenses:
|
|
54
|
+
- MIT
|
|
55
|
+
metadata:
|
|
56
|
+
homepage_uri: https://github.com/LegionIO/lex-cognitive-alchemy
|
|
57
|
+
source_code_uri: https://github.com/LegionIO/lex-cognitive-alchemy
|
|
58
|
+
documentation_uri: https://github.com/LegionIO/lex-cognitive-alchemy#readme
|
|
59
|
+
changelog_uri: https://github.com/LegionIO/lex-cognitive-alchemy/blob/main/CHANGELOG.md
|
|
60
|
+
bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-alchemy/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 alchemy LEX — transmutation of ideas through alchemical stages
|
|
79
|
+
test_files: []
|