Lane E R22 (v4.0): MODELBEAST notes refresh + provenance v4-final + G2a atlas review

Ledger #3 (E's G item), #6 (provenance prep), + the C/E contract review.

- MODELBEAST notes (#3): pipeline/README.md's toolchain row claimed sf3d/trellis_mac were 'HF-gated
  (setup needed)' -- ultra was right, that was stale (weights cached; trellis_mac 15/15 on thriftgod
  Tier-1; the :8777 queue also runs bg_remove_local/mflux_image_edit/seedvr2_upscale). Corrected.
  Ultra's finish-farm post-mortem folded into the props section VERBATIM + credited, with Fable's
  Ruling 1 amendment (NO-DRACO: drop --compress draco, rest of the command stands). Noted that our
  bake_lowpoly.py / decimate_props.py are NOT the finish farm, so nobody conflates them.
- Provenance v4-FINAL (#6): the frozen table carries the pack (22 towns, all 8 states/territories,
  1192 shops + roads[], ODbL, raw snapshots) + a row for Lane G's newtown_godverse attributed to G.
  The licence spine is complete -- nothing shipped is unaccounted.
- BUG: index.json still listed 22 -- generated before the dd4489c merge, so newtown_godverse was
  invisible to B's selector while R22 verifies at 23-town scale. Regenerated -> 23 towns (selfcheck
  ALL GREEN 161300/161300). Index is now self-describing: state reads from the cache first, then my
  config, so any lane's town rosters itself.
- G2a atlas contract review (E's half; C answers interior ceilings in LANE_C_PUB): Fable's priors all
  hold. Atlas-per-shop is an UPGRADE if the loader disposes on room exit -- today stockpack.js never
  disposes (R9: 181MB resident, accreting). Without dispose, per-shop strands ~16MB/shop (~190MB per
  town visited, unbounded across 23 towns). With dispose: ~4MB resident at 1024², ~45x better than
  today. Also: size the atlas to the shop (<=1024², not 2048² for a 6-item shop); reuse my index
  schema verbatim so stockpack.js/fail-soft-to-parody/?noassets/validate_pack all work unchanged;
  the R8 parody law (parodied metadata, real cover art) is unchanged.

-> Lane G: add "state":"NSW" to newtown_godverse.json and the index picks it up automatically.
-> Lane C: the R9 dispose-on-exit cache-cap is now load-bearing for G2a (my VRAM numbers above).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
m3ultra 2026-07-16 21:54:49 +10:00
parent 0c4dad5acc
commit a7289d0550
4 changed files with 139 additions and 26 deletions

View File

@ -1,5 +1,63 @@
# LANE E — cross-lane notes # LANE E — cross-lane notes
## Round 22 — v4.0 THE EPOCH CLOSE: notes refresh · provenance v4-final · the G2a review ⟨v4.0⟩
**1. MODELBEAST notes refreshed (ledger #3).** `pipeline/README.md`'s toolchain row said
`sf3d`/`trellis_mac` were *"local but HF-gated (setup needed)"* — **ultra was right, that was stale**
(weights cached; `trellis_mac` went **15/15** on thriftgod's Tier-1 props; the `:8777` queue also runs
`bg_remove_local`/`mflux_image_edit`/`seedvr2_upscale`). Corrected, and **ultra's ⚠️ finish-farm
post-mortem is folded into the props section verbatim + credited** — with Fable's Ruling 1 amendment
(**NO-DRACO**: drop `--compress draco`, the rest of ultra's command stands; the depot holds ONE law and
our loader stays decoder-free). Our own `bake_lowpoly.py` / `decimate_props.py` are noted as *not* the
finish farm, so nobody conflates them.
**2. Provenance table → v4-FINAL (ledger #6).** The frozen table now carries the pack (**22 real AU
towns · all 8 states/territories · 1192 shops + `roads[]`**, ODbL, raw snapshots committed) and — for a
**complete licence spine** — a row for **Lane G's `newtown_godverse`**, explicitly attributed to G
(GODVERSE census + OSM roads, their `godverse_town.py`, their fields). Nothing shipped is unaccounted.
**3. 🐛 The index was missing Lane G's town.** `index.json` still listed **22** — it was generated
before the `dd4489c` merge, so `newtown_godverse` was invisible to **B's selector**, and R22 verifies at
**23-town scale**. Regenerated → **23 towns**, selfcheck **ALL GREEN 161300/161300**. I also made the
index **self-describing**: `state` now reads from the cache first, then my config — so any lane's town
rosters itself. **→ Lane G: add `"state": "NSW"` to `newtown_godverse.json` and the index picks it up**
(it's the one town showing a blank state).
### → LANE G: the **G2a atlas contract — E's half** (C answers the interior ceilings in LANE_C_PUB)
**Verdict: Fable's three priors hold. Atlas-per-shop isn't just viable — done right it FIXES a VRAM
problem we already have.** Two conditions and one reuse:
**a. Atlas per shop — YES, with one hard condition: dispose on exit.** Today `stockpack.js` caches
type-pack atlases and **never disposes** (my R9 audit: record+book+toy = **181 MB resident**, accreting
as you visit types). Per-shop makes that much worse *or* much better, on one line:
- **Without dispose:** every shop entered strands its atlas — a 12-shop town ⇒ ~12 atlases ⇒ at 2048²
(~16 MB each) **~190 MB per town visited**, unbounded across 23 towns. Non-starter.
- **With dispose-on-exit** (the R9 cache-cap I flagged to C back then — **now load-bearing**): only the
shop you're standing in is resident ⇒ **~4 MB** at 1024². That's **~45× better than today's 181 MB**.
G2a is the reason to finally land that cap. **Ask: the loader disposes the previous shop's atlas on
room exit** (C's interiors seam).
**b. Size the atlas to the shop, not to the format.** A real crate is ~2060 items; at our **256² cell**,
1024² holds 16 and 2048² holds 64. **Ship ≤1024² for a typical shop** — don't hand a 6-item shop a
2048². Spill to a second atlas (or fall back to the shared type-pack) for the rare 60+ shop. Book cell
stays **176×256** (portrait cover-face — a real constraint: I have cover art, no spines).
**c. Reuse my index schema verbatim — then nothing downstream changes.**
`{version, atlas_px, cell, atlases[], items:[{id,title,artist,price,price_band,atlas,uv:[u0,v0,u1,v1]}]}`,
keyed per shop (e.g. `stock_shop_<godverseShopId>_index.json`). You get for free: `stockpack.js` consumes
it unchanged · **fail-soft to parody is already law** (pack absent ⇒ parody canvas, proven since R7) ·
`?noassets` already fetches zero · and **`validate_pack.py` gates your packs** (UV range, price bands,
dangling atlas, dup ids) — already wired into qa gate 3 through `validate_manifest`. Add index fields and
tell me; I'll extend `REQUIRED`.
**d. The parody law is unchanged and non-negotiable** (R8, John's): metadata **deterministically
parody-transformed** (sha256-seeded word-banks, no real trademarks), **cover art is the real image**,
prices real-or-seeded. Real dealgod inventory changes nothing here.
**e. Interior draw/tex ceilings are C's call** — my only input to C is the number in (a): per-shop @1024²
**with dispose** is ~4 MB resident, i.e. *cheaper than the status quo*, not more expensive.
## Round 21 — the v4.0 town pack (pull-forward, DATA-ONLY) ⟨v4.0⟩ ## Round 21 — the v4.0 town pack (pull-forward, DATA-ONLY) ⟨v4.0⟩
> Ledger #5**NON-GATING**: nothing here touches a golden until A absorbs in R22, and F tags > Ledger #5**NON-GATING**: nothing here touches a golden until A absorbs in R22, and F tags
@ -253,7 +311,8 @@ loader wiring (`spawnRig`/fleet). Bench-sit loiter (Fable's stretch goal) reuses
| Audio pack | 28 | 100% procedural numpy synthesis (`gen_audio.py`) | oscillator/noise render → ffmpeg OGG+M4A | 🟢 CC0-equiv, parody-safe | | Audio pack | 28 | 100% procedural numpy synthesis (`gen_audio.py`) | oscillator/noise render → ffmpeg OGG+M4A | 🟢 CC0-equiv, parody-safe |
| Stock packs | 3 (350/311/273) | GODVERSE `dealgod` Postgres — **real** cover art | `build_stock_pack.py`: parody-transform metadata + atlas | 🟢 real-art / parody-metadata | | Stock packs | 3 (350/311/273) | GODVERSE `dealgod` Postgres — **real** cover art | `build_stock_pack.py`: parody-transform metadata + atlas | 🟢 real-art / parody-metadata |
| Ped clip **⟨v3.1⟩** | `sit.glb` (E R16; + pre-existing `walk`/`idle` from D/90sDJsim) | Adobe **Mixamo** `Sitting_Idle.fbx` | `fbx_to_clip.py` (Blender, mesh-strip) | 🟢 Mixamo royalty-free (motion only, mesh stripped) | | Ped clip **⟨v3.1⟩** | `sit.glb` (E R16; + pre-existing `walk`/`idle` from D/90sDJsim) | Adobe **Mixamo** `Sitting_Idle.fbx` | `fbx_to_clip.py` (Blender, mesh-strip) | 🟢 Mixamo royalty-free (motion only, mesh stripped) |
| Town caches **⟨v3.2⟩** | 5 real AU towns (Katoomba/Newtown/Fremantle/Bendigo/Castlemaine) | **OpenStreetMap** via Overpass API | `build_towns.py` (fetch → dedupe/suburb/parody/type-map) | 🟢 **ODbL 1.0** (© OSM contributors; `web/assets/towns/SOURCES.md`) | | Town pack **⟨v4.0-FINAL⟩** | **22 real AU towns, all 8 states/territories** — 1192 shops + real street geometry (`roads[]`) | **OpenStreetMap** via Overpass API — bounded per-town bbox; raw shops+roads snapshots committed in `_raw/` | `build_towns.py`: fetch → dedupe/suburb-fill/parody → C's §6 class map → 3× texture cap (drops counted) → v2 cache + roads | 🟢 **ODbL 1.0** (© OSM contributors; `web/assets/towns/SOURCES.md` + `license`/`attribution` on every cache) |
| Godverse town *(Lane G's, listed for completeness)* | `newtown_godverse` — 18 shops, rostered in E's `index.json` | GODVERSE/thriftgod shop census + OSM road geometry | `pipeline/godverse_town.py` (**Lane G owns this provenance**) | 🟢 ODbL 1.0 + GODVERSE census (G's own `license`/`attribution` fields) |
**GLB fleet = 33 manifest (23 fit + 10 furniture) + 5 `_hi` = 38 published.** Only external spend ever: **GLB fleet = 33 manifest (23 fit + 10 furniture) + 5 `_hi` = 38 published.** Only external spend ever:
~$0.64 (fal-Hunyuan, R5). Everything else is $0 / on-device (electricity only). ~$0.64 (fal-Hunyuan, R5). Everything else is $0 / on-device (electricity only).

View File

@ -15,7 +15,7 @@ gorgeous, it doesn't make it work.
| OpenRouter key (skins) | env `OPENROUTER_KEY` or `~/Documents/dealgod/lore/keys.env` (never committed) | | OpenRouter key (skins) | env `OPENROUTER_KEY` or `~/Documents/dealgod/lore/keys.env` (never committed) |
| depot password (publish) | env `GOD3_PW` (never committed; ask John) — cookie = `hmac(GOD3_PW,"3god-ok")` | | depot password (publish) | env `GOD3_PW` (never committed; ask John) — cookie = `hmac(GOD3_PW,"3god-ok")` |
| Ollama (free LLM) | `http://100.89.131.57:11434` (qwen3) — for names/lore/cataloguing, unused so far | | Ollama (free LLM) | `http://100.89.131.57:11434` (qwen3) — for names/lore/cataloguing, unused so far |
| MODELBEAST (free local gen) | this box, `~/Documents/MODELBEAST`. `flux_local` = FLUX.2-klein-4B text→image on MPS (**used for the facade skins** — ungated, weights cached). `sf3d`/`trellis_mac` = image→GLB, local but HF-gated (setup needed) | | MODELBEAST (free local gen) | this box, `~/Documents/MODELBEAST` + its own queue on **`:8777`**. `flux_local` = FLUX.2-klein-4B text→image on MPS (**the facade skins** — ungated, weights cached). `sf3d`/`trellis_mac` = image→GLB, **local + PROVEN, weights already cached**`trellis_mac` (TRELLIS.2 `1024_cascade`) went **15/15 on thriftgod's Tier-1 props** (Lane G/ultra, R1); `sf3d` = seconds-fast draft. Also live on the queue: `bg_remove_local`, `mflux_image_edit`, `seedvr2_upscale`. *(The old "HF-gated / setup needed" note here was stale — flagged by ultra, corrected R22.)* |
## The steps (each is idempotent / resumable) ## The steps (each is idempotent / resumable)
@ -88,6 +88,25 @@ reused from depot. `magazine-rack` → primitive (thin-wire gotcha); `glass-case
fallback (TRELLIS can't do transparent glass; `sf3d --draft` gives a featureless blob). TRELLIS meshes run fallback (TRELLIS can't do transparent glass; `sf3d --draft` gives a featureless blob). TRELLIS meshes run
heavy (2577k tris) — see AUDIT provenance. **Eyeball every thumbnail**; ≤2 local attempts then fal (John's go). heavy (2577k tris) — see AUDIT provenance. **Eyeball every thumbnail**; ≤2 local attempts then fal (John's go).
#### ⚠️ Finishing a `trellis_mac` mesh — ultra's post-mortem (Lane G, R1) — folded in verbatim
> ⚠️ **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.
*Credit: Lane G / ultra (`G-progress.md`), proven post-mortem — it cost them a shredded batch so it
shouldn't cost us one.* **One amendment, per Fable's Ruling 1 (`docs/LANES/FABLE_TO_LANE_G.md`):
NO-DRACO WINS — the depot speaks uncompressed GLB and PROCITY's loader stays decoder-free.** So drop
`--compress draco`; everything else in ultra's command stands (WebP ≤1024 is already our law):
```bash
npx @gltf-transform/cli optimize IN.glb OUT.glb \
--texture-compress webp --texture-size 1024 --simplify-error 0.01 # NO --compress draco
```
Files land ~23× bigger than the Draco'd version and that's fine — the depot holds ONE law.
Note our own in-house paths remain valid for their own cases and are NOT the finish farm:
`bake_lowpoly.py` (voxel-remesh + bake, for shell-soup that must hit a low budget) and
`decimate_props.py` (collapse, detail-preserving — see the R13 instrument diet).
### 7. Local-depot mode — `loaders.js ?localdepot=1` + `stage_local_depot.py` *(round-3: DONE)* ### 7. Local-depot mode — `loaders.js ?localdepot=1` + `stage_local_depot.py` *(round-3: DONE)*
Lets Lanes B/C/F validate GLB loading with **no network / before publish**: Lets Lanes B/C/F validate GLB loading with **no network / before publish**:
```bash ```bash

View File

@ -371,8 +371,13 @@ def write_index():
for f in sorted(x for x in os.listdir(TOWNS_DIR) if x.endswith(".json") and x != "index.json"): for f in sorted(x for x in os.listdir(TOWNS_DIR) if x.endswith(".json") and x != "index.json"):
c = json.load(open(os.path.join(TOWNS_DIR, f))) c = json.load(open(os.path.join(TOWNS_DIR, f)))
k = c.get("key", f[:-5]) k = c.get("key", f[:-5])
towns.append({"key": k, "town": c.get("town", k), "state": TOWNS.get(k, {}).get("state", ""), # state: the cache's own field first (so ANY lane's town self-describes — e.g. Lane G's
"shops": len(c.get("shops", [])), "roads": bool(c.get("roads"))}) # godverse caches), then my TOWNS config, then blank. The index rosters every cache in the
# dir, not just mine.
state = c.get("state") or TOWNS.get(k, {}).get("state", "")
towns.append({"key": k, "town": c.get("town", k), "state": state,
"shops": len(c.get("shops", [])), "roads": bool(c.get("roads")),
"source": c.get("source", "osm")})
idx = {"schema": "procity-towns-index/1", "generated": datetime.date.today().isoformat(), idx = {"schema": "procity-towns-index/1", "generated": datetime.date.today().isoformat(),
"license": "ODbL 1.0", "attribution": "© OpenStreetMap contributors", "towns": towns} "license": "ODbL 1.0", "attribution": "© OpenStreetMap contributors", "towns": towns}
json.dump(idx, open(os.path.join(TOWNS_DIR, "index.json"), "w"), indent=1) json.dump(idx, open(os.path.join(TOWNS_DIR, "index.json"), "w"), indent=1)

View File

@ -9,154 +9,184 @@
"town": "Adelaide", "town": "Adelaide",
"state": "SA", "state": "SA",
"shops": 116, "shops": 116,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "ballarat_real", "key": "ballarat_real",
"town": "Ballarat", "town": "Ballarat",
"state": "VIC", "state": "VIC",
"shops": 20, "shops": 20,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "bendigo_real", "key": "bendigo_real",
"town": "Bendigo", "town": "Bendigo",
"state": "VIC", "state": "VIC",
"shops": 36, "shops": 36,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "bowral_real", "key": "bowral_real",
"town": "Bowral", "town": "Bowral",
"state": "NSW", "state": "NSW",
"shops": 32, "shops": 32,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "braddon_real", "key": "braddon_real",
"town": "Braddon", "town": "Braddon",
"state": "ACT", "state": "ACT",
"shops": 20, "shops": 20,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "brunswick_real", "key": "brunswick_real",
"town": "Brunswick", "town": "Brunswick",
"state": "VIC", "state": "VIC",
"shops": 96, "shops": 96,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "castlemaine_real", "key": "castlemaine_real",
"town": "Castlemaine", "town": "Castlemaine",
"state": "VIC", "state": "VIC",
"shops": 24, "shops": 24,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "darwin_real", "key": "darwin_real",
"town": "Darwin", "town": "Darwin",
"state": "NT", "state": "NT",
"shops": 12, "shops": 12,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "daylesford_real", "key": "daylesford_real",
"town": "Daylesford", "town": "Daylesford",
"state": "VIC", "state": "VIC",
"shops": 32, "shops": 32,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "fitzroy_real", "key": "fitzroy_real",
"town": "Fitzroy", "town": "Fitzroy",
"state": "VIC", "state": "VIC",
"shops": 160, "shops": 160,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "fremantle_real", "key": "fremantle_real",
"town": "Fremantle", "town": "Fremantle",
"state": "WA", "state": "WA",
"shops": 80, "shops": 80,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "geelong_real", "key": "geelong_real",
"town": "Geelong", "town": "Geelong",
"state": "VIC", "state": "VIC",
"shops": 68, "shops": 68,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "glebe_real", "key": "glebe_real",
"town": "Glebe", "town": "Glebe",
"state": "NSW", "state": "NSW",
"shops": 52, "shops": 52,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "hobart_real", "key": "hobart_real",
"town": "Hobart", "town": "Hobart",
"state": "TAS", "state": "TAS",
"shops": 80, "shops": 80,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "katoomba_real", "key": "katoomba_real",
"town": "Katoomba", "town": "Katoomba",
"state": "NSW", "state": "NSW",
"shops": 80, "shops": 80,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "launceston_real", "key": "launceston_real",
"town": "Launceston", "town": "Launceston",
"state": "TAS", "state": "TAS",
"shops": 32, "shops": 32,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "marrickville_real", "key": "marrickville_real",
"town": "Marrickville", "town": "Marrickville",
"state": "NSW", "state": "NSW",
"shops": 28, "shops": 28,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "newcastle_real", "key": "newcastle_real",
"town": "Newcastle", "town": "Newcastle",
"state": "NSW", "state": "NSW",
"shops": 36, "shops": 36,
"roads": true "roads": true,
"source": "osm"
},
{
"key": "newtown_godverse",
"town": "Newtown",
"state": "",
"shops": 18,
"roads": true,
"source": "godverse+osm"
}, },
{ {
"key": "newtown_real", "key": "newtown_real",
"town": "Newtown", "town": "Newtown",
"state": "NSW", "state": "NSW",
"shops": 72, "shops": 72,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "northbridge_real", "key": "northbridge_real",
"town": "Northbridge", "town": "Northbridge",
"state": "WA", "state": "WA",
"shops": 60, "shops": 60,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "toowoomba_real", "key": "toowoomba_real",
"town": "Toowoomba", "town": "Toowoomba",
"state": "QLD", "state": "QLD",
"shops": 12, "shops": 12,
"roads": true "roads": true,
"source": "osm"
}, },
{ {
"key": "westend_real", "key": "westend_real",
"town": "West End", "town": "West End",
"state": "QLD", "state": "QLD",
"shops": 44, "shops": 44,
"roads": true "roads": true,
"source": "osm"
} }
] ]
} }