port: the plate POPPED on a return to the title where the boot fades it

The Decoder warned that my port "presumably models one title". Checking that found
a real behavioural split, and the code was right where I expected it wrong and
wrong where I did not.

My prediction FAILED first: I expected the port to be inventing a plate on a
(B)-reached title, because flow.json's scope_why says that is deliberately not
claimed. It is not inventing -- the call site cites a measurement from 2026-08-30,
the plate IS re-drawn after (B). scope_why was the stale thing, and is corrected.

🔴 BUT THE TWO PATHS DIFFER, AND A `why` CLAIMED THEY DO NOT. That call site says
"the plate re-appears by the SAME path, with the same shared clock, as it does on
boot. Whatever the boot does, the return does." Filmed:

  before: el=1.39 view_u=0.00 overlay_u=  0.00  plate absent
          el=1.53 view_u=8.67 overlay_u=244.67  plate present

The overlay clock jumped 0 -> 244.67 in ONE frame. The plate POPPED, where the
boot fades it across its declared 214->236.

Cause: `_overlay_process` detected "static diagnostic mode" as
`_sequence.is_empty()`, and `_sequence` is populated only by `--boot`. So `--menu`
matched it too and the menu's return took the `--screen --overlay` diagnostic
branch, which poses the overlay at settle_time() by design. A proxy for one mode
that silently caught another.

Fixed by gating on the flag itself -- `_static_overlay`, set only by `--overlay=`
without `--boot`. Verified both directions:

  diagnostic still poses: --screen=title --overlay=press_start --time=4
                          -> "overlay press_start at t = 240.00 units, drew 2"
  return now shares the clock: overlay_u == view_u on every filmed frame, plate
                          at its 0.1377 floor through 168 units
  boot path unchanged:    plate reaches full alpha at t=236, boot completes 10.46 s

⚠️ WHAT I DID NOT OBSERVE, stated rather than glossed: the plate actually RISING
on the return path. `--script` quits when the walk settles, so the film stops at
~168 units and never reaches 214. The rise is established on the BOOT path
(measured earlier: 0.1457 at 210 u, 0.2142 at 236 u) and the return now provably
takes that same branch with an identical clock -- but the final rise on this path
is inferred from path identity, not filmed.

⚠️ And whether the GAME fades the returned plate is still unmeasured. The 7.3 s
between (B) and the pulse returning is consistent with a transition plus the
declared fade, but that is consistency, not a measurement of the ramp on this
path. Recorded in scope_why.

Not settled: finding 3, no surviving cause; the clock origin, which the Decoder
reports blocked -- no capture contains the title, because it sits on the far side
of a 137.7 s movie and the runs were too short; the ~1.0-1.2 menu residual.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AHUQvXGyNcKonSEWsgWcX
This commit is contained in:
Sylpheed port agent
2026-09-01 19:50:13 +00:00
parent 15702d0d05
commit 1c2782247d
2 changed files with 27 additions and 3 deletions

View File

@@ -389,6 +389,14 @@ func _ready() -> void:
_overlay_process(0.0)
if args.has("overlay") and not args.has("boot"):
# 🔴 THIS IS THE ONLY STATIC OVERLAY, AND IT NOW SAYS SO ITSELF.
# `_overlay_process` used to detect it as `_sequence.is_empty()`, which is
# true for `--menu` as well -- `_sequence` is populated only by `--boot`.
# So the MENU's return-to-title took the diagnostic branch and posed the
# plate at its settle instantly. Measured: the overlay clock jumped 0 ->
# 244.67 units in one frame, and the plate POPPED where the boot fades it
# across its declared 214->236.
_static_overlay = true
_overlay_spec = {"screen": args["overlay"]}
_overlay_due = 0.0
_overlay_process(0.0)
@@ -1460,6 +1468,14 @@ var _overlay_t0 := 0.0
var _overlay_view_t0 := 0.0
## Wall-clock second at which it is raised, measured from the screen's settle.
var _overlay_due: float = 0.0
## True only for `--overlay=` WITHOUT `--boot` -- the static diagnostic.
##
## It replaces `_sequence.is_empty()`, which was standing in for "diagnostic
## mode" and silently caught `--menu` too, because `_sequence` is filled only by
## `--boot`. The consequence was visible and nobody had looked: on the menu's
## return to the title the plate was posed at its settle in a single frame
## instead of fading across its declared 214->236.
var _static_overlay := false
## `--loop-phase=<units>` pins the looping record's phase. Negative is
## free-running, which is the default and what a player gets. Only the
## regression harness passes it -- see `ScreenView.loop_phase_units`.
@@ -1490,7 +1506,15 @@ func _overlay_process(delta: float) -> void:
# In a `--boot` sequence the shared clock is the whole point -- the 120
# units between build 4's last ramp and the plate's a=255 is a fixed
# interval on ONE timeline -- so that path is untouched.
if _sequence.is_empty():
if _static_overlay:
# 🔴 GATED ON THE DIAGNOSTIC FLAG, NOT ON `_sequence.is_empty()`.
# `_sequence` is filled only by `--boot`, so the old test was true for
# `--menu` as well and the menu's return-to-title took this branch:
# the plate was posed at its settle in ONE frame (overlay clock 0 ->
# 244.67) instead of fading across its declared 214->236. The call
# site's own `why` claimed "whatever the boot does, the return does",
# and it did the opposite.
#
# 🔴 A static overlay STARTS at its arrival and then ADVANCES. It used
# to be pinned there on every frame, which was this fix overshooting.
#