Skip to content

The simulation-aliveness-2 arc: live-play truth (LP-1…LP-14 + follow-ups) - #101

Merged
Maudfer merged 21 commits into
mainfrom
task/simulation-aliveness-2
Jul 18, 2026
Merged

The simulation-aliveness-2 arc: live-play truth (LP-1…LP-14 + follow-ups)#101
Maudfer merged 21 commits into
mainfrom
task/simulation-aliveness-2

Conversation

@Maudfer

@Maudfer Maudfer commented Jul 18, 2026

Copy link
Copy Markdown
Owner

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:

  • LP-1 — saving was impossible in asset play (RangeError from serializing 100k-entry hydrated pasts): saves now carry live-era entries only; the past re-hydrates from the asset on load.
  • LP-2 — the observation truth kit: the 117 T-throttle desynced movement from sim time (fixed + tested); travel logs departed entries; cancelled transitions carry no_route; travel gets "→" bubbles; the double scene-init is guarded; debug()/stepGame() harness keepers.
  • LP-3 — the workday contract: 27/43 work actions fired no lifecycle events (invisible shifts, skill days silently uncounted). All wired, validator-enforced, plus a City-level live-work keystone test.
  • LP-4/5 — food is real: pantry + shelf seeding, a genuine grocery restock recipe, honest eating (requires + consumes food), purchase solvency floor, starvation → mood/illness/death through existing machinery, satisfyNeed household meals, and the fed-week keystone (which caught three defects in its own feature before any human could).
  • LP-6 — gestation (conception → scheduled birth; miscarriage cancels by eligibility), task 122 fixed (+ the signal-coverage CI guard), and the never-serialized attribute overlay (sick loaded healthy) fixed.
  • LP-8 — squalor: uncollected garbage now measurably sickens, sours, and mobilizes the town.
  • LP-11/12/13 — the architectural centerpieces: minute-materialized commits (plan at the flip, spread across the hour, ±20% jitter, causation-shared minutes, departure spreading), the reactive BrainWake queue (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:

  • LP-7 complete — all 740 events audited: 35 curated gates, texture doubles dormant, ten wired events stripped of contradictory free-rolls, valence completion, and a CI-guarded quirk budget (~49/yr, from the audit's one-per-2-days).
  • LP-14 complete — entity-linked logs: render-time resolution, clickable person chips, and {placeholder} label templates across the interaction corpus (validator-enforced).
  • LP-9 complete — the asset decode audit (proposal Part 7: 3,412 rivals vs 70 friendships diagnosed and fixed; serial monogamy at dating formation; before-numbers pinned for the post-regen re-measure).
  • LP-10 complete — generational family-tree layout (no more hairball) + grouped skills panel.

Verification

  • 1888/1888 Jest tests across all 14 projects; every bug fix proven by the revert-dance.
  • Strict typecheck, full lint, production build all green; checked-diff docs regenerated; perf op-count baselines consciously re-pinned at each intentional behavior change.
  • New CI guards: signal coverage, the workday contract, the health-scale rule, the quirk budget, label-template placeholders.

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

Maudfer and others added 20 commits July 18, 2026 01:58
… 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>
@Maudfer Maudfer self-assigned this Jul 18, 2026
@Maudfer Maudfer added the enhancement New feature or request label Jul 18, 2026
…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>
@Maudfer
Maudfer merged commit 0584a6e into main Jul 18, 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