re(ui): the rest fallback fires on 2 elements, and "last keyframe" wins there

Scored candidate rest-pose rules by rendering and correlating instead of
arguing, and both results correct something I had published.

First, the exposure. The guessing fallback is reached only by an element
that is plateau-less AND multi-keyframe -- a single-keyframe element
short-circuits at `match len { 1 => first }`. Per screen:

  title (4)               24 elements   2 plateau-less   0 reach the fallback
  main menu (5)           16            5                0
  EXTRAS (6)              18            5                0
  publisher splash (10)    3            2                1
  developer splash (11)    7            2                1

So on the three screens the port cares most about, rest() never guesses.
That is why three different rules render builds 4/5/6 to identical
correlations -- the code is unreachable there, which I nearly read as
"the choice does not matter".

Second, where it does fire, the last keyframe is markedly better:

  publisher splash   dwell +0.9600   last +0.9982   maxalpha +0.9600
  developer splash   dwell +0.9643   last +0.9758   maxalpha +0.9643

That refutes my own earlier refutation. I had killed the last-keyframe
rule by arguing it makes palogo_anima_eff invisible while its two
siblings stay lit, which looked like an artefact. The capture says
otherwise: making it invisible is what improves the match. The sibling
symmetry was my expectation, not evidence.

Caveat kept in front: both captures are single frames of a transient
animation, so this fixes which pose matches THOSE frames, not which is
canonically at rest. Default unchanged -- better on both screens where it
fires and identical on the other three, but it would move 2 305 elements
disc-wide on two measurements. Reachable via SYLPHEED_REST_RULE=last.

Also confirmed: all 195 zero-scale rest poses are inside the corrected
2 305 ambiguous population; none is a single-keyframe element.

METHOD: score a rule where it can differ, or you measure nothing; and an
argument from symmetry is a prediction, not a refutation.
This commit is contained in:
Sylpheed RE agent
2026-08-29 04:20:27 +00:00
parent 0265da31a1
commit 93e9b185ea
5 changed files with 114 additions and 2 deletions

View File

@@ -404,8 +404,18 @@ authored version can be deleted.
and it is unambiguously their rest. Of the real 2 305, **195 get a degenerate
`scale = 0 %` pose**, and the two
candidate rules agree only **50.2 %** of the time.
✅ **This does not block you.** On the five screens the port needs, 14 elements
are affected and the candidate rules **agree on 13**. The single disagreement
✅ **This does not block you — your exposure is TWO elements, both on the
splashes.** The fallback is reached only by an element that is plateau-less
*and* multi-keyframe; a single-keyframe element short-circuits. Title, main
menu and `EXTRAS` reach it **zero** times, which is why three different
fallback rules render them to identical correlations. The publisher and
developer splashes reach it once each — and there, `SYLPHEED_REST_RULE=last`
(the final keyframe) scores **+0.9982** and **+0.9758** against the current
rule's +0.9600 and +0.9643. ⚠️ Measured against single frames of a transient
animation, so it fixes which pose matches *those* captures, not which is
canonically at rest. Default unchanged — it is better on both screens where it
fires and identical on the other three, but it would move 2 305 elements
disc-wide on two measurements. The single disagreement
is `palogo_anima_eff.t32` on the developer splash, and the current answer is
the defensible one there — see below. Still worth flagging plateau-less
elements in an export rather than silently inheriting our guess; it is one pass