Last updated: 2026-05-20

# DECISIONS

## Decision Log Format
Each entry records:
- Date (`YYYY-MM-DD`)
- Decision
- Rationale
- Implications
- Evidence

## Decision Log

### 2026-05-22 — Minimal B2 Dynamic PFS Unmount Production Fix
- Decision: Apply the B2 dynamic PFS unmount fix to the child loader pre-ExecPS2 sequence for HDD-backed POPSTARTER paths, bypassing the child loader's post-load IOP reset and re-initialization.
- Rationale: Target-side diagnostic sentinel testing proved that resetting the IOP post-load in the HDD-backed loader environment causes subsequent RPC/SIF handshake initialization (SifInitRpc) to hang due to the target partition remaining mounted. Dynamically unmounting only the exact target PFS mount prefix (e.g., `pfs0:`) resolved the hang and restored the handshake without needing a loader-side reset.
- Implications: HDD-backed POPSTARTER launches proceed with the standard SifLoadElf path but with PFS slot cleanup before ExecPS2. Non-HDD paths remain completely unaffected.
- Evidence: `src/elf_loader/src/loader/src/loader.c`, B2 diagnostic variant (`artifacts/local-d10/20260522-122000-popsloader-hdd-preexec-unmount-target-pfs/POPSLOADER.ELF`).

### 2026-03-06 — Lua runtime is embedded-only at boot
- Decision: boot and required runtime Lua modules are loaded from embedded blobs, not loose filesystem Lua files.
- Rationale: deterministic startup and fewer layout-dependent failures.
- Implications: editing runtime Lua requires rebuilding the ELF.
- Evidence: `src/luaplayer.cpp`, `etc/boot.lua`, `Makefile`.

### 2026-03-06 — Settings persist as a transaction on Settings/Profile exit
- Decision: settings edits are staged in UI draft state and committed on confirm/leave.
- Rationale: avoid repeated writes while navigating and keep save/apply failure handling explicit.
- Implications: runtime/UI state sync must still happen if save/apply fails.
- Evidence: `bin/POPSLDR/ui.lua`, `bin/POPSLDR/system.lua`.

### 2026-03-26 — USB vs MX4SIO identity is authoritative by mount driver
- Decision: mounted mass roots are classified by driver identity, not by path spelling.
- Rationale: real hardware can expose both USB and MX4SIO through `mass*:/`.
- Implications: startup auto-init, boot-device labeling, and page list building must continue to use mount-driver queries.
- Evidence: `bin/POPSLDR/system.lua`, `src/luasystem.cpp`.

### 2026-03-26 — Runtime device locks are no longer enforced
- Decision: the old per-session device lock system is no longer an active runtime constraint.
- Rationale: device access should not be blocked by stale lock state.
- Implications: docs must not claim that switching devices requires restart; future changes must not silently reintroduce that gate.
- Evidence: `bin/POPSLDR/ui.lua` (`canEnterDevice`, `setDeviceLock`).

### 2026-03-26 — Startup backend initialization is path-driven
- Decision: startup backend auto-init considers boot paths and configured executable/profile paths, not just the page the user opens first.
- Rationale: a configured POPSTARTER/DKWDRV/profile path can require backend drivers before any device page is visited.
- Implications: startup docs and validation must cover boot source plus configured paths, and HDD startup targets must run the full HDD module-load path rather than only low-level exec initialization.
- Evidence: `bin/POPSLDR/system.lua` (`CollectStartupBackendTargets`, `AutoInitStartupBackends`).

### 2026-03-26 — PAL UI uses the same 640x448 raster layout as NTSC-authored UI assets
- Decision: PAL mode keeps the UI raster at `640x448` instead of stretching the authored layout vertically.
- Rationale: reduce PAL squish on menus and authored UI assets.
- Implications: final on-TV proportions still require hardware confirmation.
- Evidence: `bin/POPSLDR/system.lua`, `bin/POPSLDR/ui.lua`.

### 2026-03-26 — Release ZIP contract is strict and PATCH_5-based
- Decision: CI package includes exact `PS1_POPSLOADER/*` launcher files plus `POPS/PATCH_5.BIN`, now including `PS1_POPSLOADER/BUILD_INFO.txt`, and rejects legacy `POPS/*.tm2` payloads.
- Rationale: prevent release drift and ambiguous installation instructions.
- Implications: docs and workflow validation must stay synchronized, and GitHub-built hardware candidates now carry a visible build stamp while CI also checks for expected embedded runtime markers before packaging.
- Evidence: `.github/workflows/compilation.yml`.

### 2026-03-29 — `QA_REGRESSION_MATRIX.md` is the detailed run ledger
- Decision: keep per-artifact hardware/CI chronology in `QA_REGRESSION_MATRIX.md`, while `README.md`, `STATE.md`, and `ROADMAP.md` summarize the stable current state and constraints.
- Rationale: repeated experiment history had started drifting across the root docs and obscuring the actual current handoff state.
- Implications: root docs should point to the matrix for detailed chronology instead of carrying their own competing mini-ledgers.
- Evidence: repository documentation audit on 2026-03-29.

### 2026-05-13 — Separate build/package CI from comment-triggered AI automation
- Decision: treat `.github/workflows/compilation.yml` as the build/package validation source of truth, and document `.github/workflows/opencode.yml` separately as comment-triggered repository automation.
- Rationale: the opencode workflow can affect repository collaboration but does not build artifacts, enforce the release ZIP contract, or prove runtime/hardware behavior.
- Implications: source-truth audits should include both workflow files, while CI/package claims should continue to cite only the compilation workflow unless the automation contract changes.
- Evidence: `.github/workflows/compilation.yml`, `.github/workflows/opencode.yml`.

### 2026-05-19 — Default cover image is optional at compile time
- Decision: `bin/POPSLDR/IMG/default.png` is optional. CI/artifact builds without it omit `asset_default_png` and fall back to the required `MISSING.png` asset for `IMG.default`.
- Rationale: default cover art should only be embedded when the PNG is present in the checkout used by GitHub Actions.
- Implications: `MISSING.png` remains required; `default.png` can be removed without breaking artifact builds.
- Evidence: `Makefile`, `src/embed_assets.cpp`, `bin/POPSLDR/images.lua`, `bin/POPSLDR/ui.lua`.

## Open Investigations
- HDD startup auto-init on HDD boot/configured paths:
  - a 2026-03-27 hardware report said booting from HDD did not auto-init the HDD driver stack.
  - current code had detected HDD startup targets correctly but only called `EnsureHddRuntimeReadyForExec()`, which stops at low-level `HDD.Initialize()`.
  - current source now routes HDD startup targets through `PLDR.LoadHDDModules()` so startup uses the same HDD status/partition/cache initialization path as the HDD page.
  - a later boot-time report showed that using the full HDD page path at startup also caused large HDD libraries to spend boot time scanning partitions and building the games list.
  - current source therefore keeps startup HDD auto-init limited to runtime readiness only; partition scanning and game-list building remain page-entry work.
  - optional HDD cache writing now reuses the page-built game list instead of rebuilding one during startup.
  - later 2026-03-28 hardware reports on that narrowed boot-time split source still said HDD-backed startup/Profile POPSTARTER could disappear after entering the USB page before the HDD page.
  - the raw boot `APP_DIR` fallback alone did not restore that case.
  - current source therefore also pre-resolves any HDD-backed startup/configured exec paths immediately after `PLDR.LoadHDDModules()` so HDD POPSTARTER/Profile paths are mounted and recorded without reintroducing HDD page work at boot.
  - current source also routes on-demand HDD path mounts through `PLDR.LoadHDDModules()` instead of only the lower-level `EnsureHddRuntimeReadyForExec()` gate, so later POPSTARTER/Profile resolution from USB or other pages uses the same runtime init path as HDD page entry.
  - repo inspection also showed the startup HDD warm-path list had been skipping Profile 1/default relative `POPSTARTER.ELF` because it only recorded explicit `hdd:` / `pfs:` paths, so current source now includes that default-relative case when boot source is HDD.
  - repo inspection of `etc/boot.lua` also showed HDD boot is established on a dedicated `pfs1:` mount before `system.lua` runs, so current source now carries that exact boot partition/slot metadata into `system.lua`, seeds the HDD mount tracker from it, and rebuilds HDD sidecar/partition context from mounted `pfs1:` candidates instead of assuming low-level HDD readiness alone preserves the boot-side path contract.
  - user later confirmed on 2026-03-28 that the exact-boot-mount/source-context source restored the USB-before-HDD-page startup/Profile repro on hardware, so the remaining blocker is no longer startup/Profile lookup.
- USB first-entry backend discovery:
  - a 2026-03-27 hardware report said the first USB page entry reported no backend, but backing out and re-entering then worked.
  - current code already had bounded retry loops for USB root discovery, but all retries happened back-to-back with no yield for the backend to become visible.
  - current source now adds a bounded wait only in `BuildUsbIdentityDeferred()`, leaving MX4SIO discovery logic unchanged.
  - user later confirmed the corrected source on hardware.
- HDD `POPSTARTER.ELF` when launcher/sidecar/CWD is on HDD:
  - current reported hardware result is still a black-screen hang.
  - path/mount/CWD mitigations plus the HDD-backed non-reboot `ExecPS2` cleanup are present in current code.
  - a 2026-03-27 hardware re-test of the current source still black-screened with boot source HDD, default/Profile 1/cwd/sidecar `POPSTARTER.ELF` on HDD, and game device HDD.
  - a second 2026-03-27 hardware report also black-screened while launching a USB game with Profile 2 pointing `POPSTARTER.ELF` to HDD, so the remaining failure is now treated as the HDD-backed POPSTARTER exec path itself rather than only HDD game routing.
  - a later 2026-03-27 hardware report also said booting from another device and launching an HDD title with sidecar `POPSTARTER.ELF` on that boot device black-screened, and the user identified it as a regression.
  - the EE-side HDD direct-load workaround in `src/elf_loader/src/elf.c` has therefore been reverted; it did not fix `D-10` and is no longer supported by hardware evidence.
  - later 2026-03-27 Memory Card staging, stripped-handoff, CWD/selector, and HDD-init-state experiments in `bin/POPSLDR/system.lua` did not fix `D-10` / `D-14` and coincided with repeated `D-15` failures.
  - user later confirmed on 2026-03-28 that USB boot + USB sidecar/cwd `POPSTARTER.ELF` + HDD game passes on the narrowed source, so the remaining blocker is again isolated to HDD-backed `POPSTARTER.ELF`.
  - a later 2026-03-28 re-test still black-screened on that narrowed Lua-side source with no visible positive change, so the next shared preservation step tested was the loader's automatic post-load exec-slot keep in `src/elf_loader/src/elf.c`.
  - that loader-side no-auto-exec-slot-preserve source still left non-HDD POPSTARTER HDD-game launches on the restored selector-only handoff, while `R2` could still request the explicit `hdd0:PART:pfs0:/GAME.ELF` selector.
  - a later 2026-03-28 re-test on that loader-side source still black-screened for `D-10` on both `X` and `R2`, and the user clarified the other same-day success result was another `D-15` run rather than `D-14`.
  - a later 2026-03-28 re-test on that forced-`reboot_iop = 1` source still black-screened for `D-10` and `D-14`, so reboot mode alone did not separate the remaining failure.
  - a later 2026-03-28 re-test on that direct-`hdd0:PART:pfsN:/POPSTARTER.ELF` preference source still black-screened for both `D-10` and `D-14`, so exec-path form alone did not separate the remaining failure.
  - follow-up repo inspection then found `BuildDirectHddExecPathFromMounted()` had been generating malformed direct aliases without the colon after `pfsN`, so that earlier direct-path experiment was not a clean control.
  - inspection of `wLaunchELF` and `PlayStation2-Basic-BootLoader-Extended` showed the common HDD ELF pattern is to mount the target partition explicitly and feed `SifLoadElf` a mounted `pfs0:/...` path rather than a direct `hdd0:` path.
  - a later 2026-03-28 re-test on that mounted-`pfs0:` embedded-loader source still black-screened for `D-10`.
  - broader comparison then showed current HEAD had drifted away from this repo's own March 24 partitioned-loader diagnostics by reintroducing `SifExitRpc()` immediately before the parent `ExecPS2` into the embedded loader.
  - this repo's earlier HDD diagnostics also recorded that the embedded-loader boundary only became stable once EE-side SIF teardown before `ExecPS2` was removed from the parent handoff.
  - comparison against `wLaunchELF` and `PlayStation2-Basic-BootLoader-Extended` also showed another remaining mismatch: this repo's embedded loader had no separate original HDD source-context argument, so it could only make reset decisions from the mounted `pfs0:/...` load target.
  - follow-up repo comparison then showed the remaining source-context gap was broader than the loader alone: Lua had usually already normalized HDD POPSTARTER to mounted `pfs1:` / `pfs3:` paths before the reboot loader saw it, so the loader was still not being given the original HDD path it needed to force the `pfs0:` remount pattern used by `wLaunchELF`.
  - broader comparison against `wLaunchELF` also showed the remaining ownership mismatch was not just reset policy: the parent/loader boundary there does not pre-unmount PFS state and the embedded loader calls `SifLoadElf` directly after `SifInitRpc(0)`, without `SifLoadFileInit/Exit`.
  - a later 2026-03-28 re-test on that exact-boot-mount/source-context source still black-screened for `D-10`, so full raw-source reconstruction alone was still not the missing link.
  - repo comparison against the local `ps2sdk` tree then showed the remaining drift was structural: the header still documented a partition-aware loader contract, but the live reboot path was still using a custom source-context channel instead of the same partition/load-path/argv split.
  - current source therefore keeps the restored non-HDD POPSTARTER path, seeds the exact boot `pfs1:` mount metadata from `etc/boot.lua` into Lua-side HDD mount tracking, and replaces that ad hoc reboot handoff with an explicit partition-aware contract across `bin/POPSLDR/system.lua`, `src/luasystem.cpp`, `src/elf_loader/src/elf.c`, and `src/elf_loader/src/loader/src/loader.c`.
  - on that contract, Lua passes exact HDD partition context separately from the mounted load path, normalizes the partition-aware exec filename back to generic `pfs:/...`, routes HDD partition-aware launches through cold external-launch prep so the old tracked `pfsN:` mount is not preserved into exec, and the parent remounts `pfs0:` from that partition while reusing the mounted relpath Lua already resolved.
  - a 2026-03-29 hardware result on the prior partition-aware source no longer black-screened, but the launcher regained control with `rc=-1 (returned after 22618 ms)`, which meant that specific artifact had moved the remaining failure past the old black-screen boundary and into the embedded-loader or target-`ExecPS2` handoff.
  - a later 2026-03-29 GitHub artifact re-test on that broader partition-aware/current-source line black-screened again, so the returned-rc boundary is not yet stable enough to treat as the new steady state.
  - repo history comparison then showed that this partition-aware reboot path had drifted away from the original parent-side embedded-loader jump contract in `src/elf_loader/src/elf.c`: it no longer performed the BRAM wipe or the original `SifInitRpc`/`SifLoadFileInit`/`SifLoadFileExit` and `SifExitIopHeap`/`SifExitRpc`/`SifExitCmd` sequence around that final `ExecPS2`.
  - repo history comparison also showed that earlier child-loader `fileXio` experiments had never been retested after the later parent-side jump-contract fixes, so they were not a clean control for the current boundary.
  - later repo audit also showed that POPSLoader's normal POPSTARTER launch path passes only the selector as target `argv[0]`, while the newer HDD child-loader path had started prepending a replacement executable path; that changed the HDD-backed POPSTARTER argv layout away from the working non-HDD path.
  - repo audit also found that selected-profile state and stored canonical profile paths could drift apart, so a chosen Profile 1/default path could still launch another profile's canonical HDD POPSTARTER path without the user realizing it.
  - current source restores that original parent-side jump contract, returns the actual embedded-loader `ExecPS2` result instead of collapsing it to `-1`, keeps legacy `System.loadELF(path, reboot_iop, selector)` on POPSTARTER's normal one-argument selector contract, aligns the child loader closer to `wLaunchELF` / `PlayStation2-Basic-BootLoader-Extended` by removing the post-reset MC module reload and exiting SIF command state before the final target `ExecPS2`, routes partition-aware HDD launches through the explicit `System.loadELFWithPartition(path, reboot_iop, partition_context, selector)` API and mounted-`pfs0:` `SifLoadElf` once the parent has already remounted the target partition, normalizes stale canonical profile-path state before launch/save, keeps the older iomanX-aware `fileXio` path only for direct `pfs:` / `hdd:` loads with no partition-aware HDD context, and now exposes the real exec filename separately from the probe/open path in the launcher popup.
  - 2026-05-19 source audit found that several current-source defects must be fixed before treating new hardware results as clean controls: Lua mounted-PFS fallback can leave stale launch context, normal HDD game labels can fail fallback partition parsing, the fallback path can skip the pre-exec gate even when reconstruction failed, `System.loadELF(..., args..., partition_context)` can leak the partition context into target argv, the generic embedded-loader default-argv contract is unreachable, and the child loader still uses `snprintf`/`strncat` despite older docs claiming that risk was avoided. See `HDD_POPSTARTER_HANDOFF.md`.
  - 2026-05-19 source change applies the handoff's recommended fixes (except for the child-loader `snprintf`/`strncat` cleanup, which would require regenerating the embedded loader blob and was intentionally deferred):
    1. `bin/POPSLDR/system.lua` adds `NormalizeHddPartitionLabelForMount` so `ResolveFallbackMountedPfsExecPath` accepts the bare partition labels (e.g. `__.POPS`) returned by `ParseHddGameEntry`. Previously the fallback parsed only `hdd0:`-prefixed labels and always failed for normal HDD game entries.
    2. `RunPOPStarterGame` now resyncs `context.exec_path`/`exec_partition_context`/`exec_mounted_path`/`exec_original_slot`/`exec_pfs_slot`/`source_pfs_slot`/`cold_external_launch`/`keep_hdd_slots`/`keep_hdd_slots_after_load` and the matching `launch_diagnostics` fields after a successful fallback, so `LaunchEngine` no longer consumes stale pre-fallback values.
    3. The HDD pre-exec gate is skipped only when the fallback actually reconstructed a partition-aware path; if reconstruction failed in non-strict mode, the gate now runs so its own partition-recovery logic can succeed or fail loudly instead of silently launching with stale context.
    4. `src/luasystem.cpp` exposes `System.loadELFWithPartition(path, reboot_iop, partition_context, args...)`. The legacy `System.loadELF` trailing partition_context detection has been removed; partition_context can no longer be copied into target argv. `LaunchEngine` calls the new binding when `context.exec_partition_context` is set.
    5. `src/elf_loader/src/elf.c` `ExecuteViaEmbeddedLoader` no longer rejects `argc == 0`, so the documented child-loader default-argv synthesis (`build_default_target_arg0`) is reachable. The HDD POPSTARTER-specific `argv[0]` guard in `ExecuteHddBackedViaEmbeddedLoader` is intentionally left in place.
  - a 2026-05-20 artifact screenshot then showed `D-10` returning to the launcher with `POPSTARTER HDD pre-exec gate failed: Cannot resolve HDD partition context`, `POP:pfs3:/POPS/POPSTARTER.ELF`, and `APP:hdd0:+OPL:pfs:/APPS/PS1_POPSLOADER/`.
  - 2026-05-20 source follow-up fixes the argument-shifted failure popup call sites, lets Lua parse `hdd0:PART:` partition-context strings, lets shared HDD recovery candidates accept safe bare labels such as `__.POPS`, and changes mounted-PFS fallback to recover the actual mounted POPSTARTER source partition before falling back to the selected HDD game partition. It does not change the POPSTARTER selector `argv[0]` contract.
  - a 2026-05-20 latest-artifact `D-15` report then showed USB boot with USB sidecar/cwd `POPSTARTER.ELF` plus an HDD title black-screening. Current source follow-up restores legacy `System.loadELF(path, reboot_iop, selector)` one-argument selector behavior for normal/non-HDD POPSTARTER launches and keeps HDD partition context on `System.loadELFWithPartition(...)`.
  - a later 2026-05-20 readable-diagnostic screenshot then showed the pre-exec gate failing on the loader-facing generic exec path `pfs:/POPS/POPSTARTER.ELF`; source now derives a real mounted probe path for `ValidateHddPopstarterExecGate()` while keeping the generic `pfs:/...` exec path for the partition-aware C loader contract.
  - a later 2026-05-20 report narrowed the non-HDD POPSTARTER regression to default/cwd sidecar resolution: explicit `mass:/POPS/POPSTARTER.ELF` launches, but default `POPSTARTER.ELF` can stop at `Cant find POPSTARTER ELF`. Current source now includes the live current directory in sidecar lookup and derives fallback sidecar paths from boot/app directories instead of blindly appending to raw boot strings.
  - 2026-05-20 simplification pass addresses the over-engineering risk: normal HDD-backed POPSTARTER launches no longer use Lua partition context, generic `pfs:/...` exec rewriting, the Lua HDD pre-exec gate, the mounted-PFS fallback remount path, or the embedded-loader reboot path by default. They keep the resolved executable path and call legacy `System.loadELF(path, 0, selector)`.
  - a 2026-05-20 hardware result on that direct non-reboot artifact still black-screened before POPSTARTER debug screens, so the next source pass removes the remaining HDD-only parent-side pre-`ExecPS2` cleanup from `LoadELFFromFileExecPS2()` (`fileXioUmount`, `SifExitIopHeap`, `SifExitRpc`, `SifExitCmd`) to match the working non-HDD POPSTARTER handoff more closely.
  - hardware status after the 2026-05-20 source follow-up remains `Unknown (verify on hardware)`. The handoff doc verification sequence (`D-15` first, then `D-10` `X`, then `D-10` `R2`, then `D-14`, then `D-12` sanity, then `U-10` separately) still applies.
  - current source still keeps the `R2` selector-path experiment for HDD game launches, but that remains secondary to restoring and preserving the non-HDD POPSTARTER baseline for HDD titles.
- `BOOT.ELF` after HDD page init:
  - repo history shows the BOOT.ELF modal originally used a simpler non-reboot `System.loadELF(elf_path, 0, elf_path)` path without launch-CWD setup, and later source changed it to `reboot_iop = 1` plus launch-CWD.
  - a later 2026-03-29 hardware report said BOOT.ELF still behaved incorrectly once HDD runtime had been initialized, which points more narrowly at carried HDD/IOP state than BOOT.ELF lookup itself.
  - current working inference is that this `U-10` failure may share the same underlying handoff/state-poisoning boundary as `D-10`, but that remains an inference rather than a proven shared root cause.
  - current source therefore keeps the no-launch-CWD rollback, re-enables `reboot_iop = 1` for BOOT.ELF only when HDD runtime has already been loaded, and uses a BOOT.ELF-specific cold external-launch prep that clears the exec keep mask and unmounts tracked HDD slots instead of preserving boot PFS state.
  - current hardware status on that conditional-reboot/cold-prep source is still `Unknown (verify on hardware)`.
- PAL asset proportions:
  - code compensates for PAL layout,
  - final display result still needs hardware confirmation.
- 2026-05-22 Diagnostic Sentinels & USB Control Test Decision:
  - A series of targeted sentinels were executed to debug the post-load/post-reset SIF RPC handshake hang (Teal/Blue freeze) on D-10.
  - SifLoadFile (`SENTINEL_SIFLOADFILE_POPSTARTER.ELF`) and fileXioInit (`SENTINEL_FILEXIOINIT_POPSTARTER.ELF`) sentinels passed on hardware, showing that initial target-side setup and fileXio services are fully stable post-handoff.
  - Post-reset SifInitRpc sentinels (`TARGET-IOPRESET`, `POST-RESET INITCMD SPLIT`, and `POSTINITCMD RPCMODE1`) hung, proving the rebooted IOP fails to respond to RPC initialization.
  - Manual RPCINIT handshake probing and retry sentinels timed out, confirming the IOP does not signal `SIF_SREG_RPCINIT` after resetting.
  - Resetting the IOP with UDNL arguments (`SifIopReset("rom0:UDNL rom0:EELOADCNF", 0)`) via `SENTINEL_TARGET_IOPRESET_UDNL_RPCINIT_POPSTARTER.ELF` also timed out (PURPLE/MAGENTA loop), ruling out the blank reset argument as the sole cause of the SIF handshake hang.
  - The USB control path (USB POPSLOADER.ELF + USB sidecar/CWD POPSTARTER.ELF) was verified on hardware to work successfully, including when selecting games from the HDD listing.
  - *Source/Device Boundary established*:
    - **Known-good**: USB POPSLOADER.ELF + USB sidecar/CWD POPSTARTER.ELF works, including when selecting HDD games.
    - **Known-bad**: HDD POPSLOADER.ELF + HDD sidecar/CWD POPSTARTER.ELF fails. HDD POPSTARTER.ELF fails regardless of selected game device/listing.
    - **Interpretation**: The failure does not follow the selected game device or the HDD game listing by itself. The failure follows the HDD-backed POPSTARTER / HDD-backed loader-origin state.
  - *Updated Diagnostic Boundary*: The next investigation focuses on what differs when POPSTARTER.ELF is resolved, loaded, and executed from HDD versus USB sidecar/CWD, including file-open/mount state, current working directory/source device state, argv/environment passed to POPSTARTER, and IOP module state left behind by loading the target ELF from HDD.


