PROCITY/tools/qa/r39_transmission.py
m3ultra 076b972f71 Lane F R39 (v9 WAVE 1, CLOSE): QA GREEN 10/0/0/0 — and the interior margin is 162, not 21 and never 6
FIVE GATES, FIVE CONTROLS, each demonstrated in the same run. New F-owned tools wired into qa.sh as
Gate 8: r39_address.mjs · r39_transmission.py · r39_runtime.py · r39_shots.py (--no-r39 skips the
browser half). Lane A's selfcheck reproduces exactly: 157,647/157,647 ALL GREEN, fingerprint
0x5f76e76 — ZERO GOLDENS MOVED, in a round that added an address layer, a fog ledger, a spawn move
and a new interior fitting.

THE ROUND'S BIGGEST NUMBER IS NOT THE ONE THE LEDGER ASKED FOR. Two port-isolated no-store roots,
the same inode for every byte except one file — the shipped bookshelf GLB vs a copy with
transmissionFactor:1 re-inserted (BIN sha1 IDENTICAL, only the JSON chunk moved) — both through
interior_test.html's own drawSweep:

  GLB-on worst   329 (opshop/hall)  ->  188 (dept/auto)     -141
  GLB-off worst  162 (opshop/hall)  ->  162 (opshop/hall)   0 — the control's own control
  margin vs <=350            21     ->  162                 +141

opshop 329->174 (-47%) · book 247->125 (-49%) · every other type 0, exactly the shape Lane C
predicted from an isolated room, at sweep scale, by a harness C did not write. The worst interior
room in the game is now dept/auto — a room with no bookshelf in it. The default boot fetches these
GLBs from the public depot, so all four R39 GLBs were fetched off digalot.fyi and scanned: sha1
identical to the local tree, 0 transmissive materials, 4/4. Binding fact #3's third and final value.

39.1 ADDRESS — GREEN. 1,192/1,219 shops (97.8%), 23/23 'ways', 857/857 membership agree / 0 wrong
(and the control is asserted to have CHECKED 857 edges). No cache -> supplier 'district', 0 names,
still labels 72/72 from district+block. RED ARM: a 3 m shift error RAISES adelaide 89 -> 98 resolved
shops (Lane A's number to the digit) while INVENTING 9 names; stats().shiftCheck reads DISAGREE on
all 72 perturbations. And the honest limit: at 3 m the membership control reads 0 disagreements,
because those shops front ways OSM leaves unnamed — only the shift cross-derivation catches it.

39.2 FOG — GREEN, both arms on one boot. HIDES 4/72 at spawn, 0 of 61 distant shops known. REVEALS
2,125 m -> 58 shops. FRONT TEST: probe from 5 m BEHIND each of 59 unknown shopfronts, 0 learned.
+0 DRAWS AND +0 TRIS, four freshly launched browsers, both orders, drained, 3 reads each, with the
arms asserted distinguishable first. 8/8 corrupt saves rejected, state untouched. Null store on
classic/game=0/fog=0; game=0 and fog=0 pixel-identical, default differs.

39.3 THE SIGN — GREEN. Shops in front of the player at spawn: 4/4 · 4/4 · 4/4 · 1/1, and ZERO on all
four with the pre-R39 sign re-derived on the same tree. The live spawn is asserted equal to the +sin
derivation, so the shell is what is scored. Re-baselined WITHOUT falsifying a release record: the
v7 tour and v7-beta frames are kept as history; docs/shots/laneF_r39/ ships the new pair with its
own BEFORE. The R35 gate itself is pose-independent and was green either side.

39.4 RUMMAGE BIN — GREEN. 120 rooms: tub 60/60 both arms, kind:'bin' 0/60 default vs 60/60 armed,
0 carves, 60/60 deterministic, reachable 0.80-1.03 m by a flood fill written here. THE CONTENTS DID
NOT SHIP: on the default street boot the tub is kind:'prop', 0 dig targets, E opens nothing.

39.5 TRANSMISSION VALIDATOR — GREEN and it FIRES: hard-fails rc 1 on the fabricated glass asset AND
passes on the shipped tree.

THREE CORRECTIONS, ALL MEASURED. A's "a 30 m shift returns 0 street names" — it returns 40/12/47
wrong ones; a big shift lands you on the next street, it does not degrade to null. B's "a fresh
export has no `known` key" — true of ?fog=0, no longer of a default boot, because B's own +sin fix
means you spawn in front of four shopfronts. And my own: I first aimed the transmission control at
web/assets/models/ when validate_manifest.py reads pipeline/_normalized/, and nearly filed a defect
against Lane E on the strength of it. Aim the control at the code path, not the plausible path.

HELD -> LANE E: check_transmission() skips any GLB with no local _normalized copy and never scans
web/assets/models/. Demonstrated with a live control — remove the local copy and the same glass
asset passes rc 0. A depot-only transmissive GLB (the exact shape of longbench and streetlight)
would ship unseen.

No tag.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 22:47:03 +10:00

291 lines
16 KiB
Python

#!/usr/bin/env python3
"""PROCITY Lane F — R39 §39.5 gate E: THE TRANSMISSION PRE-PASS, measured on both sides.
Lane E stripped `transmissionFactor: 1` from three GLBs (`bookshelf` shipped, `longbench` +
`streetlight` unwired) because three.js runs a **transmission pre-pass** when any material in the
scene has `transmission > 0` — `renderTransmissionPass()` renders the whole opaque list a second
time, so every opaque draw is issued twice. Lane C measured `opshop`/hall 191 -> 104 by zeroing it.
**That measurement is the falsifiable arm and this tool runs it.** Two port-isolated no-store roots,
identical inode-for-inode EXCEPT one file:
· TREATMENT — the shipped tree (E's stripped bookshelf)
· CONTROL — the same tree with `transmissionFactor: 1` REINSERTED into that one material,
fabricated here (JSON chunk rewritten, BIN copied through byte for byte)
…both driven through `interior_test.html`'s own `drawSweep` — the >=350-draw law's own instrument —
with `?localdepot=1` so the GLB comes off the served root and the swap is the only variable.
The fabricated glass GLB doubles as the validator's control asset: `--validator` points
`pipeline/validate_manifest.py` at a root containing it and asserts the R39 HARD FAIL fires.
Run: tools/.venv/bin/python tools/qa/r39_transmission.py [--validator] [--json OUT]
"""
import sys, os, json, time, socket, struct, shutil, subprocess, pathlib, tempfile
ROOT = pathlib.Path(__file__).resolve().parent.parent.parent
PORT_TREAT = int(os.environ.get('PROCITY_R39_PORT', '8741'))
PORT_CTRL = PORT_TREAT + 1
BOOKSHELF = 'procity_fit_bookshelf_01.glb'
MATERIAL = 'mtl_10218_Bookshelves_v1'
fails, notes = [], []
def FAIL(m): fails.append(m); print(f" \033[31m✗ FAIL\033[0m {m}")
def OK(m): print(f" \033[32m✓\033[0m {m}")
def head(m): print(f"\n\033[1m{m}\033[0m")
# ── GLB surgery (the same shape as pipeline/strip_transmission.py, run in reverse) ────────────────
def glb_chunks(data):
assert data[:4] == b'glTF', 'not a GLB'
off, out = 12, []
while off < len(data):
ln, ty = struct.unpack_from('<II', data, off); off += 8
out.append((ty, data[off:off + ln])); off += ln
return out
def glb_json(path):
for ty, payload in glb_chunks(pathlib.Path(path).read_bytes()):
if ty == 0x4E4F534A:
return json.loads(payload.decode('utf-8'))
raise AssertionError('no JSON chunk')
def transmissive_materials(path):
"""[(material name, factor)] for every material with transmissionFactor > 0."""
j = glb_json(path)
hits = []
for m in j.get('materials', []):
t = (m.get('extensions') or {}).get('KHR_materials_transmission')
if t and float(t.get('transmissionFactor', 0)) > 0:
hits.append((m.get('name'), float(t['transmissionFactor'])))
return hits
def make_glass(src, dst, material=None, factor=1.0):
"""Write `dst` = `src` with KHR_materials_transmission reinserted. BIN copied through unchanged;
the function returns (sha1_bin_src, sha1_bin_dst) so the caller can prove only JSON moved."""
import hashlib
data = pathlib.Path(src).read_bytes()
chunks = glb_chunks(data)
j = None; binp = b''
for ty, payload in chunks:
if ty == 0x4E4F534A: j = json.loads(payload.decode('utf-8'))
elif ty == 0x004E4942: binp = payload
touched = []
for m in j.get('materials', []):
if material and m.get('name') != material: continue
m.setdefault('extensions', {})['KHR_materials_transmission'] = {'transmissionFactor': factor}
touched.append(m.get('name'))
if material: break
used = j.setdefault('extensionsUsed', [])
if 'KHR_materials_transmission' not in used: used.append('KHR_materials_transmission')
jb = json.dumps(j, separators=(',', ':')).encode('utf-8')
jb += b' ' * ((4 - len(jb) % 4) % 4)
bb = binp + b'\x00' * ((4 - len(binp) % 4) % 4)
total = 12 + 8 + len(jb) + (8 + len(bb) if binp else 0)
out = bytearray(b'glTF' + struct.pack('<II', 2, total))
out += struct.pack('<II', len(jb), 0x4E4F534A) + jb
if binp: out += struct.pack('<II', len(bb), 0x004E4942) + bb
pathlib.Path(dst).write_bytes(bytes(out))
return touched, hashlib.sha1(binp).hexdigest(), hashlib.sha1(bb).hexdigest()
# ── servers ──────────────────────────────────────────────────────────────────────────────────────
def port_up(port):
with socket.socket() as s:
s.settimeout(0.4); return s.connect_ex(('127.0.0.1', port)) == 0
NOSTORE = r'''
import sys, http.server, functools
class H(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate')
self.send_header('Pragma', 'no-cache')
super().end_headers()
def log_message(self, *a): pass
http.server.HTTPServer(('127.0.0.1', int(sys.argv[1])),
functools.partial(H, directory=sys.argv[2])).serve_forever()
'''
def serve(root, port):
proc = subprocess.Popen([sys.executable, '-c', NOSTORE, str(port), str(root)],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
for _ in range(80):
if port_up(port): return proc
time.sleep(0.1)
proc.terminate(); raise SystemExit(f'could not serve {root} on :{port}')
def mirror_except(src, path_parts, replacement):
"""A temp mirror of `src` in which every entry is a SYMLINK to the original except the single
file at `path_parts`, which is a copy of `replacement`. Only the directories on that path are
real; everything else is the same inode, so the one file is the only variable."""
dst = pathlib.Path(tempfile.mkdtemp(prefix='procity-r39-mirror-'))
def walk(s, d, parts):
d.mkdir(parents=True, exist_ok=True)
for e in pathlib.Path(s).iterdir():
if parts and e.name == parts[0]:
if len(parts) == 1: shutil.copy2(replacement, d / e.name)
else: walk(e, d / e.name, parts[1:])
else:
(d / e.name).symlink_to(e)
walk(src, dst, list(path_parts))
return dst
def glass_root(glb_name=BOOKSHELF, material=MATERIAL):
"""web/ mirrored symlink-for-symlink EXCEPT assets/models/<glb_name>, which is the fabricated
glass copy. Every other byte the browser sees is the same inode."""
d = pathlib.Path(tempfile.mkdtemp(prefix='procity-r39-glass-'))
src = ROOT / 'web'
for e in src.iterdir():
if e.name != 'assets': (d / e.name).symlink_to(e)
a = d / 'assets'; a.mkdir()
for e in (src / 'assets').iterdir():
if e.name != 'models': (a / e.name).symlink_to(e)
m = a / 'models'; m.mkdir()
for e in (src / 'assets' / 'models').iterdir():
if e.name != glb_name: (m / e.name).symlink_to(e)
touched, s0, s1 = make_glass(src / 'assets' / 'models' / glb_name, m / glb_name, material)
return d, touched, s0, s1
# ── the sweep ────────────────────────────────────────────────────────────────────────────────────
def sweep(pg, host, glb):
pg.goto(f'{host}/interior_test.html?localdepot=1')
pg.wait_for_function('() => !!window.PROCITY_C', timeout=30000)
pg.wait_for_timeout(600)
return pg.evaluate('(glb) => window.PROCITY_C.drawSweep({ glb })', glb)
def main():
from playwright.sync_api import sync_playwright
want_validator = '--validator' in sys.argv
out_json = None
if '--json' in sys.argv: out_json = sys.argv[sys.argv.index('--json') + 1]
result = {}
head('GATE R39 §39.5-E: THE TRANSMISSION PRE-PASS — the shipped tree vs a fabricated glass control')
shipped = ROOT / 'web' / 'assets' / 'models' / BOOKSHELF
hits = transmissive_materials(shipped)
if hits: FAIL(f'the SHIPPED {BOOKSHELF} still carries transmission: {hits}')
else: OK(f'shipped {BOOKSHELF}: 0 transmissive materials (E\'s strip is in the served tree)')
gdir, touched, sha_src, sha_dst = glass_root()
result['glassMaterials'] = touched
if touched == [MATERIAL] and sha_src == sha_dst:
OK(f'control asset fabricated: {touched[0]} transmissionFactor 1 · BIN sha1 IDENTICAL ({sha_src[:12]}…) — only the JSON chunk moved')
else:
FAIL(f'control asset fabrication wrong: touched={touched} binSha {sha_src[:12]} vs {sha_dst[:12]}')
gh = transmissive_materials(gdir / 'assets' / 'models' / BOOKSHELF)
if gh: OK(f'control asset re-scans DIRTY, as intended: {gh}')
else: FAIL('control asset did not take the transmission flag — the control is vacuous')
# ── the validator's hard fail, proven to FIRE (E's gate) ──────────────────────────────────────
if want_validator:
head('the validator control — pipeline/validate_manifest.py must HARD FAIL on the glass asset')
# validate_manifest.py reads pipeline/_normalized/<file> (NOT web/assets/models/), so the
# control asset has to land THERE or the gate is being pointed at a file it never opens.
# My own first cut patched web/assets/models/ and the control reported "did not fire" — the
# harness bug, not E's gate. Recorded because it is exactly the species this round is about.
vroot = mirror_except(ROOT, ('pipeline', '_normalized', BOOKSHELF),
gdir / 'assets' / 'models' / BOOKSHELF)
r = subprocess.run([sys.executable, 'pipeline/validate_manifest.py'],
cwd=str(vroot), capture_output=True, text=True)
blob = r.stdout + r.stderr
result['validator'] = {'rc': r.returncode, 'mentions': 'transmissionFactor' in blob or 'transmission' in blob.lower()}
if r.returncode != 0 and 'transmission' in blob.lower():
line = next((l for l in blob.splitlines() if 'transmission' in l.lower()), '')
OK(f'validator HARD FAILS on the glass asset (rc {r.returncode}): {line.strip()[:150]}')
else:
FAIL(f'validator did NOT fail on a transmissive GLB (rc {r.returncode}) — E\'s gate is vacuous')
r2 = subprocess.run([sys.executable, 'pipeline/validate_manifest.py'],
cwd=str(ROOT), capture_output=True, text=True)
if r2.returncode == 0: OK('validator PASSES on the shipped tree (the positive control — the gate is not simply always-red)')
else: FAIL(f'validator red on the shipped tree: {(r2.stdout + r2.stderr)[-300:]}')
# ...and the gate's OWN blind spot, measured rather than assumed: check_transmission()
# returns silently when pipeline/_normalized/<file> is absent, so a depot-only GLB is never
# parsed. Demonstrated by deleting the local copy and re-running with the glass file live.
vroot2 = mirror_except(ROOT, ('pipeline', '_normalized', BOOKSHELF), gdir / 'assets' / 'models' / BOOKSHELF)
(vroot2 / 'pipeline' / '_normalized' / BOOKSHELF).unlink()
r3 = subprocess.run([sys.executable, 'pipeline/validate_manifest.py'],
cwd=str(vroot2), capture_output=True, text=True)
result['validatorDepotOnly'] = {'rc': r3.returncode}
if r3.returncode == 0:
notes.append('validate_manifest.py check_transmission() SKIPS any GLB with no local '
'pipeline/_normalized copy — a depot-only transmissive asset passes silently. '
'(web/assets/models/, which ?localdepot=1 actually serves, is never scanned either.)')
print(f" \033[33mnote\033[0m the validator's own blind spot, demonstrated: with the local "
f"_normalized copy removed the same glass asset passes (rc {r3.returncode}) — the check is "
f"local-file-only. Ask filed to Lane E.")
shutil.rmtree(vroot2, ignore_errors=True)
shutil.rmtree(vroot, ignore_errors=True)
if '--no-sweep' in sys.argv:
shutil.rmtree(gdir, ignore_errors=True)
print()
if fails: print(f"\033[31m{len(fails)} FAIL\033[0m"); return 1
print("\033[32mvalidator arm GREEN\033[0m"); return 0
# ── the sweep, both roots ─────────────────────────────────────────────────────────────────────
head('the interior draw sweep — 12 types x 7 archetypes, GLB off and on, on both roots')
p_t = serve(ROOT / 'web', PORT_TREAT)
p_c = serve(gdir, PORT_CTRL)
try:
with sync_playwright() as p:
b = p.chromium.launch()
pg = b.new_page(viewport={'width': 1280, 'height': 720})
errs = []
pg.on('console', lambda m: errs.append(m.text) if m.type == 'error' else None)
for name, port in (('treatment', PORT_TREAT), ('control_glass', PORT_CTRL)):
host = f'http://127.0.0.1:{port}'
off = sweep(pg, host, False)
on = sweep(pg, host, True)
result[name] = {'glbOff': off, 'glbOn': on}
print(f" {name:14s} GLB-off worst {off['worst']:4d} ({off['worstAt']}) "
f"GLB-on worst {on['worst']:4d} ({on['worstAt']})")
b.close()
finally:
p_t.terminate(); p_c.terminate(); shutil.rmtree(gdir, ignore_errors=True)
t_on = result['treatment']['glbOn']; c_on = result['control_glass']['glbOn']
t_off = result['treatment']['glbOff']; c_off = result['control_glass']['glbOff']
delta = c_on['worst'] - t_on['worst']
result['summary'] = {'glbOnWorst': t_on['worst'], 'glbOnWorstAt': t_on['worstAt'],
'glassWorst': c_on['worst'], 'glassWorstAt': c_on['worstAt'],
'saved': delta, 'law': t_on['law'],
'marginTreatment': t_on['law'] - t_on['worst'],
'marginGlass': c_on['law'] - c_on['worst'],
'glbOffWorst': t_off['worst'], 'glbOffWorstAt': t_off['worstAt']}
head('the verdict')
print(f" GLB-on worst room · with E's fix: {t_on['worst']} ({t_on['worstAt']}) "
f"· with transmission restored: {c_on['worst']} ({c_on['worstAt']}) saved {delta}")
print(f" GLB-off worst room · {t_off['worst']} ({t_off['worstAt']}) vs {c_off['worst']} ({c_off['worstAt']}) "
f"(a GLB-off room loads no GLB, so this pair MUST be equal — it is the control's own control)")
if delta > 0: OK(f"the pre-pass is real and E's fix took it out: {c_on['worst']} -> {t_on['worst']} draws (-{delta}, -{100*delta/max(1,c_on['worst']):.0f}%)")
else: FAIL(f"the sweep did NOT drop with transmission stripped (delta {delta}) — E's fix is not reaching the served tree")
if t_off['worst'] == c_off['worst']: OK(f"GLB-off is identical on both roots ({t_off['worst']}) — the delta above is the GLB and nothing else")
else: FAIL(f"GLB-off differs between roots ({t_off['worst']} vs {c_off['worst']}) — the two roots are not otherwise identical")
if t_on['worst'] <= t_on['law']: OK(f"the >=350 law holds with {t_on['law'] - t_on['worst']} draws of margin (was {c_on['law'] - c_on['worst']} with the glass bookshelf)")
else: FAIL(f"the shipped tree BREACHES the {t_on['law']}-draw interior law at {t_on['worst']}")
per = [(k, c_on['perType'].get(k, 0), t_on['perType'].get(k, 0)) for k in t_on['perType']]
print('\n per type (GLB-on worst archetype): glass -> fixed')
for k, c, t in sorted(per, key=lambda r: -(r[1] - r[2])):
print(f" {k:10s} {c:4d} -> {t:4d} {t - c:+d}")
if out_json: pathlib.Path(out_json).write_text(json.dumps(result, indent=1))
print()
if fails:
print(f"\033[31m{len(fails)} FAIL\033[0m"); return 1
print("\033[32mR39 §39.5-E GREEN\033[0m"); return 0
if __name__ == '__main__':
sys.exit(main())