PROCITY/docs/LANES/ROUND7_INSTRUCTIONS.md

234 lines
15 KiB
Markdown
Raw Permalink 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 — Round 7 lane instructions (from Fable, integrator)
> **⚠ SUPERSEDED by [ROUND8_INSTRUCTIONS.md](ROUND8_INSTRUCTIONS.md) (2026-07-14).** Round 7 is
> complete — roster flipped to default, `?stock=real` live, harness strict, v2.0-beta tagged
> (`4feba02`). B (weather) and A (osm parity) slipped — round 8 carries both §Lane A and §Lane B
> verbatim; everything else is historical reference only.
Date: 2026-07-14 · Written after the Fable round-6 review (`6948372`) and the **v2.0-alpha
tag**. You are an Opus 4.8 agent assigned ONE lane (read your session prompt). Read this
file, your lane spec, your `<X>-progress.md`, and NOTES addressed to you first.
Repo state: everything committed on `main` at `6948372` = `v2.0-alpha`. `tools/qa.sh
--strict` GREEN **5/5** (incl. the v2 flags harness at warn level). Four v2 flags live,
default-off: `?plansrc=osm` · `?winmap=1` · `?dig=1` · `?roster=stream`. Goldens: synthetic
`0x3fa36874`, osm `0x34cfdec0`. Interior law ≤350 draws/room (worst 313, sweep asserts).
27 procity GLBs live. fal balance ~$21.36. Tags `v1.0`/`v1.1`/`v2.0-alpha` await John's push.
## Theme: the flip round + the content firehose
Round 6 built the machinery; round 7 turns two keys:
1. **`?roster=stream` becomes the DEFAULT.** D's readiness memo says it's deterministic,
leak-free, hours-aware, and composes — gated only on one optimisation (the ped sub-mesh
merge, so full density fits the draw budget). E merges, D validates, F flips.
2. **Real stock enters the dig** (the reason this system exists — V2_IDEAS #1, deferred
twice): a curated GODVERSE content pack feeds C's `stockAdapter` behind `?stock=real`,
so the crates you riffle hold *real* record sleeves instead of parody canvas.
Plus: the flags harness graduates **warn → strict**, B ships weather, A hardens osm mode.
End-of-round milestone: **`v2.0-beta`** (F tags; criteria in decision #6).
## Prime-law amendment (read carefully — the baseline moves this round)
The v2 prime law ("default boot stays v1-identical") gets its first **deliberate,
versioned** exception: when F flips the roster default, the default boot changes. Protocol
(decision #1): the flip commit and the flags-off-baseline re-pin happen in ONE F-owned
commit, with the old baseline recorded in the commit message. **Plan goldens do NOT move**
(`0x3fa36874` / `0x34cfdec0` — the plan layer is untouched by the roster). Any other lane
whose feature would move the default boot: that's still a land-blocker — the exception is
the flip only.
## Integrator decisions (so nobody blocks)
1. **Roster-flip protocol**: E1 (sub-mesh merge) → D1 (validate + full-density numbers) →
F1 (flip default; keep `?roster=v1` as the escape hatch back to the fixed roster;
re-pin the flags-off draws/tris baseline in the same commit). Order is strict — no lane
pre-empts the flip.
2. **Real-stock scope**: read-only content, NO economy backend. E builds the pack offline
from GODVERSE (`~/Documents/dealgod/GODVERSE.md` — recordgod's 185k vinyl w/ images is
the target): curate ~200400 sleeves per record-shop archetype (+ optional small packs
for book/toy if cheap), bake into atlas textures + a JSON index (id, title, artist,
price band, atlas UV), publish atlases to the depot like any asset. C consumes behind
`?stock=real` through the existing `stockAdapter` seam. Buying stays a stub. `?noassets`
and flag-off behavior untouched. **No runtime network beyond the existing depot path;
no databases; nothing from GODVERSE checked into the repo except the built pack index
if it's small.** Parody-name law: run titles/artists through the same
no-real-trademarks screen as everything else — if the source data is real-world
metadata, parody-transform it in the pack builder (deterministic).
3. **Weather is B's round**, behind `?weather=1`: seeded per-day weather state (clear /
overcast / rain), rain particles + wet-ground response, wind sway on awnings/trees if
cheap. The sky domes for it already exist in `web/assets/gen/`. Tram loop is a stretch
goal ONLY if weather lands early (`?tram=1`, instanced, one path over B's bus_shelter
stops, no traffic sim).
4. **Harness graduates to strict** (F, after the flip lands): a red flags-harness now
fails qa.sh. New flags this round (`stock`, `weather`, `tram` if it lands) enter at
warn and graduate next round.
5. **fal**: no new spends. Broken-prop re-gen clause (≤2 attempts, logged) still stands.
6. **Tag `v2.0-beta`** (F, end of round) when: roster default-on + escape hatch verified ·
flags harness strict + green · `?stock=real` riffles real sleeves in a record shop ·
`?weather=1` rains · qa strict green. If stock OR weather slips, tag anyway with what
landed and note it — same no-hostage rule as always.
## Process rules (unchanged)
- ONE shared working tree. `git status` first; stage only your files by exact path;
options before `--`; `add` new files first; commit immediately; pin a durable lane ref.
- Leave `qa.sh --strict` GREEN. Update `<X>-progress.md`; cross-lane asks in your NOTES.
- F owns `web/index.html` + `tools/`; document call sites for F.
- `procityprogress.txt` / `settings.local.json` stay untracked.
- Repo `/Users/m3ultra/Documents/procity`; GODVERSE reference `~/Documents/dealgod`;
dev server `:8130`.
## Sequencing
```
E1 (ped sub-mesh merge) ──→ D1 (validate + density numbers) ──→ F1 (FLIP + re-pin baseline)
E2 (GODVERSE stock pack) ──→ C1 (?stock=real in the dig) ──────→ F2 (strict harness + new smokes)
B1 (?weather=1) · A1 (osm parity + 2nd town) ── parallel ──────→ F3 (tag v2.0-beta)
```
E has both feeder tasks — start E1 immediately (it gates the flip), E2 right after.
F1 lands before F2 (strict) so the baseline only re-pins once.
---
## Lane A (Citygen) — osm mode to parity + a second town
The Melbourne import works; make osm a first-class citizen, not a demo.
1. **Selfcheck parity**: parameterize the full selfcheck suite by plan source so osm plans
get the same invariant coverage as synthetic (lots/shops integrity, hours contract,
exactly-one openLate, storeys ranges, determinism, <100ms). Wire so `qa.sh` runs both
(F already pins both goldens extend the checks behind them).
2. **A second fixture town**: extract another AU town from the thriftgod cache (different
scale/shape than inner-Melbourne a smaller coastal or regional strip is ideal)
`?plansrc=osm&town=<key>`. Same laws: checked-in module fixture, zero network,
deterministic, pinned golden per town (give F the hashes).
3. **Document the "add a town" recipe** in LANE_A_NOTES (fixture extraction module
golden pin) so future towns are mechanical.
4. Watch for: osm towns must satisfy the SAME downstream contracts (openLate exactly-one,
registry types, hours sanity) if a real town's data fights a contract, the importer
normalizes it (and logs what it changed), the contract doesn't bend.
**Acceptance**: full selfcheck green on every (source, town); second town boots end-to-end;
recipe documented; both plan goldens unchanged, new town's golden pinned; qa green.
## Lane B (Streetscape) — weather
`?weather=1` (decision #3). Seeded, deterministic, cheap.
1. **Weather state**: seeded per (citySeed, day) clear / overcast / rain (weights feel
AU-plausible). Expose `window.PROCITY.weather` for other lanes (D may thin crowds in
rain later; not this round).
2. **Rain**: a particle layer (instanced/points, ONE draw), audible-later, camera-following;
wet ground = roughness/darkening response on street surfaces; puddle sheen if cheap.
Sky: pick the matching dome from the existing `sky-*.jpg` set (summer storm / grey
drizzle are already in `web/assets/gen/`).
3. **Wind**: subtle sway on awnings + trees during overcast/rain if it fits the budget
vertex-shader time offset, not per-frame CPU.
4. **Budget + composition**: worst view 300 draws with weather on; works with winmap
(rain outside a lit window is the money shot screenshot it), night, and interiors
(rain audio/visual stops inside; interiors are separate scenes so mostly free).
5. **Stretch ONLY if 14 land early**: `?tram=1` one instanced tram/bus on a seeded
main-street loop over your bus_shelter stops, door-stop pause at each. No traffic sim.
**Acceptance**: `?weather=1` deterministic per seed/day; rain + wet ground + matching sky
render; 300 draws; composes with winmap/night; flag-off identical; screenshots (incl.
rain-through-window); qa green.
## Lane C (Interiors) — real sleeves in the crates
`?stock=real` (decision #2). The stockAdapter seam you built in v1 finally eats.
1. **Define the pack contract with E** (you own the consumer side): what the JSON index +
atlases must provide per item (title/artist/price-band/atlas+UV). Put the agreed schema
in LANE_C_NOTES *first* so E builds against it a half-day handshake beats a rework.
2. **Consume**: when `?stock=real` and the pack is available (depot or `?localdepot=1`),
record-shop bins draw sleeves from the pack (seeded pick per bin same seed, same
crate contents) instead of parody canvas; the dig riffle shows real covers + pack
titles/prices; the pull-out card shows title/artist/price.
3. **Laws**: deterministic per shop.seed · leak-free (atlas textures dispose with the room
or share via the loader cache prove with the soak) · 350 draws (atlas = the sleeves
stay batched; assert via drawSweep) · `?noassets` and flag-off untouched · fail-soft
(pack missing parody canvas, warn once).
4. **Extend the dig soak**: `?dig=1&stock=real` enter/riffle/exit × N rooms, zero leaks,
determinism.
5. If E's pack covers book/toy too, wire those shelves as a bonus record shops are the
acceptance bar.
**Acceptance**: riffling a bin with `?stock=real` shows real (parody-screened) sleeves with
titles/prices, deterministic + leak-free + 350 draws; fail-soft proven; contract doc'd;
qa green.
## Lane D (Citizens) — validate the merge, hand F the flip
1. **D1 — validate E1's merged peds** (the flip gate): rigs bind + animate (walk/idle),
silhouettes/materials intact, impostor bake clean, identity variety preserved. Then the
numbers: draws-per-near-rig before/after, worst-view draws/tris at FULL density
(`?roster=stream`, no reduced-density concession), 30-chunk soak leak-free. Write the
go/no-go into LANE_D_NOTES with the exact figures F flips on your word (decision #1).
2. **Full-density defaults**: with the merge in, set the stream path's density/near-cap
defaults to the values your memo said full density needs these become the shipping
defaults when F flips.
3. **Post-flip verification** (after F1 lands): default boot runs the streamed roster
re-run your determinism + far-field-density + leak checks on a NO-FLAG boot; verify the
`?roster=v1` escape hatch actually restores the fixed roster.
4. Do NOT start rain-behavior/schedules/queues crowds react to weather in a later round.
**Acceptance**: merged peds validated with published numbers; go/no-go memo written; after
the flip, no-flag boot passes your full check suite; escape hatch verified; qa green.
## Lane E (Assets) — the two feeders
Both critical-path. E1 gates the flip; E2 gates the stock. In that order.
1. **E1 — ped sub-mesh merge (START IMMEDIATELY).** Per-ped GLBs carry multiple
primitives/materials multiple draws per near rig. Merge to (ideally) ONE primitive +
one atlased material per ped: gltf-transform `join`/`palette`/`instance` pipeline
**preserving skinning (joints/weights), morphs if any, and compatibility with the shared
walk/idle clips**. Backup originals (gitignored), process all 19, verify each loads +
binds in the vendored GLTFLoader, record before/after draws+tris in AUDIT.md, hand to D.
2. **E2 — the GODVERSE stock pack.** Build `pipeline/build_stock_pack.py`: read recordgod
data from `~/Documents/dealgod` (fixture-extract like A's pattern the pipeline reads
the local dataset at build time; NOTHING queries it at runtime), curate 200400 sleeves
(image quality + variety), **parody-transform titles/artists deterministically** (the
no-real-trademarks law applies to metadata too), bake atlas PNG/WebPs + JSON index to
C's schema (wait for C's contract note it's their task 1), publish atlases to the
depot, stage for `?localdepot=1`. Provenance in AUDIT.md (source dataset, count,
transform). Small packs for book spines / toy boxes only if the record pack lands early.
3. **On-call**: B may want a rain-streak sprite or puddle texture (procedural first
generate only if truly needed, flux_local, free).
**Acceptance**: E1 all peds single-draw (or documented floor), skinned + animating, D
signs off; E2 pack published + staged, index validates against C's schema, parody screen
run, provenance logged; qa green (incl. your own provenance-drift gate).
## Lane F (Integration) — flip, tighten, tag
1. **F1 — the roster flip (after D1's go).** In `web/index.html`: streamed roster becomes
default; `?roster=v1` restores the fixed roster; `?roster=stream` stays accepted (now a
no-op). **Same commit**: re-pin the flags-off regression baseline (draws/tris snapshot)
to the new default boot, old values in the commit message (prime-law amendment). Plan
goldens untouched. Then boot no-flags + escape hatch and eyeball both.
2. **F2 — harness to strict (after F1).** Flags harness failures now fail qa.sh. Add
smokes for the new flags as they land: `stock=real` (enter record shop, open dig,
assert non-parody sleeve count > 0), `weather=1` (boot, assert particle layer + wet
response active, 0 errors), `tram=1` if B ships it. New flags enter at warn (decision
#4), existing four + flags-off are strict.
3. **F3 — tag `v2.0-beta`** (decision #6 criteria): summary tag message with the flip
baseline note; update flags table + runbook + F-progress. Local; John pushes (remind
him v1.0/v1.1/v2.0-alpha are also still unpushed).
4. **Marshal**: this round has two hard sequams (E1→D1→F1, E2→C1) — if a lane stalls,
flag it in F-progress early rather than at round end. The R5 lesson (silent no-show)
now has a harness for code, but not for schedule — you're the schedule harness.
**Acceptance**: default boot = streamed roster with re-pinned baseline + working escape
hatch; harness strict + green with new-flag smokes; `v2.0-beta` tagged on a green tree;
runbook/flags table current.
---
*— Fable (integrator). Two keys turn this round: the town gets permanently busier, and the
crates get real. Both have hard sequencing — respect the arrows, commit atomically, pin
your refs, leave it green.*