Repository navigation
feat: heritable genomes and the lineage store (Phase 4, PR 4/5) - #100
Merged
Merged
Conversation
Phase 4 PR 4. Inheritance goes live. A child's genome is now built from both parents' genomes by recombination (blend crossover for continuous genes, per-block segment crossover for brain weights so both parents' brains contribute) followed by per-gene mutation, drawing only from the genetics stream. The copy-the-mother stand-in from the previous PR is removed. New LineageStore records every genome ever created and how they are related, and keeps each record after its organism dies: parents, ancestors, descendants, most recent common ancestor, founders, and lineage extinction, with traversals computed on demand. ReproductionSystem registers each child, DeathSystem marks deaths, World exposes it read-only as World.lineage, and World.validate() now also checks that every living genome has a lineage record naming the same parents and that those parents are still recorded. Lineage is a derived record and is not part of the state hash. Gates: - Mutation off reproduces Phase 3 exactly: all 53 full-state digests recorded from the pristine Phase 3 engine still match (children are blends of identical parent genes, and nothing reads a brain yet), and Scenario A's 26 active / 47 born / 21 starved is kept as a permanent test. - Stability with default mutation: four seeds over 50,000 ticks stay in a 17-40 population band with no extinction, every genome stays valid across roughly 650 births each, and trait means stay near baseline (no drift toward free-lunch extremes). The 50k-tick stability test holds unchanged. Behavior change, stated: mutation makes trajectories diverge, so three golden hashes (default-1k, scenario-a, long-run-100k) are regenerated; the three scenarios with no births are unchanged. Scenario A's default pins move to 25 active / 39 born / 14 starved, and the boom-then-bust extinction tick moves from 17,002 to 11,901, with that test's purpose (extinction stays permanent after reproduction has succeeded) intact. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fourth of five Phase 4 PRs. Inheritance goes live. This is the PR where simulated behavior changes, and it states that plainly.
geneticsstream. The copy-the-mother stand-in from feat: organisms carry genomes, behavior-preserving (Phase 4, PR 3/5) #99 is removed.LineageStore(new): records every genome ever created and how they are related, and keeps each record after its organism dies. Parents, ancestors, descendants, most recent common ancestor, founders, and lineage extinction; traversals anddescendantCountare computed on demand.ReproductionSystemregisters each child,DeathSystemmarks deaths, andWorldexposes it read-only asWorld.lineage. It is a derived record and is not part of the state hash.World.validate()now also checks that every living genome has a lineage record naming the same parents, and that those parents are still recorded (so a record genuinely survives its organism).The two gates
1. Mutation off reproduces Phase 3 exactly. With
mutationRateScale: 0every child is a blend of identical parent genes (only brains differ, and nothing reads a brain yet), so all 53 full-state digests recorded from the pristine Phase 3 engine still match, and Scenario A's original 26 active / 47 born / 21 starved is kept as a permanent test. So mutation is the only new force; recombination and lineage add no behavior of their own.2. Stability with default mutation. The risk named in the plan was that selection could drift genes toward free-lunch extremes (cheap metabolism, huge sensors) and inflate the population. Measured on four seeds over 50,000 ticks: population stays in a 17-40 band with no extinction, every genome stays valid across roughly 650 births each, and trait means stay near baseline (radius ~5, basal cost ~0.49, cooldown ~30). The existing 50k-tick stability test holds unchanged, so no defaults needed tuning.
Behavior changes (stated, not hidden)
default-1k,scenario-a-foraging-5k,long-run-100k. The three scenarios with no births (extinction, verbose events, zero population) are unchanged, which confirms the effect is confined to inheritance.Tests
424 simulation tests (up from 378): 30+
LineageStoreunit tests on a diamond ancestry (including a 500-generation chain), child-genome inheritance assertions per system, lineage-over-a-run world tests, and lineage invariants.Test plan
pnpm format:checkclean in a fresh clonepnpm checkgreen in a fresh clone: 7 contracts, 55 config, 424 simulationpnpm buildgreen (all 8 packages/apps)pnpm test:determinism: 17/17 on the final treeNext (final PR): genetics hardening, a Phase 4 exit-criteria sweep, and long-run checks with mutation active.
🤖 Generated with Claude Code