port: the PRESS A plate comes back after B, and it did not here

The Decoder measured that after B from the menu the plate is re-drawn (daf8f47).
The port landed on a BARE title: _menu_arrive drops the overlay -- correct, the
plate goes with the screen it was measured on -- but nothing put it back, since
_overlay_spec is cleared the instant the overlay is raised and only the boot
sequence ever set it. Confirmed by running it: ten title elements, no ptbtn00.

_rearm_overlay_for reads the declaration out of authored/flow.json's boot step
for that screen rather than naming press_start, so the plate returns by the same
path and shared clock as on boot, with NO new constant. Controlled both ways:
cancel raises it, entering EXTRAS (no overlay declared) raises nothing.

Script steps now carry an elapsed timestamp, without which the port's own press
latency could not be compared to a measured one. With it: B at 1.01 s, title at
1.37 s = 0.36 s, against their measured <= 0.4 s -- nothing was fitted to that.

The plate's RETURN time does not agree: 4.33 s here against their 7.3 s to pulse,
of which up to 2 s is pulse-detection phase. Not adjusted -- an authored delay in
this same block was already refuted once. Recorded as an ask.

auto_repeat and title/on_cancel upgraded to MEASURED on their run.

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-30 11:23:05 +00:00
parent 7ecbed1d09
commit 7dc5117a09
4 changed files with 120 additions and 5 deletions

View File

@@ -731,6 +731,22 @@ func _menu_arrive() -> void:
push_error(view.tree.error)
get_tree().quit(2)
return
# 🔴 THE PLATE COMES BACK IN THE GAME, AND IT DID NOT HERE.
#
# `_drop_overlay()` at the top of this function is right -- the plate goes
# with the screen it was measured on -- but nothing ever put it back, so Ⓑ
# from the main menu landed on a BARE title. `_overlay_spec` is cleared the
# moment the overlay is raised, and only the boot sequence ever sets it.
#
# MEASURED by the Decoder 2026-08-30 (branch `auto/no-disc-and-menu-captures`,
# `docs/re/data/nav-autorepeat-and-settled-b.txt`): after Ⓑ from the menu the
# plate IS re-drawn -- pressed at 351.2 s, its pulse back at 358.5 s.
#
# ⚠️ No new constant. The delay is not authored here and must not be: the
# overlay declaration is read back out of `authored/flow.json`'s boot step
# for this screen, so 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.
_rearm_overlay_for(name)
var buttons: Array = view.screen.get("buttons", [])
if action.get("pop", false):
# MEASURED, HANDOFF Q5: (B) restores the focus you came from.
@@ -899,7 +915,11 @@ func _run_script() -> void:
elif token == "wait":
pass
elif SCRIPT_ACTIONS.has(token):
print("script[%d] %s" % [i + 1, token])
# The elapsed clock goes in the line because a press with no timestamp
# cannot be compared against a MEASURED latency. The Decoder's Ⓑ
# figures are press-to-effect times; without this the port's own
# press time had to be guessed from the surrounding lines.
print("script[%d] %s at %.2f s" % [i + 1, token, _elapsed])
_press(String(SCRIPT_ACTIONS[token]))
else:
push_error("--script: no such step %s (have %s, wait, wait:<seconds>)"
@@ -1107,6 +1127,26 @@ func _overlay_process(delta: float) -> void:
_raise_overlay(String(_overlay_spec.get("screen", "")))
## Re-arm the overlay a screen declares in the authored boot sequence.
##
## Used when the MENU arrives at a screen, not just when the boot walks onto it.
## It looks the declaration up rather than naming `press_start`, so a screen that
## gains an overlay in `authored/flow.json` gets it on both paths at once and
## this function needs no edit.
func _rearm_overlay_for(name: String) -> void:
if _flow == null or not (_flow as Dictionary).has("boot"):
return
for step: Dictionary in _flow["boot"]:
if String(step.get("screen", "")) != name:
continue
var spec: Variant = step.get("overlay", null)
if typeof(spec) == TYPE_DICTIONARY:
_overlay_spec = spec
_overlay_due = _elapsed
_overlay_process(0.0)
return
## Composite a second build over the first.
##
## It starts at `time_units = 0` and plays its OWN group, so the plate rises and