Commit Graph

20 Commits

Author SHA1 Message Date
m3ultra
50385c0f08 Lane F R31 wave 1 (v7.0-alpha close): THE DIG FLIP — the alpha-blocker Fable's playtest found. DIG_ON = flagOn('dig') (default-ON, ?dig=0 opt-out, ?classic=1 off — the v3.1 pattern; the v2-era opt-in survived 6 epochs past the README's 'dig on' claim because every R30 gate booted dig=1 explicitly: the explicit-flag blindfold). Fenced forever: default_boot_gate asserts dig REACHABILITY on a NAKED boot (E at a bin → digActive true), classic_regression asserts dig INERT at the bin (zero pcdg DOM, measured not assumed). PROCITY.flags gains dig. Splash de-staled ('Every door opens.' — no more '(soon)'; controls line carries E riffle/sell · C crate · SLEEP to save) + README manual row (sell at counter · C crate · SLEEP = save/advance/rotate). PROCITY_QA_PORT env override (flags_check, interior_scale_check, town_matrix) so the suite runs port-isolated instead of silently reusing whatever holds :8130. Verified both ways on :8951 (naked boot digs + closes clean; dig=0 and classic zero dig DOM, classic ZERO storage calls; noassets digs parody, 0 errors). qa.sh --strict --matrix on :8931: 7/0/0/0, flags_check 0 fails 0 warns, MATRIX 10 towns green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 16:37:02 +10:00
m3ultra
b2d29ba112 Lane F R27 (v5.0): the covenant re-pinned, the frame that took five tries, QA GREEN
qa.sh --strict --matrix: 7 passed / 0 failed / 0 warn. selfcheck ALL GREEN 156,352/156,352 ·
MATRIX GREEN 10 towns x 7 gates · scaffold_check GREEN (F's re-pins took) · flags harness green,
carrying the kill-the-server gate and the beta crate gate.

F RE-PINNED ITS OWN FILES per A's handoff (A doesn't edit other lanes' files, correctly):
GOLDEN_HASH 0x3fa36874 -> 0x5f76e76 · GIG_GOLDEN 0xb1d48ea1 -> 0xec7a2d39 · melbourne · katoomba
· the captions. AND A CAUGHT A LIVE HAZARD IN F'S GATE: hash_ok carried `or ('3fa36874' in
r.stdout)` — a bare-string OR-clause, dead the moment the covenant moved and worse than dead,
because it would go green off a SENTENCE ABOUT the old covenant appearing in stdout. Deleted.
The check derives from GOLDEN_HASH or it doesn't exist.

JOHN'S RULING IS THE EPOCH'S BEST LINE: the covenant is anti-drift machinery, not a defect
preservative. 0x3fa36874 did its job for five epochs — it never drifted. It just was never right,
and no hash can catch what was wrong in the first commit. A golden proves NOTHING CHANGED; it
cannot prove anything is CORRECT. Every gate we own was green over a world of back walls, and the
only thing that ever saw it was a human standing in the street looking at a wall.

THE FRONTAGE FRAME TOOK FIVE ATTEMPTS, FOUR OF THEM F'S FAULT:
  1-3. cluster pose (the town's heart isn't this shop) / lot-anchored facing along the edge /
       lot-normal facing — three photographs of empty road. Also never winnable: the shops faced
       backwards the whole time. F was posing a camera at a wall and tuning the geometry.
  4.   B's helper — and F THREW THE RESULT AWAY. poseForShopFront RETURNS a pose; it does not
       apply one. F called it, error-checked it, and never touched the camera, so the frame was
       the spawn paddock — and F's error-check PASSED, because the call succeeded perfectly. The
       vacuous check one last time, in the last frame of the epoch.
  5.   Applied it -> MONSTER ROBOT PARTY. Sign, door, awning, a ped walking in off Musgrave Road.

The measurement that would have found the facade bug in five minutes — compare the two
conventions against each other — is the one nobody ran for nine rounds, F included, right up to
the vacuous 72/72 F nearly filed as "B is wrong".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:48:22 +10:00
m3ultra
630042fbe1 Lane F R27: the kill-the-server gate GREEN — and two corrections to F's own gate
THE KILL-THE-SERVER GATE, permanent and green (charter law #1 made falsifiable):
  ARM 1 server-up   · gone[3] → 117 survivors · items[] 120, identity AND ORDER intact ·
                      COLLATERAL 0 · `gone` carries the atlas id verbatim (R26 fence)
  ARM 2 killed mid-session · enter 6ms vs control 6ms (Δ+0) · worst frame 204ms vs control
                      202ms (Δ+2) · room complete from files · ZERO game errors · EXACTLY 1
                      refused connection
  ARM 3 server-down boot   · pure tier 1, gone[0] · ZERO game errors · exactly 1 refusal
  SANDBOX · POST/PUT/PATCH/DELETE all 501 · a mint shop 404s
The subject exists only because G built `make-fixture`: production `gone` is EMPTY (0 sales
since 2026-07-01), so this gate would have passed vacuously forever on live data.

CORRECTION 1 — "ZERO console errors on server death" is UNACHIEVABLE, and F measured why. A
fetch to a dead host logs net::ERR_CONNECTION_REFUSED at the BROWSER level; no .catch() sees it.
To log zero the reader would have to know the server is dead WITHOUT ASKING. One refusal is the
irreducible cost of discovering death. F's replacement is strictly stronger: ZERO errors from
game code, and EXACTLY ONE refusal — which PROVES the circuit breaker. Without the breaker it is
one error per shop entry forever, and "zero" could never tell a working breaker from a broken
one because both fail it. F is the beneficiary of this change, so it is filed loudly in §27 for
Fable to ratify or overrule, not quietly relaxed.

CORRECTION 2 — F's frame assertion was weak: `< 250ms` is a number with no control. ARM 2 first
reported worst-frame 201ms and PASSED. But entering a shop rebuilds an interior, which costs the
same with or without a server — so an absolute threshold measures Lane C's room build, not the
network. The arm now walks the same shop with the breaker tripped and asserts the DELTA: 202ms
control, 204ms killed, Δ+2ms. The death cost nothing the room didn't. F told A the same thing one
round ago; a number without a control is not a measurement.

THE TOUR — 3 of 4 frames, and the 4th is FILED NOT SHIPPED. The real crate (the money shot: its
own 120 records, price stickers, the keeper), a mint crate (captioned MINT — plausible, not
real), the classic covenant. 0 page errors. The FRONTAGE frame does not land after three
attempts and F will not ship a frame that doesn't show what its caption claims: the cluster
primitive answers "where is this town's heart", which is not the question a frontage frame asks
— Red Hill's heart is 2 shops/60m and does not contain Monster Robot. Next: ask B, who owns the
frontage and shipped its mark this round. Re-deriving B's anchor in a tour script is how you get
three bad frames.

Also: the interior beauty shot came back with the HUD across it — R21's lesson, fixed on the
street frames only. Now every DOM overlay is hidden, not a guessed selector list.

NOT TAGGED. qa.sh --strict --matrix and the frontage frame remain.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 15:05:17 +10:00
m3ultra
8ac3b18b36 Lane F R22 (v4.0 — THE EPOCH CLOSE): the re-measure, the selector, the release tour, the tag
The blocking gate is CLOSED, and the epoch closes green.

- #1b THE BLOCKING RE-MEASURE: F's R21 re-measure made the tri diet blocking; B diagnosed layer-by-layer,
  the driver traced A -> E (A's own commit: "B's numbers say the fix is E's"), E fixed it, F re-measured:
  katoomba venue_night 221,935 (+11%) -> 108,365 (-51%); bendigo 201k -> 124,682; fremantle -> 88,397.
  Worst 124,682 — the 200k stress edge is closed. The measure-first loop worked end to end.
- #3 DBG.enterShop(selector) (Lane G's ask): id · registry type · exact name · name substring, resolved
  most-specific-first so an id-shaped string can't be shadowed. One-liner QA on any of 23 towns.
- #4 The release tour -> docs/shots/release_v4/: the Fremantle hero · the Fitzroy mecca · the Toowoomba thin
  tail · the synthetic control · the ?classic=1 covenant. Every real-town frame poses through F's R21
  cluster primitive; B's R22 bookmarks anchor on the same retail heart, so tour and bookmarks agree by
  construction. HUD hidden throughout (F's R21 ruling corollary).
  The primitive earned itself twice: the first cut posed via street_noon and the MECCA CAME OUT AS BARE
  BITUMEN — the same trap as R21. Re-posed through the cluster, Fitzroy reads.
- HONEST FINDING (filed v4.x): the brief asked for the thin tail as "proof the floor holds". It does not,
  and the frame says so — Toowoomba reads as an empty road. The floor is a RATIO, not a count: 0.008
  shops/edge vs the heroes' 0.06-0.08. Shipped labelled honestly rather than swapped for a flattering town.
- #6 Docs: README v4 section (the towns ARE the product), LANE_F_NOTES §22, F-progress.

qa.sh --strict --matrix GREEN 7/7; MATRIX GREEN — 10 towns × 7 gates (the budget gate green everywhere for
the first time); selfcheck 161,300/161,300 (A's 36 goldens + the 23-town pack).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:32:32 +10:00
m3ultra
201a2bb868 Lane F R21 (v4.0-beta close): the beta gate — tram dimension, the re-measure, the beta shot
All five lanes in (A's venue cluster bias, B's selector-from-index, C's density door-soak, D's relocation
verify PASSES, E's 22-town pack non-gating); F gated and tagged.

- town_matrix.py: a `tram` dimension — B's R20 shop-adjacency ruling verified EXACTLY (newtown runs 16 stops
  after B's phantom-stop fix, castlemaine 10; katoomba/fremantle/bendigo FENCED at 3/2/1 shops fronted, all
  below the 5-shop floor). 10 towns x 7 gates: boot/determ/district/roads/tram/noassets green on all ten.
- index.html: expose window.PROCITY.tram — B built `routeInfo` FOR F's smoke but nothing published it; F owns
  the shell, so F wired the seam.
- RECORDED (ledger #6b — the instruction was "record the new number"): the venue_night re-measure. A's cap
  WORKED (posters 438->111) but E's density widening ate it — katoomba 200,965 (+965, R19) -> 221,935
  (+21,935, +11%); bendigo 201k (+0.5%); fremantle/newtown/castlemaine in budget. Draws fine everywhere
  (151/300 — half budget); tris-only, at the worst night stress view. Filed as R22's first item, where the
  tri-diet backlog (instrument LOD, tram tri diet) already lives. katoomba is the outlier: 966 edges, 72 shops.
- Ruling (ledger #6d): the town selector stays ALWAYS-IN-HUD, not ?dbg-gated — THE REAL MAP's product IS the
  towns. Corollary (F's own gap): money shots hide the HUD; the R19 alpha shot had the selector in-frame
  because F's harness screenshotted the full viewport.
- Beta money shot: Fremantle's real street at golden hour — a corridor of shopfronts, footpaths, a crossing,
  gum trees, and a genuinely busy crowd (the density widening, visible). 126d/167k tris, HUD hidden.
- docs: LANE_F_NOTES §20 (the honest why-R20-had-no-tag record) + §21, README beta paragraph, F-progress.

qa.sh --strict GREEN; selfcheck 154141/154141 (A's re-pinned goldens hold).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 21:37:04 +10:00
m3ultra
ddd1e6827e Lane F R19 (v4.0-alpha close): the alpha gate + roads dimension + the first real-street money shot
A resolved the R18 findings (fragmentation cull/join, poster clamp, goldens pinned) + D verified; F gated.

- town_matrix.py: a `roads` dimension — a schema-v2 cache (roads[]) must build the REAL street graph
  (norm.mode==='roads', read via the plan_osm opts.report sink); synthetic/fixtures stay marched/synthetic.
  10 towns x 6 gates: real roads green everywhere; classic/default proven untouched (roads ride the cache
  schema, not a flag — 0x3fa36874 frozen).
- docs/shots/v4_alpha/katoomba_mainstreet.png: the first real-street money shot — Katoomba's actual main
  street (asphalt + lane markings, footpaths, a pedestrian crossing, a walking crowd, gig posters, B's town
  selector in-frame), PROCITY's look on real bones, 121k tris midday.
- docs: LANE_F_NOTES §18 (why F correctly HELD in R18 — the gate would have failed by design) + §19 (the
  close), README real-roads note, F-progress.

qa.sh --strict --soak GREEN 7/7. One filed NON-blocking finding: katoomba_real venue_night 200,965 tris
(+965 / 0.5% over the soft ceiling, poster-count-scales-with-real-edges driven; midday play is 121k) — a
v4.0-beta hardening item (A caps posters per real town), on the opt-in --matrix warn-gate, not a play view.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 18:07:24 +10:00
m3ultra
e4a49b5bc8 Lane F R17 (v3.2): real towns boot in the engine + the town-matrix scout gate (ledger #7)
F wired the last mile of the real-map scout and gated the whole matrix.

- index.js barrel re-exports registerTownCache/validateTownCache; the shell fetches + registers
  assets/towns/<key>.json before generatePlanFor when the town isn't a checked-in fixture — so
  ?plansrc=osm&town=bendigo_real boots a REAL AU town in the engine (the gap: E's caches were on disk +
  in the node selfcheck, but the shell never loaded them → silent Melbourne fallback). Fail-soft
  (404 / invalid / ?noassets -> fixture fallback); opt-in, never on the default or ?classic path.
- tools/qa/town_matrix.py (opt-in qa.sh --matrix): boot / determinism / budget / district / ?noassets
  across 10 towns (2 synthetic hero seeds + 3 osm fixtures + E's 5 real AU caches). ALL 5x10 GREEN —
  Castlemaine at the 6-shop floor still lands a 3-venue district. The existing CityPlan contract eats real
  Australian geography: the evidence John charters v4 = THE REAL MAP on.
- docs: LANE_F_NOTES §17 (the town x gate table), README real-town row, F-progress R17.

qa.sh --strict --soak GREEN 7/7. Verified: ?plansrc=osm&town=bendigo_real -> Bendigo, 9 shops, 3 venues, 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 15:23:15 +10:00
m3ultra
9277238462 Lane F R16 (v3.1 THE FLIP) — close: default-boot tour + week soak + docs
The closing half of F's bookend. All gates green on the flipped tree (qa.sh --strict --soak: classic
regression + default-boot gate + smokes + no-giants incl. the seated drummer + the full-week soak).

- tour_shots.py -> docs/shots/release_v3_1/: the money shots on the DEFAULT boot (no per-shot flag juggling
  now the flip covers it) + a ?classic=1 before/after ("the town before v3"). 7 shots, settled, 0 page errors.
- week_soak.py: re-pointed to the default boot; the leak check now treats an at/below-baseline OR non-climbing
  trail as leak-free (a decreasing tex trail is GC/atlas-settle, not a leak — it was false-failing at warn-level).
- docs: README v3.1 flags table (defaults on + ?classic=1), CITY_SPEC v3.1 amendment (the rewritten prime
  law + classic covenant, A's deferred edit), LANE_F_NOTES §16, F-progress R16.

Numbers (seed 20261990): default @ venue block 124 draws / 57k tris (<=300/200k); ?classic 161 draws / 24k
tris (the v2 baseline); seated drummer 1.32 m stature; week soak 42 cycles leak-free (net +0/-6).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 13:32:22 +10:00
m3ultra
a4946b7ca2 Lane F R16 (v3.1 THE FLIP): defaults on + ?classic covenant + seated-stature gate (ledger #1, #3)
The town shows its best by default. gigs / weather / winmap / tram flip ON (each keeps a ?flag=0 opt-out;
?classic=1 forces the exact v2 boot). The prime-law covenant MOVED from "flags off" to "?classic=1" —
byte-identical forever (synthetic fingerprint 0x3fa36874). The default boot is now the full experience,
deterministic to the gig golden 0xb1d48ea1 (A's R16 corner-poster re-pin).

- index.html: CLASSIC + flagOn(); gigs/weather/tram default-on; loadPedFleet({sit:!CLASSIC}) for the seated
  drummer (?classic keeps the zero-fetch-delta covenant); a window.PROCITY.flags intent surface for the gates
- buildings.js: winmap default-on + classic-aware (the one cross-lane flip line the flag placement requires)
- flags_check.py: flags_off_regression -> classic_regression (?classic=1 byte-identical); a new default_boot_gate
  (all four flags on, gig layer present, gig golden, budget); every gig smoke re-pointed at the DEFAULT boot
- seated-stature gate (ledger #3, published for D): interior_scale_check.py + flags_check.py accept
  fig.userData.procitySeated at stature [0.9,1.5] m (the drummer); standing figs stay [1.4,2.0]
- qa.sh flags-harness gate name updated (classic regression + default-boot gate)

Verified: ?classic byte-identical (0x3fa36874, gig layer absent); default boot = the full town (14 gigs, 15
posters, tram, gig golden green, 112 draws @ the venue block); the seated drummer passes at 1.32 m stature;
district (3 venues / 3 genres), continuity, and cover all green on the default boot.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 13:20:43 +10:00
m3ultra
6a35b29352 Lane F R15 (v3.0): the release money-shot tour (ledger #4) + settled measurements (ledger #5)
tools/qa/tour_shots.py: one deterministic run capturing the release set into docs/shots/release_v3/
(+ contact.html), grouped by the flags each shot needs, all seed 20261990:
- venue_night, district_posters, queue_night (John's HERO — now with A's flipped frontage poster VISIBLE
  by the door), gig_interior (the 4-piece + real instruments + a roster crowd — 2 punters carried through),
  rain_verandah, tram_stop
- settled discipline (ledger #5): every shot measured after the async instrument GLBs / poster textures /
  chunk stream land (shoot-twice), from a clean per-group load; the queue is driven LIVE (explicit admits,
  not rAF auto-drain which automation throttles)

The hero confirms ledger #1: the frontage poster reads from the street for the first time. Interior settles
35k->182k tris (draws 56 <= 350 gate). All street shots <=300 draws / <=200k tris. 0 page errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 11:35:27 +10:00
m3ultra
edc0c479c1 Lane F R15 (v3.0): full-week gig soak (ledger #3) — leak/cover/roster over 7 nights
tools/qa/week_soak.py: rolls the day-clock through all 7 nights in one context, entering every playing
venue each night. Asserts latch state per plan.gigs (dark venues stay quiet), the cover STAMP per venue
per night (debited once, re-entry free, due again next night), tonight's roster clears per night (no
accumulation), and geo/tex return to a WARMED baseline across >=20 enter/exit cycles — leak proven by a
plateau (a real leak climbs every cycle; warm-up cache residue plateaus). Opt-in --soak warn-gate in
qa.sh (never blocks the tag; the core 6 stay a fast strict run).

Verified seed 20261990: 2 playing (Exchange Hotel + RSL) + 1 dark, 28 cycles, $60 covers, geo/tex flat
across the back half (115/86 -> 115/84), 0 console errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 11:29:43 +10:00
m3ultra
146b5f3d2d Lane F R15 (v3.0): retire the R12 single-venue alias (ledger #2)
The compat alias delegating to the primary venue is gone — every read is now keyed by venueShopId.
B swept the cross-lane readers in R14; this migrates F's own tools + the spec, one atomic commit.

- gig_state.js: delete the alpha-shape alias block + the now-unused primaryId/P; update() just ticks all latches
- flags_check.py + gig_shot.py: .venueShopId->venueShopIds[0], .state->stateOf(id), .cover->coverOf(id), .bandName->bandNameOf(id)
- CITY_SPEC \S v3: delete the two alias sentences, add the omitted nightOf(id) to the accessor list

selfcheck 14264/14264 green (base 0x3fa36874, gig 0x4f4a549d); flags_off + smoke_gigs green, 0 warn.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 11:14:19 +10:00
m3ultra
a358c5d9ef Lane F R13 (v3.0-beta, the district): per-venue gig state + walla/applause + queue wiring; qa --strict 6/6
Wires A–E + D's district together and fires it. Seed 20261990 → "Boolarra Heads": 3 venues, 2 playing
tonight (The Exchange Hotel pub gig-pubrock + an RSL gig-covers, one dark), Screaming Utes $10 on the door.

- gig_state.js → PER-VENUE latches off the shared procity:segment spine (one per venueShopId); all three
  hard-won R12 laws kept. New runtime surface window.PROCITY.gigs.byVenue + onOf/openOf/gigOf/coverOf/
  bandNameOf/paidOf(id) + markPaidOf/venueShopIds; the R12 single-venue alias kept for one round.
- interior_mode.js: crowd-walla rides the interior tone layer under the live band bed while `on`; an
  applause sting fires once on the on->done edge. DELETE the GIG_BED bridge — debt #1, and it was a LIVE
  BUG: E renamed pubrock-live->gig-pubrock, so the bridge (gig-pubrock->pubrock-live) pointed at a dead
  key => the band would have mimed in silence. room.audio.gigKey (already the manifest key) feeds directly.
- index.html: per-venue cover charge (a night at two venues is two covers), concurrent per-venue setGig
  surges, and the outdoor VenueQueue lifecycle (D shipped the class + left the street-side seam to F:
  spawn at doors off B's queueZoneFor, drive each frame, dispose by done), exposed as queueCountOf(id).
- interior_scale_check.py: human-size assert now measures STATURE (crown-foot, platform-independent);
  world-crown ceiling-clip assert kept as its own line (debt #6).
- flags_check.py smoke_gigs -> THE DISTRICT: band->4, per-venue loop (every gigKey resolves across 3
  genres, crowd <= its own watchPoints, no-giants by stature), street budget at the busiest venue block,
  the queue assert; plus the R12 determinism/cover/noassets/flags-off arms.
- CITY_SPEC: pin the window.PROCITY.gigs runtime surface. gig_shot.py -> r13 interior + venue_night shots.

qa.sh --strict GREEN 6/6, 0 warn. Interior 63 draws/35k tris; street @ venue block 121 draws/51k tris;
band+crowd stature 1.61-1.81 m under a 4 m ceiling; flags-off fingerprint 0x3fa36874 unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 00:22:03 +10:00
jing
2498fdc892 Lane F R12: wire the v3.0-alpha gig layer (?gigs=1) — state machine, cover charge, band+crowd, gig audio
F last: five landed lanes → one Friday night. Seed 20261990 → The Thornbury Hotel,
tonight SCREAMING UTES, $10 on the door. qa.sh --strict GREEN 6/6.

- gig_state.js (new, F-owned): quiet → doors (DUSK) → on (NIGHT) → done (DAWN) → quiet.
  Rides lighting's procity:segment event (a poll only sees the segments it samples, and
  missed the night roll entirely); `state` is a getter because B's audio reads it from its
  own rAF while the player is inside a shop.
- ?gigs=1 seam: custom_bands.json fetched in the bootstrap (no fetch flag-off or ?noassets)
  → generatePlanFor(seed, src, {gigs:true, customBands}). 7 of John's 10 names fill the week.
- Cover charge on the R8 buy seam, zero new UI: paid debits once with a toast, re-entry the
  same night is free, broke → polite knockback, free nights walk straight in.
- interior_mode: opts.gig → C's gigKey; D's GigCrew (band 3 + crowd 8, 3 dancing) at C's
  stage/watch points; both disposed with the room (leak-free over 4 cycles).
- Cross-lane fix at the glue: C emits gigKey 'gig-pubrock', E shipped the bed as
  'pubrock-live' — unresolved the pub plays to a silent room and nothing errors. Bridged
  here; C/E/Fable owe CITY_SPEC a contract line. Details + 2 more findings in LANE_F_NOTES §12.
- smoke_gigs (16 gates): schedule determinism, band==3, crowd ≤ watchPoints, dance mix, bed
  resolves, ≤350 draws (47 rig / 171 placeholder), no-giants by STATURE (the band stands on a
  0.32m deck, so world-crown fails a correct band), cover ruling, ?noassets+?gigs.
  Flags-off regression gains a v3 arm: no state machine, no plan.gigs, no pub, no venue geo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 21:09:56 +10:00
m3ultra
8c275c711b Lane F R11: wire interior audio beds + audio smokes + gate scope
Interior audio (interior_mode): enter -> PROCITY.audio.playInterior(room.audio) with Lane C's
{musicKey,toneKey} (fade in), exit -> stopInterior() (0.7s fade). Guarded/no-op when
muted/noassets/pre-gesture -- silent-and-happy.

New smoke_audio gate (flags harness, fresh Chromium per the R10 standing law): pre-gesture silence
(ctx not unlocked), 0 boot errors, ?mute=1 muted, ?noassets=1 zero audio fetches, enter/exit
AudioNode leak-free (12 cycles, 8 shops with a music bed, live sources bounded at 5). Gesture via
keyboard -- a mouse-click gesture tripped PointerLockControls in headless.

scaffold_check: scoped the Math.random generation-ban to exempt runtime FX PLAYBACK
(web/js/world/audio.js) -- Lane B's footstep SFX variant/gain jitter is transient, not world
generation (which shop plays which bed is seeded upstream in interiors.js). Noted to B.

Soak with audio on PASS (heap 48MB stable, 0 errors, no drift). qa.sh --strict GREEN 6/6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 17:13:19 +10:00
m3ultra
3432fccd1f Lane D round 10: fix interior giant rigs + no-giants QA gate
R9 blocker: interior rig figures were ~2x too tall (keeper crown 3.83m in a 3.4m room,
clipping the ceiling). Root cause in rigs.js buildFigure: it normalised scale by height/headY,
where headY is the head bone's world Y in BIND POSE — but the Mixamo skeleton origin is the hips
(~mid-body), so headY is head-above-hips (~half the standing height), not feet->crown. Every rig
came out ~1.83-2.0x too tall. (The head does NOT move when posed — bind crown 3.209m vs idle
3.205m — so it's a hips-relative measure, not an animation issue.)

Fix: normalise by the feet->crown span (headY - minY, both already computed). buildFigure(rig, h)
now lands the crown at exactly h above planted feet. Fixes keepers, browser rigs, near-tier street
rigs AND the impostor bake (all ride buildFigure). Verified: all 19 fleet rigs crown==1.75m; live
keeper 3.83m -> 1.82m; determinism + dispose-leak soak unchanged.

Regression guard (required): new tools/qa/interior_scale_check.py (Playwright) enters a sample of
shops, injects browser rigs at browse points, asserts every interior fig crown in [1.4,2.0]m AND
< room dims.H AND feet planted. Wired into tools/qa.sh --strict (run_gate => a giant fails qa).
Proven bidirectional: PASS on the fix (24 figs/6 shops), FAIL on a reintroduced giant. Full
qa.sh --strict: 6 passed, 0 failed.

Re-shot laneD/r10_browsers_fixed.jpg. Figures human-sized relative to doors/fittings: yes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 13:01:54 +10:00
m3ultra
9cc00ad29c Lane F R8: wire town/weather/patronage/buy + graduate harness + new smokes
Shell seams (F owns index.html): A &town=<key> -> generatePlanFor(seed,'osm',{town}) (Katoomba);
B weather (createWeather on ?weather=1; PROCITY.weather={state,intensity}, {clear,0} off; update in
loop); C session wallet bound to the dig BUY (getCash/onBuy in interior_mode); D patronage door
points -> citizens.setShops + ?patronage=0 off-switch + setWeather each frame.

Harness: stock=real + weather=rain graduated warn -> STRICT. New warn smokes: buy-v0 (dig BUY ->
wallet, cash 191->179 bag 0->1), patronage (7 peds visit shop doors/~18s), book/toy stock (6/11
real atlas meshes). Determinism gate: pinned osm/katoomba golden 0x0f652510 keyed on (seed,plansrc,
town) + fixed a hex zero-pad bug the katoomba golden exposed (0x0f652510 vs unpadded 0xf652510).

No patronage baseline re-pin needed (nets fewer draws, within tolerance). qa.sh --strict GREEN 5/5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 09:09:11 +10:00
m3ultra
781baea4e2 Lane F R6 F2: wire ?plansrc=osm shell selector + pin osm golden + dig nearest-bin fallback
A landed the plansrc seam (52eb109); F owns the shell bootstrap. index.html: ?plansrc=osm
-> citygen.generatePlanFor(seed,'osm') (real-data 'Melbourne' 95 shops); default synthetic
'Boolarra Heads' unchanged (prime law). scaffold_check.mjs: pin BOTH goldens keyed by
(seed,plansrc) — synthetic 0x3fa36874, osm 0x34cfdec0 (deterministic) — + assert the selector
routes synthetic|osm. flags_check auto-detects + smokes plansrc + the all-on combo (4 flags).

interior_mode.js: restored binUnderAim's nearest-bin fallback (Lane C test-page parity) so E
riffles a nearby bin without perfect aim / before the bin GLB async-loads — fixes the dig
smoke's raycast-miss under fast headless AND improves real UX.

qa.sh --strict GREEN; flags_check GREEN (all 4 flags + all-on combo, 0 console errors).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 22:59:45 +10:00
m3ultra
9416d0ae08 Lane F R4: wire citizens.setExposure (F1) + permittedMax storeys-checker fix (F2)
F1: pass renderer.toneMappingExposure into CitizenSim each street frame so mid-tier
impostors track the animated day/night exposure (per LANE_D_NOTES). Verified: boots
clean, 0 console errors, exposure animates night 1.18 <-> midday 0.98.

F2: scope the consistency storeys check to permittedMax = max>=2 ? min(max+1,3) : max
(Lane A's corner-anchor rule, LANE_A_NOTES R3). Consistency now 0 warnings across 6
seeds; a single-storey type at >1 still trips. qa.sh --strict GREEN 4/4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 18:15:42 +10:00
m3ultra
aa4ed4fdca Lane F: integration — interiors + keepers + street peds + QA harness
interior_mode.js bridges Lane B's enterShop seam to Lane C buildInterior and Lane D
keepers (spawn at counter keeperStand, greet, leak-free over 5 cycles). CitizenSim
wired into the street loop (pop 140, ~96 active midday, worst ~191 draws). tools/:
qa.sh gate runner (all 4 landed gates GREEN --strict), scaffold/consistency checks,
shots.py + soak.py browser harnesses. docs/shots/ reference tree, LANE_F_NOTES
runbook, V2_IDEAS parking lot.

(F's inline seam edits to index.html/skins.js landed with the Lane B commit.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:29:03 +10:00