Skip to content

The simulation-aliveness-3 arc: W0-W10 — a healthy steady state, answerable failures, scenes that read - #102

Merged
Maudfer merged 25 commits into
mainfrom
task/simulation-aliveness-3
Jul 19, 2026
Merged

The simulation-aliveness-3 arc: W0-W10 — a healthy steady state, answerable failures, scenes that read#102
Maudfer merged 25 commits into
mainfrom
task/simulation-aliveness-3

Conversation

@Maudfer

@Maudfer Maudfer commented Jul 19, 2026

Copy link
Copy Markdown
Owner

The aliveness-3 player-experience arc (W0–W10), one PR per the maintainer's bundling rule. Proposal + findings + re-measure evidence: docs/proposals/simulation-aliveness-3-audit.md; engine narrative: CLAUDE.md §4.17. Theme: a healthy steady state, answerable failures, and scenes that read — the month-long observed town was a chronic-famine, garbage-saturated, mood-collapsed place nobody could fix; this arc closes that loop.

The workstreams (sequential commits)

  • W0 — the food chain, for real: per-item-optional purchase baskets (+ a basket that buys nothing still fails typed), the purchase-sustainability validator (both directions), demand-scale restock, logged consequence-plan failures (rate-limited inputs_unavailable), the hunger→shopping producer, the adjustMoney debit floor with running planned-spend, empty-draw announcements, per-window HUD error boundaries.
  • W8 — sprite & travel truth: the commute vehicle lifecycle owned by the transition (cancelTransition, abortTravel, the setVehicle guard — the audit counted 148 orphaned cars in 32 days), the spawn/despawn sprite race closed, leaving a building clears currentBuilding, label merge ×N + stagger, auditSprites() as the standing invariant read.
  • W9 — construction & demolition UX: bulldoze anchor-resolve (no more ghost buildings) + grass ghost preview, physical ejection onto the connected street, the looking_for_a_home ambulatory wired to recovery-at-the-door, 1.5-tile snap capture, tool reset to Select after building placement.
  • W1 — the labor answer: front-line-first hiring (the audit's town made 14 of 24 people "Manager"), the critical-service boost, and migration (full employment + real openings + a vacant home → one household draw/day).
  • W2 — venues people go to: 8 venue kinds mapped, 7 located repertoires with real spending (eating out, cinema, gym, library, church, salon, fresh-bread runs), opening hours derived from staffed shifts (live-only), new routines.
  • W3 — scenes, not events: full-duration interrupts record completions (sleep finally completes), work→work handovers (no phantom clock-outs), the arrest interrupts the officer's leisure, the aftershock dampener.
  • W4 — household truth 2: household-unit rehousing, retirement gates on job seeking + retiree repertoire, conception rides had_sex (background hazard demoted), wedding kin fan-out, move-out cooldown 2y.
  • W5 — the visible street: curb bags render, side-by-side formation walking (render-layer offsets; the chase pair aliases as one scene).
  • W7 — observation keepers: build(blueprintKey), hireAs, forceEvent, selectPerson; avaiableJobsavailableJobs.
  • W10 — first-class time control: ONE authoritative frame transform (hitch-capped, pause-zeroed) consumed by both clock and movement, the pause/1×/4×/8× HUD toolbar, the composed contract pinned by timeConsistency.test.ts.
  • W6 — generator re-pin + the regenerated asset (v137.0): the abstract-encounter chase discount, standing-priced askFirst proposals, the conception channel now respects the population thermostat (the pre-fix run compounded 335→490 living against the 250 target), and a 16GB heap for generate-history (the hot band OOM'd node's 4GB default — no aliveness-3 regeneration had ever completed).

The post-arc live-found wave (fresh-game verification)

A maintainer fresh-game session surfaced sprites popping visible "on the house" and sprites stuck at houses during outdoor actions. Root-caused live and fixed (audit doc Appendix B.1): placement never set currentBuilding (ghost commutes to the house you're already inside + located-action deadlocks — healed via a physical-containment arrival fallback, set at all placement sites, re-derived on load), unclamped walk() steps (overshoot-oscillation at 4×/8× frame deltas — a walker frozen 1px from his car for 21 sim-hours), the wander commit-before-path-check freeze, and doorstep parking (stepOutside() lands on the curb now).

Evidence

  • Live re-measure on the audit's exact town (Appendix B): sprite invariants all-zero for the whole run, the town staffs itself (1 Manager vs 14), groceries purchased daily (was 0 for 28 days), blocked venue trips 0 (was 166), sleep completes.
  • Asset decode vs baselines (the asset commit message carries the numbers): population flat around target across 120y, cooking:eating 14:1 → ~2:1, sleep 8h and completing in the hot band, the median justice profile 9 attempts → 2 caught → 1 term (was 15 → 12 → 11), hug-ask volume down ~12×, venue life in every decoded biography.
  • Full suite: 1,932 tests / 168 suites green; typecheck + lint clean; perf gates green; every bug fix revert-danced.

Flagged follow-ups (documented in the audit doc): the location-less-actions data pass (people idle wherever the body is stranded — needs a home-location pass, deferred because it perturbs generator streams), and the habitual-criminal tail (one decoded life with 23 jail terms — the crime-habit escalation loop wants a cooling tune).

🤖 Generated with Claude Code

Maudfer and others added 25 commits July 18, 2026 17:35
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… failures)

The aliveness-3 P0 wave (docs/proposals/simulation-aliveness-3-audit.md):

- P0-1a: purchase baskets are per-item-optional — 'buy what's there' instead of
  all-or-nothing (the cream_jar bug starved live towns); a basket that buys
  NOTHING still fails typed.
- P0-1b: purchase-sustainability validator — every food purchase query must be
  restocked (OAR location output) or placement-seeded; granola_bar/cream_jar
  joined supermarket_restock, quantities raised to demand scale.
- P0-1d: unplannable consequence commits now LOG (failed: inputs_unavailable,
  rate-limited per person/action/24 ticks) and count toward recency.
- P0-1e: the hunger→shopping producer — critical food with nothing edible in
  hand or at the location proposes the located shopping trip.
- P0-1f: went_grocery_shopping fires from bought_groceries, not trip completion.
- P1-8: the adjustMoney debit floor + running planned-spend across a commit —
  balances can no longer drift negative through micro-flows.
- P0-4: an empty household draw announces itself in the feed.
- P0-5: per-window HUD error boundaries — a crashed inspector closes with a
  toast instead of unmounting the whole HUD.
- Staple generation raised (shelves and pantries seed at grocery scale).

Tests: basket/floor/logging suite in marketEndToEnd (revert-dance verified:
3 fail with the fix stashed), the hunger→shop producer in needs.test, the
sustainability-validator fixtures, atomicity tests updated to the new logging
contract, fed-week recast to bounded-flux, docs + perf baselines re-pinned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…wn race, coherent aborts)

The visuals-debug pass (proposal simulation-aliveness-3, workstream W8):

- P0-2.1: mid-flight re-plans never orphan cars — setVehicle despawns any
  live link (occupant cleared, no phantom drivers); the audit counted 148
  stranded vehicles in 32 in-game days.
- P0-2.2: the spawn/despawn sprite race closed for vehicles AND people —
  a removed entity destroys any late-attaching sprite (markRemoved +
  setAsset self-destroy) instead of ghosting outside the lists.
- P0-2.3: coherent travel aborts — WorldAdapter.cancelTransition (optional;
  live-only), called by the engine whenever a pending handle's intent dies
  (interrupt/pause/block/finish): the body parks where it stands, a boarded
  person steps out visible at the car, the car despawns. LiveWorld's pump
  also aborts travel when a destination vanishes mid-flight.
- The false-instant-arrival hole: leaving a building now CLEARS
  currentBuilding, so a return trip requested mid-street can no longer
  resolve 'arrived' while the sprite stands on the road.
- Belt-and-suspenders: a minute-cadence orphan sweep in City (controlled,
  unlinked cars despawn; debug wander cars untouched).
- W8d: TestHarness.auditSprites() — the standing sprite-vs-state invariant
  read (orphan/occupied-driverless/visible-indoors counters).
- W8e: activity-label collision pass — identical co-located labels merge
  into one '×N'; distinct labels stagger vertically instead of over-inking.

Tests: 4 new commute-suite cases (re-plan leak, cancelTransition, boarded
abort, the cleared-currentBuilding false-arrival guard); full suite green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n, home seeking, soft snap)

Workstream W9 (proposal simulation-aliveness-3):

- P0-6 bulldoze truth: the bulldozer resolves any clicked cell to the
  occupying structure's ANCHOR and stamps soil across its whole footprint —
  off-anchor clicks used to leave ghost buildings (sprite standing,
  household/business already destroyed). The bulldoze cursor now shows the
  grass ghost preview like every other tool (toolAssets 'bulldoze').
- P1-11 physical ejection: demolition (house AND workplace) steps everyone
  inside — and everyone traveling TOWARD the doomed building — out onto the
  connected street, visible, travel coherently aborted. The hidden-homeless
  flow is retired: displaced people stay on the map.
- P1-11 home seeking: the new looking_for_a_home ambulatory action (parity
  with job_hunting — street presence, bubble, asked_about_a_vacancy child),
  enqueued daily per homeless adult via the agenda (routineId dedup), whose
  looked_for_housing commit triggers the recovery attempt AT THE DOOR
  (tryRecoverHousehold extracted from the monthly sweep; attemptRecoveryFor).
- W9c much softer snapping: buildings capture the cursor only within 1.5
  tiles (was a 4-tile yank); beyond that the preview is honestly invalid.
- W9d one click, one building: a successful house/work placement returns
  the cursor to Select (bus-synced with the toolbar); roads and the
  bulldozer keep drag-painting.

Tests: off-anchor bulldoze full teardown, visible ejection, the seek→recover
loop, capture-gate + bulldoze-anchor placement cases; eviction tests updated
to the visible-homeless contract; reachability list gains the agenda
producer. Full suite green (1904).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ost, migration)

Workstream W1 (proposal simulation-aliveness-3 P0-3, the Manager-magnet fix):

- Front-line-first hiring: JobMarket's per-workplace pick now prefers the
  ROLE with the most unfilled slots (fit breaks ties within a role), and
  Workplace.hire fills the market's CHOSEN position instead of the
  first-fit walk that made 14 of 24 townspeople 'Manager' in the audit.
- The critical-service boost: businesses whose coverage line sits below
  neutral (services.json facilityBlueprints, derived daily by City) get a
  decisive cross-workplace score boost — the town staffs its hospital,
  police, fire, and sanitation before its third gym clerk.
- Migration, the labor inflow: when every materialized adult is employed,
  ≥3 real openings remain, and a fully-vacant home stands, City draws ONE
  household into it per day through the normal setupHousehold path
  (hydration + career retcons included) with a feed announcement.
  Self-limiting: arrivals are unemployed, which blocks the next draw until
  the market absorbs them. Voluntary job switching stays a documented
  deferral.

Tests: front-line-first + critical-boost cases in the JobMarket suite; the
four migration gates (draw / locals-first / not-a-shortage / no-home) in a
new execution suite. Full suite green (1910).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…money sink)

Workstream W2 (proposal simulation-aliveness-3 P1-1/P1-2/P1-8):

- The venue desert closed: venues.json maps restaurant, cafe, bakery,
  cinema, gym(+sports_complex), library, church, and salon; new located
  continuous repertoires with real spending (eating_out with ordered_a_meal
  −22 and a tip, night_at_the_cinema, working_out_at_the_gym,
  reading_at_the_library, attending_a_service, pampering_at_the_salon —
  hygiene finally has a venue — and the morning fresh_bread_run buying the
  bakery's real bread). catching_up_over_coffee moves to the café where it
  always belonged (the asset audit found it was every life's #1 social
  outlet AT A SUPERMARKET). All carry the 095 depressed dampener.
- Opening hours (P1-2): a venue is open only while an employee is ON SHIFT
  (derived from authored shifts; no new data) — hasVenue and venue
  resolution skip dark shops, ending the audit's 2 AM shopping trips.
  Live-only; bootstrap venues stay abstract (the sanctioned seam).
- Routines: gym_habit, weekly_service, dinner_out (money-gated) — the
  mid-frequency layer that makes venue life habitual, plus the money sink
  live play lacked.
- Fixed in passing: a latent LP-11/121 streamed-asset divergence — the
  generator's outcome-pass appends (adoptions, counterparts, cohabitation)
  drained to disk minute-less when a flush boundary landed between; both
  paths now stamp after the outcome invokes (batch-insensitive by the
  (person, tick) group rule).

Tests: opening-hours cases (unstaffed = closed, off-shift = closed, on
shift opens); venue fixtures staff their shops; the fed-week meal filter
counts restaurant meals; reactions fixture pins co-location. Docs + perf
baselines re-pinned. Full suite green (1912).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…he aftershock)

Workstream W3 (proposal simulation-aliveness-3 P1-3):

- Natural conclusions: interrupting an instance that already ran its FULL
  duration records a COMPLETION (onComplete fires) — the audit's
  every-morning 'sleep interrupted' (26 starts / 27 interrupted / 0
  completed) was the wake-up obligation winning arbitration in the very
  tick sleep would have completed; biographies read as chronic sleep
  disruption. Mid-duration displacement stays an interruption.
- Work→work HANDOVERS: a same-shift task switch (the doctor turning from
  her charts to a patient) no longer fires stopped_working — the Brain
  flags work→work replacements and the engine suppresses the lifecycle
  events while still logging the instance transition. Real exits (shift
  end, sickness, leisure displacement) fire it as before, so the
  SkillProgression day credit keeps its once-per-day close.
- The officer's side of the arrest: the arrest ceremony now interrupts the
  arresting officer's NON-work activity first (the audit watched an arrest
  land mid-coffee-date without the date pausing); on-duty work keeps
  running — arresting IS the job.
- The aftershock (P1-3c): a fresh high-shock event (was_arrested,
  got_caught, lost_home_to_fire, escaped_a_fire — json/arbitration.json,
  validated) dampens OUTGOING social/leisure free-time weights ×0.25 for 12
  ticks; home/maintenance keep theirs, so the bias reads as lying low, not
  paralysis.

Tests: full-duration-completes + mid-duration-interrupts, the handover
suppression vs the real clock-out, and the aftershock cohort comparison.
Full suite green (1916).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tion, the wedding)

Workstream W4 (proposal simulation-aliveness-3 P1-4/P1-5/P1-6/P1-10):

- Household-unit rehousing (P1-4): displacement offers the WHOLE living
  group to a relative with room for everyone before any per-member split —
  the audit's fire rehoused the wife with kin and left her partner
  homeless at the supermarket. Fallback stays per-member when no host fits
  them all.
- Retirement is real (P1-5): job_hunting (the action AND the routine)
  gates on retired == false and age < 68 — the audit watched a
  seriously-ill 75-year-old get hired off a morning application. Retirees
  gravitate to the park/hobby/walks (retired ×1.6 selection boosts).
- Conception rides intimacy (P1-6): a had_sex commit rolls a seeded 10%
  conception chance and INVOKES the real pregnancy event on the would-be
  mother — whose own eligibility (recent intimacy, married,
  wantsMoreChildren, not pregnant) keeps the last word. Shared by City
  (live) and LogicalWorld (off-map): one salt, identical both sides. The
  background probabilistic hazard demotes 0.6 → 0.15.
- The wedding is a family scene: partnershipFormed fans out a new
  attended_a_wedding milestone (+2 valence) to both spouses' close kin.
- moved_out_of_parents cooldown 60d → 2y (P1-10): the jail-cycle replay
  that produced 8 move-outs in one asset life reads absurd no more.

Tests: the never-split couple rehousing case; the conception suite (from
either subject, eligibility last word, pinned chance). Perf baselines
re-pinned (conception rolls joined the spine). Full suite green (1920).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rmations)

Workstream W5 (proposal simulation-aliveness-3 P1-7 / Part 5.3):

- Curb-bag piles: the town's uncollected curb bags finally RENDER — small
  brown mounds at the street side of occupied homes, growing with neglect.
  The sim's curb pool is one shared 'outside' location (the 112 collection
  contract), so per-house attribution is a documented display
  approximation (round-robin across occupied homes). Squalor 1.0 looks
  like squalor instead of a pristine street with a nagbar.
- Side-by-side formations: co-located people running the SAME activity —
  a couple's walk, coworkers, and the chase pair (fleeing↔chasing alias
  as one scene) — draw with small lateral offsets by stable slot index.
  Render-layer only: logical positions stay canonical; refreshed per
  in-game minute, applied in the person redraw closure.
- The squalor→cleaning selection loop was verified already bound (LP-8
  modifiers present on the cleaning set) — no change needed.

Scene-layer changes (excluded from the Jest coverage gate per the repo
convention; the Playwright browser suite covers the render glue). Full
suite green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Event, safe selection)

Workstream W7 (proposal simulation-aliveness-3 Part 5.6): the seams every
observation/scenario session monkey-patched by hand, promoted to the
TestHarness API:

- build(tool, row, col, blueprintKey?) — pinned civic placement through
  the same tileClicked path a construction-menu pick takes (placeholder
  texture included; the audit session's black-square foot-gun closed).
- hireAs(personId, workplaceKey, title) — a REAL hire into a chosen
  position (WorkLife set, slot consumed) for forced-staffing scenarios.
- forceEvent(eventId, personId, params?) — EventEngine.invoke with the
  live state/clock plumbed; one call to make someone fall ill or adopt.
- selectPerson(personId) — the payload-safe PersonSelected dispatch (a
  hand-built payload once unmounted the whole HUD).
- Workplace.avaiableJobs → availableJobs (the Part-5.7 grep-hostile typo).

The P1-9 live-map school-attendance keystone stays deferred to W10's
speed-invariance suite (arrival-rate assertions belong with the
distortion-free time contract they measure under).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, distortion-free)

Workstream W10 (proposal simulation-aliveness-3), the arc closer:

- One authoritative frame transform: effectiveFrameDelta(raw, scale) —
  hitch-capped (MAX_FRAME_DELTA_MS=100: a 5s hang is lost wall time, never
  a sim leap) and pause-zeroed. GameManager.advanceTime AND Field.update
  both consume it, so the clock and movement can never diverge, and a
  stall stalls everything together.
- The shipped ladder is pause(0)/1x/4x/8x (was the debug 1x/4x/16x). The
  setTimeScale/timeScaleChanged bus pair keeps every setter (HUD, debug T
  key) and every surface (toolbar highlight, debug overlay, fire particle
  emitters — which now speed up and freeze with the world) in sync.
- The time HUD: a floating top-right toolbar — Pause / Play / double- /
  triple-chevron — active speed highlighted; talks to the game only
  through the bus (§4.9). No masterSwitch gate: this is a player control.
- Tests: the effectiveFrameDelta contract (scale/cap/pause), ladder
  cycling, schedule-equivalence at the util level, AND the composed
  contract — equal SIM time at 1x/4x/8x lands a walking commuter at the
  IDENTICAL position with the IDENTICAL clock; a 5s hitch advances both by
  exactly the cap; pause moves nothing. The LP-2 field test migrated to
  the new one-authority stub.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…g, version bump)

Workstream W6 (proposal simulation-aliveness-3 Part 4):

- The abstract-encounter chase discount (Part 4.2): off-map co-location is
  a shared abstract venue, so officer-meets-suspect fired constantly and
  the decoded asset showed 12 catches in 15 petty crimes — 11 jail terms
  in 27 years, ate_prison_food ×678. LogicalWorld's chase resolution keeps
  City's catch formula but discounts the final chance ×0.4, restoring
  live-like CUMULATIVE odds (impunity and recidivism get room to breathe).
- AskFirst social pricing (Part 4.4): the social hook now prices intimacy
  proposals by the SAME standing the target's consent policy reads —
  strong/kin bonds full weight, strangers ×~0.2, rivals ×0.05. The
  asset's ~39% lifetime hug-decline rate (1,142 rejected hugs across 30
  lifetimes) came from under-priced proposals; the frequency-band test now
  pins the new regime (strangers barely ask; casual no-consent socials
  keep the cadence).
- Part 4.1/4.3 (cooking:eating, illness cadence) ride the W0/W3/W4 fixes
  organically — the regeneration re-measures them.
- HISTORY_GENERATOR_VERSION 121.0 → 136.0 (the arc's stream shifts).

Full suite green (1925); perf op-count baselines re-pinned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…proposal status v2

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d-venue choke guard

Found by running the arc against the audit's exact civic town in the
browser (the fed-town keystone, live):

- The basket now spans the FULL grocery restock set (milk, pasta, cheese,
  butter, cereal joined) — the shelf drained of exactly what the basket
  asked for while the rest silted (13 butter sticks and 14 cereal boxes
  nobody could buy). New INVERSE validator rule: every restocked food must
  be purchasable by some purchase query — which immediately caught the
  bakery's cake and the restaurant's grilled_steak too (production nobody
  could buy, the 12k-dough problem's descendants): fresh_bread_run gains
  bought_a_cake, and ordered_a_meal now consumes the restaurant's REAL
  steak stock alongside the service charge.
- milk/cereal are honestly eatable (ate_breakfast_from_cereal +
  ate_meal_from_milk OAR alternatives; the Brain meal sets know them) —
  no granola-bar-deadlock class regression.
- The closed-venue guard at the arbitration CHOKE POINT: planner routines
  (weekly shopping, dinner out) proposed straight into shops that had just
  closed — a 166-blocked-trip wall at 16:00-19:00, right after the clerk
  clocks off. One guard in resolveIntents covers every intent source.

Live re-verification: orphan cars 0 across the whole run (was ~4.6/day),
the town staffed itself (1 Manager vs the audit's 14; nurses, officers, a
firefighter, collectors), bags collected, purchases flowing. Full suite
green; perf baselines re-pinned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…the menu config

The textures are generated per menu ENTRY id (civic_landfill), not per
blueprint key (sanitation_depot) — harness placements of the landfill and
prison rendered as missing-texture black squares. Verified live: the time
toolbar's full bus loop (click → setTimeScale → timeScaleChanged →
highlight), the ×2 label merge, and empty midnight streets all confirmed
in the browser.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… holds WHILE it runs

Aliveness-3 follow-up (maintainer observation): the JSON location field was
only enforced at start — a running location-gated instance whose person got
physically displaced (the W9 ejection class, off-map detention relocations)
kept 'running' wherever they stood. The advance loop now re-validates the
concrete location kinds (home / building:<key> / person-resolved) every
tick: a displaced instance reverts to PENDING and re-materializes (walks
back and continues) or gets replaced at the flip. Structurally, 'Sleeping'
can never run on the street again. (The observed street labels were the
'→ Sleeping' TRAVEL labels — heading somewhere to sleep — but the gate
makes the violation class impossible rather than merely unobserved; a live
probe over a running town found zero standing violations.)

venue:* stays ungated here (it resolves to a concrete host at
materialization; the handle is gone by running time), as does 'outside'.

Test: displacement mid-nap bounces the instance out of running and it
resumes honestly after returning home — revert-dance verified (fails with
the gate stashed). Full suite green (1926).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two maintainer reads from the live session:

- '→ Sleeping' over a street walker read as street-sleeping — travel labels
  are now destination-first: '→ home: Sleeping', '→ Oliveira-Saraiva:
  Treating patients', '→ the supermarket: Going on a shopping trip'. The
  destination resolves from the instance's own location requirement (home /
  venue kind / hosting business name / a visit).
- Pedestrians all walk the EXACT curb polyline, so co-located walkers
  rendered perfectly stacked regardless of activity. A stable per-person
  render offset (±4px, hashed from the id — people using different parts
  of the sidewalk) separates everyone; the W5 formation offsets stack on
  top for same-activity groups. Render-layer only; logical positions and
  every stream untouched (no regeneration impact).

Verified on screenshot: three hospital staff converging by name with
staggered labels, the collectors' '×2' merge, visibly-separated sprites.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lding

Aliveness-3 follow-up (maintainer read): the per-frame redraw closure hid
the sprite on entry but returned early WITHOUT touching the bubble (or the
pet dot) — the label stood at the door until the next per-minute refresh,
a ghost over every entrance during arrival waves. Entering now hides
sprite + bubble + pet dot frame-accurately.

Live probe across an arrival wave (8 samples, up to 6 visible bubbles):
zero visible-bubble-while-indoors ghosts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Maintainer spec: line one says where ('Going home', 'Going to Moraes
S.A.'), line two what for ('Plan: Spending time at home'), centered, no
arrow. Bubble labels also strip unresolved {param} template segments (the
LP-14 resolver lives in the inspector; the destination line carries the
entity here) — 'Plan: Applying for a job', never '…at {employer}'.

Verified live at the evening rush: 'Going home / Plan: Spending time at
home ×2' (the merge suffix rides line two), job seekers converging on
named businesses.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…amping, wander stall

Live-found (fresh-game observation, real browser): people at home popped visible
"on top of their house" when their activity changed, and outdoor actions left
sprites stuck at houses. Four root causes, all in the physical layer:

1. Placement never set currentBuilding — materialization, newborns, recovery
   movers and loads left everyone "indoors with a null link", so the first
   located action ghost-commuted to the house the person was already inside
   (sprite pops out, walks to a car, drives home), and LiveWorld's identity-only
   arrival check could deadlock located actions forever (a pending 'home' handle
   12 sim-hours old on a man standing in his own living room, sleep waiting all
   night). Placement sites now set the link; LiveWorld's arrival check falls
   back to physical containment (indoors + the tile under the pixel references
   the destination) and heals the link; SaveManager re-derives it on load.

2. walk() steps were unclamped — speed × timeDelta overshoots the <1px arrival
   window at large frame deltas (4×/8× throttle, harness stepping, hitch cap)
   and the walker ping-pongs across the target forever (observed: frozen 1px
   from the commute car for 21 sim-hours). Steps now clamp to the remaining
   distance.

3. updateDestination committed the destination before the reachability check —
   one unreachable (or own-building) pick froze an ambulatory walker for the
   rest of the session. The pick only commits with a real path; failures retry.

4. Outside transitions parked the body at the entrance pixel (inside the
   footprint — read as "standing on the house sprite"). stepOutside() now lands
   on the curb of the connected street, entrance fallback in road-less worlds.

Verified live: max pending handle age 22 -> 4 ticks, frozen walkers 269 -> 0,
stuck sleeps 4 -> 0 (8 running at 06:00), sprite invariants all zero. Generator
untouched (live/physical layer only — the running regeneration stays valid).
Revert-dance: stashing the fixes fails exactly the 5 new tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…stat (v137.0)

Mid-regeneration the living count compounded past target (335 at year 30 → 490
at ~year 90 against a 250 target): the W4 conception channel (had_sex commit →
10% pregnancy invoke) is the dominant conception path and manual invokes bypass
setProbabilityScale — the thermostat was braking only the demoted background
hazard. maybeConceive now multiplies its chance by the engine's scale for
'pregnancy' (a new getProbabilityScaleFor read); live play never installs a
scale, so live behavior is untouched. Generator stream changes →
HISTORY_GENERATOR_VERSION 137.0; the in-flight regeneration is restarted.

Also folds the doc addendum lint fix (MD004: a continuation line starting
with '+' parsed as a list marker).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ew node's default

The v137.0 regeneration OOM'd at recording year 96 (six years into the 10-year
hourly hot band) at node's ~4GB default old-space. The hot band holds up to
flushIntervalYears (5) of HOURLY action logs for ~250-270 people between drains,
and the aliveness-2/3 arcs raised per-tick log volume (work wiring, food chain,
venue repertoires, minute stamps) past the default's headroom — no aliveness-3
regeneration had ever completed. cross-env pins NODE_OPTIONS in the script so
the requirement is documented and repeatable (machine needs ~24GB+ RAM; the dev
box has 32GB).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ines (v137.0)

The arc's closing evidence run: 100 recorded years (90 daily + 10 hourly),
2h22m, 704 retained people, 1.59 GB. Population holds 207-294 around the 250
target across all 120 simulated years — the thermostat brake works through the
W4 conception channel now (the pre-fix run compounded to 490). Decode
re-measures vs the audit Appendix baselines:

- cooking:eating ~14:1 → ~2:1 (p600: 4,125 cookings / 1,782 meals), with typed
  ate_a_meal:failed entries where scarcity bites instead of pantomime cooking
- sleep is real in the hot band (8h ×2,552 vs 24h ×277) and COMPLETES
  (2,829 completed vs 1,219 interrupted; baseline: zero completions ever)
- justice: the median profile is 9 shopliftings → 2 caught → 1 jail term over
  27.5y (baseline: 15 → 12 caught → 11 terms) — the abstract-encounter
  discount works; a habitual-criminal tail case remains (p650: 23 terms/19.3y,
  the crime-habit escalation loop) — flagged as a post-arc balance item
- hug-ask volume collapsed ~12× (2,946 → ~240 attempts/lifetime — the standing
  pricing works); decline share among remaining asks is largely unchanged
- the W2 venue repertoires are lived off-map: library/salon/cinema/gym/church
  all appear in every decoded life; illness ~2.5/yr (was 3-4)

Boot-verified live: asset draws hydrate (158k-181k pre-game entries/person)
and drawn people arrive with the placement link set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Maudfer Maudfer self-assigned this Jul 19, 2026
@Maudfer Maudfer added the enhancement New feature or request label Jul 19, 2026
@Maudfer
Maudfer merged commit 51be1ca into main Jul 19, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant