Go to file
m3ultra 839575b28d Lane A round 27 (v5.0): the docs freeze — CITY_SPEC v5 + the risk list judged (ledger #6)
Docs only. No code, no golden moved — correct: tier 2 touches no plan, no cache, no atlas bytes. selfcheck
ALL GREEN 156,212/156,212; scaffold + consistency green; classic 0x3fa36874 and gig 0xb1d48ea1 frozen. The
whole stock epoch moved zero plan goldens, which was the determinism boundary's entire promise.

CITY_SPEC v5 SECTION — written from the ARTIFACTS, not the briefs (this epoch's own lesson):
- The tier ladder: 0 parody / 1 static real / 2 live GODVERSE, each degrading softly to the rung below.
- `sourcing` is NOT `tier`, and C's ruling is the precise one — both ship in every index. `tier: 1` is the
  LADDER RUNG (a mint atlas is still a static file, so still rung 1); `sourcing: "real"|"mint"` is WHERE
  THE CONTENTS CAME FROM. Different axes. Collapsing them is exactly how a mint crate comes to read as
  real. Measured: 15 keyed atlases = 1 real + 14 mint.
- The three id-space fences, verified rather than restated (below).
- The manifest: existence DECLARED, never probed — the root fix for fail-soft-by-404 colliding with the
  zero-console-errors law. No entry, no fetch, zero 404s, no attribution exceptions. 15 entries / 15 dirs.
- Ruling 2 as law (mixed caches are the design; no gate may assert it away — mine did).
- Lane A's seam is exactly one field: godverseShopId, and `'godverseShopId' in shop` is the tier test.

THE ID FENCES ARE VERIFIED, NOT ASSERTED. The plan-id/godverse-id trap is STILL LIVE in the data and I
reproduced it: in redhill_godverse, bare `31` is "Wholefood Cafe" as a plan id and "Silky Oak Furnature" as
a godverse id — the exact ambiguity that made F's enterShop(31) enter the wrong shop and pass a soft-fall
assertion vacuously on the wrong subject. So it goes in the spec as a STANDING RULE, not a fixed bug: no
code or gate may compare a bare number across the two spaces. (Within the godverse space, G's two halves —
census <=2992, dealgod store ids — are numerically disjoint by construction, which is what makes the opaque
key safe.)

THE RISK LIST, JUDGED LINE BY LINE — AND I DID NOT PRE-RETIRE ANYONE'S GATE:
1. CARRIED. Tier-2 latency/stutter is this round's defining gate and I'm writing in wave 2 — F's reader and
   kill-the-server gate do not exist yet. NOTHING retires this line except that gate going green. Retiring
   it from a doc while the code is unwritten would be the precise species this epoch spent four holds
   catching: a rule meeting a case that doesn't exist yet. The offline law is a promise until #3 makes it
   falsifiable; that's the whole point of #3.
2. RETIRED — measured, and the remedy the risk NAMED is the remedy that shipped ("crate rotation rather
   than bigger atlases"). Max 2 atlases/shop vs C's hard cap of 2; the 14 mint shops sit at 16 items / 1
   atlas / 1024²; only the one real POS shop earns 2048² (120 items, 2 atlases, 1.2 MB) under the 60+ rule.
3. RETIRED — DESIGNED OUT, not solved. The risk assumed a fuzzy-matching problem ("names drift, shops
   move"). There is no matcher: identity is an explicit opaque key G emits. The predicted failure cannot
   occur in the predicted form — and the proof is the headline shop: Monster Robot is in NEITHER the census
   NOR OSM, so no name-matching strategy could ever have found it. Mis-stocking is fenced structurally
   instead (duplicate ids error, uniqueness over defined ids, the orphaned-atlas gate).
4. SPLIT. Write-back RETIRED by John's ruling recorded as MECHANISM, not config: /reserve and /buy are
   ABSENT, not stubbed — races and reservation semantics cannot occur because the verbs don't exist, and
   "prove the absence" beats any sandbox flag a config typo could flip. (Option B re-opens this line
   deliberately at v5.x, behind a hold budget.) The `gone` read half is CARRIED to F's #4.
5. Unchanged, extended: static-atlas determinism proved in practice (G's index-only sku re-emit moved no
   .webp bytes); the fail-soft ladder proved on every rung; the id fences now have case law behind them.
6. NEW, CARRIED — the orphaned atlas, with a live near-miss on the books.
7. NEW, CARRIED — "real" is one shop wide: 14 of 15 keyed atlases are mint, because exactly one shop has a
   POS. Honest and marked, not a defect — but the epoch's headline claim rests on ONE shop, and any future
   claim of scale needs either siblings for monsterrobot or continued care that `sourcing` stays legible to
   humans and not just to gates.

THE GATE THAT ARMED ITSELF (the law working unattended, worth recording). My R25 orphaned-atlas gate SKIPped
on newtown_godverse all through R25 — "no committed atlas keys to this town", subject absent, so it said so
instead of passing quietly. The moment G's 14 mint atlases landed it STARTED BINDING ON ITS OWN and passed:
156,211 -> 156,212, and that +1 IS the gate arming itself. Nobody edited it. That is what the vacuous-gate
law buys — a gate that waits, in the open, for its subject to exist.

G: redhill_godverse's lift drops keyed shop 2286 "Empire Revival"; you stocked its numeric neighbour 2287.
Nothing is orphaned and the gate is green — but stocking 2286 would orphan it today, and the hazard grows
with every shop stocked. Carried as risk #6.

F: nothing of mine gates your tag.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 13:52:47 +10:00
docs Lane A round 27 (v5.0): the docs freeze — CITY_SPEC v5 + the risk list judged (ledger #6) 2026-07-17 13:52:47 +10:00
pipeline Lane E R26 w4: the mint-id fence — my rule was the stale thing (wave 4, E's one line) 2026-07-17 13:08:40 +10:00
priorwork Fable (integrator): round-3 lane instructions + archive round-1 lane prompts 2026-07-14 14:30:36 +10:00
tools Lane F R26 (v5.0-beta): the manifest consumed, the tolerance retired — tag HELD on the mint-id rule 2026-07-17 11:38:44 +10:00
web Lane F R26 (v5.0-beta): the manifest consumed, the tolerance retired — tag HELD on the mint-id rule 2026-07-17 11:38:44 +10:00
.gitignore Fable: R14 kickoff rulings recorded (push done, flag stays opt-in, genres final) + gitignore local session files 2026-07-16 00:59:42 +10:00
B-progress.md Lane B (Streetscape): round-12 v3.0-alpha — venue frontage + posters + muffled-gig spill (?gigs=1) 2026-07-15 20:15:40 +10:00
C-progress.md Lane C R26 w4: the mint-id fence — my rule was the stale thing (wave 4, C's one line) 2026-07-17 12:32:45 +10:00
D-progress.md Lane D round 12: gig band + crowd + patronage surge (?gigs=1) 2026-07-15 19:49:07 +10:00
E-progress.md Lane E R12 (v3.0-alpha gig layer): 5 instruments + 4 posters + 3 gig audio 2026-07-15 19:44:48 +10:00
F-progress.md Lane F R26 (v5.0-beta): the manifest consumed, the tolerance retired — tag HELD on the mint-id rule 2026-07-17 11:38:44 +10:00
G-progress.md Lane G R26 (v5.0-beta): the mint baker, the crate menu, the atlas manifest (ledgers #2, #6) 2026-07-17 10:33:40 +10:00
README.md Lane F: the v5 README teaser — held three rounds, shipped with the tag 2026-07-17 10:41:50 +10:00

PROCITY

A standalone, procedurally generated, fully walkable 90s-Australian shopping town — every building enterable (the Vuntra City trick), every interior seeded and themed: record stores, op shops, toy shops, book barns, video rental, pawnbrokers, milk bars, market stalls. Built on the proven house stack (three.js r175 vendored, plain JS, no build step) and the asset DNA of 90sDJsim + thriftgod. v1 is the system; the GODVERSE/BaseGod real-item content plugs in later.

Run

cd web && python3 -m http.server 8130
# http://localhost:8130            (game shell — Lane B)
# http://localhost:8130/map.html   (2D plan debugger — Lane A)

Read first

  • docs/CITY_SPEC.md — the treaty: schema, units, seeds, budgets, file ownership.
  • docs/RESEARCH.md — what the parent repos already solved, with exact paths to port from.

The lanes (parallel Opus 4.8 sessions)

Each lane is a self-contained prompt. To run one, start an Opus session in this repo and say: "Read docs/LANES/LANE_X_….md and execute it." AE are parallel-safe (disjoint files, standalone test pages); F integrates after they land.

lane mission owns
A — CITYGEN seed → CityPlan data (streets, blocks, lots, shops) + 2D map js/citygen, js/core/registry.js, map.html
B — STREETSCAPE chunk-streamed instanced 3D town + game shell index.html, js/world
C — INTERIORS every door opens: seeded themed shop interiors js/interiors, interior_test.html
D — CITIZENS rigged-near / impostor-far NPCs + shopkeepers js/citizens, citizens_test.html, models/
E — ASSETS audit ultra's library, normalize GLBs, skins, manifest pipeline/, assets/
F — INTEGRATION wire AE into one seed-to-town game + QA gates (after AE)

Already in the repo

  • web/vendor/ — three.js r175 + addons (vendored from 90sDJsim; no CDN at runtime).
  • web/assets/gen/ — 69 generated texture skins (25 shopfront facades, 10 skies, 10 grounds, 8 wallpapers, 16 interior surfaces) inherited from thriftgod + 90sDJsim, style-locked.
  • web/js/core/ — frozen shared modules: prng.js (seeded-everything law), loaders.js (fail-soft promise-cached GLB/texture + 3GOD depot), canvas.js (text planes).

House laws (short form — CITY_SPEC has the fine print)

Seeded everything, Math.random banned in gen code · the game must run with zero assets · instancing from day one · canvas text, no font files · characters = shared base rigs + one clip bank, canonical sources live outside this repo · 🟢 web-ok licensing only.

v3.1 — THE FLIP: the town shows its best by default

The Friday-night layer soaked through alpha, beta, and the v3.0 release — so v3.1 flips it on by default, and the mature v2 flags flip with it. Boot the plain URL and each town seeds 24 venues (pub, band room, RSL) with a full seeded week of gigs, town-wide posters, and a Friday night that reads: a 4-piece band (trio + a seated drummer) with real instruments, a mixed crowd, an outdoor queue, a per-venue cover charge, muffled gig spill + walla and applause, town-wide streetlamp pools, and identity continuity — the ped you followed in is in the crowd. Plus weather, the tram, and the parallax interior-window shader, all live by default.

The covenant moved, it didn't disappear. ?classic=1 boots the exact v2 town — byte-identical forever (synthetic golden 0x3fa36874, zero gig layer, zero fetch delta). That is the new frozen regression target; the default boot is deterministic to the gig golden 0xb1d48ea1. Asset-free (?noassets=1) composes with the default boot and stays silent-and-fine.

Flags — the four headliners are ON by default, each with a =0 opt-out; ?classic=1 is the master off:

flag default what
?classic=1 off the exact v2 boot — all four below off, byte-identical to the frozen baseline
?gigs=0 on the gig district — venues, week schedule, band/crowd/queue, cover, posters, night pass
?weather=0 · ?tram=0 · ?winmap=0 on seeded weather · the tram loop · the parallax interior-window shader
?roster=v1 · ?pop=N stream chunk-streamed citizen density is the baseline; ?roster=v1 restores the fixed roster
?dig=0 · ?stock=real dig on crate-riffle on record bins · real GODVERSE sleeves in the stock
?noassets=1 · ?plansrc=osm · ?mute=1 · ?dbg=1 off asset-free (zero network) · OSM plan source · silence · the window.DBG capture/soak harness
?plansrc=osm&town=<key> boot a real Australian town: fixtures melbourne/katoomba/silverton, or a real OSM cache bendigo_real/castlemaine_real/fremantle_real/katoomba_real/newtown_real (ODbL, web/assets/towns/SOURCES.md). REAL ROADS: a cache with roads[] (schema v2) builds the CityPlan street graph from the town's actual OSM streets; without roads[] a cache marches onto synthetic avenues. Or just pick a town from the HUD selector — no URL needed

v4.0 — THE REAL MAP: the towns are the product

23 real Australian towns — 1,210 real shops, every state and territory — on their actual streets. Not "inspired by": Fitzroy's shops sit on Fitzroy's roads, at their real positions, because the pipeline eats OpenStreetMap and marches it through the same CityPlan contract the procedural town uses. Pick one from the in-HUD selector and walk it. Everything built across v1v3 comes along unchanged — the venues and their seeded week of gigs, the 4-piece band with the seated drummer, the crowd that follows you into the pub, the interiors behind every door, weather, the tram — because they all hang off the plan contract and never had to know the geography got real.

The towns run from meccas (Fitzroy, 160 shops) to the thin tail (12), at real retail density: the secondhand heroes keep their footfall while the street around them gets ~4× busier — texture, never a takeover. Venues bias to the retail heart. The tram only runs where it fronts a real high street (elsewhere it was honestly "a highway bus", so it's fenced). Everything stays deterministic from the seed, silent under ?noassets=1, and ?classic=1 still boots the exact v2 town, byte-identical forever (0x3fa36874).

The tour: docs/shots/release_v4/contact.html — the Fremantle hero, the Fitzroy mecca, the thin tail (labelled honestly: the floor is shops-per-street-metre, and Toowoomba is below it), the synthetic control, and the ?classic=1 covenant made visible. Charter: docs/V4_REAL_MAP.md · data + licences (ODbL): web/assets/towns/SOURCES.md.

v5.0-alpha — THE FIRST REAL CRATE: the shops get real too

v4 made the towns real. v5 makes the shops real — and the first one is standing.

Boot ?plansrc=osm&town=redhill_godverse&stock=real, walk down Musgrave Road into Monster Robot Party (147 Musgrave Rd, Red Hill, Brisbane — a real record shop), and riffle its crate. The records in it are that shop's real stock: 120 real records off its real point-of-sale, real covers, real titles, real prices. Buy one and the wallet debits what the sticker says. It's gone for the session and back next boot — because until the live tier lands, the crate is a file, not a shop's ledger.

Stock is a data tier now, exactly like assets — each rung fully playable, each degrading softly to the one below, so the game never depends on a server to be a game:

tier what deterministic?
0 · parody seeded canvas sleeves (v1) — any boot, always works yes — the QA baseline
1 · static real per-shop atlases baked from the shop's own POS yes — atlases are files
2 · live GODVERSE live stock, sold-means-gone (design ratified, not built) no — by design

The offline law: the server enriches, never gates. ?noassets=1 still fetches zero bytes and plays silent-and-fine; a shop whose atlas is missing falls soft to parody rather than borrowing someone else's crate; and ?classic=1 still boots the exact v2 town, byte-identical forever (0x3fa36874). The world stays seeded and golden-gated — only the stock inside it is data.

Provenance: item photos are each shop's own product shots, 🟢 in-house — flagged before any public or commercial release, and every atlas carries that flag where the QA gate must print it. Real titles and artists are an in-house amendment to the no-real-trademarks law, on the same footing. Nothing an in-game purchase does touches real inventory — v5.0 ships sell-sandboxed by ruling; a real reservation tier is chartered for v5.x, not assumed. Charter: docs/V5_REAL_SHOP.md · economy design: docs/G3_ECONOMY_DESIGN.md. | ?seed=N | 20261990 | town seed |

Release tour: docs/shots/release_v3_1/contact.html — the money shots on the default boot, plus a ?classic=1 before/after. QA: tools/qa.sh --strict (classic regression + default-boot gate + smokes + no-giants) --soak (the full-week soak); the seated drummer passes the no-giants gate at the seated stature band [0.9,1.5] m.