qa.sh --strict --matrix: 7 passed · 0 failed · 0 warn · 0 skipped, MATRIX 10 towns green. New
STRICT smoke_first_five: the fresh game hunts a roster artist and the splash names hunt + cash
· the beats walked the REAL paths (② at the crate, ③ on the buy, the send-off on the ⚖) · a
returning save gets no tutorial · a second fresh browser hunts the SAME artist (seeded, not
random) · ?game=0 shows nothing · 0 console errors. THE CROSS-ROUND CATCH: the seeded want
moved a fresh-boot invariant (wants 1, not 0) and the R33 gate went red on the FULL run while
green solo — amended to a baseline snapshot, lesson filed in §35 (a feature that moves a boot
invariant must sweep every gate that assumed it; full runs exist for exactly this). Money shot:
docs/shots/v7_beta/first_five_splash.png. Remaining for v7.0: the tour + docs freeze + THE TAG
— which waits for John's hands (the alpha precedent).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
qa.sh --strict --matrix: 7 passed · 0 failed · 0 warn · 0 skipped, MATRIX 10 towns green. New
STRICT smoke_godbay: consigned through the real crate DOM · ONE-HAMMER determinism (a frozen
pre-sleep export slept twice lands byte-identical — the seeded gavel, measured not trusted) ·
honest bounded resolution (net $19 ≤ 2×$24×0.88) · the wake toast carried the morning paper ·
the ride to melbourne hammered a listing on arrival · ?game=0 has no crate to list from · 0
console errors. Money shots in docs/shots/v7_beta/ (the dawn paper + the ⚖ crate). The full
v7 loop now closes end to end: dig the gem → keeper cash now or the gavel tomorrow → the
wantlist points at another town → the ride costs a day and hammers your listings on arrival.
Remaining for the v7.0 tag: THE FIRST FIVE MINUTES (onboarding), the tour, docs freeze — and
John's hands on the whole thing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
qa.sh --strict --matrix on the final tree: 7 passed · 0 failed · 0 warn · 0 skipped, MATRIX 10
towns green. New STRICT smoke_wantlist_travel: ☆→★ through the real card (the save carried
{THE VERANDAHS — 'Servo at Midnight'}) · a keeper muttered the hunted artist within 2 shops
('saw one in Castlemaine just last week') · buying the wanted sleeve cleared the hunt · the
synthetic→melbourne ride cost EXACTLY one day with $179 and the find riding along · the
same-town reboot was free (the control discriminates) · the ride home charged again (day 3) ·
?game=0 built zero want DOM and muttered nothing · 0 console errors. Matrix note: town_matrix
shares one browser across towns so travel drifts the day as it walks — safe because
determinism double-boots the SAME town (free by the same-town rule); reasoned before landing.
Money shots: docs/shots/v7_beta/rumor_and_wantlist.png (the keeper's mutter over the toy
shop's 70s wallpaper + THE WANTLIST open in the crate) + want_card.png. README manual row.
v7.0-beta systems are now ALL BUILT — what remains of v7: Esc-in-person (John's hands), then
the v7.0 close (GodBay offline auctions, THE FIRST FIVE MINUTES, the tour, the tag).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
qa.sh --strict --matrix on the final tree: 7 passed · 0 failed · 0 warn · 0 skipped, MATRIX 10
towns green. New STRICT gate smoke_bible: band law over EVERY bin off the digOffers surface
(80 offers/5 bins), the buy-everything ledger runs on THE GEM'S BIN so the finder-margin leg is
non-vacuous (bin1: 2 gems, grail asking $19 vs keeper $30; ledger closes to the cent — Σask
$333 → Σoffer $135, gems alone +$21, every non-gem strictly negative), scarcity measured
(emptied bin 0/16 on re-open AND across a full reload; 16 pulls in the save) with the ?game=0
negative control re-opening 16/16 (the detector discriminates). sell_routing amended from the
alpha inequality (credited < paid) to the exact formula (credited == min(basis−1, basis//2),
basis = bandLow-or-pricePaid) — the fence moved from the receipt to the band, which is what
charter law #2 always said; it passed on a banded standard item (+$4 on basis $8). _at_bin
grows an idx param (back-compatible). Money shots in docs/shots/v7_beta/ (the guide card + the
crate at the counter). LANE_F_NOTES §32 (incl. the JING5 fresh-checkout trap: gitignored
web/assets/models synced from m3ultra — also un-warned the validator's 15 cross-pack checks).
README manual: the guide/gem/scarcity rows. Remaining beta charter queued in the round doc:
wantlist + rumors · travel costs a day · Esc-in-person · then GodBay.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
EVERY CRATE IS DIFFERENT, and F measured it rather than taking G's 15/15 on trust — from the
indexes of record, not by entering one lucky shop: 15 keyed crates, 105 pairs, 0 sharing a
title; 0 crates overlap the generic v2 pack; 0 ids reused across crates (G's sku fix holds at
scale — the R24 vacuity dead at the source, not papered over in F's gate). 4 crates in Red Hill
+ 11 in Newtown = the manifest's 15 exactly, and the manifest lists nothing not on disk.
SOURCING, NOT TIER — C was right and the gate follows C. `tier` is the charter's ladder rung and
a mint atlas is ALSO rung 1: still a file, still offline, still deterministic. What differs is
where the stock came from. 15/15 indexes declare sourcing, every one agrees with the manifest,
a mint crate can never report as real, and the gate PRINTS it per room — provenance a human
never reads isn't doing anything (R24's licence lesson, one round on).
THE 404 TOLERANCE IS DELETED, NOT TUNED. R24 probed every keyed shop and ate a 404 per
atlas-less one; F's smoke could only cope by NAMING them, and a tolerance is a confession. F
filed the real fix as a contract ask rather than inventing it; G built the manifest; F now
consumes it — the shell asks for nothing unlisted. Zero 404s because nothing absent gets asked
for, not because the gate stopped looking. AND DELETING IT IMMEDIATELY CAUGHT A LEFTOVER: F had
wired the boot preload but left a second blind probe at the door, 404ing on every
keyed-but-unfetchable shop. While the gate said "8 probes, expected", a ninth was invisible too.
A named exception starts protecting new bugs the moment the real fix exists.
F's beta gate GREEN: distinctness · sourcing (real + mint rooms) · soft fall silent · ZERO 404s ·
0 console errors, no attribution exceptions. Selfcheck ALL GREEN 156,212/156,212.
TAG HELD — atlas-QA FAIL, 14 errors, and it is not the product. E's SLOT_ID_PREFIX = "sku_"
(validate_atlas.py:73) applies to every pack; E reads `sourcing` at :178 but the slot-id check is
sourcing-blind. All 14 mint crates fail; the real crate passes. A mint crate HAS no POS sku — it
was never in that shop's till — so the rule demands what cannot exist, the same shape as R24's
sweep demanding a cafe carry a godverseShopId.
F measured the rule's intent and it holds: mint_<dealgod listing id>, non-positional, sorted by
it, seeded bake, 0 ids reused across all 15 crates. Only the literal prefix fails. And G refused
to go green the easy way for the best reason — F's own R24 collision grown up: a POS sku and a
dealgod listing id are different id spaces, and filing one under `sku_` recreates that bug
INSIDE the economy, where tier-2's sold-means-gone looks up POS skus. R24's collision entered
the wrong shop; the same collision in the money layer sells the wrong record.
F did not fix E's one line: E's file, C's contract, C's call as its author (the principle Fable
ratified when C overruled `tier`) — and F is the party that benefits, since that line is the
only thing between F and the tag. Cost of waiting: one line. Cost of F being quietly wrong: a
gate that green-lights id-space collisions in the layer that moves money.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
You can boot redhill_godverse, walk down Musgrave Road into Monster Robot Party, riffle its
own real crate and buy a real record. Proven falsifiably, not by eyeball:
base assets/stock_godverse/3962749/ (its own, not the town-wide)
TITLES 120/120 the shop's atlas · 0/120 the generic pack
TEXTURES 2 from stock_godverse/3962749/*.webp · 0 generic — the pixels' own file
BUY rec_0000 "Abstract Latin Lounge II (Part II)" @ $15 → cash 191→176, exact
REBOOT 191/0 restored — gone-this-session, back next boot
Ladder: ?noassets → ZERO network requests · keyed-but-atlas-less shop → 404 → parody, live ·
newtown_real → base null, 350 items: the wire is a NO-OP off the godverse path.
flags_check GREEN (0 fails, 0 warns).
#6a THE WIRE: godverseBaseFor(shop), exported and used by BOTH the shell's boot preload and
the room's lookup — C's cache identity is the LITERAL (type, base) pair, so two sides building
that string differently would drop a real shop to parody, a bug indistinguishable from "no
stock" by eye. One function, one string, one key. Gated on stockReal, never the id alone.
#6b THE GATE: smoke_real_crate + DBG.stockInfo() — permanent, and it cannot pass without
touching its subject (SKIPs with a printed reason when the town/atlas is absent).
FINDING — THE BRIEF'S OWN HONEST-GATE SPEC WAS VACUOUS. It specified id equality. Both packs
number items POSITIONALLY (rec_0000…), so all 120 atlas ids are generic-pack ids too: an
id-equality gate goes GREEN on the generic pack — the exact failure the vacuous-gate law was
written to stop, reproduced inside its first application. Ids there are slot numbers, not
identity. Titles (0 overlap) and the texture URL discriminate; F asserts on those.
FINDING — THE ID SPACES COLLIDE, and it bit F's own selector inside the anti-vacuous gate.
Plan ids (1..N) and godverse ids (31, 767, 3962749) share a numeric space: Silky Oak's godverse
id is 31 and another shop's PLAN id is 31, so enterShop(31) silently entered "Wholefood Cafe"
and the soft-fall assertion PASSED ON AN UNKEYED CAFE. Fixed both ends: 'g:<n>' selects a
godverse id explicitly, a bare number stays the plan id and now REPORTS the collision, and the
smoke asserts it landed in the shop it asked for before asserting anything about it.
FINDING — F'S OWN GATE CRIED THE LOUDEST WOLF WE OWN. classic_regression reported "plan
fingerprint != golden 0x3fa36874 — determinism/prime-law broken" while the covenant was
provably intact. F wrote it in R16 as `hash_ok and returncode == 0` — two assertions, ONE
verdict, reported with the fingerprint's message — so any unrelated selfcheck red screamed that
the byte-identical-forever covenant had broken. Two assertions, two verdicts now. It isn't
enough to fail for a reason; you have to fail for YOUR reason.
FINDING — fail-soft-by-404 vs the 0-console-errors law. The boot preload must resolve a keyed
shop's pack before the door opens (getStockPack is sync), so it probes blind: 9 of Red Hill's
10 keyed shops have no atlas → 404 → parody. That IS fail-soft working, and it is also 8
console errors no .catch() can suppress. Fix is not to loosen the law but to stop probing for
what isn't there: an atlas index in G's namespace (or hasStock on the cache entry, A+G). Filed
as a contract ask, not invented. Until then the smoke counts and NAMES the probes and fails on
any other error — tolerance stated out loud.
Verified the lift is clean: cache 10 keyed → plan 9 keyed, every one a real secondhand shop.
No cafe keyed, zero duplicate ids — there is no mis-stocking.
F did NOT touch A's identity sweep or E's validator. F was the party that would benefit, and
changing a red gate to green in another lane's file to unblock F's own tag would retroactively
devalue every green F has ever reported. Filed instead — and R25 has since landed A's
reconciliation and the six pins, which is the right hands doing it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
v5.0-alpha is NOT tagged. #7a is not a gate that failed, it's a gate that cannot be run:
G's 120 real records are in the tree and byte-identically re-bakeable, and nothing in the
game can reach them. R18's law — release rounds don't ship known breaches.
GREEN (everything except the crate): qa.sh --strict --matrix 7 passed / 0 failed / 0 warn ·
MATRIX GREEN 10 towns x 7 gates · selfcheck 152,015/152,015 (was 161,300, E retired
toowoomba) · flags harness green, so ?classic=1 still holds through the merge · tier 0
?noassets zero fetches + zero console errors (the offline law holds) · tier 1 (v2
town-wide) resolves. Tier 1 (v5, per-shop) is NEVER FETCHED.
FINDING 1 — the atlas contract contradicts itself. LANE_C_PUB:271 publishes
stock_shop_<id>_index.json; C's own loader (stockpack.js:25) fetches
${base}stock_${type}_index.json. Incompatible. G built runtime-compatible (which is why
C's base-override check passed); E built contract-compatible (which is why E's validator
can't see it). Nobody was wrong — the contract was. F recommends amending to G's shape:
it's the only one the runtime can load, and it costs G nothing.
FINDING 2 — the gate built to catch that was blind and green. validate_atlas.py globs a
filename that can't exist at runtime, finds nothing, and returns 0 ("No atlases yet =>
clean pass"), which validate_manifest.py:158 propagates. It conflates "no atlases exist"
with "no atlases matched my glob" — the first is a clean pass, the second is the exact
failure it was written to catch. Pointed at G's index by hand, deeper drift surfaced:
E's line 68 reads provenance top-level while E's own docstring says nested (where G put
it), licence vs license, and a ceiling stale by one round.
FINDING 3 — #7a would have passed vacuously. Walked into The Vintage Record (real shop,
real road) via DBG.enterShop: the crates filled with real covers — from E's 350-item
town-wide v2 pack, not the crate. Zero requests to stock_godverse/, ever. Eyeballed as
written, the gate goes green and proves nothing. Two vacuous gates in one round, same
species: both test the presence of a thing rather than the identity of it.
R24 — three gaps, none F-only: A+G land a godverse_id (verified live: every godverse shop
reports null; the schema has no such field) -> E builds redhill_real (one Overpass fetch,
E's file, outward-facing — not F's to invent) -> C keys the pack cache by type+base
(today a hit returns before base is read, so two stocked shops collide and fail-soft
breaks) -> F passes the per-shop base and re-gates. F deliberately did not build its half:
untestable with no street and no identity field. Filed, not guessed.
Also: A's spacing warn earned on day one — ballarat now warns at 255 m, so the thin tail
has a second member. The README v5 teaser is held with the tag; they're one claim.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
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>
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>
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>
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>
- README: a v3.0 'venues & gigs, THE DISTRICT' section — what shipped, the flags table, the release tour
- LANE_F_NOTES §14 (R14: F never ran, brief carried) + §15 (the R15 release-close runbook, numbers, gotcha ledger)
- F-progress: R15 release-close summary at the top
- confirmed all five freezes committed (A a3911a4/35da83c, B eee60e0/a0b5784, C 62e38c5/2446ae3, D 9a65f51/66aec0f, E 55f6698)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
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>
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>
Verified Lane D's R10 buildFigure span-normalize fix: qa.sh --strict GREEN 6/6 incl. the new
no-giants scale gate (24 interior figs / 6 shops all crown 1.4-2.0m, under-ceiling). The 3.83m I
first measured live was a STALE ES-module cache in a day-old browser tab, not a regression
(served rigs.js + fresh-chromium gate both correct).
Re-shot the v2 tour on the fixed tree: browsers.png now shows human-sized figures (browser at the
rack + keeper at the counter). night_crowd.png re-framed to a readable clean-night "lit VIDEO REGAL
amid CLOSED town" (pulled out of the rain group; reuses night_neon's tighter dist-12 pose).
Honest finding: night_crowd has no visible street crowd and can't without new work. Lane D's night
patronage parks ducked-in patrons hidden INSIDE the shop (they are the interior browsers), and this
seed's video shop is a low-traffic corner (tested: 0 patronage / 0 visible at night). Flagged for D;
a visible outdoor night queue is a v3 mechanic. ~20fps in night captures is a headless software-GL
artifact (scene is light: 128 draws / 65k tris).
Full-default soak PASS (heap 54MB stable, no perf drift, 0 errors). Tour README updated with stable
v2 filenames. v2.0 annotated tag staged separately (push held for John — public release + the
night_crowd caveat on his flagged money shot).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
qa.sh: flags harness warn_gate → run_gate — flags-off regression + the 4 existing flags +
all-on combo are now STRICT (a harness FAIL fails qa). New flags stay warn-level in-harness.
?stock=real wiring (F owns the shell + interior bridge): shell preloads the record stock pack
(preloadStockPack('record'), fail-soft, off under ?noassets) + passes stockReal to the bridge.
interior_mode builds makeStockAdapter(getStockPack(shop.type)) and passes it to BOTH buildInterior
(static crate sleeves) and dig.open (riffle) — null pack → parody canvas (Lane C fail-soft).
Harness: added stock=real smoke (assert non-parody = batched userData.isStock atlas meshes > 0;
verified 7 real sleeves in the record shop) + weather=1 smoke (auto-skips until Lane B lands),
both warn-level (decision #4). qa.sh --strict GREEN (5 gates); crates now show real covers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The first deliberate flags-off baseline change. On D's GO (43edabf: E1 ped sub-mesh merge
447188a validated → ~1 draw/near-rig → full density 241 worst-street draws <=300, leak-free).
index.html: chunk-streamed roster default-on (chunkStream:{radius:2}); ?roster=v1 restores the
old fixed roster (escape hatch); ?roster=stream still accepted (now a no-op). Hours-aware
setNightLivelyChunks keeps the open-late block lively at night.
Flags-off regression baseline RE-PINNED (same commit, prime-law amendment):
OLD (roster-off, v1.1): 163 draws, 19000 tris
NEW (roster default-on, R7): 164 draws, ~66000 tris
Draws barely move — E1's merge makes each near-rig ~1 draw (exactly what gated the flip). The
tris jump is the streamed crowd (D worst-view 65,899); it is frame-variable, so the drift WARN
is now DRAWS-ONLY, tris guarded by the STREET_TRIS_MAX hard cap. PLAN GOLDENS UNCHANGED
(synthetic 0x3fa36874, osm 0x34cfdec0).
Also fixed the harness roster probe (read a nonexistent prop c.streaming → was blind to
streamMode) + flipped the assertion to REQUIRE streamMode on default boot + added a ?roster=v1
escape-hatch check. flags_check GREEN; qa.sh --strict green; 0 console errors both modes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Added an interior draw-budget sweep to flags_check.py (decision #2): enter all 9 shop types,
assert <=350 draws/room, dig on so it also confirms C1's batching kept ?dig=1 riffling.
The sweep caught a real bug in interior_mode.js (F-owned): the interior/dig render never called
renderer.info.reset() while the shell runs autoReset=false (for the composer), so
renderer.info.render.calls ACCUMULATED every frame — inflating any interior draw read (and the
HUD were it shown). Fixed: reset per interior frame before both the dig and the walk render.
True per-frame result after the fix: all 9 room types <=350 draws (worst dept 96) — C1 batching
(35981ad) verified. flags_check GREEN (regression + interior budget + 4 flag smokes + all-on combo).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
tools/flags_check.py — the machine version of the R5 review, headless, self-contained
server, ~90s:
• flags-off regression (prime-law enforcement): plan fingerprint == golden 0x3fa36874,
all v2 subsystems inactive, street view within v1 budget (<=300 draws / <=200k tris),
within 40% of the v1.1 snapshot, 0 console errors.
• per-flag smoke (winmap/dig/roster, +plansrc auto-detected when A lands): boot flag-on,
cross >=2 chunks, enter an interior; dig also opens+closes a riffle. 0 console errors.
• all-on combo (flag-composition law, decision #4): every landed flag on at once.
Wired into qa.sh as a WARN-level gate (strict in r7): --no-flags skips fast; auto-skips
without the Playwright venv; a soft_skip so it never trips --strict readiness. Current tree:
all smokes GREEN, regression clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
C shipped dig.js + the flag but left the in-game input/mode hook to F (LANE_C_NOTES C2).
interior_mode.js (F-owned): aim at a userData.kind==='bin' fitting + press E -> createDig +
dig.open (per-bin seed binSeed(shop.seed,pos)); the dig owns the frame (renders dig.scene,
suppresses interior walk); WALK OUT/Esc closes back to the room; closed on interior exit.
Shell (index.html): ?dig=1 -> dig: opt; procity:digOpen releases pointer-lock (riffle is
cursor-driven); the unlock->leaveShop guard reads interiorMode.digActive so opening a bin
isn't read as walking out; canvas re-locks for interior walk after close.
Fresh-chromium smoke: E opens the riffle (seeded sleeves + prices render), WALK OUT closes
to the interior, leak-free (steady-state geo/tex flat over 3 open/close cycles), 0 console
errors. Flag off => no listener, dig stays null => byte-identical to v1 (prime law).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ROUND3/ROUND4_INSTRUCTIONS.md: 'SUPERSEDED by R5' banner (F4 archive task).
- LANE_F_NOTES §10: round-5 tracking — v2 flag-seam table (?plansrc/?winmap/?dig/?roster,
all pending owning-lane specs), v2 QA-harness plan, v1.1 watch.
- F-progress: round-5 section. Confirmed fal already un-parked at 039c179 (no F change needed).
- v1.1 tag is on watch for Lane C re-map (C1) + Lane E hero-prop bake (E1).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Gate table (LANE_F_NOTES §4) rewritten to R4 all-green with measured evidence:
1 determinism (selfcheck 1301/1301, fingerprint 0x3fa36874) · 2 soak (37 chunks/20 shops,
heap 38->38MB, 0 errors, leak-free) · 3 budget (draws 138/tris 31k, decimated peds) ·
4 asset-free (heap 13->13MB, 0 net) · 5 selfchecks (qa.sh --strict 4/4, 23 GLBs on depot) ·
6 shots (10 full-frame 1280x720, no letterbox, night closed-facade + real interiors).
shots.py: interior tour shots (record/opshop) now capture via DBG.enterShop(id) directly —
they were passing {type} to enterShop (needs id) then calling shot() (which forces street
mode), so both showed streets. Now they show the themed interiors with keeper + hero props.
Verified by a 6-auditor adversarial v1-readiness workflow -> GO.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Gate 3 (budget) official re-measure vs committed decimated peds (E1 518678d, D2
signed off a5e4b64): busiest node, pop 200, midday, 12-yaw peak -> draws 138 (<=300),
tris ~31k (<=200k). Baseline was 372k. Green.
D3 (a5e4b64) made the impostor toneMapped:true so exposure is global via
renderer.toneMappingExposure; citizens.setExposure() became a no-op, so the F1 wire is
removed (removing it before D's commit would have regressed night brightness). Boots
clean, 0 console errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>