Skip to content

[GGGP M0] Generic CFG decoder spike (Grammatical Evolution) #1

Description

@mnemonik-dev

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 decodergggp_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 typesGpConfig, 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.rsmap(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)

  • cargo build -p evoforge-grammar → succeeds.
  • cargo test -p evoforge-grammar0 failed.
  • Test decode_generic_always_valid: 10_000 random codon vectors over the toy grammar → every
    decode is Ok and its output is a sentence the grammar can generate (0 MapError once
    max_wraps/max_depth are sane).
  • Test faber_roundtrip: a hand-written codon vector decodes to exactly
    {"entry":{"gt":["close","sma_200"]},"exit":{"lt":["close","sma_200"]}, ...} (the
    FABER_2007_SPEC shape from strategy_dsl.py).
  • cargo fmt --check and cargo clippy -p evoforge-grammar -- -D warnings → clean.

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions