# PROCITY — Round 16 lane instructions (from Fable, integrator) Date: 2026-07-16 · **v3.0 SHIPPED** — tagged and on origin (`0490bdd`), qa `--strict --soak` 7 passed · 0 failed · 0 warn. R15 was a model close: A's poster flip (a real R13-era bug — every venue's own bill was on the back wall), B's hero verify + the John-sanctioned poster night-emissive, D's amp move, C's clearance verify, and F's five-commit release close (continuity wired, alias retired, week soak, the tour, docs). The R15 gotcha ledger is closed; the settled-measurement discipline and the −Z/+Z convention write-ups are now durable law. Round 16 is **v3.1: THE FLIP** — the town shows its best by default. `?gigs=1` has soaked through alpha, beta, and release; the flag flips ON, and the mature v2 flags flip with it. Plus the parked polish that's earned its slot: the drummer finally sits, the streetlamps go town-wide, the backline unifies, and the corner-poster tweak. Tag **`v3.1`** at close. ## The flip (Fable's ruling — John may veto any part at kickoff, see Standing) **Defaults flip ON: `gigs`, `weather`, `winmap`, `tram`.** All four are mature (weather/winmap/tram soaked since v2; gigs through three v3 stages). Each keeps an individual opt-out (`?gigs=0`, `?weather=0`, `?winmap=0`, `?tram=0`), and a new **`?classic=1`** forces all four off at once. **The prime law is REWRITTEN, not repealed — the covenant moves to `?classic=1`:** - **Classic law:** the `?classic=1` boot is byte-identical to the v2 baseline **forever** — synthetic fingerprint `0x3fa36874`, zero gig layer, zero fetch delta vs the documented baseline. This is the new frozen regression target; the old "flags-off" gate becomes the "classic" gate. - **Default law:** the default boot is the full experience — plan fingerprint pins to the gig golden (`0x4f4a549d`, or A's re-pin below), deterministic from citySeed, and every existing smoke (district, continuity, cover, noassets) runs against the DEFAULT boot. - `?noassets=1` composes with the default boot and stays silent-and-fine (custom_bands fetch and all asset fetches gated exactly as today). Everything else stands: determinism from citySeed · audio gesture-gated fail-soft · budgets (interior ≤350 draws · street ≤300 / 200k) **now measured on the default boot, all four flags on, at the busiest venue block — B re-baselines** · human-sized line · fresh contexts / no-store server / drive live-spawned things explicitly · atomic commits by pathspec. ## The ledger 1. **The flip itself (F).** Shell defaults + `?classic=1` + the individual `=0` opt-outs, then the harness: `flags_check.py`'s "flags-off regression" arms swap to **classic regression** (`?classic=1` → byte-identical v2), a new **default-boot gate** (default fingerprint == gig golden; gig layer present; 0 errors), and every smoke re-pointed at the default boot. qa.sh gate names updated. This is the round's structural change — land it FIRST. 2. **The drummer sits (E produces, D wires).** E: fetch `Sitting_Idle.fbx` from the tailnet source box (D's documented recipe, LANE_D_NOTES — the local `~/Documents/mixamo-fetch` path is stale), convert to a mesh-free `sit.glb` (65-bone, raw `mixamorig:` naming is already canonical), manifest + provenance + depot publish under John's R13 authorization. D: the shared-rig-stack wiring — a `_rotWithHips` variant (keep `Hips.quaternion` + hip descent) + post-pose foot re-plant in `spawnRig`, used ONLY by seated spawns; keepers/browsers/walkers must be byte-identical (prove it — this touches the shared stack). Drummer retires `SEAT_DROP` and the `m.seated` sink. **Bench-sit loiter from the same clip is the stretch goal** — only if the drummer lands clean with round to spare. 3. **Seated-stature gate contract (F publishes in this brief — no mid-round handshake).** A seated figure fails the no-giants floor by design. Contract: D tags seated figs `fig.userData.procitySeated = true`; F's `interior_scale_check.py` + `flags_check.py` stature asserts accept seated figs at **stature ∈ [0.9, 1.5] m** (still < ceiling, feet planted). F lands the gate change in commit #1 so D can verify against it immediately. 4. **Town-wide streetlamp pools (B).** Ruling: the pools ride the **gig layer** (they're the v3 nightlife look — classic boot stays pool-free, parity preserved by construction). Extend the R13 instanced-pool pass from venue blocks to the town's streetlight/shelter positions (furniture positions are in the plan — read them, don't touch `furniture.js`). Night-driven as now. Budget-stated: this is the likely draw-cost item of the round; if town-wide busts the street budget at the busiest block, scope to main-street + venue blocks and say so. 5. **`stage.backline[]` unification (C, then D).** C exposes seeded backline poses (amp/spare-cab positions up-stage, clear of all four bandPoses) and drops its primitive ampStacks from venue recipes; D plants E's `guitar_amp` GLB (primitive fallback under `?noassets`) at `backline[]` instead of its own hardcoded pose. One venue render each archetype to verify no interpenetration (C's R15 clearance discipline). 6. **Corner-poster tweak (A).** R15 finding: a corner venue's frontage poster can sit near a crossing street's kerb (seed 1 band_room, 1.58 m). Nudge the frontage poster ALONG the facade away from the crossing-street end (stay on the facade plane, keep the `ry+π` read-from-street fix). Moves `plan.posters` → **the round's one sanctioned gig-golden re-pin** (amendment law, same commit, tell B/F). Re-run the 400-seed sweep; keep the frontage-poster exemption honest (assert distance-to-crossing-kerb ≥ some floor now that you control it). 7. **No-spine osm fixture (A).** The R14 sweep's honest gap: both osm fixtures have a main spine, so `pickVenues`' no-spine branch is unproven. Build the minimal single-row fixture and add it to the sweep. Parked still (v3.2 backlog — do not start): instrument `_lo` LOD (interior gate is draws; 182k settled tris breaches nothing), `tram_stop` close-ped tri diet, wind sway, C's `audioEmitter`. ## Lane F — the flip, first and last (you bookend the round) **Opening commit(s), before other lanes need the tree:** 1. Ledger #1 — the shell flip + `?classic=1` + harness rework. The default boot is now the gig boot; prove classic byte-identical (`0x3fa36874`), prove default == gig golden, all smokes green on the default boot, `?noassets` silent-and-fine on the default boot. 2. Ledger #3 — the seated-stature gate contract, same opening push. **Closing, after all lanes land:** 3. Re-run everything: `qa.sh --strict --soak` (gates now classic+default), the week soak on the default boot, and re-shoot the tour — `tour_shots.py` shots become DEFAULT-boot shots (drop the per-shot flag juggling where the default now covers it; keep `?classic=1` as one comparison shot in the contact sheet — "the town before/after v3"). New shots into `docs/shots/release_v3_1/`. 4. Docs: CITY_SPEC gets the v3.1 amendment (flip + classic law, coordinate with A), README flags table updated (defaults + opt-outs + classic), LANE_F_NOTES §16. 5. Tag **`v3.1`**, push main + tag (standing authorization). ## Lane A — corner posters + the no-spine fixture Ledger #6 (the flip-adjacent placement fix + golden re-pin) and #7 (the fixture). CITY_SPEC v3.1 amendment wording with F (you own the spec; F owns the flags table). Nothing else — your sweep and freeze machinery is exactly right as-is. ## Lane B — town-wide pools + the default re-baseline 1. Ledger #4 — the pools, town-wide, gig-gated, night-driven, instanced. 2. **Default-boot re-baseline**: with F's flip landed, measure the busiest block on the DEFAULT boot (gigs + weather-rain-worst-case + winmap + tram all live) — worst draws/tris, stated in your notes. This is the number the budget law now means. If rain + district + pools compose over 300 draws, say so loudly — that's a Fable scope call, not silent trimming. 3. Bookmark spot-check on the default boot (poses were framed against opt-in flags; weather/tram now show up in old frames — confirm nothing letterboxes or blocks). ## Lane C — the backline handoff Ledger #5, C's half: `stage.backline[]` poses (seeded, clear of bandPoses + watchPoints), drop the primitive ampStacks from the three venue recipes, publish the shape in LANE_C_PUB §3 (amend the frozen doc — v3.1 marker, same discipline as A's spec amendments). Verify with D once wired. ## Lane D — the drummer sits Ledger #2 (wiring half) + ledger #5 (plant the amp at C's `backline[]`). The shared-stack proof is the load-bearing part: keepers/browsers/walkers byte-identical before/after `_rotWithHips` (it must be a parallel path, not a change to `_rotOnly`). Tag seated figs per ledger #3. Bench-sit is stretch — drummer first, prove it, then decide. ## Lane E — the sit clip + provenance Ledger #2 (asset half): fetch → convert → `sit.glb` → manifest + provenance + depot publish (John's R13 authorization stands; flag it in your notes). Update the frozen provenance table with a v3.1 amendment marker. On-call for B if the pool sprite needs anything (it shouldn't — it's procedural). ## Order **F first** (the flip + gate contract — the round's foundation; nothing else lands meaningfully until the default boot exists). Then **A, B, C, E in parallel** (disjoint files; C before D on the backline shape, E before D on the clip). **D** once C's backline + E's clip + F's gate are in. **F last** (re-baseline acceptance, tour, docs, tag `v3.1`). Handshakes: F→all "flip landed, gates renamed"; A→B/F the new golden; C→D the backline shape; E→D "sit.glb on depot"; B→F the default worst-case numbers. ## Standing - **John — one decision, veto-by-kickoff:** the flip scope. Fable flips **gigs + weather + winmap + tram** ON by default (`?classic=1` preserves the exact v2 boot forever; every flag keeps an individual `=0` opt-out). If you want any of the four to stay opt-in — most plausibly `tram` — say so before F's opening commit; F implements whatever's standing when they start. FYI: the gig golden re-pins once (A's corner-poster fix), and E publishes `sit.glb` to the depot under your R13 authorization. - **v3.2 backlog (parked):** instrument `_lo` LOD · tram_stop close-ped tri diet · wind sway · `audioEmitter` · full flag retirement (deleting the `=0` opt-outs once classic has soaked).