re: F5 survives the full-quad reader, measured rather than asserted
Last iteration I asserted F5 was unaffected by the truncating-reader bug because it compared like with like. Asserting that is the move that produced the bug, so this measures it. The new reader sees 9.7 quads/frame vs ~7.5. Scalar that needs no element identification: quads mid-ramp (0<a<250) per frame goes 6,4,4,4,2,1,4,3 -> 0 at f436, while the control never reaches 0 anywhere in 48 frames of build-in. One frame with nothing part-way through a ramp is the cut. Bonus the old reader could not show: both sweeps enter at f436-438 at their declared opening alphas -- pteff03 at 255, pteff03a at 1,2,3,4,6,11,17 from its declared 0. Refutation attempt on the port's "clock jumps to 236.0": tried and failed. My bound is [100,238), which contains 236 -- consistent, not independent confirmation. Adds tools/re-capture/read_draws.py so the truncating regex is not re-rolled. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jc4pciRArGHfxGGhEbwp5t
This commit is contained in:
63
docs/re/f5-verified-with-full-quad-reader.md
Normal file
63
docs/re/f5-verified-with-full-quad-reader.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# F5 re-verified with a reader that sees every quad — the snap holds
|
||||
|
||||
**Question:** does F5's "Ⓐ snaps the whole title" survive a reader that reads
|
||||
every quad, not the first vertex of each draw?
|
||||
|
||||
**What the human looks at:** nothing new — this re-checks an answer already
|
||||
given. Pass = the snap conclusion is unchanged.
|
||||
|
||||
**What this does NOT cover:** the snap target's exact instant, F6.
|
||||
|
||||
**Instrument:** ⟨capture⟩ — same three logs, re-read by
|
||||
[`tools/re-capture/read_draws.py`](../../tools/re-capture/read_draws.py).
|
||||
|
||||
## Why re-check
|
||||
|
||||
[`f6-unit11`](f6-unit11-pteff03a-IS-drawn.md) found my reader took the first
|
||||
`v:` per draw line and dropped the rest, which killed two findings. I asserted
|
||||
F5 was unaffected because it compared like with like. **Asserting that is the
|
||||
same move that produced the bug**, so it is measured here instead. The new
|
||||
reader finds **9.7 quads/frame against ~7.5**.
|
||||
|
||||
## ✅ Measured — it holds, and it is sharper than before
|
||||
|
||||
Count of quads **mid-ramp** (`0 < α < 250`) per frame:
|
||||
|
||||
| | mid-ramp quads |
|
||||
|---|---|
|
||||
| press run, f428…f435 | 6 · 4 · 4 · 4 · 2 · 1 · 4 · 3 |
|
||||
| **press run, f436** | **0** |
|
||||
| control `f6b`, 48 frames of build-in | **never 0** (min 2) |
|
||||
|
||||
One frame in which **nothing on screen is part-way through a ramp** — every
|
||||
element at a settled alpha at once. The control never does this anywhere in its
|
||||
build-in. That is the cut, on a scalar that needs no element identification.
|
||||
|
||||
The count rises again after (1 · 2 · 2 · 2 · 3) because the snap **restarts the
|
||||
leaves**: both sweeps then run their own ramps from their own `t=0`.
|
||||
|
||||
## ✅ A bonus the old reader could not show
|
||||
|
||||
At f436–f438 **both** sweeps enter, each at its declared opening alpha:
|
||||
|
||||
* `pteff03` at x = −1.69, **α255** — its leaf declares α255 at `t=0`;
|
||||
* `pteff03a` at x = +1.99, **α1, 2, 3, 4, 6, 11, 17** — its leaf declares **α0**
|
||||
at `t=0` ramping to 128, and x = 1721 is the right-hand start.
|
||||
|
||||
Both leaves' declared openings, observed directly. This is the same page's
|
||||
`indices=8` batching that unit 11 uncovered.
|
||||
|
||||
## Refutation attempt — the port's "clock jumps 109.4 → 236.0"
|
||||
|
||||
The port reports a filmed boot showing the snap landing on **236.0**. I tried to
|
||||
contradict it and **could not**: at f436 the sweeps sit at α255, so the parent's
|
||||
declared ramp puts the title clock in `[100, 238)` — past `t=100` and before the
|
||||
`238…250` exit. 236.0 sits inside that. **Their figure survives**, but my data
|
||||
cannot separate 236 from 200; it is consistent, not independently confirmed.
|
||||
|
||||
## Not settled
|
||||
|
||||
* The snap target, still `[100,238)` from my side.
|
||||
* Whether any *other* finding of mine rests on the truncating reader. Unit 10's
|
||||
decomposition and the pulse ratio are the two candidates and are **not**
|
||||
re-checked here.
|
||||
67
tools/re-capture/read_draws.py
Executable file
67
tools/re-capture/read_draws.py
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Read a Xenia UI draw log -- EVERY quad, not the first vertex of each draw.
|
||||
|
||||
⚠️ THIS EXISTS BECAUSE THE OBVIOUS READER IS WRONG. A draw line carries
|
||||
`indices=N` vertices on ONE `v:` line, and N is routinely 8 -- two quads batched
|
||||
into a single draw. A reader that takes the first `v: [...]` match per line sees
|
||||
one of them and silently drops the rest.
|
||||
|
||||
That produced a clean, complete-looking negative twice in this corpus
|
||||
(`f6-unit5-pteff03a-never-drawn.md`, `f6-unit6-...`), both refuted by
|
||||
`f6-unit11-pteff03a-IS-drawn.md`. `REFUTED.md` L170 had already recorded a draw
|
||||
carrying two rotated parallelograms. Use this reader; do not re-roll the regex.
|
||||
|
||||
from read_draws import read
|
||||
frames = read(path) # {frame: [Quad, ...]} Quad = (page, verts, alpha, blend, cx)
|
||||
"""
|
||||
import re, collections
|
||||
|
||||
_F = re.compile(r'^--- frame (\d+) ')
|
||||
_TEX = re.compile(r'tex\[base=(0x[0-9A-F]+) (\d+)x(\d+) fmt=(\d+)(?: h=([0-9A-F]+))?\]')
|
||||
_IDX = re.compile(r'indices=(\d+)')
|
||||
_V = re.compile(r'\[(-?\d+\.\d+),(-?\d+\.\d+),z=[-\d.]+,col=([0-9A-F]{8})\]')
|
||||
|
||||
class Quad(tuple):
|
||||
__slots__ = ()
|
||||
def __new__(cls, page, verts, alpha, blend, cx):
|
||||
return tuple.__new__(cls, (page, verts, alpha, blend, cx))
|
||||
page = property(lambda s: s[0])
|
||||
verts = property(lambda s: s[1])
|
||||
alpha = property(lambda s: s[2])
|
||||
blend = property(lambda s: s[3])
|
||||
cx = property(lambda s: s[4])
|
||||
|
||||
def read(path):
|
||||
frames = collections.defaultdict(list)
|
||||
frame = page = blend = None
|
||||
idx = 0
|
||||
for line in open(path, errors='replace'):
|
||||
m = _F.match(line)
|
||||
if m:
|
||||
frame = int(m.group(1)); continue
|
||||
if frame is None:
|
||||
continue
|
||||
mt = _TEX.search(line)
|
||||
if mt:
|
||||
page = mt.group(5) or mt.group(1)
|
||||
mi = _IDX.search(line); idx = int(mi.group(1)) if mi else 0
|
||||
mb = re.search(r'blend=(0x[0-9A-F]+)', line); blend = mb.group(1) if mb else None
|
||||
continue
|
||||
if page is not None and ' v: ' in line:
|
||||
vs = _V.findall(line)
|
||||
# every group of 4 vertices is one quad; a partial tail is dropped
|
||||
for q in range(len(vs) // 4):
|
||||
quad = vs[q*4:(q+1)*4]
|
||||
cx = sum(float(v[0]) for v in quad) / 4
|
||||
frames[frame].append(Quad(page, [(float(a), float(b)) for a, b, _ in quad],
|
||||
int(quad[0][2][:2], 16), blend, round(cx, 3)))
|
||||
page = None
|
||||
return dict(frames)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
fr = read(sys.argv[1])
|
||||
ks = sorted(fr)
|
||||
tot = sum(len(v) for v in fr.values())
|
||||
print(f"{len(ks)} frames, {tot} quads, frames {ks[0]}..{ks[-1]}")
|
||||
print(f"mean quads/frame {tot/len(ks):.2f}")
|
||||
Reference in New Issue
Block a user