Skip to content

Open work markers

Deferred work that used to live as TODO comments in the source, plus defects found by the 2026-10-26 slim pass that need a Mac to settle. Third-party and vendored files are not listed (for example gfx/src/nvnapi/nvn.h carries four upstream "TODO: reverse and define" notes from its author).

File What Why deferred
runtime/src/services/hid.c (emulate_load, NAPPLE_HID_TRACE only) The ldur/ldurs and pre/post-index masks never matched (the value had bit 22 set but the mask did not cover it); they now require opc != 0 like the unsigned-offset branch. The decode was checked against real encodings on Linux, the emulator itself only runs on Darwin. Verify on a Mac with NAPPLE_HID_TRACE=1 that loads of these forms are now traced instead of reported unhandled.
input/src/tinyjson.h, frontend/src/tinyjson.h Identical copies kept in sync by a cmp in input/Makefile; one shared header would remove 200 duplicated lines. The fix touches the Makefiles (mac-slim) and the include paths of both libraries.
runtime/src/services/fs.c (833 lines), applet.c (474 lines) Split into smaller files. No Linux build exists for fs.c (needs macOS headers), so a split cannot be tested here.
runtime/tests/test_svc_time.c (linux-check) Fails to link on Linux: time.c needs host_symbols_register, which tools/linux-check/ipc_mock.c does not provide. Pre-existing; a one-line mock addition in the Linux harness.

ACNH start flake (host crash fixed 2026-10-28 b8; guest race fixed 2026-11-01 r3: exclusive ordering)

Headless ACNH starts failed about 10-30% of the time on the base build and about 5% on the update build (host SIGSEGV/SIGTRAP/abort in the gfx command recorder; also a guest null read at main+0x1b61xxx, and on the update build a guest Break at sdk+0xc80730 after "program hash 0x3 is not a shader hash"). - Cause (gfx-recorder-flake, docs/archive/changes/2026-10-28-claude-gfx-recorder-flake-2026-10-28-b8.md): two guest threads record the same object's command list at once (main+0x1ae75c0 binds a stack-allocated context into a shared per-object slot). One thread then works on the other's stack-allocated NVNcommandBuffer while its owner finalizes, re-initialises and finally overwrites it. The old recorder turned that into a use after free, realloc races and a 64-byte static scratch overflowed by large commands. - Fixed in gfx: host parts are addressed by slot+generation and never freed; the recording state is locked; grown buffers are freed late; unrecorded commands go to a payload-sized sink. gfx/tests/t_cmdshare.c reproduces the misuse without a game. - Still open (runtime): why the two threads overlap. On hardware the game must keep them apart; NVN command buffers are not thread-safe. Timer preemption makes the overlap likelier (60 x 5 s base starts: 2 with overlap at the default slice, 0 with NAPPLE_SLICE_MS=0). Find it with NAPPLE_GFX_CBTRACE=1, which dumps both threads' events and backtraces. After the gfx fix: update+DLC 0 of 40, both builds 0 of 10 under MallocScribble, base 3 of 40, all three guest null reads (main+0x1b61d3c, main+0x19d04d4, main+0x667178) with no recorder warning and no host heap crash. Recheck these after the runtime fix. - 2026-11-01 (sched-applets, docs/archive/changes/2026-11-01-claude-sched-applets-2026-11-01-r1.md): not a scheduling bug. Two real Horizon divergences were fixed (equal-priority rotation only at priority 59; a preempted thread keeps the head of its priority), but ACNH base overlaps as often as before (30 s starts with NAPPLE_GFX_CBTRACE=1: base-commit scheduler 8 of 20 runs, final 11 of 40) and also with NAPPLE_SLICE_MS=0 (2 of 10): timer preemption is not the trigger (the earlier 0-of-60 was a small 5 s sample). Guest crashes main+0x1b61d3c 0/20 old vs 2/40 new: too few to compare. The update stays clean (10 of 10). - The collision is always the guest main thread 0x51 (core 0) against worker 0x57/0x58 inside the same parallel-for job path (dispatcher main+0x19b7460, item method 0x19b654c, view method G 0x1ad9018, recorder F 0x1ae75c0); job pop and item claim are proper spinlocks. The job manager's own "wait for workers" (0x19b6ed0) is compiled to discarded loads and does not wait (same shape in the update at 0x390d2b0, so not sufficient as an explanation). Next: find the real join of the main thread with the job group (after 0x1b4d164 / 0x197a248; the per-job done counter [job+0x70]) and check the wait primitive it uses (kernel or gfx sync). - Fixed 2026-11-01 (acnh-race-atomics r3, docs/archive/changes/2026-11-01-claude-acnh-race-atomics-2026-11-01-r3.md): the job's item-claim spinlock (main+0x19b65d4) acquires with plain ldxr/stxr; Apple cores run the protected loads early, so two threads claimed the same items (litmus on this Mac: thousands of double claims per 41 M with ldxr, 0 with ldaxr). napple-rewrite now gives every exclusive pair acquire/release ordering; title data must be rebuilt. The kernel sync path (LightEvent / MessageQueue svcs) was traced at a real collision and is correct. Open: the AArch32 lifter still emits plain ldxr/stxr for ldrex/strex.