Repository navigation
feat: organisms carry genomes, behavior-preserving (Phase 4, PR 3/5) - #99
Merged
Merged
Conversation
Phase 4 PR 3. Every organism now owns an immutable genome, and every trait a system reads comes from it instead of global config. Founders get identical genomes built from the config baseline (each with its own random brain from the genetics stream); a child gets a new GenomeId and, for now, a copy of its mother's (the lower-id parent's) genes and brain. Recombination and mutation are switched on in the next PR. Movement, Interaction, Metabolism, Perception, Decision, Death and Reproduction read the organism's own genes. Capability is coupled to cost through derived traits (organisms/traits.ts): energy capacity and basal cost scale with body size, sensor cost with sensor radius, and a parent pays its own investment plus overhead. Reproduction also requires energy >= max(minEnergy gene, cost), so paying can never drive energy negative. At the baseline genome every derived value equals its Phase 3 value exactly. genomeId is added to the snapshot, birth event and history record; World.genomeOf returns the frozen genome; snapshot radius is the organism's own gene. World.validate() now checks every living genome against the gene table and brain architecture and that genome ids are unique. Spatial grid cell sizes become the gene range maximum. DeathSystem and PerceptionSystem lose their now-unused config parameter. Hash schema v3 (nextGenomeId plus each organism's genome); published hash vectors and all golden hashes are regenerated, and stream-usage drops genetics from the reserved list. The golden values change only because the schema did. Equivalence gate: world.test.ts (the pinned Phase 3 scenarios) is byte-identical and passes. Beyond that, 53 full-state digests (every organism's position, energy, age and cooldown, plus the complete event lists) recorded from the pristine Phase 3 engine match the refactored engine exactly across 7 scenarios, including custom baselines, up to 20,000 ticks. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 tasks done
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
Third of five Phase 4 PRs (design in #97, engine in #98). Every organism now owns an immutable genome, and every trait a system reads comes from it instead of global config. Simulated behavior is unchanged from Phase 3, which is the point of this PR: it lets the change be reviewed as "nothing moved" before PR 4 turns inheritance on.
geneticsstream.GenomeIdand, for now, a copy of their mother's (the lower-id parent's) genes and brain. Recombination, mutation and lineage arrive in PR 4.maxSpeed,maxTurnRate, life-stage ages), Interaction (radius), Metabolism (cost genes), Perception (sensorRadius), Decision (wanderJitter), Death (maxAge), Reproduction (minEnergy,offspringInvestment,cooldown,searchRadius).organisms/traits.ts): energy capacity and basal cost scale with body size, sensor cost with sensor radius, and a parent pays its own investment plus overhead. Reproduction also requiresenergy >= max(minEnergy, cost), so paying can never drive energy negative.genomeIdonOrganismSnapshot,OrganismBornEventandHistoricalOrganismRecord;World.genomeOf(organismId)returns the deeply frozen genome; snapshotradiusis the organism's own gene.World.validate()now checks every living genome against the gene table and brain architecture, and that genome ids are unique.DeathSystemandPerceptionSystemlose their now-unusedconfigparameter. Spatial grid cell sizes become the gene range maximum (queries are correct for any cell size; this only affects efficiency).The equivalence gate
Two independent checks that nothing moved:
world.test.ts(the pinned Phase 3 scenarios: Scenario A 26/47/21, extinction at tick 845, Scenario C, the 50k-tick stability band) is byte-identical tomainand passes.main) match the refactored engine exactly. Each digest covers every organism's position, velocity, energy, age and cooldown, plus the complete event lists, across 7 scenarios (default, Scenario A/B/C, verbose events, a 20,000-tick run, and custom baselines that exercise every gene plumbing) sampled at regular intervals up to 20,000 ticks. Re-run on the final tree: still 53 of 53.Hash schema v3 and goldens
HASH_SCHEMA_VERSION2 -> 3 (nextGenomeIdplus each organism's genome). The publishedStateHashervectors and all six golden hashes are regenerated. The golden values change only because the schema did, not because behavior did, which is what the gate above proves.stream-usage.test.tsdropsgeneticsfrom the reserved list since founders draw their brains from it.Tests
378 simulation tests (up from 326). New: gene-driven behavior per system (two organisms under the same config behave differently when their genes differ), derived-trait exactness at baseline and scaling, world-level genome wiring, and genome invariants. The existing system tests derive each organism's genome from the test's own config via a shared helper.
Test plan
pnpm format:checkclean in a fresh clonepnpm checkgreen in a fresh clone: 7 contracts, 55 config, 378 simulationpnpm buildgreen (all 8 packages/apps)pnpm test:determinism: 17/17 against the regenerated v3 goldensNext: PR 4 switches on recombination and mutation, registers lineage, and adds the stability gate (the 50k-tick band must still hold with default mutation).
🤖 Generated with Claude Code