203 lines
14 KiB
Markdown
203 lines
14 KiB
Markdown
# PROCITY — Round 37 instructions (from Fable, integrator)
|
||
|
||
Date: 2026-07-26 · **v8 opens.** Charter: [V8_SOMEONE_LIVES_HERE.md](../V8_SOMEONE_LIVES_HERE.md)
|
||
· evidence: [REVIEW_CITY_PATTERNS.md](../REVIEW_CITY_PATTERNS.md) (16-agent audit) ·
|
||
[ANIMALS_ANSWER.md](../ANIMALS_ANSWER.md) (5-agent spike). **Read the charter first.**
|
||
|
||
Round 37 is **WAVE 0 — THE FLOOR**. No content. Five micro items that every v8 content idea
|
||
stands on. John's rulings are made: **the kerb is FOOTPATH**, **real towns get the content**,
|
||
**animals are generated not downloaded**. Nothing here is a design question; it is execution
|
||
plus honest measurement. **No tag this round** — wave 0 closes when the floor is level.
|
||
|
||
## The ledger
|
||
|
||
### 0.3 — SETTLE THE BUDGET OF RECORD *(Lane F, and it goes FIRST)*
|
||
Two independent measurements disagree and **no proposal may spend against a number nobody can
|
||
reproduce**: the city-patterns audit measured a **walked worst frame of 280/300 draws** (8 m
|
||
steps down the main spine, carrying the R+1 dispose window at up to 31 live chunks); the animal
|
||
spike re-measured and got **191 default / 167 classic** by teleport-walk and could not
|
||
reproduce 280. Both were headless (SwiftShader). Settle it:
|
||
- Walk it properly — real continuous motion, not bookmark teleports, sampling every frame
|
||
through the chunk dispose window, on the default boot AND `?classic=1`.
|
||
- If you can get a real-GPU number, say so and say how; if not, state that the number is
|
||
headless and what that costs in confidence.
|
||
- **Re-pin the budget of record** in the docs that assert it, and state the tri number the same
|
||
way (99–124k of 200k was the audit's range; two sessions disagreed enough that it needs a pin).
|
||
- **Settle ONE shared instance cap** for future town-wide standing layers (three animal
|
||
proposals independently invented 120, 250 and "plus gulls" for the same layer). One number,
|
||
written down, with the reasoning.
|
||
Deliverable: the pinned numbers + the method, in LANE_F_NOTES §37 and wherever the laws are
|
||
asserted. This unblocks everyone else's budget claims for the whole epoch.
|
||
|
||
### 0.1 — THE KERB: FOOTPATH *(Lane A ruling-side · Lane B code · Lane F gate)*
|
||
John's ruling: the 9 m band between kerb and shopfront is **footpath**. Lane A's published
|
||
corridor law (`roadWidth` / `vergeBand` / `poleOffset` in `core/registry.js`) is the single
|
||
source of truth and Lane B adopts it.
|
||
- **B:** extend the **existing merged `footGeos` class** inward from `e.width/2` to
|
||
`roadWidth(e)/2` in `ground.js`. **This must stay +0 draws** (same merged mesh) — if it
|
||
cannot, stop and report rather than paying a draw. Expect ~2k tris and *better* fill-rate
|
||
(18 m of every main street stops being painted as road). **Special-case or it breaks:**
|
||
`arcade` (`roadWidth` 0 → zero-area road quad + coincident kerbs) and `lane`
|
||
(`vergeBand` = [2,2]). Grass verges survive on **residential edges only**.
|
||
- **B:** ship **`?verge=0`** — a permanent flag that reverts to the pre-ruling geometry. It is
|
||
the gate's falsifiability control and it costs nothing; it stays in the codebase forever.
|
||
- **A:** the corridor law is yours — confirm the exports are what B should consume, and fix the
|
||
selfcheck's poster-clearance assertion, which currently validates against `roadWidth/2` (5 m)
|
||
while B painted bitumen to 14 m, i.e. **the gate was green while 14 gig posters stood in the
|
||
road on the default boot**. Say plainly whether any golden moves (it should not — this is
|
||
render-side), and if one does, amendment law, same commit.
|
||
- **F (after B):** the gate — assert poster clearance on the default boot, and **assert the
|
||
same leg FAILS under `?verge=0`**. The pre-change failure is known and counted at exactly 14.
|
||
|
||
### 0.2 — REPAIR `smoke_tram` *(Lane F, micro)*
|
||
`flags_check.py:617-630` asserts exactly one thing — `!!getObjectByName('tram')` — prints a SKIP
|
||
and returns when absent, and **passes on the fenced path**, because `tram.js:110-114` adds a
|
||
named empty group. A live vacuous-gate violation inside our own suite. Fix it so it proves the
|
||
tram *runs* (route resolved, stops sane, moves between frames) on the towns where it runs, and
|
||
proves it is *genuinely absent* on the fenced towns — with a control that fails.
|
||
|
||
### 0.5 — `classic_regression` GETS A NETWORK ALLOW-LIST *(Lane F, micro)*
|
||
`classic_regression` (`flags_check.py:128-241`) makes **no network assertion at all**. That is
|
||
why R36's fetch-surface widening (five DJ bodies) needed a brand-new smoke to catch it. Give it
|
||
an **allow-list**: the four v2-era depot furniture GLBs (`bench`, `bin`, `bus_shelter`,
|
||
`food_cart` — git-verified v2 baseline, `24cef5a`, tagged v2.0-alpha→v2.0) plus same-origin.
|
||
**Allow-list, never deny-list** — a deny-list only catches what you already thought of.
|
||
Prove it discriminates: point it at a fabricated extra fetch and assert it goes red.
|
||
|
||
### 0.4 — WIRE `ctx.onChunkBuilt` / `onChunkDisposed` *(Lane B, one line each)*
|
||
Producer at `chunks.js:43-51`, consumer at `sim.js:203-205`. Both shipped, never connected,
|
||
since R3. Every per-chunk entity system in the v8 slate wants it. Wire it, prove a consumer
|
||
actually fires, and confirm zero behaviour change when nobody subscribes.
|
||
|
||
## Laws
|
||
|
||
Everything standing. This round specifically: **+0 draws is a requirement, not an aspiration,
|
||
for 0.1** · every new/repaired gate must FAIL when its subject is absent, and each ships with
|
||
its falsifiability control demonstrated · pathspec-atomic commits (three lanes share the tree) ·
|
||
no pushes, no tags — Fable pushes at the close · measurement over brief: if a premise here is
|
||
wrong, prove it with numbers and say so loudly.
|
||
|
||
## Order
|
||
|
||
1. **Parallel: F (0.3 first, then 0.2 + 0.5 — all in `tools/`) · B (0.1 code + `?verge=0` +
|
||
0.4) · A (0.1 ruling-side + selfcheck).** Disjoint files by construction.
|
||
2. **Then F again:** the kerb gate against B's landed code + the `?verge=0` control, full
|
||
`qa.sh --strict --matrix`, and the round report.
|
||
|
||
## FABLE'S MID-ROUND RULING — CLASSIC KEEPS ITS PAINT (B's escalation, §0.1)
|
||
|
||
B implemented the kerb ruling with `?classic=1` **forcing verge off** — i.e. classic keeps the
|
||
pre-ruling ground — rather than moving a covenanted town's render on its own initiative, and
|
||
escalated the choice. **RULED: keep the fence. Classic keeps v2's paint.**
|
||
|
||
Reasoning, and it is not the R27 precedent: R27 (John's facade ruling — "the covenant is
|
||
anti-drift machinery, not a defect preservative") applies when classic is preserving a **live
|
||
defect**. Here it is not. The defect this ruling fixes is *posters standing in the road* — and
|
||
**`?classic=1` has no gig layer, therefore no posters, therefore no defect to preserve**. What
|
||
classic would be adopting is a cosmetic change to road paint on a town whose entire job is to
|
||
be v2, unchanged, forever. The museum piece keeps its paint.
|
||
|
||
**The one real cost, and its mitigation:** a fenced classic means two ground geometries exist —
|
||
and "two implementations of one thing" is precisely the disease this round was convened to stop
|
||
(four `isOpen`s, three `chunkIndex` divergences, two registries). So the fence is ruled
|
||
acceptable **only as a single branch on one code path**, never a second implementation. B has
|
||
built it that way (one flag, one `bandOuter <= bandInner` test); it stays that way. If it ever
|
||
starts to fork, the fence comes down and classic takes the footpath.
|
||
|
||
*John may overrule; it is a one-token change (drop `!classic`), and B has proven both sides
|
||
render identically to their intended baselines.*
|
||
|
||
## FABLE'S SECOND MID-ROUND RULING — CLASSIC'S POST-v2 FETCH DELTA (F's escalation, §0.5)
|
||
|
||
F built the allow-list by deriving it from the **v2.0 tag at gate time** rather than from my
|
||
brief's literal ("four depot GLBs + same-origin"), and was right to: my shape **would have gone
|
||
green straight through the R36 breach**, because `models/peds/woman_dj_01.glb` is same-origin.
|
||
Deriving from `git ls-tree v2.0` enumerates the covenanted 21 ped files where today's directory
|
||
holds 32. That is the correct mechanism and it stands.
|
||
|
||
Doing it, F measured a **+6 file delta** between the real v2.0 tree's wire and today's
|
||
`?classic=1`, and refused to improvise a verdict on a six-epoch-old fact. **RULED:**
|
||
|
||
- **The 5 audio files (R11, `f7dd44f`): RATIFIED as baseline.** The covenant preserves "the
|
||
exact v2 town", and **v2.1 was v2's final tagged state** — audio shipped inside v2, so
|
||
classic fetching it is classic being correct, exactly as the four furniture GLBs are.
|
||
- **`assets/towns/index.json` (R20/R21): NOT baseline — carried as a NAMED, PRINTED exception,
|
||
not silently.** It is v4 selector machinery in a v2 museum. It changes nothing about the
|
||
classic town (a UI list, no geometry, no identity, no seeded draw), so it is not the R36
|
||
species and it does not get gated in a floor round. It goes on the allow-list **labelled as a
|
||
post-v2 exception** so it can never read as baseline.
|
||
- **Filed to the v8 debt ledger, for R38 or later:** *should `?classic=1` show the town selector
|
||
at all?* In v2 there was no selector (it landed R19). Hiding it under classic would retire the
|
||
exception at the source and cost one branch — but it is a question about what classic *means*,
|
||
which is a design ruling, not a leak to plug mid-round.
|
||
|
||
**Also ratified from F's report:** the budget of record is **292 draws / 124,793 tris** (the
|
||
280-vs-191 split was **camera bearing** — 110 draws of spread, the audit took `DBG.teleport`'s
|
||
default yaw 0 which is the worst bearing, the spike took a travel-facing yaw; both correct,
|
||
different quantities). My "viewport is the variable" hypothesis was **disproven** — F ran
|
||
1280×720 vs 2560×1440 with everything else fixed and got byte-identical counts; three's culling
|
||
is frustum-shaped, not pixel-shaped. Shared instance cap: **256**, binding companions ≤24
|
||
tris/instance and proximity-first spending. **Margin is 8 draws, not twenty.**
|
||
|
||
**Filed, not fixed (R38+):** `?r=3` on the default town measures **307 draws** — an ungated
|
||
override that breaches the ≤300 law, with no gate covering it. Documented in the README as a
|
||
diagnostic, not a supported boot; whether `?r=` gets clamped is a later ruling.
|
||
|
||
## ROUND CLOSED (Fable) — **THE FLOOR IS LEVEL. All five items, all green, no tag.**
|
||
|
||
`qa.sh --strict --matrix`: **7 passed · 0 failed · 0 warn · 0 skipped** · selfcheck **157,407**
|
||
(+1,055 of A's new poster assertions, all green on the ruled street) · flags harness **0 fails
|
||
/ 0 warns** · **MATRIX GREEN 10 towns × 7 gates**. Deliberately **no tag** — wave 0 levels the
|
||
floor, it does not ship a version.
|
||
|
||
**What actually changed, in one line each.** The kerb is footpath and it cost **+0 draws with
|
||
triangles going DOWN** (A/B'd against HEAD on a second port; sum-of-draws identical at all 102
|
||
walked steps). **14 posters stood in painted bitumen; 0 do now — and not one poster moved, the
|
||
ground did.** The budget of record is **292/124,793**, and the 280-vs-191 fight was **camera
|
||
bearing** (110 draws of spread; the audit took `DBG.teleport`'s default yaw 0, the worst
|
||
bearing; the spike took a travel-facing yaw — both correct, different quantities). Two vacuous
|
||
gates are dead: `smoke_tram` (green exactly where it was meant to look, because a named empty
|
||
group satisfied it) and the poster clearance check (**the placer seats via `poleOffset`, which
|
||
is derived from `roadWidth`, and the gate asserted against `roadWidth/2` — the same function
|
||
agreeing with itself, the R27 trap inside the file whose header explains the R27 trap**). The
|
||
chunk seam is subscribable at last — the producer was fine; **`chunks.ctx` was never returned**,
|
||
so a consumer holding `PROCITY.chunks` had nowhere to attach.
|
||
|
||
**The round's own lesson, recorded.** B's first cut passed every number — +0 draws, posters
|
||
clear, zero errors — **and painted every intersection shut.** A screenshot caught what the
|
||
metrics could not. Fixed by lifting the carriageway over the footpath at junctions, verified on
|
||
Katoomba's worst 4.3° corner. *Green metrics over a wrong world is this project's oldest
|
||
failure mode and it does not care which epoch it is.*
|
||
|
||
**Two lanes, two independent methods, one number.** A counted 14 plan-side (node, over the
|
||
plan, by offset); F counted 14 paint-side (browser raycast, over B's geometry, classified by
|
||
**material identity** so it cannot drift when B edits). Both flip to 0 on the ruled street and
|
||
both fire at exactly 14 under `?verge=0`. F's two **detector controls** are the load-bearing
|
||
part: "0 posters on road" is a sentence about nothing unless the classifier is shown saying
|
||
*road* AND *footpath* on the same boot.
|
||
|
||
**Cross-lane corrections that landed mid-round** (the shepherd's whole job): A's measurement
|
||
killed three literals in Fable's brief — `lane`'s band is `[4,4]` on 56 real edges, not the
|
||
synthetic `[2,2]`; the "9 m band / 18 m of main" figures are synthetic-only (a real main is
|
||
24 m ⇒ 7 m, and `side`@12 is **72% of the corpus** at 3 m). B confirms it would have shipped
|
||
the `[2,2]` assumption otherwise. F's allow-list mechanism corrected Fable's other literal:
|
||
"four GLBs + same-origin" **would have gone green straight through the R36 breach**, so the
|
||
list is derived from `git ls-tree` at gate time — and per this round's ruling the authority tag
|
||
moved `v2.0 → v2.1`, which git made surgical (`git diff v2.0 v2.1 -- web/` is the audio pack
|
||
and its wiring, zero other assets, zero deletions).
|
||
|
||
**Carried to the v8 debt ledger (filed, not smuggled):** A's D1–D4 (three `chunkIndex`
|
||
divergences · four `isOpen` implementations, A's canonical export with **zero importers** ·
|
||
two registries, which is why gig venues have worn op-shop signage since R13 · A's own
|
||
nearest-edge/arcade poster-gate hole, costed at 11 of 26 town gig goldens and deferred so this
|
||
round's "did the kerb move a golden?" stays a clean **no**) · the town-matrix's budget column
|
||
is **bookmark numbers**, which this round proves under-report a walked-and-turned frame by
|
||
~120 draws — a regression signal, not the budget of record · `?r=3` breaches at **307 draws**
|
||
through an ungated override · *should `?classic=1` show the town selector at all?*
|
||
|
||
## Standing
|
||
|
||
- John's three rulings are made; nothing in this round needs him.
|
||
- Still open for later rounds, not now: the market-plaza amendment, hardyards provenance,
|
||
where MOCAPGOD actually lives.
|