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>
This commit is contained in:
parent
a9a5ef05d8
commit
528829eeba
@ -4,6 +4,35 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Round 26 (v5.0-beta — EVERY CRATE DIFFERENT) — F: the manifest consumed, the tolerance retired
|
||||||
|
|
||||||
|
**Every crate is different, and F measured it rather than taking G's word.** Not by entering one lucky
|
||||||
|
shop — from the indexes of record: **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 that isn't on disk.
|
||||||
|
|
||||||
|
**Sourcing, not tier — C was right.** `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, which is
|
||||||
|
`sourcing: real|mint`. E built to C's contract over the brief on the principle that the contract's author
|
||||||
|
owns the contract's shape. F's gate asserts it: 15/15 declare sourcing, every index 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 (the R24 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 instead of inventing it; G built the manifest; **F now consumes it**, and the shell asks for
|
||||||
|
nothing that isn't listed. Zero 404s because nothing absent gets asked for, not because the gate stopped
|
||||||
|
looking. **And deleting the tolerance immediately caught a leftover**: F had wired the *boot* preload but
|
||||||
|
left a second blind probe at the *door*, which 404'd on every keyed-but-unfetchable shop. While the gate
|
||||||
|
said "8 probes, expected", a ninth would have been invisible too. A named exception protects new bugs the
|
||||||
|
moment the real fix exists.
|
||||||
|
|
||||||
|
**Gate: `flags_check` GREEN** — distinctness · sourcing (real + mint rooms) · soft fall silent · **ZERO
|
||||||
|
404s** · **0 console errors, no attribution exceptions**. Full record: `LANE_F_NOTES` §26.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Round 24 (v5.0-alpha — THE ALPHA COMPLETION) — **the crate WALKS; F held the tag on A's gate**
|
## Round 24 (v5.0-alpha — THE ALPHA COMPLETION) — **the crate WALKS; F held the tag on A's gate**
|
||||||
|
|
||||||
**THE CRATE WALKS.** Boot `redhill_godverse`, walk down Musgrave Road into **Monster Robot Party**,
|
**THE CRATE WALKS.** Boot `redhill_godverse`, walk down Musgrave Road into **Monster Robot Party**,
|
||||||
|
|||||||
@ -1112,3 +1112,93 @@ the cache's shop entries, A+G) so the shell preloads exactly the shops that have
|
|||||||
mean a genuinely missing file, which is what fail-soft is *for*. **Filed as a contract ask, not
|
mean a genuinely missing file, which is what fail-soft is *for*. **Filed as a contract ask, not
|
||||||
invented.** Until it lands, F's smoke counts the probes, names them, and fails on any other error —
|
invented.** Until it lands, F's smoke counts the probes, names them, and fails on any other error —
|
||||||
tolerance stated out loud, never blanket-ignored.
|
tolerance stated out loud, never blanket-ignored.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 26. Round 26 — v5.0-beta EVERY CRATE DIFFERENT. F: the manifest consumed, the tolerance retired.
|
||||||
|
|
||||||
|
### The 404 tolerance is gone — and that is the point
|
||||||
|
R24's wire preloaded a pack for **every keyed shop** and ate a `404` for each one with no atlas. That was
|
||||||
|
the fail-soft law working, and it was also **console errors on every godverse boot**. F's smoke could only
|
||||||
|
cope by *naming* the probes — and **a tolerance is a confession, not a fix**. F filed the real fix as a
|
||||||
|
contract ask rather than inventing it: *an atlas index in G's namespace, so we never ask for what isn't
|
||||||
|
there.* G built it. **F now consumes it** (`assets/stock_godverse/index.json` → `{godverseShopId, types[],
|
||||||
|
sourcing}`): the shell preloads only manifest-listed `(shop, type)` pairs, and the gate asserts **ZERO
|
||||||
|
404s with no attribution exceptions**. The 404s are gone because there is nothing absent to ask for — not
|
||||||
|
because the gate stopped looking. Fail-soft still covers the case that matters (manifest says yes, file is
|
||||||
|
gone), which is what fail-soft was always *for*. Fetched only when the town has keyed shops, so a plain
|
||||||
|
town stays byte-identical: no manifest, no fetch.
|
||||||
|
|
||||||
|
### Distinctness — G reported 15/15; F measured it, from the indexes of record
|
||||||
|
Not by entering one lucky shop: **105 pairs across all 15 keyed crates, 0 sharing a title**; **0 crates
|
||||||
|
overlapping the generic v2 pack**; **0 ids reused across crates** — G's sku fix holds at scale, which is
|
||||||
|
the R24 vacuity dead at the source rather than papered over in F's gate. 4 crates in Red Hill + 11 in
|
||||||
|
Newtown = the manifest's 15 exactly, and the manifest lists nothing that isn't on disk.
|
||||||
|
|
||||||
|
### Sourcing, not tier — C was right and the gate follows C
|
||||||
|
C ruled the brief's `tier` field wrong: `tier` is the **charter's ladder rung**, and a mint atlas is *also*
|
||||||
|
rung 1 — a mint crate is still a deterministic file, still offline, still tier 1. What differs is where the
|
||||||
|
stock **came from**, which is `sourcing: real|mint`. E built to C's contract over Fable's brief on the
|
||||||
|
principle that *the contract's author is the authority for the contract's shape*, and Fable ratified it.
|
||||||
|
F's gate asserts `sourcing`: every index declares it, every index agrees with the manifest, and **a mint
|
||||||
|
crate can never report as real**. The gate prints it per room, because provenance a human never reads is
|
||||||
|
provenance that isn't doing anything — the same lesson as R24's silent licence line.
|
||||||
|
|
||||||
|
*Note for whoever reads the runtime:* C's pack (`stockpack.js`) does **not** carry `sourcing` through —
|
||||||
|
the gate reads it from the index of record, which is correct (the index is the artifact; B's street mark
|
||||||
|
reads the manifest). Not a gap; recorded so nobody re-derives it.
|
||||||
|
|
||||||
|
### ⚠ The tolerance came out and immediately caught the leftover
|
||||||
|
F wired the **boot** preload to the manifest, ran the gate with the 404 tolerance **deleted**, and it went
|
||||||
|
red on exactly one 404: `stock_godverse/31/stock_opshop_index.json`. That was F's *other* probe — R24 also
|
||||||
|
preloaded a shop's pack **on entry**, so walking into a keyed shop whose type has no atlas fired a fetch
|
||||||
|
that could only ever 404. Removed: the door does a lookup, never a fetch. The manifest is consulted once,
|
||||||
|
at boot, and by the time a door opens the pack is either resolved or was never going to exist.
|
||||||
|
|
||||||
|
The lesson is the round's, not just the bug's: **the tolerance was hiding a second instance of the very
|
||||||
|
thing it tolerated.** While the gate said "8 atlas-probe 404s, expected", the ninth would have been
|
||||||
|
invisible too. A named exception is still an exception; it earns its keep only until the real fix exists,
|
||||||
|
and the moment it does, the exception must die or it starts protecting new bugs.
|
||||||
|
|
||||||
|
### The gate, green
|
||||||
|
`DISTINCTNESS 15 crates / 105 pairs / 0 shared · 0 vs the generic pack · SOURCING 15/15 declared, all
|
||||||
|
agreeing with the manifest · Monster Robot Party → sourcing REAL, 120/120 own titles, 2 own textures / 0
|
||||||
|
generic · Presents of Mind → sourcing MINT, 16/16 own, 1 own / 0 generic · soft fall silent · ZERO 404s ·
|
||||||
|
0 console errors, no attribution exceptions.`
|
||||||
|
|
||||||
|
### ⚠ THE HOLD — `v5.0-beta` NOT tagged. `atlas-QA FAIL — 14 error(s)`, and it is not the product.
|
||||||
|
`qa.sh --strict --matrix` is **RED at the manifest validator**: E's `validate_atlas` rejects **all 14 mint
|
||||||
|
crates** (the real crate passes). Selfcheck is ALL GREEN 156,212/156,212; F's own beta gate is GREEN;
|
||||||
|
`flags_check` GREEN. The red is one assertion.
|
||||||
|
|
||||||
|
**The conflict:** `SLOT_ID_PREFIX = "sku_"` (`validate_atlas.py:73`) is a module constant applied to
|
||||||
|
**every** pack — E reads `sourcing` at :178 but the slot-id check is **sourcing-blind**. C §7.2a's rule is
|
||||||
|
*"derive from the source's own stable key, never position, unique across ALL packs"*, and it specifies
|
||||||
|
`sku_<POS sku>` **"for a real-stock (godverse) pack"**. **A mint crate has no POS sku by construction** —
|
||||||
|
it was never in that shop's till. Demanding one demands a thing that cannot exist: the same shape as R24's
|
||||||
|
sweep demanding a cafe carry a `godverseShopId`, and as the brief's `tier` demanding a rung where the
|
||||||
|
question was provenance.
|
||||||
|
|
||||||
|
**F measured the rule's INTENT, and it holds:** mint ids are `mint_<dealgod listing id>` — a real external
|
||||||
|
key, **non-positional**, items sorted by it, the bake seeded (`random.Random(158)` over an id-ordered
|
||||||
|
pool), and **0 ids reused across all 15 crates** (F's own pairwise measurement). Stable, unique,
|
||||||
|
non-positional. Only the literal prefix fails.
|
||||||
|
|
||||||
|
**G refused to go green the easy way, and was right to** — worth recording, because it is F's own R24
|
||||||
|
finding grown up: *"a POS sku and a dealgod listing id are different id spaces; filing dealgod listing ids
|
||||||
|
under `sku_` recreates that bug INSIDE the economy — tier-2's sold-means-gone looks up POS skus, and
|
||||||
|
`sku_6031122` (a dealgod id) is indistinguishable by shape from a real sku."* R24's plan-id-31 vs
|
||||||
|
godverse-id-31 collision entered the wrong shop; the same collision in the money layer sells the wrong
|
||||||
|
record. G caught it **before** shipping rather than after. Emitting `sku_` would have made this gate green
|
||||||
|
and the economy wrong.
|
||||||
|
|
||||||
|
**Why F did not fix E's one line:** identical to R24's conflict #2, and the answer has not changed. It is
|
||||||
|
**E's file implementing C's contract**, the question ("does §7.2a's sku rule bind a mint pack?") is **C's
|
||||||
|
to answer as the contract's author** — the principle Fable ratified when C overruled `tier` — and **F is
|
||||||
|
the party that benefits**, since the fix is the only thing between F and the tag it was sent to place.
|
||||||
|
F's whole worth is that F never shades a result. 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.
|
||||||
|
|
||||||
|
**The fix (C rules, E lands it, one line):** gate `SLOT_ID_PREFIX` on `sourcing == 'real'`; for `mint`,
|
||||||
|
assert `mint_`-prefixed + non-positional + unique — which F has already measured true. Then F re-gates
|
||||||
|
and tags. **Everything else for the beta is done and green.**
|
||||||
|
|||||||
@ -1004,100 +1004,143 @@ def smoke_gigs(p):
|
|||||||
|
|
||||||
|
|
||||||
GODVERSE_TOWN = 'redhill_godverse'
|
GODVERSE_TOWN = 'redhill_godverse'
|
||||||
GODVERSE_SHOP = 3962749 # Monster Robot Party, 147 Musgrave Rd, Red Hill QLD — the real shop
|
GODVERSE_SHOP = 3962749 # Monster Robot Party, 147 Musgrave Rd, Red Hill QLD — the one REAL crate
|
||||||
GODVERSE_BASE = f'assets/stock_godverse/{GODVERSE_SHOP}/'
|
GODVERSE_BASE = f'assets/stock_godverse/{GODVERSE_SHOP}/'
|
||||||
|
STOCK_MANIFEST = 'assets/stock_godverse/index.json'
|
||||||
|
|
||||||
|
|
||||||
def smoke_real_crate(p):
|
def smoke_real_crate(p):
|
||||||
"""R24 — THE REAL CRATE, gated so it cannot pass without touching its subject (the vacuous-gate law).
|
"""R26 — THE BETA GATE: every crate different, sourcing visible, and NOT ONE 404.
|
||||||
|
|
||||||
R23's #7a would have gone green on "real covers render" while the room held the generic v2 pack and
|
The lineage of this gate is the epoch's whole argument. R23's #7a would have gone green on "real
|
||||||
stock_godverse/ was never fetched once. R24's brief then specified id equality — which ALSO cannot
|
covers render" while the room held the generic v2 pack. R24's brief then said assert id equality —
|
||||||
discriminate, because both packs number items positionally (rec_0000…), so all 120 of the atlas's ids
|
which also couldn't discriminate, because both packs numbered items positionally and every atlas id
|
||||||
are generic-pack ids too. Presence proves nothing; slot numbers prove nothing. This smoke asserts the
|
was a generic-pack id too. What survives is what a wrong pack cannot fake: TITLES only this crate
|
||||||
two things a wrong pack cannot fake:
|
has, and the TEXTURE URL the GPU actually samples.
|
||||||
1. TITLE equality — the room's pack titles are the atlas's (0 of them exist in the generic pack).
|
|
||||||
2. TEXTURE provenance — the URL the GPU samples IS the shop's atlas file.
|
R26 adds the two beta claims. DISTINCTNESS: 15 keyed crates, pairwise title-disjoint — asserted
|
||||||
Plus the rungs either side: a keyed shop with no atlas falls SOFT to parody, and a plain town is
|
across the indexes of record, so it cannot pass by entering one lucky shop. SOURCING (C's §7.2b,
|
||||||
untouched. Subject absent (no town/atlas) ⇒ explicit SKIP with the reason, never a quiet pass."""
|
which correctly overruled the brief's `tier`): every index declares real|mint, a mint crate can
|
||||||
head(f'SMOKE: the real crate (R24 — {GODVERSE_TOWN} · Monster Robot Party · per-shop atlas identity)')
|
never report as real, and the gate PRINTS it.
|
||||||
|
|
||||||
|
And the 404s are gone for the right reason. R24 probed every keyed shop and ate a 404 for each one
|
||||||
|
with no atlas; F's smoke could only tolerate that by naming it — a tolerance is a confession. G's
|
||||||
|
manifest now says which (shop, type) pairs exist, so the shell asks for nothing else. ZERO console
|
||||||
|
errors, NO attribution exceptions. Subject absent ⇒ SKIP with the reason, never a quiet pass."""
|
||||||
|
head(f'SMOKE: the beta crate gate (R26 — 15 crates distinct · sourcing · zero 404s · {GODVERSE_TOWN})')
|
||||||
b, pg, errs = new_page(p)
|
b, pg, errs = new_page(p)
|
||||||
missing = [] # atlas probes that 404 — the fail-soft path, counted not hand-waved
|
four04 = []
|
||||||
pg.on('response', lambda r: missing.append(r.url) if (r.status == 404 and 'stock_godverse/' in r.url) else None)
|
pg.on('response', lambda r: four04.append(r.url) if r.status == 404 else None)
|
||||||
try:
|
try:
|
||||||
pg.goto(f'{HOST}/assets/towns/{GODVERSE_TOWN}.json')
|
pg.goto(f'{HOST}/{STOCK_MANIFEST}')
|
||||||
if 'godverse+osm' not in pg.content():
|
if 'godverseShopId' not in pg.content():
|
||||||
print(f'· SKIP: {GODVERSE_TOWN} cache absent or not godverse+osm — subject absent, nothing asserted (Lane G/E)')
|
print('· SKIP: no atlas manifest — subject absent, nothing asserted (Lane G)'); return
|
||||||
return
|
|
||||||
boot(pg, f'plansrc=osm&town={GODVERSE_TOWN}&stock=real&dig=1')
|
boot(pg, f'plansrc=osm&town={GODVERSE_TOWN}&stock=real&dig=1')
|
||||||
res = pg.evaluate("""async ({shop, base}) => {
|
res = pg.evaluate("""async ({manifest, real, base}) => {
|
||||||
const D = window.DBG, P = window.PROCITY;
|
const D = window.DBG, P = window.PROCITY;
|
||||||
const idxR = await fetch(base + 'stock_record_index.json');
|
const man = await (await fetch(manifest)).json();
|
||||||
if (!idxR.ok) return { skip: 'atlas absent for ' + shop };
|
|
||||||
const atlas = new Set(((await idxR.json()).items || []).map(i => i.title));
|
// ── DISTINCTNESS across the indexes of record (not just the shop we walk into) ──
|
||||||
const town = new Set((((await (await fetch('assets/models/stock_record_index.json')).json()).items) || [])
|
const crates = [];
|
||||||
|
for (const sh of (man.shops || [])) for (const t of (sh.types || [])) {
|
||||||
|
const u = `assets/stock_godverse/${sh.godverseShopId}/stock_${t}_index.json`;
|
||||||
|
const r = await fetch(u);
|
||||||
|
if (!r.ok) return { fail: `manifest lists ${u} but it 404s` };
|
||||||
|
const idx = await r.json();
|
||||||
|
crates.push({ id: sh.godverseShopId, type: t, manSourcing: sh.sourcing,
|
||||||
|
sourcing: idx.sourcing || null,
|
||||||
|
titles: (idx.items || []).map(i => i.title) });
|
||||||
|
}
|
||||||
|
const gen = {};
|
||||||
|
for (const t of ['record', 'book', 'toy'])
|
||||||
|
gen[t] = new Set((((await (await fetch(`assets/models/stock_${t}_index.json`)).json()).items) || [])
|
||||||
.map(i => i.title));
|
.map(i => i.title));
|
||||||
const entered = D.enterShop(shop);
|
let shared = 0, vsGeneric = 0, noSourcing = 0, manMismatch = 0;
|
||||||
await new Promise(r => setTimeout(r, 1400));
|
for (let i = 0; i < crates.length; i++) {
|
||||||
const si = D.stockInfo();
|
if (!crates[i].sourcing) noSourcing++;
|
||||||
if (!si || si.error) return { fail: 'no room: ' + JSON.stringify(si) };
|
if (crates[i].sourcing !== crates[i].manSourcing) manMismatch++;
|
||||||
// a keyed shop with NO atlas must fall soft to parody, not inherit this crate
|
if (crates[i].titles.some(t => gen[crates[i].type] && gen[crates[i].type].has(t))) vsGeneric++;
|
||||||
const other = (P.plan.shops || []).find(s => s.godverseShopId && s.godverseShopId !== shop);
|
for (let j = i + 1; j < crates.length; j++) {
|
||||||
let soft = null;
|
const a = new Set(crates[i].titles);
|
||||||
// 'g:<id>' — NOT the bare number: plan ids and godverse ids share a numeric space, so a
|
if (crates[j].titles.some(t => a.has(t))) shared++;
|
||||||
// bare id can silently enter a different shop and pass this assertion for the wrong reason.
|
}
|
||||||
if (other) { D.exitShop(); await new Promise(r => setTimeout(r, 300));
|
}
|
||||||
D.enterShop('g:' + other.godverseShopId); await new Promise(r => setTimeout(r, 900));
|
|
||||||
const o = D.stockInfo();
|
// ── the ROOM binds to the right crate: one REAL, one MINT, one soft fall ──
|
||||||
soft = { name: o.name, gid: o.godverseShopId, want: other.godverseShopId,
|
const byId = new Map((man.shops || []).map(s => [s.godverseShopId, s]));
|
||||||
packItems: o.packItems }; }
|
const stocked = (P.plan.shops || []).filter(s => { const e = byId.get(s.godverseShopId);
|
||||||
return {
|
return e && (e.types || []).includes(s.type); });
|
||||||
entered, base: si.base, name: si.name, gid: si.godverseShopId,
|
const unfetch = (P.plan.shops || []).find(s => { if (!s.godverseShopId) return false;
|
||||||
inAtlas: si.packTitles.filter(t => atlas.has(t)).length,
|
const e = byId.get(s.godverseShopId);
|
||||||
inTown: si.packTitles.filter(t => town.has(t)).length,
|
return !e || !(e.types || []).includes(s.type); });
|
||||||
packItems: si.packItems,
|
const visit = async (shop) => {
|
||||||
fromAtlasTex: si.texUrls.filter(u => u.includes(base)).length,
|
D.exitShop(); await new Promise(r => setTimeout(r, 250));
|
||||||
fromTownTex: si.texUrls.filter(u => u.includes('assets/models/stock_')).length,
|
D.enterShop('g:' + shop.godverseShopId); await new Promise(r => setTimeout(r, 1200));
|
||||||
soft,
|
const si = D.stockInfo();
|
||||||
|
const c = crates.find(c => c.id === shop.godverseShopId && c.type === shop.type);
|
||||||
|
const own = c ? new Set(c.titles) : new Set();
|
||||||
|
return { name: si.name, gid: si.godverseShopId, want: shop.godverseShopId, type: si.type,
|
||||||
|
base: si.base, packItems: si.packItems,
|
||||||
|
sourcing: c ? c.sourcing : null,
|
||||||
|
inOwn: si.packTitles.filter(t => own.has(t)).length,
|
||||||
|
fromOwnTex: si.texUrls.filter(u => u.includes(`stock_godverse/${shop.godverseShopId}/`)).length,
|
||||||
|
fromGenericTex: si.texUrls.filter(u => u.includes('assets/models/stock_')).length };
|
||||||
};
|
};
|
||||||
}""", {'shop': GODVERSE_SHOP, 'base': GODVERSE_BASE})
|
const realShop = stocked.find(s => s.godverseShopId === real);
|
||||||
if res.get('skip'):
|
const mintShop = stocked.find(s => (byId.get(s.godverseShopId) || {}).sourcing === 'mint');
|
||||||
print(f"· SKIP: {res['skip']} — subject absent, nothing asserted (Lane G)"); return
|
const out = { crates: crates.length, shared, vsGeneric, noSourcing, manMismatch,
|
||||||
|
stocked: stocked.length,
|
||||||
|
realRoom: realShop ? await visit(realShop) : null,
|
||||||
|
mintRoom: mintShop ? await visit(mintShop) : null };
|
||||||
|
if (unfetch) { D.exitShop(); await new Promise(r => setTimeout(r, 250));
|
||||||
|
D.enterShop('g:' + unfetch.godverseShopId); await new Promise(r => setTimeout(r, 900));
|
||||||
|
const o = D.stockInfo();
|
||||||
|
out.softFall = { name: o.name, gid: o.godverseShopId, want: unfetch.godverseShopId,
|
||||||
|
packItems: o.packItems }; }
|
||||||
|
return out;
|
||||||
|
}""", {'manifest': STOCK_MANIFEST, 'real': GODVERSE_SHOP, 'base': GODVERSE_BASE})
|
||||||
if res.get('fail'):
|
if res.get('fail'):
|
||||||
FAIL(f"the crate: {res['fail']}"); return
|
FAIL(f"beta crate gate: {res['fail']}"); return
|
||||||
print(f" room: {res['name']} (godverse {res['gid']}) → base {res['base']}")
|
|
||||||
OK(f"resolves its OWN base ({res['base']})") if res['base'] == GODVERSE_BASE else FAIL(f"base is {res['base']}, expected {GODVERSE_BASE}")
|
# ── distinctness (independently measured; G reported 15/15) ──
|
||||||
OK(f"TITLE equality: {res['inAtlas']}/{res['packItems']} titles are the shop's own atlas") \
|
pairs = res['crates'] * (res['crates'] - 1) // 2
|
||||||
if (res['packItems'] > 0 and res['inAtlas'] == res['packItems']) \
|
OK(f"DISTINCTNESS: {res['crates']} keyed crates, {pairs} pairs, {res['shared']} sharing a title") \
|
||||||
else FAIL(f"TITLE equality: only {res['inAtlas']}/{res['packItems']} titles are the shop's atlas")
|
if res['shared'] == 0 else FAIL(f"DISTINCTNESS: {res['shared']} crate pair(s) share titles")
|
||||||
OK(f"TITLE equality: 0/{res['packItems']} titles from the generic pack — the crate is not the v2 pack") \
|
OK(f"DISTINCTNESS: 0/{res['crates']} crates overlap the generic v2 pack") \
|
||||||
if res['inTown'] == 0 \
|
if res['vsGeneric'] == 0 else FAIL(f"{res['vsGeneric']} crate(s) overlap the generic pack")
|
||||||
else FAIL(f"TITLE equality: {res['inTown']}/{res['packItems']} titles came from the GENERIC pack")
|
# ── sourcing (C §7.2b — an index with no `sourcing` FAILS; the gate PRINTS it) ──
|
||||||
OK(f"TEXTURE provenance: {res['fromAtlasTex']} tex from the shop's atlas, {res['fromTownTex']} generic — the pixels' own file") \
|
OK(f"SOURCING: {res['crates']}/{res['crates']} indexes declare sourcing") \
|
||||||
if (res['fromAtlasTex'] > 0 and res['fromTownTex'] == 0) \
|
if res['noSourcing'] == 0 else FAIL(f"SOURCING: {res['noSourcing']} index(es) declare none")
|
||||||
else FAIL(f"TEXTURE provenance: {res['fromAtlasTex']} atlas / {res['fromTownTex']} generic — the GPU is sampling the wrong file")
|
OK('SOURCING: every index agrees with the manifest') \
|
||||||
if res.get('soft') is not None:
|
if res['manMismatch'] == 0 else FAIL(f"SOURCING: {res['manMismatch']} index/manifest disagreement(s)")
|
||||||
sf = res['soft']
|
|
||||||
# the subject must BE a keyed shop, or this assertion proves nothing (it passed on an
|
for label, want in (('realRoom', 'real'), ('mintRoom', 'mint')):
|
||||||
# unkeyed cafe first time round — a vacuous pass inside the anti-vacuous-pass gate)
|
r = res.get(label)
|
||||||
if sf.get('gid') != sf.get('want'):
|
if not r:
|
||||||
FAIL(f"soft fall: entered the WRONG shop — wanted godverse {sf.get('want')}, got {sf.get('gid')} (\"{sf['name']}\")")
|
FAIL(f"{label}: no {want} crate reachable in {GODVERSE_TOWN}"); continue
|
||||||
elif sf['packItems'] == 0:
|
if r['gid'] != r['want']:
|
||||||
OK(f"soft fall: keyed-but-atlas-less \"{sf['name']}\" (godverse {sf['gid']}) → parody, not this crate")
|
FAIL(f"{label}: entered the WRONG shop — wanted {r['want']}, got {r['gid']}"); continue
|
||||||
else:
|
print(f" room: {r['name']} (godverse {r['gid']}, {r['type']}) → {r['base']} [sourcing: {r['sourcing']}]")
|
||||||
FAIL(f"soft fall BROKEN: \"{sf['name']}\" inherited {sf['packItems']} items")
|
OK(f" {want}: sourcing reports '{r['sourcing']}'") if r['sourcing'] == want \
|
||||||
# Console errors: the ONLY tolerated ones are the atlas probes that 404 — that IS the fail-soft
|
else FAIL(f" {want} crate reports sourcing '{r['sourcing']}' — a {want} crate must never report otherwise")
|
||||||
# path (a keyed shop with no atlas → null → parody), and it is counted and named here, never
|
OK(f" {want}: TITLE equality {r['inOwn']}/{r['packItems']} from its OWN crate") \
|
||||||
# waved through. Any other error fails. The 404 noise itself is a real cost of probing blind;
|
if (r['packItems'] > 0 and r['inOwn'] == r['packItems']) \
|
||||||
# the fix is an atlas index in G's namespace so we never ask for what isn't there (F, R24 §24).
|
else FAIL(f" {want}: only {r['inOwn']}/{r['packItems']} titles are its own")
|
||||||
probes = len(missing)
|
OK(f" {want}: TEXTURE provenance {r['fromOwnTex']} own / {r['fromGenericTex']} generic") \
|
||||||
if probes and len(errs) == probes:
|
if (r['fromOwnTex'] > 0 and r['fromGenericTex'] == 0) \
|
||||||
print(f' · {probes} atlas-probe 404(s) — the fail-soft path, expected; 0 other console errors')
|
else FAIL(f" {want}: textures {r['fromOwnTex']} own / {r['fromGenericTex']} generic — wrong file")
|
||||||
print(f' (cost of probing blind; fix = an atlas index so we never probe an absent shop)')
|
|
||||||
elif errs:
|
sf = res.get('softFall')
|
||||||
FAIL(f'the crate: {len(errs)} console error(s), {probes} explained as atlas probes; first: {errs[0][:120]}')
|
if sf:
|
||||||
else:
|
if sf['gid'] != sf['want']: FAIL(f"soft fall: entered the wrong shop ({sf['gid']} != {sf['want']})")
|
||||||
print(' · 0 page errors')
|
elif sf['packItems'] == 0: OK(f"soft fall: keyed, unfetchable type \"{sf['name']}\" → parody, silently")
|
||||||
|
else: FAIL(f"soft fall BROKEN: \"{sf['name']}\" inherited {sf['packItems']} items")
|
||||||
|
|
||||||
|
# ── ZERO 404s. No exceptions. The manifest is what makes this honest. ──
|
||||||
|
OK('ZERO 404s — the manifest means we never ask for an atlas that is not there') \
|
||||||
|
if not four04 else FAIL(f"{len(four04)} unexpected 404(s) — the manifest should have prevented every one; first: {four04[0]}")
|
||||||
|
OK('0 console errors (no attribution exceptions)') if not errs \
|
||||||
|
else FAIL(f'the crate: {len(errs)} console error(s); first: {errs[0][:140]}')
|
||||||
finally:
|
finally:
|
||||||
b.close()
|
b.close()
|
||||||
|
|
||||||
|
|||||||
@ -205,12 +205,25 @@ const STOCK_REAL = params.get('stock') === 'real' && !NOASSETS;
|
|||||||
// parody: fail-soft runs through the same path, and that is the tier-0 rung of the ladder, live.
|
// parody: fail-soft runs through the same path, and that is the tier-0 rung of the ladder, live.
|
||||||
if (STOCK_REAL) {
|
if (STOCK_REAL) {
|
||||||
preloadStockPack('record'); preloadStockPack('book'); preloadStockPack('toy');
|
preloadStockPack('record'); preloadStockPack('book'); preloadStockPack('toy');
|
||||||
const seen = new Set();
|
// [Lane F R26 §7 — THE MANIFEST KILLS THE PROBES] R24 preloaded a pack for EVERY keyed shop and ate a
|
||||||
for (const s of (plan.shops || [])) {
|
// 404 for each one that had no atlas. That was fail-soft working, but it was also console errors on
|
||||||
const gBase = godverseBaseFor(s);
|
// every godverse boot, and F's smoke could only tolerate them by NAMING them — a tolerance is a
|
||||||
if (!gBase || seen.has(gBase + s.type)) continue;
|
// confession, not a fix. G's manifest (F's R24 finding #4/#7) says exactly which (shop, type) pairs
|
||||||
seen.add(gBase + s.type);
|
// exist, so now we ask for nothing else: zero 404s because there is nothing absent to ask for, not
|
||||||
preloadStockPack(s.type, { base: gBase });
|
// because we stopped looking. Fail-soft still covers the real case — manifest says yes, file is gone.
|
||||||
|
// Only fetched when the town actually has keyed shops, so a plain town stays byte-identical (no fetch).
|
||||||
|
if ((plan.shops || []).some((s) => s.godverseShopId)) {
|
||||||
|
try {
|
||||||
|
const r = await fetch('assets/stock_godverse/index.json', { cache: 'force-cache' });
|
||||||
|
if (r.ok) {
|
||||||
|
const man = await r.json();
|
||||||
|
const byId = new Map((man.shops || []).map((s) => [s.godverseShopId, s]));
|
||||||
|
for (const s of (plan.shops || [])) {
|
||||||
|
const e = byId.get(s.godverseShopId);
|
||||||
|
if (e && (e.types || []).includes(s.type)) preloadStockPack(s.type, { base: godverseBaseFor(s) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) { /* no manifest ⇒ no per-shop packs ⇒ parody. The ladder's bottom rung, unchanged. */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// [Lane F R8 — Lane C buy loop v0] ONE session wallet (seeded start cash) bound to the dig BUY across shops.
|
// [Lane F R8 — Lane C buy loop v0] ONE session wallet (seeded start cash) bound to the dig BUY across shops.
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
// The interior renders into its OWN dark THREE.Scene (the street scene is frozen, not disposed —
|
// The interior renders into its OWN dark THREE.Scene (the street scene is frozen, not disposed —
|
||||||
// CITY_SPEC L3 "pause, not dispose"), so returning to the street is instant.
|
// CITY_SPEC L3 "pause, not dispose"), so returning to the street is instant.
|
||||||
|
|
||||||
import { buildInterior, getStockPack, makeStockAdapter, preloadStockPack } from '../interiors/interiors.js';
|
import { buildInterior, getStockPack, makeStockAdapter } from '../interiors/interiors.js';
|
||||||
import { KeeperManager } from '../citizens/keepers.js'; // Lane D — shopkeeper behind the counter
|
import { KeeperManager } from '../citizens/keepers.js'; // Lane D — shopkeeper behind the counter
|
||||||
import { GigCrew } from '../citizens/band.js'; // Lane D — band trio + audience (R12, ?gigs=1)
|
import { GigCrew } from '../citizens/band.js'; // Lane D — band trio + audience (R12, ?gigs=1)
|
||||||
import { createDig, binSeed } from '../interiors/dig.js'; // Lane C — crate-riffle (v2, gated on ?dig=1)
|
import { createDig, binSeed } from '../interiors/dig.js'; // Lane C — crate-riffle (v2, gated on ?dig=1)
|
||||||
@ -206,8 +206,13 @@ export function createInteriorMode({ THREE, renderer, camera, plan, fleet = null
|
|||||||
// coexist instead of the per-shop pack silently inheriting the town-wide one (the R23 bug that held
|
// coexist instead of the per-shop pack silently inheriting the town-wide one (the R23 bug that held
|
||||||
// the tag). Missing atlas → 404 → null → parody: the fail-soft law runs through the SAME path.
|
// the tag). Missing atlas → 404 → null → parody: the fail-soft law runs through the SAME path.
|
||||||
// Gated on stockReal, never on the id alone: ?noassets ⇒ stockReal false ⇒ not one byte fetched.
|
// Gated on stockReal, never on the id alone: ?noassets ⇒ stockReal false ⇒ not one byte fetched.
|
||||||
|
// [R26] NO probe here. R24 preloaded this shop's pack on entry — which meant walking into a keyed
|
||||||
|
// shop whose type has no atlas fired a fetch that could only 404. The shell now preloads every
|
||||||
|
// (shop, type) the manifest actually lists, at boot, so by the time a door opens the pack is either
|
||||||
|
// resolved or was never going to exist; asking again at the door can only ask for the absent one.
|
||||||
|
// F's own gate caught this leftover the moment the 404 tolerance came out — which is the argument
|
||||||
|
// for taking tolerances out. Lookup only: a shop with no pack gets null → parody, silently.
|
||||||
const gBase = stockReal ? godverseBaseFor(shop) : undefined;
|
const gBase = stockReal ? godverseBaseFor(shop) : undefined;
|
||||||
if (gBase) preloadStockPack(shop.type, { base: gBase }); // idempotent; re-entry is a cache hit
|
|
||||||
currentAdapter = stockReal ? makeStockAdapter(getStockPack(shop.type, gBase)) : null;
|
currentAdapter = stockReal ? makeStockAdapter(getStockPack(shop.type, gBase)) : null;
|
||||||
// [Lane F R13 THE DISTRICT] Is THIS shop the venue with a gig on right now? Per-venue query — a town has
|
// [Lane F R13 THE DISTRICT] Is THIS shop the venue with a gig on right now? Per-venue query — a town has
|
||||||
// 2–4 venues, each with its own latch keyed by shop id. Lane C only stamps room.audio.gigKey when we pass
|
// 2–4 venues, each with its own latch keyed by shop id. Lane C only stamps room.audio.gigKey when we pass
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user