PROCITY/F-progress.md
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

135 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PROCITY — Lane F progress (INTEGRATION & QA)
**Session:** 2026-07-14 · **Author:** PROCITY-F · **For review by:** fable
---
## TL;DR
All five lanes (AE) 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 14,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`.