port: running it as a player finds two defects reading it did not

--boot --script= parsed, was stored, and did nothing. The script only starts at
_menu_enter, and a --boot run without --play never enters a menu -- it holds on
the title and quits. The run completed, exit 0, no menu line, no press: a clean
result to a question never asked. This file already warns about that exact shape
600 lines above the bug, where --capture used to photograph the first frame of a
scripted run. The warning was written, kept, and did not stop the same class
recurring in the neighbouring flag. Now push_errors and exits 2, naming both
working forms, refusing rather than implying --play since the two runs differ by
157 s of intro. Verified: --boot --play --script walks power-on through splashes,
ADV, title, (A), main menu, down, (A).

A comment above audio.play_bed described the port as CHOOSING the menu track,
which HANDOFF Q10 refuted a week ago -- BGM_103 is measured on three independent
legs and audio.json says so. Third instance of the drifted-comment trap. The dead
phrase is now a check-claims register row, controlled: a planted revival fails and
removing it passes.

And the boot's wall-clock seconds are a property of this container. ADV takes
146.6 s of wall clock for 137.44 s of media, +6.7%, while S00A runs real time at
-0.4%. Not a post-roll and not a general deficit: ADV is 1280x720 and S00A is
768x432, this box has no GPU, and 720p Theora decodes below real time here. The
transcode is faithful against a 137.71 s source and the exporter does not rescale.
P3/P7 artifacts quote seconds containing that deficit -- reproducible here, not a
statement about the port or the game. Comparisons with the Decoder's measurements
must go through media length, not wall clock; they carry an explicit emulator
pacing factor for the same reason and I had been quoting mine as exact.

Their negative result on LOAD GAME, TUTORIAL and OPTIONS leaves guard_focus_scope
right to count them UNMEASURED rather than 'resets'. The transferable part is
their instrument story: a narrow calibrated reader failed, so they generalised to
a whole-frame comparison, which died the moment a crash dialog overlaid the frame
while the narrow reader kept working. contract-check is deliberately narrow,
individually anchored checks for the same reason, and the temptation after an
ANCHOR LOST will be to loosen the matching -- trading a failure I can see for one
I cannot.

Every asserting check passes.

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 22:35:13 +00:00
parent 3ddd298262
commit cf3a9a0454
4 changed files with 138 additions and 6 deletions

View File

@@ -170,6 +170,27 @@ func _ready() -> void:
# screen directly, which is what makes an unattended run cheap -- it does not
# sit through 137 s of intro to press a d-pad.
_play = args.has("play") or args.has("menu")
# 🔴 `--boot --script=…` PARSED, WAS STORED, AND DID NOTHING. The script only
# ever starts at `_menu_enter`, and a `--boot` run without `--play` never
# enters a menu: it holds on the title and quits. So the run completed, exit
# 0, no menu line, no press -- a clean-looking result to a question that was
# never asked.
#
# This file already warns about exactly this shape 600 lines up, where
# `--capture` used to photograph the first frame of a scripted run: "a flag
# combination that silently photographs the wrong instant is worse than one
# that errors". Same class, found again by running the port as a player would
# rather than by reading it.
#
# Refusing rather than implying `--play`: the two runs differ by 157 seconds
# of intro, and quietly choosing that for someone is its own surprise.
if not _script.is_empty() and not _play:
push_error("--script needs a live menu. `--boot` alone ends on the title "
+ "and quits, so the script would never run. Use `--boot --play "
+ "--script=…` to walk from power-on (157 s of intro), or `--menu=<screen> "
+ "--script=…` to start on a screen.")
get_tree().quit(2)
return
if _play:
_menu = MenuFlow.new()
if not _menu.configure(_flow):
@@ -769,11 +790,24 @@ func _menu_enter(name: String, fresh: bool) -> void:
_menu.stack[_menu.stack.size() - 1]["focus"] = _force_focus
view.focused_id = _menu.focus()
view.queue_redraw()
# AUTHORED, and the weakest thing in P6: HANDOFF Q10 says nothing on the disc
# names which track a menu plays, so `authored/audio.json` picks one. It
# starts when the menu becomes live and CARRIES ACROSS submenus -- `play_bed`
# is idempotent, because music that restarts every time you press (B) is the
# kind of wrong that reads as "the audio works".
# MEASURED, and this comment is a correction of itself. It read "AUTHORED, and
# the weakest thing in P6: HANDOFF Q10 says nothing on the disc [refuted] names
# which track a menu plays, so `authored/audio.json` picks one" -- which was
# true when written and was refuted the same week. `BGM_103` is measured from
# three independent legs: the phase handler `sub_821C5580` plays cue 1103,
# the bank's two waves are byte-for-byte what the XMA probe saw at the menu,
# and the disc census agrees. `authored/audio.json` CITES it; it does not
# choose it.
#
# 🔴 Left visible rather than swapped out, because this is the third instance
# of the drifted-comment trap in this project -- a correction lands in the
# code or the data and the sentence above it keeps describing the old world.
# Neither agent's checker looks at prose that contradicts the code under it.
#
# What is still true: the bed starts when the menu becomes live and CARRIES
# ACROSS submenus -- `play_bed` is idempotent, because music that restarts
# every time you press (B) is the kind of wrong that reads as "the audio
# works".
audio.play_bed("main_menu")
print(" menu on %s, focus %s" % [name, _focus_label(view.focused_id)])
if not _script.is_empty() and not _script_started: