port: pin formats-pin-2026-08-29c -- the knob I tested last iteration was retired

I tested the wrong switch. SYLPHEED_KF_TIME_SHIFT is a superseded partial fix: it
got the association right but LEFT POSE 0 UNTIMED, which is exactly why the
untimed keyframe appeared to move from last to first. The real correction is the
DEFAULT in the tagged crate, with the old reading behind SYLPHEED_KF_TIME_LEGACY.
So last iteration's five rows measured a mismatch against a knob nobody should
use -- I suspected they were not decisive, I did not suspect the knob was retired.

THE CONSEQUENCE IS MUCH SMALLER THAN I BUDGETED. A placement group is an 8-byte
header then frames x {u32 time; 36-byte pose}, so pose 0's time is the group's
lead-in word and every pose is timed. Measured on the re-export: 866 keyframes,
0 untimed. `pose_at`'s "the final keyframe carries no t, so give it a synthetic
time" premise does not invert, it DISAPPEARS -- dead code rather than wrong code,
which is why nothing needed re-deriving. And the leaf now reads t=0 x=-639,
t=150 x=-39, t=540 x=1521, giving x=781 at t=355: the Decoder's predicted
top-left, and the 1300 px discrepancy is gone.

Pinned by tag, which is what MISSION section 2's tagging rule is for. BLOCKED was
wrong in both directions -- "cannot be taken yet" AND "only when that branch lands
on main". It arrives when the tag is pinned.

COST STATED: sylpheed-cli builds from the workspace crate, so until this reaches
main the exporter and the reference renderer read different decoders and
verify-screen compares two eras. verify-capture is unaffected -- it compares
against oracle captures and never touches the CLI. Revert to the path dependency
when the tag is an ancestor of main.

Oracle: publisher_logo 1.00% -> 0.75%, developer_logos 0.39% -> 0.33%, and
extras' differing region COLLAPSING from 736x525 to 398x295 at the sweep position
-- the residual localised onto the one element still in question. title unchanged
at 1.82%, now posed at t=355, the Decoder's FITTED sweep time. t=390 measures
1.65% and picking it would be fitting the pose to the score.

REFUTED, MINE: "ptlogo_eff2 is the single drawn element at a scale that is not a
whole multiple of 100%". That census was parents-only; the 45 leaves hold
thirteen distinct non-whole-multiple scales and 125% is among the rarest at two.
The claim's real content was "the only one the port draws" -- about my element
set, not the disc.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
Sylpheed port agent
2026-08-29 18:20:41 +00:00
parent 1380bbdcff
commit e5be03709a
5 changed files with 147 additions and 7 deletions

View File

@@ -52,7 +52,18 @@ CAPS=docs/re/captures/title-builds
MAP=(
"main_menu:$CAPS/live-main-menu.png:menu"
"extras:$CAPS/live-extras.png:menu"
"title:$CAPS/live-title-build4-no-plate.png:screen"
# ⚠️ THE TITLE IS POSED AT t=355 UNITS, NOT AT ITS SETTLE, and the time is
# MEASURED rather than chosen. The two `ptloop` sweeps are a continuous
# animation whose leaf group ends at t=600 with the quads parked off-screen at
# x=1521, so posing at the settle compares a still frame against a capture
# taken mid-sweep and simply omits them. The Decoder fitted t=355 from the
# game's own composed alpha -- per-draw vertex colours 195 and 182 against the
# two leaf ramps -- and the same t then predicted the quad centres to ~11 px.
#
# ⚠️ It is NOT the time that minimises the difference: t=390 measures 1.65 %
# against 1.82 % here. Picking that one would be fitting the pose to the
# score, which is the thing this harness exists not to do.
"title:$CAPS/live-title-build4-no-plate.png:t355"
"publisher_logo:$CAPS/live-splash-publisher.png:screen"
"developer_logos:$CAPS/live-splash-developer.png:screen"
)
@@ -72,6 +83,9 @@ for row in "${MAP[@]}"; do
godot --path port --resolution 1280x720 -- "--menu=$name" --script=wait \
"--shots=$OUT/$name" >"$OUT/$name.log" 2>&1 || true
[ -f "$OUT/${name}_00_start.png" ] && cp "$OUT/${name}_00_start.png" "$OUT/$name.render.png"
elif [ "$pose" = t355 ]; then
godot --path port --resolution 1280x720 -- "--screen=$name" --time=5.9167 \
"--capture=$OUT/$name.render.png" >"$OUT/$name.log" 2>&1 || true
else
godot --path port --resolution 1280x720 -- "--screen=$name" --time=99 \
"--capture=$OUT/$name.render.png" >"$OUT/$name.log" 2>&1 || true
@@ -84,7 +98,7 @@ for row in "${MAP[@]}"; do
note=""
case "$name" in
main_menu|extras) note="rendered with authored initial focus" ;;
title) note="ptloop sweeps never stop -- one moment vs another" ;;
title) note="posed at t=355, the Decoder's fitted sweep time" ;;
esac
# Where the difference lives. This comes FIRST because it is what the gamma
# sweep has to be protected from.