640bdbb55d
28 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
640bdbb55d |
Lane E R28 (v5.1): Spike 1 — look.glb shipped; lean does not exist (ledger #1)
look.glb — DONE, published, verified. Looking_Around.fbx (675 KB) from the CACHED tailnet stash (not re-downloaded — the asset-pipeline skill's law) -> fbx_to_clip.py -> web/models/peds/look.glb: mesh-free, 65 mixamorig joints, 195 tracks, inverseBindMatrices present, 136 KB. Structurally identical to the sit.glb precedent on every measurable field (meshes/nodes/skins/joints/bind), so D's _canon binds it exactly like walk/idle/sit. Depot: published to digalot.fyi/3god under John's R22 standing authorization for Lane E assets (_published.json 43 -> 44), verified by fetching the bytes BACK from the public depot: https://digalot.fyi/3god/a/look.glb -> HTTP 200, 139,640 bytes, sha1 identical to local. -> D: it's ready. Gate it behind an opt the way rigs.js gates sit (loadPedFleet(base, { sit })) — a raw fetch would breach the ?classic=1 zero-fetch-delta covenant, same as sit.glb. `lean` DOES NOT EXIST — the spike's premise is half wrong. The brief and kickoff both say "two of the 34 already-cached clips (lean, look-around)" and "Spike 1 needs nothing from anyone". look-around is cached; lean is not, anywhere. Measured, not assumed: the stash's 34 clips contain no lean; `find ~/Documents -iname "*lean*"` on ultra returns nothing (not mixamo-fetch, not character_kit, not 3D=models, no FBX by that name at any depth); and the fetch tool cannot help unattended — `node fetch.cjs search "lean"` -> "FATAL nothing on debug port 9222 — quit Brave and relaunch with --remote-debugging-port=9222". It needs John's logged-in Brave session (his browser, his Mixamo account); I won't relaunch it. I did NOT substitute a lookalike. `Bored` is the nearest stash clip and it is a standing weight-shift idle, not a wall-lean — D's half explicitly needs shopfront adjacency ("lean against a wall wants the same care"), so a standing idle would quietly change what Spike 1 proves. Half a spike, honestly, beats a whole one that lies. -> John: one small unblocker — relaunch Brave with --remote-debugging-port=9222 and open a Mixamo tab; the fetch+convert is minutes once the token exists. Instrument LOD — D killed it and D's measurement is better than mine. I had built the five _lo variants in scratch (14k -> 3500/3500/4000/6000/3000) when D's commit landed saying "E: STOP — do not build the _lo variants". Nothing shipped; scratch discarded. D measured the rooms an LOD must fire in: max diagonal 15.2m in the largest venue, so the player can never be far enough — practical win 0 tris. My own reading reached the same verdict by another route, recorded as corroboration: C's §4 already says "the interior gate is DRAWS; tris are the STREET budget (200k)", and an LOD swap does not change draws at all (same object, same material, fewer tris) — the item's entire win landed on a metric no interior gate reads. Two independent measurements, one verdict. Salvage if it ever returns: at ~3k the guitar_amp SHREDS (white gaps punched through its silhouette — confirmed against the shipped 14k thumb as a decimation artifact, not a source defect, per the R22 food_cart discipline); it needs 6k to read clean. The other four were clean at 3-4k. -> A: your own file's comment now contradicts its code. Chasing why the fingerprint read 0x5f76e76 rather than the 0x3fa36874 I'd seen every round, I confirmed it is LEGITIMATE — your R27 w5 facade fix re-pinned 51 goldens under the amended covenant. But selfcheck.js:267 pins hash: 0x5f76e76 while selfcheck.js:301 still says "the synthetic golden above stays 0x3fa36874". Code and comment disagree by 34 lines — the exact species as R24's validator bug (my docstring said nested, my code read top-level); the next reader trusts whichever they read first. Your file, your call; flagging per the round's "flag loudly if anything disagrees". Gates: selfcheck ALL GREEN 156,352/156,352 · qa.sh --strict 6 passed / 0 failed. look.glb moves NO golden — proved by moving it aside and re-running: the fingerprint is identical either way, because an unreferenced clip is never fetched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
bee7563a76 |
Lane E R27 (v5.0): provenance v5-final — and the roster gap the freeze caught (ledger #6)
THE BUG THE FREEZE FOUND: redhill_godverse was ON DISK but NOT IN THE ROSTER — for three rounds. The v5 provenance table needed real numbers, so I measured instead of carrying the v4 row forward. The count didn't match: 23 caches on disk, 22 rostered. The missing one was redhill_godverse — THE TOWN THE ENTIRE v5 EPOCH WALKS TO. Mine, squarely. index.json is Lane E's file (write_index()). G's redhill_godverse landed in R24 ( |
||
|
|
f2989858aa |
Lane E R26 w4: the mint-id fence — my rule was the stale thing (wave 4, E's one line)
THE RED WAS MINE. My R25 slot-id check demanded `sku_` on every real-stock pack — faithfully implementing C's R25 line, which was written BEFORE MINT EXISTED. It then failed all 14 of G's mint crates, whose ids honour its every intent: non-positional, seeded, stable, zero reuse. C's ruling names it exactly: "the rule was the stale thing, not E's check." Fourth hold of the epoch, and the fourth to trace to a rule meeting a case written before the case existed. THE FIX IS A FENCE, AND IT IS STRONGER THAN THE RULE IT REPLACES — that was the thing to prove. The easy green was to drop the prefix check. Instead the form is sourcing-scoped per C §7.2a (R26 w4): sourcing="real" => `sku_` (a POS copy on a shelf) · sourcing="mint" => `mint_` (a dealgod listing standing in for one). A crate wearing the other's prefix FAILS. WHY THIS IS A MONEY BUG, NOT A NAMING BUG — G's judgment, now law. G refused to file dealgod listing ids under `sku_` to go green the easy way. They were right: tier-2's sold-means-gone looks up POS skus. R24's id collision entered the WRONG SHOP; the same collision in the money layer SELLS A REAL RECORD out of a real shop to satisfy a minted stand-in. The gate's error says that, in those words — the cost, not the rule. The message also distinguishes a fence-crossing from a merely positional id, because they are different faults and the reader shouldn't have to guess which one bit. PROVED 7/7 — that the fence BITES, not merely that the red stopped. G's real crate (sku_...) -> PASS · G's mint crate (mint_...) -> PASS · mint filed under `sku_` (the exact shortcut G refused) -> FAIL, naming the fence and the real cost · real wearing `mint_` (the reverse) -> FAIL · positional ids still FAIL in BOTH sourcings (the old rule's whole intent, retained) · duplicate ids -> FAIL. Loosening would have passed the first two and lost the last four; this passes the first two and keeps all four. BOTH OLDER SUITES BROUGHT FORWARD RATHER THAN LEFT TO ROT. The R26 suite's mint fixture wore sku_ ids, so the fence correctly rejected it — a fixture that fails for a NEW reason has stopped testing what it was written for. Moved to the mint_ space: 17/17. R25 licence suite: 8/8, tally still firing VIA THE TALLY. Third round running where the near-miss was a test going quietly stale around a changing contract; it is the failure mode I now look for first. Gates: atlas-QA OK — 15 per-shop atlas(es) valid, 15 licence line(s) shown, 0 warning(s) (1 real + 14 mint, every one showing its flag to a human) · validate_manifest exit 0 · qa.sh --strict --matrix 7 passed / 0 failed / 0 warn — QA GREEN. -> F: your 6/1/0 is now 7/0/0. The beta is yours to tag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
33577a9675 |
Lane E R26 (v5.0-beta): the sourcing arm + the atlas manifest, both ways (ledgers #3, #6)
THE FIELD IS `sourcing`, NOT `tier` — and reading C's contract instead of the brief is the only reason
this gate isn't already broken. The R26 brief says "the validator grows the tier arm... `tier` required
on every atlas". C ruled it CANNOT be `tier` (§7.2b): `tier` is already the charter's ladder rung (0
parody / 1 static-real / 2 live) and a mint atlas is ALSO rung 1 — same mechanism, different data origin.
Overloading it puts two meanings in one name: the same species as the plan-id/godverse-id collision and
the positional ids. Had I built the brief's word, my gate would demand `tier` while G emits `sourcing` —
R23 exactly, re-run. The contract's author is the authority for the contract's shape.
THE HONESTY SEPARATION, BOTH DIRECTIONS (C §7.2b). `sourcing` ∈ {real, mint} required; no `sourcing` =>
FAIL (a crate that cannot say where it came from must never pass as one that can). mint must carry no POS
claim; real must carry the POS provenance it claims. The licence line prints for both — verified, not
assumed.
-> C: §7.2b says "a mint index MUST NOT carry POS-snapshot fields" but does not enumerate them, so I named
the set — correct it if it's wrong. I assert on `crate`, `provenance.source.pos_db`,
`provenance.source.pos_dump` — the fields that claim a SPECIFIC SHOP'S ACTUAL INVENTORY. I deliberately
excluded `snapshot`: §7.3 requires it on every atlas as the determinism pin, and a mint bake has its own
honest source snapshot (the dealgod dump it sampled). The error names the exact field found, so a
divergence with G surfaces as a diagnosis, not a mystery.
THE MANIFEST (§7.2d, ledger #6), consistency both ways. An atlas on disk absent from the manifest FAILS
(no entry => no fetch => that crate silently never loads; an unreachable atlas is not a passing atlas). A
manifest entry with no atlas FAILS (the wire fetches it and 404s — the exact noise the manifest exists to
kill). C's "absent manifest => legitimate zero-shop state" is honoured: no atlases + no manifest => SKIP.
-> C: one hole your rule implies but doesn't spell out — a manifest that PROMISES shops while zero atlases
exist now FAILS rather than skipping. "Absent" scopes to the empty tree; a tree where something on disk
still asserts atlases exist is the vacuous shape wearing a hat. Flagging it as my reading, not your words.
PROVED BEFORE HANDING G THE GATE — 17/17, including a mint crate that does not exist yet (the R25 rule:
never hand a lane a gate that fails on compliance). real -> PASS · mint -> PASS WITH ITS LICENCE LINE
PRINTED (ledger #3's "prints for both") · real+mint side by side -> PASS · mint carrying `crate` -> FAIL ·
mint carrying pos_db -> FAIL · real carrying no POS provenance -> FAIL (the reverse) · no `sourcing` ->
FAIL · sourcing='realish' -> FAIL · atlas absent from manifest -> FAIL · manifest entry with no atlas ->
FAIL · declared type not on disk -> FAIL · manifest says mint while the index says real -> FAIL · manifest
missing while atlases exist -> FAIL · unparseable manifest -> FAIL · empty tree -> SKIP · empty manifest
-> SKIP · manifest promising a shop with no atlases -> FAIL.
THE R25 SUITE WAS GOING STALE AND I BROUGHT IT FORWARD RATHER THAN LET IT ROT. Adding `sourcing` + the
manifest made every R25 licence case fail for a NEW reason — which would leave the licence arm untested
while appearing tested. Updated to the R26 contract: 8/8 green, and the tally tripwire still fires VIA THE
TALLY (via_tally=True), not incidentally. Near-miss worth recording: the manifest error briefly shadowed
the tally in the harness, which is precisely how the tally died the first time. A test that fails for a
new reason has stopped testing what it was written for.
The gate is RED until G lands (2 errors: no `sourcing`, no manifest). G is in my wave, parallel; it goes
green on their re-emit with no change from me — same as R25.
-> F: THERE IS STILL NO v5.0-alpha TAG, and C's + B's BETA commits (
|
||
|
|
9b1df5cca0 |
Lane E R25 (v5.0-alpha): the licence line made unmissable + the sku form asserted
THE BUG WAS A DIVERGENCE, NOT A SPELLING (ledger #2). The R24 gate printed "OK — 0 warnings" on a
real shop's product photos while saying NOTHING about their licence. Two paths read one field with
different spellings:
the CHECK: lic = prov.get("licence") or prov.get("license") <- permissive: passed either
the PRINT: lic = prov.get("licence") <- strict, behind `if lic:`
While G's artifact was British they agreed. G's R24 keyed re-emit moved it to US `license`: the check
still passed, the print silently resolved to {}, and FLAG BEFORE ANY PUBLIC/COMMERCIAL RELEASE stopped
reaching a human. The `or` fallback WAS the bug — it made one path permissive so it could not feel the
other break. That is my own R21 stale-roads lesson one layer up (a check applied to one of two
symmetric paths is a trap with a fuse on it) — I wrote that lesson down and shipped it again anyway.
Fixed structurally, not by adding the missing spelling: ONE spelling, NO fallback (British `licence`
now ERRORS and names C's §7.3 retirement); ONE lookup, ONE owner (validate_index returns the evidence
string, main prints what it is handed and never re-looks-up the field — no second path left to drift);
and the evidence line is COUNTED — judged N atlases means N licence lines shown, or FAIL.
MY OWN FIRST CUT HAD THE SAME DISEASE AND MY OWN TEST PASSED FOR THE WRONG REASON. I added the tally
tripwire — but main() also appended its own missing-licence error, so all_errs was never empty when the
tally would fire: the tally was UNREACHABLE DEAD CODE, and the test went green through the other path
and reported PASS. Exactly the trap I recorded in R24 ("a gate that fails for the wrong reason is a
gate that will pass for the wrong reason later") — one round later, on me, in the file where I wrote
it. Now the field check owns the precise error and the tally sits after the all_errs return, existing
only for the day that check goes permissive again. Verified by stubbing validate_index permissive: it
fails VIA THE TALLY, not incidentally.
Proved 8/8: G's sku re-emit -> PASS with the flag shown · `license` gone/empty -> FAIL · British at top
level -> FAIL · British nested -> FAIL · attribution/snapshot gone -> FAIL · THE R24 SILENT SHAPE ->
FAIL · permissive-check simulation -> FAIL via the tally.
Aligned to C §7.3 as the provenance authority: the four gate fields (license, attribution, generator,
snapshot) live at TOP LEVEL, US spelling — the convention 21 shipped town caches already use. This
reverses R24's #2/#3, which read the artifact of the day. Docstring and code now say the same thing;
R24's fourth bug was that they didn't.
C §7.2a — THE SKU FORM (ledger #3), and I verified C's claim before building to it: independently
measured 120/120 godverse ids also present in the generic pack (F and C exactly right), and G's
snapshot carries 120/120 unique skus so the re-emit was feasible. Proved the compliant shape passes
BEFORE handing G the gate (4/4: sku_<POS sku> -> PASS · positional -> FAIL · sku-but-duplicated ->
FAIL · one id sneaking back into rec_ -> FAIL at 1/120, so it catches a real collision, not only an
all-or-nothing one).
-> C: two things beyond your literal ask, say if you disagree. (1) I also assert the actual property
your rule exists to guarantee — the pack's ids are DISJOINT from the shipped generic packs, measured
against web/assets/models/stock_*_index.json; the prefix says ids should be disjoint, this measures
whether they are, and it catches the reverse drift (a generic pack wandering into sku_) a prefix check
never could. Absent generic packs WARN rather than passing silently. (2) I flag British `licence`
anywhere, including inside the nested provenance{} "colour" block — §7.3 retires the spelling and R25
is what a spelling fork costs, so I read the retirement as global. Scope it back if you meant
otherwise.
The gate was RED by design for one wave: between my readiness and G's re-emit the collision was real
and unfixed, so it failed deliberately — a gate that stayed green on a defect F had just found would
be the vacuous species in a different hat. It went green when G landed
|
||
|
|
5815dfbd58 |
Lane E R24 (v5.0-alpha): the crate's real street, the honest gate, and Ballarat retired
THE STREET (ledger #3). redhill_real: Red Hill, Brisbane — 36 shops (9 heroes + 27 texture, -29 subsampled), 884 roads, median NN 73 m. **Musgrave Road is in roads[] (41 ways, primary + residential)** — that was the point: Monster Robot Party's real shop now has its real street. One bounded Overpass fetch under the standing authorization; raw snapshots in _raw/, ODbL, C's mapping. This is G's donor for godverse_town.py -> redhill_godverse. TWO HAZARDS HANDED TO G/A, both measured against the real geometry (notes R24 §1): (a) The shop is NOT in OSM — no shop=music node, no name match anywhere in the bbox (checked the raw snapshot, not the emitted cache). It cannot arrive via the fetch; G must inject id 3962749 from the census or the town ships without the shop the release is about. (b) THE SEATING HAZARD: A's lift seats on the NEAREST edge, and from G's geocode three streets are nearer than the addressed one — Zig Zag Street 38.6 m (residential), Craig Street 46.1 m, Musgrave Road 51.6 m. The shop would seat on Zig Zag St and the headline would quietly become false. Measured fix (G's call): the point on the real Musgrave centreline nearest G's geocode is -27.455169, 153.006902 — 0 m to Musgrave, next candidate 43 m. Snaps the street, does NOT verify the house number; I have no address data for where #147 sits along the road. THE HONEST GATE (ledger #4). F's catch was right and there were FOUR bugs: the glob used the published-contract name the runtime can never load (0 matches -> returned 0: it passed identically whether atlases were absent, misnamed, or perfect); the code read provenance top-level while my own docstring said nested (G nested it correctly — the gate would have failed G's real artifact); licence/license; and a stale ceiling. Rebuilt on the "runtime is the authority" ruling: globs stock_godverse/<id>/stock_<type>_index.json, type in {record,book,toy}. Vacuous-gate law implemented literally — 0 matches + stray files FAIL (listing them); 0 matches + empty dir prints "atlas-QA SKIP: no atlases present (0 files matched glob ...)"; plus an id equality (shop.godverse_id == dir) so it proves it touched its subject. Proved on four cases: empty -> loud SKIP, misnamed (F's exact bug) -> FAIL, unparseable -> FAIL, G's real atlas -> PASS (120 items, 2 atlases, licence printed). My own test found a fifth hole — the glob still matched the old stock_shop_* name, so the misnamed case failed only incidentally; added a STOCK_TYPES name check so it fails for the RIGHT reason. A gate that fails for the wrong reason will pass for the wrong reason later. BALLARAT — RETIRED, counted, and a DIFFERENT illness from Toowoomba (notes R24 §3). Toowoomba was dead everywhere. Ballarat is alive exactly where the game isn't: 103 POIs, densest 400 m disc = 47 of them (Toowoomba's was 3) — but that disc is cafes/clothes/bakeries while the op-shops sit 854 m, 1042 m and 1709 m out. Heroes and density don't coincide, so no bbox holds both. Real builds at every span: 1.0 km -> 8 shops/184 m/hub 4-8 but ZERO op-shops (a thrift town with no thrift shop); 2.0 km -> 12/186 m/3-12; 3.0 km as shipped -> 20/255 m/4-20. Every row worse than any shipped town. THE BINDING CONSTRAINT WAS MINE, NOT OSM'S: with 2 heroes the 3x texture cap keeps 6 of 47 texture POIs and the subsample is spatially blind, so survivors scatter at any span — part of the 255 m A's warn caught was my own cap's fingerprint. Seeding texture near heroes fixes the class but moves every town's golden -> filed as a v5.x proposal, not done in a release round. I OVERSTATED MY R23 ADVICE TO A: the hub fraction is NOT a standalone discriminator — glebe (shipped, healthy) reads 13% and redhill 14%; a hub threshold would false-flag both. Median NN is the robust primary; hub is only comparable at equal shop counts (toowoomba 2/12 vs darwin 7/12 was fair because both had 12). The raw-vs-seated calibration point stands. METHODOLOGY, recorded because it nearly shipped: I picked Ballarat's span from an offline simulation that predicted 68 m / hub 5-8, and had already written those numbers into a config comment as fact. The real build returned 184 m / 4-8 — same counts, different sample. Never trust a re-implementation of the pipeline's own selection; run the pipeline. -> A (batched pins): ADD REAL_TOWN_GOLDENS['redhill_real']=0x6046700f and REAL_TOWN_GIG_GOLDENS['redhill_real']=0x673785ee (the headline town currently only WARNS as UNPINNED — ungated until you pin it). REMOVE ballarat_real 0xf0a9e8a1 / 0xf097c331 — dead config by your own R23 note. -> F: tools/qa/tour_shots.py still shoots town=toowoomba_real, which I deleted in R23 — the v4 tour breaks on a missing town. Your file, your call. A retirement isn't done when the cache is deleted; it's done when the consumers are swept. -> C: built to the runtime + G's real artifact per the ruling; LANE_C_PUB §7 line 271 still names the contradictory stock_shop_<id>_index.json. I reconcile when your corrected contract lands. Determinism receipt: the retirement forced a full 21-town rebuild from cached raw (no refetches) and every existing cache came back byte-identical — only ballarat, redhill and index.json moved. Pack: 21 real towns · 1196 shops · 299 heroes (22 rostered with G's newtown_godverse). Selfcheck ALL GREEN 149,696, synthetic golden 0x3fa36874 unchanged. qa.sh --strict --matrix: 7 passed / 0 failed, MATRIX GREEN 10x7. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
84e0a1b764 |
Lane E R23 (v5.0-alpha): the atlas validator + toowoomba retired (ledger #4)
1. validate_atlas (the G2a format gate). pipeline/validate_atlas.py, wired into validate_manifest so it
runs in qa gate 3. Judges Lane G's tier-1 atlases from the COMMITTED FILES ALONE -- no dealgod DB, no
network. No atlases yet => clean pass, so it's in place before G's lands. Enforces: provenance
{license, attribution, generator, snapshot} (charter law #3 + determinism); NO private-individual item
fields (law #3); 1 atlas/shop hard cap 2 (C §7.1); <=1024², 2048² only for a 60+ item shop (C §7.2);
declared atlas_px == the atlas's REAL pixels + every listed atlas exists; schema/UV/bands/dup-ids
(C §7.3). The licence string is PRINTED, not pattern-matched -- clearing photos for public release is
a human call, so the gate surfaces it. Dependency-free PNG/WebP header parser. Tested against a
10-case matrix (real 2048² WebP + 1024² PNG): good passes clean, all 9 violations caught.
2. toowoomba RETIRED (my call, counted). Tried the re-bbox FIRST: 3.0km CBD-wide -> 1.6km on the Ruthven
St heart. It fixed the named metric (median NN 395.7 -> 89.4m raw, 'passes') but made the real thing
WORSE: hub density 3/12 -> 2/12 within 160m, the pack's worst (D's alive-darwin is 7/12). Its shops
are PAIRS strung along a road, not a high street; densest 300m cluster is 3 shops (< MIN_TOWN_SHOPS),
so no tighter box exists. Shipping it would have gamed the number while leaving a town nobody shops in
(D: 0 finds / 1417 checks). Config entry kept commented with the rationale. Pack: 21 real + 1 godverse
= 22 rostered, 1180 shops, all 8 states/territories (QLD keeps westend). selfcheck ALL GREEN 152015.
-> Lane A, before you freeze the spacing warn (#5): (a) your validator sees the CACHE (raw lat/lon) but
D's numbers are SEATED (post-lift) -- darwin is 27m seated vs 68.3m RAW, so a threshold picked off D's
table would FALSE-WARN darwin; calibrate on the raw spread (daylesford 11.6 ... braddon 119.2,
ballarat 254.6 -- a ~200m line has daylight). (b) median NN alone is GAMEABLE: my re-bbox improved it
4.4x while the town got worse -- the hub fraction is the discriminator, and my raw hub metric
reproduces D's darwin exactly (7/12), so it's directly encodable (alive ~38-75%, dead <=20%).
(c) ballarat is a SECOND spread town D's two-town comparison missed (NN 254.6m, hub 4/20 = 20%) -- it
will trip your warn, correctly. Not retired: the ledger named toowoomba only.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
d81e499194 |
Lane E R22 (v4.0): the venue_night tri diet — B's #1a driver was mine, fixed (BLOCKING #1b)
B's diagnosis nailed it: 149,161 of 163,015 tris (91.5%) at katoomba venue_night were four of my GLB street props. Buildings 348, posters 222 (A's cap worked, never the lever), pools 0. B's sharpest point: it is NOT the density widening -- road density drives the bench/bin/shelter cadence (~100 props on a 966-edge real graph). Fix (collapse-decimate via the R13 instrument tool; originals kept as _hi): bench 1942 -> 500 rendered 60,202 -> 15,500 bus_shelter 7998 -> 2500 rendered 55,986 -> 17,500 bin 3000 -> 800 rendered 18,000 -> 4,800 food_cart 4991 -> 1000 rendered 14,973 -> 3,000 furniture total 149,161 -> 40,800 (-108,361) Projected view ~54.7k (B's 163,015 baseline) / ~113.6k (vs F's 221,935) -- PASSES the 200k gate either way with 86-145k spare. F: these are projections off B's per-instance attribution; yours is the real measure. -> F: RE-MEASURE. Eyeballed every prop; two needed re-cutting: bus_shelter @1000 shredded (thin roof plate on a voxel-remeshed shell) -> @2500 clean; bin @400 creased -> @800 clean. food_cart's black base slab is in the SOURCE model (confirmed against the pre-diet thumb from git), not a decimation artifact. Zero blast radius: dims/footprints/heights identical -> manifest.json byte-identical -> B's placement and A's goldens untouched. Published 4 diet + 4 _hi archives to the depot (John re-authorized explicitly; GLBs are git-ignored so the depot IS the archive). -> Lane B (your 2nd note, cause found, NOT fixed by design): the MeshPhysicalMaterial on bench+food_cart is KHR_materials_specular in the glTF, and it survives a Blender re-export. Fix = neutralise specular pre-export. Deliberately deferred to v4.x: the gate is tris (cleared), and changing shipped shading in a release round without a visual re-verify is risk for no gate benefit. Same list: food_cart is 3.1MB on the depot -- 28 textures now dominate (tris are 1000); a texture-merge item, not a tri item. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a7289d0550 |
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
|
||
|
|
8a383e494e |
Lane E R21 (v4.0): the town pack — 22 towns, 1192 shops (DATA-ONLY, non-gating)
Ledger #5 pull-forward. Nothing here touches a golden until A absorbs in R22; F tags v4.0-beta with or without it. selfcheck ALL GREEN 154141/154141, synthetic 0x3fa36874 unmoved, all 22 byte-identical on re-run. - Curated 18 candidates on secondhand density first (heroes are the game), a walkable 2-3.4km centre, and a national spread; 17 survived -> 22 towns, 1192 shops, 298 heroes, all 8 states/territories. fitzroy is the mecca (40 heroes/160 shops, 2x katoomba); thin tail toowoomba/darwin (3 heroes) left in as honest data -- A/Fable may drop them in R22. - FINDING: the 3x-hero cap is a CURATION FILTER, not just a density knob. Wollongong had ~62 real shops but 1 hero -> capped to 4 -> dropped by the >=6 floor. A town without a secondhand strip cannot inflate into a retail strip; John's SUBTLE directive does quality control for free. - Newcastle: my centre was wrong, not the town (CBD held 2 heroes; the strip is Hamilton/Beaumont St). Re-centred: 2 -> 9 heroes, 8 -> 36 shops. - BUG (mine, shipped R18, caught here): fetch_roads_raw had no query-comparison while fetch_raw did, so re-centring refetched shops but silently reused the OLD CBD roads -> Hamilton shops seated against a graph 2.5km away -> the town marched out with ZERO shops (surfacing as 32 bogus 'open-late invariant' failures; ten other no-video towns passing is what proved it wasn't the open-late rule). Fixed: the roads path now compares its query too -- the bbox lives in the query, so a re-centre must invalidate BOTH snapshots. Newcastle rebuilt: 34 shops seated, openLate=1. - Discipline: bounded bboxes, raw snapshots committed (shops+roads), C's §6 mapping, SUBTLE guardrails (heroes never subsampled, texture 3x, 2392 drops counted), ODbL. Overpass rate-limits hard at pack scale (batch 1 died on a fatal 504 after 25 retries) -- courtesy sleep 4s, two polite batches. -> Lane A (R22): 34 goldens to pin (17 new towns x base+gig); sizes 12->160 shops load-test your capacity/overflow fences. -> Lane B: index.json now lists 22 towns (your selector already reads it). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
078245f7bd |
Lane E R20 (v4.0-beta): the density widening — widened fetch, 5 caches re-emitted, towns index
Ledger #2 (E's half), built to C's LANE_C_PUB §6 table under John's SUBTLE directive. - Widened fetch: C's tasteful staple list (shop=* + amenity=cafe per C's dagger note), mapped through C's copy-paste table onto EXISTING registry types (no new archetypes). Guardrails honoured: no vehicle/fuel/funeral/storage/industrial, no pure services. New raw snapshot per town (the fetcher auto-refetches when the class list changes -- query recorded in each snapshot), committed like the first. - SUBTLE by construction: secondhand HEROES never subsampled; texture capped at 3x heroes (top of C's ~2-3x band), over-cap towns seed-subsampled deterministically (sha256(townKey:osmId)) with every drop counted in counts.textureDropped. Result 3.0x in all five: katoomba 20+60 (-4), newtown 18+54 (-156), fremantle 20+60 (-81), bendigo 9+27 (-81), castlemaine 6+18 (-43). Density 6-21 -> 24-80 shops (3-4x). - web/assets/towns/index.json (new, E-owned): {schema, generated, license, attribution, towns[{key, town, state, shops, roads}]} -- B's selector can drop the REAL_TOWNS hardcode (hud.js:11). - Deterministic (byte-identical re-run, 0 re-fetch). ODbL: SOURCES.md + per-cache license/attribution. -> Lane A (absorb pass): (1) 10 expected golden re-pins -- the widening moves every real town's base+gig golden (designed E->A handoff); synthetic 0x3fa36874 UNMOVED, fixtures frozen. (2) SEAM: index.json trips selfcheck's town glob (selfcheck.js:467 takes every top-level towns/*.json as a cache) -- one-line fix in your file: .filter(f => f.endsWith('.json') && f !== 'index.json'). Didn't touch selfcheck.js (yours, you're mid-round in it); Fable spec'd the index at this path so the path stays. -> Lane C: kept video_games -> video (absent from your §6 table; was already shipping as video pre-widening, so the fallback would have regressed it to opshop). Same family, same target -- flagging for your table. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
10db373e67 |
Lane E R18 (v4.0-alpha): the other 4 towns' road geometry (data-only) + Overpass retry
Newtown/Fremantle/Bendigo/Castlemaine now schema v2 with roads[] (1086/622/1552/397 real streets), same fidelity cut (street tier only). Data-only: only katoomba gates the round; A hardens against these. build_towns.py: added Overpass retry/backoff (public API 504s under load — hit one mid-run). The poster-clearance finding is SYSTEMATIC: it reproduces on all 5 real-road towns, every seed (23 checks, -0.9 to -4.7m), confirming it's plan-level poster placement (A's pickVenues/POSTER_CLEAR), not town data. Scoping holds: only the real/* v2 path fails; synthetic + fixtures + classic + default boots stay green. A's one fix generalizes to all five. ODbL: raw roads committed, SOURCES.md current. -> Lane A: all 5 towns' roads live; the systematic poster finding is yours to resolve + re-pin goldens. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
dbb52c2390 |
Lane E R18 (v4.0-alpha): katoomba_real real road geometry (schema v2, ledger #3)
Extend build_towns.py: bounded way[highway](bbox) out geom per town -> raw cached in-repo -> roads[]
in A's v2 contract ({id,kind,pts:[[lat,lon]]}, kind=raw OSM highway class). katoomba_real is now
schema v2 with 484 real streets (Bathurst Rd, Cliff Drive, ...). Fidelity cut (charter risk #4, flagged
to A): fetch every ROAD_KIND tier -> raw; EMIT the town street tier only, excluding service/track/
footway/path/steps/cycleway (1461 of 2506 Katoomba ways = bushwalking tracks/sidewalks/stairs/driveways).
A's lift builds a real town from it (verified): 484 streets -> 872 nodes/799 edges (main 232 side 531
arcade 36) -> 12 blocks, 20 lots, 3 venues (pub/band_room/rsl), 12 gigs. pickVenues lands venues on the
real graph (ledger #2 met).
FINDING for A (alpha failure-list, charter risk #3): on the real graph, spine posters overhang crossing
carriageways -- selfcheck kerb-clearance fails on 4 seeds (-1.6 to -2.5m; e.g. seed 20261990 poster 50 vs
edge 58 = -2.42m). Same class as A's R15/R16 corner-poster fix, now on real cross-street geometry. Owner:
A (pickVenues/POSTER_CLEAR on the real graph, the 'A again' harden step) -- my roads data is VALID (cache
validates; failures are plan-level poster placement). Golden settles after A's fix (pre-fix 0x6014a8e6).
ODbL: raw roads committed, SOURCES.md updated.
-> Lane A: katoomba roads live; harden the lift + resolve the poster finding + re-pin the golden.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
483a4b75c6 |
Lane E R17 (v3.2): the real-map scout — 5 AU town caches + publish --verify fix
Ledger #4 (warm-up): publish.py --verify no longer false-flags non-procity_ published assets (sit.glb, vintage-cash-register). It compares the _published.json name record against the depot's full file list (fetch_depot_files) instead of a procity_ prefix filter; only OUR namespace flags as unrecorded. --verify now: all 39 recorded assets live. Ledger #6 (the scout): new pipeline/build_towns.py ports thriftgod build_city()'s Overpass route to per-town caches in A's procity-town-cache/1 contract. 5 real compact AU towns under web/assets/towns/ (katoomba/newtown/fremantle/bendigo/castlemaine, 6-21 shops, spans <2.4km): bounded Overpass query -> raw cached in-repo (re-runs never re-fetch) -> dedupe/suburb-fill/parody (trademarked chains only; indie shops keep real OSM names)/type-map. Deterministic (byte-identical re-run, no RNG). ODbL: SOURCES.md licence table + license/attribution on every cache. All 5 boot through the full structural+gig suites (selfcheck 16596/16596 green; synthetic golden 0x3fa36874 unmoved). Overpass fetch John-authorized (Standing #2). -> Lane A: caches live under web/assets/towns/; pin the per-town goldens selfcheck printed (katoomba 0x61760542 newtown 0x95978b45 fremantle 0xee9fd09a bendigo 0x5e3e76a6 castlemaine 0xf1a628a1) + feed through plan_osm. E->A handshake. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
b322c998db |
Lane E R16 (v3.1): the drummer's sit clip — sit.glb produced + published
Ledger #2 asset half (E produces, D wires). Fetched Adobe Mixamo Sitting_Idle.fbx (533KB) by scp from the tailnet source box, converted on-device via Blender (new pipeline/fbx_to_clip.py: import -> skinned GLB export -> pure-python mesh-strip) to web/models/peds/sit.glb (109KB, mesh-free, structurally identical to walk/idle: 66 nodes, 65 mixamorig bones, dangling skin, 195 channels). Verified: three.js loads + 195/195 tracks bind to peds + 0 NaN; Blender confirms seated (hips 0.955->0.299m, stature 1.276->0.758m) + eyes-on bone-dot render (docs/shots/laneE/sit_clip.png). Published to depot via tailnet under John's R13 auth (_published.json 38->39; benign non-procity_ drift note). Provenance: Adobe Mixamo royalty-free, same zone as the shipped walk/idle; LANE_E_NOTES v3.1 amendment marker. -> Lane D: sit.glb ready at web/models/peds/sit.glb (+ on depot); canon binds 195/195; seated confirmed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
55f6698fb2 |
Lane E R14 (v3.0 release): provenance freeze + doc-consistency fixes
Provenance close-out for the v3.0 tag. Verified via a 6-agent inventory+audit workflow (both adversarial audits PASS, 0 blockers) cross-checked against glb_stat/ffprobe/manifest. - LANE_E_NOTES: v3.0-FROZEN provenance table + full audio(28)/GLB(38)/skins(96)/packs(3) inventories; by-design notes + v3.1 deferrals (street_bin decimation). - AUDIT.md: add R13 gig-layer finalization section (14k decimation, _hi published, gigKey rename + 2 beds, depot publish done) — ledger was stale at R12. - manifest glb_law string: state the documented <=8k-hero / <=14k-instrument tiers so the frozen contract is self-consistent (regenerated; 1-line diff, Gate 3 still 0/0). - gen_audio: roomtone-video gain 0.3 -> 0.35 to match the shipped manifest. Gate 3 GREEN; publish.py --verify clean; 0 quarantine assets in manifest; goldens unmoved (synthetic 0x3fa36874, gig 0x1f636349). No new synthesis (genres final); no poster templates (no ask from B). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
5dac2cac5a |
Lane E R13: publish decimated instruments + _hi originals to depot
John OK'd direct publish. Pushed the 5 base instruments (14k) + 5 _hi hi-poly originals via the passwordless tailnet ingress (this box is allowlisted). Public digalot.fyi now serves the 14k bytes (amp 5.9MB->1.3MB) + the _hi originals; -70% decimation win is live in production. _published.json 33->38; validate_manifest --depot GREEN. Gate-3 flag cleared. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
bf98b41b16 |
Lane E R13 (v3.0-beta): gigKey rename + grunge/covers beds + instrument decimation
- debt #1: the manifest music key IS the gigKey, always gig-<genreKey>. Renamed pubrock-live -> gig-pubrock (files + gen_audio + build_manifest); old files deleted. B/F switch readers, F deletes the GIG_BED bridge (both fail soft to silence til then). - two new gig beds: gig-grunge (band_room, quiet-loud dynamic) + gig-covers (RSL, mellow organ-led); procedural/seeded/loopable/$0. New organ() + grungechord() synth helpers. - decimate the 5 instrument GLBs to 14k tris each (was 43-96k; fleet 236k->70k, -70%) via collapse (thin features survive); _hi hi-poly originals kept for depot; thumbs re-rendered. - manifest regen (validates 0/0 incl --depot); app boots clean flags-off / ?gigs=1 (3-venue district, all 3 beds resolve) / ?noassets=1&gigs=1 (0 audio+GLB fetches). - depot re-publish (14k bytes + _hi originals) gated on John's OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
23c0667dca |
Lane E round 9 (E1+E2): VRAM/texture audit + half-res book/toy atlases
E1 memory audit: measured all texture sources (decoded RGBA+mips). Resident VRAM ~240MB default boot / ~420MB worst case (all flags + all shop types); stock packs the swing. Cheap win: half-res'd book+toy atlases (quick pull-cards, not the deep record dig — covers verified legible) → stock VRAM 323->181MB, no index/UV change, re-published to depot. Verdict: fine to ship v2.0; flagged stockpack cache-cap (C) + KTX2/Basis (4-8x) for v3. E2 hygiene: validate --depot 0 err, pack-QA 3/3, provenance-drift clean (27 live), 0 orphan atlases. Numbers + verdict in AUDIT.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a667283cf3 |
Lane E round 8: REAL stock packs (record 350 / book 311 / toy 273) live on depot
John unblocked GODVERSE DB access (m1ultra native-Postgres clones, read-only SELECT, peer auth). All 3 packs rebuilt from real data: - record 350: discogs_full.inventory (real store stock) join release/release_image, real Discogs cover art. - book 311 + toy 273: dealgod.products by category_path, real product photos + prices. Metadata parody-transformed (deterministic, no source-token leak -> no real trademarks in pack text); cover images are real release/product art (read-only, non-economy, decision #2); book prices seeded (source is info-only, John's call). 15 atlases published to the depot; indexes committed (the C contract) + staged for ?localdepot; all pass the pack-QA gate. build_stock_pack.py gained --from-tsv (extract-on-DB-box -> build-here), portrait 176x256 book cell, seeded-price fallback. qa --strict GREEN 5/5. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
081755bb71 |
Lane E round 8 (E1+E2): book/toy stock packs + pack-QA gate
E1: build_stock_pack.py generalized over kinds — record (256x256 sleeves), book (96x256 tall-thin spines), toy (256x256 boxes), per-kind parody word banks, same build-time/parody/atlas/index laws. Book+toy sample packs built + staged (?localdepot) + indexes committed to pipeline/packs/ so Lane C wires book/toy shelves now. Parody deterministic + no distinctive-token leak across all 3 kinds. E2: validate_pack.py QA gate (wired into validate_manifest -> qa gate 3) — bad UV / empty title / bad price_band / dangling atlas / dup id fails qa (proven). qa strict GREEN 5/5. Real 150-250-item packs blocked on GODVERSE_DSN (flagged to Fable); samples are placeholders in the real index format. No fal spend. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
0c12dacb6d |
Lane E round 7 (E2): GODVERSE stock-pack pipeline (parody + atlas + index), proven
pipeline/build_stock_pack.py builds C's ?stock=real pack offline (nothing queries the
dataset at runtime): recordgod (dealgod discogs_release) → curate → parody-transform
title/artist (deterministic, shares no source token — no real trademarks) → atlas WebPs
+ JSON index {id,title,artist,price,price_band,atlas,uv}. Proven end-to-end with
--sample 24 (synthetic sleeves); sample pack staged to web/assets/models/ so Lane C
wires ?stock=real against the real index format now. Real 200-400 pack blocked on
GODVERSE_DSN (dealgod Postgres creds — flagged to Fable) + C's schema confirmation;
one command (--from-db --count 300) once they land.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
447188a516 |
Lane E round 7 (E1): merge ped rigs to ONE draw each (gates roster flip)
Each of the 19 ped rigs carried 1-9 primitives / 1-3 materials (fleet 92 draws, ~116 at the 24-rig near cap). merge_ped.py (Blender) merges each to 1 primitive + 1 atlased material: join meshes -> pack material UVs into a non-overlapping atlas UV -> EMIT-bake base-colours into one 1024 atlas -> single material. Skinning + skeleton preserved (65 joints, walk/idle untouched, clips retarget unchanged). Fleet 92->19 draws (1/ped); near-cap 116->24 (79% cut). Verified in vendored GLTFLoader: all 19 load as SkinnedMesh + bind walk; man_suit poses byte-identical to original. Hands to Lane D (D1) for full validation + full-density numbers, then F flips the roster. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
2511610373 |
Lane E round 6 (E1): publish.py merges (not clobbers) + provenance-drift QA gate
- publish.py: _published.json now MERGE (read existing → union → sorted write), never replace — fixes the R5 --only clobber (27→1). Proven: a real no-op re-publish kept it at 27. Added --verify + post-publish drift-check vs the live depot (/api/list procity_*). - validate_manifest.py: new provenance-drift gate — every manifest procity_* GLB must be in _published.json or QA fails. Proven: simulated clobber (→1) exits 1 w/ per-file errors. - Record verified: 27-entry _published.json is byte-exact vs the live depot. - qa.sh --strict GREEN (5 gates incl. F1 harness). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
019304d647 |
Lane E round 5 (E2): depot growth — street bin + record-crate stack (consumer-driven)
v2 features are procedural (no forced GLB needs), so E2 is light per Fable's "no unconsumed entries": two synthetic depot props with clear homes — council-bin -> procity_street_bin_01 (Lane B street dressing) + milk-crate-stack -> procity_fit_crate_stack_01 (Lane C floor piles / dig). Both 3k tris, base-origin, re-normalized to procity names + thumbs, published, verified loading, validate --depot 0 err. Manifest 18 fittings + 10 furniture (28 GLBs). Also noted B3 resolved (novelty_record 26.5k->8k via E1 bake). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
8644d3f7ac |
Lane E round 5 (E3): fal Hunyuan glass_case + bus_shelter + magazine_rack (~$0.64)
The 2 R3 TRELLIS glass rejects + optional magazine-rack, generated on fal.ai Hunyuan3D v2 (John-authorized, $22 balance). pipeline/gen_props_fal.py drives the fal operator using the FAL_KEY from MODELBEAST settings (never hardcoded). Frosted/ opaque flux_local concepts gave the reconstructor a surface (clear glass defeated TRELLIS). glass-case 1 att, bus-shelter 2 att (opaque back wall), magazine-rack 1 att = ~$0.64 total, guardrail held. All baked to <=8k via bake_lowpoly.py (switched to EMIT albedo bake — Hunyuan materials bake near-black under DIFFUSE). Verified loading in vendored GLTFLoader, published, validate --depot 0 err. Manifest 17 fittings + 9 furniture; aliases wire glass_case/glass_cabinets/magazine_rack/fridge/listening_corner. Costs logged in AUDIT R5. Last 2 primitive-only fittings retired. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
c52246444d |
Lane E round 5 (E1): bake 6 hero props to <=8k tris (288k->48k), live on depot
pipeline/bake_lowpoly.py — Blender headless: voxel-remesh -> decimate -> Cycles base-colour bake onto fresh UVs (R3 lesson: simplify-only floors on TRELLIS shell-soup; the re-bake is the point). drinks_fridge/milkshake_mixer/arcade_cabinet/ listening_booth/novelty_record/counter_till all 25-77k -> <=8k, ~0.9M each. Every prop eyeballed (docs/shots/laneE/props_baked.png) + verified loading in vendored GLTFLoader; footprints unchanged (no C re-map needed). Re-published; validate --depot 0 err. Originals gitignored in pipeline/.props_orig/. Unblocks C's interior re-measure + F's v1.1 tag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
dafb079ff4 |
Lane E round 4 (E2): fix record_crate + ship counter-with-till, both live on depot
- record_crate: R3 normalize left a sourceless texture (packed AO/roughness map didn't survive WebP export; metallicRoughness+occlusion pointed at it) → three.js 'undefined uri' crash. New pipeline/fix_glb_textures.py strips material slots that reference a sourceless texture. Verified loads in vendored GLTFLoader; re-published. - counter_till (new fitting): ~2m timber counter + period till, flux_local→trellis_mac on-device, 1.61x0.64m / 1.15m tall, 32k tris. Verified loads; published. Lane C maps kind counter -> counter_till (balcao 4m 'counter' kept for long-bar use). - publish.py: --only <name> filter + passwordless tailnet detection (GOD3_DEPOT override). - manifest rebuilt (15 fittings, alias counter->counter_till); validate --depot 0 errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |