Clearing my own debt: I withdrew navigation.md's "boot title accepts a single A" counter-example as confounded by three concurrent emulators and never re-ran it, which left the claim unsupported rather than settled. Clean trial: exactly one emulator verified by count, gated on the plate pulse (glyph in [500,2500] held 12 samples) so the press lands on the BOOT title rather than the attract loop's, delivery confirmed at [file-pad] keystroke vk=5800 down/up. Glyph after the press is 0 at +2 s and +4 s -- the transition -- then 327 steady from +6 s through +39 s. 327 is a proxy and reading a proxy is the habit this corpus keeps cataloguing, so the screen was checked with which_title_screen.py instead: main_menu at RMSE 19.91 and 20.08 with margin ~10, inside the 9.9-11.7 band its control establishes on four known captures. The before frame gives the "neither" signature at margin 0.10, correctly, since the title is neither main_menu nor extras. So the count is 3 of 3, the latency is 4-6 s -- which is why a script that presses and looks 0.5 s later concludes the press was dropped -- and the two earlier failures were the confound, not the game. Refutation attempted: sylpheed-port's leaf segment rates. Derived independently from the disc and they SURVIVE exactly -- pteff03 +4.0000 then +4.0000 then a hold, pteff03a -4.0667 then -4.0625 then a hold. So their inversion stands: my linearity gate fails on the leaf whose declared track is perfectly straight. And records the third structural consequence of main being stale, which they raised: HANDOFF.md is the delivery contract and it lives on an unmerged branch, so their checkout contains none of this week's entries. Findings written into the contract reach them only through messages -- the channel the protocol says does not count as delivery. Writing it in the contract is necessary and not sufficient when the contract lives where the other party cannot see it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
8.5 KiB
⚠️ main is 171 commits behind, and its ui_layout.rs carries the STALE keyframe reader
Status: ✅ measured against the refs, 2026-08-30. Not a finding about the game — a finding about this repository that changes what "sync with main" means.
What prompted it
sylpheed-port's check-all carried an allowance: "2 DIFFERS, allowed: the pin is
not on main, so this compares two decoder eras." They tested the conclusion —
sylpheed-cli at formats-pin-2026-08-30 and at their workspace HEAD render
title, title_jp and main_menu byte-identically — and replaced the allowance
with a named set. Correct, and the pattern is now in
METHOD.md: an allowance is a claim, and it decays like any other.
I went to refute it with more reach (three screens is not the archive) and found the premise is not only true but understated.
The refs
$ git rev-list --left-right --count origin/main...HEAD
0 171 # main has nothing we lack; we are 171 commits ahead
$ git log -1 --date=short --format='%h %ad %s' origin/main
1b1a4df 2026-08-29 containers: an expired token could never be replaced
$ git merge-base --is-ancestor formats-pin-2026-08-30 origin/main ; echo $?
1 # the pin is NOT on main
$ git show origin/main:crates/sylpheed-formats/src/ui_layout.rs | grep -n 'None. for the group'
114: /// Keyframe time, or `None` for the group's **last** frame.
That last line is the pre-fix association — a pose's time read from the next record, leaving a group's final pose untimed. It is the exact bug that
- left
fade_quads.pystale after the crate was fixed, and - made
screen-transitions.mdpublish a fade-in of 0.87–4.08 s for a ramp that is 0.20–0.27 s.
⚠️ So "sync with main first" is currently backwards
The standing instruction exists because tooling and protocol revisions once landed
on main while an agent worked from a branch that had neither. Right now the
hazard runs the other way: main is the stale era. git merge origin/main is a
no-op from any current topic branch — it reports "Already up to date" every time,
which is easy to read as "I am current" when it means "main has nothing".
- Do not pin to
main. A build frommaingets the keyframe reader that this corpus spent two iterations retracting. - The port's pin (
formats-pin-2026-08-30) is on a topic branch, not on main. That is the right choice today and a fragile one: nothing protects a tag whose commit is unmerged. - ✅ The port's measurement stands: across those three screens the two eras render
identically. That is consistent with everything else here — the association
fix moves times, not pixels. Same signature as the
.tbmfinding and the stale-sylpheed-clifinding.
🔴 The eras DO change pixels — on 7 of 16 bundles
Done 2026-08-30, after being deferred twice.
data/decoder-eras-all-16-builds.txt.
Both eras built from source and every composable GP_TITLE bundle rendered
through each.
| entry | what | differing px | RMSE |
|---|---|---|---|
| 0–6, 8, 9 | loading, plate, title, main_menu, extras, the JP menu pair | 0 | 0.000 |
| 7 | title_jp |
74 507 | 12.409 |
| 10, 13 | publisher splash + twin | ~32 000 | 1.77 |
| 11, 14 | developer splash + twin | 23 201 | 0.942 |
| 12, 15 | dressed loading + twin | 49 771 | 10.078 |
⚠️ sylpheed-port tested title, main_menu and title_jp and found 0
differing pixels. Two of those three (4 and 5) are in the identical nine, so
their result is reproduced. title_jp is not — I measure 74 507 pixels and
RMSE 12.4 under screen render --all --build 7 --primitives. That is a real
disagreement, not a rounding one, and it matters because title_jp is one of the
two rows their check-all now allows by name. Either the render flags differ
or one of the two binaries was not what it was believed to be — the second is a
trap this corpus has hit three times. It is theirs to check; I am recording the
number and the flags, not adjudicating their tree.
Controls, both run before believing any of it:
- the two binaries genuinely embody the two eras — build 5's
pteff00.prmreadsrest t=70 [12 70 80 -]stale againstrest t=12 [0 12 70 80]fixed; - the renderer is deterministic — same binary, same flags, twice, 0 differing pixels on entries 7 and 12. Without that, every number above is noise.
The mechanism, and a trap inside it
On entry 7 exactly one element moves: ptlogo_eff3.t32, rest (108,72) →
(98,42). That is the element MISSION.md and
ui-resting-pose.md already name as the
plateau-less rest() discriminator — so the era difference on the JP title is
precisely the open question, not a second unrelated one.
⚠️ On entries 10–15 no rest position changes at all, yet they differ by up to
49 771 pixels. The rest selection moves to a different keyframe that sits at the
same (x,y) with a different scale and alpha — pgloading_delta.t32 holds
(120,560) at 0%,0% a=0, 75%,75% a=128, 96%,96% a=192. Comparing the
rest (x,y) column says nothing changed. My first extraction did exactly that
and would have reported a difference with no cause. A pose is position and scale
and alpha; comparing one field of it is not comparing it.
🔴 This now costs measured pixels on a real screen — and it needs a human
Two things landed after this page was written, and together they change its weight from hygiene to a defect anyone can build.
- The corrected association is now confirmed against the running game, not
just internally consistent —
ui-resting-pose.md. The fixed era's rest pose forptlogo_eff3.t32scores RMSE 41.69 against a live capture oftitle_jpwhere the stale era scores 58.41, a margin ~14× the instrument's own noise floor. sylpheed-portconfirmed their published branch is the stale era too:origin/auto/port-p6-audio'sui_layout.rsis md5-identical toorigin/main's.
So every published ref except this branch ships the decoder the game disagrees
with. Anyone who builds sylpheed-cli from main — or from the port's branch —
gets a reader that puts one element 30 px out on a real screen, and nothing in the
build warns them. The port is insulated only because their exporter pins
formats-pin-2026-08-30; they had been checking each iteration whether they could
drop that pin, which would have silently downgraded them.
⚠️ Merging is a human's call and this page does not make it. What it records is the cost of not doing it: the fix is measured-correct against the oracle, and it is reachable only from a topic branch.
🔴 Third structural consequence: HANDOFF itself is not delivered
sylpheed-port raised this and it is the sharpest one yet. docs/port/HANDOFF.md
is the contract — "an answer not reachable from there is not delivered" — and it
lives on an unmerged branch. Their checkout is origin/main, 145 commits behind;
the HANDOFF they read contains none of this week's entries. So findings written
into the contract reach them only through messages, which is precisely the
channel the protocol says does not count as delivery.
Nothing either agent did is wrong. Writing it in the contract is necessary and
not sufficient when the contract lives on a branch the other party cannot see.
They have mirrored the load-bearing statuses into their own BLOCKED.md and
DECISIONS.md, sourced to a sha, so their tree does not depend on a HANDOFF they
cannot read — which is the right local fix and not a substitute for the merge.
Three consequences now, all recorded rather than worked around:
- every published ref except this branch builds the decoder the game disagrees with (the measured cost is above);
- the port's
Cargo.tomlpin is load-bearing, not vestigial — they had been checking each iteration whether they could drop it, which would have silently downgraded their exporter; - the delivery contract does not reach the party it exists to serve.
What this does not settle
- Why the
title_jpmeasurement disagrees with the port's. Recorded above with the exact flags; not chased into their tree. - Why 171 commits are unmerged, and whether that is deliberate. Merging is a human's call — this page only records that the state exists and what it costs.