The simulation-aliveness-2 arc: live-play truth (LP-1…LP-14 + follow-ups) - #101
Merged
Conversation
… LP-1..LP-14 arc The deliverable of the in-browser observation pass (the live redo of task 117): P0 findings (save RangeError, dead live food loop, sporadic on-duty work, T-throttle movement/time desync, the 122 movedOut orphan), the systemic P1/P2 sweeps, the maintainer's M1-M5 observations validated (intra-tick cadence, reactive wakeups, physicalized job seeking, entity-linked logs) and the wake-trigger catalogue. Also ships the observation harness the session built: __townbox.debug() (the GameManager escape hatch, test mode only) and stepGame() (tick advancement interleaved with movement frames — plain stepTicks starves LiveWorld transitions). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… past on load Saving an asset-backed town threw 'RangeError: Invalid string length' in SaveManager.serialize: lazy hydration installs each drawn person's full pre-game asset history (~100k entries observed) into the live LifeLog, and the v8 save serialized the whole append-only table — 32 residents was enough to overflow JSON.stringify, and no such payload could ever fit localStorage anyway. The pre-game past is now a hydration-time view, never save payload: - LifeLog tracks a per-person LIVE floor seq, set when installPersonEntries installs a pre-game past (max installed seq + 1), with an idempotence guard (a second install for the same person is a no-op). load() resets the floors. - getLiveTable()/EventEngine.getLiveLog() expose the at/above-floor view, and SaveManager serializes THAT (eventLogSeq still spans the full history so re-installed seqs never collide). - GameManager.rehydratePersonLogs(): after a load, the pinned v14 hydration ref streams the hydrated people's pre-game logs back in (logs only — skills and the aggregate history are already in the save), fire-and-forget; a missing or regenerated asset degrades exactly like v14 always did. No save-version bump: the table shape is unchanged, snapshots just stop carrying the past. Guards: LifeLog floor/idempotence/round-trip tests (test/events) and a snapshot-content test (test/save) proven by the revert-dance (fails with the SaveManager hunk reverted). Part of the simulation-aliveness-2 arc (docs/proposals/simulation-aliveness-2.md). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four fixes that make live play honestly observable (proposal simulation-aliveness-2, P0-5 / P0-3a / P2-1 / P2-5): - Time-throttle movement desync (P0-5): Field.update now scales movement deltas by GameManager.getTimeScale() — the 117 T-throttle scaled the clock but moved people at 1x, so a 16x session made every commute consume 16x its in-game duration and silently degraded every arrival-gated loop (work starts, school runs, dispatch, collection rounds). Guarded by a delta-scaling test proven by the revert-dance. - Silent travel (P0-3a): a continuous instance en route logs a 'departed' lifecycle entry (once per instance, carrying the destination) — stuck or cancelled commutes used to leave zero trace, which is how people 'clocked out' of shifts they never reached with nothing to diagnose. A cancelled transition now blocks with a typed 'no_route' failureReason. Departures are travel, not commits: recency counting ignores them; hasAction (aggregate-based) was never affected. Departure entries are inherently live-only records (bootstrap transitions resolve instantly), and the live<->bootstrap equivalence suites stay green. - Travel labels (P2-1): activity bubbles now render for waiting_for_materialization as '→ <label>' — the street's most common visible state (going somewhere) was the one state never narrated. The 115 pet dot stays runs-only. - Double boot (P2-5): postSceneInit is idempotent — a duplicate sceneInitialized (observed: MainScene.create firing twice in one boot) used to rebuild every engine including a second full asset selection; it now warns and returns. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nt re-seek guard Two of the audit's cheapest/highest-yield fixes (proposal simulation-aliveness-2 P1-8): - health-scale bugs (8, not 1): manifest comparisons authored on a 0–100 scale against the 0–1 health attribute — spending_time_at_home 'health < 40' gave every person a permanent ×1.5 (likely the whole 117 'leads the fallback 2×' flag), sitting_in_park/visiting_beach/cleaning_house '< 25' always-true, exercising's healthy-boost '>= 70' NEVER fired, taking_a_walk '>= 60' never fired, and running_errands' pharmacy child '< 60' gated for everyone. All divided by 100, and the whole class is now an authoring error: the predicate validator rejects any |value| > 1 comparison on health (invalid fixture added; reverting the data fix makes the shipped-data validation fail — the guard bites). - receiving_treatment re-seek guard (the 117 balancing notes' #1 structural flag): the treatment hook re-proposed the moment a 4-tick session ended, so a sick person camped at the hospital in a rapid re-fire loop. One session per SEEK_COOLDOWN_TICKS (24 — mirroring the doctors' rounds cadence); between sessions the 092 rest behavior stands. Cooldown-lapse regression test proven by the revert-dance. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…aterialize across the hour) The architectural centerpiece of the aliveness-2 arc (proposal M1 / task 132). Decisions, RNG streams, ordering and state stay flip-resolved — nothing reads state between flips, so determinism, perf discipline and tick-boundary equivalence are untouched — but commits now carry a materialization MINUTE: - LifeLog.stampMinutes (TickRunner phase 10, both execution modes): every entry appended during a tick gets a deterministic intra-hour minute — a person's same-tick entries spread evenly across the 60 minutes with ±20%-of-slot jitter (the M1 spec), causation chains inherit their root's minute (a gift and its received-counterpart land together), and minutes stay monotonic per (person, hour). The CADENCE_SALT stream is isolated from every decision stream. Slot groups key by (person, tick) so stamp-batch boundaries can NEVER change a minute — proven by the streamed-vs-in-memory asset identity test, which caught exactly that: the generator's flush now runs BEFORE the day-cadence invokes (whose entries carry the next tick's timestamp) and the end-of-run tail is stamped explicitly in both paths. - Departure spreading (LiveWorld): commutes physically start at a deterministic minute within DEPART_JITTER_MINUTES (15) of the hour, pumped by the existing minute cadence with a later-tick catch-up — the whole-town :00 pulse dissolves; the bound keeps obligation arrivals from slipping a full hour. Minute-less pumps (tests, harnesses) depart immediately. - Surfaces: log entries carry a "minute" field (additive, optional — no save bump; old entries render :00); the inspector shows real minute timestamps (formatTickAtMinute); generator logs carry the same sub-hour texture, so the next asset regeneration gains minute-textured histories for free. Op-count perf baselines re-pinned (the LP-5 health-gate fixes legitimately shifted selection paths; the deterministic gate flagged it as designed). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Proposal simulation-aliveness-2 M2 / task 133. The Brain evaluated only on the
hourly flip, so world mutations between flips — a business opening under the
player's cursor, a closure, a bulldozed home — went unnoticed for up to an hour,
and data cooldowns (job_hunting's 24 ticks + the 2-day job_seeking routine)
stretched the non-reaction into days: the audit's town placed employers nobody
acknowledged.
- game/actions/Wakes.ts: a transient BrainWakeQueue of {kind, ids} records with
a per-kind cooldown-clear class (WAKE_CLEARS) — clearing job_hunting reopens
both the action cooldown and the routine cadence (both read one aggregate).
- Producers wired: businessOpened (setupBusiness; scope resolved at drain time
to the currently unemployed adults), businessClosed (the laid-off, captured at
closure), homeLost (demolished-house residents).
- City.runWakePass (drained on the minute cadence beside the LP-11 departure
pump): resolves scopes against the materialized roster, clears the wake kind's
recencies, and runs a bounded Brain pass for the woken people only — same
deps, same market wiring, same per-(tick, person) streams as the flip (jobOf
extracted to City.jobFactsOf, shared by both paths), log appends stamped
through the LP-11 pass. Deterministic given the mutation; the generator and
bootstrap never enqueue — wakes are an input channel, not a mode branch.
The wake-trigger catalogue's event-commit and analytic-threshold producers ride
later phases; this lands the queue, the drain, and the flagship world-mutation
producers.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Proposal simulation-aliveness-2 P0-3 / task 125. The audit measured 7 started_working against 40 stopped_working over 16 live days and a doctor who never visibly worked. A large slice of that was a DATA hole, not the commute: - 27 of 43 continuous work actions declared no lifecycle events at all — shifts starting through them fired no started_working (invisible in log and feed) and no stopped_working on completion (the day-progression seam, SkillProgression, only credits stopped_working — so whole worked days silently didn't count toward skills/promotion unless the automated fallback caught them). All 27 now wire onStart started_working + stopped_working on both exits. - started_working gains limit once-perDay (stopped_working already had it): the orchestrator rotates several work actions per shift, and every rotation pick used to re-fire the day's start. - treating_patient (person-targeted care DURING a shift, with its own 111 counterpart lifecycle) is exempt — the validator contract applies to shift wrappers only: any work-category continuous action without an interaction block must wire the full started/stopped set. Revert-dance proven (stashing the data fix fails the shipped-data validation). - The LP-3 keystone (test/execution/city.test.ts): a City-level live-mode scenario — real Brain + orchestrator + jobOf + LiveWorld commute — asserting an on-shift employee produces a work instance, logs the LP-2 departure, and fires started_working on physical arrival. Any break in that chain now fails a test instead of a playtest. Checked-diff docs regenerated (event-classification, simulation-relationships). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…olvency) Proposal simulation-aliveness-2 P0-2 / task 126. The audit found the live food loop structurally dead: homes generated a kitchen with one banana, the placed supermarket shelf held office props plus four food items, restocking_shelves produced NOTHING (no OAR entry — no grocery production chain existed at the object level), and with 113 having retired the conjuring fallback at real shops, half the town starved by day 10 while completing 169 ingredient-less cookings that fed nobody. Four fixes: - The pantry: every home-cooking recipe input (egg, flour, lettuce, tomato, potato, onion, bread, butter, cheese + milk/apple/banana/pasta) gains kitchen placement and a minPerBuilding guarantee — the same essentials mechanism that pins the stove. Fresh houses cook out of the box; supermarkets get guaranteed initial BUSINESS-OWNED stock through the identical mechanism. - The restock channel: restocking_shelves gains a stocked_the_shelves pool child whose new OAR entry (supermarket_restock) produces employer-owned staples at the workplace — bounded by the 089 per-archetype stock ceiling like every production recipe, so shelves refill under real clerk labor and never mound. - Honest satisfaction: cooking_meal / bake_cake / bake_bread / the spending_time_at_home wrapper no longer satisfy the food need — only genuine eating does (ate_a_meal 45, shared_a_meal 40, the eat children). Pantomime cooking stops reading as a meal. - The solvency floor (P1-5): an unaffordable retail purchase is a typed plan failure with zero mutations — balances stop drifting negative. Revert-dance proven. Checked-diff docs regenerated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Proposal simulation-aliveness-2 P1-1 / P1-7 / task 127. The audit's starving town held a median mood of 77: needs fed nothing but selection weights, so hunger at zero had no mood, health, or story consequence, eating was decoupled from food existing (ate_a_meal had no requirements and consumed nothing), and children — who can't shop or cook — starved independently of their employed parents. - foodLevel/restLevel context attributes (EventEngine reads the bound needs ledger; well-fed defaults keep market-less tests inert) join the closed vocabulary. - went_hungry / utterly_exhausted: wired probabilistic events hard-gated on the meters (< 10), once per day, valence −2/−1 — the needs→mood coupling rides the existing 091 valence machinery, zero new state. fell_ill gains a foodLevel factor (×2.5 starving → ×1 fed): starvation raises illness, illness lowers health, and the death event's existing health gradient closes the chain — emergent arithmetic, never a scripted penalty. - Honest eating: ate_a_meal requires carried food (meal/ingredient/snack tags) and CONSUMES the pantry through ordered OAR alternatives (bread, eggs, salad, potatoes, pasta, fruit) — so pantries drain, spoilage matters, and the shopping loop re-arms. The pre-LP-5 free meal is gone. - The family table (P1-7): a new satisfyNeed consequence op (scope coLocated, capped fan-out) + served_the_family (cooking_meal child, staple-consuming OAR alternatives) — the cook feeds everyone sharing the room; dependents eat because someone cooks for them. Op-count perf baselines re-pinned (intentional data-driven behavior shifts). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… fix, overlay persistence) Proposal simulation-aliveness-2 P1-3 + task 122 / task 128. Gestation (P1-3): pregnancy stops being an instant baby — - The pregnancy event is CONCEPTION: it sets the (previously dead-vocabulary) pregnant attribute, gates on not-already-pregnant, and keeps its partner bind, had_sex recency, wantsMoreChildren gate, and the thermostat hook. - gave_birth (new): scheduled via the automated queue nine in-game months after the conception commit (afterEvent +6480), gated on pregnant==true — it births, clears the state, and emits rehousingNeeded. A miscarriage (re-chained to the REAL pregnancy state, not the became_pregnant texture double, which goes dormant/manual-only) clears the state so the scheduled delivery rejects on its own eligibility — cancellation by gate, no queue surgery. - The fertility rate band now measures conceptions (the authored rate's actual subject); the hospital mortality cohort doubled (stream shifts moved a marginal seed one death from noise). Task 122: the movedOut producer restored (option b — one event, one story): moved_out_of_parents gates on canMoveOut and emits movedOut; City's existing resolveMoveOut consumer comes back to life. The generator coupling the ticket flagged is resolved deliberately: LogicalWorld supplies a standing-yes logical housing market (off-map housing is elastic by design). Guards: the signal-coverage CI test (every City-consumed signal must have a manifest producer — the 052-regeneration failure class, closed) proven by the revert-dance, plus a City-level EVENT-PATH regression (hot-rated fixture manifest through handleTick → relocation; no vacant house → gated silent). Overlay persistence (found en route): the setAttr attribute overlay (health/retired/depressed/pregnant) was never serialized — a sick person loaded healthy, a retiree loaded employable, and a 9-month pregnancy made the loss untenable. Additive eventOverlay save field, absent-loads-empty. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mething) Proposal simulation-aliveness-2 P1-2 / task 130 — the audit founding example: 95 uncollected curb bags accumulating with zero consequence beyond pixels. - computeSqualor (CityServices): uncollected curb bags per resident, clamped 0..1 — the coverage ledger OUTCOME sibling (staffing says who is employed; squalor says whether the trash actually left). The City daily services sweep counts the shared curb (the 112 "outside" location) and publishes the reading; absent readers (pure tests, the off-map generator whose curb is collected daily) read 0, at which every factor curve passes through 1. - A "squalor" context attribute joins the closed vocabulary, and the data consumes it three ways: fell_ill gains a squalor factor (x1 clean -> x2.2 at full squalor — a filthy town measurably sickens more people, proven by a seeded 60-person cohort test with the revert-dance), sick_of_the_filth (valence -1, once per day, gated >= 0.6) couples squalor to mood through the 091 valence machinery, and the cleaning repertoire (cleaning_the_sidewalk, picked_up_litter, took_out_the_trash) gains x2.5 weights when squalor >= 0.5 — a neglected town visibly pushes its people to clean. Op-count perf baselines re-pinned (new factor + event in the walk). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…at the counter) Proposal simulation-aliveness-2 M3 / task 134. Job seeking was a generic stroll: applications were abstract discretes committed mid-walk, bound to no business, and get_job stayed a free-floating probabilistic roll — the audit feed showed hires landing at 01:00-04:00 with nobody anywhere near a workplace. - JobMarket.bestOpeningKeyFor (optional on the market interface): the workplace key of the best reachable opening — apply where the market would actually place you. - The jobSeekingHook (Brain built-in, after the planner): unemployed adult + business hours (09-17) + a real opening -> a LOCATED application trip (applying_at_business, employer param + locationOverride), one per day, need band — beats leisure, yields to obligations and critical needs. The person physically walks/drives there under LP-11 departure spreading. - The counter-hire: applied_for_a_job (the trip child) gains onComplete -> get_job (manual trigger added; canBeHired gate and the JobMarket keep sole hiring authority) — the hire lands where and when the person applied, causation-chained to the application. The probabilistic get_job stays as the background/off-map channel: the logical market does not expose bestOpeningKeyFor, so the hook is silent off-map and the generator dynamics are untouched. - The ambulatory job_hunting stroll remains the no-openings seeking texture (asking around IS what seeking looks like) — no visible Idle either way. Covered by test/actions/jobSeekingHook.test.ts (proposal targeting, the night/no-opening/employed gates, and the counter-hire end to end). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ckable chips)
Proposal simulation-aliveness-2 M5 / task 135. Log entries have carried typed
entity params since the aliveness arcs (hugged_person {target: p37}, counterpart
{from}, the LP-2 departures' {destination}) — and the HUD threw them away:
event params rendered as raw '[with: p488]' suffixes, action params (where the
social targets live) not at all.
- hud/logEntities.ts: render-time resolution — a param id becomes a pool
person's full name (with the family-tree's † once its bearer dies, and the
materialized Person for the chip), a building key becomes the business name,
a location key prettifies, an archetype id becomes its authored label. Never
baked into the log: ids survive the asset re-identification.
- PersonDetails renders resolved chips for BOTH entry kinds; person chips
dispatch PersonSelected (the HouseDetails resident-click pattern), so
'Hugged a person [Ana Souza]' opens Ana. Departure entries name their real
destination business.
The remaining M5 layer — the full param-coverage data pass + {placeholder}
label templates across the corpus — rides the LP-7 content pass. HUD surface,
covered by the browser integration suite per the repo's testing split.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… trims) Proposal simulation-aliveness-2 P1-4 / task 129 — the audit-named offenders (the exhaustive 700-event catalogue pass remains the flagged content follow-up): - Work-named texture (worked_overtime, late_for_work, made_work_friend, injured_at_work, quit_job) gains the employed gate — no more overtime stories for unemployed sixteen-year-olds. The got_job texture double of the vital get_job goes dormant (manual-only, no deletion). - Dreams happen at night: had_nightmare / had_wonderful_dream gain an hourOfDay factor zeroing the waking hours (the audit caught a 19:00 nightmare). - spread_rumor free-rolled beside the REAL gossip system (shared_gossip pairs 63/63 in live play) — dormant until the C2 wiring gives it a true source. - had_surgery requires real recent medical trouble (fell_ill/injury within 30 days); adopted_child (an adoption that never produced a child) goes dormant. - Two kinship-derived attributes join the vocabulary: hasMinorChild (gates helped_with_homework, dog_ate_homework) and hasGrandchildren (gates spoiled_grandkids, taught_grandchild_to_fish — previously age-60-gated only). - Quirk-budget rate trims on the accident cluster the audit measured at one mishap every other day per person (fainted, concussion, allergic reaction, chili cookoff, dental filling, terrible day, laughed-until-it-hurt). Gates proven by the revert-dance; docs regenerated; perf baselines re-pinned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…th fixes it caught) - LP-9 (asset social rebalance, the defensible slice): a wedding now settles the couple OTHER romances — dangling dating/engaged edges demote to ex_partner (the audit asset carried ~4.7 dating edges per drawn person because off-map marriages never closed them; marriage gains a manual trigger for the test path). Rival half-life 200 → 60 days: grudges fade in months, not years (the asset held 224 rival edges against 19 friendships). The full generator edge- dynamics decode audit + regeneration remain the flagged follow-up. - LP-10: School joins the construction menu — the nagbar scolded about school seats while the menu could only gamble on generic lots. - The fed-week keystone (test/execution/alivenessTwoArcs.test.ts): a full hourly week over the REAL manifests + a really generated house — real meals, honestly depleted pantry, the food meter alive all week, hunger-events bounded. It immediately caught three real defects in the LP-4/5 meal path: (1) the pantry fetch took ingredient-TAGGED items only (bread is meal-tagged — never fetchable) alphabetically (butter first), matching no consumption alternative; it now prefers the MEAL_CONSUMABLES staples and falls back to any cooking ingredient. (2) with wrapper satisfaction removed, NO continuous action satisfied food, so critical hunger could only propose coffee — the needs hook now proposes ate_a_meal directly when food is in hand, and cooking_meal keeps a small grazing credit (10) so cooking stays a proposable answer. (3) the consumption alternatives widened (banana, granola bar, cheese) so nobody deadlocks holding food the meal machinery cannot eat. Op-count perf baselines re-pinned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…roposal status v2 - CLAUDE.md gains §4.16 (the LP-1…LP-14 engine changes: intra-tick cadence, reactive wakes, live-truth save/overlay/throttle fixes, the workday contract, food/needs truth, gestation, squalor, physicalized employment, entity-linked logs) and the 122 producer references are corrected (moved_out_of_parents + the signal-coverage guard). - Task 122 renamed _DONE with its landing note; docs/tasks/README.md marked. - The proposal's status header records the implementation and the flagged follow-ups (the exhaustive texture catalogue, label templates, the generator decode audit + regeneration, family-tree/skills polish). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…oss the interaction corpus)
The remaining M5 layer. Labels gain {placeholder} template syntax resolved at
render time — "Hugged {target}" renders "Hugged Ana Souza" with the name
clickable inline; unreferenced params still append as chips, so untemplated
labels degrade to the layer-2 rendering unchanged.
- hud/logEntities.renderLabelSegments: split-and-substitute into segments with
the resolved param attached (pure; unit-tested); PersonDetails renders
segments with inline person chips.
- Validators (actions + events): every {placeholder} must name a declared
parameter — a typo would render as a bare word forever. Invalid fixtures.
- The authored pass: all 34 person/object-parameterized actions (the social
repertoire, the generic object verbs, the application trip) and 18
parameterized events (counterparts, the object_* family, the justice/visit
set) carry natural-language templates now.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ts audited and enforced) The full P1-4 pass over the corpus (the earlier slice covered the audit-named offenders; this closes the catalogue): - Curated gates (35 flagged, all resolved): school texture bound to the 7–17 band (detention for adults, closed), driving texture to driver ages with once-ever milestones (first car, license, first crush), came_out_of_retirement requires retired, downshift/career-switch require employed, the-talk requires a minor child, graduated_nursing_school chains to the REAL nursing_school, crushes require being unmarried, get-off-my-lawn requires being 55. - Texture doubles dormant: got_married and retired (duplicating the vital marriage/retirement stories) join got_job/spread_rumor/adopted_child. - C2 completed: ten WIRED events that still free-rolled beside their real producers (tried_new_recipe — the starving audit town #1 event — plus graduated_school, learned_new_skill, went_grocery_shopping, planted_garden, hosted_dinner_party, decluttered_house, finished_great_book, found_money_on_street, reconnected_with_relative) lose the probabilistic trigger; the producer is the only true source now. - Valence completion: +51 keyword-clear ±1 assignments over the previously valence-less texture pool (neutral stays absent by design). - The quirk budget: 460 deliberately-kept free-rollers carry an explicit quirk marker (new schema field, validated true-or-absent; a Quirk column joins the generated classification doc), and the pool aggregate hazard is budgeted at ~49/yr — one whimsy per person per ~7 days, down from the audit-measured one-per-2-days. A CI guard pins both invariants: every ungated free-roller must be a marked quirk, and the aggregate stays ≤ 60/yr. Docs regenerated; perf baselines re-pinned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nogamy The generator-side follow-up, closed. Decoded the committed asset social graph (28,642 edges, ~250 living) and recorded the findings of record in the proposal (Part 7) as the pinned baseline for the post-regeneration re-measure: - Rivals outnumbered friendships 49:1 (3,412 vs 70) because hostility was a one-shot mint: any argument driving a near-stranger acquaintance (avg strength 4.8, argue delta −8) to zero flipped it to a rival seeded at 15 — a months-long feud from one spat — while friendship needed slow accumulation to 30 against decay. Tunes: hostility seeds at 6 (weak grudges fade in ~9 months unless fed; the existing rival sign inversion still heats them), promoteAt 30→22 and 65→55, acquaintance half-life 120→150 days (with the earlier rival half-life 200→60). - 1,172 standing dating edges (~4.7 per living person): a consented ask seeded a new romance and nothing closed the others. Dating is now EXCLUSIVE at formation — the adjustRelationship consequence demotes both parties other dating/engaged edges to ex_partner (with the earlier weddings-settle fix). Revert-danced regression in romanceArc.test.ts. - The 23.9k acquaintance carpet was diagnosed HEALTHY (avg 82 days since touch = actively maintained weak ties) — pruneBelow stays 0.25; a raise to 2 was tried and reverted (it made small-delta edge formation impossible). Graph config-pinning tests updated to the authored numbers; perf re-pinned. The regeneration itself remains the maintainer pre-merge run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d skills panel The last flagged follow-up. Proposal status → v3 (everything but the maintainer's asset regeneration is in). - Family tree: the graph builder's BFS now carries a GENERATION level (subjects 0, parents −1, children +1; spouses/siblings share their anchor's row — unit-tested through three generations), and the renderer pins each level to its own horizontal row (a strong per-node forceY), leaving the force sim to spread within rows. Dense asset genealogies rendered as an unreadable force-directed hairball before; now they read as generations at a glance. Legacy builders without levels fall back to the old centring. - Skills panel: the ~70-row flat wall becomes top-8 abilities + a collapsible tail + the (mostly-60.0) school basics folded into their own details group. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ines The maintainer's pre-merge regeneration (npm run generate-history, default flags): the asset now carries the arc's whole texture — minute-stamped log entries (LP-11), gestation-real pregnancies (LP-6), the workday lifecycle (LP-3), the coherence-gated + quirk-budgeted texture corpus (LP-7), and the rebalanced social dynamics (LP-9). The Part 7 re-measure (recorded in the proposal) validates the LP-9 fixes on 27,903 edges: dating 1,172 → 37 (serial monogamy + weddings-settle; 3,633 ex_partner edges carry the settled history), rivals 3,412 → 1,377 at avg strength 4.2, friendships tripled (friend 70 → 203, close_friend 39 → 70) — the rival:friend ratio moved from 49:1 to ~5:1. Co-Authored-By: Claude Fable 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.
The simulation-aliveness-2 arc: the live-play truth pass. Where rounds 080–118 made the engines feed each other (validated headless), this arc makes the map feed them — driven by a full in-browser observation audit whose findings, evidence, and traceability live in
docs/proposals/simulation-aliveness-2.md(now at v3, implemented).What's in here (20 commits, LP-1…LP-14 + follow-ups)
P0 live-play breakers, fixed:
RangeErrorfrom serializing 100k-entry hydrated pasts): saves now carry live-era entries only; the past re-hydrates from the asset on load.departedentries; cancelled transitions carryno_route; travel gets "→" bubbles; the double scene-init is guarded;debug()/stepGame()harness keepers.satisfyNeedhousehold meals, and the fed-week keystone (which caught three defects in its own feature before any human could).BrainWakequeue (a placed business wakes the unemployed at the next minute), and physicalized employment (apply at the door, hired at the counter — no more 3 AM hires).The follow-up wave:
{placeholder}label templates across the interaction corpus (validator-enforced).Verification
Remaining before merge
The maintainer's asset regeneration (
npm run generate-history) — gestation, minute stamping, and the romance changes moved the RNG streams; proposal Part 7 holds the baseline numbers for the re-measure.🤖 Generated with Claude Code