From f522021765608afc243a1bf88510931bb4915e99 Mon Sep 17 00:00:00 2001 From: m3ultra Date: Mon, 3 Aug 2026 17:30:59 +1000 Subject: [PATCH] =?UTF-8?q?Lane=20F=20R37=20(v8=20wave=200,=200.1=20F-half?= =?UTF-8?q?):=20THE=20KERB=20GATE=20=E2=80=94=20poster=20clearance=20measu?= =?UTF-8?q?red=20on=20the=20PAINT,=20and=20the=20=3Fverge=3D0=20control=20?= =?UTF-8?q?fires=20at=20exactly=2014?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New STRICT smoke_kerb. Lane A's corrected selfcheck asks the plan-side question (is the poster's offset inside vergeBand(e)[0]?) -- right for A's file, but it still reads no number that came from Lane B, which is the precise failure that made the old gate vacuous. So F asks the runtime question, of the paint: RAYCAST STRAIGHT DOWN AT EVERY RENDERED POSTER AND CLASSIFY THE TOPMOST GROUND HIT. Classification is by MATERIAL IDENTITY -- skins.groundMat() is a cached factory, so the road mesh's material IS the object groundMat('djsim-road') returns. No mesh names, no string matching, nothing that drifts when B edits ground.js. Topmost rather than first, deliberately: B put the carriageway on top at junctions (ROAD_Y 0 -> 0.04) so roads run through intersections, and what the player sees under a poster is the top surface. Six arms, all green on the final tree: subject 14 posters rendered == 14 in plan.posters, every one within 0 m of its planned position, read off the real venue-posters InstancedMesh matrices. Nobody had ever asserted that the poster you see is the poster A placed. Zero posters => FAIL. detector ctl A the centreline of the longest main (main@28 m, 137.5 m) classifies ROAD at y 0.04 detector ctl B 13 m off it (1 m inboard of the corridor edge) classifies FOOTPATH at y 0.02 THE RULING 0 of 14 posters stand on road paint -- tally {djsim-footpath: 14} THE CONTROL the same leg under ?verge=0 FAILS at EXACTLY 14 -- tally {djsim-road: 14}. Keyed to B's flag, never to a line number, matching A's discipline. classic 13 m off the centreline is still ROAD under ?classic=1 and classic renders 0 posters -- Fable's CLASSIC KEEPS ITS PAINT ruling holds. The two detector controls are the load-bearing part: "0 posters on road" is a sentence about nothing unless the classifier is shown to say road AND footpath on the same boot. TWO LANES, TWO INDEPENDENT METHODS, THE SAME NUMBER: A counted 14 plan-side by offset in node over the plan; F counted 14 paint-side by raycast in the browser over B's geometry. Both flip to 0 on the default boot. Also lands Fable's ruling on classic's post-v2 fetch delta (4a7c0f1) in the mechanism. The audio pack is RATIFIED BASELINE -- v2.1 was v2's final tagged state -- so the allow-list authority moves v2.0 -> v2.1. Git makes that surgical rather than generous: `git diff v2.0 v2.1 -- web/` is the audio pack, js/world/audio.js and four wiring edits; zero other assets, zero deletions. So the tag change admits precisely the five ratified files and nothing else, and the depot GLB names survive in v2.1's manifest unchanged (verified: same-origin baseline 47 -> 52, exceptions 2 -> 1, control still discriminating). assets/towns/index.json is NOT baseline and now prints every run as "EXCEPTION (NOT v2.1 baseline)" with its provenance, so it can never read as covenant. README: the ?verge=0 row now carries A's corrected band figures rather than the charter headline -- 9 m is the synthetic 28 m main only; a real main is 24 m => 7 m, and side@12, 72% of the corpus, is 3 m. Co-Authored-By: Claude Opus 5 --- README.md | 2 +- tools/flags_check.py | 266 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 243 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 8806bdb..b197c65 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ master off: | `?weather=0` · `?tram=0` · `?winmap=0` | **on** | seeded weather · the tram loop · the parallax interior-window shader | | `?roster=v1` · `?pop=N` | stream | chunk-streamed citizen density is the baseline; `?roster=v1` restores the fixed roster | | `?dig=0` · `?stock=real` | dig on | crate-riffle on record bins · real GODVERSE sleeves in the stock | -| `?verge=0` | **off** | reverts the ground to the **pre-kerb-ruling** geometry (bitumen painted to the full corridor). John's v8 ruling made the 9 m band between kerb and shopfront **footpath**; this flag keeps the old geometry available forever as the gate's falsifiability control — the poster-clearance leg is asserted to FAIL under it | +| `?verge=0` | **off** | reverts the ground to the **pre-kerb-ruling** geometry (bitumen painted to the full corridor). John's v8 ruling made the band between kerb and shopfront **footpath** — 9 m on the synthetic town's 28 m main, **7 m** on a real 24 m main, and **3 m** on the `side`@12 edge that is 72% of the corpus. The flag stays forever as the gate's falsifiability control: the poster-clearance leg is asserted to FAIL under it, at exactly 14 posters standing on road paint. `?classic=1` forces the ruling off — the covenanted town keeps its paint | | `?r=N` · `?shadows=0\|1` | auto | streaming radius and the sun-shadow pass. **Auto is load-bearing**: a big town (>120 shops or >200 street edges) gets radius 2 with shadows off. Forcing `?r=3` on the default town measures **307 draws**, i.e. over the 300 gate — these overrides are diagnostics, not supported boots | | `?live=1` · `?live=` | **off** | **tier 2** — live stock from the GODVERSE server (sold-in-the-real-shop means gone in the game). Opt-in by design: absent ⇒ byte-identical to tier 1, and the game never asks a question it has no reason to expect an answer to | | `?noassets=1` · `?plansrc=osm` · `?mute=1` · `?dbg=1` | off | asset-free (zero network) · OSM plan source · silence · the `window.DBG` capture/soak harness | diff --git a/tools/flags_check.py b/tools/flags_check.py index 8a2cb38..00716fc 100644 --- a/tools/flags_check.py +++ b/tools/flags_check.py @@ -148,18 +148,28 @@ def plansrc_landed(p): # plus same-origin" would have been green straight through it. Same-origin is NOT a free pass here; # `/models/peds/` is enumerated by the v2.0 tree, which contains exactly the covenanted 21 files. # -# POST-v2.0 ADDITIONS (Tier P) — measured, named, dated, and NOT silently swallowed. Booting the -# actual v2.0 tree and diffing its fetch surface against today's ?classic=1 gives a delta of exactly -# +3 files, all shipped years of rounds ago and never ruled on: -# /assets/audio/* R11 audio engine (f7dd44f, Lane B round-11) -# /assets/towns/index.json R20/R21 town selector (078245f, 4b01449) -# They are allowed here so the suite is not permanently yellow over shipped behaviour, and PRINTED -# every run so the delta can never go invisible. Fable's to ratify or retire — not F's to improvise. -V2_TAG = 'v2.0' +# THE BASELINE TAG IS `v2.1`, AND THAT IS FABLE'S R37 RULING, NOT A CONVENIENCE. F measured classic's +# live fetch surface against the actual `v2.0` tree and found a delta of +6 files: five audio and +# `assets/towns/index.json`. Fable ruled (ROUND37_INSTRUCTIONS, 4a7c0f1): the covenant preserves "the +# exact v2 town", and **v2.1 was v2's final tagged state**, so the audio pack shipped inside v2 exactly +# as the furniture GLBs did — RATIFIED BASELINE. Git makes that ruling exact rather than generous: +# `git diff v2.0 v2.1 -- web/` is the audio pack, `js/world/audio.js`, and four wiring edits. **Zero +# other assets, zero deletions.** So moving the authority from v2.0 to v2.1 admits precisely the +# ratified audio and nothing else, and the depot GLB names survive in v2.1's manifest unchanged. +# +# `assets/towns/index.json` is **NOT baseline** — it is v4 selector machinery (R20/R21). Fable ruled it +# carried as a NAMED, PRINTED EXCEPTION: no geometry, no identity, no seeded draw, so not the R36 +# species and not gettable in a floor round. It is labelled EXCEPTION, never baseline, so a reader of +# this log can never mistake the two. "Should classic show the town selector at all?" is on the v8 debt +# ledger for R38+. +V2_TAG = 'v2.1' DEPOT_HOSTS = ('digalot.fyi',) -POST_V2_PREFIXES = ( - ('/assets/audio/', 'R11 audio engine (f7dd44f)'), - ('/assets/towns/index.json', 'R20/R21 town selector (078245f, 4b01449)'), +# (prefix, label) — carried, NOT baseline. Printed on every run, tagged EXCEPTION in the output. +POST_V2_EXCEPTIONS = ( + ('/assets/towns/index.json', + 'v4 town-selector machinery (078245f R20, 4b01449 R21) — NOT v2 baseline; carried by Fable\'s ' + 'R37 ruling as a named exception (no geometry, no identity, no seeded draw). Debt ledger R38+: ' + 'should ?classic=1 show the town selector at all?'), ) # The core that must ALL be observed, or the observer is not looking at a live boot (anti-vacuous): # the four v2-era depot street GLBs + the covenanted ped fleet's shared clips. @@ -199,9 +209,9 @@ def _classify_fetch(url, host, paths, depot): return 'ok', 'code (same-origin module/document)' if path == '/favicon.ico': return 'ignored', 'browser noise' - for pre, why in POST_V2_PREFIXES: + for pre, why in POST_V2_EXCEPTIONS: if path.startswith(pre): - return 'ok', f'POST-v2.0 addition, allowed + unratified — {why}' + return 'ok', f'CARRIED EXCEPTION (not {V2_TAG} baseline) — {why}' if path in paths: return 'ok', f'same-origin asset present in the {V2_TAG} tree' return 'violation', f'same-origin asset NOT in the {V2_TAG} tree' @@ -362,17 +372,16 @@ def classic_regression(p): depot_n = len(tiers.get(f'depot asset named in the {V2_TAG} manifest', [])) v2_n = len(tiers.get(f'same-origin asset present in the {V2_TAG} tree', [])) code_n = len(tiers.get('code (same-origin module/document)', [])) - OK(f"classic fetch surface CLEAN against the {V2_TAG} tag — {len(observed)} network " - f"requests, 0 outside the baseline ({code_n} code modules · {v2_n} same-origin assets " - f"present at {V2_TAG} · {depot_n} depot assets named in the {V2_TAG} manifest, incl. the " - f"four v2-era street GLBs, which are BASELINE and must never be 'fixed' away)") + exc_n = sum(len(v) for k, v in tiers.items() if k.startswith('CARRIED EXCEPTION')) + OK(f"classic fetch surface CLEAN against the {V2_TAG} tag ({V2_TAG} = v2's final tagged " + f"state, Fable's R37 ruling) — {len(observed)} network requests, 0 outside the baseline " + f"({code_n} code modules · {v2_n} same-origin assets present at {V2_TAG} · {depot_n} depot " + f"assets named in the {V2_TAG} manifest, incl. the four v2-era street GLBs, which are " + f"BASELINE and must never be 'fixed' away · {exc_n} carried exception(s), listed below)") for tier, urls in sorted(tiers.items()): - if tier.startswith('POST-v2.0'): - WARN_ONCE = f"classic carries a POST-{V2_TAG} fetch delta: {len(urls)} file(s) — " \ - f"{sorted({u.split('/')[-1] for u in urls})} — {tier.split('— ')[-1]}. " \ - f"Allowed here so the suite is not permanently yellow over shipped " \ - f"behaviour; UNRATIFIED. Fable's to bless or retire." - print(f" \033[33m·\033[0m {WARN_ONCE}") + if tier.startswith('CARRIED EXCEPTION'): + print(f" \033[33m·\033[0m EXCEPTION (NOT {V2_TAG} baseline): " + f"{sorted({u.split('/')[-1] for u in urls})} — {tier.split('— ', 1)[-1]}") # ── THE CONTROL, demonstrated in-run: two fabricated fetches must both go RED ── # (a) the R36 breach replayed exactly — a same-origin ped GLB added after v2.0. An @@ -1072,6 +1081,214 @@ def smoke_tram(p): finally: b.close() +# ── [R37 item 0.1, F half] THE KERB GATE — poster clearance, measured on the PAINT ──────────────── +# John's ruling: the band between kerb and shopfront is FOOTPATH. Lane A corrected its plan-side +# selfcheck (e4d7762) and pinned the pre-ruling failure at exactly 14 posters on the default boot; +# Lane B narrowed the road quad and extended the merged footGeos class inward (47db478) and shipped +# `?verge=0`, which reverts to the pre-ruling geometry permanently. +# +# A's gate is PLAN-SIDE: it asks whether a poster's offset is inside `vergeBand(e)[0]`. That is the +# right question for A's file, but it still never reads a number that came from B — which is the +# exact failure mode ("the gate and its subject were the same function agreeing with itself") that +# made the old one vacuous. So F's gate asks the RUNTIME question instead, and asks it of the paint: +# +# RAYCAST STRAIGHT DOWN AT EVERY POSTER AND SEE WHAT SURFACE IS ACTUALLY UNDER IT. +# +# The topmost ground hit is classified by MATERIAL IDENTITY — `skins.groundMat()` is a cached +# factory, so the road mesh's material IS the object `groundMat('djsim-road')` returns; no string +# matching, no mesh names, nothing that drifts when B edits. Topmost (not first-by-edge) is +# deliberate: B put the carriageway ON TOP at junctions (ROAD_Y 0 → 0.04) so roads run through +# intersections, and what a player sees under a poster is the top surface. +_KERB_JS = r""" +() => { + const P = window.PROCITY, T = P.THREE, skins = P.skins; + // the four merged ground classes, identified by the cached material instance itself + const CLASSES = ['djsim-road', 'djsim-footpath', 'grass', 'brickpave']; + const matOf = new Map(CLASSES.map(n => [skins.groundMat(n), n])); + const meshes = []; + P.scene.traverse(o => { if (o.isMesh && matOf.has(o.material)) meshes.push(o); }); + const classify = (x, z) => { + const rc = new T.Raycaster(new T.Vector3(x, 40, z), new T.Vector3(0, -1, 0), 0, 200); + const hits = rc.intersectObjects(meshes, false); + if (!hits.length) return { cls: 'none', y: null }; + let top = hits[0]; + for (const h of hits) if (h.point.y > top.point.y) top = h; + return { cls: matOf.get(top.object.material), y: +top.point.y.toFixed(3) }; + }; + // ── the rendered posters: read the real InstancedMesh matrices, not the plan array ── + const rendered = []; + const m4 = new T.Matrix4(), v3 = new T.Vector3(); + P.scene.traverse(o => { + if (o.isInstancedMesh && o.name === 'venue-posters') { + for (let i = 0; i < o.count; i++) { + o.getMatrixAt(i, m4); v3.setFromMatrixPosition(m4); o.localToWorld(v3); + rendered.push([+v3.x.toFixed(3), +v3.z.toFixed(3)]); + } + } + }); + const planned = (P.plan.posters || []).map(q => [+q.x.toFixed(3), +q.z.toFixed(3)]); + // rendered ↔ planned agreement (licenses using plan ids for the per-poster report) + let matched = 0, worstDelta = 0; + for (const r of rendered) { + let bd = 1e18; + for (const q of planned) { const d = Math.hypot(r[0] - q[0], r[1] - q[1]); if (d < bd) bd = d; } + if (bd <= 0.01) matched++; + if (bd > worstDelta) worstDelta = bd; + } + // ── the clearance measurement ── + const per = rendered.map(([x, z]) => ({ x, z, ...classify(x, z) })); + const onRoad = per.filter(q => q.cls === 'djsim-road'); + // ── DETECTOR CONTROLS: the classifier must be able to SAY 'road' and to SAY 'footpath' on this + // boot, or "0 posters on road" is a sentence about nothing. Sample the centreline of the + // longest main edge (must be road) and a point just outboard of its kerb (must be footpath). + const nodes = new Map(P.plan.streets.nodes.map(n => [n.id, n])); + let best = null, bestL = -1; + for (const e of P.plan.streets.edges) { + if (e.kind !== 'main') continue; + const a = nodes.get(e.a), b = nodes.get(e.b); if (!a || !b) continue; + const L = Math.hypot(b.x - a.x, b.z - a.z); + if (L > bestL) { bestL = L; best = { e, a, b }; } + } + let centre = null, band = null, outboard = null, edgeInfo = null; + if (best) { + const { e, a, b } = best; + const mx = (a.x + b.x) / 2, mz = (a.z + b.z) / 2; + const dx = (b.x - a.x) / bestL, dz = (b.z - a.z) / bestL; + const px = -dz, pz = dx; // perpendicular + centre = { at: [+mx.toFixed(2), +mz.toFixed(2)], ...classify(mx, mz) }; + const inner = (P.plan.__vb || null); // not published; derive from the edge + const half = e.width / 2; + // 1 m inboard of the corridor edge — under the RULING this is footpath, pre-ruling it is road + const ox = mx + px * (half - 1), oz = mz + pz * (half - 1); + outboard = { at: [+ox.toFixed(2), +oz.toFixed(2)], offset: +(half - 1).toFixed(2), ...classify(ox, oz) }; + edgeInfo = { kind: e.kind, width: e.width, len: +bestL.toFixed(1) }; + } + const tally = {}; + for (const q of per) tally[q.cls] = (tally[q.cls] || 0) + 1; + return { posters: rendered.length, planPosters: planned.length, matched, worstDelta: +worstDelta.toFixed(4), + groundMeshes: meshes.length, tally, onRoad: onRoad.length, + onRoadSample: onRoad.slice(0, 4).map(q => ({ x: q.x, z: q.z, y: q.y })), + centre, outboard, edgeInfo }; +} +""" + + +def _kerb_measure(p, query, label): + b, pg, errs = new_page(p) + try: + boot(pg, query) + pg.evaluate("() => window.DBG.setSegment(2)") + pg.wait_for_timeout(400) + r = pg.evaluate(_KERB_JS) + r['errs'] = errs + r['label'] = label + return r + finally: + b.close() + + +def smoke_kerb(p): + """[R37 item 0.1, Lane F half] THE KERB IS FOOTPATH — the runtime gate, and its control. + + Measured on the PAINT, not on the plan: raycast straight down at every rendered poster and + classify the topmost ground hit by the cached `skins.groundMat()` material instance itself. + Lane A's corrected selfcheck asks the plan-side question and pins the pre-ruling failure at + exactly 14; this asks whether the player is looking at bitumen under the poster, which is a + number that comes from Lane B's geometry and from nowhere else. + + Arms: + 1. SUBJECT — posters exist on the default boot, and the RENDERED InstancedMesh matrices agree + with `plan.posters` to 1 cm (nobody had ever asserted that the poster you see is the poster + A placed). Zero posters ⇒ FAIL, never a skip. + 2. DETECTOR CONTROLS — the classifier must be able to return 'road' AND 'footpath' on this + boot: the centreline of the longest main edge must classify as road, and a point 1 m inboard + of the corridor edge must classify as footpath. Without this pair, "0 posters on road" could + be true because the detector never says road. + 3. THE RULING — 0 posters stand on road paint on the default boot. + 4. THE CONTROL — the SAME leg under `?verge=0` must FAIL, at exactly 14 (Lane A's pinned + pre-ruling count, and B's flag reverts to byte-identical pre-ruling vertices). Keyed to the + FLAG, not to a line number, exactly as A keyed its own control. + 5. CLASSIC KEEPS ITS PAINT (Fable's mid-round ruling) — under `?classic=1` the same outboard + sample must still classify as ROAD, i.e. the covenanted town's render did not move.""" + head('SMOKE: the kerb (R37 0.1 — poster clearance measured on the paint · ?verge=0 is the control)') + + d = _kerb_measure(p, '', 'default') + v = _kerb_measure(p, 'verge=0', '?verge=0') + + # ── arm 1: the subject, and rendered == planned ─────────────────────────────────────────── + if not d['posters']: + FAIL('kerb: ZERO rendered posters on the default boot — the gate has no subject and FAILS ' + '(it does not skip). Expected the gig layer default-on since R16.') + return + if d['posters'] == d['planPosters'] and d['matched'] == d['posters']: + OK(f"subject: {d['posters']} posters rendered == {d['planPosters']} in plan.posters, every one " + f"within {d['worstDelta']} m of its planned position (the poster you see IS the poster A placed)") + else: + FAIL(f"kerb: rendered posters do not match the plan — {d['posters']} rendered / " + f"{d['planPosters']} planned / {d['matched']} matched, worst delta {d['worstDelta']} m") + + # ── arm 2: the detector can say both words ──────────────────────────────────────────────── + c, o, ei = d.get('centre'), d.get('outboard'), d.get('edgeInfo') + if not c or not o: + FAIL('kerb: no main edge to calibrate the surface detector against') + else: + if c['cls'] == 'djsim-road': + OK(f"detector control A: the centreline of the longest main ({ei['kind']}@{ei['width']} m, " + f"{ei['len']} m) classifies as ROAD at y={c['y']} — the detector can see bitumen") + else: + FAIL(f"detector control A: a main-edge CENTRELINE classifies as '{c['cls']}', not road — " + f"the surface detector is not measuring what it thinks ({c})") + if o['cls'] == 'djsim-footpath': + OK(f"detector control B: {o['offset']} m off that centreline (1 m inboard of the corridor " + f"edge) classifies as FOOTPATH at y={o['y']} — THE RULING IS IN THE PAINT") + else: + FAIL(f"detector control B: {o['offset']} m off the main centreline classifies as " + f"'{o['cls']}', expected footpath — the kerb ruling is not in the geometry ({o})") + + # ── arm 3: the ruling ───────────────────────────────────────────────────────────────────── + if d['onRoad'] == 0: + OK(f"THE RULING HOLDS: 0 of {d['posters']} posters stand on road paint on the default boot " + f"(surface tally {d['tally']})") + else: + FAIL(f"KERB RULING BREACHED: {d['onRoad']} of {d['posters']} posters stand on road paint on the " + f"default boot — {d['onRoadSample']} (tally {d['tally']})") + + # ── arm 4: THE CONTROL — the same leg, under ?verge=0, must go red at exactly 14 ─────────── + if v.get('posters') != d['posters']: + FAIL(f"kerb control: ?verge=0 changed the POSTER population ({v.get('posters')} vs {d['posters']}) " + f"— it is a render flag and must not touch the plan; the control is not comparable") + elif v['onRoad'] == 0: + FAIL('kerb CONTROL FAILED: ?verge=0 reverts to the pre-ruling street and the clearance leg ' + 'still passes there — the leg is blind to where the road is painted, which is the exact ' + 'vacuous species this item was opened to retire') + elif v['onRoad'] == 14: + OK(f"CONTROL: the same leg FAILS under ?verge=0 at EXACTLY 14 posters on road paint — Lane A's " + f"pinned pre-ruling count, reproduced at runtime off Lane B's geometry (tally {v['tally']})") + else: + WARN(f"kerb control goes red under ?verge=0 as required, but at {v['onRoad']} posters, not the " + f"pinned 14 (A: selfcheck, plan-side; F: raycast, paint-side). Both are non-zero so the leg " + f"is falsifiable; the count needs reconciling — sample {v['onRoadSample']}, tally {v['tally']}") + + # ── arm 5: CLASSIC KEEPS ITS PAINT (Fable's mid-round ruling) ───────────────────────────── + cl = _kerb_measure(p, 'classic=1', '?classic=1') + co = cl.get('outboard') + if not co: + FAIL('kerb/classic: no main edge to sample') + elif co['cls'] == 'djsim-road': + OK(f"CLASSIC KEEPS ITS PAINT: {co['offset']} m off the main centreline is still ROAD under " + f"?classic=1 (footpath on the default boot at the same point) — the covenanted render did " + f"not move on a render-side ruling") + else: + FAIL(f"?classic=1 ADOPTED the kerb ruling: {co['offset']} m off the centreline classifies as " + f"'{co['cls']}', expected road. Fable ruled classic is FENCED, not amended ({co})") + if cl['posters']: + FAIL(f"?classic=1 rendered {cl['posters']} posters — the gig layer leaked into the covenant") + + for r in (d, v, cl): + if r.get('errs'): + FAIL(f"kerb/{r['label']}: {len(r['errs'])} console error(s); first: {r['errs'][0][:140]}") + + def smoke_audio(p): """R11 audio house-law (Lane F): silent-and-happy, nothing plays pre-gesture, ?mute=1 silences, ?noassets=1 fetches zero audio, and interior beds play + release AudioNodes across enter/exit. @@ -3223,7 +3440,8 @@ def main(): smoke_booktoy(p) # STRICT (r9) — book/toy real stock smoke_presence(p) # new (warn) — interior presence (browsers) smoke_shelfbuy(p) # new (warn) — buy-anywhere (book/toy shelves) - smoke_tram(p) # new (warn) — tram (auto-skips if not landed) + smoke_tram(p) # [R37 0.2] REBUILT STRICT — runs where it runs, genuinely absent where fenced + smoke_kerb(p) # [R37 0.1] THE KERB IS FOOTPATH — poster clearance on the paint + the ?verge=0 control smoke_audio(p) # R11 — audio house-law (silent-happy · pre-gesture · mute · noassets · leak) smoke_gigs(p) # R12/13 — the district gig layer (schedule · band · crowd · budget · cover · noassets) smoke_continuity(p) # R15 — identity continuity (the ped you followed is in the crowd · settled tris)