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:
m3ultra 2026-07-17 11:38:44 +10:00
parent a9a5ef05d8
commit 528829eeba
5 changed files with 270 additions and 90 deletions

View File

@ -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**
**THE CRATE WALKS.** Boot `redhill_godverse`, walk down Musgrave Road into **Monster Robot Party**,

View File

@ -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
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.
---
## 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.**

View File

@ -1004,100 +1004,143 @@ def smoke_gigs(p):
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}/'
STOCK_MANIFEST = 'assets/stock_godverse/index.json'
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
stock_godverse/ was never fetched once. R24's brief then specified id equality — which ALSO cannot
discriminate, because both packs number items positionally (rec_0000), so all 120 of the atlas's ids
are generic-pack ids too. Presence proves nothing; slot numbers prove nothing. This smoke asserts the
two things a wrong pack cannot fake:
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.
Plus the rungs either side: a keyed shop with no atlas falls SOFT to parody, and a plain town is
untouched. Subject absent (no town/atlas) explicit SKIP with the reason, never a quiet pass."""
head(f'SMOKE: the real crate (R24 — {GODVERSE_TOWN} · Monster Robot Party · per-shop atlas identity)')
The lineage of this gate is the epoch's whole argument. R23's #7a would have gone green on "real
covers render" while the room held the generic v2 pack. R24's brief then said assert id equality —
which also couldn't discriminate, because both packs numbered items positionally and every atlas id
was a generic-pack id too. What survives is what a wrong pack cannot fake: TITLES only this crate
has, and the TEXTURE URL the GPU actually samples.
R26 adds the two beta claims. DISTINCTNESS: 15 keyed crates, pairwise title-disjoint asserted
across the indexes of record, so it cannot pass by entering one lucky shop. SOURCING (C's §7.2b,
which correctly overruled the brief's `tier`): every index declares real|mint, a mint crate can
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)
missing = [] # atlas probes that 404 — the fail-soft path, counted not hand-waved
pg.on('response', lambda r: missing.append(r.url) if (r.status == 404 and 'stock_godverse/' in r.url) else None)
four04 = []
pg.on('response', lambda r: four04.append(r.url) if r.status == 404 else None)
try:
pg.goto(f'{HOST}/assets/towns/{GODVERSE_TOWN}.json')
if 'godverse+osm' not in pg.content():
print(f'· SKIP: {GODVERSE_TOWN} cache absent or not godverse+osm — subject absent, nothing asserted (Lane G/E)')
return
pg.goto(f'{HOST}/{STOCK_MANIFEST}')
if 'godverseShopId' not in pg.content():
print('· SKIP: no atlas manifest — subject absent, nothing asserted (Lane G)'); return
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 idxR = await fetch(base + 'stock_record_index.json');
if (!idxR.ok) return { skip: 'atlas absent for ' + shop };
const atlas = new Set(((await idxR.json()).items || []).map(i => i.title));
const town = new Set((((await (await fetch('assets/models/stock_record_index.json')).json()).items) || [])
const man = await (await fetch(manifest)).json();
// DISTINCTNESS across the indexes of record (not just the shop we walk into)
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));
const entered = D.enterShop(shop);
await new Promise(r => setTimeout(r, 1400));
const si = D.stockInfo();
if (!si || si.error) return { fail: 'no room: ' + JSON.stringify(si) };
// a keyed shop with NO atlas must fall soft to parody, not inherit this crate
const other = (P.plan.shops || []).find(s => s.godverseShopId && s.godverseShopId !== shop);
let soft = null;
// 'g:<id>' NOT the bare number: plan ids and godverse ids share a numeric space, so a
// 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();
soft = { name: o.name, gid: o.godverseShopId, want: other.godverseShopId,
packItems: o.packItems }; }
return {
entered, base: si.base, name: si.name, gid: si.godverseShopId,
inAtlas: si.packTitles.filter(t => atlas.has(t)).length,
inTown: si.packTitles.filter(t => town.has(t)).length,
packItems: si.packItems,
fromAtlasTex: si.texUrls.filter(u => u.includes(base)).length,
fromTownTex: si.texUrls.filter(u => u.includes('assets/models/stock_')).length,
soft,
let shared = 0, vsGeneric = 0, noSourcing = 0, manMismatch = 0;
for (let i = 0; i < crates.length; i++) {
if (!crates[i].sourcing) noSourcing++;
if (crates[i].sourcing !== crates[i].manSourcing) manMismatch++;
if (crates[i].titles.some(t => gen[crates[i].type] && gen[crates[i].type].has(t))) vsGeneric++;
for (let j = i + 1; j < crates.length; j++) {
const a = new Set(crates[i].titles);
if (crates[j].titles.some(t => a.has(t))) shared++;
}
}
// the ROOM binds to the right crate: one REAL, one MINT, one soft fall
const byId = new Map((man.shops || []).map(s => [s.godverseShopId, s]));
const stocked = (P.plan.shops || []).filter(s => { const e = byId.get(s.godverseShopId);
return e && (e.types || []).includes(s.type); });
const unfetch = (P.plan.shops || []).find(s => { if (!s.godverseShopId) return false;
const e = byId.get(s.godverseShopId);
return !e || !(e.types || []).includes(s.type); });
const visit = async (shop) => {
D.exitShop(); await new Promise(r => setTimeout(r, 250));
D.enterShop('g:' + shop.godverseShopId); await new Promise(r => setTimeout(r, 1200));
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})
if res.get('skip'):
print(f"· SKIP: {res['skip']} — subject absent, nothing asserted (Lane G)"); return
const realShop = stocked.find(s => s.godverseShopId === real);
const mintShop = stocked.find(s => (byId.get(s.godverseShopId) || {}).sourcing === 'mint');
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'):
FAIL(f"the crate: {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}")
OK(f"TITLE equality: {res['inAtlas']}/{res['packItems']} titles are the shop's own atlas") \
if (res['packItems'] > 0 and res['inAtlas'] == res['packItems']) \
else FAIL(f"TITLE equality: only {res['inAtlas']}/{res['packItems']} titles are the shop's atlas")
OK(f"TITLE equality: 0/{res['packItems']} titles from the generic pack — the crate is not the v2 pack") \
if res['inTown'] == 0 \
else FAIL(f"TITLE equality: {res['inTown']}/{res['packItems']} titles came from the GENERIC pack")
OK(f"TEXTURE provenance: {res['fromAtlasTex']} tex from the shop's atlas, {res['fromTownTex']} generic — the pixels' own file") \
if (res['fromAtlasTex'] > 0 and res['fromTownTex'] == 0) \
else FAIL(f"TEXTURE provenance: {res['fromAtlasTex']} atlas / {res['fromTownTex']} generic — the GPU is sampling the wrong file")
if res.get('soft') is not None:
sf = res['soft']
# the subject must BE a keyed shop, or this assertion proves nothing (it passed on an
# unkeyed cafe first time round — a vacuous pass inside the anti-vacuous-pass gate)
if sf.get('gid') != sf.get('want'):
FAIL(f"soft fall: entered the WRONG shop — wanted godverse {sf.get('want')}, got {sf.get('gid')} (\"{sf['name']}\")")
elif sf['packItems'] == 0:
OK(f"soft fall: keyed-but-atlas-less \"{sf['name']}\" (godverse {sf['gid']}) → parody, not this crate")
else:
FAIL(f"soft fall BROKEN: \"{sf['name']}\" inherited {sf['packItems']} items")
# Console errors: the ONLY tolerated ones are the atlas probes that 404 — that IS the fail-soft
# path (a keyed shop with no atlas → null → parody), and it is counted and named here, never
# waved through. Any other error fails. The 404 noise itself is a real cost of probing blind;
# the fix is an atlas index in G's namespace so we never ask for what isn't there (F, R24 §24).
probes = len(missing)
if probes and len(errs) == probes:
print(f' · {probes} atlas-probe 404(s) — the fail-soft path, expected; 0 other console errors')
print(f' (cost of probing blind; fix = an atlas index so we never probe an absent shop)')
elif errs:
FAIL(f'the crate: {len(errs)} console error(s), {probes} explained as atlas probes; first: {errs[0][:120]}')
else:
print(' · 0 page errors')
FAIL(f"beta crate gate: {res['fail']}"); return
# ── distinctness (independently measured; G reported 15/15) ──
pairs = res['crates'] * (res['crates'] - 1) // 2
OK(f"DISTINCTNESS: {res['crates']} keyed crates, {pairs} pairs, {res['shared']} sharing a title") \
if res['shared'] == 0 else FAIL(f"DISTINCTNESS: {res['shared']} crate pair(s) share titles")
OK(f"DISTINCTNESS: 0/{res['crates']} crates overlap the generic v2 pack") \
if res['vsGeneric'] == 0 else FAIL(f"{res['vsGeneric']} crate(s) overlap the generic pack")
# ── sourcing (C §7.2b — an index with no `sourcing` FAILS; the gate PRINTS it) ──
OK(f"SOURCING: {res['crates']}/{res['crates']} indexes declare sourcing") \
if res['noSourcing'] == 0 else FAIL(f"SOURCING: {res['noSourcing']} index(es) declare none")
OK('SOURCING: every index agrees with the manifest') \
if res['manMismatch'] == 0 else FAIL(f"SOURCING: {res['manMismatch']} index/manifest disagreement(s)")
for label, want in (('realRoom', 'real'), ('mintRoom', 'mint')):
r = res.get(label)
if not r:
FAIL(f"{label}: no {want} crate reachable in {GODVERSE_TOWN}"); continue
if r['gid'] != r['want']:
FAIL(f"{label}: entered the WRONG shop — wanted {r['want']}, got {r['gid']}"); continue
print(f" room: {r['name']} (godverse {r['gid']}, {r['type']}) → {r['base']} [sourcing: {r['sourcing']}]")
OK(f" {want}: sourcing reports '{r['sourcing']}'") if r['sourcing'] == want \
else FAIL(f" {want} crate reports sourcing '{r['sourcing']}' — a {want} crate must never report otherwise")
OK(f" {want}: TITLE equality {r['inOwn']}/{r['packItems']} from its OWN crate") \
if (r['packItems'] > 0 and r['inOwn'] == r['packItems']) \
else FAIL(f" {want}: only {r['inOwn']}/{r['packItems']} titles are its own")
OK(f" {want}: TEXTURE provenance {r['fromOwnTex']} own / {r['fromGenericTex']} generic") \
if (r['fromOwnTex'] > 0 and r['fromGenericTex'] == 0) \
else FAIL(f" {want}: textures {r['fromOwnTex']} own / {r['fromGenericTex']} generic — wrong file")
sf = res.get('softFall')
if sf:
if sf['gid'] != sf['want']: FAIL(f"soft fall: entered the wrong shop ({sf['gid']} != {sf['want']})")
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:
b.close()

View File

@ -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.
if (STOCK_REAL) {
preloadStockPack('record'); preloadStockPack('book'); preloadStockPack('toy');
const seen = new Set();
for (const s of (plan.shops || [])) {
const gBase = godverseBaseFor(s);
if (!gBase || seen.has(gBase + s.type)) continue;
seen.add(gBase + s.type);
preloadStockPack(s.type, { base: gBase });
// [Lane F R26 §7 — THE MANIFEST KILLS THE PROBES] R24 preloaded a pack for EVERY keyed shop and ate a
// 404 for each one that had no atlas. That was fail-soft working, but it was also console errors on
// every godverse boot, and F's smoke could only tolerate them by NAMING them — a tolerance is a
// confession, not a fix. G's manifest (F's R24 finding #4/#7) says exactly which (shop, type) pairs
// exist, so now we ask for nothing else: zero 404s because there is nothing absent to ask for, not
// 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.

View File

@ -15,7 +15,7 @@
// 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.
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 { 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)
@ -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
// 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.
// [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;
if (gBase) preloadStockPack(shop.type, { base: gBase }); // idempotent; re-entry is a cache hit
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
// 24 venues, each with its own latch keyed by shop id. Lane C only stamps room.audio.gigKey when we pass