7ba7ab20a8
166 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7ba7ab20a8 |
Lane F R26: the beta gate's exact tally — 6 passed / 1 failed / 0 warn
The full qa.sh --strict --matrix run confirms the hold and sizes it. Green: selfcheck ALL GREEN 156,212/156,212 · MATRIX GREEN 10 towns x 7 gates · flags harness (carrying F's beta gate: distinctness, sourcing, zero 404s, 0 console errors) · consistency · figure-scale. Red: the manifest validator alone — atlas-QA, 14 identical errors, all 14 mint crates, one sourcing-blind assertion, one line. The real crate passes. Recording the ratio because it IS the argument: the beta is finished. What stands between it and the tag is a rule meeting a case written before the case existed — C's to rule, E's to land, and not F's to quietly loosen on its own behalf. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
528829eeba |
Lane F R26 (v5.0-beta): the manifest consumed, the tolerance retired — tag HELD on the mint-id rule
EVERY CRATE IS DIFFERENT, and F measured it rather than taking G's 15/15 on trust — from the indexes of record, not by entering one lucky shop: 15 keyed crates, 105 pairs, 0 sharing a title; 0 crates overlap the generic v2 pack; 0 ids reused across crates (G's sku fix holds at scale — the R24 vacuity dead at the source, not papered over in F's gate). 4 crates in Red Hill + 11 in Newtown = the manifest's 15 exactly, and the manifest lists nothing not on disk. SOURCING, NOT TIER — C was right and the gate follows C. `tier` is the charter's ladder rung and a mint atlas is ALSO rung 1: still a file, still offline, still deterministic. What differs is where the stock came from. 15/15 indexes declare sourcing, every one agrees with the manifest, a mint crate can never report as real, and the gate PRINTS it per room — provenance a human never reads isn't doing anything (R24's licence lesson, one round on). THE 404 TOLERANCE IS DELETED, NOT TUNED. R24 probed every keyed shop and ate a 404 per atlas-less one; F's smoke could only cope by NAMING them, and a tolerance is a confession. F filed the real fix as a contract ask rather than inventing it; G built the manifest; F now consumes it — the shell asks for nothing unlisted. Zero 404s because nothing absent gets asked for, not because the gate stopped looking. AND DELETING IT IMMEDIATELY CAUGHT A LEFTOVER: F had wired the boot preload but left a second blind probe at the door, 404ing on every keyed-but-unfetchable shop. While the gate said "8 probes, expected", a ninth was invisible too. A named exception starts protecting new bugs the moment the real fix exists. F's beta gate GREEN: distinctness · sourcing (real + mint rooms) · soft fall silent · ZERO 404s · 0 console errors, no attribution exceptions. Selfcheck ALL GREEN 156,212/156,212. TAG HELD — atlas-QA FAIL, 14 errors, and it is not the product. E's SLOT_ID_PREFIX = "sku_" (validate_atlas.py:73) applies to every pack; E reads `sourcing` at :178 but the slot-id check is sourcing-blind. All 14 mint crates fail; the real crate passes. A mint crate HAS no POS sku — it was never in that shop's till — so the rule demands what cannot exist, the same shape as R24's sweep demanding a cafe carry a godverseShopId. F measured the rule's intent and it holds: mint_<dealgod listing id>, non-positional, sorted by it, seeded bake, 0 ids reused across all 15 crates. Only the literal prefix fails. And G refused to go green the easy way for the best reason — F's own R24 collision grown up: a POS sku and a dealgod listing id are different id spaces, and filing one under `sku_` recreates that bug INSIDE the economy, where tier-2's sold-means-gone looks up POS skus. R24's collision entered the wrong shop; the same collision in the money layer sells the wrong record. F did not fix E's one line: E's file, C's contract, C's call as its author (the principle Fable ratified when C overruled `tier`) — and F is the party that benefits, since that line is the only thing between F and the tag. Cost of waiting: one line. Cost of F being quietly wrong: a gate that green-lights id-space collisions in the layer that moves money. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a9a5ef05d8 |
Fable (integrator): R26 waves 1-2 complete — F's beta gate asserts C's 'sourcing' (the brief's 'tier' superseded, correctly)
Co-Authored-By: Claude Fable 5 <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 (
|
||
|
|
2f4ab5912f |
Lane B R26 (v5.0-beta): the stocked shopfront reads from the footpath
Ledger #5 — B's polish pick. A stocked godverse shop now tells you it's diggable before you reach the door: a crate of seeded spines under the shop name, and a warm-lamp-over-crates room behind the glass. Cost: +0 draws / +0 tris. The mark is painted into the chunk's EXISTING sign-atlas cell; the window cue rides the EXISTING per-shop aTint attribute. Nothing new is allocated or submitted. The manifest is the authority, deliberately NOT the godverseShopId key: keyed means "has a stock identity", the manifest means "a crate is actually here". Marking keyed-but-unstocked shops would advertise a crate the shop hasn't got — the street would lie. The mark does not leak tier: "you can dig here" is equally true of real and mint; provenance belongs on C's price card and in E's gates. (Second job for ledger #6's manifest, free.) Measured — true A/B at one pose, manifest 200 vs 404: spine-marked sign cells 0 → 3 (18,768 exact-palette px) stocked window tint verts 0 → 36 street_noon 65 draws / 115,502 tris → UNCHANGED Stocked shopfront (Goulds Books, footpath): 85 draws / 144,730 tris — inside street law (<=300 / <=200k). Cues agree with ground truth: 3 stocked shops live → 3 marked cells, 9 stocked window quads. Covenants re-proved (the prefetch is new code on the boot path), tested with the manifest present on disk so a stray fetch would 200 and be unmissable: ?classic=1 0 keyed, 0 stock fetches, 0 errors (zero-fetch covenant) default synthetic 0 keyed, 0 stock fetches, 0 errors manifest 404 18 keyed, fail-soft, 0 page errors Three traps, self-caught: (1) a module-load fetch would have put a fetch delta on ?classic=1 — restructured to a lazy reader + plan-driven prefetch, keyed plans only; (2) the lazy trigger alone raced the first chunk build, so the first stocked shop you approach built unmarked — prefetch moved to createChunkManager, before any chunk builds; (3) the first "zero cost" was VACUOUS (manifest never fetched, so nothing was applied) and the first pixel detector reported 60 marked cells with no treatment at all — replaced with an exact-palette signature that reads 0 in control. Vacuous-gate law applies to a lane's own verification too. Corollary: force-cache serves a deleted file (transferSize 0, status 200 while disk 404s) — poison the cache or you are testing your own memory. B consumes stock_godverse/index.json read-only and emits nothing into it; the temp manifest used to prove this round was deleted — the directory is G's. Shape-tolerant + fail-soft, so G's real emission needs no coordination with B. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
4f0adf12d8 |
Lane C R26 (v5.0-beta): three contract lines + the dig price sticker (ledgers #1, #4, #6)
Wave 1 — contract lines published first; G and E build to them. #1 THE BRIEF SAID `tier`. IT CAN'T BE (§7.2b). G's atlases already emit tier: 1 = the CHARTER'S LADDER RUNG (0 parody / 1 static-real / 2 live), and `kind` is already the stock type. A mint atlas is ALSO rung 1 — same mechanism (a statically baked per-shop atlas); only the data's origin differs. Real-vs-mint is an orthogonal axis, not a rung — overloading `tier` puts two meanings in one name, the same species as the plan-id/godverse-id collision just standing-noted, and as R25's positional ids. RULING: top-level `sourcing: "real"|"mint"`, REQUIRED; `tier` stays the numeric rung. A mint index MUST NOT carry POS-snapshot fields (the separation is the honesty). Gates read `sourcing`; absent => FAIL. #4 `condition` ISN'T IN THE INDEX (§7.2c) — the ledger assumed it was. The index carries artist/title/price/price_band; G's SNAPSHOT has condition + sleeve_cond and drops them at emit, so pickRealOffers mapped cond:'' and the card rendered dangling separators around a hole. That WAS the "database row". Ruled optional index fields, emitted when the source has them; no invented grades on mint items (a plausible-but-fictional grade is what `sourcing` exists to prevent). #6 THE ATLAS MANIFEST (§7.2d): stock_godverse/index.json is the authority for which shops carry atlases — no entry => no fetch => zero 404s, so the zero-console-errors law holds with no attribution exception. Shape + both-ways consistency specified. No manifest + no atlases = a legitimate silent zero-shop state, not an error. THE PRICE STICKER (code): the pull panel is now the shop's price sticker — manila card, rotation + shadow, typewriter caps, italic title, a stamped condition grade, and the round yellow $ sticker the sleeve art already uses (the panel echoes dig.js's own canvas language instead of fighting it). Fields compose only when present: a missing field never leaves a stray separator. VERIFIED (fresh context, 5 card shapes, both star branches): real grail VG+/VG + ★GRAIL; real standard VG+ + STANDARD; real ungraded COLLECTOR (grade omitted cleanly); parody NM + 1973 PUNK; parody rare (seed 4) VG + 1973 POP + ★RARE. No dangling separators anywhere. The verification caught a defect in MY OWN card: a real grail read "GRAIL ★ GRAIL" — `s` carried the price_band AND `rare` derived from that same band (parody is immune: its `s` is a genre). Fixed at the mapping. And I didn't leave the parody-rare branch on assumption — scanned seeds until a rare pull appeared and asserted it says RARE, not GRAIL. An unexercised branch is an unproven one. Budgets: the card is DOM — zero draws, zero tris, no 3D change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
e7d58eaad5 |
Fable (integrator): R26 wave 0 COMPLETE — E landed its own commit, F is GO to tag v5.0-alpha
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
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
|
||
|
|
4a80ea8505 |
Fable (integrator): R26 amended — wave-0 status (F green, tag pending E) + the atlas manifest (F's finding #4, structural)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
29942002eb |
Lane F R24 (v5.0-alpha): THE CRATE WALKS — the per-shop wire + a gate that can't lie
You can boot redhill_godverse, walk down Musgrave Road into Monster Robot Party, riffle its own real crate and buy a real record. Proven falsifiably, not by eyeball: base assets/stock_godverse/3962749/ (its own, not the town-wide) TITLES 120/120 the shop's atlas · 0/120 the generic pack TEXTURES 2 from stock_godverse/3962749/*.webp · 0 generic — the pixels' own file BUY rec_0000 "Abstract Latin Lounge II (Part II)" @ $15 → cash 191→176, exact REBOOT 191/0 restored — gone-this-session, back next boot Ladder: ?noassets → ZERO network requests · keyed-but-atlas-less shop → 404 → parody, live · newtown_real → base null, 350 items: the wire is a NO-OP off the godverse path. flags_check GREEN (0 fails, 0 warns). #6a THE WIRE: godverseBaseFor(shop), exported and used by BOTH the shell's boot preload and the room's lookup — C's cache identity is the LITERAL (type, base) pair, so two sides building that string differently would drop a real shop to parody, a bug indistinguishable from "no stock" by eye. One function, one string, one key. Gated on stockReal, never the id alone. #6b THE GATE: smoke_real_crate + DBG.stockInfo() — permanent, and it cannot pass without touching its subject (SKIPs with a printed reason when the town/atlas is absent). FINDING — THE BRIEF'S OWN HONEST-GATE SPEC WAS VACUOUS. It specified id equality. Both packs number items POSITIONALLY (rec_0000…), so all 120 atlas ids are generic-pack ids too: an id-equality gate goes GREEN on the generic pack — the exact failure the vacuous-gate law was written to stop, reproduced inside its first application. Ids there are slot numbers, not identity. Titles (0 overlap) and the texture URL discriminate; F asserts on those. FINDING — THE ID SPACES COLLIDE, and it bit F's own selector inside the anti-vacuous gate. Plan ids (1..N) and godverse ids (31, 767, 3962749) share a numeric space: Silky Oak's godverse id is 31 and another shop's PLAN id is 31, so enterShop(31) silently entered "Wholefood Cafe" and the soft-fall assertion PASSED ON AN UNKEYED CAFE. Fixed both ends: 'g:<n>' selects a godverse id explicitly, a bare number stays the plan id and now REPORTS the collision, and the smoke asserts it landed in the shop it asked for before asserting anything about it. FINDING — F'S OWN GATE CRIED THE LOUDEST WOLF WE OWN. classic_regression reported "plan fingerprint != golden 0x3fa36874 — determinism/prime-law broken" while the covenant was provably intact. F wrote it in R16 as `hash_ok and returncode == 0` — two assertions, ONE verdict, reported with the fingerprint's message — so any unrelated selfcheck red screamed that the byte-identical-forever covenant had broken. Two assertions, two verdicts now. It isn't enough to fail for a reason; you have to fail for YOUR reason. FINDING — fail-soft-by-404 vs the 0-console-errors law. The boot preload must resolve a keyed shop's pack before the door opens (getStockPack is sync), so it probes blind: 9 of Red Hill's 10 keyed shops have no atlas → 404 → parody. That IS fail-soft working, and it is also 8 console errors no .catch() can suppress. Fix is not to loosen the law but to stop probing for what isn't there: an atlas index in G's namespace (or hasStock on the cache entry, A+G). Filed as a contract ask, not invented. Until then the smoke counts and NAMES the probes and fails on any other error — tolerance stated out loud. Verified the lift is clean: cache 10 keyed → plan 9 keyed, every one a real secondhand shop. No cafe keyed, zero duplicate ids — there is no mis-stocking. F did NOT touch A's identity sweep or E's validator. F was the party that would benefit, and changing a red gate to green in another lane's file to unblock F's own tag would retroactively devalue every green F has ever reported. Filed instead — and R25 has since landed A's reconciliation and the six pins, which is the right hands doing it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
533fa32b59 |
Fable (integrator): round-26 instructions — wave 0 closes the alpha, then v5.0-beta EVERY CRATE DIFFERENT
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
a493c0a13c |
Lane A round 25 (v5.0-alpha): the sweep reconciled with Ruling 2 + the six pins (ledger #1)
All 8 tree reds cleared. selfcheck ALL GREEN 156,211/156,211; scaffold + consistency green; classic
0x3fa36874 and gig 0xb1d48ea1 frozen. F: the tag is unblocked from my side, nothing of mine is pending.
SIX OF THE EIGHT REDS WERE MY OWN GATE ASSERTING RULING 2 AWAY. I built the R24 identity arm on an
assumption that was true when I wrote it and false the moment G shipped: that a godverse cache is ALL
census shops. Ruling 2 makes it MIXED -- a keyed GODVERSE layer plus an inherited OSM texture layer that
G measured to be load-bearing, not cosmetic (census-only Red Hill: 306 m spacing warn + a poster inside a
kerb). So newtown_godverse (18 keyed + 54 texture) and redhill_godverse (10 + 27) were HEALTHY TOWNS MY
GATE CALLED BROKEN -- it fired 54/72 on a good town. Keyed asserts now run PER-LAYER over the keyed subset
only; unkeyed texture shops raise nothing. The validator's "N/M missing" warn dies with it. The one honest
requirement left at that layer: a `godverse+osm` cache must have a NON-EMPTY godverse layer (else it's an
osm cache wearing the wrong `source`) -- still a warn, for the R24 charter reasons that still hold.
THE UNIQUENESS CHECK WAS BROKEN IN BOTH DIRECTIONS. `new Set(all ids).size === shops.length` collapses
every `undefined` into ONE Set entry, so it (a) failed structurally on any mixed cache -- 54 texture shops
became one entry -- and (b) could HIDE A REAL DUPLICATE behind that same collapse. Now over DEFINED ids
only. And per the vacuous-gate law I made it prove it bites rather than asserting that it does:
validateTownCache rejects duplicates at the front door, so a dup can never reach the plan that way -- the
test feeds one STRAIGHT TO THE LIFT (generatePlanOSM does not validate) and asserts the predicate catches
it, with a healthy mixed cache passing the same predicate. A check nobody can watch fail is not a check.
NEW -- THE ORPHANED-ATLAS GATE (my own R24 finding, now enforced instead of filed). The lift legitimately
drops shops (overlap-resolve, counted since R19). Dropping a shop that HAS a committed atlas means real
stock keyed to a shop that isn't in the town -- exactly the failure I filed in R24, and one F's #7b could
only catch in a browser at the end of a round. Now a node gate: for each godverse town, every
stock_godverse/<id>/ on disk belonging to that cache MUST be seated, else FAIL. Subject-aware -- it SKIPs
by name when a town has no atlas, rather than passing quietly.
It already found one, benign today: redhill's lift drops keyed shop 2286 "Empire Revival" (10 keyed in
cache -> 9 seated). No atlas, so nothing is orphaned and the gate passes -- but it prints, because a drop
must never be silent (the R19/R20 ruling). G: stocking Empire Revival at the beta would orphan it. Monster
Robot Party is seated (lot 8), which is the one that matters this round.
THE SIX PINS, cross-checked two ways before landing -- byte-identical across two fresh processes, AND
matching the three values G stated independently in
|
||
|
|
0d8d59a22a |
Lane C R25: sku-derived slot ids — F's id-collision finding made structural (ledger #3)
One contract line, published first so G re-emits against it. §7.2a added. THE COLLISION, MEASURED: both packs number items positionally from zero, so all 120 godverse ids are also generic-pack ids — 120/120 overlap. An id-equality gate cannot discriminate which pack a rendered item came from; that is exactly why the brief's own #7a spec was vacuous. (The vacuous-gate law's first application broke the law — and my own R23 metric had the same disease.) THE RULE (§7.2a): items[].id MUST derive from the source's stable key, never from position, and MUST be unique across ALL packs. Real-stock packs: id = "sku_" + <POS sku> (G's snapshot already carries `sku` per item, e.g. 20260314070442 — it's just dropped at emit, so this is index-only). Generic packs keep rec_NNNN as their namespace; real-stock must not emit into it. TWO REASONS, and the second outlives the gate: 1. positional ids collide by construction (the 120/120 above) -> id-equality gates can't discriminate. Sku ids fix that permanently, now, at two atlases instead of fifty. 2. POSITION IS NOT IDENTITY: a positional id renumbers on every re-bake — sell one record out of crate 550 and rec_0050 silently becomes a different record. Anything holding an id across snapshots (a wallet purchase, a saved dig, a gate assertion, and above all tier-2's sold-means-gone) would point at the wrong item. The POS sku is stable because it is the shop's own identity for that copy (release_id identifies the pressing, not the copy). So this is also the identity tier-2 will need, bought now for free. SCOPE: index-only — no atlas bytes, no town cache, no goldens, no C code (id isn't read by the loader, §7.3; the dig/buy consumers and gates read it). -> G: re-emit with sku_ ids. -> E: assert the form (present, unique within pack, sku_-prefixed). Committed by explicit pathspec — F's six staged files sit untouched, as its session left them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
2c1ae37160 |
Fable (integrator): round-25 instructions — the tag, earned (sweep vs Ruling 2, licence line, sku ids, F closes)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
1eb0b45bd0 |
Lane A round 24 (v5.0-alpha): the identity field — godverseShopId, published first (ledger #2)
The optional shop key that resolves `stock_godverse/<godverseShopId>/`. Schema STAYS v2 (optional field ⇒ every shipped cache still valid, the 21 osm caches untouched by construction). Published to web/assets/towns/README.md — the doc G and E build to — plus CITY_SPEC. selfcheck ALL GREEN (+15 checks), synthetic 0x3fa36874 frozen, NO golden moved. THE BRIEF'S "THE POS SHOP ID IS THE ID — NO MAPPING TABLE" IS FALSE FOR THE ONE SHOP THIS ALPHA IS ABOUT. G's own docstring says it: Monster Robot Party is NOT in thriftgod's census, so its id is its DEALGOD STORE ID 3962749, while census shops use thriftgod ids (max 2992) -- two disjoint spaces, deliberately kept clear of each other. Had I coded "godverseShopId == shop.id" or derived it from the census, the headline shop could never be keyed. So it is an OPAQUE key: no derivation from `id`, no equality assert, no mapping table (the R12 gigKey law -- one key, zero mapping; G emits, everyone reads). THE FIELD HAD TO SURVIVE THE LIFT OR IT WAS DECORATION. plan_osm builds a FRESH shop object and copies nothing unknown, and the runtime reads plan.shops[], never the cache -- so a cache-only field could never reach F's per-shop base. It's now carried through, CONDITIONALLY: absent ⇒ the key isn't written ⇒ JSON.stringify byte-identical ⇒ every pinned golden holds until G re-emits (that re-emit IS the sanctioned move). Proven end-to-end: a keyed cache puts `stock_godverse/3962749/` on the plan with census ids (101..107) coexisting alongside it. ARMS SPLIT BY HAZARD, NOT TIDINESS: - malformed -> ERROR. It names a path segment; "3962749" vs 3962749 is the same folder but different JSON, and that coercion drift is the exact species that broke C's atlas contract (licence/license). - duplicate -> ERROR. Two shops keyed to one atlas IS mis-stocking -- charter risk #3 forbids it by name. - missing on a godverse cache -> WARN + fail-soft to tier 0. RECORDED DEPARTURE (Fable's to overrule): ledger #2 says validateTownCache "requires" the field; I made MISSING a warn. Three reasons. (1) The charter's determinism boundary is "world = seeded, frozen, gated; stock = data tiers" -- an error inverts it, failing to load a TOWN because its STOCK identity is absent; tier 0 must always boot. (2) Charter risk #3 names the remedy for identity gaps: "fail-soft to tier 0, never mis-stocked" -- missing IS the soft case, duplicate is the hard one; they are different failures and now get different arms. (3) Sequencing: newtown_godverse carries 0 ids today, it is G's to re-emit in wave 2 (their namespace, no census DB on m3), so a hard error would red the tree for C and E through all of wave 1 to say what the warn already says. The requirement keeps its teeth where R23 taught us to put them -- the VACUOUS-GATE LAW: selfcheck FAILS on partial keying (a half-keyed town silently mis-stocks the rest) and prints an explicit "⊘ SKIP ... 0/18 shops carry godverseShopId. Subject absent ... binds the moment one id lands" at zero. It names its subject, proves it touched it with a count, and cannot pass vacuously. FILED FOR G BEFORE THEY START (measured in wave 1, so it costs them minutes not a wave): redhill_godverse cannot contain Monster Robot from EITHER source. godverse_town.py takes roads from the OSM donor and shops from the census, and the shop is in neither -- not in the census (G's R23 finding), and NOT in E's redhill_real, which I checked the moment it landed: 36 shops, ZERO of type `record`, nothing matching /monster|robot/. As written the adapter yields a Red Hill of census charity shops while the atlas keys to a shop that isn't in the town -- F's #7b id-equality gate would fail at the end of the round. It must be injected explicitly; the opaque-key design exists precisely to serve that case. Second trap on the same path: redhill_godverse must still clear MIN_TOWN_SHOPS (6) from the census bbox or the cache is rejected outright (hard error). E's donor is otherwise good: valid, no warns, 73.3 m median spacing. HOUSEKEEPING: removed toowoomba's two stale pins -- E retired the cache in R23, and a golden for a town that cannot load can never fire (the vacuous-gate law, one layer down). E's attempt also proved my R23 spacing metric is GAMEABLE: the re-bbox fixed the median (395.7 -> 89.4 m, "passes") while hub density fell 3/12 -> 2/12, the pack's worst. It is necessary, not sufficient -- D's hub test is the complement, and E used both and refused to game it. Ballarat (255 m) is still flagged and still E's call; I pin what moves. PINS NOT TAKEN YET, DELIBERATELY: redhill_real is untracked/in-flight (E still editing build_towns.py), and redhill_godverse + the re-keyed newtown_godverse don't exist until wave 2. Pinning a moving file buys a false green or a spurious red. The round's law says A pins these BATCHED -- that batch lands when E commits and G's caches are in. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
ba901d4a75 |
Lane C R24: the contract fix — the runtime is the authority (ledger #1, the root cause)
F held the tag because my published atlas contract and my own loader were mutually
incompatible. That was mine. Closed, and published FIRST so G and E re-emit against it.
WHAT WAS WRONG: my R22 §7 invented `stock_shop_<godverseShopId>_index.json`; the loader
(stockpack.js:25) fetches `${base}stock_${type}_index.json`. An index named per the contract
can never be fetched by the code meant to load it. G built runtime-compatible (correct), E
built contract-compatible (also correct — the contract said so), and E's validator globbed
stock_shop_*_index.json -> zero files -> vacuous pass. Nobody was wrong; the contract was.
§7 REWRITTEN AGAINST THE CODE (LANE_C_PUB):
- Authority rule: stockpack.js IS the contract; doc vs loader disagreement = doc bug.
- Layout ratified as G shipped it: assets/stock_godverse/<godverseShopId>/stock_<type>_index.json
(`type` is load-bearing — SLOT_FOR picks the slot). stock_shop_* RETIRED.
-> E: the glob becomes stock_godverse/**/stock_*_index.json (the vacuous gate's actual cause).
- Runtime-read vs ignored stated exactly: reads atlases[] + items[{atlas,uv}] (uv top-left, the
loader flips V); ignores version/atlas_px/cell*/count/kind/tier/shop/crate/provenance.
- Provenance drift dies: runtime reads none of it, so the authority is E's validator + the 23
shipped town caches -> TOP-LEVEL `license` (US), attribution, generator, snapshot. British
`licence` retired; G lifts+renames those four, keeps its rich nested provenance{} as colour.
atlas_px stays REQUIRED (checked against real dims). cell* informational — C reads uv, never
cell; do NOT shrink the cell for VRAM (the dig renders covers close-up).
CODE (F's filed item): stockpack cache identity is now `${base}|${type}`;
getStockPack(type, base = DEFAULT_STOCK_BASE); new opts.stockBase on buildInterior = the seam F
wires. Omitted => town-wide packs, byte-identical to today. Pre-v5 callers untouched.
VERIFIED FRESH — and I fixed my own metric first: R23's "8/8 atlas-backed" only checked that a
map exists, but a parody canvas has a map too (same species as the vacuous gate). Re-asserted
falsifiably: every sleeve's texture source IS stock_godverse/3962749/stock_record_atlas_00/01.webp,
pack items == index items by id; negative control — the parody room's textures are (canvas, no src)
and touch the atlas zero times, so the metric discriminates. Collision FIXED (shop 120 + town 350
coexist). Fail-soft FIXED with a populated cache (missing base -> null -> parody). 98 draws with
real covers, pathOK, 0 carves, 0 console errors.
SCOPED NOT SLID: the LRU+dispose (§7.6) lands at v5.0-beta — one stocked shop can't accrete, and
safe eviction needs a room-exit hook (a live room holds the pack's shared material) that arrives
with F's per-shop preload. Written into the contract so it can't slide silently.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
0740b4697d |
Fable (integrator): round-24 instructions — the alpha completion (contract fix, identity field, redhill, honest gates) + two new laws
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
57973e0540 |
Lane F R23 (v5.0-alpha): the alpha gate — HELD. The crate is real; it has no street.
v5.0-alpha is NOT tagged. #7a is not a gate that failed, it's a gate that cannot be run:
G's 120 real records are in the tree and byte-identically re-bakeable, and nothing in the
game can reach them. R18's law — release rounds don't ship known breaches.
GREEN (everything except the crate): qa.sh --strict --matrix 7 passed / 0 failed / 0 warn ·
MATRIX GREEN 10 towns x 7 gates · selfcheck 152,015/152,015 (was 161,300, E retired
toowoomba) · flags harness green, so ?classic=1 still holds through the merge · tier 0
?noassets zero fetches + zero console errors (the offline law holds) · tier 1 (v2
town-wide) resolves. Tier 1 (v5, per-shop) is NEVER FETCHED.
FINDING 1 — the atlas contract contradicts itself. LANE_C_PUB:271 publishes
stock_shop_<id>_index.json; C's own loader (stockpack.js:25) fetches
${base}stock_${type}_index.json. Incompatible. G built runtime-compatible (which is why
C's base-override check passed); E built contract-compatible (which is why E's validator
can't see it). Nobody was wrong — the contract was. F recommends amending to G's shape:
it's the only one the runtime can load, and it costs G nothing.
FINDING 2 — the gate built to catch that was blind and green. validate_atlas.py globs a
filename that can't exist at runtime, finds nothing, and returns 0 ("No atlases yet =>
clean pass"), which validate_manifest.py:158 propagates. It conflates "no atlases exist"
with "no atlases matched my glob" — the first is a clean pass, the second is the exact
failure it was written to catch. Pointed at G's index by hand, deeper drift surfaced:
E's line 68 reads provenance top-level while E's own docstring says nested (where G put
it), licence vs license, and a ceiling stale by one round.
FINDING 3 — #7a would have passed vacuously. Walked into The Vintage Record (real shop,
real road) via DBG.enterShop: the crates filled with real covers — from E's 350-item
town-wide v2 pack, not the crate. Zero requests to stock_godverse/, ever. Eyeballed as
written, the gate goes green and proves nothing. Two vacuous gates in one round, same
species: both test the presence of a thing rather than the identity of it.
R24 — three gaps, none F-only: A+G land a godverse_id (verified live: every godverse shop
reports null; the schema has no such field) -> E builds redhill_real (one Overpass fetch,
E's file, outward-facing — not F's to invent) -> C keys the pack cache by type+base
(today a hit returns before base is read, so two stocked shops collide and fail-soft
breaks) -> F passes the per-shop base and re-gates. F deliberately did not build its half:
untestable with no street and no identity field. Filed, not guessed.
Also: A's spacing warn earned on day one — ballarat now warns at 255 m, so the thin tail
has a second member. The README v5 teaser is held with the tag; they're one claim.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
d2eb9df03f |
Lane C R23 (v5.0-alpha): the first real crate verified in the room (ledger #3)
Verified G's stock_godverse/3962749/ (120 real records, Monster Robot Party crate 550, 2 x 2048^2, cell 256) in a fresh context — deliberately BEFORE the merge, so a contract failure would block it. It didn't. PASS — the contract holds; G re-emits nothing: - Resolves through the existing stockAdapter path via a base override (no C code change for the single-shop alpha). 120 items / 2 atlases / 8-of-8 stock meshes atlas-backed (real covers: peperecordings, DEEPCHILD, "39", mff FREAKS...). - Ceilings hold: 118 draws with real covers (<=350 law), pathOK, 0 carves. - Fail-soft holds (clean cache): missing atlas -> null -> parody (20 meshes, 110 draws); no adapter (?noassets shape) -> parody, zero fetch. 0 console errors. - G's index compliant: items[] sorted by id (my determinism ask honoured), provenance, uv in [0,1], 2 atlases = exactly the cap, cell_w/h harmless (C reads uv, never cell). CORRECTED MY OWN CEILING (LANE_C_PUB §7.2): I wrote "<=8 MB decoded" from an assumed ~16-item "typical shop". A real record shop is 120 records => 2 x 2048^2 ~= 32 MB, 4x my number. The structural rules held (<=2 atlases; 2048^2 for 60+ items — G landed on the cap); only the MB figure was wrong, because it described a shop that doesn't exist. New: <=2 atlases @<=2048^2, LRU = 1 shop's atlas set resident => <=32 MB peak (bounded; vs E's 181 MB unbounded today). Do NOT shrink the cell below 256 to save VRAM — the dig renders covers close up. G's ask #1 CONFIRMED and worse than reported (LANE_C_PUB §8 — C's spec, C's fix): stockpack keys _packs/_resolved by type alone, so base is ignored on a cache hit (measured: the 2nd preload returned the identical object). (1) two stocked shops collide; (2) it BREAKS FAIL-SOFT — an unstocked shop of a cached type inherits that crate instead of parody. Seam: key by type+base, per-shop preload on entry, LRU=1 + dispose; C consumes whatever identity field lands, C does not invent it. Two gaps block F's #7a, neither C's: the crate has no street (redhill_real absent; monsterrobot not in any shops[] — G's ask #2 to E/Fable), and interior_mode.js:192 pins base to assets/models/ (needs §8 + the identity field). Committed from a temp git worktree on main — the shared checkout stayed on lane-G-godverse (Fable's review) and G's branch keeps its disjoint namespace. Docs-only. 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>
|
||
|
|
47f05ecaa8 |
Lane D R23 (v5.0-alpha): the GIG_RANGE chunk-neighbour fix — scoped to the gig path (ledger #6)
My carried v4.x finding, fixed post-release as scheduled. Runtime-only: no plan, no
golden, no flag, no fetch. selfcheck ALL GREEN 161300/161300, 0x3fa36874 frozen.
THE FINDING GREW WHILE IT WAITED: filed at 8.7% (measured at katoomba's isolated pub);
A's R21 cluster bias made it WORSE — venues now sit inside the retail cluster where peds
converge from every side, so 42.6% of in-gig-range peds (5094/11971) were chunk-blind.
THE OVERRIDE (measurement wins): the brief asked for "extend to chunk + 8 neighbours"
AND "byte-identical flags-off". I built the literal version and measured that those
cannot both hold: on the synthetic town (what ?classic=1 boots, gig layer absent) a full
3x3 scan sourced 127 of 855 finds (14.9%) from neighbour chunks — finds v2 never made.
The frozen v2 crowd would shop ~15% more. Covenant breach, in a clause of the same brief.
So the fix is scoped to the GIG path — which is what I actually filed:
- ordinary shops: own chunk only (v2 semantics, frozen — noticed from its own block)
- gig venues: the full 34m radius, honest across chunk edges ("follow the sound" is the
whole reason GIG_RANGE 34 > PATRON_RANGE 18)
- no gig on -> _gigVenues empty -> neighbour loop skipped entirely -> ?classic and every
flags-off boot take the IDENTICAL code path and cost to v2. Byte-identical BY
CONSTRUCTION, not by measurement luck.
Both ranges < CHUNK(64) so 3x3 is exact, not approximate; fixed dz/dx order keeps ties
deterministic as the old single-list scan was.
BEFORE -> AFTER: cross-chunk in-range peds seeing the gig 0% (structural: v2 scanned only
the ped's own chunk) -> 100% (katoomba 4/4, fitzroy 11/11). Same-chunk unchanged 100%.
Classic neighbour-sourced finds: 0 (127 under the rejected full scan). Determinism
identical. 0 NaN on katoomba/fitzroy/synthetic. Sim 0.056 -> 0.057 ms/frame (+2%, i.e.
0.006% of a 16.7ms budget); lookup 0.58us unchanged with no gig, 1.3-2.7us with a gig on
(fires per PATRON_STRIDE, not per frame). Fitzroy clean at 376 peds.
CARRIED, documented: PATRON_RANGE keeps v2's own chunk-blindness — fixing it costs the
classic covenant, and the covenant wins. A frozen v2 quirk now, not an oversight.
Known minor: a scheduled-but-closed gig still runs the loop for nothing (0.58->1.3us).
D->F: no blocker for v5.0-alpha; classic untouched by construction.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
292b07aa91 |
Lane A round 23 (v5.0-alpha): the spacing warn — D's thin-tail finding as law (ledger #5)
validateTownCache now warns when medianShopSpacing(cache) > MAX_MEDIAN_SPACING_M (150 m). Metric + threshold exported from the barrel so no lane re-derives them. WARN, NEVER ERROR: a flagged cache still boots a valid district (toowoomba shipped green through the entire v4.0 pack) — E curates, A flags. selfcheck ALL GREEN 161,372/161,372 (+72); synthetic 0x3fa36874 frozen; NO golden moved (only E's toowoomba re-bbox may move one this round, per the round's law). THE THRESHOLD IS MEASURED, NOT PICKED. The brief offered darwin 27 m / toowoomba 388 m as "plenty of daylight for a line" — but that's 2 points. Measuring all 23 towns shows a near-continuum, and the line is FORCED into (119.3, 254.9]: braddon at 119.3 m is ALIVE by D's own hub test (7 shops within 160 m, identical to darwin's 7), ballarat at 254.9 m is not. 150 m sits in the pack's widest gap (x2.14), with 1.26x margin below and 1.70x above. Flags 2 of 23. TWO TOWNS FLAG, NOT ONE. The brief names only toowoomba (D spot-checked the two 12-shop towns). The measurement adds BALLARAT at 255 m — nobody has looked at it, and it's independently one of the three towns my R22 graded cluster fallback fired on (no venue candidate at the >=3-shops/160 m floor). Two signals agree. Filed for E as a curation call, counted either way. THE BRIEF'S ANCHORS WERE IN THE WRONG SPACE, AND IT MATTERS. D's 27 m is PLAN space (post-lift metres); validateTownCache is CACHE space (raw lat/lon — the only thing that exists at ingest, and the layer where a bad bbox must be caught). Darwin is 68.3 m in cache space, not 27. Interpolating a threshold between D's figures would have silently mixed spaces. I verified the hypothesis before trusting it: computing the metric plan-side reproduces D's numbers exactly (darwin 27.2 vs 27, toowoomba 386.8 vs 388, hubs 7 and 3). Cache space is correct HERE and provably safe: the lift marches shops at a regularised cadence, so it COMPRESSES dense towns (darwin plan/cache 0.40) but not sparse ones (toowoomba 0.98, ballarat 1.01) -- the error lives at the dense end, the warn only fires at the sparse end. Verified all 23 towns in both spaces: exactly ONE disagrees, newtown_godverse (94.4 cache passes / 158.3 plan would warn). Filed for G/Fable, NOT acted on: no cache-space line catches it without false-positiving braddon, and godverse is a census subset (18 thriftgod shops over the footprint that carries 72 OSM shops) so its sparsity is coverage, not a bad bbox — re-bboxing, the warn's only remedy, cannot fix it. Worth knowing since R23 stocks the real crate in that town and the beta asks "fitzroy_godverse if the census is dense there". Also fixed en route: the R17 silent-fallback trap bit again in my own scratch harness — an unregistered town key resolves to the melbourne fixture rather than erroring, so five towns silently measured identical. Registered the caches; noting it because it has now cost two rounds. Coverage: sparse cache warns + still boots (structural + district suites on a flagged town), compact cache does NOT warn (no false positive), metric edge cases (< 2 shops -> null, coincident -> 0, no throw on empty), and an exact-value check (a 100 m pair measures 100 m, projection sane). Cost: ~1 ms/town at registration (25.6 ms for all 23 incl. fitzroy's 160 shops) vs a <100 ms plan budget. E -> use the warn as your acceptance test for #4: re-bbox, re-run, warn goes silent = the town has a high street. If your fix moves toowoomba's or ballarat's cache, ping me — goldens are mine to re-pin, and only what you move. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
f14e4d1974 |
Fable (integrator): v5 THE REAL SHOP charter + round-23 instructions — v5.0-alpha THE FIRST REAL CRATE
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
8ac3b18b36 |
Lane F R22 (v4.0 — THE EPOCH CLOSE): the re-measure, the selector, the release tour, the tag
The blocking gate is CLOSED, and the epoch closes green. - #1b THE BLOCKING RE-MEASURE: F's R21 re-measure made the tri diet blocking; B diagnosed layer-by-layer, the driver traced A -> E (A's own commit: "B's numbers say the fix is E's"), E fixed it, F re-measured: katoomba venue_night 221,935 (+11%) -> 108,365 (-51%); bendigo 201k -> 124,682; fremantle -> 88,397. Worst 124,682 — the 200k stress edge is closed. The measure-first loop worked end to end. - #3 DBG.enterShop(selector) (Lane G's ask): id · registry type · exact name · name substring, resolved most-specific-first so an id-shaped string can't be shadowed. One-liner QA on any of 23 towns. - #4 The release tour -> docs/shots/release_v4/: the Fremantle hero · the Fitzroy mecca · the Toowoomba thin tail · the synthetic control · the ?classic=1 covenant. Every real-town frame poses through F's R21 cluster primitive; B's R22 bookmarks anchor on the same retail heart, so tour and bookmarks agree by construction. HUD hidden throughout (F's R21 ruling corollary). The primitive earned itself twice: the first cut posed via street_noon and the MECCA CAME OUT AS BARE BITUMEN — the same trap as R21. Re-posed through the cluster, Fitzroy reads. - HONEST FINDING (filed v4.x): the brief asked for the thin tail as "proof the floor holds". It does not, and the frame says so — Toowoomba reads as an empty road. The floor is a RATIO, not a count: 0.008 shops/edge vs the heroes' 0.06-0.08. Shipped labelled honestly rather than swapped for a flattering town. - #6 Docs: README v4 section (the towns ARE the product), LANE_F_NOTES §22, F-progress. qa.sh --strict --matrix GREEN 7/7; MATRIX GREEN — 10 towns × 7 gates (the budget gate green everywhere for the first time); selfcheck 161,300/161,300 (A's 36 goldens + the 23-town pack). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
b0e4ce103e |
Lane C R22 (v4.0): 23-town door-soak (#5) + the G2a atlas contract (#3)
Wave 3 — ran after A pinned the 36 goldens ( |
||
|
|
15ff53685f |
Lane D R22 (v4.0): citizens at pack scale — fitzroy stress PASS + the thin-tail clustering finding (ledger #5)
Against A's pack absorb (
|
||
|
|
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> |
||
|
|
d485b18ecc |
Lane A round 22: close the tri-diet loop — B's numbers say the fix is E's, not A's (ledger #1)
Docs-only handshake close; no code, no goldens. Filed so F isn't waiting on A for the re-measure. My R22 notes left ledger #1's ownership open on purpose: "if B's layer-by-layer names plan geometry (lot or poster counts) as the venue_night driver, I own the fix and will take it." B's diagnosis ( |
||
|
|
af8a6db020 |
Lane B round 22 (v4.0): #3 per-town bookmarks — anchor on the retail heart (Lane G's filed bug) + F's primitive
ROOT CAUSE: every "nearest" resolver in dbg.js sorted by distance from the WORLD ORIGIN. That's the town centre only on a synthetic plan -- a real OSM town is projected about its cache's bbox centre while its shops cluster hundreds of metres away, so bookmarks teleported into arbitrary far-flung geometry, exactly as G reported. Measured origin-pick distance from the retail heart: katoomba 408m, newtown 626m, fremantle 371m. FIX: resolve bookmarks about the town's DENSEST SHOP CLUSTER (grid-bin shop lots at 120m; heaviest bin's centroid = the retail heart) instead of the origin -- byDist, lotsByDist, streetViewPose, stopPose, and crossroadsPose's tie-break. GATED on the REAL-ROADS signal (edges > 200) -- the same primitive as the R20 tram fence -- so synthetic and the marched fixtures keep their exact origin-centred behaviour and F's release-tour control shot cannot move. The gate is load-bearing, not cosmetic: synthetic's anchor is only 117m out but it DOES re-pick (Anglibarn Op Shop -> Dusty Pages), so an unconditional switch would have silently moved the control. Same reason the new crossroadsPose tie-break is gated (a degree tie would otherwise resolve differently on synthetic). Verified across the town set: synthetic(22 edges)/melbourne(15)/katoomba-fixture(15)/silverton(1) -> origin, UNCHANGED; newtown_godverse(1626) -> anchor(98,-629); katoomba_real(993) -> anchor(-227,-625). G's own town is fixed. Result on katoomba: shopfront bookmarks went from ~408m adrift to <=42m of the retail heart (arcade 7m, milkbar_dusk/patronage_door/shopfront_detail 24m, market_square 26m, dig_real 42m); strip views ~195m on the high street; venue_night/queue_night ~345m (A's venue placement, not the bookmark). All 19 resolve, 0 errors; synthetic 19/19 unchanged. warehouse_fringe sits 3,074m out -- correct by design (it's the far:true fringe shot; on a 5km town the fringe genuinely is 3km away). -> F (ledger #4, the shared posing primitive): published on the harness as DBG.townAnchor {x,z,n,anchored,ref} (the retail heart + whether it's in use) and DBG.clusterPose(kinds) (stand on the road at the densest cluster, look along it). Your cluster-pose finding as a dbg.js-consumable -- the tour and the bookmarks now resolve through the SAME primitive, so a tour shot and its bookmark can't drift apart. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3face97046 |
Lane A round 22: absorb the town pack — 23 towns, 36 goldens pinned in one commit (v4.0, ledger #2)
E's 17 new towns + Lane G's newtown_godverse fed through the lift. ONE batched golden commit as briefed: REAL_TOWN_GOLDENS + REAL_TOWN_GIG_GOLDENS go 5 -> 23 towns each, zero unpinned. THE HEADLINE: everything built this epoch held at 23-town scale, FIRST TRY. 1,210 shops -> 1,133 seated (77 dropped, 6.4%, all counted by cause); 1 CONNECTED COMPONENT and 3 VENUES on every one of the 23 towns. fitzroy — 160 shops, 2x anything absorbed before — landed 139 seated, 1 component, 3 venues, 212 posters, all invariants green. The junction-protected DP, fragmentation ruling, cluster bias, poster cap and capacity fence needed NO new hardening: the pack needed absorbing, not fixing. - Graded cluster fallback (the one refinement). Three towns have no candidate at the floor at all (ballarat/toowoomba/newtown_godverse top out at 2 shops within 160m); R21's bias switched off entirely there, stranding venues at 0. It now falls back to the DENSEST AVAILABLE — ballarat 0,2,0 -> 2,2,2, godverse 0,1,1 -> 2,2,2, toowoomba 1,0,0 -> 1,2,1. Fires only where the floor is unreachable, so NO already-pinned town moved (verified). Acceptance at pack scale: 20 of 23 towns have every venue >=3; the three above sit at their town's genuine ceiling — the carved-out case, stated explicitly. - Drop outliers, counted not hidden: daylesford 19% (32 shops on a 171-road graph, the thinnest in the pack, all overflow), fitzroy 13%. RGAP is already 0.5m and NODE_CLEAR 3m; the only lever left is spilling overflow onto a DIFFERENT street, which buys a few percent by putting a shop on a road it isn't on. Same ruling as R20: drop and count beats teleport. - selfcheck ALL GREEN 161,300/161,300; scaffold + consistency GREEN; cross-process deterministic (pack-xor 0xca140954). classic 0x3fa36874 / gig 0xb1d48ea1 / marched fixtures FROZEN. Handshake -> C + D + F: the pack is in, 23 towns pinned, start your verifies. Tri diet (ledger #1): if B's layer-by-layer names plan geometry as the venue_night driver, I own the fix. 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
|
||
|
|
0c4dad5acc |
Lane B round 22 (v4.0): #1a venue_night tri diagnosis — the driver is E's four furniture GLBs (91.5%)
BLOCKING-ITEM DIAGNOSIS, filed first so E/A/F aren't waiting. Method: katoomba venue_night, settled, then
hide-a-layer-and-re-measure (frustum-accurate: a layer's cost = the tris that vanish when hidden), then the
same drill inside furniture bucketed by geometry.
VERDICT: the four GLB street-furniture props are 149,161 of 163,015 tris = 91.5% of the stress view.
OWNER: LANE E (asset tris), per the ledger's own rule. Decimation clears the gate with ~120k to spare.
Layer breakdown (baseline 163,015 tris / 88 draws):
chunk-furniture 151,341 (92.8%) | ground 9,932 | venue-presentation 770 | lighting 624 |
chunk-buildings 348 (0.2%) | venue-posters 222 | citizens/weather/tram/venue-pools 0
Buildings are 348 tris (the R3 atlas/instancing holds). Posters are 222 -- A's cap already worked and was
never the lever. Pools cost 0.
Inside furniture -- the four GLBs are the whole bill:
bench 1,942 tris/inst x64 = 60,202 (37%) <- procity_street_bench_01
bus_shelter 7,998 x10 = 55,986 (34%) <- procity_street_bus_shelter_01
bin 3,000 x19 = 18,000 (11%) <- procity_street_bin_01
food_cart 4,991 x8 = 14,973 (9%) <- procity_street_food_cart_01
pole/lamp/trees/novelty (primitives) x303 = 2,180 (1.3%)
Identity confirmed by DCC-authored material names (wire_143225087 = a Sketchfab scan, baked_mat,
"2 wood frame ", Material_0) -- E's GLBs, not our procedural materials. Two use MeshPhysicalMaterial.
WHY NOW (and why it is NOT the density widening): shop count doesn't drive this -- ROAD density does. Real
towns put the bench/bin/shelter cadence on a 966-edge graph, so ~100 GLB props land in the streamed set
where synthetic had a handful. A 1.2m bench at 1,942 tris is ~5x the entire building stock in frame. This is
B's own R6 note coming due ("street_bin 3.0k tris... a decimate to ~500 would give back tri headroom if the
combined-lane budget tightens").
-> E, suggested targets: bench 1942->~250, bus_shelter 7998->~600, bin 3000->~200, food_cart 4991->~400.
149,161 -> ~29,000 (saves ~120k). Projected: my 163k -> ~43k; F's 221,935 -> ~102k. Both far under 200k.
Cheap extra: drop the two MeshPhysicalMaterials to MeshStandardMaterial.
-> Fable: a B-side fallback exists (furniture.js already has a primitive fallback for every GLB prop via the
R4 use-if-ready path), so a distance-gated LOD is a contained B change I can land fast. NOT doing it
unilaterally -- per the ledger this is E's, and source decimation helps every town/view, not just this one.
-> F: my baseline is 163,015 vs your 221,935 on the same view -- my automation's rAF is throttled so the live
gig crowd never spawns (citizens measured 0). Furniture is still ~68% of your number; decimation clears the
gate on either baseline. Re-measure against the live crowd, not my figure.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
4590197259 |
Fable (integrator): round-22 instructions — v4.0 THE EPOCH CLOSE (tri diet first, pack absorb, release tour, G items)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
dd4489c70e |
Fable (integrator): merge Lane G R1 at the v4.0-beta boundary — godverse adapter + newtown_godverse (per FABLE_TO_LANE_G ruling)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
201a2bb868 |
Lane F R21 (v4.0-beta close): the beta gate — tram dimension, the re-measure, the beta shot
All five lanes in (A's venue cluster bias, B's selector-from-index, C's density door-soak, D's relocation verify PASSES, E's 22-town pack non-gating); F gated and tagged. - town_matrix.py: a `tram` dimension — B's R20 shop-adjacency ruling verified EXACTLY (newtown runs 16 stops after B's phantom-stop fix, castlemaine 10; katoomba/fremantle/bendigo FENCED at 3/2/1 shops fronted, all below the 5-shop floor). 10 towns x 7 gates: boot/determ/district/roads/tram/noassets green on all ten. - index.html: expose window.PROCITY.tram — B built `routeInfo` FOR F's smoke but nothing published it; F owns the shell, so F wired the seam. - RECORDED (ledger #6b — the instruction was "record the new number"): the venue_night re-measure. A's cap WORKED (posters 438->111) but E's density widening ate it — katoomba 200,965 (+965, R19) -> 221,935 (+21,935, +11%); bendigo 201k (+0.5%); fremantle/newtown/castlemaine in budget. Draws fine everywhere (151/300 — half budget); tris-only, at the worst night stress view. Filed as R22's first item, where the tri-diet backlog (instrument LOD, tram tri diet) already lives. katoomba is the outlier: 966 edges, 72 shops. - Ruling (ledger #6d): the town selector stays ALWAYS-IN-HUD, not ?dbg-gated — THE REAL MAP's product IS the towns. Corollary (F's own gap): money shots hide the HUD; the R19 alpha shot had the selector in-frame because F's harness screenshotted the full viewport. - Beta money shot: Fremantle's real street at golden hour — a corridor of shopfronts, footpaths, a crossing, gum trees, and a genuinely busy crowd (the density widening, visible). 126d/167k tris, HUD hidden. - docs: LANE_F_NOTES §20 (the honest why-R20-had-no-tag record) + §21, README beta paragraph, F-progress. qa.sh --strict GREEN; selfcheck 154141/154141 (A's re-pinned goldens hold). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
01c925816e |
Lane D R21 (v4.0-beta close): relocation verify — A's venue cluster bias PASSES (ledger #4)
Verified A's venue cluster-adjacency bias (
|
||
|
|
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> |
||
|
|
110c82833b |
Lane A round 21: venue cluster-adjacency bias — D's relocation finding (ledger #1)
D found katoomba's pub 1,000m from the retail cluster — a gig with no passing crowd. Measuring all five towns first showed it was SYSTEMIC: 11 of 15 venues sat with <3 shops within 160m (newtown's were 0/0/1 — every venue stranded). After the bias: 0 of 15. Katoomba's pub 1 → 9. Castlemaine cleared without needing the floor exception the brief anticipated. - pickVenues builds a CLUSTER-ADJACENT field first (>= CLUSTER_MIN 3 shops within CLUSTER_R 160m), then the kind flavors (pub corner / band_room fringe / rsl off-spine) bias WITHIN that field rather than overriding it (per the brief: biases, not absolutes) — a fringe band_room in the cluster beats one a kilometre from anyone. A town with no cluster at all falls back to the pool. - SYNTHETIC FROZEN BY CONSTRUCTION, not by luck. The brief assumed a blanket filter would be a no-op because 'the synthetic town is one dense cluster anyway'. Measurement says otherwise: 4 synthetic candidates PER SEED sit under the threshold (min cluster 0-1), so a blanket filter WOULD have moved the frozen golden. Gated on plan.source === 'osm' (undefined on synthetic) — impossible rather than unlikely. The marched fixtures are 'osm' but genuinely dense (min cluster 3/11/13) ⇒ verified no-op. - Only the GIG goldens moved (venue selection is gig-layer; base town goldens untouched): katoomba 0xbf586b77, newtown 0xacdb3eee, fremantle 0xcf3426fc, bendigo 0x646b2c23, castlemaine 0xf9713a69. classic 0x3fa36874 / gig 0xb1d48ea1 / marched fixtures FROZEN. selfcheck ALL GREEN 66419/66419; scaffold + consistency GREEN; cross-process deterministic. - FYI: E's v4.0 pack (glebe/marrickville/newcastle) already boots clean through my loader (validates + full suites pass), listed UNPINNED — I pin the pack in R22; it does not gate the beta tag. Handshake → C + D: cluster bias landed, goldens re-pinned, start your verifies (before/after table in LANE_A_NOTES §R21). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
4b0144989b |
Lane B round 21 (v4.0-beta): town selector reads E's towns index (ledger #2, the missed R20 #5)
Closes the gap Fable caught (hud.js:11 still hardcoded REAL_TOWNS). The real-town list now comes from E's web/assets/towns/index.json (procity-towns-index/1), so it grows with the town pack instead of being edited in hud.js. Verified fresh Chromium. Nothing else touched -- tram/ground work is done and verified. Fail-soft by construction: createHUD is synchronous, so the picker is built immediately from the fallback literal and UPGRADED IN PLACE when the index resolves -- if the index never arrives, a working list is already on screen. - index present -> real names/states/shop counts: "Katoomba, NSW · 80 shops", "Fremantle, WA · 80 shops", "Newtown, NSW · 72 shops", "Bendigo, VIC · 36 shops", "Castlemaine, VIC · 24 shops" (roads:false -> "· marched"). - ?noassets -> the fetch is SKIPPED entirely (asset law; the shell doesn't load town caches there either). Measured: 0 index fetches, fallback list, 0 errors. - anything wrong with the index -> the fallback simply stands. Exercised the exact chain: 404, network error, malformed JSON, towns:[], towns-not-an-array, junk entries (no key) -> none throws, none rebuilds from junk; only a good index rebuilds. REAL_TOWNS_FALLBACK is retained ONLY as that fallback (comment says so), no longer the source of truth. Verified live: booting katoomba_real shows "Katoomba, NSW · 80 shops" pre-selected; fits (193px of 230px max); 0 page errors; navigation unchanged (onchange is set once on the <select>, so rebuilding options never clears it). -> F: unchanged from R19 -- NO shell seam (selector is entirely hud.js, already built by createHUD) and it lives inside #pc-hud so setVisible(false) hides it for the beta money shot. The gating call is still yours. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
e3917dd35b |
Fable (integrator): response to Lane G — Draco ruling (no-Draco depot), density ruling, bug triage, G2/G3 sequence
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
223fbcaf72 |
Lane G (GODVERSE, ultra) R1: real-shop census adapter — 18 real Newtown shops on the real road graph
godverse_town.py marries a donor OSM cache's roads[] with thriftgod's DealGod-scraped shop census (2,928 real AU secondhand shops) -> <town>_godverse.json, schema v2 unchanged. First artifact newtown_godverse boots clean (?plansrc=osm&town=newtown_godverse). Lane brief + asks (Draco ruling, per-town bookmarks, enterShop selector) in docs/LANES/LANE_G_GODVERSE.md + G-progress.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
d678138ec1 |
Fable (integrator): round-21 instructions — the v4.0-beta close (venue cluster bias, selector index, density soak, the gate)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
0d992803c5 |
Lane D R20 (v4.0-beta): citizens at density — five-town verdict + the main-street relocation finding (ledger #7)
Re-ran everything against A's absorbed graph (
|
||
|
|
5d29863b78 |
Lane A round 20: absorb E's density widening — capacity, pub facade bias, goldens pinned (ledger #2)
E's five caches landed at 3-6x shops (292 total: katoomba 20→80, fremantle 21→80, newtown 18→72,
bendigo 9→36, castlemaine 6→24). All five absorb cleanly and still place 3 venues; the R20 poster cap
auto-scaled off the live shop count exactly as designed (katoomba 111 posters at 80 shops).
- CAPACITY WIDENED (the R18 overflow fence, load-tested). At 4x the dominant drop cause was OVERFLOW —
an edge-side holding more shops than fit (katoomba 10 of 11 drops). Tightened the run: NODE_CLEAR 6→3
and a ROADS-ONLY RGAP 2→0.5 (the shared marched GAP is untouched ⇒ marched fixtures stay frozen).
Drops 7.9% → 5.5% (16/292). 0.5m also reads truer — a real AU main street is continuous terrace
shopfronts, not detached boxes. Stopped there deliberately: the next lever (spilling overflow onto a
DIFFERENT street) buys ~1% by putting a shop on a road it isn't on — dropping a crowded shop is the
honest trade. Residual drops stay COUNTED, now BY CAUSE (dropped_overflow/_overlap/_stranded).
- VENUE FACADE BIAS NOW COVERS pub. R16 exempted pub ('spine-fronted, +Z always open') — true on the
synthetic/marched towns, but on a REAL graph at density the pub landed where its frontage poster
overhung a cross street (newtown, -0.91m). The POSTER_CLEAR filter now covers every venue kind; still a
NO-OP on synthetic (every pub candidate already clears) ⇒ gig golden 0xb1d48ea1 frozen.
- Goldens re-pinned ONCE (base + gig, all five towns). classic 0x3fa36874 / gig 0xb1d48ea1 / marched
fixtures FROZEN. selfcheck ALL GREEN 51866/51866; scaffold + consistency GREEN; cross-process
deterministic.
- Fixed: my real-cache loader globbed *.json and tried to validate E's new index.json as a town cache —
it now skips it (that's B's selector index, not a cache).
Handshake → all: densities absorbed, goldens pinned. → F: re-measure venue_night + gate the five towns.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
94e56ed5fa |
Lane B round 20 (v4.0-beta): the tram ruling — route by shop adjacency + per-town fence (ledger #3/#4)
Verified fresh Chromium across 9 town configs (synthetic, 3 fixtures, 5 real). TRAM RULING (ledger #3): spinePolyline now walks from each main-subgraph dead-end, greedily taking the unused main edge fronting the most shops (lot.frontEdge), keeping the best-scoring path (ties -> longer). SYNTHETIC + FIXTURES BYTE-IDENTICAL by construction AND measurement (a synthetic main node has <=2 mains so there's never a choice; its two dead-ends tie exactly and strict > keeps the pre-R20 start). Old vs new logic on the same plan = identical polylines (Boolarra: 7 pts, 6 edges, 810m, 172 shops, 2 stops). The alpha tram fronted 0 shops on 4 of 5 real towns (it was a highway bus). New: katoomba 0->3, newtown 0->8, fremantle 0->2, bendigo 0->1, castlemaine 1->6. Where the best main chain still fronts <5 shops the tram is FENCED per-town (Fable's fallback). RUNS: synthetic, all fixtures, newtown (8 shops/1924m/16 stops), castlemaine (6/2184m/10 stops). FENCED: katoomba (3), fremantle (2), bendigo (1) -- highway, not high street. The fence keys off the REAL-ROADS signal (edges>200), NEVER shop count alone: the marched fixtures front 0 shops on their mains (bare spine, avenues carry shops) so a naive fence would have killed their v2 tram. routeInfo{fenced,reason,shopsFronted,routeMetres} exposed for F's smoke. BUG FOUND+FIXED: the stop projection accepted every shelter in the town with no distance gate -- harmless on synthetic (2 shelters on the spine), nonsense on real graphs: Newtown made 149 phantom stops (~9 min of dwell at points the tram never passes). Added a 30m gate (a shelter sits halfRoad+1.7 <=~16m off its centreline, so genuine stops survive): newtown 149->16, castlemaine 37->10; synthetic 2 / fixtures 3 unchanged. GROUND POLISH (ledger #4): measured, NO fix needed. Real Katoomba has 325 deg-3+ junctions, 28 under 30 deg, worst 4.3 deg (near-parallel). At grazing eye level the worst reads clean -- no z-fight, no gaps. Layers are already y-separated (road 0.0/foot 0.02/kerb 0.06) and road-on-road overlap is invisible by design (OVERLAP=1.5 overruns nodes on purpose; one skin, one y, one merged draw on uniform asphalt). Cosmetic only: footpath/kerb double up on the sliver between <10deg near-parallel roads -- v4.0 candidate, not a defect. Selector polish (ledger #5): BLOCKED -- E's towns/index.json not landed (build_towns.py WIP); REAL_TOWNS hardcode stands, one-line swap when E lands. -> A (finding, measured): only a slice of shops front a MAIN edge on real towns -- katoomba 7/69, fremantle 4/79, bendigo 7/35, newtown 32/64, castlemaine 11/22. The real high street classifies as 'side', which is WHY three towns need the fence. If the main/side classifier promoted shop-dense ways to main, the fence would lift. Note onMain also gates gigs.js pickVenues pub placement. -> F: tram verdict above; selector gating (HUD vs ?dbg) is your call, one line either way. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
62cbb955b1 |
Lane D R20 (v4.0-beta): the density A/B + correcting my own sparsity misread (ledger #7, part 2)
SELF-CORRECTION first. My part-1 note called the 95-98% patronage null rate "sparsity-throttled" and made it the headline metric. Both halves were wrong: (1) it was measured at 21:00, when only 4 of 69 shops are open — retail is shut BY DESIGN, so a high night null is correct behaviour, not sparsity; (2) it sampled each town's first venue, and katoomba's is the pub — 1000m from the retail cluster with 1 neighbour. I had parked the camera on the one isolated venue in town. Same town, same seed: at the pub 99.4% null / 0 visits; on the actual main street 77.2% / 64 visits. The gig-crowd table stands (it measures the mechanism — 0 NaN, rosters, venue-win — which is location-independent); only my sparsity reading was bad. THE REAL A/B (main street, 14:00, same seed, pre-cache from git vs E's widened): hub density 8 -> 25 shops within 160m; null 90.2% -> 77.2%; total visits 17 -> 64 (3.8x); hero visits 17 -> 19; texture visits 0 -> 45; hero share 100% -> 30% of visits from 26% of shops. THE DIRECTIVE LANDS, measured from the crowd side: the secondhand heroes did NOT lose footfall (17 -> 19). The 45 texture visits are added ON TOP, not taken from them. The street is 3.8x busier while the heroes stay over-indexed. "More alive, not a different game." FILED: (a) venue placement at density — katoomba's rsl/band_room sit in the strip (13/10 neighbours) but the pub is 1000m out with 1; a gig there has no passing retail crowd. Quality observation, A/F's lane. (b) GIG_RANGE is a 34m radius but _nearestOpenShop searches only the ped's own 64m chunk — 8.7% of in-range peds are chunk-blind. Real but small; v4.x candidate, not a mid-beta hot-path change. POST numbers are vs E's committed caches but BEFORE A's absorb (11/80 still overflow- drop). Final re-run + the other four towns once A lands. 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> |
||
|
|
85745d2017 |
Lane D R20 (v4.0-beta): gig crowd on the five real towns — pre-density baseline (ledger #7, part 1)
The unblocked half of "citizens at density": the gig crowd's BEHAVIOUR on all five real towns' venues, measured BEFORE E's widening so the after-table is a real A/B. Density re-audit follows once E's caches + A's absorb land. BEHAVIOUR IS CORRECT ON ALL FIVE: 0 NaN everywhere; tonightRoster populates (2-7), so R14 identity continuity holds on real bones; every town generates 3 venues (pub/band_room/rsl) on night hours; and the surge works — whenever a patronage check finds any shop, the gig venue beats ordinary shopfronts (venue-win 100% on newtown/ fremantle/bendigo, 74% katoomba). Castlemaine's 40% is the 6-shop floor, not a leak: 3 of its 6 shops ARE venues, so "other" hits are mostly other venues. FINDING (quantifies Fable's ledger #2 "real towns are sparse"): the crowd is SPARSITY-throttled — 94.9-97.7% of patronage checks return null on every town, because peds spend nearly all their time in shopless chunks (katoomba: 19 shops in ~5 door-chunks of a ~78x78-chunk town). The mechanism is fine; the town has no shops per chunk. The density widening attacks exactly this — null% is my headline before/after metric. FILED (not fixed): GIG_RANGE is a 34m radius but _nearestOpenShop searches only the ped's own 64m chunk, so in-range peds across a chunk edge are blind to the gig — 8.7% of in-range ped-samples (852/9740) on katoomba. Small vs the 97% sparsity throttle; not worth a hot-path change mid-beta. Revisit if the widening leaves null% high. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
c7ca39b4f7 |
Lane C R20 (v4.0-beta): publish OSM-class -> archetype mapping (ledger #2, C's half)
The density widening's C half: real towns fetch general retail, not just secondhand. Published the OSM shop-class -> registry-archetype mapping in LANE_C_PUB.md §6 (new v4.0-beta amendment; frozen venue contract §0-§5 untouched). C->E handshake: E builds to it. - No new archetypes. General retail wears existing recipes: food/grocer/newsagent/chemist -> milkbar; clothes/hardware/big-retail -> dept; produce/florist -> stall. - Secondhand stays the hero (charity->opshop, books->book, music->record, video->video, pawn->pawn, toys->toy); never subsampled. Unknown/unlisted -> opshop (R18-proven). - Subtle per John: texture not takeover. Copy-paste JSON map + tasteful fetch list (skip vehicle/funeral/industrial/pure-services) + guardrail for E to subsample if retail drowns the secondhand strip (count in norm.dropped). - Mechanic: plan_osm keeps registry types, so E bakes a registry type per the map into each cache's shop.type -> no C code change, budgets unchanged. Pre-validated before E builds to it: milkbar/dept/stall/opshop all build valid at a real katoomba lot (8.5x14, 0 carves, <=143 draws); dept reads as a clean dressed-retail floor (shelves+racks+counter, escalator does not dominate the 7.9x11.7 hall) -> clothes/hardware -> dept confirmed. Full five-town door-soak (ledger #6) follows E's re-emitted caches. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |