This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docs/re/dynamic-re-state-restore.md
Sylpheed RE agent 7146aed1a5 docs: fold the launcher repair and the clean scan into the backlog
The launcher item closes: unattended boot to Stage 02 flight works again, and the
entry now names all three defects that were in the way, including the
wait_flight pixel that was outside the HUD.

The objective-counter item stays open but is sharper: a HUD-clean scan exists,
and the surviving candidate that is hard to dismiss is named with the odds
against it being chance. The blocker is now the pilot's survival, not the method.

Also withdraws yesterday's claim that the "Auto-Save is active. OK?" dialog does
not return - the run that appeared to show that was tapping A every six seconds
while it waited, so it cannot distinguish "absent" from "dismissed unseen".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
2026-08-23 18:04:53 +00:00

7.1 KiB

The container's dynamic-RE state is not durable — how to rebuild it

Status: CONFIRMED by rebuilding it (2026-08-23). Everything the dynamic side of this corpus runs on — the baseline emulator binary, the Xbox profile, the Stage 02 save, the shader/code caches — lives outside the two git repos and was gone at the start of this session. None of it is recoverable from a git pull, and sylph-doctor reports "all good" without it, so the first symptom is a boot that dies instantly with NO PROFILE on disc.

This file is the recipe, measured rather than remembered.

What was missing, and what it blocks

gone consequence
/sylph-home/re/pure/xenia-canary (the auto/upstream-baseline worktree) and its build no baseline binary. The instrumented branch stops at the Stage 02 briefing under 384 crash dumps (upstream-baseline.md), so no in-mission work is possible at all
~/.local/share/Xenia/ — the whole storage root no profile, no save, no config, no caches

launch_mission.sh needs all of it: it signs in $(ls "$XENIA_CONTENT") and navigates title → LOAD GAME → slot 01 → READY ROOM → TAKE OFF.

1. The baseline binary — rebuild it incrementally, not from scratch

The branch itself survives (auto/upstream-baseline, tip c1b57f93b = upstream a5a18f5c7 + the three file-pad commits + the lost-resume fix). What is gone is only the checkout and the build.

The cheap move is not a new worktree: a fresh build directory means building all of third_party again. Instead check the branch out in the shared /work/xenia-canary and let ninja do an incremental build into the existing $XENIA_BUILD_DIR, because the two branches differ in 202 files and zero submodule gitlinks:

cd /work/xenia-canary && git worktree prune     # the dead worktree still claims the branch
git checkout auto/upstream-baseline
build-canary Release                            # ~9 min at -j4 here, vs a scratch build

git worktree prune is not optional — without it the checkout fails with "'auto/upstream-baseline' is already used by worktree at /sylph-home/re/pure/…" for a directory that no longer exists.

Keep both binaries, because switching the branch back costs another build:

/sylph-home/re/bin/baseline-c1b57f93b/xenia_canary       XENIA_BIN=… run-canary
/sylph-home/re/bin/instrumented-a60fe7d11/xenia_canary

🔴 Trap, paid for once here: keep the file name xenia_canary. A copy saved as xenia_canary.baseline-… runs fine and then survives every pkill -x xenia_canary in the toolkit — -x matches the whole name. The emulator keeps the flock on /tmp/xenia-canary.lock, and the next launch fails with "an emulator is already running" while ps -C xenia_canary shows nothing. Put the variant in a directory and leave the file name alone.

Tell the two apart by what is in them, not by the path, since build-canary writes both to the same place and has reported success on a failed build:

strings -a "$BIN" | grep -c log_ui_draws     # instrumented: 5   baseline: 0

2. The profile — bootstrap it with the instrumented binary

--create_profile_if_none is one of our 50 RE commits (7dbb24e64) and is not on the baseline branch; the baseline cannot make a profile, and the Sign In dialog cannot be driven from a script (an ImGui text field, no synthetic key events reach it). So make the profile once with the instrumented binary and then run the baseline against it — the content root is emulator-build independent:

XENIA_BIN=/sylph-home/re/bin/instrumented-a60fe7d11/xenia_canary \
  run-canary --create_profile_if_none=SylphRE
# wait for: ProfileManager: RE bootstrap profile 'SylphRE' -> created
pkill -x xenia_canary

XUID is fixed at B13EBABEBABEBABE, which is what makes it scriptable, and launch_mission.sh picks it up on its own.

3. The Stage 02 save — from the repo, and without a .header

docs/re/captures/savedata-stage02-5pct.bin is a complete GDHA container (parses clean: phase GP_BUNK, slot 0 used, 2026-07-23 20:07). Drop it in at the path structures/savegame-format.md records:

C=~/.local/share/Xenia/content/B13EBABEBABEBABE/535107D4/00000001/game01
mkdir -p "$C" && cp docs/re/captures/savedata-stage02-5pct.bin "$C/savedata"

The companion Headers/00000001/game01.header is not in the repo and is not needed — checked in the source rather than assumed: ContentManager::ListContent (src/xenia/kernel/xam/content_manager.cc) enumerates directories, and when ReadContentHeaderFile fails it synthesises the record from the directory name. The slot is listed either way; only the display string differs (game01 instead of Game01 07/23/2026 21:08 STAGE02 EASY). So there is no need to fabricate a 328-byte Xbox content header, which would have been a guess with no oracle.

Verified end to end — and one new trap in the scripted route

The restored state was checked by driving it, not by inspecting files:

  1. LOAD GAME lists the slot () as 01 · 07/23/2026 21:08 · EASY · 000:05:24 · 5 %, with the Details panel reading STAGE02 — Declaration of War, At Standby, 4101 P. Note what that settles: every detail on that screen comes out of savedata, not out of the Xbox content header that was not installed.
  2. → READY ROOM → TAKE OFF → launch cinematic → objective card → Stage 02 flight (), TIME 00:18.01, REMAINING OB 004, hull 1500 / shield 400. pilot.py bound and flew it (ENGAGE … tgt=e010_ADAN_Attacker_S), so the whole live-memory toolchain works against the restored profile.

🔴 A fresh profile inserts an extra dialog, and it desynchronises launch_mission.sh. After LOAD GAME → slot 01 → YES the title puts up "Auto-Save is active. OK?" (YES preselected) before the READY ROOM. The launcher's press sequence is fixed and has no slot for it, so every later press lands one screen early — this run ended up sitting in OPTIONS → GAME SETTINGS, and wait_flight.sh correctly reported NEVER REACHED FLIGHT. The mission above was reached by driving the menus by hand from there.

On the next boot the launcher gets further — READY ROOM instead of OPTIONS — but that run does NOT establish that the dialog is gone, and the earlier wording here claiming it did is withdrawn: wait_flight.sh taps A every six seconds while it waits, so a dialog would have been dismissed by those taps without ever being seen. What run 2 does show is where it stopped: it lands on BRIEFINGS, i.e. its step up; tap A for TAKE OFF is swallowed by the READY ROOM transition, because what precedes it is a fixed sleep 28 rather than a wait for the screen. So launch_mission.sh is one wait away from working unattended on restored state, and both runs here were finished by hand from the screen it stopped on. That repair is left for whoever needs the launcher, and is noted in BACKLOG.md; nothing here depends on it.