PROCITY/G-progress.md
m3ultra 0608f9c8c1 Lane G R24: G3 §7 RATIFIED — John's write-back ruling, A then B (charter law #4 satisfied)
John ruled at the R24 kickoff: v5.0 ships on Option A (sandbox) — an in-game purchase never
touches real monsterrobot/Square inventory; Option B (reservation via the POS's existing
hold_expires_at) is CHARTERED as a v5.x upgrade behind a hold budget John sets; Option C is not
chartered and happens only as a deliberate business launch, if ever. Recorded inline in §7 with
the options preserved beneath it, since the trade-offs are the record of why A-then-B was chosen.

Written in as binding, because a one-line ruling isn't a mechanism: /reserve + /buy stay ABSENT,
not stubbed behind a flag (a sandbox a config typo can flip isn't a sandbox); the tier-2 reader
connects read-only, enforced at the credential — a role with SELECT on inventory/crate/disc_cache
and nothing else, which carries the §9 PII fence in the same grant; and the gate asserts the write
verbs 404 and the role's grants are read-only, because "we didn't call buy()" proves nothing —
the vacuous-gate law turned on ourselves.

Option B's preconditions are stated so it can't slide in quietly: the hold budget (John's number,
NOT YET SET — B is not startable until it is; a v5.x item, not a v5.0 blocker), the-shop-always-
wins on a race with an in-store Square sale, a staff-visible `held: GODVERSE` reason code, and
soak before ship. Doc header/§10 updated so the whole file tells one story: §7 ruled, the rest
still DESIGN pending both Fables' sign-off, no server code before that.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 01:33:27 +10:00

212 lines
16 KiB
Markdown
Raw 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.

# G-progress — GODVERSE lane (runs on ultra)
*Lane brief: `docs/LANES/LANE_G_GODVERSE.md`. This file follows your progress-file convention —
newest round first. Fable-on-ultra writing.*
## Round 24 (2026-07-17) — the re-emit + THE SHOP'S REAL STREET (ledger #5)
**THE WRITE-BACK RULING — John, 2026-07-17: A THEN B.** G3 §7 is **ratified** with the ruling
inline; charter law #4 is satisfied. v5.0 ships **sandboxed** — a game purchase never touches real
monsterrobot/Square inventory. **Option B (reservation) is chartered as a v5.x upgrade** behind a
hold budget John sets; **C is not chartered**. What I wrote into the doc as binding, beyond the
one-liner, because a sandbox that can be flipped on by a config typo isn't a sandbox:
`POST /reserve` + `/buy` stay **absent, not flag-stubbed**; the tier-2 reader connects with a
**read-only role** (`SELECT` on inventory/crate/disc_cache only — which carries the §9 PII fence in
the same grant); and the gate asserts the write verbs **404** + the role's grants are read-only,
because "we didn't call buy()" proves nothing (the vacuous-gate law applied to ourselves).
**Carried to v5.x: the hold budget is John's number and is not yet set** — B isn't startable until
it is. B's non-negotiable: **the shop always wins** a race with an in-store Square sale.
**Landed (branch `lane-G-godverse`):**
- **`redhill_godverse`** — the town whose record shop is THE shop. Monster Robot Party seated on
Musgrave Road (**verified: lot 8, type `record`, `godverseShopId` 3962749**), 37 shops, 884 real
Red Hill roads off E's donor.
- **The atlas re-emit** — US `license` throughout (British `licence` retired, 0 occurrences),
provenance lifted to top level per C §7.3 **and** kept nested per E's validator (see conflict #1).
`atlas-QA OK`, 120 real records, byte-identical re-bake holds.
- **`newtown_godverse` re-emitted with `godverseShopId`** (ledger #2) — 18 census shops keyed.
- **`godverse_town.py`**: psycopg2 → `psql` (the m3 has no psycopg2); emits `godverseShopId`;
`EXTRA_SHOPS` roster; **Fable's R22 Ruling 2 finally implemented** (see below).
- G3 §4: the `godverseShopId`/`godverse_id` naming split recorded (two artifacts, two conventions).
**Monster Robot Party's coordinate** is John-supplied (Google Maps place `/g/11g6rlbbc0`
-27.4553791, 153.0076244). It could not be derived: OSM doesn't know the shop (no name match, no
147 Musgrave Rd address node), the census doesn't have it, dealgod's `stores`/`store_entity` rows
carry NULL lat/lng, and recordgod has no address anywhere. Verified inside E's bbox **and** on
Musgrave Road's own geometry. My own estimate was ~120 m out — asked instead of shipping it.
**FABLE'S RULING 2, IMPLEMENTED (R22 → R24) — and it was load-bearing, not cosmetic.** "Merge
census heroes WITH the donor's texture shops; census heroes win a collision; count the swap."
I never built it. Measured this round, census-only Red Hill is **not shippable**:
| redhill_godverse | shops | A's spacing warn | poster-clears-kerb |
|---|---|---|---|
| census only | 9 | **306 m** ⚠ | pass |
| census + Monster Robot | 10 | **261 m** ⚠ | **FAIL** (poster inside edge 1037 by 2.95 m) |
| **+ donor texture (Ruling 2)** | **37** | **none** ✓ | **pass** ✓ |
| *(E's donor `redhill_real`, for reference)* | 36 | none | pass |
261 m is **worse than the 255 m that retired ballarat this round** — the alpha's headline town
would have shipped flagged "scattered, not a high street, or retire the town". Ruling 2 fixes both.
9 donor heroes swapped for their census entries in Red Hill, 18 in Newtown — counted, per the ruling.
**CONFLICT #1 — C's contract §7.3 vs E's validator (provenance).** C says "lift the four to TOP
LEVEL, US `license`; British retired — *exactly what E's validator reads*". **Measured: it is not.**
`validate_atlas.py:98` reads **nested** `provenance`, and `:105` reads `licence` British-first.
Lifting-and-retiring as written **fails the gate**. My R23 atlas already passed it untouched. This
is the same species as the bug that held the tag — a doc asserting what code does without running
it. **Resolved without drama:** E's check accepts `licence or license`, so US-nested passes; I emit
the four at top level (C's contract + the town-cache house convention) off ONE source of truth.
**→ E, one line:** `validate_atlas.py:198` PRINTS `licence` British-only while its *check* accepts
both — so adopting C's mandated US spelling **silently stops printing the licence flag**, which
:199's own comment calls a human call ("the licence is PRINTED — clearing it is a human call").
The gate still passes; the evidence line vanished. Fix: `.get("licence") or .get("license")`.
**CONFLICT #2 — Ruling 2 vs A's identity gate. THIS ONE NEEDS A RULING; it is why the tree is red.**
Ruling 2 makes a godverse cache *mixed*: a keyed GODVERSE layer (census + Monster Robot) plus an
inherited OSM texture layer. A's sweep asserts **every** shop is keyed → partial ⇒ FAIL. The two
standing rulings cannot both hold.
**The texture shops carry no `godverseShopId` deliberately**, and I'd argue A's own words settle it:
- The field *means* "this lot's stock lives at `stock_godverse/<id>/`". An OSM milkbar has no
GODVERSE identity. Minting one from its OSM id pushes a **third id space** into a field that
already carries two, and A's validator calls a duplicate **mis-stocking** — charter risk #3's
exact nightmare, with Monster Robot's crate as the prize. (Measured: OSM ids here are ≥53.1 M vs
census ≤2992 and store id 3,962,749 — no collision *today*; dealgod store ids reach 7 digits and
OSM ids are 8+, so the margin is thin, and "no collision today" is not an id-space design.)
- **A's validator and A's sweep disagree with each other.** The validator: *"Missing = tier 0
(soft). Duplicate = mis-stocked (hard). **They are not the same failure.**"* The sweep fails
partial keying because it *"mis-stocks the rest"* — conflating precisely the two failures A said
are not the same. Unkeyed → parody is the **designed ladder**, not a gap.
- **Proposed (A's call, Fable's ruling):** assert coverage over the **godverse layer**, not the
inherited texture layer — the subject is "shops that claim stock", and the gate stays honest
(it still names its subject and proves a count). Zero-keyed still SKIPs; duplicates still error.
**The 8 red checks, itemised — no surprises for F:**
- `newtown_godverse` base+gig goldens (**2**) — my re-emit moved them, exactly as ledger #2
intends. **A re-pins** (batched): base `0xcf69b387`, gig `0x1e266f60`.
- `godverse identity` ×3 on each godverse town (**6**) — conflict #2, above. Nothing else.
- Unpinned (warn, expected): `redhill_godverse` base `0xb2224939` / gig — **A pins**.
- **Classic covenant `0x3fa36874` intact.** `atlas-QA OK`.
**If Fable rules the other way** (texture layer out): revert to census-only and F inherits the
poster-kerb FAIL at edge 1037 + a 261 m town — that break is A/B's invariant, exposed by real data,
and would need an owner before the tag. I'd rather hand F the conflict than the broken town.
## Round 23 (2026-07-16) — G2a: THE FIRST REAL CRATE + the G3 draft
**Landed (branch `lane-G-godverse`, G namespace only — ready for your mid-round merge):**
- `pipeline/godverse_stock.py` — the per-shop atlas pipeline, split at **the snapshot boundary**:
`snapshot` (runs where the DBs are; freezes every source row + every cover's sha256) →
`pack` (pure: snapshot + image bytes → atlas, no DB, no network). That split is deliberate —
**it's what lets E's `validate_atlas` gate G's output on m3 without the dealgod DB** (ledger #4).
- `pipeline/_godverse/monsterrobot_550.snapshot.json` — the artifact of record (committed).
- `web/assets/stock_godverse/3962749/`**120 real records** from a real crate: 2 atlases
(2048², 256px cells, E's contract verbatim) + index with provenance.
- `docs/G3_ECONOMY_DESIGN.md` — the draft (ledger #2), incl. **the write-back question framed for
John** (§7), now grounded in a real trading shop rather than a hypothetical.
- **Verified:** byte-identical re-bake (same snapshot → same bytes); uv ⊂ [0,1]; every item's
atlas ref resolves; bands standard 58 / collector 56 / grail 6. Eyeballed the atlas: it's a real
deep-house crate (Basement Jaxx, Byron Stingily, Angel Moraes, 4hero, Murk, Blaze).
**THE HEADLINE FINDING — the brief's premise doesn't hold (all measured, R23):**
The ledger asked for "dealgod inventory → one real **Newtown** record shop". That can't be built:
- **No Newtown record shop has stock in any database.** Egg Records / Papa Disquo / Haze Guitars /
The Vintage Record / Downtown Music: **0 items each**.
- **`dealgod.stores` is not a shop census** — 8,754 of 9,285 are **Discogs seller accounts**.
Zero Newtown stores, zero census name matches. It's an item *feed*, not a shop directory.
- **`thriftgod.item` is a demo seed** — 2,221 items across 29 shops, **all Brisbane/Newcastle/Alice
charity shops**, zero record shops.
- **`mint()` cannot produce tier 1**: `TABLESAMPLE SYSTEM (0.5)` + `random.random/uniform/shuffle`,
and **`random.seed` appears nowhere in `server.py`**. Non-deterministic, and it assigns other
sellers' listings to shops that never owned them — which also voids the licence law's "the
*stores' own* product shots" green and makes write-back meaningless. (G3 §2.)
- This is **not** risk #3's "fuzzy matching" — it's a population mismatch. Nothing to match *to*.
**What we found instead — and it's better.** `monsterrobot` (**147 Musgrave Rd, Red Hill, Brisbane**
— John's ruling) is the same real shop in three datasets: `recordgod` (its POS: 28,624 live vinyl,
**24,914 in 357 real crates** with real labels and slot numbers), `monsterrobot.party` (its own
site — **the covers are the shop's own product shots**), and dealgod store **3962749** (the scrape;
the cover cache + the godverse id). **99.3%** of its crate stock joins to a cached cover by Discogs
`release_id`. Not in thriftgod's census, so its godverse id = its dealgod store id 3962749 (real,
stable, clear of the census space — thriftgod max shop id = 2992). Drops counted: 120 of 122 in
crate 550 baked; 2 dropped (no own photo).
**Rulings received from John this round (recorded):**
1. **The crate ships as the shop it really is** — Red Hill, Brisbane, not Newtown.
2. **Real titles/artists at tier 1** — an amendment to the no-real-trademarks law that
`build_stock_pack.py` enforces (it parody-transforms metadata). Same shape as the licence law:
in-house 🟢, **flagged before anything public**. Recorded in every atlas's provenance.
**Asks — two things gate the crate reaching a room, and both are outside G's namespace:**
1. **[C + F] Per-shop packs aren't wired at runtime.** `stockpack.js` caches by `type` alone
(`_packs`/`_resolved`), and `interior_mode.js:192` does `getStockPack(shop.type)` with `base`
fixed to `assets/models/`. R23's single shop works via a `base` override, but **two stocked
shops collide in that cache** — so this blocks v5.0-beta, not just ledger #3. Seam needed:
key the cache by `type + base` (or `godverse_id`) + preload per-shop on entry. **C owns the
wording (LANE_C_PUB); G re-emits to whatever lands.**
2. **[E, via Fable] The crate has no street.** `redhill_real` doesn't exist; `westend_real` is the
only Brisbane cache and stops ~2.3 km south. Needs a `build_towns.py` TOWNS entry
(~`center: (-27.4553, 153.0064), span_km: 2.4`) + one Overpass fetch, then
`godverse_town.py redhill_real redhill_godverse`. **That's E's file and an outward-facing
fetch — G touched neither.** Note monsterrobot must be added to the godverse cache's `shops[]`
as id 3962749 (it's not in the census); `godverse_town.py` takes shops from thriftgod only, so
that's a small G change once you rule on the town.
**Environment note (matters for reproducibility):** this ran on the **m3**, not ultra — the box has
neither `thriftgod` nor `dealgod` Postgres. Both were restored/read from John's mounted backup
drive (`/Volumes/johnking/db-backups`, **2026-07-15** dumps); dealgod (2 GB gz) was never restored,
its cover map was streamed straight out of the dump (command recorded in
`godverse_stock.py:load_image_map`). This is *better* for the charter's snapshot discipline, not
worse: the dump date is pinned in every snapshot's provenance. I left two restored DBs on the m3
(`thriftgod`, `recordgod`) — say the word and I'll `dropdb` them.
**Fences held:** PII — `recordgod` holds real `customer`/`staff`/`sales`; the pipeline reads only
`inventory`/`crate`/`disc_cache`, and G3 §9 makes that a standing fence. Licence — covers are the
shop's own shots, in-house 🟢, flagged before public, provenance in every atlas.
## Round 1 (2026-07-16, ultra) — the marriage's first artifact
**Landed:**
- `pipeline/godverse_town.py` — thriftgod PG census + donor OSM cache → `<key>_godverse.json`
(schema v2, `source: "godverse+osm"`). Deterministic, stdlib+psycopg2, runs where the DB lives
(ultra). Type map thriftgod→registry: music→record, charity/second_hand/antiques→opshop,
books→book, toys/games→toy, video_games→video, pawnbroker→pawn, market→dept.
- `web/assets/towns/newtown_godverse.json`**18 REAL Newtown shops** (Sydney; DealGod census)
on your real 1,086-road graph (roads donated from `newtown_real`, attribution extended).
- Verified on ultra: boots via `?plansrc=osm&town=newtown_godverse&seed=20261990` — splash and
HUD show Newtown, selector shows "Newtown Godverse · OSM fixture", streets render, 25 chunks /
~78 draws. Real shop names should render on facades exactly as your fictional ones do
(data-driven) — **not yet eyeball-confirmed on a specific facade** (see bookmark ask below).
**Found while verifying (asks, no files touched):**
1. **Per-town bookmarks:** `DBG.teleport('shopfront_detail')` on an OSM town lands inside
geometry (synthetic-town coords). Suggest bookmarks resolve against the active plan.
2. **`DBG.enterShop(selector)`** — took neither a type nor a shop name from the cache; a
name/type/id selector would make cross-repo QA one-liners. (Your harness is excellent —
`info/teleport/shot` made this round's verification trivial.)
3. **Sync:** gitea `origin/main` is at `06fe648` (R20 kickoff); the m3 clone holds R20 lane
commits beyond that (up to `94e56ed`). Push when the round closes so ultra tracks you.
**Context from the ultra side (useful to AF):**
- **MODELBEAST grew:** `trellis_mac` (local TRELLIS.2 image→3D, ~$0, proven 15/15 on thriftgod's
Tier-1 props), `sf3d`, `bg_remove_local`, `mflux_image_edit`, `seedvr2_upscale` all live on the
m3's own queue (:8777). Lane E's "HF-gated, setup needed" note is stale — weights are unlocked.
- ⚠️ **Do NOT run trellis_mac output through the MESHGOD finish farm** — its fill_holes+decimate
shreds 200k-tri marching-cubes meshes (proven on ultra, post-mortem in dealgod memory). The
working pipeline: raw GLB → `npx @gltf-transform/cli optimize --compress draco --texture-compress
webp --texture-size 1024 --simplify-error 0.01` → 0.41.8 MB at raw-quality look.
- **Which collides with your no-Draco law** → the ruling ask in the lane brief. If no-Draco wins,
same command minus `--compress draco` (files ~2-3× bigger, still fine); if Draco wins, three.js
needs the DRACOLoader wire your vendored addons already include. Either is one re-emit; the
depot should hold ONE law.
- **15 thriftgod hero props** sit in `OPSHOPGAME/tools/props_out/game/` on ultra (record-crate,
rummage-tub, teapot, crt-tv, suitcase, mannequin-bust…) — op-shop interior dressing your Lane C
might want; John is picking keepers for the 3GOD depot now.
**Next round (G2, proposed):** real-stock atlases — dealgod inventory → `build_stock_pack.py`
per-shop record/book atlases keyed by the godverse shop id, behind `?stock=real`. Contract I'd
like C/E's eyes on: atlas file per shop vs per town; budget per interior; cache invalidation
when stock sells (thriftgod items are one-of-a-kind — sold means GONE, which is the whole
GODVERSE magic: the crate you riffle is a real crate in a real shop).