They proposed the test and said they had not run it. It needs the port's render
beside the capture, so it was mine: a shift makes the signed residual track the
gradient (and the fitted slope is the shift in pixels), a blur makes it track the
laplacian. New tool, tools/port/edge-residual-kind.
Controls first, and they are not optional: a known +1 px shift reads back as
+0.938 px (r +0.789), a known blur as r -0.896 on the laplacian, neither leaking
into the other's channel.
Result: -0.010 px, -0.009 px, laplacian r +0.103. Flat. Any whole-frame
translation is under a hundredth of a pixel, and the weak blur term has the
opposite sign to the blur control. Misregistration is excluded.
Reach: whole-frame fit. One misplaced element is a small share of 38 752 edge
pixels and would not move these numbers -- this excludes a GLOBAL translation,
not a local one. A misplaced soft element remains untouched.
Exit codes 0 or 2, no 1 -- it classifies, it does not judge. The control-failure
branch verified by raising the thresholds: report suppressed, exit 2.
Also: GP_DIALOG 2/3 restored to authored/flow.json. I declined to re-add it on a
relay; they have now taken the ja capture (HANDOFF at 5a7f34d) -- 1.82 % of pixels
in four bands, EASY/NORMAL/HARD not among them because JP keeps Latin script. My
objection stands as an objection: adjacency never implied a language pair, and 26
of 65 adjacent pairs differ in button count. The claim now rests on a capture
instead of on that inference.
139 lines
5.5 KiB
Python
Executable File
139 lines
5.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""What KIND of error is left at the edges after tone is accounted for?
|
|
|
|
tools/port/edge-residual-kind [screen] # default main_menu
|
|
|
|
`verify-capture`'s `diff` column thresholds at 25 % and so only sees GROSS
|
|
displacement. Fitting a per-level LUT removes everything a tone effect can
|
|
explain. What is left on the main menu is concentrated 3.2x on edge pixels
|
|
(DECISIONS.md, 2026-08-31) -- and three things produce that: a misregistration,
|
|
an antialiasing difference, or a genuinely misplaced element.
|
|
|
|
THE DISCRIMINATOR IS THE SIGN, and it is the Decoder's, from their reply on
|
|
2026-08-31: a shift gives a residual with a CONSISTENT DIRECTION along the edge,
|
|
an antialiasing difference does not. Made concrete:
|
|
|
|
* shifted by (dx,dy): residual ~ dx*d/dx + dy*d/dy -- and the fitted SLOPE
|
|
IS THE SHIFT IN PIXELS
|
|
* blurred/sharpened : residual ~ -k * laplacian -- symmetric, no direction
|
|
|
|
EXIT CODES. 0 the report is trustworthy, 2 A CONTROL FAILED so the numbers below
|
|
it mean nothing. There is no 1: this tool classifies, it does not judge. A
|
|
correlation this tool reports is worthless without the two controls above it,
|
|
which is why they are not optional and not a flag.
|
|
"""
|
|
import math, os, subprocess, sys, tempfile
|
|
|
|
CAPS = "docs/re/captures/title-builds"
|
|
SCREEN = sys.argv[1] if len(sys.argv) > 1 else "main_menu"
|
|
# The captures are a 1279x675 top-left crop of the 1280x720 guest surface, so the
|
|
# render is cropped to match and NOTHING IS SCALED -- resampling would manufacture
|
|
# exactly the edge signal this tool measures. See verify-capture, same reason.
|
|
W, H = 1279, 675
|
|
EDGE = 12 # |grad| above which a pixel is an edge
|
|
PASS_SHIFT, PASS_BLUR = 0.70, -0.70
|
|
|
|
|
|
def gray(png, out):
|
|
subprocess.run(["convert", png, "-colorspace", "Gray", "-depth", "8",
|
|
"gray:" + out], check=True)
|
|
return open(out, "rb").read()
|
|
|
|
|
|
def lutfit(a, b):
|
|
tot = [0] * 256; cnt = [0] * 256
|
|
for i in range(len(a)):
|
|
tot[a[i]] += b[i]; cnt[a[i]] += 1
|
|
return [(tot[v] // cnt[v]) if cnt[v] else v for v in range(256)]
|
|
|
|
|
|
def analyse(a, b):
|
|
lut = lutfit(a, b)
|
|
gx = []; gy = []; lp = []; rs = []
|
|
for y in range(1, H - 1):
|
|
o = y * W
|
|
for x in range(1, W - 1):
|
|
i = o + x
|
|
ax = (a[i + 1] - a[i - 1]) * 0.5
|
|
ay = (a[i + W] - a[i - W]) * 0.5
|
|
if abs(ax) + abs(ay) < EDGE:
|
|
continue
|
|
gx.append(ax); gy.append(ay)
|
|
lp.append(float(a[i + 1] + a[i - 1] + a[i + W] + a[i - W] - 4 * a[i]))
|
|
rs.append(float(lut[a[i]] - b[i]))
|
|
n = len(rs)
|
|
if n < 1000:
|
|
print(f" 🔴 only {n} edge pixels -- nothing to classify"); sys.exit(2)
|
|
mr = sum(rs) / n
|
|
|
|
def fit(u):
|
|
mu = sum(u) / n
|
|
suu = sum((v - mu) ** 2 for v in u)
|
|
srr = sum((v - mr) ** 2 for v in rs)
|
|
sur = sum((u[k] - mu) * (rs[k] - mr) for k in range(n))
|
|
return (0.0, 0.0) if suu <= 0 or srr <= 0 else (sur / suu, sur / math.sqrt(suu * srr))
|
|
return n, fit(gx), fit(gy), fit(lp)
|
|
|
|
|
|
def row(label, res):
|
|
n, (sx, rx), (sy, ry), (sl, rl) = res
|
|
print(f" {label} (n={n})")
|
|
print(f" horizontal shift : r={rx:+.3f} slope={sx:+.3f} px")
|
|
print(f" vertical shift : r={ry:+.3f} slope={sy:+.3f} px")
|
|
print(f" blur / sharpness : r={rl:+.3f} coef ={sl:+.3f}")
|
|
return rx, ry, rl
|
|
|
|
|
|
def shifted(a, dx):
|
|
out = bytearray(a)
|
|
for y in range(H):
|
|
for x in range(W):
|
|
out[y * W + x] = a[y * W + min(W - 1, max(0, x - dx))]
|
|
return bytes(out)
|
|
|
|
|
|
def blurred(a):
|
|
out = bytearray(a)
|
|
for y in range(1, H - 1):
|
|
o = y * W
|
|
for x in range(1, W - 1):
|
|
i = o + x
|
|
out[i] = (a[i] * 4 + a[i + 1] + a[i - 1] + a[i + W] + a[i - W]) // 8
|
|
return bytes(out)
|
|
|
|
|
|
tmp = tempfile.mkdtemp()
|
|
cap_png = f"{CAPS}/live-{SCREEN.replace('_', '-')}.png"
|
|
if not os.path.exists(cap_png):
|
|
print(f" 🔴 no capture: {cap_png}"); sys.exit(2)
|
|
render = os.environ.get("RENDER") or f"{tmp}/render.png"
|
|
if not os.path.exists(render):
|
|
print(f" 🔴 no render at {render} -- set RENDER=<png>"); sys.exit(2)
|
|
subprocess.run(["convert", render, "-crop", f"{W}x{H}+0+0", "+repage",
|
|
f"{tmp}/crop.png"], check=True)
|
|
r = gray(f"{tmp}/crop.png", f"{tmp}/r.gray")
|
|
c = gray(cap_png, f"{tmp}/c.gray")
|
|
|
|
print("CONTROLS -- the render against a deliberately damaged copy of itself.")
|
|
print("A correlation below is meaningless unless these two recover what was done.\n")
|
|
ra = analyse(r, shifted(r, 1))
|
|
rxa, _, rla = row("known +1 px HORIZONTAL shift", ra)
|
|
rb = analyse(r, blurred(r))
|
|
_, _, rlb = row("known BLUR, no shift", rb)
|
|
bad = []
|
|
if rxa < PASS_SHIFT: bad.append(f"shift control r={rxa:+.3f} < {PASS_SHIFT}")
|
|
if rlb > PASS_BLUR: bad.append(f"blur control r={rlb:+.3f} > {PASS_BLUR}")
|
|
if bad:
|
|
print("\n 🔴 CONTROL FAILED: " + "; ".join(bad))
|
|
print(" The discriminator cannot see what it is for. Report suppressed.")
|
|
sys.exit(2)
|
|
print(f"\n ✅ controls pass -- a 1 px shift reads as {ra[1][0]:+.3f} px\n")
|
|
print(f"THE REAL PAIR -- {SCREEN}\n")
|
|
rx, ry, rl = row(f"{SCREEN} render vs oracle capture", analyse(r, c))
|
|
print()
|
|
if max(abs(rx), abs(ry)) < 0.15 and abs(rl) < 0.3:
|
|
print(" => NEITHER a global shift NOR a uniform blur.")
|
|
print(" ⚠️ REACH: this is a WHOLE-FRAME fit. One misplaced element is a small")
|
|
print(" share of the edge pixels and would not move these numbers. This")
|
|
print(" excludes a global translation; it does not exclude a local one.")
|