Summary
First milestone (M0) of the production-ready GGGP module built on top of evoforge. Stand up the
generic grammar + Grammatical-Evolution (GE) decoder as a new pure-Rust crate evoforge-grammar
(depends on evoforge). No engine wiring, no Python — just prove that any CFG can be decoded from a
codon vector into a grammar-valid output, and that a hand-written codon vector reproduces a known
target (Faber SMA-200).
Full spec (locked decisions D1–D8):
https://github.com/mnemonik-dev/genetic_algorithms/blob/main/docs/technical-reference/gggp-implementation-spec.md
Background: gggp-grammar-tech-review.md (§3 BNF, §4 worked Faber derivation) and ga-grammar-glossary.md
in the same docs/technical-reference/ directory.
⭐ Reuse from autonomous-eden/gggp_bundle (do NOT greenfield)
A real Rust GE decoder already exists; port + adapt it rather than writing from scratch (see spec
§11 "Reuse map" + autonomous-eden-technical-reference.md §3):
- The decoder —
gggp_bundle/rust/src/gggp/mod.rs: GpConfig::tree_from_chromosome(chromosome) +
parse_chromosome() -> Vec<i32> + select_choice + build_node. This is GE (int codons → grammar
→ tree) — exactly M0's map(). Adapt the int-string chromosome to our Vec<i64> codons.
- The CFG types —
GpConfig, GpSymbol, GpChoice, GpRef, collect_non_terminals,
build_choice, build_ref → map to our Grammar/Symbol/Production/Rule.
- CFG load/serialize (reference) —
gggp_bundle/rust/src/storage/{node.rs,codec.rs,types.rs} (a
.cfg Node format). We use serde-JSON for the Grammar; treat .cfg as an optional import.
- Caveats: strip
reqwest/nalgebra (HTTP + embedding math) and the embedding/agent-trait domain;
it's research-grade (no CI, ~2 tests) so anything ported must pass M0's gates below.
- Extraction shortcut:
gggp_bundle/docs/SDK_REPO_SPLIT_PLAN.md gives a git subtree split --prefix gggp_bundle path into a gggp-core layout — the clean way to lift the decoder + grammar.
Scope (do exactly this)
- New crate
evoforge-grammar/ (Cargo, depends on evoforge, serde, serde_json, thiserror, uuid).
src/grammar.rs — generic Symbol / Terminal (Literal/Int{min,max}/Float{min,max}/FromSet) /
Production / Rule / Grammar { start, rules, sets } + Grammar::validate() + serde JSON roundtrip.
src/decode.rs — map(grammar, codons: &[i64], cfg: &MapConfig) -> Result<Derivation, MapError>
(port/adapt tree_from_chromosome + parse_chromosome). Derivation { output: String, tree: DerivNode, codons_used, wrapped, depth }. GE rule: leftmost-nonterminal, codon % n_productions,
advance/wrap (max_wraps), typed terminals consume a codon scaled into range; max_depth cap;
incompletable → MapError.
examples/evolve_toy.rs — a tiny non-trading grammar, decode random codons (proves arbitrary-DSL).
- Minimal hardcoded Archimedes condition grammar in the test only (enough for the Faber roundtrip).
Acceptance criteria (runnable, exact expected output)
Verify
cargo test -p evoforge-grammar -- --nocapture
cargo run -p evoforge-grammar --example evolve_toy
Anti-goals (do NOT)
- Do not add the
GrammarEngine / evoforge wiring yet (that's M1).
- Do not add the full Archimedes
Target adapter / repair / validate (that's M2).
- Do not add any Python / PyO3 /
gggp-repo bindings (D7: deferred).
- Do not modify the
evoforge core crate.
- Do not port
gggp_bundle's embedding/HTTP machinery or its Gggp population engine (M1 uses
evoforge's engine; Gggp is reference-only).
Notes
Depends on nothing. Blocks M1 (#2). Assigned per session direction.
Summary
First milestone (M0) of the production-ready GGGP module built on top of
evoforge. Stand up thegeneric grammar + Grammatical-Evolution (GE) decoder as a new pure-Rust crate
evoforge-grammar(depends on
evoforge). No engine wiring, no Python — just prove that any CFG can be decoded from acodon vector into a grammar-valid output, and that a hand-written codon vector reproduces a known
target (Faber SMA-200).
Full spec (locked decisions D1–D8):
https://github.com/mnemonik-dev/genetic_algorithms/blob/main/docs/technical-reference/gggp-implementation-spec.md
Background:
gggp-grammar-tech-review.md(§3 BNF, §4 worked Faber derivation) andga-grammar-glossary.mdin the same
docs/technical-reference/directory.⭐ Reuse from
autonomous-eden/gggp_bundle(do NOT greenfield)A real Rust GE decoder already exists; port + adapt it rather than writing from scratch (see spec
§11 "Reuse map" +
autonomous-eden-technical-reference.md§3):gggp_bundle/rust/src/gggp/mod.rs:GpConfig::tree_from_chromosome(chromosome)+parse_chromosome() -> Vec<i32>+select_choice+build_node. This is GE (int codons → grammar→ tree) — exactly M0's
map(). Adapt the int-string chromosome to ourVec<i64>codons.GpConfig,GpSymbol,GpChoice,GpRef,collect_non_terminals,build_choice,build_ref→ map to ourGrammar/Symbol/Production/Rule.gggp_bundle/rust/src/storage/{node.rs,codec.rs,types.rs}(a.cfgNodeformat). We use serde-JSON for theGrammar; treat.cfgas an optional import.reqwest/nalgebra(HTTP + embedding math) and the embedding/agent-trait domain;it's research-grade (no CI, ~2 tests) so anything ported must pass M0's gates below.
gggp_bundle/docs/SDK_REPO_SPLIT_PLAN.mdgives agit subtree split --prefix gggp_bundlepath into agggp-corelayout — the clean way to lift the decoder + grammar.Scope (do exactly this)
evoforge-grammar/(Cargo, depends onevoforge,serde,serde_json,thiserror,uuid).src/grammar.rs— genericSymbol/Terminal(Literal/Int{min,max}/Float{min,max}/FromSet) /Production/Rule/Grammar { start, rules, sets }+Grammar::validate()+ serde JSON roundtrip.src/decode.rs—map(grammar, codons: &[i64], cfg: &MapConfig) -> Result<Derivation, MapError>(port/adapt
tree_from_chromosome+parse_chromosome).Derivation { output: String, tree: DerivNode, codons_used, wrapped, depth }. GE rule: leftmost-nonterminal,codon % n_productions,advance/wrap (
max_wraps), typed terminals consume a codon scaled into range;max_depthcap;incompletable →
MapError.examples/evolve_toy.rs— a tiny non-trading grammar, decode random codons (proves arbitrary-DSL).Acceptance criteria (runnable, exact expected output)
cargo build -p evoforge-grammar→ succeeds.cargo test -p evoforge-grammar→0 failed.decode_generic_always_valid: 10_000 random codon vectors over the toy grammar → everydecode is
Okand itsoutputis a sentence the grammar can generate (0MapErroroncemax_wraps/max_depthare sane).faber_roundtrip: a hand-written codon vector decodes to exactly{"entry":{"gt":["close","sma_200"]},"exit":{"lt":["close","sma_200"]}, ...}(theFABER_2007_SPECshape fromstrategy_dsl.py).cargo fmt --checkandcargo clippy -p evoforge-grammar -- -D warnings→ clean.Verify
Anti-goals (do NOT)
GrammarEngine/ evoforge wiring yet (that's M1).Targetadapter / repair / validate (that's M2).gggp-repo bindings (D7: deferred).evoforgecore crate.gggp_bundle's embedding/HTTP machinery or itsGggppopulation engine (M1 usesevoforge's engine;
Gggpis reference-only).Notes
Depends on nothing. Blocks M1 (#2). Assigned per session direction.