# PROCITY — Lane F progress (INTEGRATION & QA) **Session:** 2026-07-14 · **Author:** PROCITY-F · **For review by:** fable --- ## TL;DR 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: 1. **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`](web/js/world/interior_mode.js). 2. **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.) 3. **Street crowds (§3.3b).** Deterministic pedestrians walk the footpaths (`graph = plan.streets` directly), 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 in [`index.html`](web/index.html). 4. **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`](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/ `-0` norm); 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 just `enterShop` calls); `--minutes` now honored. - `shots.py`: fixed an `IndexError` on a trailing `--seed`. - **Runbook** (`LANE_F_NOTES.md`): corrected against the **real landed APIs** — `chunkIndex` returns `{chunkSize,chunks}` (not callable); chunks is a `createChunkManager` **factory** with no lifecycle hooks; `CitizenSim` is **graph-driven, not per-chunk**; keepers use `spawn/remove/disposeAll`. ### Integration passes (verified live in-browser) - **`web/js/world/interior_mode.js`** (new F-owned bridge) + thin marked seam in `index.html` → **§3.2 interiors: every door opens.** `enterShop` looks the shop up in the plan, attaches its lot dims, calls Lane C `buildInterior`, and switches to a new `interior` mode 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 types** `ok+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)** — `CitizenSim` in `index.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().hour` is 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) → `facadeMat` normalizes full-filename skins. Verified: `facade-*.jpg` requests 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) 1. ✅ ~~**Interiors (§3.2)**~~ — **DONE**. 2. ✅ ~~**Citizens + keepers (§3.3)**~~ — **DONE** (both verified live; see Integration passes above). 3. **Manifest + `?noassets` (§3.4)** — GLB upgrades from `manifest.json`; primitive-fallback flag. Doubles as the **rig-fleet upgrade** that makes keepers/peds cheap (shared meshes) so `?pop=` can rise. 4. **Hours / closed shops (§3.5)** and the **draw-budget shave** (finding 3). 5. **Full QA gates 1–4,6** once Lane B exposes the `window.DBG` hook (§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 in `index.html`: interior wiring (import, bridge create, `enterShop`/`leaveShop`, loop branch, `setMode` lock, Esc-exit, M/P guards, `window.PROCITY` hooks) + citizens (import, `CitizenSim` create + `setPopulation`, street-loop `setTimeOfDay`+`update`, `visibilitychange` pause). 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.md` msg `Lane F: integration — interiors + keepers + street peds + QA harness + barrel + skins fix`. - A local `python3 -m http.server 8130` is running for the smoke test (harmless; kill when done). - Lane prompts hard-code `/Users/jing/Documents/PROCITY`; real path is `/Users/m3ultra/Documents/procity`.