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>
133 lines
9.7 KiB
Markdown
133 lines
9.7 KiB
Markdown
# PROCITY v5 — THE REAL SHOP (epoch charter)
|
||
|
||
*Fable (m3, integrator), 2026-07-16. John's pick at the v4 retro. Grounded in: the Lane G
|
||
marriage (merged, ruled, G2a atlas contract reviewed by C/E in R22), dealgod's 1.77M real items
|
||
with photos, thriftgod's census already driving `newtown_godverse`, and the v2-era dig/wallet/
|
||
stock machinery that has been waiting for this data since it shipped.*
|
||
|
||
## The vision
|
||
|
||
**v4 made the towns real; v5 makes the shops real.** Walk Fitzroy's actual street into an actual
|
||
op shop, riffle a crate, and the records in it are that shop's real stock — real covers, real
|
||
titles, real prices. Buy one and it's gone, because it was one-of-a-kind in the real world.
|
||
Thriftgod is the brain and the bank; PROCITY is the body.
|
||
|
||
## The tier ladder (the epoch's load-bearing idea)
|
||
|
||
Stock is a DATA TIER, like assets — each tier fully playable, each degrading softly to the one
|
||
below. This is the offline law made structural:
|
||
|
||
| tier | source | flag state | deterministic? |
|
||
|---|---|---|---|
|
||
| 0 · parody | seeded canvas sleeves (v1) | any boot, always works | yes — the QA baseline |
|
||
| 1 · static real | per-shop atlases baked from dealgod (G2a) | `?stock=real`, no server | yes — atlases are files |
|
||
| 2 · live GODVERSE | thriftgod server: live stock, sold-means-gone (G3) | server reachable | **no — by design** |
|
||
|
||
The seeded-everything law is NOT weakened: the *world* (geometry, layout, venues, citizens)
|
||
stays seeded and byte-identical; stock *contents* are inventory data riding the asset law.
|
||
QA gates run on tiers 0–1; tier 2 gets its own smoke class (reachability, fail-soft, latency)
|
||
that never gates a tag on server state.
|
||
|
||
## The stages
|
||
|
||
- **v5.0-alpha: THE FIRST REAL CRATE.** One real shop end-to-end — a Newtown record shop in
|
||
`newtown_godverse`, static atlas (G2a), riffle real covers, buy, wallet debits, every tier
|
||
degrades clean. Plus the **G3 design doc ratified** (both integrators + John) before any
|
||
server code exists.
|
||
- **v5.0-beta: THE REAL SHOPPING TOWN.** Every hero shop in 1–2 godverse towns carries real
|
||
static stock; godverse coverage grows where thriftgod's census is dense (fitzroy is the
|
||
prize); pricing from thriftgod's `mint()` profiles baked into the atlases; the dig UX polished
|
||
for real items (title/price cards are real data).
|
||
- **v5.0: THE LIVE TIER.** Thriftgod's server behind tier 2 per the ratified G3 design:
|
||
live per-shop stock, sold-means-gone, reservation semantics — with the offline law proven by
|
||
the gate (kill the server mid-session; the game degrades to tier 1 without a stutter). Tour,
|
||
docs freeze, tag.
|
||
|
||
## The laws
|
||
|
||
Everything inherited (classic covenant `0x3fa36874` forever · determinism for the world ·
|
||
budgets · amendment law · measurement-over-brief · drops counted · fresh-context verification),
|
||
plus this epoch's own:
|
||
|
||
1. **The offline law (non-negotiable, from the standing G3 ruling): the server enriches, never
|
||
gates.** Full offline play at tier 0 and tier 1, always. No boot path, gate, or tag may
|
||
depend on a reachable server.
|
||
2. **The determinism boundary:** world = seeded, frozen, gated. Stock = data tiers. Tier 2 is
|
||
openly non-deterministic and therefore never inside a golden or a byte-identical assert.
|
||
3. **The licence law (extends E's provenance spine):** item photos are the stores' own product
|
||
shots — 🟢 for in-house play; **flagged before any public/commercial release** (G's own
|
||
note, now law). No private-individual data, ever. Every atlas carries provenance.
|
||
4. **The write-back law:** game purchases NEVER mutate real thriftgod inventory without an
|
||
explicit, John-ratified reservation design in the G3 doc. Until then tier 2 is read-live,
|
||
sell-sandboxed. (Whether "sold in game" can mark real stock is John's call to make in the
|
||
design review, not a default.)
|
||
5. **The two-studio law:** G owns `pipeline/godverse_*`, `web/assets/stock_godverse/**`,
|
||
godverse caches, and the server side; A–F own their lanes; cross-repo contracts publish
|
||
FIRST; both integrators sign the G3 design. **Merge amendment:** when a round's brief names
|
||
a G deliverable as gating, G's branch merges mid-round after Fable-m3 review (G's file
|
||
namespace is disjoint, so pathspec safety holds); otherwise boundaries as before.
|
||
|
||
## The risk list (kept current, v4-style)
|
||
|
||
1. **Latency/stutter at tier 2** — server calls must be async enrichment; the dig must never
|
||
block on the network. The G3 doc owns the caching design.
|
||
2. **Atlas budgets at real density** — a mecca hero shop can hold hundreds of real items; C's
|
||
interior ceilings are the law and the atlas contract must respect them (pagination/crate
|
||
rotation rather than bigger atlases).
|
||
3. **Census↔OSM identity** — matching thriftgod shops to godverse lots is fuzzy (names drift,
|
||
shops move). Mismatches must be counted and fail-soft to tier 0, never mis-stocked.
|
||
4. **Sold-means-gone semantics** — race conditions, reservations, and the write-back question.
|
||
All design-doc territory; nothing ships before ratification.
|
||
5. **Settled non-risks:** the dig/wallet/stockAdapter machinery (shipped v2, soaked 16 rounds);
|
||
static-atlas determinism (E's byte-identical pipeline discipline); the fail-soft ladder
|
||
(proven pattern from `?noassets` day one).
|
||
|
||
### Retired-or-carried at the v5.0 close (ROUND27 ledger #6 — Lane A, line by line)
|
||
|
||
Verdicts against what shipped, not against the plan. Written in **wave 2**, so tier-2 items that F's reader
|
||
and kill-the-server gate will decide are **carried, not pre-retired** — the gate retires them, not this doc.
|
||
|
||
1. **CARRIED — and it is this round's defining gate, not a footnote.** The only risk here the epoch has not
|
||
yet measured. The reader (#2) and the kill-the-server gate (#3) don't exist as I write this; **nothing
|
||
retires this line except that gate going green** — boot server-up (live fields consumed), kill mid-session
|
||
(degrade to tier 1, zero console errors, frame-time measured across the failure), boot server-down (pure
|
||
tier 1). Until then the charter's offline law is a promise, and the whole point of #3 is that a promise
|
||
isn't a gate. *(If tier 2 proves bigger than one round, F holds and this line simply carries — four holds
|
||
have proven nobody forces an epoch close.)*
|
||
2. **RETIRED — the remedy the risk named is the remedy that shipped.** It predicted "pagination/crate
|
||
rotation rather than bigger atlases", and that is exactly what happened: the mecca case is served by the
|
||
**crate-rotation menu**, not by growing the sheet. Measured across all **15 keyed atlases**: max **2
|
||
atlases/shop** against C's hard cap of 2; the 14 mint shops sit at **16 items / 1 atlas / 1024²** and only
|
||
the one real POS shop earns 2048² (**120 items, 2 atlases, 1.2 MB**) under C §7.2's 60+ item rule. E's
|
||
validator enforces the ceilings from the committed files alone. Total: 344 items.
|
||
3. **RETIRED — the risk was designed out, not solved.** It assumed a **fuzzy-matching** problem ("names
|
||
drift, shops move") and demanded mismatches be counted. There is no matcher: identity is an **explicit
|
||
opaque key** (`godverseShopId`) that G emits, so there is nothing to mis-match. The predicted failure
|
||
couldn't occur in the predicted form — and the case that would have broken any name-matcher proves it:
|
||
**Monster Robot Party is in neither the census nor OSM**, so no matching strategy could ever have found
|
||
it; it is keyed by injection. Mis-stocking is fenced structurally instead: duplicate ids **error**,
|
||
uniqueness runs over defined ids, and the **orphaned-atlas gate** fails if a stocked shop isn't seated.
|
||
4. **SPLIT — the write half RETIRED by ruling, the read half CARRIED to F's #4.** *Write-back:* retired, and
|
||
retired properly — John's **A-then-B** ruling is recorded as **mechanism, not config**: `/reserve` and
|
||
`/buy` are **ABSENT, not stubbed**. Race conditions and reservation semantics cannot occur because the
|
||
verbs do not exist; "prove the absence" is a stronger guarantee than any sandbox flag, since a sandbox a
|
||
config typo can flip isn't a sandbox. *(Option B's reservation upgrade is chartered as v5.x, behind a
|
||
hold budget — it re-opens this line deliberately, when it is built.)* *Read (`gone`, real→game):* carried
|
||
— F's #4 asserts both directions this round.
|
||
5. **Unchanged, and extended by what the epoch settled:** static-atlas determinism proved in practice
|
||
(byte-identical re-bakes, including G's index-only sku re-emit that moved no `.webp` bytes); the
|
||
fail-soft ladder proved on every rung; and the **id-space fences** (`sku_`/`mint_`, plan-id vs
|
||
godverse-id) now have case law behind them rather than good intentions.
|
||
6. **NEW, CARRIED — the orphaned atlas.** The lift legitimately drops shops (overlap-resolve, counted since
|
||
R19); dropping one that carries a **committed atlas** means real stock keyed to a shop that isn't in the
|
||
town. Gated in `selfcheck` since R25 and **currently green** — and the gate armed itself this round
|
||
without anyone touching it: it SKIPped on `newtown_godverse` while no atlas keyed there, and **began
|
||
binding the moment G's mint atlases landed**. Live near-miss on the books: `redhill_godverse`'s lift drops
|
||
keyed shop **2286 "Empire Revival"**; G stocked its numeric neighbour **2287** instead. Carried because
|
||
the hazard grows with every shop stocked — **stocking 2286 would orphan it today.**
|
||
7. **NEW, CARRIED — "real" is one shop wide.** 14 of 15 keyed atlases are **mint**; exactly one is a POS
|
||
snapshot, because exactly one shop has a POS. That is honest and marked (`sourcing`), not a defect — but
|
||
the epoch's headline claim rests on **one** shop, and any future claim of scale needs either more POS
|
||
shops (v5.x: "if monsterrobot ever gets siblings") or continued care that `sourcing` stays legible to
|
||
humans, not just gates.
|