Cambrian explosion (100 founders × 500 generations → 101 species), biome-aware ecosystem with first-principles biogeography, an autonomous Twin Driver that runs evolution campaigns on a cron, and 17 blog posts shipped behind it. All on the public Rappter Engine Twin, ~1,300 lines of stdlib Python.
Built on top of the Rappter Engine Twin shipped earlier today. This workstream took the substrate and put life on it: a Cambrian-scale population study, a planetary biome simulation, and an autonomous driver that runs both on a 6-hour cron without supervision. Then 17 follow-up blog posts to tell the story. Everything lands in this repo and on GitHub Pages — zero servers, zero deps.
Public twin of the private Rappter engine. Frame loop, RNG isolation, deterministic seeding. ~150 LOC, stdlib only.
100 founder eggs → 500 generations → 101 named species. Speciation when interbreeding compatibility crosses a floor. ~330 LOC.
4 biomes (forest/ocean/mountain/sky), per-biome fitness, migration cost. Geographic isolation breeds new species. ~280 LOC.
Autonomous campaign manager. Picks a sim, picks parameters, runs it, indexes the result. ~270 LOC.
Interactive cladogram viewer. Mobile-responsive SVG tree of life with named species + divergence times.
World map with biomes colored by dominant lineage. Biogeography emerges; no species was assigned to a biome.
Live dashboard reading state/twin_runs/index.json. Shows last 10 campaigns with one-click re-run links.
Cron 0 */6 * * *. Runs a campaign, commits the result, pushes. State accrues without anyone watching.
egg-phylogeny.py (4 founders, 50 gens). User asked to scale to Cambrian (100 × 500). Naive copy: blew memory in the offspring buffer. Lesson: the population graph grows quadratically when you keep all ancestors.docs/cambrian.html) renders the SVG tree on mobile. Tap a species to see its trait genome.docs/ecosystem.html): world map with biomes colored by dominant lineage. Click a biome to see its species composition.scripts/twin_driver.py + cron workflow.state/twin_runs/index.json. Dashboard live.kody-w.github.io, _posts/2026-05-02-* through 2026-05-18-*. Mobile-readable verified.Most of the day was spent on the speciation function. Logging them so we don't repeat the failure path:
Final (v8): lineage tracking + compatibility floor + explicit back-merge logging. Reproducible, generation-stable, biologically honest.
What makes a species "the same species" across generations isn't its genome at frame N — it's the unbroken chain of ancestors back to its founder. Snapshot identity gives you instability; lineage gives you continuity.
If you fitness-select hard enough, the population converges to one phenotype. Diversity requires either weak selection, niche pressure (ecosystem!), or explicit minority protection. We chose niche pressure.
Deterministic seeding via hashlib.sha256(f"{seed}-{frame}-{individual_id}") gives portable, reproducible randomness. No pickle, no numpy state, no version drift. Same seed → same Cambrian explosion forever.
Cambrian and Ecosystem are both twin_engine.frame_loop() calls with different mutators. The loop is a substrate. New simulations ≈ new mutator + new fitness function. The engine doesn't change.
~1,300 lines of pure Python stdlib produced a phylogenetic tree, a biogeographic world map, and an autonomous campaign runner. random, hashlib, json, collections, pathlib. That's the toolkit.
Both Cambrian and Ecosystem write to state/twin_runs/{run_id}.json with the same schema. The Twin Driver doesn't know what kind of sim it just ran — it just indexes the result. Polymorphism via convention, not inheritance.
$ python3 scripts/cambrian.py --founders 100 --generations 500 --seed 42
[cambrian] founders=100 gens=500 seed=42
[cambrian] gen 100: 14 species, 1,832 individuals
[cambrian] gen 200: 47 species, 2,418 individuals
[cambrian] gen 300: 78 species, 2,901 individuals
[cambrian] gen 400: 94 species, 3,144 individuals
[cambrian] gen 500: 101 species, 3,287 individuals
[cambrian] back-merges logged: 23
[cambrian] dominant lineage: founder-073 (487 descendants across 12 species)
[cambrian] wrote state/twin_runs/cambrian-1776528-42.json (164 KB)
[cambrian] cladogram: docs/cambrian.html
$ python3 scripts/ecosystem.py --biomes forest,ocean,mountain,sky --gens 100
[ecosystem] biomes=4 gens=100 seed=auto
[ecosystem] migration cost: 0.15 fitness
[ecosystem] gen 100 dominance:
forest → lineage-014 (62% of biome)
ocean → lineage-039 (71% of biome)
mountain → lineage-008 (54% of biome)
sky → lineage-051 (88% of biome) <-- isolated, hardest to migrate to
[ecosystem] migrations recorded: 188
[ecosystem] wrote state/twin_runs/ecosystem-1776528.json
[ecosystem] map: docs/ecosystem.html
$ cat state/twin_runs/index.json | python3 -m json.tool | head -40
{
"runs": [
{"id": "phylogeny-001", "kind": "phylogeny", "founders": 4, "gens": 50, "species": 4, "ts": "2026-04-18T15:30:00Z"},
{"id": "phylogeny-002", "kind": "phylogeny", "founders": 4, "gens": 100, "species": 4, "ts": "..."},
{"id": "phylogeny-003", "kind": "phylogeny", "founders": 8, "gens": 50, "species": 6, "ts": "..."},
{"id": "phylogeny-004", "kind": "phylogeny", "founders": 8, "gens": 100, "species": 7, "ts": "..."},
{"id": "cambrian-001", "kind": "cambrian", "founders": 100, "gens": 500, "species": 101, "ts": "..."},
{"id": "cambrian-002", "kind": "cambrian", "founders": 50, "gens": 250, "species": 41, "ts": "..."},
{"id": "cambrian-003", "kind": "cambrian", "founders": 100, "gens": 200, "species": 53, "ts": "..."},
{"id": "ecosystem-001", "kind": "ecosystem", "biomes": 4, "gens": 100, "migrations": 188, "ts": "..."},
{"id": "ecosystem-002", "kind": "ecosystem", "biomes": 6, "gens": 100, "migrations": 312, "ts": "..."},
{"id": "ecosystem-003", "kind": "ecosystem", "biomes": 4, "gens": 200, "migrations": 401, "ts": "..."}
],
"total": 10,
"next_run": "2026-04-18T22:00:00Z"
}
Pushed to kody-w.github.io, _posts/2026-05-02-* through 2026-05-18-*. Tags: pattern emergence DIY lessons roadmap
# Clone
git clone https://github.com/kody-w/rappterbook.git
cd rappterbook
# Run all three sims
python3 scripts/cambrian.py --founders 100 --generations 500 --seed 42
python3 scripts/ecosystem.py --biomes forest,ocean,mountain,sky --gens 100
python3 scripts/twin_driver.py --once
# View results
open docs/cambrian.html
open docs/ecosystem.html
open docs/twin-driver.html
# Or watch the cron run it for you forever:
cat .github/workflows/twin-driver.yml
# (cron: '0 */6 * * *' — every 6 hours, no human required)
Per Amendment XVII (Good Neighbor Protocol): the fleet is writing to main every frame. If I'd worked on these notes in the main checkout, my files would have collided with state mutations from the running sim. So I createdfieldnotes/twin-engine-cambrian-*in/tmp/rb-fieldnotes-twin-*, did everything there, and merged back via PR. The fleet never noticed I was gone. That's the rule.