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>
16 KiB
PROCITY — Lane F progress (INTEGRATION & QA)
Session: 2026-07-14 · Author: PROCITY-F · For review by: fable
Round 5 (v1.1 close-out + v2 foundations) — IN PROGRESS
Lane F role: v1.1 watch + v2 flag-seam wiring + QA-harness-for-v2 + shared-tree marshal.
Full tracking in LANE_F_NOTES §10.
| task | status |
|---|---|
| fal un-park check | ✅ Verified already done — 039c179 un-parked fal in Lane E's brief (decision #4 + Lane E task 3: glass-case + bus-shelter + optional magazine-rack, ≤2 attempts, costs logged in AUDIT.md). Nothing for F to change. |
| archive R3/R4 instruction claims (F4) | ✅ Added "SUPERSEDED by R5" banner to ROUND3_INSTRUCTIONS.md + ROUND4_INSTRUCTIONS.md. |
| v2 flags table (F4) | ✅ Scaffolded in LANE_F_NOTES §10 (?plansrc=osm A, ?winmap=1 B, ?dig=1 C, ?roster=stream D) — all pending owning-lane specs. |
| F1 tag v1.1 | ✅ TAGGED. C1 (aa9c140: record_crate fixed + counter_till re-map) + E1 (c522464: 6 hero props baked 288k→48k, ≤8k each, live on depot) landed. Verified: depot serves baked props (counter_till 7999, drinks_fridge 8000, listening_booth 7986 tris ≤8k), C's glb.js maps them, record/opshop interiors render the counter_till GLB with keeper stand pose working + no double till, bins upgraded. Re-captured the 2 interior tour shots (fresh chromium → baked props). qa GREEN. git tag v1.1 (local). |
F2 wire ?dig=1 |
✅ DONE + verified. C shipped dig.js + the flag but left the in-game input/mode hook to F (LANE_C_NOTES §C2). Wired the consumer pattern into interior_mode.js (F-owned): aim at a userData.kind==='bin' fitting + press E → createDig/dig.open (per-bin seed via binSeed(shop.seed,pos)); the dig owns the frame (render dig.scene, no interior walk); WALK OUT / Esc closes → back to the room. Shell seam (index.html): ?dig=1 → dig: opt; procity:digOpen releases pointer-lock (riffle is cursor-driven); unlock→leaveShop guard reads interiorMode.digActive so opening a bin ≠ leaving. Fresh-chromium smoke: E opens riffle (seeded sleeves + prices render), WALK OUT closes to interior, leak-free (steady-state geo/tex flat over 3 cycles), 0 console errors. Flag off ⇒ no listener/no dig ⇒ byte-identical to v1. |
| F2 — other v2 seams | B ?winmap / D ?roster=stream are self-contained (no shell input hook needed); smoked clean (boot, 0 errors, budget OK). A ?plansrc not taken. |
| F3 v2 QA harness | ⏳ determinism gate (first-interior-hash per seed) · flags-off regression check (v2-prime-law enforcement) · v2 smoke → qa.sh warn-gate. Build as flags land. |
Base state: v1.0 (2698b40), qa.sh --strict GREEN 4/4, tree clean.
Round 4 (v1-tag round) — DONE ✅ (all 6 gates green; v1.0 tagged)
Executed Fable's ROUND4_INSTRUCTIONS.md Lane F tasks. All lanes committed R4; a 6-auditor
adversarial v1-readiness workflow returned GO; v1.0 tagged locally on the F finalization commit.
| task | status |
|---|---|
| F1 setExposure | ✅ Wired (9416d0a) then correctly removed (aad9baa): D3 (a5e4b64) made the impostor toneMapped:true, so citizens.setExposure() became a no-op tone-mapped globally via renderer.toneMappingExposure. Removed only after D committed (removing earlier would regress night brightness). Final state: no dead call. |
| F2 storeys-checker | ✅ permittedMax = max>=2 ? min(max+1,3) : max (Lane A's rule, 9416d0a). Consistency 0 warnings across 6 seeds; single-storey-type-at-2 still trips. A confirmed (5b8c806). |
| F3 gate-3 budget | ✅ PASS. E1 decimated peds (518678d, 924k→46k, ≤3k each) + D2 sign-off (a5e4b64, fleet ≈59.6k at 24-cap). Official measure: busiest node, pop 200, midday, 12-yaw peak → draws 138 (≤300) · tris ~31k (≤200k). Baseline 372k. |
| F4 gate-6 shots | ✅ PASS. Against committed B2 (6323d58, dbg.js letterbox+poses): shots.py v1_tour → 10 full-frame 1280×720, no letterbox; §3.5 night closed-facade (CLOSED plates + lit openLate video "VIDEO REGAL") + real record/opshop interiors (keeper + hero props). Fixed shots.py so interior shots capture via enterShop(id) (were falling back to a street bookmark). |
| F5 tag v1.0 | ✅ TAGGED on the F finalization commit (gate table all-green + shots committed). Local only — John pushes. |
| audit | 6-auditor v1-readiness workflow: 5 GREEN (gates 1/3/5/6 + release hygiene) + 1 procedural "land finalization commit first" → resolved. GO. |
Round 3 (lead lane) — DONE, verified live
Executed Fable's ROUND3_INSTRUCTIONS.md Lane F tasks. All wiring verified in-browser on seed 20261990.
| task | result |
|---|---|
| §3.5 hours / closed shops | isOpen() gate on enterShop. Midday: open. Night (22:00): all closed except the openLate video rental (Video Regal [11,23]) — verified toy shop blocked, video enters. |
§3.4 ?noassets |
Zero network (Perf API: 0 GLB/depot/manifest/ped-model requests); 100% primitive, legible. |
| §3.4 interior GLB | useGLB → fitting GLBs load from the 3GOD depot (bookshop shelves, +8 meshes, visually confirmed). |
| §3.4 rig fleet | 19 ped GLBs → peds and keepers upgrade placeholder→GLB rigs; leak-free (shared-cache proven, cycle2/3 flat). |
--depot on qa.sh |
validate_manifest.py --depot = 0 err (16 GLBs live). qa.sh GREEN 4/4. |
| Gate 2 soak | PASS both modes — assets: 20 interiors leak-free (+GLB-cache warmup), heap 98MB stable; noassets: 37 chunks, heap 15MB. 0 console errors. |
| Gate 4 asset-free | PASS. |
| Gate 6 shots | docs/shots/v1_tour/ (10 shots) + contact sheet captured; letterbox + 3 fallback bookmarks are Lane B dbg.js. |
Findings → other lanes (details in LANE_F_NOTES §9):
- D/E: rig ped GLBs are tri-heavy (~45k each) → gate 3 tris ~279k > 200k budget (draws fine ~200/300).
Decimate the ped GLBs; F holds
?pop=140until then. - B: add 3 shots bookmark poses; fix the headless composer letterbox in
DBG.shot(); render the §3.5 closed-facade visual (dark windows + CLOSED plate; predicatewindow.PROCITY.isOpen). - Fixed 5 F-owned harness bugs so
shots.py/soak.pyactually run (DBG async-poll,DBG.plan→PROCITY.plan,enterShopbare-id,shop.lotis an id, midday-pin + GLB-cache warmup + budget→warning).
Git: working tree synced to canonical main (862bbcd) mid-session — my R2 work is committed as aa4ed4f.
R3 edits below are staged by pathspec (see Housekeeping). Nothing pushed.
TL;DR (round 2 — for context)
All five lanes (A–E) landed; F stood up the QA harness, adversarially reviewed and fixed its own tooling, then wired the lanes into a walkable, living town — interiors, shopkeepers, and street crowds all integrated and verified live:
- Interiors — every door opens (§3.2). A door opens into a themed, seeded, self-lit 90s-AU
interior; walk it, walk back out (or Esc), room disposes. Verified across all 9 shop types,
leak-free, worst build 8.4 ms. F-owned bridge
web/js/world/interior_mode.js. - Shopkeepers (§3.3a). A keeper stands at the counter of every shop and turns to greet you; disposed with the room, leak-free over 5 cycles. (Asset-free placeholder; rig-fleet upgrade later.)
- Street crowds (§3.3b). Deterministic pedestrians walk the footpaths (
graph = plan.streetsdirectly), density follows time-of-day (busy midday, empty at night), LOD-tiered. Draw budget holds — worst main-street view ~191 draws (budget 300). Shell wiring inindex.html. - Plan swap (§3.1) + facade skins fix (prior pass): boots on Lane A's real town, textured.
tools/qa.sh is GREEN (4/4 gates, 0 skipped). Remaining: manifest GLB upgrades + ?noassets
(§3.4 — also upgrades keepers/peds to shared rigs), hours/closed-shops (§3.5), draw-budget shave.
Scoped in docs/LANES/LANE_F_NOTES.md §3.4–§3.5,§7.
Lane readiness — ALL COMPLETE ✅ (node tools/qa/scaffold_check.mjs)
| Lane | status | notes |
|---|---|---|
| A CITYGEN | 5/5 | plan.js, registry.js, names.js, selfcheck.js, map.html — determinism gate green, verified in-browser |
| B STREETSCAPE | 4/4 | index.html shell, chunks.js streamer, buildings.js, fixture_plan.js — walkable town verified live |
| C INTERIORS | 2/2 | interiors.js (buildInterior), interior_test.html |
| D CITIZENS | 3/3 | rigs.js, sim.js (CitizenSim), keepers.js (KeeperManager), citizens_test.html |
| E ASSETS | 3/3 | manifest.json (validates green), validate_manifest.py, AUDIT.md + pipeline |
What F built / did this session
QA harness (F-owned, tools/) — trustworthy, all green
| file | what | state |
|---|---|---|
tools/qa.sh |
gate runner; --strict = v1 umbrella |
✅ 4/4 green |
tools/qa/scaffold_check.mjs |
scaffold + PRNG determinism (golden-locked) + live readiness matrix + plan-determinism | ✅ |
tools/qa/consistency_check.mjs |
cross-lane gate: plan ↔ registry ↔ assets ↔ manifest | ✅ |
tools/shots.py · tools/soak.py |
Playwright beauty-tour + 10-min soak/budget/--noassets (gates 2,3,4,6) |
✅ ready; need Lane B window.DBG hook (§4) |
Adversarial self-review (Workflow, 23 agents)
Ran a 4-auditor + verifier workflow against F's own scripts + runbook. It confirmed 14 real defects in F's tooling (false-confidence checks + wrong API assumptions). All applied:
scaffold_check: JSON round-trip was a tautology (fixed → real deep-compare w/-0norm); Math.random-ban regex had false negatives (fixed → anchored to comments); irange golden check re-seeded per draw (fixed → single stream).consistency_check: added a storeys-vs-registry-range check, fixed a dead late-night branch, removed a dead metric.soak.py: heap heuristic no longer silently passes when heap isn't reported; shop count now requires verified interior loads (not justenterShopcalls);--minutesnow honored.shots.py: fixed anIndexErroron a trailing--seed.- Runbook (
LANE_F_NOTES.md): corrected against the real landed APIs —chunkIndexreturns{chunkSize,chunks}(not callable); chunks is acreateChunkManagerfactory with no lifecycle hooks;CitizenSimis graph-driven, not per-chunk; keepers usespawn/remove/disposeAll.
Integration passes (verified live in-browser)
web/js/world/interior_mode.js(new F-owned bridge) + thin marked seam inindex.html→ §3.2 interiors: every door opens.enterShoplooks the shop up in the plan, attaches its lot dims, calls Lane CbuildInterior, and switches to a newinteriormode that renders the room in its own scene and walks it via the room's occupancy grid. Exit on walk-out /procity:exitShop/ Esc →dispose()+ player restored to the door. Verified: door → Toy Shop renders; exit state-machine correct; leak-free (134 geo/37 tex → 217 loaded → 134/37 after dispose); all 9 shop typesok+pathOK, worst build 8.4 ms; 0 console errors.- Keepers (§3.3a) — wired into
interior_mode.js:KeeperManager(no fleet → placeholder actor), spawned at the counter stand pose (places.find(p=>p.userData.keeperStand)), ticked in the interior loop,disposeAll()on exit. Verified: 11-mesh keeper at the counter, greets the player (turns 0.21 rad, eases back), leak-free over 5 cycles/5 types (net growth 0). - Citizens (§3.3b) —
CitizenSiminindex.html:graph = plan.streets(no adapter needed),setPopulation(140)(?pop=),setTimeOfDay((seg+frac)/6)+update(dt)in the street loop,visibilitychange→setPaused. Fixed a NaN bug (getClock().houris a string). Verified: 96 active midday, peds walk footpaths ~1.5 m/s, budget-safe (worst ~191 draws across all main edges). web/js/citygen/index.js(barrel) → game boots on Lane A's real generated town (was the fixture). Verified: console "using Lane A generatePlan", HUD "Boolarra Heads · 493 shops".web/js/world/skins.js(1-line chokepoint fix) →facadeMatnormalizes full-filename skins. Verified:facade-*.jpgrequests now 200 OK, town textured (was all flat-grey).
Docs (F-owned)
docs/LANES/LANE_F_NOTES.md— integration runbook (real APIs, wiring steps, QA gates, DBG hook request).docs/V2_IDEAS.md— parked scope (content firehose, override layer, weather, venue, …).docs/shots/— reference-shot tree (the other lanes are already dropping acceptance shots into it).
Findings for the lanes (F flags; the two blocking-visual ones are already fixed)
| # | lane | finding | status |
|---|---|---|---|
| 1 | B | shell imported non-existent js/citygen/index.js → ran on fixture |
fixed by F (barrel) |
| 2 | B | skins.js facadeMat double-wrapped full-filename skins → facades 404 |
fixed by F (normalize) |
| 3 | B | street measures ~334 draw calls at spawn (radius 3) — over CITY_SPEC ≤300 | open — shave (radius 2 or more merging) |
| 4 | A | ~10% of shop names have a doubled possessive ("Tex's's Toys") — names.js |
open (cosmetic) |
| 5 | A | some shops have storeys outside the registry type range (e.g. video at 2, range [1,1]) | open — confirm corner-anchor intent |
| — | contract | facadeSkin is a full filename in the registry but skins.js expected a bare key |
worth a CITY_SPEC line so ground/awning/interior skins avoid the same trap |
Remaining integration (scoped in LANE_F_NOTES §3; ready to execute)
- ✅
Interiors (§3.2)— DONE. - ✅
Citizens + keepers (§3.3)— DONE (both verified live; see Integration passes above). - Manifest +
?noassets(§3.4) — GLB upgrades frommanifest.json; primitive-fallback flag. Doubles as the rig-fleet upgrade that makes keepers/peds cheap (shared meshes) so?pop=can rise. - Hours / closed shops (§3.5) and the draw-budget shave (finding 3).
- Full QA gates 1–4,6 once Lane B exposes the
window.DBGhook (§4) my harnesses drive.
Next natural step is §3.4 (manifest + ?noassets) — it's the asset-free gate AND the fleet upgrade
that upgrades placeholder keepers/peds to shared GLB rigs. §3.5 (hours) is a small data-driven follow-on.
Note on verification: pointer-lock doesn't engage in the automated browser, so a real walk is
best playtested by a human (cd web && python3 -m http.server 8130 → localhost:8130?seed=20261990).
F drives/inspects via window.PROCITY + JS for programmatic checks.
Housekeeping
- Nothing committed (all working tree). F's edits are minimal, commented
[Lane F integration], reversible. New F-owned file:web/js/world/interior_mode.js(interior + keeper bridge). Shell seam edits inindex.html: interior wiring (import, bridge create,enterShop/leaveShop, loop branch,setModelock, Esc-exit, M/P guards,window.PROCITYhooks) + citizens (import,CitizenSimcreate +setPopulation, street-loopsetTimeOfDay+update,visibilitychangepause). Also edited:skins.js(facade fix, prior pass). Suggested commit once reviewed — use a pathspec (lanes share one tree, see memory):git commit -- web/js/world/interior_mode.js web/index.html web/js/world/skins.js web/js/citygen/index.js tools docs/LANES/LANE_F_NOTES.md docs/V2_IDEAS.md docs/shots F-progress.mdmsgLane F: integration — interiors + keepers + street peds + QA harness + barrel + skins fix. - A local
python3 -m http.server 8130is running for the smoke test (harmless; kill when done). - Lane prompts hard-code
/Users/jing/Documents/PROCITY; real path is/Users/m3ultra/Documents/procity.