Skip to content

2026-10-27 glue-up (single local session, main)

A deep-integration pass over everything landed on 2026-10-27: no new features, only hooking finished code that nothing called, small fixes, and a local test of every suite and puppeteered run. Everything below ran on this Mac from the working tree that became the commits named here.

Hooked / fixed

  • Web and album applets (applets-rare landed them with no caller): service_register_applet registers the web / offline web (0x13, 0x17) and album (0x15) handlers through libapplet_register_handler, so ILibraryAppletAccessor::Start reaches them before the "not implemented, cancelled" branch. caps.c hands its album state to the album applet (applet_album_set_source). The offline document root is <data-dir>/html when it exists (NAPPLE_HTML_ROOT overrides). The frontend hooks (applet_ui.h) stay unset: the web applet answers "left at once" and the album "nothing picked".
  • Stencil view slots (shader-rare-ops asked the replay for it): pipe_key.stencil_slots[2], filled by ds_slot_masks next to the depth slots (a depth-stencil texture bound in STENCIL mode, or a Stencil8 texture, is a stencil slot and no longer a depth slot), copied into the stage ShaderKey. The translator already declared texture2d<uint> for those slots and the replay already bound the X32_Stencil8 view; now the key says so.
  • fs.c rows 1003 / 1005 / 1006 are IPC_IMPL with the reason (the console's offline answers: no auto save creation, log mode 0, nothing to the SD card).
  • test_timescale flake (seen twice under load): the 3x skew check assumed a 200 ms sleep and a zero accumulated skew; the earlier sections' retry loops leave a variable skew. It now measures the delta over the real elapsed time.
  • NAPPLE_AUDIO_DEVICE=0 keeps a windowed run on the null sink (before, only headless runs could be silent).
  • applet.c: the unused af_event is gone (cmd 210 uses af_event_210).

  • Deterministic a32jit.dylib: two builds of MK8D differed in 51 bytes, the linker's default install name (the per-pid temp work path) and the content-derived UUID. The link now passes -install_name @rpath/a32jit.dylib (the runtime dlopens by absolute path); two builds hash identically.

  • Mii Maker died at 0.1 s (e2e mii-db FAIL, ThrowFatal 2115-0064): ipc-polish made nfc:sys real, and the applet's first call on the system interface is SendCommandByPassThrough with no device selected; the simulated INfc answered DeviceNotFound, which the applet treats as fatal (the old catch-all stub had answered "success, no output"). nfc:sys now hands out an INfcSystem object whose pass-through answers empty before a device is selected (nfc:user keeps DeviceNotFound); test in test_svc_offline_depth (+2). The Mii Maker runs its 20 s again.

  • Studio Devices pane put up a macOS password prompt ("xcodebuild is trying to install Apple software"): xcrun devicectl makes Xcode finish its first launch (its device-support components). DeviceService.allDevices now runs xcodebuild -checkFirstLaunchStatus first (never prompts; exit 69 = pending) and shows a note saying the one-time prompt is Xcode's, then lists as before (on this Mac the status stays 69 after the components are in, so the note never blocks the listing). Nothing was entered into the prompt by this session; the user accepted it, and devicectl / simctl run silently since.

Verified here

  • Clean rebuild (napple_latest.sh build, commit 06747ed + the a32 fix): cargo, gfx, audio, input, frontend, runtime, studio suites all PASS; signature ok.
  • make -C runtime test test-services test-host and make -C gfx test green on the glue commit (test_timescale 55/55 after the fix).
  • MK8D data built four times: before the fix two different dylib hashes, after it two identical ones (27876dd5…), manifest unchanged throughout.
  • Final package (napple_latest.sh build, then --incremental for the last Studio commit): all seven suites PASS (Studio 64/64), signature ok, ~/Desktop/NappleLATEST (BUILD_INFO.txt names the commit).
  • tools/e2e/run.sh all with NAPPLE_AUDIO_DEVICE=0 (no sound played; the "audio PASS" rows are the PCM counter on the null sink): LAS, SMO, ACNH and MK8D build, bundle, camera-mic, boot, audio, input, save, overlay all PASS; mii-serve PASS on MK8D; amiibo N/A on all four (the routes never reach StartDetection). The one FAIL, LAS mii-db (the Mii Maker fatal above), is PASS on the re-run after the fix (Mii in the shared database, 0 -> 2).
  • Golden routes inside the e2e (report only): every title exit 0, 0 gfx warnings, 0 Metal validation, no crash (LAS 8647 frames, SMO 14755, ACNH 2620, MK8D 8431). Frame diffs against the stored goldens remain on several frames (LAS 1500/3000/4500, SMO 4000, ACNH 1200, MK8D 1500/3000/4500; SMO 8000/9000 have no golden); nothing approved here, same pattern as the earlier integrations (run-to-run noise at those frame numbers).
  • Studio --debug-tour: 7 panes captured twice (before and after the Devices fix); every pane renders; the second tour shows the Devices pane listing the paired iPhone with no system prompt.
  • Mii Maker headless 20 s run (LAS applet dir, audio off): exit 0, no fatal, the pass-through answered empty once.
  • Not run: anything on an iOS device; the fuzz/ crate; the 280 s SMO and 150-start LAS checks of kernel-threads.

Not done: bigger work found (the list for the next planning round)

  1. Web / album frontend UI (runtime/src/services/applet_ui.h): no WKWebView sheet and no image viewer exist in frontend/; the hooks are null, so a title opening the web applet gets "the user left at once" and the album never shows a picture. Needs frontend work on the game window (a sheet over the Metal view, modal to the guest thread) and a frontend -> runtime registration path like frontend_text_input.
  2. HtmlDocument extraction at build time: napple build does not extract the HtmlDocument (manual) NCA of a title, so <data-dir>/html never exists and offline web pages cannot resolve. crates/napple-build (content type html is already recognised in fwlist.rs) should write it next to romfs.map.
  3. RomFS mod overlay in the runtime (docs/mods/integration.md item 2): romfs_overlay_* is loaded and tested but fs.c serves the RomFS as a raw IStorage image (the guest parses the directory tables itself), so a path-level overlay needs either a host-side RomFS reader that rebuilds the directory/file tables with the overlay merged, or the builder re-packing the image. Not a glue change.
  4. Mod cheats, config, shader replacement, Studio/overlay UI (docs/mods/integration.md items 3-6): all still open; each is a feature.
  5. ACNH load-only null deref (main+0x6d65a4, kernel-threads KNOWN) and the unreproduced Break / SIGBUS; also the cold-boot race at the olsc:u open (about 1 in 10 runs). Needs the writer of the singleton field (NAPPLE_SVC_RING / NAPPLE_THREAD_LOG hunt).
  6. Stencil sampling by a real shader: the key is wired, but none of the four titles samples a stencil view, so the uint path is only covered by t_xlate.
  7. iOS device limits (ios-candidate): colour attachment sets over 32 bytes (SMO), cube array textures (ACNH), RGBA8 -> RGBA32Uint view usage (MK8D); plus padding tiny applet module images so the Mii Maker module wraps on iOS.
  8. fuzz/ crate never built on the Mac (needs nightly + network); the C fuzz targets run (make -C runtime fuzz-regress), the ipc target is Linux-only.
  9. Unused core API (not dead on purpose, but nothing calls them, not even tests): mii_db_set_storage (iOS provider hook), time_info_read, bsd_lookup, irs_core_access_done, nfp_build_*, mii_new_create_id, ngc_words_clear. Either a test each or a removal, later.
  10. docs/todo.md items stand (BC block-grid copy-back, hid trace masks, tinyjson duplicate, fs.c/applet.c split, linux-check time mock).