PROCITY/pipeline/AUDIT.md
m3ultra bd40ec7e7a Lane E round 3 (landed by Fable after review): 5 hero props gen'd local + published, local-depot mode, manifest 14 fittings + 8 furniture
- gen_props.py: flux_local -> trellis_mac -> normalize pipeline; 5/8 props kept
  (arcade-cabinet, listening-booth, drinks-fridge, milkshake-mixer, novelty-record)
- magazine-rack -> primitive (thin-wire gotcha); glass-case + bus-shelter -> fal.ai fallback
- cash-register reused from depot; all 22 GLBs live, validate --depot 0/0
- loaders.js ?localdepot=1 + stage_local_depot.py for network-free GLB validation
- qa.sh --strict GREEN 4/4 at commit time

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 18:03:03 +10:00

161 lines
13 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.

# PROCITY Asset Audit — Lane E, Step 1
*Generated 2026-07-14 from a live inspection of `johnking@100.91.239.7:~/Documents/3D=models/`
(the sorted house library) + the 3GOD depot `GET /api/list`. Tri counts / bounding boxes from
`pipeline/glb_stat.py` (dependency-free GLB parser); orientation & final scale verified by
rendering every candidate through Blender and looking at the thumbnails (never "should look right").*
## TL;DR
- The library is a **raw dump**: almost nothing obeys the house GLB law. Scale is arbitrary
(only `record_crate_plastic_01` was native-metres), up-axis varies, tri counts span **12 → 960k**,
textures reach **4096px**, and several assets carry **branded/trademarked designs** (quarantined).
- `pipeline/normalize.py` fixes scale/orientation/tris/textures uniformly. **16 assets** normalized
clean, verified upright & metre-scaled, WebP ≤1024, ≤5k tris, +Y up, base origin — ready to publish.
- Gaps with **no usable source** (→ `MESHGOD_BATCH.md` or in-engine primitives): glass display
case, fridge, till/register, spinner rack, magazine rack, market stall, escalator, VHS shelving.
- Depot already holds a few reusable house props (`street-bench`, `council-bin`, `milk-crate-stack`)
and 138 assets total (mostly TRELLIS `*-views-3d-*` / `image-3d-*` MeshGod outputs).
- **Skin caveat:** 5 of the 25 facades carry **baked-in sign text** (`djsim-milkbar` "MILK BAR",
`djsim-video`, `djsim-pub`, `market`, `grimy`) — they break the blank-signboard convention, so
the manifest tags them `signboard:"baked"` and Lane B must not overlay a name on them. The other
20 are genuinely blank.
## Toolchain reality (differs from the lane brief)
| thing | brief said | actual |
|---|---|---|
| Blender on ultra | "runs on ultra against Blender" | present but **not on PATH**`/Applications/Blender.app/Contents/MacOS/Blender` (v5.0.1). Renders 4 angles in ~0.9s. |
| coreutils / timeout | none | confirmed — used ssh `ConnectTimeout`, no `timeout`/`setsid` |
| python on ultra | 3.9 | 3.9.6 — `glb_stat.py`/`normalize.py` written to that floor |
| OpenRouter key | `thriftgod/.env` | absent; house convention `~/Documents/dealgod/lore/keys.env` (auto-read by gen scripts) |
| depot upload cred | — | `GOD3_PW` env, **not set here** → publish is gated on John (see `publish.py`) |
## Normalized set (16 — ready; `manifest.json` → `fittings` / `furniture`)
house law enforced on every one: metres · +Y up · origin at base (minY=0, centred X/Z — verified
node-aware) · ≤5k tris · WebP ≤1024 · no Draco. *Facing is not auto-corrected* — symmetric props are
orientation-agnostic; the few directional ones (counter, food_cart) keep their native front and
Lane B/C rotate when placing (per-asset `yaw` is available in `batch.json`).
| PROCITY id | source GLB | src tris → out | footprint (m) | height (m) | notes |
|---|---|---|---|---|---|
| **fit** record_crate | shop-fittings/record_crate_plastic_01 | 18320→5000 | 0.46 × 0.63 | 0.41 | ★ native-metres, textured red milk crate; serves record bin too |
| **fit** wire_shelf | shop-fittings/shelf_metal_wire_01 | 330→330 | 1.17 × 0.44 | 1.80 | ★ clean upright wire shelving |
| **fit** clothes_rack | shop-fittings/clothes_rack_01 | 3152→3152 | 1.34 × 0.43 | 1.50 | ★ rolling clothes rack (opshop) |
| **fit** bookshelf | shop-fittings/bookshelves | 45128→5000 | 0.20 × 1.02 | 2.00 | tall bookshelf w/ books (book/video/opshop) |
| **fit** cube_shelf_wide | shop-fittings/shelf_cube_bookshelf_01 | 17734→4999 | 0.75 × 1.24 | 1.10 | stocked cube shelving (toy/book) |
| **fit** counter | shop-fittings/balcao | 276→276 | 1.06 × 4.02 | 1.10 | long bar counter — Lane C may want to scale to lot |
| **fit** coffee_table | shop-fittings/coffeetable | 495→495 | 0.67 × 1.49 | 0.45 | low display/side table |
| **fit** work_table | shop-fittings/computertable | 1556→1556 | 0.44 × 1.04 | 0.75 | work/trestle table w/ lower shelf |
| **fit** box_crate | shop-fittings/warehouse_box | 78→78 | 1.35 × 1.32 | 0.60 | open bulk bin / bric-a-brac box |
| **street** bench | street-furniture/bench | 1942→1942 | 0.44 × 1.21 | 0.85 | slatted seat |
| **street** bench_modern | street-furniture/eb_hipster_bench | 640→640 | 1.68 × 0.47 | 0.45 | low modern bench |
| **street** bench_wood | street-furniture/woodbench | 11728→3999 | 1.34 × 0.59 | 0.85 | timber park bench |
| **street** longbench | street-furniture/longbench | 1172→1172 | 5.86 × 1.08 | 0.85 | long feature bench (arcade/market) |
| **street** park_bench | street-furniture/park_bench_01 | 9884→5000 | 1.92 × 1.62 | 0.85 | classic slatted park bench |
| **street** streetlight | street-furniture/streetlight | 6592→4999 | 1.64 × 1.82 | 5.00 | ornate lamppost |
| **street** food_cart | street-furniture/food_cart_bakso_01 | 30316→5000 | 3.00 × 2.07 | 2.00 | textured food cart (~3MB — heavy, 28 tex; optimize later) |
## Rejected during normalize (needs-manual-fix — NOT in manifest)
| source | issue (verified by render) | disposition |
|---|---|---|
| shop-fittings/cube_bookcase (`cube_shelf`) | node-scale distortion → 6.3 × 8.4 m footprint | dropped; `cube_shelf_wide` covers the need |
| shop-fittings/garage_shelves_metal_v2 | imports lying flat (green pallet); baked node transform, up-fix didn't help | needs manual re-origin in Blender; `wire_shelf` covers shelving |
| shop-fittings/table, saloon_table, table_02, desk_01, kitchen_table | degenerate/flat or node-distorted (`table` → 55×55 m; `desk` → 17×17 m) | rejected; `work_table`/`coffee_table` cover tables |
| shop-fittings/radiogram_furniture_v2_l1 | Blender "Please select a file" on import (bad GLB) | needs re-export |
| street-furniture/market_stall_01_CHECK | import error (`_CHECK` = sorter-flagged) | → MeshGod/primitive (see `MESHGOD_BATCH.md`) |
## QUARANTINE — licence unclear / branded (🔴 do NOT publish or ship)
The house rule is 🟢 web-ok only; anything branded or of unknown provenance is quarantined until
cleared. These are **excluded from the manifest**:
| asset | reason |
|---|---|
| `furniture/armchair-vitra-eames`, `ines-chair-calligaris` | protected designer marques (Vitra/Eames®, Calligaris®) |
| `shop-fittings/ikea-cupboard` | IKEA® product design (+259k tris) |
| `props-scenes/mk2_1210_turntable_-_old` | Technics SL-1210® industrial design (trademark) |
| `props-scenes/tuborg_fest_scene` | Tuborg® brand scene |
| `furniture/uploads_files_*`, `props-scenes/uploads_files_*` (Couch William, Harland Office Chair, nv toufa, Backpack) | CGTrader/free3d bulk dumps, licence not recorded |
| `furniture/sofa-c`, `hug-armchair`, `dragonchest`, `kitty-bed-01`, `bean_bag_chair` | provenance unrecorded — verify before use |
> **Blanket caveat (applies to the 16-asset publish set):** the *generic* fittings we normalized
> (benches, shelves, counter, crate…) carry **no explicit licence/provenance record** — I cross-
> checked all 16 source filenames and none is a recognizable trademark, and they were pre-sorted
> into the house library by John for exactly this use, so they're treated as usable per the lane
> brief. But "unclear ⇒ quarantine" is the house rule: **before `publish.py` pushes to the shared
> CDN, record a one-line source/licence per asset**, and for any CC-BY source carry attribution.
> If provenance genuinely can't be established for one, pull it from the publish set. This is a
> reason the publish step is deliberately gated on John, not automated.
## Provenance — round-3 hero props (for the depot publish sign-off)
Per the round-3 instruction ("record the per-asset provenance list in AUDIT.md first, then hand
John the two-liner"). The hero props have the **cleanest provenance in the whole set** — they are
100% generated on-device, from no third-party source:
| asset (`procity_fit/street_<id>_01.glb`) | origin | licence zone |
|---|---|---|
| **5 generated** — listening_booth, drinks_fridge, arcade_cabinet, milkshake_mixer (fit) · novelty_record (street) | **fully synthetic, local**: concept image = MODELBEAST `flux_local` (FLUX.2-klein-4B, Apache-2.0 model) → mesh = `trellis_mac` (TRELLIS.2, an original reconstruction of that concept image). No scanned/third-party geometry, no copyrighted source asset. | 🟢 original work (CC0-equivalent) |
| cash_register (`vintage-cash-register.glb`) | **reuse** of John's own `thriftgod_hero` asset, already live on 3GOD (round-3 reuse check) — not regenerated. | 🟢 same as existing depot set |
| magazine_rack | **not shipped** — TRELLIS wire rack floored ~112k tris (thin-wire gotcha) → in-engine primitive. | n/a |
| glass_case, bus_shelter | **not shipped** — TRELLIS failed on the transparent glass → fal.ai fallback list (John's go, ≤$2.70) or primitive. | n/a |
- **Prompts were generic period objects with explicit `no text, no brands, no people`.** Every kept
prop was eyeballed for accidental baked branding (contact sheet `docs/shots/laneE/props_gen_local.png`).
The only textual marks are the **drinks-fridge's weathered faux-stickers** — verified at full concept
resolution to be **garbled, illegible pseudo-lettering** (no real trademark; e.g. a faux barcode +
nonsense glyphs), which reads as period flavour and blurs out at mesh-texture resolution. 🟢 cleared.
- Tri/size note: TRELLIS meshes are dense multi-shell scans; `normalize.py`'s COLLAPSE decimate floors
well above the ≤5k library budget (**2577k tris, ~0.33.5 MB/prop**; neither COLLAPSE nor meshopt
can reduce shell-soup without a voxel-remesh that destroys the baked UVs). Accepted for **focal,
optional, LOD-able** props (texture-intact) — flagged for a later texture-bake-to-lowpoly / gltfpack pass.
- These GLBs stage locally (`web/assets/models/`, git-ignored, served by `?localdepot=1`) and await
John's depot publish; they are **not** committed binaries (same policy as the library `_normalized` set).
## Coverage vs the registry fittings needs
| shop type | fittings need | covered by | gap → |
|---|---|---|---|
| record | bins, crates, counter, listening corner | record_crate, counter, wire_shelf | **listening booth** → MeshGod |
| opshop | clothes racks, bric-a-brac shelving, book wall | clothes_rack, wire_shelf, bookshelf, box_crate | — |
| toy | cube shelves, display tables, **glass case** | cube_shelf_wide, coffee_table | **glass case** → MeshGod |
| book | bookshelves, **spinner racks**, armchair | bookshelf, cube_shelf_wide | spinner rack, armchair → MeshGod/primitive |
| video | aisle shelves, **returns slot**, poster wall | bookshelf, wire_shelf | returns slot, poster wall → primitive |
| pawn | **glass cabinets**, wall hooks, barred window | counter | glass cabinet → MeshGod; pegboard = `tex-pegboard` skin |
| milkbar | counter, **fridge**, magazine rack | counter | **fridge**, magazine rack → MeshGod/primitive |
| dept | mixed sections, **escalator prop** | (all above) | escalator → primitive |
| stall | trestle tables, crates | work_table, box_crate, record_crate | **market stall** → MeshGod/primitive |
| street | bench/streetlight/bin/tree | bench×4, longbench, park_bench, streetlight, food_cart | bin (`council-bin` on depot), tree → billboard (Lane B) |
Gaps with no clean source are shortlisted in `MESHGOD_BATCH.md` (budget-gated) — everything has an
in-engine primitive fallback, so none of these block the game.
## Depot cross-reference (`GET /api/list`, 138 assets)
- **90 named + 48 TRELLIS-hash.** Reusable house props already live (verify visually + licence
before wiring): `street-bench.glb`, `council-bin.glb`, `milk-crate-stack.glb`, `cashbot.glb`.
⚠️ `akai-mpc-live-iii-*` is a **trademarked product design** — same quarantine class as Technics/
IKEA; do not treat as clean web-ok reuse without a licence check.
- **No `procity_*` assets yet** — this lane is the first to publish that namespace.
- Our 16 normalized GLBs are staged in `pipeline/_normalized/` and upload via `pipeline/publish.py`
once `GOD3_PW` is provided (idempotent, reversible).
## Full library inventory (dispositions)
`shop-fittings/` (33): normalized 9 · rejected 8 (7 node-distorted/degenerate + radiogram bad-GLB) ·
quarantine 1 (ikea) · unused/dup 15 (heavier or duplicate tables/shelves — `shelf_storage_rack_01`
alone is 960k tris).
`street-furniture/` (9): normalized 7 · error 1 (market_stall) · `building_shell_01` reserved for
Lane B (38k-tri building shell — not a fitting).
`furniture/` (17): mostly domestic (beds/sofas/chairs) — out of scope for shop fittings; 6 quarantined.
`props-scenes/` (10): `dj_roomv01` + turntable = record-shop dressing (turntable quarantined: Technics);
rest branded/scene dumps.
Raw stats for every **parsable `.glb`** (59 of the ~69 library entries; the rest are `.fbx`/`.obj`
or subdir sources not counted): `pipeline/_audit_stats.json`. `glb_stat.py` reports **world-space**
dims (node-transform-aware) and WebP/PNG/JPEG texture sizes. Normalizer output:
`pipeline/_normalize_results.json`.