chore: add migration/ bundle for cross-machine setup
Bundles state that lives OUTSIDE the xenia-rs repo so a fresh clone on
another machine can be brought up to identical configuration via
migration/setup.sh:
- claude-memory/ ~/.claude/projects/-home-fabi-RE-Project-Sylpheed/memory/
(103 files, 1.1 MB - MEMORY.md + every
project_xenia_rs_*.md from audits
addis_signext through audit-058)
- project-root/dot-claude/ <project-root>/.claude/settings.json
(Stop hook + permissions)
- project-root/ppc-manual/ <project-root>/ppc-manual/
(PowerPC reference docs, 397 files, 3.7 MB)
- project-root/run-canary.sh <project-root>/run-canary.sh
- README.md Human-readable setup checklist
- setup.sh Idempotent installer (also reclones
xenia-canary at pinned HEAD 6de80dffe)
- MANIFEST.md Per-file mapping + per-file-not-bundled
restoration recipe
Excluded from bundle (not shippable via git):
- Sylpheed ISO (7.8 GB; copyright; manual copy required)
- sylpheed.db (395 MB; regenerable from XEX via analysis tooling)
- target/ build artifacts (rebuild on target)
- audit-runs probe firehoses (.log/.stdout/.stderr ~11 GB; rerun if needed)
- audit-runs memory dumps (.bin ~4.5 GB; rerun audit-026/027/029 if needed)
- xenia-canary checkout (setup.sh reclones from
git.mc02.dev/fabi/Xenia-Canary.git at HEAD 6de80dffe)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
105
migration/claude-memory/MEMORY.md
Normal file
105
migration/claude-memory/MEMORY.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Memory Index
|
||||
|
||||
- [audit_058_sub825070F0_activation](project_xenia_rs_audit_058_sub825070F0_activation_2026_05_10.md) — Canary fires sub_825070F0 1× after `DiscImageDevice::ResolvePath(\\dat\\movie)`. Static caller ladder (6 levels: sub_824F7800 ← sub_824F7CD0 ← sub_824F8398 ← sub_821B55D8 ← sub_821B6DF4 [top]). ALL 6 fire 0× in ours. Break is NOT CRT-fnptr-array — it's the AUDIT-049 main-thread wedge (handle 0x12A4 wait at 0x824ac578) blocking the entire post-intro phase. Vtables 0x8200A208/0x8200A928 have **zero vptr_writes in DB** — writer ctor is computed-store-only OR in unreachability island. Confirms AUDIT-050 half-bootstrap: vtable-writer subset dead. AUDIT-059: pivot to unblocking the wedge (049+057 unified γ-investigation), not chasing caller-ladder further.
|
||||
- [audit_057_thread_gap](project_xenia_rs_audit_057_thread_gap_2026_05_10.md) — Canary 23 thread-spawns / ours 10 = **13 missing**. 8 distinct missing-thread spawners. **Top: sub_825070F0** (4 missing, initializes 4 workers w/ shared ctx 0xBCE25340, entries 0x82506528/58/88/B8). **11 of 13** from spawners that don't fire at all in ours — same audit-050 CRT-fnptr-array unreachability. sub_821C4EB0 fires (1×) but early-returns (audit-056); sub_821746B0 fires 1× / should spawn 2. AUDIT-058: probe sub_825070F0 activation chain in canary, find fnptr-array entry ours doesn't enumerate. Cascade D 10-20% (multiple independent gaps).
|
||||
- [audit_056_producer_trace](project_xenia_rs_audit_056_producer_trace_2026_05_10.md) — LR distribution at sub_82452DC0: canary 45/60s vs ours 14/26s (3.21× ratio). **Two CANARY-ONLY divergence introducers**: (a) sub_821C4EB0 calls sub_821CEDF8 5× in canary, 0× in ours despite IDENTICAL caller-LR — early-exit somewhere in +0x44..+0xE0; (b) sub_824AFF88 thread-trampoline fires 5× canary / 0× ours — **12 vs 30 XThread count gap** (18 missing threads). 3.0× thread-count ratio matches 3.21× throughput ratio. AUDIT-057: probe sub_82174828 + post-bl PCs inside sub_821C4EB0 (`0x821C4F2C/0x821C5014/0x821C5048`); fallback = audit which 18 thread-creates fail to land. Wine canary not yet justified.
|
||||
- [audit_055_subB078_internal](project_xenia_rs_audit_055_subB078_internal_2026_05_10.md) — Probed sub_8245B078's body with cache override: BODY EXECUTES CORRECTLY (internal call parity ~98%, sub_8217FA08 2449/2411). Divergence is UPSTREAM — sub_82452DC0 fires 5.6× less in ours. Sharpest specific divergence: sub_8217FA08 from LR=0x82455E60 (=sub_82455DF0+0x70), canary 20 / ours 0. Bug class refined: **δ-throughput** (producer of work items doesn't fire at canary rate). AUDIT-056 recommendation: probe sub_82452DC0 entry, aggregate LR distribution upward.
|
||||
- [audit_054_vfs_layout_landed](project_xenia_rs_audit_054_vfs_layout_landed_2026_05_10.md) — **TRACK A LANDED**: commits `2a8ff95` (74 LOC) + `ac2f89a` (golden re-baseline). FILE_DIRECTORY_FILE bit threaded through nt_create_file → open_cache_file. `cache:\<HASH>` with disp=2 opts=0x4021 → mkdir; leaf paths with opts=0x4020 → file. Closes ζ-class layout aliasing. Track B persistent cache OPT-IN via `XENIA_CACHE_PERSIST=1`; default keeps AUDIT-038 wipe for lockstep. Cascade A/B confirmed via AUDIT-053 Phase 1 (canary cache override); **cascade C/D STILL FAIL** — cache is necessary but not sufficient. Warm-start regression (cxx_throw=10) when persistent enabled — our cold-start halts at swaps=1 producing half-baked .tmp journals. Next: probe sub_8245B078 internal body to find next gate.
|
||||
- [audit_053_cache_layout_bug](project_xenia_rs_audit_053_cache_layout_bug_2026_05_10.md) — Phase 1 confirms AUDIT-052 gate hypothesis (PCs `0x82452E30`/`0x8245B078`/`0x8245AD94` go 0→6 with canary cache override; cascade A/B PASS) BUT cascade C/D FAIL (NtSetEvent 68→63, VdSwap=1 unchanged). Phase 2 permanent fix REVERTED — warm-start regression from VFS layout aliasing: `open_cache_file` treats all `NtCreateFile` as files, but `cache:\d4ea4615 disp=CREATE` is meant as a DIRECTORY. 0-byte file blocks hierarchical creates. AUDIT-038 wipe masked this for 14 audits. **15th reading-error class ζ**: VFS layout aliasing. AUDIT-054 = honor `FILE_DIRECTORY_FILE` bit + retry persistent cache.
|
||||
- [audit_052_cache_root_cause](project_xenia_rs_audit_052_cache_root_cause_2026_05_10.md) — **🔥 ROOT CAUSE FOUND**: AUDIT-051 struct hypothesis REFUTED (struct bit-identical canary/ours). `[r3+0]`/`[r3+4]` are halves of a hash key formatted into `cache:\<HASH1>\<X>\<HASH2>` paths. Real bug: `NtQueryFullAttributesFile` returns -1 for `cache:\*` in ours because **AUDIT-038's per-boot tmpdir cache is WIPED every startup**. Canary's `~/.local/share/Xenia/cache/` is persistent + pre-populated (d4ea4615/e/46ee8ca etc — game-built shader/PSO/material caches). **Reading-error class #15**: AUDIT-038 "missing-or-stale ≡ fresh" assumption invalidated. Fix = persistent cache (`crates/xenia-kernel/src/state.rs:387-398`). Cascade A/B/C HIGH; D 30-40% (cache may not be only gate).
|
||||
- [audit_051_work_submitter_trace](project_xenia_rs_audit_051_work_submitter_trace_2026_05_10.md) — **CONCRETE DIVERGENCE FOUND**: `sub_8245B078` fires 18× canary / 0× ours. Gate at `sub_82452DC0+0x78` (PC `0x82452E2C beq cr6, 0x82452E88`) controlled by `sub_8245B000` returning 1 iff `[r3+0]≠0 AND [r3+4]≠0` for 80-byte stack-local struct at `r31+96`. Ours has one of those fields NULL — missing-population. Struct upstream-written by `sub_8245AE50`/`sub_82452068`/`sub_82452200` (fire in both, ours doesn't write right fields). **Single root cause** for AUDIT-047's 4 wedges (0x10A0/0x10A4/0x1530/0x1534) via `sub_8245AD00` + plausibly tid=13's stall on 0x1288. Direct-bl divergence (NOT vtable) — at this level. AUDIT-052: dump struct at PC `0x82452E1C` in both engines, find NULL field, identify missing writer. Cascade D 20-30% (5 vtable dispatches downstream might re-hit island).
|
||||
- [audit_050_reframe](project_xenia_rs_audit_050_reframe_2026_05_10.md) — **🔥 METHODOLOGICAL REFRAME (2026-05-10)**: 11 prior audits' "audit-009 cluster unreachable" claim is STATIC-ANALYZER ARTIFACT. `--ctor-probe` shows CRT driver `sub_824ACB38` (called from entry_point) iterates 0x82870xxx fnptr arrays (557 slots, 82 non-NULL); `sub_8280E148` (RegisterToFactory<silph::GamePart_Title>) fires at cycle 1.4M; tid=13 chain (sub_821C4EB0/sub_821CC3F8/sub_821CBA08/sub_821CB030) fires; **work-submitter sub_82452DC0 fires on tid=13 at cycle 8127**. Real bug = γ missing-signaler inside sub_82452DC0's descendant tree. **14th reading-error class**: BFS-only insufficient when binary uses CRT-driven fnptr arrays. **Angle B (-n 5B) DEFINITIVELY FALSIFIED** (bit-identical to 500M). Cluster is HALF-bootstrapped (worker-thread subset live, vtable-writer subset dead) — virtual dispatches hit garbage. Wine canary no longer only route. Top angle: probe sub_82452DC0's 9 direct targets + 1 ind_call (`0x8245AE50,0x82452068,0x82452200,0x8245B000,0x8245B078,0x82454A40,0x82452AB8,0x82454918,0x82452EC4`) in both engines, find divergent branch. Cascade D=draws>0 YES POSSIBLE 30-50%.
|
||||
- [audit_049_tid1_stall_0x1280](project_xenia_rs_audit_049_tid1_stall_2026_05_10.md) — Post-AUDIT-032 wedge: handle 0x1280 = **Thread handle** for tid=13 (not event); tid=1 is doing thread-join. Real sub-stall: tid=13 waits INFINITE on event 0x1288 (created at `sub_821CB030+0x128`, in audit-009 cluster front-end UI). 5 NtSetEvent callers in worker cluster `0x82450000-0x8245C000`: only `sub_82452DC0` (work-submitter) statically reachable; rest unreachable. tid=13 create-chain: `sub_821748F0`→`sub_821C4EB0(UImpl@GamePart_Title@silph)`→`sub_821CC3F8(AVGamePart_Title)`→`sub_821CBA08`→`sub_821CB030`. All in audit-009 island. Discipline 3/5 PASS, D=draws>0 NO. **5th consecutive audit (044/045/046/047/049) converging on same unreachability island.** Path 1 (Wine canary) now justified per user's "meaningful progress" framing.
|
||||
- [audit_048_audio_host_pump_fix](project_xenia_rs_audit_048_audio_host_pump_fix_2026_05_10.md) — **PATH 2 LANDED in working tree (not committed)**. AUDIT-032 audio fix: dedicated audio worker thread per client, 75 net LOC across 4 files. Cascade A/B/D ✅ — tid=9/10 unblock from `0x828a3254`/`0x828a3230`, KeReleaseSemaphore 0→1, xaudio.callback.delivered=1. swaps 2→1 (degenerate splash lost). draws 0→0 (expected — audio≠renderer per AUDIT-032). **Boot phase advanced**: NtWaitForSingleObjectEx 1.4M→30, NEW StfsCreateDevice/XamContent*/ExCreateThread×10/XeCryptSha/etc. New stall: tid=1 main Blocked on handle 0x1280 at pc=0x824ac578. Tests pass (kernel 127/127, app 5/5 non-ignored). Lockstep goldens deferred (will drift).
|
||||
- [autonomous_run_synthesis](project_xenia_rs_autonomous_run_synthesis_2026_05_10.md) — **AUTONOMOUS-MODE SYNTHESIS (2026-05-10, sessions 5-8 of 10 used; 9-10 RESERVED)**: 4 audits (044-047) refuted 4 hypotheses; no fix landed; no draws cascade; methodological floor reached within Linux Debug + READ-ONLY discipline. Cluster activation past Linux Debug horizon. Best near-reachable signaler `sub_8245AD00` covers 4 wedges but its callers sit in audit-009 unreachability island. KeReleaseSemaphore 0 ours / 73,914 canary = AUDIT-032 audio host-pump gap (already named). Three paths forward (user pick): (1) Wine/Lutris canary build for new oracle [HIGH effort/reward], (2) audit-032 audio host-pump fix [MEDIUM effort, D≠draws], (3) guest-thread injection [HIGH risk]. Sessions 9-10 held in reserve.
|
||||
- [audit_047_gamma_wedges](project_xenia_rs_audit_047_gamma_wedges_2026_05_10.md) — 10 NO_SIGNALS handles inventoried + XAudio. `sub_8245AD00` reachable, covers 4 wedges (0x10A0/0x10A4/0x1530/0x1534), but callers in audit-009 island. Of 125 signal-source fns, only 2 statically-reachable + near-wedge: sub_8245AD00, sub_82450218. KeReleaseSemaphore 0/73914 canary divergence = known AUDIT-032 audio host-pump (PC 0x824D229C, r3=0x828A3230). Discipline 3/5 PASS, D=draws>0 NO. γ-wedge convergence: all hit audit-009 unreachability island.
|
||||
- [audit_046_loop_exit](project_xenia_rs_audit_046_loop_exit_2026_05_10.md) — REFUTES audit-035 slot-pointer-region divergence as causal AND audit-034 "canary 3.75/5 vs ours 5/5" iter divergence. Both engines run 5/5 iters at sub_82450720+0x160..+0x1F4, fall through to no-match exit. Slot-table region split (canary 0xBC3xxxxx vs ours 0x4024xxxx) is REAL but BEHAVIORALLY INERT — predicate compares within each engine's own heap region. **Drop sub_82450720 chain as critical-path target.** Reading-error #13 (mid-block PC unprobeable in ours) reconfirmed; workaround via post-bne block-entry PC `0x82450908`. Recommended AUDIT-047: γ-cluster handle wedges per audit-042 (handles `0x10A0+0x10A4`, `0x12AC`, `0x1004`, etc).
|
||||
- [audit_045_cluster_ctor_probe](project_xenia_rs_audit_045_cluster_ctor_probe_2026_05_10.md) — REFUTES audit-044 ctor hypothesis: `0x8228FAC8` (vptr write) + `0x8228F858` (ctor entry) fire **0× in CANARY too** at 50s. Cluster genuinely not activated at this horizon either engine — RECONCILE-B (Linux Vulkan/XCB) blocks before front-end-UI activation. T6 (audit-033 LR `0x82172BF8`) fires in both — gateway chain `entry→sub_8216EA68→sub_822F1AA8→sub_82172BA0` runs; cluster-ctor branch off it doesn't. **13th reading-error class**: probe-firing-granularity — ours `--pc-probe` fires only at basic-block entry, canary `--log_lr_on_pc` per-instruction; mid-block PCs systematically give ours=0. Recommended AUDIT-046: probe loop-exit predicate `0x82450904` (audit-034 5/5 vs 3.75/5 divergence). DB caveat: `v_call_graph` uses `xrefs.source`; prefer `xrefs.source_func` for caller-set queries.
|
||||
- [audit_044_m55_cluster_survey](project_xenia_rs_audit_044_m55_cluster_survey_2026_05_09.md) — M5.5 lifts cluster `0x82285000-0x82294000` from 0/321 static-reach to 41/321 indirect (12.8%); only 4 vtable methods are entries. Cluster's 6 vptr-writer constructors all dead. Top probe: `sub_8228F858` writer at `0x8228FAC8` (vtable `0x820a9c28` ctor). Audit-033 chain ends genuinely at `sub_821CECF0`/`sub_821C4988` (7-hop BFS finds no ancestor). M5.5 `cand_count≤10` actionable; `=203` noise.
|
||||
- [project_xenia_rs_audit_043_record_zero_offset_2026_05_09.md](project_xenia_rs_audit_043_record_zero_offset_2026_05_09.md) — **🎯 KRNBUG-AUDIT-043 (2026-05-09, READ-ONLY, master `d8766c6` tests 645)**: identifies writer of +0x00 at "records" 0x40542300/40/400/4C0. Mem-watch (-n 500M) → writer = memcpy `pc=0x825F1080 lr=0x825ED608` called from `std::basic_string::reserve_then_assign sub_8216E138+0xC8`. **Records are not records** — they are 64-byte slots in Sylpheed's pool allocator (`sub_821505D8` allocs 58MB via `sub_824A8858`; `sub_82152728` chains 64-byte free-list over 1.25MB; bucket sizes 4/16/32/64/96/128/160/192/256). Audit-030 patch reapplied; canary probe at `pc=0x825F1080`: 94,945 fires/25s, **zero hit `0x40542xxx`**, top destinations `0x705Dxxxx`/`0xBC36xxxx` (canary's pool base = `0xBC32C880` per pool-init probe). **Audit-039's "0xF80000B8 vs game" comparison is a VA-equality fallacy**: same guest VA backs different live data because allocator returns different host VAs in canary vs ours. Bug class **ε (host-allocator address-space divergence)** — NOT a guest-write bug, NO missing/wrong write at +0x00 in our impl. **Reading-error ledger 12th entry**: VA-equality fallacy across emulators — comparing memory at identical guest VAs assumes both allocators return same VA for same logical alloc; Sylpheed's pool factory makes this assumption false in general. **Recommended audit-044**: drop "record at 0x40542300+" line entirely; pivot to audit-042's actually-stalled-handle plan (0x10A0+0x10A4 worker pair, 0x12AC sema, 0x1004 event/manual). Bug class for next = γ (missing signaler). Trace `audit-runs/audit-043-record-zero-offset/{mem-watch.log, mem-watch.stdout, canary-825f1080-traces.txt.gz, audit-043-canary-poolinit.log}`. Discipline 5/5 PASS; canary patch reverted clean; xenia-rs source unmodified.
|
||||
- [project_xenia_rs_audit_042_handle_lifecycle_2026_05_09.md](project_xenia_rs_audit_042_handle_lifecycle_2026_05_09.md) — **🎯 KRNBUG-AUDIT-042 (2026-05-09, READ-ONLY, master `d8766c6` tests 645)**: disambiguates audit-041 root cause for handle 0x1454 missed wakeup. Re-applied audit-030 canary patch (30 LOC, reverted clean canary `6de80dffe`). Method: ours `--trace-handles-focus=0x1454` (existing audit.rs); canary `--log_lr_on_pc=0x8284DF1C` (NtCreateEvent ord 209) + cross-ref audit-041 log. **STRUCTURAL FINDING**: `KernelState::alloc_handle` (state.rs:588) is **monotonic atomic counter** `fetch_add(4)` from 0x1000 — **bump-only, NO recycling, structurally impossible**. `nt_close` removes object but never returns ID to pool. **Lifecycle of 0x1454 in ours** (2 reruns identical): created tid=13 lr=0x824a9f6c (NtCreateEvent, kind=Event/Manual), waited tid=13 lr=0x824ac578 (do_wait_single), signaled tid=5 lr=0x824aa304 (NtSetEvent), wake fired (wake_eligible_waiters/auto). Final: waiters=0 signaled=true wakes=1 — **fully consumed, NOT stuck**. Created stack frames sub_822DFC74←sub_822E0344←sub_822D2CA4←sub_822DE768←sub_821C4B1C. **Lifecycle of canary F80000CC family**: 5+ Added/Removed/Added cycles in 30s (XObject→XEvent→XEvent→...). **Slab/free-list allocator**: F8000098 reused 130×, F80000D0 95×, F80000DC 71× per 30s window. **VERDICT: ROOT CAUSE NOT (A) HANDLE-RECYCLING** — recycling structurally impossible in ours; signal lands on same KEVENT object the wait registered for. **Audit-041's premise provisionally falsified for 0x1454**: audit-041 inferred stall from `--lr-trace` "7 pre-bl, 6 post-bl" but ran `--quiet` so end-of-run dump was suppressed; post-bl miss explained by KeWaitForSingleObject's wake-side context-restore bypassing post-bl PC. **Real wedges** (this run's stalled handles): `0x1004` (tid=11), `0x1020` (tid=3), `0x1040` (tid=5), `0x1544` (tid=17), `0x1578` (tid=19), `0x12ac` (tid=14,15), `0x10a0+0x10a4` (tid=6) — all `<NO_SIGNALS_DESPITE_WAITS>`. **Bug class**: δ-namespace + δ-wakeup BOTH RULED OUT for 0x1454; wedge migrates to **γ (missing-signaler)** on different handle set. Sharp 4-dim cascade prediction (audit-043 fix on real handle): A=signal_attempts 0→≥1, B=stalled tid Blocked→Ready, C=`<NO_SIGNALS>` count drops ≥2, D=swaps>2 OR draws>0 (low probability — γ-cluster plateau). **Recommended audit-043**: pivot to (1) `0x10a0+0x10a4` Event+Sema worker pair on tid=6, (2) `0x12ac` Sema with 2 waiters, (3) `0x1004` Event/Manual on tid=11. Trace `audit-runs/audit-042-handle-lifecycle/{probe.log, probe-run2.log, canary-create-0x8284DF1C.log}` (~11.5 MB). Discipline gate 5/5 PASS. xenia-rs source unmodified, no commit.
|
||||
- [project_xenia_rs_audit_041_wait_site_2026_05_09.md](project_xenia_rs_audit_041_wait_site_2026_05_09.md) — **🎯 KRNBUG-AUDIT-041 (2026-05-09, READ-ONLY, master `d8766c6` tests 645)**: wait-site signaler determination. Re-applied audit-030 patch (30 LOC, reverted clean canary `6de80dffe`). Wait at PC `0x822DFC34 bl 0x824AA330` (KeWaitForSingleObject INFINITE) inside sub_822DFBC8 — direct caller of audit-040's NtCreateEvent. **Wait completion (canary 30s vs ours 500M-instr)**: canary 9 bl + 9 post-bl = **100%**; ours 7 pre-bl (probe at `bl` elided in HIR; pre-bl `0x822DFC30 addi r4,r0,-1` is fair) + 6 post-bl = **6/7 = 85%**. **7th wait stalls on handle `0x00001454`** (audit-040 family) at cycle 48,849. **Outcome (i) confirmed**: handle-namespace divergence is **load-bearing**. **Signaler = NtSetEvent** (xboxkrnl ord 246, thunk 0x8284DF5C): canary 9245 fires, **2 on F80000CC/C0** with LR=0x824AA304 (wrapper sub_824AA2F0, 89 callers). KeSetEvent 20588 fires, 0 on those handles (takes KEVENT*). **Cross-check**: ours's NtSetEvent fires **1× on r3=0x1454** at cycle 3,519,453 (AFTER stall) — **signaler IS firing in ours, but waiter not woken**. Bug class refined to **δ-namespace + δ-wakeup composite**: signal-before-wait race ruled out (signal is later); candidate causes = (a) handle slot 0x1454 recycled between create-epochs so signal hits different KEVENT than wait registered for, OR (b) KeSetEvent/wait-queue plumbing has missed-wake. **Recommended audit-042** (two-track): (1) probe sub_824AA2F0 entry filtering r3=0x1454 to name signaler caller chain; (2) dump our handle table state for slot 0x1454 at cycle 48,849 (wait) vs 3,519,453 (signal) — if different KEVENT pointers → handle aliasing in `xenia_kernel::handle_table`; if same → wait-queue bug. Both fixes ≤60 LOC. xenia-rs HEAD `d8766c6` unchanged. Trace `audit-runs/audit-041-wait-site/`.
|
||||
- [project_xenia_rs_audit_040_record_ctor_inputs_2026_05_09.md](project_xenia_rs_audit_040_record_ctor_inputs_2026_05_09.md) — **🎯 KRNBUG-AUDIT-040 (2026-05-09, READ-ONLY, master `d8766c6` tests 645)**: identified divergent INPUT to sub_8244FC90 record ctor. Re-applied audit-030 patch + extended TrapLogLR (+56 LOC, reverted clean). Canary 33 fires at 30s; ours 8 fires via `--lr-trace`. Calling conv: r3=dest, **r4=28-byte source struct ptr (memcpy'd to dest+0x3C)**, r5=2nd this, r6/r7=scalars. LR=`0x82450440` (=sub_824503A0+0xA0) IDENTICAL in both. **Divergent dword**: `*r4+0` = canary `0xF80000DC` vs ours `0x00001454` — **NtCreateEvent OUT handle** (xboxkrnl ord 209 thunk `0x8284DF1C`). Upstream chain: sub_8244FC90 ← sub_824503A0 ← sub_824528A8 ← sub_822DFBC8 ← **sub_822DFC74** (which calls sub_824A9F18→NtCreateEvent at +0xC8C, stores result at `[r31+44]` then dispatches via vtable[7]). Both runtimes call NtCreateEvent 395× successfully — divergence is **handle-namespace cosmetics** (canary `0xF8000xxx` XObject-kernel-region vs ours `0x10xx-0x14xx` KernelState-handle-table-id). **Bug class δ-namespace** (handle representation; benign unless downstream interprets bits semantically). **AUDIT-037 framing partial-correction**: the inline filename text lives at dest record's `+0x40+` (written by sibling callees `sub_822F8A70`/`sub_82150030` AFTER sub_8244FC90 returns), NOT in the 28-byte memcpy region. **Recommended audit-041**: probe `sub_822DFC34` (`bl 0x824AA330` waitsite) in BOTH runtimes — if canary's wait completes but ours doesn't = signaler-missing bug. If both stall = handle namespace finding is benign and pivot to RDX search-criteria producer. Trace `audit-runs/audit-040-record-ctor-inputs/{canary-0x8244FC90.log, ours-lrtrace.jsonl, ours-dump.log, canary-patch.diff}`. xenia-canary HEAD `6de80dffe` clean; xenia-rs HEAD `d8766c6` unchanged.
|
||||
- [project_xenia_rs_audit_039_track_2_extended_canary_2026_05_09.md](project_xenia_rs_audit_039_track_2_extended_canary_2026_05_09.md) — **🎯 AUDIT-039 TRACK 2 (2026-05-09, READ-ONLY, canary `6de80dffe`, xenia-rs `d8766c6`)**: extended-horizon canary trace for cluster activation. Re-applied audit-030 `--log_lr_on_pc` patch (30 LOC, 4 files); reverted clean. Probed 3 Tier-2 PCs serially (audit-031 single-PC constraint), 15-min wallclock each: **0x82172524 = 0 fires / 22 min**, **0x82175810 = 0 fires / 15 min**, **0x8217EB78 = 0 fires / 15 min**. ~52 min canary CPU total. Steady-state mix 240k KeReleaseSemaphore + 75k VdRetrainEDRAM/XamInputGetCapabilities loop in all 3. Per task brief Step 3 outcome **(ii)**: cluster activation past Linux Debug's reach in 15 min — skipped Tier-1 (3 PCs) + L1 (6 PCs) per compressed plan (consequences of Tier-2). Confirms+extends audit-034 Phase B (5 min, 0×) and VERIFY-A (35 sec, 0/12). RECONCILE-B host-presenter caveat dominates: Vulkan/XCB Linux fails to display intro video, front-end-UI state machine never advances past post-intro. **3 horizons (35 sec/5 min/15 min) all stop in same idle loop.** Sister Track 1's cascade-A verdict FAIL combined with this OUTCOME (ii): transformation-step (`RtlInitAnsiString`-driven filename externalization) IS missing AND cluster activation IS past Linux Debug reach — independent gates. **Recommended pivot B (static-only, M5.5 alias-aware vtable dispatch resolution)** first; pivot A (Lutris Windows canary instrumentation) as fallback. Trace `audit-runs/audit-039-track-2-extended-canary/canary-0x{82172524,82175810,8217EB78}.{log,err}`. Canary patch reverted, HEAD `6de80dffe` unchanged; xenia-rs HEAD `d8766c6` untouched, tests 645.
|
||||
- [project_xenia_rs_audit_039_track_1_verify_2026_05_09.md](project_xenia_rs_audit_039_track_1_verify_2026_05_09.md) — **🎯 AUDIT-039 TRACK 1 (2026-05-09, READ-ONLY, master `d8766c6`)**: cascade dimension A verification post audit-038 cache fix. Probe sub_8228E498 = 0 fires (silenced by fix). Fallback `--dump-addr` 0x40542300/40/400/4C0 + extended 0x40542100..800. **VERDICT: FAIL** — 0x40542300 IDENTICAL to audit-037 pre-fix (inline "game:\\hidden\\Resource3D\\Common.xpr…", +0x20=0x7072005C "pr\\0\\\\" text bytes); 0x405424c0 has descriptor-shape pointers at +0x20=0x40541ED8 but **filename still inlined at +0x44** ("ptc_pack.xpr"). Canary records hold pointers (0xF80000B8 handle@+0, BC65xxx/BC36xxx sub-pointers); strings live on separate `RtlInitAnsiString`-allocated heap. Cache fix is correct hygiene (silenced sub_82459D18/sub_8245D230/0x82450904) but DID NOT externalize filenames into ANSI-string heap. **Bug class η record-layout divergence (audit-036) PERSISTS** — record-population transformation step is upstream/sibling of cache machinery, untouched by audit-038. Lockstep instr=500000019 stable, swaps=2. **Recommended next**: (A) trace `RtlInitAnsiString` callers vs canary to find missing `game:/dat:/cache:` prefix populator, (B) mem-watch +0x20 of 0x40542320 to capture writer PC+LR, (C) wait for sister Track 2's extended-horizon canary trace before declaring transformation-step missing, (D) KRNBUG entry on `RtlInitAnsiString` prefix branching. Trace `audit-runs/audit-039-track-1-verify/{probe-element,dump-extended}.{out,log}`. xenia-rs HEAD `d8766c6` unchanged.
|
||||
- [project_xenia_rs_audit_036_vptr_deref_2026_05_09.md](project_xenia_rs_audit_036_vptr_deref_2026_05_09.md) — **🎯 KRNBUG-AUDIT-036 (2026-05-09, READ-ONLY, master `9028021`)**: hypothesis test of audit-035 narrative — captured `[[r3+0]+32]` at sub_8228E498/sub_82451E20+0x58 in BOTH runtimes. Canary patch 49 LOC (audit-030 base + 19-LOC TrapLogLR ext to deref `[r3+0]` + 64-byte struct dump); reverted clean. **Disasm correction**: sub_8228E498 is a deque iterator deref returning element_address (NOT vtable dispatcher); the `[+32]` deref happens in CALLER sub_82451E20 at PC 0x82451E78 reading the returned element's `[+0]` (key) then `[key+32]`. **Canary value `[[r3+0]+32]` = `0xBC65D018/D2D8/CFD8/D118/D198/D398`** — phys-heap pointers. **Ours value `[[r3+0]+32]` = `0x7072005C`** — mid-FILENAME-STRING text bytes ("pr\\0\\\\" from "...Common.xpr\\0\\..."). **VERDICT: REFUTED-AS-STATED** — ours's value is text not a heap pointer. **STRONGER finding**: records held by container have FUNDAMENTALLY DIFFERENT LAYOUTS. Canary's `[r3+0]=0xBC65D1C0` is a 16-dword pointer-bearing struct (handle@+0=0xF80000B8, sub-pointers@+32/+36/+44). Ours's `[r3+0]=0x40542300` is a struct STARTING WITH inline filename "game:\\hidden\\Resource3D\\Common.xpr\\0..." — offset 32 falls inside string text. Predicate `r28 == [[r3+0]+32]` compares stack pointers vs string bytes in ours (impossible match). Bug class **η — record-layout divergence (NEW class)**, distinct from audit-035's heap-region axis. **Recommendation: DO NOT proceed with physical-heap separation as audit-037** — even after heap-split, ours's records would still hold inline strings; predicate would still fail. **Audit-037 = identify the record populator** that builds container elements (mem-watch on `0x40542300+0x20` → writer PC + LR, walk caller chain, compare to canary's resource-loader). xenia-rs HEAD `9028021` unchanged. Tests 640. Trace `audit-runs/audit-036-vptr-deref/{canary.log, canary-callsite.log, ours.log, ours-exit.log, ours-final.log}`.
|
||||
- [project_xenia_rs_audit_035_slot_table_2026_05_08.md](project_xenia_rs_audit_035_slot_table_2026_05_08.md) — **🎯 KRNBUG-AUDIT-035 (2026-05-09, READ-ONLY, master `9028021`)**: re-applied audit-030 patch + extended TrapLogLR (+19 LOC, total 49) to dump 5×20-byte slot table from r3+108 at sub_82450720 entry. Disasm verified r26+108 / 5 slots / 20 stride. r3=r26=0x828F3B68, base=0x828F3BD4 in BOTH runtimes. Canary 22 entries / 30s wall; ours --dump-addr at 50M (==500M, identical). **Diff**: slots 1/2/4 same shape (zeros + ptr + size 8) but ptrs in **canary 0xBC3xxxxx (physical heap)** vs **ours 0x4024xxxx (v40 bump heap)**; slot 3 canary `(2,5)` push counters vs ours `(0,0)` (ours over-cycles 0..0xB). Slot 0 zero in both. **Bug class ε — heap-region cross-reference mismatch**: predicate at 0x82450904 compares sub_82451E20's vptr-table-derived sum vs slot's local sum; the table walked via sub_8228E498's `[r3+0][32]` holds canary-physical addresses, but slot writers push v40 addresses on ours — per-element inconsistency causes predicate to never match early in ours. 1066 mem-watch hits on slot 3 ours (writers at sub_82450bc4 chain + 0x822f8b20/0x82323364/0x8231eee8). **Falsifies audit-034**'s "different positions" — slots match in shape, mismatch is in pointer value. **Sharp cascade**: A=land physical-heap separation (CPPBUG-AUDIT-001); B=sub_8228E498 vtable + slot writers same heap region; C=predicate matches iter 1-2; D=`draws>0` UNKNOWN. Pointed-to objects: 0x4024A240=vtable-headed (vptr=0x40111860), valid. Connects directly to audit-027/029. Canary patch reverted; xenia-rs HEAD `9028021` unchanged. Tests 640. Trace `audit-runs/audit-035-slot-table/{canary-0x82450720-fix.log, ours-lrtrace.jsonl, ours-dump-stdout.log, ours-memwatch-slot3.log}`.
|
||||
- [project_xenia_rs_audit_034_frame_chain_divergence_2026_05_08.md](project_xenia_rs_audit_034_frame_chain_divergence_2026_05_08.md) — **🎯 KRNBUG-AUDIT-034 (2026-05-09, READ-ONLY, master `9028021`)**: re-applied audit-030 patch; probed audit-033's full 8-PC ours-side chain in canary 50s + ours -n 500M. **Firing matrix** L0..L5 uniform **6.3× divergence** (sub_821C4988=1/1, sub_821CECF0=2/2, sub_821CBEA8=7/7, sub_821CD458=7/7, sub_821CB968=14/14, sub_82450638=14/14 — same shape, ours iterates 6.3× more often per second). L6 sub_82450720 = 24 canary / 16 ours = 4.2×; L7 sub_82451E20 = 90 canary / 80 ours = 5.5×. **Loop-exit-divergence located**: sub_82450720+0x160..+0x1F4 (PC 0x82450880..0x82450914, 5-iter loop bounded by `r25<5`). Ours runs 5/5 iters (80/16=5.00); canary avg 3.75/5 (90/24=3.75) — exits via 0x82450904 `bne` on sub_82451E20's success-predicate match. **Exit predicate**: `[sub_82451E20_out+0]==r30-12 AND [+4]==[r30+0]+[r30+4]` where r30=r26+108+iter*20; data source = 5×20-byte slot table at r26+108..207 (r26=container struct arg1). Predicate fed by sub_82451E20's inner-loop, which dereferences Tier-1 cluster sub_8228E498's `[r3+0][32]`. Bug class **β-data-divergence + γ-deep entry** (sub_821C4988=0 static call xrefs → vtable). **Phase B (300s canary) Tier 2/3 horizon** — ALL 5 PCs (0x82172524, 0x82175810, 0x8217EB78, 0x821A6CF0, 0x821A8578) = **0 fires at 300s**. Cluster activation gated deeper than 5-min Linux Debug horizon (consistent with RECONCILE-A: Linux trace reaches frame 42/186, Lutris Windows reaches 72/186). Tests 640, lockstep instr=100000003. Canary patch reverted; master `9028021` unchanged. **Recommended next**: AUDIT-035 mem-watch r26+108..207 to identify slot-table writer ours misses; OR M5.5 to name sub_821C4988 trigger; OR extended pc-probe of sub_8228E498 capturing `[r3+0][32]` to name predicate compare-target.
|
||||
- [project_xenia_rs_audit_033_ui_entry_chain_2026_05_08.md](project_xenia_rs_audit_033_ui_entry_chain_2026_05_08.md) — **🎯 KRNBUG-AUDIT-033 (2026-05-08, READ-ONLY, master `9028021`)**: re-applied audit-030 `--log_lr_on_pc` patch (30 LOC, build via `ninja -f build-Debug.ninja xenia_canary`; Checked variant has code-cache alloc collision). Probed 8 PCs (Tier1 cluster externals 0x8228A628/0x8228E138/0x8228E498; Tier2 callers 0x82172524/0x82175810/0x8217EB78; Tier3 CMessageBridge sites 0x821A6CF0/0x821A8578) in BOTH canary (50s wall) and ours (-n 500M). **Convergence**: both fire 0x8228E138 (canary 2× LR=0x82172BF8 in sub_82172BA0, ours 1× same LR) AND 0x8228E498 (canary 28× LR=0x82451E78 in sub_82451E20, ours 62× same LR). **Falsifications**: 0x8228A628 + all Tier 2 + all Tier 3 = 0 fires in canary at 50s — cluster's full activation isn't triggered in canary either at this boot horizon. **Frequency divergence**: ours 62× / 8s guest vs canary 28× / 50s wall on sub_82451E20 — busy-loop in array-ctor dispatch; loop-exit gate is the divergence target. CTOR-PROBE captures full call chain sub_82451E20←sub_82450720←sub_82450638←sub_821CB968←sub_821CD458←sub_821CBEA8←sub_821CECF0←sub_821C4988. Bug class **γ (vtable-driven dispatch)** — both reach Tier 1 entries via same LR; M5.5 (this-flow vptr) prerequisite for deeper top-down probes. Canary patch reverted. Trace `audit-runs/audit-033-ui-entry-chain/{canary-0x*.log,ours.log,ours.err}`. xenia-rs HEAD `9028021` unchanged. **Recommended next**: M5.5 milestone OR pivot to probing sub_82450720/sub_82450638/sub_821CB968 to find loop-exit gate (62 vs 28 fires divergence) OR longer canary trace via Lutris Windows build for post-intro Tier 2+3 activation.
|
||||
- **🚨 CLUSTER IDENTITY REFRAME (2026-05-08)** — The `0x82285000-0x82294000` cluster (audit-009/016/017/020/021/026/027/029) is **NOT the renderer plateau**. It is the **front-end UI / save-game / mission-select / HUD subsystem** per RAPID-SURVEY-Q4 (93 string refs: BASE_INFO, LOAD_BASES, SAVE_MENUS, MISSION_SELECT, NOW_LOADING, FlightTime, etc.). Past sessions calling this "renderer cluster" or "renderer plateau" misidentified the subsystem. The cluster doesn't fire because the front-end UI flow never *activates*, not because the renderer is broken. The actual renderer (which produces the 2 splash swaps we DO get) lives elsewhere. The `swaps>2 / draws>0` gate is the **front-end loader** — what should activate after intro video → main menu → mission select. **Future sessions: do NOT label this cluster "renderer"**. Add this to running-error ledger as the 11th entry (subsystem-mislabeling class, distinct from the 10 function-boundary entries).
|
||||
|
||||
- [project_xenia_rs_overhaul_rapid_survey_2026_05_08.md](project_xenia_rs_overhaul_rapid_survey_2026_05_08.md) — **🎯 RAPID-SURVEY (2026-05-08, READ-ONLY, master `9028021`)**: post-overhaul DB survey of audit-009 cluster `0x82285000-0x82294000`. **Q1 zero**: 6 L1 PCs in NEITHER `methods` NOR `function_pointer_array_entries` (pure `this->vptr` per audit-031/032). **Q2 LEAD**: 13 static arrays at `0x820A9B98-0x820AA024` point INTO cluster; ctor candidates `sub_8228F858, sub_82293EC8, sub_82294898, sub_82284590, sub_822A0860, sub_822A0E90` (all themselves trapped in cluster or adjacent 0x822A0xxx). **Q3 BIG**: cluster has **309 pdata-validated fns, 309 unreachable** via static-call BFS AND indirect-reach view (M5 added 0 edges, ind_call=0 globally). Audit-009's "42 unreached" was 7x undercount. **Q4 PIVOT**: 93 string refs from cluster name **save-game/mission-select/UI subsystem**: BASE_INFO, LOAD_BASES, SAVE_MENUS, AUTO_SAVED, MISSION_SELECT, NOW_LOADING, FlightTime, ClearTimes, Disk free space, Content request — NOT raw renderer. SilpheedSCS::CMessageBridge strings live OUTSIDE cluster (caller `sub_821A6CF0+0xE6C`, `sub_821A8578+0xE0`). **Q5**: 68 cluster fns have `has_eh=true` (heavy C++ EH around save I/O). **Q6**: 0 mis-merge candidates in 0x82200000-0x822F0000 — past audits stand. **Q7**: audit-031 boundary fix verified (sub_824D23B0/29F0/2BD8/2C08 separate). **External entries** sub_8228A628/sub_8228E138/sub_8228E498 ARE called from outside (`sub_82172524, sub_82175810, sub_8217EB78` etc) but THEMSELVES still unreachable in BFS — gate is even higher. **Verdict**: audit-009 framing should pivot from "renderer plateau" to "front-end-UI/save-game cluster never instantiated". M5.5 NOT mandatory before next probe — Q4 already names subsystem; M5.5 would name the trigger ctor. **Recommended next**: `--lr-trace` canary-diff on cluster external-entry PCs + their parents (sub_82172524, sub_82175810, sub_8217EB78); cross-check SilpheedSCS::CMessageBridge::Load/CreateDeviceObjects; schedule M5.5 as next analyzer milestone.
|
||||
- **✅ ANALYSIS-OVERHAUL FULL CLOSE-OUT (M1-M12 + 5 closers) LANDED (2026-05-08+10)** — [analysis_overhaul_M1_M12](project_xenia_rs_analysis_overhaul_2026_05_08.md). 9 no-ff merges off `e061e21` → master `7bc9e3a`. **All 12 milestones + all 5 deferred closers done.** M1 pdata (12156→25481 fns); M2 demangler; M3 722 vtables/499 anon classes/5571 methods; M4 Class::* probes; M5+M5.5 ind_call (687,963 edges, 97 single-cand + 6,745 multi-cand, **2,746 newly reachable functions** via vptr-write inference — M5.5 surfaces audit-009 cluster); M6+VMX `addr_mode` + 442 x_form_indexed + 40 atomic + 110 stvx; M7+SJIS/UTF-8 strings (6,311 ASCII + 790 SJIS + 39 UTF-8); M8/M11/M11.5 1,110 funcptr arrays (388 dispatch + 0 static_init); M9 has_eh (2,975 fns); M9.5 EH scope-tables (2,588 FuncInfo / 10,019 unwind / 315 try-blocks); M10 .tls infra (Sylpheed none); M12 `--lr-trace` JSONL canary-diff harness. Tests 605→655. Lockstep deterministic at instr=2000005. SCHEMA.md documents all 17 layers + remaining future work (M9.6 EH→function linkage; M11.6 non-canonical static-init drivers; full SJIS→UTF-8 decode; VMX128).
|
||||
- **🚨 METHODOLOGY CORRECTION (2026-05-08)** — [audit_032_audio_host_pump](project_xenia_rs_audit_032_audio_host_pump_2026_05_08.md) revises audit-025's central claim "audio gate IS renderer gate". They are SEPARATE STALLS. 7+ prior sessions (KRNBUG-018, KE-001, AUDIT-024A/025/026/030/031) chased an audio gate believing it was the renderer gate. The fixes that landed addressed real divergences but did NOT approach `draws > 0`. **Future sessions must NOT re-conflate.** The renderer plateau (audit-009 cluster L1 reachability) is INDEPENDENT and remains the actual `swaps>2 / draws>0` gate. Audio fix is hygiene cleanup; renderer hunt is critical-path. All static analysis avenues for the renderer cluster are exhausted (audit-020/021/026/027/029); next probes need new tooling — analysis-toolset overhaul motivated.
|
||||
- [project_xenia_rs_methodology_verification_2026_05_08.md](project_xenia_rs_methodology_verification_2026_05_08.md) — **🔍 META-AUDIT (2026-05-08)**: 4 parallel verifications + reconciliations. **VERIFY-A**: 0/12 cluster L1 PCs fire in canary → static reachability BFS is SOUND. **VERIFY-B**: 12/12 PowerPC store classes hooked by mem-watch → coverage COMPREHENSIVE. **RECONCILE-A**: Linux Debug canary kernel-call trajectory IDENTICAL to Lutris Windows; Linux log was simply terminated earlier (frame 42/186 vs 72/186). **RECONCILE-B**: user's "Linux black window vs Windows intro video" is HOST-PRESENTER divergence (Vulkan/XCB-only on Linux; Wayland TODO; H1 swapchain failure most likely; user confirmed Weston also shows black). **Combined verdict**: methodology is sound at kernel-call level. Reading-error ledger (10 entries, mostly function-boundary mis-attribution) is the real motivating gap. Past audit findings stand; no re-grading. Master HEAD `e061e21`, tests 605.
|
||||
- [project_xenia_rs_audit_032_dispatcher_lr_2026_05_08.md](project_xenia_rs_audit_032_dispatcher_lr_2026_05_08.md) — **🎯 KRNBUG-AUDIT-032 (2026-05-08, READ-ONLY, master `e061e21`)**: re-applied audit-030 `--log_lr_on_pc` canary patch (30 LOC, 4 files), reverted at session close. **7,875 fires** of `pc=0x824D6640` in canary; ALL from single host-flagged kernel thread named **"Audio Worker"** (handle=`0100001C`, native=`467FC6C0`); **LR invariant `0xBCBCBCBC`** = host stack-fill canary, NOT a guest PC. r3=`0x30063000` driver-ctx, r4=0|1 init-vs-tick, r5=`0x1800` frame-size, r6=`0xBDFBA600` callback_arg. Canary log: `XAudioRegisterRenderDriverClient(701CF210(824D6640), BDFBA658(00000000))`. **Mechanism: canary `xe::apu::AudioSystem` (`apu/audio_system.cc:84-159`) spawns host XHostThread "Audio Worker" that loops `WaitAny(client_semaphores_) → processor_->Execute(callback_pc, args)`** — invokes thunk DIRECTLY via host emulator, no guest call site, hence LR=stack-canary. **Falsifies AUDIT-031 vtable[7] hypothesis**: `addi r4, r10, 26176` at sub_824D2C08+0x374 loads PC 0x824D6640 as the callback_ptr ARGUMENT to XAudioRegisterRenderDriverClient (caller-side parameter), not vtable registration. **Outcome δ+α composite**: the "caller PC" we sought is canary's HOST C++, not guest. **Our impl gap**: `XAudioRegisterRenderDriverClient` (exports.rs:2705-2745) registers (callback_pc=0x824D6640, arg=0x41E9DD5C) correctly but **does NOT spawn a host worker thread to pump the callback**, no semaphore-release loop. Probes (`--pc-probe` and `--branch-probe` × 0x824D6640/0x824D29F0) at -n 500M: **0 fires both**. tid=9 parks `pc=0x824D28D0` waiting `0x828A3254`; tid=10 parks `pc=0x824D2990` waiting `0x828A3230` (count=0/limit=6). Bug class **δ-α composite — host-side AudioSystem worker thread missing**. Sharp cascade: A=tid 9 unparks on first sub_824D29F0:KeSetEvent(0x828A3254); B=tid 10 unparks on next sema release; C=XAudioSubmitRenderDriverFrame >0; D=KeReleaseSemaphore non-zero. **Audio gate is NOT renderer gate** (revising audit-025) — separate stalls sharing "host pump missing" symptom only. Tid 10's limit=6 sema = audio-frame queue depth (canary's `queued_frames_=6`), isolated from renderer. Recommended next: implement host-side audio worker (60-120 LOC) per `apu/audio_system.cc`. Won't flip swaps=2→draws>0 plateau alone — audit-025 strategic pivot to audit-009 renderer cluster L1 callers REMAINS priority. Trace `audit-runs/audit-032-dispatcher-lr/{canary-patch.diff, probe.{log,err}, probe-sanity.{log,err}, branchprobe.{log,err}}` + `/tmp/audit-032-canary.log` (7,875 LR fires). Tests 605, lockstep instr=100000003. Master HEAD `e061e21` unchanged.
|
||||
- [project_xenia_rs_verify_A_canary_pc_trace_2026_05_08.md](project_xenia_rs_verify_A_canary_pc_trace_2026_05_08.md) — **🎯 VERIFY-A (2026-05-08, READ-ONLY, master `e061e21`)**: re-applied audit-030 patch; probed 12 PCs (6 narrow L1 + 6 broader cluster) from audit-009 unreachable cluster `0x82285000-0x82294000` in canary. **0/12 fires** across 35-sec windows while audio loop runs hot (5,600-5,800 KeReleaseSemaphore/window). Sanity-check `0x824D28D0` = 5683 fires confirms trace mechanism. **Outcome (i): static reachability claim is SOUND** — xrefs.kind='call' BFS conclusion is corroborated by canary runtime trace; indirect-dispatch reachability is NOT being missed for this cluster. Audit-009/-016/-017/-020/-021/-029 framing of the cluster as unreachable holds. AUDIT-031's γ-deep dispatcher hypothesis reinforced (the dispatcher exists, but is NOT in this cluster — different code region). 95% upper bound on cluster reach-rate ~22% from sample size; full 112-PC sweep would harden to <5% in ~75 min. Reading-error ledger UNCHANGED (this claim was not on it). Recommended next session: AUDIT-031 sharp-prediction step 1 (probe `0x824D6640`); analysis-toolset overhaul remains motivated by other 10 errors not by this verification. Canary patch reverted. Trace `audit-runs/verify-A-static-reachability/probe-*.log` (13 files).
|
||||
- [project_xenia_rs_audit_031_audio_wait_site_2026_05_08.md](project_xenia_rs_audit_031_audio_wait_site_2026_05_08.md) — **🎯 KRNBUG-AUDIT-031 (2026-05-08, READ-ONLY, master `e061e21`)**: re-applied audit-030's `--log_lr_on_pc` canary patch (30 LOC, 4 files); reverted at session close. **Outcome (a) — canary EXECUTES PC 0x824D28D0**: 54128 fires in ~5min, audio worker hot-loops through wait→release. Wake source captured via probe of KeSetEvent thunk `0x8284DDDC`: `tid=0100001C lr=0x824D2A44 r3=0x828A3254` = `KeSetEvent(0x828A3254,1,0)` from PC `0x824D2A40`. **AUDIT-025/-030 mis-attribution corrected**: IDA-DB `sub_824D23B0` (claimed range `0x824D23B0..0x824D2878`) actually contains a SECOND function prologue at `0x824D29F0` — that's the real wake-source, NOT sub_824D23B0. sub_824D23B0 entry probe = 0 fires confirms. Static reachability of sub_824D29F0: tail-jump from thunk at `0x824D6640` (which loads `r3=[0x828A3264]`); `0x824D6640` is data-referenced at `sub_824D2C08+0x374` (PC `0x824D2F7C: addi r4, r10, 26176`); next instructions deref `[r31][68]`, load vtable[7] at `[[r3]+28]`, `bcctrl 20,lt` to register the thunk. **Our impl tid=9 state matches AUDIT-025**: `Blocked(WaitAny [0x828A3254]) pc=0x824d28d0`. Bug class **γ-deep, vtable-driven** (refines AUDIT-025 with named downstream witness `sub_824D29F0`). The dispatcher loop that should periodically invoke `0x824D6640` is the unreached gate — likely in `0x82287000-0x82294000` cluster (AUDIT-009). Discipline gate: 5/5 PASS. **Recommended AUDIT-032**: probe `0x824D6640` directly in canary (names dispatcher PC) + probe `0x824D2F90 bcctrl` to capture r3 (audio-engine "this") + vtable[7] address; walk dispatcher's caller chain in our DB; cross-check audit-009 cluster overlap. NO source mods, NO commit. Trace `audit-runs/audit-031-wait-site/{canary-0x824D2878.log, canary-0x824D28D0.log, canary-KeSetEvent.log, canary-sub23B0.log}`.
|
||||
- [project_xenia_rs_audit_029_physical_mem_diff_2026_05_08.md](project_xenia_rs_audit_029_physical_mem_diff_2026_05_08.md) — **🎯 KRNBUG-AUDIT-029 (2026-05-08, READ-ONLY, master `e061e21`)**: physical-heap diff — LAST guest-memory surface. Architectural finding: our impl has NO separate physical heap (MmAllocatePhysicalMemoryEx folds into v40 bump allocator at 0x40000000+); 0xA0/0xE0/flat-0x00 dumps all `0 committed pages`. Canary physical extracted: 58458 commits / 228 MiB / 24.5 MB nonzero / 28851 0x82xxxxxx PC dwords across 4467 4K pages / 536 64K-regions. **L1 hits: narrow 0/6, broad 2/116 (sub_8228CC18, sub_8228A220 — both scalar, no tables); audit-017 chain 0/8.** **CONFIRMS audit-027 misplacement**: our v40 table at 0x40211900 (18 PCs, 0x20 stride) appears verbatim on canary physical at 0x1c32c910 — same 18 PCs same 0x20 stride same trailing dup. Largest PC run on canary physical: 232 dwords at 0x1e568f38 (XAM/UI 0x824b0xxx-0x824b2xxx family, ~220 PCs); 4 smaller runs ≤9. Top bucket 0x82026000 × 12655 (per-instance vtable in stride-0x38 object array at 0x144x0000). **Outcome ζ — ALL FOUR HEAPS ELIMINATED.** All vtable/dispatch-table hypotheses across audits 010/011/012/015/016/017/026/027/029 refuted. Cluster L1 functions invoked exclusively via static `bl` in unreached parents — gate is upstream of any heap data structure (control-flow gate, not data-population gate). **Strategic pivot mandatory.** Recommended AUDIT-030: Option A (preferred) comparative-execution divergence trace (canary patch periodic tid:pc:lr sample, diff vs ours to find first divergent guest instruction); Option B targeted canary trace logging LR on every entry to sub_824D23B0 (sole KeSetEvent(0x828A3254) caller, vtable-only invoked) to name the per-frame renderer caller; Option C CPPBUG-AUDIT-001 backlog. Discipline gate fails 1. NO source mods, NO commit. Tests 605, lockstep instr=100000003 preserved. Master HEAD `e061e21` unchanged. Trace `audit-runs/audit-029-physical-mem-diff/`.
|
||||
- [project_xenia_rs_audit_027_v40_mem_diff_2026_05_08.md](project_xenia_rs_audit_027_v40_mem_diff_2026_05_08.md) — **🎯 KRNBUG-AUDIT-027 (2026-05-08, READ-ONLY, master `e061e21`)**: v40 heap byte-level dword diff vs canary's audit-024A 248.6 MiB dump. Captured ours via `--dump-section=0x40000000:0x3F000000` (60119 commits, 1056964608 bytes); extracted canary v40 = 90 commits / 1008 MiB. A-list (canary 0x82xxxxxx, ours differs) = **536**; B-list inverse = 31947. **Cluster L1 (0x82285000-0x82294000) hits = 0/0** broad-and-narrow — v40 ELIMINATED as dispatch-table source (after audit-026 v80 elimination). Top A-list buckets: `0x828f3xxx`(90, .data dispatcher), `0x8284dxxx`(78, .text), `0x8284cxxx`(64, .text near .text-end), `0x82150xxx`(30), `0x828f4xxx`(23), `0x82882xxx`(20). Three vtable-runs detected: `0x40000770` len=32, `0x400015a0` len=110 (same shape, two instances of 110-method class), `0x40000d90` len=20 — all target `.text` heap-allocator handler thunks NOT renderer cluster. Listener anchor `0x40BA9A80` is canary-uncommitted in this dump; ours has audit-016 listener content (`+0x2C=0x4024AC00`, `+0x3C=0x4024B3E0`) — heap-pointer divergent, not missing-write. B-list discovery: `0x40211900..0x40211B50` in OURS has 23 fn-entries spaced 0x20 apart (`0x82183ae8, 0x82187e38, 0x8218cf10, ...`) = a function-table our impl builds in v40 that canary builds elsewhere (likely physical heap). **Strategic pivot mandatory** per task brief outcome (iii). Recommended **AUDIT-029 = extract canary physical heap (0x20000000 span, 58458 commits = 228 MiB)** with same script targeting `physical`. Alt: vtable-write-tap instrumentation. Alt: CPPBUG-AUDIT-001 backlog (`nt_allocate_virtual_memory` silent-success / `mm_allocate_physical_memory_ex` ignores alignment). Trace `audit-runs/audit-027-v40-mem-diff/`. NO source mods; NO commit. Master HEAD `e061e21` unchanged. Sister 028 untouched.
|
||||
- [project_xenia_rs_audit_028_steady_state_notify_2026_05_06.md](project_xenia_rs_audit_028_steady_state_notify_2026_05_06.md) — **🎯 KRNBUG-AUDIT-028 (2026-05-08, READ-ONLY, canary log + source analysis only)**: XNotify steady-state publisher audit. Canary log (17245 lines) shows ONLY `XamNotifyCreateListener(0x2F)` @1347 + `XNotifyPositionUI(0x0A)` @2018 — NO further notification API calls. `XNotifyGetNext` is `kHighFrequency` (xam_notify.cc:96), per-call logging suppressed. 34 `BroadcastNotification` publisher sites across 11 files in canary; ALL event-driven (host UI, profile change, XMP play, SMC tray, controller hotplug edge) — NONE periodic. Controller hotplug log message absent → no `kXNotificationSystemInputDevicesChanged` fired. `VdSwap` count = 1 (TOC entry only) → ZERO actual swaps in canary; our impl swaps=2 is AHEAD. Audio-sema released 2224× in canary tail. **Outcome β: XNotify queue is NOT the gate**. Our impl matches canary's notification timeline byte-for-byte. The 1.49M `XNotifyGetNext` polls are dutiful idle polling, not missing-publisher symptom. **Strategic pivot: audio/render gate is still the γ-cluster from AUDIT-009/016/017/025** (`sub_824D23B0` via vtable on audio_system `0x82006CF4`, renderer cluster `0x82287000-0x82294000` unreached). AUDIT-029 = static-grep canary for what populates the `0x82006CF4` audio_system vtable at runtime + diff against ours. Provisional cascade A: cluster L1 PC fires; B: KeReleaseSemaphore(0x828A3230) 0→many; C: XAudioSubmitRenderDriverFrame 0→many; D: VdSwap climbs. NO source mods, NO commit, master HEAD `e061e21` unchanged. Trace `audit-runs/audit-028-steady-state-notify/`.
|
||||
- [project_xenia_rs_audit_025_audio_thread_start_2026_05_06.md](project_xenia_rs_audit_025_audio_thread_start_2026_05_06.md) — **🎯 KRNBUG-AUDIT-025 (2026-05-07, READ-ONLY, master `de5a15e` post-Path-2)**: audio thread-start gate identified as **γ-DEEP, vtable-driven**. XAudioRegisterRenderDriverClient (exports.rs:2705) ≈ canary `xboxkrnl_audio.cc:56-82` semantically; `0x41550000|index` return matches. Audio init `sub_824D2C08` runs to completion in our impl (KeInitializeSemaphore=1 on 0x828A3230 limit=6, ExRegisterTitleTerminateNotification=3, ExCreateThread spawns tids 9 entry=0x824D2878 + 10 entry=0x824D2940, KeResumeThread=2). DISPATCHER_HEADERs correctly populated with Path 2's "XEN\0"+ptr stamp. **Worker correctly parks on `KeWaitForSingleObject(0x828A3254)` waiting for job-submit signal** — but `sub_824D23B0` (the ONLY KeSetEvent(0x828A3254) wake-source, at +0x54/+0x4FC/+0x688) is never reached. Probe set 12 PCs × -n 500M: only `0x824D2DF8` (ExRegTitleTerm in sub_824D2C08) fires; `0x824D23B0`/`0x824D2404` zero fires. **`sub_824D23B0` body at 0x824D2BD8 has ZERO static call-xrefs** — invoked only via vtable on audio_system object (`[r31+0]=0x82006CF4`). Caller would be a per-frame audio update from renderer/scenegraph = the **same `0x82287000-0x82294000` cluster identified by AUDIT-009 as unreached**. Audio gate IS the renderer gate — no new bug class, same γ-cluster blocker. tid 9 state: `Blocked(WaitAny [0x828A3254])` pc=0x824D28D0, signal_attempts=0. Discipline gate fails 1+3. **Recommended next: strategic pivot back to AUDIT-009/016/017's renderer cluster L1 callers + listener vtable population** — what kernel call materializes the listener-dispatch table so renderer can route per-frame audio. Audio worker host-thread emulation is option C (regresses swaps via xaudio-tick path). Trace `audit-runs/audit-025-audio-thread-start/probe.{log,err}`. Master HEAD `de5a15e` unchanged.
|
||||
- [project_xenia_rs_kernel_stashhandle_2026_05_06.md](project_xenia_rs_kernel_stashhandle_2026_05_06.md) — **🎯 KRNBUG-α-006 (2026-05-07, LANDED branch `xobj-stashhandle/p0-canary-mirror` → master `de5a15e`)**: `ensure_dispatcher_object` (exports.rs:~3097) now writes `+0x08=0x58454E00` (`'X','E','N','\0'` kXObjSignature) and `+0x0C=ptr` (stash handle) per canary `XObject::StashHandle` (xobject.h:253-256). 7 LOC impl + 27 LOC tests. Tests 604→605. Lockstep `instructions=100000003 imports=987516` ×2 reruns (identical to pre-fix d9e40d3 — host-side write). Cascade @ -n 500M: NIL ripple — workers=20, KeReleaseSemaphore=0, XAudioSubmitRenderDriverFrame=0, NtSetEvent=3334, VdSwap=2 all match post-ke-resume baseline. **0x828F4838+0x08 still zeros** at -n 500M because guest never invokes Ke* with that ptr (canary uses `SetNativePointer` lifecycle there, which we don't traverse via `ensure_dispatcher_object`). Audit-024A's hypothesis that this stamp gates audio init is **observationally falsified post-fix**. Lands as canary-correctness restoration (sister of XamUserGetSigninState pattern); no sharp cascade prediction per task brief. Trace `audit-runs/post-stashhandle/`. Next: audio-thread-start gate (post-XAudioRegisterRenderDriverClient) — coordinate with sister AUDIT-025.
|
||||
- [project_xenia_rs_audit_024a_canary_delayed_trigger_2026_05_06.md](project_xenia_rs_audit_024a_canary_delayed_trigger_2026_05_06.md) — **🎯 KRNBUG-AUDIT-024A (2026-05-07, READ-ONLY, canary patch+rebuild+revert)**: re-applied audit-023's mem-dump pattern with delayed trigger on first `XAudioSubmitRenderDriverFrame_entry` (39 LOC: cpu_flags hunk + xboxkrnl_audio.cc hook). Linux Debug build success after `/home/fabi/xenia-canary` symlink + `--disable_instruction_infocache=true`. Captured 248.6 MiB dump (260,659,200 bytes) at deep boot — canary log shows `KeReleaseSemaphore(0x828A3230,...)` firing repeatedly, VdSwap, VdRetrainEDRAM, texture loads. **AUDIT-017 β-class hypothesis FALSIFIED**: `[0x828F40B0]` (=0x828F4070+64) is **ALL ZEROS in canary** at this post-populator moment, while ours has `-1` sentinel from sub_821701c8. The `[+64]==-1` blocker is not the gate — canary admits `[+64]==0` or takes a different path entirely. **`0x828F4838+0x08` "XEN\0 + 0xF8000034" divergence stable** across audit-023 (early) and 024A (late) triggers — populator wrote it during early init. Heap pointers at `0x828F4838+0x20..0x60` populated in BOTH (canary `0xBC36xxxx`, ours `0x4024xxxx`). `0x828A3230` audio sema has full canary state (`05000000`, "XEN\0+F8000070", count=1, chain to F8000080/F800007C, ts BE628EDC1FCA7000 at +0x38) — KeReleaseSemaphore=0 in ours. Bug class refined β→**γ-deep**: the audio-thread that calls XAudioSubmitRenderDriverFrame is never started in ours despite `XAudioRegisterRenderDriverClient=1` and `KeInitializeSemaphore=1`. Patch reverted (canary `git status` clean). xenia-rs HEAD `d9e40d3` unchanged. Sister AUDIT-024B running in parallel for "XEN\0" writer source-grep. Next: cross-reference 024B's writer with our canary-only export queue (ExTerminateThread/KeReleaseSemaphore) OR α/δ probe of audio-thread-start gate post-XAudioRegisterRenderDriverClient. Trace `audit-runs/audit-024a-canary-diff/`.
|
||||
- [project_xenia_rs_audit_023_canary_diff_2026_05_06.md](project_xenia_rs_audit_023_canary_diff_2026_05_06.md) — **🎯 KRNBUG-AUDIT-023 (2026-05-06, READ-ONLY, Path B canary patch+rebuild+revert)**: temp 44-LOC canary patch (cpu_flags + xam_notify) added `--memory_dump_path` flag, dumped 216 MB on first XamNotifyCreateListener (mask=0x2F). Linux Debug build success after `--disable_instruction_infocache=true` workaround for canary's pre-existing XexInfoCache SIGBUS. PageEntry `state` bitfield empirically at qword bits 60-61 (NOT declaration-order 48-49). Canary's first-listener dump shows v80=146 committed pages but 0x828F4070 area ALL ZEROS (too-early trigger — populator hadn't run). Diff vs ours @-n 50M reveals: (1) `0x828E1F08` ours has listener pointer 0x40111890, canary=0 (mechanism difference, ours stuffs guest-mem, canary uses host-side notify_listeners_ vector); (2) **`0x828F4838+0x08` canary has ASCII `"XEN\0"` + handle `0xF8000034`, ours has zeros — NEW POPULATOR-EFFECT LEAD inside audit-016/017 cluster**; (3) `0x82124xxx` audit-009 cluster L1 PCs visible as data — REFUTED as populator target, this is static .pdata exception table, byte-identical in ours; (4) various `0xBC...` host-physical aliases vs ours `0x40...` virtual aliases (handle-namespace difference, not bug). **Audit-017 β-class hypothesis NEITHER confirmed NOR refuted** (canary trigger too early). Patch reverted (`git status` clean). Trace `audit-runs/audit-023-canary-diff/canary-memory.dump,canary-patch.diff,parse_dump.py,diff.txt`. Master HEAD `d9e40d3` unchanged. Next: AUDIT-024 either re-apply with later trigger (Nth listener / first XAudioSubmitRenderDriverFrame / first NtSetEvent on specific event) for fair like-for-like, OR static-search canary's xboxkrnl source for "XEN\\0" writer at 0x828F4840 (names populator's CODE).
|
||||
- [project_xenia_rs_kernel_ke_resume_thread_2026_05_06.md](project_xenia_rs_kernel_ke_resume_thread_2026_05_06.md) — **🎯 KRNBUG-KE-001 (2026-05-06, LANDED branch `ke-resume-thread/p0-canary-mirror`)**: real `KeResumeThread` per canary `xboxkrnl_threading.cc:216-227` (mirrors nt_resume_thread plumbing). 600→601 tests; lockstep `instructions=100000003 imports=987516` ×2. **Cascade A PASS**: tids 9 (entry=0x824D2878) / 10 (entry=0x824D2940) leave Suspended → run prologue → park on audio buffer-completion semaphores 0x828A3254 / 0x828A3230. **B PARTIAL FAIL**: NtSetEvent 667→3334; KeReleaseSemaphore=0; XAudioSubmitRenderDriverFrame=0. **C FAIL** (predicted 2→1, actual 2→2): both ExTerminateThread + KeReleaseSemaphore still canary-only. **D FAIL**: γ-cluster blocker unchanged — `--pc-probe=0x82184318,0x82184374` no fires; `--dump-addr=0x828F4070` no DUMP; signal_attempts on 0x1004/0x100c/0x1020/0x15e4 still 0. swaps=2 draws=0 plateau intact. Goldens re-baselined `n50m: instructions 50000003→50000011, imports 407255→407247`. **Necessary-but-not-sufficient fix**: workers unsuspend but park on a downstream gate that's part of the audit-009/-016/-017 γ-cluster (`[0x828F4070+64]==-1`). Trace `audit-runs/post-ke-resume/`. Next: AUDIT-019 memory-watch on `[0x828F4070+64]` (audit-017 Option B).
|
||||
- [project_xenia_rs_audit_018_canary_diff_2026_05_06.md](project_xenia_rs_audit_018_canary_diff_2026_05_06.md) — **🎯 KRNBUG-AUDIT-018 (2026-05-06, READ-ONLY)**: canary-log diff identifies α-class load-bearing stub. Function-name set-diff: only 2 calls in canary not in ours — `ExTerminateThread`, `KeReleaseSemaphore`. The latter is hammered by canary tid `F800006C` (audio render-frame ticker, entry=0x824D2878, ctx=0, flags=0x10000001) which canary unsuspends via `KeResumeThread(KTHREAD_ptr)`. **Our `ke_resume_thread` (exports.rs:3658-3664) is a no-op stub that ignores r3 and sets r3=0** — comment claims `nt_resume_thread` covers it, but `KeResumeThread` is a separate export. Canary `xboxkrnl_threading.cc:216-227` calls `thread->Resume()`. **Result: tids 9 (entry=0x824D2878) and 10 (entry=0x824D2940) are `Blocked(Suspended)` at -n 500M end-of-run** despite our `KeResumeThread=2` counter matching canary. Bug class **α (load-bearing stub_success)**. **All 5 discipline boxes pass — first time since IO-004**. Fix is 5 LOC (mirror nt_resume_thread pattern). Sharp 4-dim cascade prediction: A=tids 9/10 leave Suspended; B=KeReleaseSemaphore non-zero; C=2→1 canary-only; D=open hypothesis on `[0x828F4070+64]` becoming non-(-1) if β-blocker is downstream of audio init. Trace `audit-runs/audit-018-canary-diff/ours.{log,stdout.log}`. Master HEAD `7ed6192` unchanged. Next: KRNBUG-α-005, branch `ke-resume-thread/p0-canary-mirror`.
|
||||
- **XamUserGetSigninState landed (2026-05-06, master `7ed6192`)** — small canary-mirror fix at xam.rs:48 (returns 1 for user 0 per `xam_user.cc:90-101`). Tests 599→600. Lockstep `instructions=100000006` deterministic ×2 reruns (was 100000012). Cascade ripple: `XamUserReadProfileSettings` now fires 2× (was canary-only). Canary-only kernel exports: 3→2 (still missing: ExTerminateThread, KeReleaseSemaphore). β-class blocker `[0x828F4070+64]==-1` unmoved per audit-017. swaps=2 draws=0 plateau intact.
|
||||
- [project_xenia_rs_audit_017_state_bits_writer_2026_05_06.md](project_xenia_rs_audit_017_state_bits_writer_2026_05_06.md) — **🎯 KRNBUG-AUDIT-017 (2026-05-06, READ-ONLY)**: 5 static bit-14/15 setters of `[listener+4]` found; case-0xA `0x82173e04` sets bit-15 once at cycle 9183060, sub_821737F0 work-path enters at 9183561, but bit-14 setter at 0x82173950 NEVER fires — gated at 0x821738E0 by `[r30+64]==-1` where r30=`[0x828F48B0+0]=0x828F4070` (singleton sub-object). `[+64]` initialized to -1 by sub_821701c8; only non-(-1) writer is sub_82184318:0x82184374 (`bl 0x82456B58 (kernel handle); stw r3, 64(r30)`); chain bottoms in audit-009 cluster (`sub_82187dd0 ← sub_82183ca8 ← sub_822919c8`). bit-28 of `[singleton+60]` set at cycle 9224352 by sub_821c4988 — too late, AND is a NEGATIVE gate. Bug class **β-dominant + α-tail** (`XamUserGetSigninState=stub_return_zero` at xam.rs:48 breaks 2 separate guest paths but won't fire cascade alone). Discipline gate fails 1+3. No fix. Trace `audit-runs/audit-017-state-bits-writer/probe{1..5}.log`. Master HEAD `d736a1d` unchanged. Next: AUDIT-018 either probe-confirm sub_82184318 chain (3rd γ-cluster confirmation → strategic pivot) or canary-log-diff for missing kernel writer of `[0x828F4070+64]`.
|
||||
- [project_xenia_rs_audit_016_submitter_callers_2026_05_06.md](project_xenia_rs_audit_016_submitter_callers_2026_05_06.md) — **🎯 KRNBUG-AUDIT-016 (2026-05-06, READ-ONLY)**: 0/16 submitter-chain PCs fire at -n 500M across 4 levels of caller walk-up (workitem chain `sub_822AE1F0/sub_822F55F0 → sub_822C8B50 → sub_822C6808` + parents `sub_822ADD70/sub_821A9920/sub_822ACAB8/sub_821A8578` + grandparents `sub_82299250/sub_822A4460/sub_821A82A0`). Both static caller chains bottom-out in audit-009 unreached renderer cluster (`0x82294xxx` / `0x821A6xxx`). Listener-struct dump at `0x40ba9a80`: vtable populated, callback-table A `[+0x2C]=0x4024AC00` POPULATED (audit-015's "==0" claim was WRONG), callback-table B `[+0x3C]=0x4024B3E0` POPULATED, but `[+0x04]` dispatch-state-bits=0 — real gate is `sub_821737F0`'s bit-14/15 read of [+4]. Bug class refined δ→**γ (deeper indirection)**: chicken-and-egg vtable-registry-not-populated. Discipline gate fails 1+3. Probe-machinery anomaly: `sub_82174040` entry never fires despite mid-body PC executing — verify in AUDIT-017. Next: probe `sub_822F1AA8` frame-poll + writers of `[0x40ba9a80+4]` + `sub_82181D48` predicate. Trace `audit-runs/audit-016-submitter-callers/probe{,2}.{log,err}`. Master HEAD `d736a1d` unchanged.
|
||||
- [project_xenia_rs_audit_015_l1_propagation_2026_05_06.md](project_xenia_rs_audit_015_l1_propagation_2026_05_06.md) — **🎯 KRNBUG-AUDIT-015 (2026-05-06, READ-ONLY, FORK B)**: 28/112 PCs fired at -n 500M post-IO-004. sub_82173DC8 dispatches all 4 startup notifications then idles via early-exit at 0x82173ed8 (`[r31+44]==0` callback-table NULL). Worker 0x822c6870 (tids 14, 15) parks on Semaphore handle 0x1308 (`signals=0 waits=2`); producer chain `sub_822AE1F0/sub_822F55F0 → sub_822C8B50 → sub_822C6808 → 0x824AB158 (NtReleaseSemaphore)` is unreached. Worker sub_824563E0 (tid=16) is healthy XAM inactivity-poll loop; not the gate. Worker sub_823DDB50 (tid=19) parks at entry on 0x160C Event/Auto. All 21 audit-009 baseline PCs still UNFIRED. Bug class **δ (pure-guest renderer)** — no kernel boundary stub. Discipline gate fails 1+3, no fix. Next session: probe submitter chain entries + `--dump-addr=0x40ba9a80` listener struct. Trace `audit-runs/audit-015-l1-propagation/`. Master HEAD `d736a1d` unchanged.
|
||||
- [project_xenia_rs_audit_014_0x15e0_wake_2026_05_06.md](project_xenia_rs_audit_014_0x15e0_wake_2026_05_06.md) — **🎯 KRNBUG-AUDIT-014 (2026-05-06, READ-ONLY)**: 0x15e0 wake-eligibility hypothesis FALSIFIED. 0x15e0 is a Semaphore (creator `lr=0x824ab110`), `signal_attempts=1 waits=1 wakes=1`, healthy handshake (tid=1 wait → tid=16 NtReleaseSemaphore wake). tid=17 actually parks on **0x15e4** (Event/Manual, signals=0/waits=1/wakes=0, creator `lr=0x824a9f6c`) — same producer-missing class as 0x1004/0x100c/0x1020. Long-standing transcription error: AUDIT-002/008/009/IO-004 label "0x15e0 worker" should be "0x15e4 worker". Bug classes α-ζ all N/A. Discipline gate fails box 1. No fix. Master HEAD `d736a1d` unchanged. Trace `audit-runs/audit-014-0x15e0-wake/probe.{log,err}`. Next: Fork B branch-probe data on `sub_82173DC8 / 0x822c6870 / 0x824563e0 / 0x823ddb50` for the actual producer.
|
||||
- [project_xenia_rs_io_004_xnotify_listener_2026_05_06.md](project_xenia_rs_io_004_xnotify_listener_2026_05_06.md) — **🎯 KRNBUG-IO-004 (2026-05-06, LANDED branch `xnotify-listener/p0-startup-enqueue`)**: real `XamNotifyCreateListener` + `XNotifyGetNext` per canary `kernel_state.cc:1013-1033` + `xam_notify.cc:22-96`. NotifyListener variant + 4 startup notifications on first listener (mask 0x2F): SystemUI/SystemSignInChanged on kXNotifySystem; LiveConnectionChanged(0x001510F1)/LiveLinkStateChanged on kXNotifyLive. 594→599 tests; lockstep `instructions=100000012` deterministic ×2 reruns. Phase 1.5 sanity probe confirmed CTR=0x82175338 (audit-012-predicted dispatch target unchanged). **Cascade: dispatch arm 0x822f1be8 fires; sub_82173DC8 entered repeatedly; 3/21 renderer-cluster L1 PCs newly reached (0x822c6870 from 2 workers, 0x824563e0, 0x823ddb50)**; canary-only 7→3 (KeResetEvent/ObCreateSymbolicLink/XamTaskCloseHandle/XamTaskSchedule re-classified to fired; still missing: ExTerminateThread/KeReleaseSemaphore/XamUserReadProfileSettings); worker count 18→20; signal_attempts on 0x15e0=1 (primary=1, was 0); draws=0 still expected at this step. LOC 119 ≤ 120. Trace `audit-runs/audit-013-io-004-phase1.5/`.
|
||||
- [project_xenia_rs_cpp_runtime_audit_2026_05_06.md](project_xenia_rs_cpp_runtime_audit_2026_05_06.md) — **🔍 CPPBUG-AUDIT-001 (2026-05-06, READ-ONLY, BACKGROUND-BACKLOG)**: 0x825ED990 = CRT abort dispatcher (NOT _purecall — corrects audit-010); Sylpheed CRT is statically linked. Top-3 vtable=0 candidates REFUTED by audit-012. Real gaps for later: nt_allocate_virtual_memory silent-success-on-error (exports.rs:622-625) + heap.rs:465 silent-unmapped-write drop (combined = "phantom allocation"); mm_allocate_physical_memory_ex ignores alignment/range/protect; sync/eieio interpreter no-ops; RtlRaiseException stub doesn't fatal-stop on MSVC throws. Track for after draws>0.
|
||||
- [project_xenia_rs_audit_012_vtable_zero_2026_05_06.md](project_xenia_rs_audit_012_vtable_zero_2026_05_06.md) — **🎯 KRNBUG-AUDIT-012 (2026-05-06, READ-ONLY)**: ALL FIVE bug-class hypotheses for vtable=0 REFUTED. Vtable IS correctly initialized: mem[0x40111890+0] transitions monotonic 0→0x820AD894→0x820A183C, stays. AUDIT-011's "vtable=0" was a misread (captured PC 0x8284E45C XAM thunk, treated lwz address as live PC). AUDIT-010's "vtable[1]=0x825ED990 abort" was the inner ctor's transient vtable, overwritten 3 instructions later. Real runtime vtable[1] = thunk 0x82175338 → sub_82173DC8. Discipline gate now PASSES for AUDIT-011's listener fix. Next: KRNBUG-IO-004 (real xnotify queue per kernel_state.cc:1013-1033 + xam_notify.cc) with Phase 1.5 sanity probe at 0x822f1c00 (expect CTR=0x82175338) before commit.
|
||||
- [project_xenia_rs_audit_010_xnotify_diff_2026_05_05.md](project_xenia_rs_audit_010_xnotify_diff_2026_05_05.md) — **🎯 KRNBUG-AUDIT-010 (2026-05-05, READ-ONLY)**: branch (α) — xnotify_get_next + xam_notify_create_listener are stubs; canary auto-enqueues 4 startup notifications on listener registration (SystemUI/SystemSignInChanged/LiveConnectionChanged/LiveLinkStateChanged). Discipline gate FAILS box 3: vtable[1] of dispatcher (mem[0x828E1F08]) statically=0x825ED990 abort handler — needs runtime --pc-probe before fix. Provisional cascade: XamUserReadProfileSettings fires next. Trace `audit-runs/audit-010/findings.md`. Master HEAD `50a4887` unchanged.
|
||||
- [project_xenia_rs_audit_009_renderer_unreached_2026_05_05.md](project_xenia_rs_audit_009_renderer_unreached_2026_05_05.md) — **🎯 KRNBUG-AUDIT-009 (2026-05-05, READ-ONLY DIAGNOSTIC)**: 0/21 PCs fired at -n 500M (12 audit-008-recommended renderer-cluster parents+shims+dispatcher + 9 audit-005 producer-callsites). Stop condition 1 triggered. The 0x82287000-0x82294000 cluster is structurally above its observed call boundary — likely reached via vtable/function-pointer that's never populated (sylpheed.db: zero non-call xrefs to its level-1 roots `sub_82293448`/`sub_822919C8`). Main parks in `sub_822F1AA8` frame-poll loop forever (XNotifyGetNext=1.49M, NtWaitForSingleObjectEx=1.49M, RtlEnter/LeaveCS=889k each). 18 workers spawned incl. 0x100c (tid=3, ctx=0x828F3D08), 0x1004 (tid=11, ctx=0x828F3EC0), 0x15e0 (tid=17, ctx=0x828F4070) — all parked, signal_attempts=0. canary-only exports unchanged: ExTerminateThread/KeReleaseSemaphore/XamUserReadProfileSettings. Discipline gate fails boxes 1+3. No fix. Next probe set: cluster L1 roots (sub_82293448/sub_822919C8/sub_82288028/sub_82292d80/sub_822851e0/sub_82286bc8) + new thread entries (0x822c6870/0x824563e0/0x823dde30/0x823ddb50) + main frame-poll callees + main's post-poll continuation (sub_822F1638/sub_8216F088/sub_82173360 etc). Trace at `audit-runs/audit-009/probe-500m.{log,err}` (branch-probe.trace EMPTY).
|
||||
- [project_xenia_rs_audit_008_branch_probe_2026_05_05.md](project_xenia_rs_audit_008_branch_probe_2026_05_05.md) — **🎯 KRNBUG-AUDIT-008 (2026-05-05, READ-ONLY DIAGNOSTIC)**: Model reset on IO-003 cascade. 0x100c worker IS spawned post-IO-003 (tid=3, ctx=0x828F3D08, entry=0x82181830, parked on event 0x1020). Same for 0x1004 (tid=11), 0x15e0 (tid=6). Real next gate is β-class: 5 non-create-chain callers of `sub_821800D8` (shims `bl getter; lwz r3,80(r3); bl sub_824AA1D8` at 0x821802D8/06E0/0B28/0EA0/1254) are never called; parents live in 0x82287000-0x82292FFF (renderer/scene-graph). **AUDIT-009 falsified the audit-008 hypothesis: those parents are themselves not entered — gate is one level higher still.** Discipline gate failed boxes 1+4. Trace at `audit-runs/audit-008/`.
|
||||
- [project_xenia_rs_io_003_ioctl_2026_05_04.md](project_xenia_rs_io_003_ioctl_2026_05_04.md) — **🎯 KRNBUG-IO-003 (2026-05-04, LANDED branch `xboxkrnl-ioctl/p0-fsctl-mountinfo`)**: `nt_device_io_control_file` real impl per canary `NullDevice::IoControl` for FsCtlCodes 0x70000 + 0x74004. **Cascade fired**: priv-11 query runs, XamTaskSchedule fires, canary-only exports 7→3, AND 0x100c worker (tid=3, ctx=0x828F3D08) + 0x1004 worker (tid=11, ctx=0x828F3EC0) + 0x15e0 worker (tid=17, ctx=0x828F4070) all spawn (the original IO-003 prediction-scorecard's "0x100c UNCREATED / spawn count unchanged" marks were wrong per AUDIT-008 — workers were always there post-IO-003, just unlinked from dispatcher addresses in the audit). 592→594 tests; lockstep deterministic. Stack args 9-10 land at `[sp+0x54]` / `[sp+0x5C]` (Xbox 360 PPC EABI param save area = sp+0x14 + 64). `sylpheed_n50m` re-baselined `50000004→50000003`, `imports 407362→407255`. Still canary-only: `ExTerminateThread`, `KeReleaseSemaphore`, `XamUserReadProfileSettings`. **All 3 workers parked, signal_attempts=0** — the producer-side cascade is downstream of where IO-003 reaches; AUDIT-008 + AUDIT-009 trace it to the unreached 0x82287-0x82294 renderer cluster.
|
||||
- [project_xenia_rs_audit_007_branch_probe_2026_05_04.md](project_xenia_rs_audit_007_branch_probe_2026_05_04.md) — **🎯 KRNBUG-AUDIT-007 (2026-05-04, READ-ONLY branch `investigate-sub-824a9710/p0-branch-probe`)**: `--branch-probe` instrumentation landed; runtime trace decisively identifies the priv-11 gate. **Exit branch: `0x824a9944` (post-bl sub_824ABD88 first call, r3=0xC0000034)**. Root cause: `NtDeviceIoControlFile` is `stub_success` at `exports.rs:90` — game-side `sub_824ABD88:0x824abe9c-eb0` reads `[out_buf+8]` of the FsCtlCode=0x74004 IOCTL response, finds zero (stub doesn't write OUT), assigns hardcoded `r3=0xC0000034` (STATUS_OBJECT_NAME_NOT_FOUND) at 0x824abea8-ac, propagates to caller, gates priv-11 site at `0x824a99a0` indefinitely. 592→592 tests, lockstep deterministic. **Next session = KRNBUG-IO-003**: implement `nt_device_io_control_file` per canary `NullDevice::IoControl` for FsCtlCodes 0x70000 + 0x74004. Predicted cascade: priv-11 fires + XamTaskSchedule fires + 0x100c worker spawn + 7→≤3 canary-only exports.
|
||||
- [project_xenia_rs_io_002_volallocunit_2026_05_04.md](project_xenia_rs_io_002_volallocunit_2026_05_04.md) — **🎯 KRNBUG-IO-002 (2026-05-04, LANDED branch `xboxkrnl-vol-allocunit/p0-65536-cluster`)**: vol-info class-3 fixed from 2048→65536 alloc unit (canary NullDevice byte-identical). 591→592 tests, lockstep deterministic. **Audit-006's predicted 7→0 cascade FALSIFIED** (7→7 unchanged): all 16 NtQueryVolumeInformationFile calls originate from a single LR `0x82611f38` and complete successfully — vol-info is NOT the priv-11 gate. Stop condition triggered, no second fix attempted. Next session: `--pc-probe` on `sub_824A9710` entry to find the actual gate (priv-11 site has never fired in any session).
|
||||
- [project_xenia_rs_audit_006_export_queue_2026_05_04.md](project_xenia_rs_audit_006_export_queue_2026_05_04.md) — **🎯 KRNBUG-AUDIT-006 (2026-05-04, READ-ONLY)**: 7/7 canary-only exports all REAL_BUT_UNREACHED → next session is **KRNBUG-IO-002** (block-size 2048→65536 in `exports.rs:1241-1269`, ≤4 LOC). Queue: `xenia-rs/audit-runs/audit-006/canary_export_queue.md`. **Cascade prediction FALSIFIED post-IO-002 — see io_002 memory.**
|
||||
- [project_xenia_rs_io_nullfile_2026_05_04.md](project_xenia_rs_io_nullfile_2026_05_04.md) — **🎯 KRNBUG-IO-001 (2026-05-04, LANDED master `556a8c3`)**: `nt_read_file` on synth-empty files returns SUCCESS+0 instead of EOF, mirroring canary `NullFile::ReadSync`. AUDIT-005's attribution to `sub_824ABA98` was wrong — runtime trace decisively located the failure at the `NtReadFile(\Device\Harddisk0\partition0, off=2048, len=1024)` call inside `sub_824A9710` at PC `0x824a9810`. **`sub_824ABA98 = VerifyDirBlockSize(path, expected_alloc_unit_bytes)`**, **`sub_824ABD88 = MaybeMountAndIoctl`** (NtOpenFile WindowsPartition + NtDeviceIoControlFile 0x70000+0x4004). 590→591 tests. Lockstep BIT-IDENTICAL × 3 reruns. **Cascade walked massively: canary-only exports 10 → 7** (XeCryptSha + XeKeysConsolePrivateKeySign + NtDeviceIoControlFile now run; cache-recreate path executes through to NtWriteFile). Worker threads **6 → 19** at -n 500M (tid=10 `0x82178950` and tid=16 `0x82170430` — the original `0x1004`/`0x15e0` workers — now spawn). `n50m` golden re-baselined `50000004→50000000`, `imports 407416→407362`. **Next blockers**: (1) XamTaskSchedule cluster + ExTerminateThread/KeReleaseSemaphore/KeResetEvent/ObCreateSymbolicLink/XamTaskCloseHandle/XamUserReadProfileSettings — the 7 still-canary-only exports; (2) **block-size mismatch**: `nt_query_volume_information_file` returns `SectorsPerAllocUnit=1, BytesPerSector=2048` (=2048) but Sylpheed expects `0x10000=65536` from `main(1, 0x10000, 0xFF000)` → `sub_824A9710 r27=0x10000`; sub_824ABA98 will return `0xC000014F` when the recreate path eventually reaches it. New parked sites: 0x12fc/0x1600/0x1040/0x10b8/0x15e8/0x1014/0x101c/0x10bc/0x1044 + 0x42450b5c. `swaps=2 draws=0` plateau persists.
|
||||
- [project_xenia_rs_xam_avpack_hdmi_2026_05_04.md](project_xenia_rs_xam_avpack_hdmi_2026_05_04.md) — **🎯 KRNBUG-XAM-001 (2026-05-04, LANDED)**: `XGetAVPack` `0x16` → `8` (HDMI). One-line at `xenia-kernel/src/xam.rs:383` mirroring canary `xam_info.cc:35` (`DEFINE_int32(avpack, 8)`); Sylpheed accepts `{3,4,6,8}` only (`xam_info.cc:250-251`). 589→590 tests. Lockstep deterministic across 3 reruns: `instructions=100000010, import_calls=987686 (+2.4×), VdSwap=2`; `n50m` golden re-baselined `50000005→50000004`. **Canary diff: 11 → 10 missing exports** (XGetAVPack matched). Cascade went exactly **one step**. **NEW telemetry signal**: `RtlNtStatusToDosError(c0000011)` from `lr=0x824a97e4` post-fix — `sub_824A9710` IS being entered now but priv-11 query never fires (a precondition exits early). **Next blocker: `sub_824ABA98` returning negative NTSTATUS** (per AUDIT-005 disasm); if cleared, `XeCryptSha`/`XeKeysConsolePrivateKeySign`/`NtDeviceIoControlFile`/etc. should follow. Parked handles 0x1004/0x100c/0x15e0 still `signal_attempts=0`; 9-PC producer probe still 0×; `swaps=2 draws=0` plateau persists.
|
||||
- [project_xenia_rs_xex_priv_fix_2026_05_04.md](project_xenia_rs_xex_priv_fix_2026_05_04.md) — **🎯 KRNBUG-XEX-001 (2026-05-04, LANDED)**: real `XexCheckExecutablePrivilege` reading XEX `SYSTEM_FLAGS=0x00030000` bitmap (Sylpheed=`0x00000400`, bit 10 set). 588→589 tests. Lockstep deterministic at new value (`instructions=50000005, imports=407417, swaps=2, draws=0` × 3 reruns). Goldens re-baselined. **Priv-10 gate FLIPPED** — `XGetAVPack: 0→1`. Other 10 canary-only exports + 9 producer PCs + 3 parked handles still unchanged: priv-11 site at `sub_824A9710` is downstream and not reached because the AV/crypto block aborts after `XGetAVPack`. **Next blocker: `XGetAVPack` returns `0x16`** — canary returns `cvars::avpack` (default 8 = HDMI), and Sylpheed accepts only 3/4/6/8 (xenia-canary `xam_info.cc:250-251`). One-line follow-up at `xenia-kernel/src/xam.rs:383`.
|
||||
- [project_xenia_rs_audit_005_priv_stub_2026_05_04.md](project_xenia_rs_audit_005_priv_stub_2026_05_04.md) — **🎯 KRNBUG-AUDIT-005 (2026-05-04, LANDED master `451b3b2`)**: --pc-probe extension + canary kernel-call diff. 9 producer PCs unreached at -n 500M (failure mode α). **Root cause: `XexCheckExecutablePrivilege` is `stub_return_zero`** — gates XGetAVPack (priv=10) and XamTaskSchedule (priv=11) via opposite polarities, so guest walks wrong arm of every priv-gated branch and skips the entire init flow that populates dispatcher fields. 11 exports canary calls and we don't (XGetAVPack/XeCryptSha/XamTaskSchedule/...). Next: implement real priv-bit lookup from XEX header.
|
||||
- [project_xenia_rs_audit_004_ctor_probe_2026_05_04.md](project_xenia_rs_audit_004_ctor_probe_2026_05_04.md) — **🎯 KRNBUG-AUDIT-004 (2026-05-04, LANDED master `6a070be`)**: read-only `--ctor-probe=PC` + `--dump-addr=ADDR` diagnostics; 586→588 tests; lockstep `instructions=100000002` preserved. **DECISIVE: "8-instance pool" hypothesis FALSE** — handle 0x1004 has a SINGLE dispatcher at `0x828F3EC0`; inner per-instance ctors `[0x821783D8,0x82181750,0x821701C8]` each fire EXACTLY ONCE. The "called 8 times" claim from AUDIT-002/003 came from miscounting OUTER getter `sub_8217C850` entries — itself a Meyers singleton-getter. **Producer indirection layer IDENTIFIED**: outer getters `sub_821800D8` (0x100c) and `sub_8216F618` (0x15e0) have 5+4 non-create-chain callers using canonical pattern `bl outer_getter; lwz r3, OFFSET(r3); bl 0x824AA1D8` (OFFSET=80 for 0x100c, =36 for 0x15e0). Static byte-scan of .rdata/.data shows 0 hits → no registry table; indirection is via the singleton-getter return value. **Interpretation (2) confirmed.** 9 producer-callsite PCs ready for next-session probe to discriminate failure mode A (producer never reached) from B (producer fires but reads zero from dispatcher field). Files: `crates/xenia-kernel/src/state.rs` (`fire_ctor_probe_if_match`, `ctor_probe_pcs`, `dump_addrs`), `crates/xenia-app/src/main.rs` (CLI wiring + 128-byte struct dumper). Trace at `audit-runs/audit-004/`.
|
||||
- [project_xenia_rs_audit_003_class_probe_2026_05_03.md](project_xenia_rs_audit_003_class_probe_2026_05_03.md) — **🎯 KRNBUG-AUDIT-003 (2026-05-03, LANDED master `48eed25`)**: vtable/RTTI class-readout helper + create-time + wait-time per-frame class probes. 581→586 tests; lockstep `instructions=100000002` preserved. **Identified dispatcher addresses**: handle 0x100c → `0x828F3D08` (verified by `[this+0]=-1` POD struct + sub_82181750 disasm + xref table); handle 0x15e0 → `0x828F4070` (xref table). RTTI is **stripped**; dispatchers are hand-rolled job queues, NOT C++ polymorphic classes (so no class names — `[this+0]=-1` sentinel, not a vtable). **Producer hunt deliverable**: `xrefs` table audit shows EVERY reference to 0x828F3D08 / 0x828F4070 is in a ctor or the CRT — NO submitter code references either dispatcher in static analysis. Confirms unreachable-producer hypothesis. Handle 0x1004's 8-instance pool member addresses still need offline analysis (saved-r31 in MSVC ctors didn't preserve `this`; need to hook sub_8217C850 to capture each pool element's r3). 0x42450b5c remains a separate bug class (heap-allocated, AUDIT_BLIND). Files: `crates/xenia-kernel/src/state.rs` (`read_class_at_this`, `probe_create_stack_classes`), `crates/xenia-app/src/main.rs` (WAIT-side dump). Trace at `audit-runs/audit-003/run-500m-v4.txt`.
|
||||
- [project_xenia_rs_producer_stack_trace_2026_05_03.md](project_xenia_rs_producer_stack_trace_2026_05_03.md) — **🔍 KRNBUG-AUDIT-002 (2026-05-03, LANDED master `6440261`)**: multi-frame back-chain capture at `NtCreateEvent`/`NtCreateSemaphore`/`NtCreateTimer`/`XamTaskSchedule` gated on `--trace-handles-focus`; 576→581 tests; lockstep `sylpheed_n50m` BIT-IDENTICAL. **Subsystems identified**: 0x1004 = static-ctor 8-instance pool (sub_821783D8 + sub_8217C850 chain → static ctor 0x8280F810 calls bridge 8×); 0x100c = singleton built inside main() (sub_8216EA68 = main); 0x15e0 = singleton in distinct cluster (sub_82172BA0 chain). All 3 ctors share identical 4-callee shape (Rtl InitCS + silph::Event ctor + silph internals); all 3 workers do `silph::Thread::SetProcessor(CURRENT,5)` first thing. **Corrections to prior memory**: (1) third handle is **0x15e0**, not 0x15e4 (transcription typo); (2) **0x42450b5c is not a kernel handle** — it's a guest-heap pointer (0x4xxxxxxx), tid=6 parks via a non-`do_wait_single` path (`<UNCREATED> <AUDIT_BLIND>`) — separate bug class. Walker is in `state.rs::walk_guest_back_chain` (PPC EABI back-chain, gated, read-only).
|
||||
- [project_xenia_rs_xaudio_register_driver_2026_05_03.md](project_xenia_rs_xaudio_register_driver_2026_05_03.md) — **🎯 APUBUG-PRODUCER-001 (2026-05-03)**: XAudio register stub replaced with canary-faithful registration + dual-mode ticker (`XAUDIO_INSTR_PERIOD=48k` / `XAUDIO_PERIOD=5.333ms`) + `try_inject_audio_callback` reusing SavedCallbackCtx; 562→576 tests. Ticker gated **default-off** behind `--xaudio-tick`/`XENIA_XAUDIO_TICK=1` so lockstep `sylpheed_n*m.json` goldens stay green. **Producer hypothesis FALSIFIED for handles 0x1004/0x100c/0x15e4** — at `-n 500M --xaudio-tick` all 3 still show `signal_attempts=0`. Side-effect: under the flag the audio callback fires once, hijacks a guest HW thread on a `KeWaitForSingleObject` infinite loop (4M waits, swaps regress 2→1). Next candidate: **Timer DPC** (`KeSetTimer` / `KeInsertQueueDpc`). Master HEAD `9d45efe`.
|
||||
- [project_xenia_rs_xam_task_schedule_2026_05_03.md](project_xenia_rs_xam_task_schedule_2026_05_03.md) — **🎯 XAMBUG-PRODUCER-001 (2026-05-03)**: XamTaskSchedule stub replaced with canary-faithful real spawn; 561→562 tests; lockstep `instructions=100000002` preserved. **Producer hypothesis FALSIFIED for handles 0x1004/0x100c/0x15e4** — counter `kernel.calls{XamTaskSchedule}` never appears at -n 500M (call site `0x824a9a10` unreached). Boot stalls before XamTaskSchedule. Next candidate: `XAudioRegisterRenderDriverClient` (counter=1, currently stub). Master HEAD `38f78c8`.
|
||||
- [project_xenia_rs_audit_2026_05_followup_session.md](project_xenia_rs_audit_2026_05_followup_session.md) — **🎯 FOLLOW-UP SESSION COMPLETE (2026-05-03)**: 3 audit IDs landed (GPUBUG-DRAIN-001 vd_swap fallback warning silenced + new `drain_until_wptr`; KRNBUG-AUDIT-001 ghost-trail diagnostic with `--trace-handles-focus`; KRNBUG-D08 wall-clock vsync under `--parallel`). Tests 556→561. Lockstep BIT-IDENTICAL. **DECISIVE FINDING**: parked-waiter handles 0x1004/0x100c/0x15e4 show `signal_attempts=0 (primary=0, ghost=0)` after 500M instructions — producer is genuinely missing, **NOT a wake-eligibility bug or BST-paradox**. 3 share creator `lr=0x824a9f6c` + wait-wrapper `lr=0x824ac578`. Next session: producer hunt (file I/O completion / XAM async / XAudio buffer-complete / Timer DPC). Master HEAD `b54aa48`.
|
||||
- [project_xenia_rs_fix_session_2026_05_03.md](project_xenia_rs_fix_session_2026_05_03.md) — **🛠️ AUDIT FIX SPRINT (2026-05-03)**: applied 11 commits closing 12 audit IDs across 4 of 8 planned phases. **swaps 1→2** confirmed (Phase A SWAPBUG-001). VdSwap PM4 ring path live (Phase C). Shader operand decode fixed (D1/D2/D3). 8 register addresses + index_size bit corrected (E). Kf-spinlock real impl (F1). 2 P1s (G1 GPUBUG-006 mmio ordering, G2 XMODBUG-002 write_bulk page bumps). **`draws=0` persists at -n 100M lockstep** — renderer plateau is multi-causal, parked-waiter handles still unresolved. Next session: trace producers for handles 0x1004/0x100c/0x15e4/0x42450b5c. Tests 551→556. Plan: `we-just-finished-a-shiny-conway.md`. **Engineering gotchas saved**: VdSwap buffer_ptr is NOT in primary ring; D1's c-vs-temp selector is at w0 bits 29-31 not bit 7; canary's addic actually does full 64-bit add (Plan agent was wrong, G3 deferred); `--stable-digest` flag added to xenia-rs check for byte-exact lockstep determinism.
|
||||
- [project_xenia_rs_audit_2026_05_02.md](project_xenia_rs_audit_2026_05_02.md) — **🎯 COMPREHENSIVE AUDIT COMPLETE (2026-05-02)**: 13-milestone read-only audit of all modules vs canary. **197 finding IDs (15 P0, 40 P1) across 9 prefixes**. **SWAP REGRESSION SOLVED**: SWAPBUG-001 = PPCBUG-001 (addi 32-bit truncation in `bf8208e` at `interpreter.rs:114-118`) — single revert restores swaps=2. **Renderer plateau explained (multi-causal)**: VdSwap PM4 ring bypass + 5 P0 GPU shader/draw bugs (operand modifiers, constant-reg selector, vertex endian, 8 register addresses). Memory write-visibility NOT broken. Parked-waiter handles still unexplained. Final report: `xenia-rs/audit-2026-05-final.md`.
|
||||
- [project_xenia_rs_ppc_audit_2026_04_29.md](project_xenia_rs_ppc_audit_2026_04_29.md) — **🔍 PPC AUDIT COMPLETE (2026-04-29)**: 253 PPCBUG IDs (~55 HIGH, ~75 MEDIUM, 5 retracted). Audit-only, no code changes. **Triaged fix-order plan at `xenia-rs/audit-report-2026-04-29.md`** — start there for fix session. Detailed per-bug entries at `xenia-rs/audit-findings.md`. **Headline finds**: PPCBUG-107 cascade (50+ stores missing `invalidate_for_write` → cross-thread atomics broken, likely Sylpheed renderer cause); 8 decoder/field-extraction bugs collapse into 6 missing accessors + 1 wrong sh64 + 1 missing decode_op6 entry (Phase 2 sweep); PPCBUG-046 (`clrldi r3, r4, 32` no-op); PPCBUG-053+054 (broken `bdnz` after `negx`); PPCBUG-510 (stvewx128 corrupts 12 bytes); PPCBUG-424/425 (vmaddfp128/vmaddcfp128 operand swap — every D3D FMA wrong). 14 must-land-together coupling pairs documented. Audit verified mechanically: every tracker entry referenced in the report.
|
||||
- [project_xenia_rs_addis_signext_root_cause_2026_04_29.md](project_xenia_rs_addis_signext_root_cause_2026_04_29.md) — **🎯 ROOT CAUSE FIX (2026-04-29)**: addis was sign-extending simm16 to 64 bits per PPC ISA, but Xbox 360 user code runs in 32-bit ABI. When sign-extended addis result mixed with zero-extended lwz value, the 64-bit unsigned subfc compare yielded wrong CA, breaking BST traversals. Fix: truncate addis result to 32 bits (`result as u32 as u64`). Throw at sub_82175F10→sub_82454770 fully silenced WITHOUT the r31=14 hack (now removed). All 506+ tests pass. -n 4B runs clean. Renderer plateau at swaps=2 persists — not caused by the addis bug. Lookup other simm16-immediate instructions (`addi rD,r0,...`, `addic`, `subfic`) for similar bugs if more issues surface.
|
||||
- [project_xenia_rs_sylpheed_event_chain_2026_04_29.md](project_xenia_rs_sylpheed_event_chain_2026_04_29.md) — **Stage 3 Path A traced + DECISIVE FINDING (2026-04-29)**: The BST callback-walker hypothesis is RULED OUT (BST module has no walker; only 2 indirect calls in the module are byte-walkers for string transforms). HOWEVER traced upstream and **found that 0x828F3F68 IS registered in the BST by sub_82175E68 at instruction 0x82179134, eight instructions before the validation site sub_82175F10 at 0x82179144 — same function, same thread, sequential execution**. This means the PPC validator's failure to find 0x828F3F68 in the just-populated BST is the PRIMARY bug. **Our throw fix masks it but doesn't fix it.** The likely same memory-coherence issue prevents event 0x1004's signal from being visible to its waiter. Next session: trace specific guest-memory addresses (e.g. `0x40249F68`) at the emulator level, log every write+read with PC, find the visibility bug. This is the unresolved paradox from [project_xenia_rs_sylpheed_throw_2026_04_28.md](project_xenia_rs_sylpheed_throw_2026_04_28.md) — now confirmed as load-bearing.
|
||||
- [project_xenia_rs_sylpheed_stage3_2026_04_29.md](project_xenia_rs_sylpheed_stage3_2026_04_29.md) — **Stage 3 thread-state map (2026-04-29)**: post-throw-fix run at -n 4B confirms deadlock isn't slow-init. 10 worker threads parked, 4 of them on `mr=true` events with `sig=false`: handle 0x1004 (tid=10, sub_82178950), 0x100c (tid=2, sub_82181830), 0x15e4 (tid=16, sub_82170430), 0x42450b5c (tid=6, sub_824CD458). tid=1 main is in a healthy frame-poll loop (PC=0x822F1E00 inside sub_822F1AA8). The throw fix is necessary but not sufficient — Sylpheed renderer cascade has additional breaks. Next session candidates: (A) trace producer for event 0x1004, (B) per-handle NtSetEvent telemetry, (C) Canary diff.
|
||||
- [project_xenia_rs_sylpheed_throw_fix_2026_04_29.md](project_xenia_rs_sylpheed_throw_fix_2026_04_29.md) — **Sylpheed throw silenced (2026-04-29)**: `rtl_leave_critical_section` HLE detects the failing BST validation (cs=0x828F3DA8, lr=0x824546C8, our Rust CEIL finds the node, but PPC computed r31=32) and overrides ctx.gpr[31]=14 → sub_82454600 returns valid → no throw. Game advances to loading renderer resources (ptc_pack.xpr) + spawning all 18 worker threads. **But draws=0 plateau persists** — Stage 2 gate NOT met. The PPC-vs-Rust traversal paradox remains unexplained. Workers park on unsignaled events (Stage 3 territory).
|
||||
- [project_xenia_rs_sylpheed_throw_2026_04_28.md](project_xenia_rs_sylpheed_throw_2026_04_28.md) — **Sylpheed VdSwap=2 plateau diagnosed (2026-04-28)**: rtl_raise_exception rewritten with correct EXCEPTION_RECORD layout + 6-level PPC stack walk + runtime_error decoder (one-shot via new `KernelState::cxx_throw_logged`). Single throw on tid=1 at ~1.2s: `std::runtime_error("lhs is not valid instance")` at PC `0x824547e4` in `sub_82454770` (a generic intrusive-list validator with 29 callers, called from a chain inside `silph::Silph::Impl::OnInit`'s config-tree walker). Canary's RtlRaiseException is also a stub — so the divergence is upstream. Memory file lists next-session candidates (trace registry, or implement minimal SEH).
|
||||
- [project_xenia_rs_hle_import_fixes_2026_04_27.md](project_xenia_rs_hle_import_fixes_2026_04_27.md) — **HLE import fixes (2026-04-27)**: KeInitializeSemaphore now seeds count/limit (was zero-fill), XexGet{Module,Procedure}Address use distinct `HMODULE_XBOXKRNL`/`HMODULE_XAM` pseudo-handles + reverse `(ModuleId,ordinal)→thunk_addr` map populated from main.rs Phase 1. 76 kernel tests pass; -n 30M --parallel still reaches VdSwap=2 with unimpl=0.
|
||||
- [project_xenia_rs_disasm_unify_phase4.md](project_xenia_rs_disasm_unify_phase4.md) — **Disassembler unification Phase 4 complete (2026-04-27)**: assert-based JSON-fixture goldens for base/extended/VMX128 mnemonics + 7 VMX128 accessor unit tests + analysis-shim parity test + DB schema golden (PRAGMA table_info per-table, 5 SQL views). Old println-only audits deleted. All 4 phases complete; constraints honored end-to-end.
|
||||
- [project_xenia_rs_disasm_unify_phase3.md](project_xenia_rs_disasm_unify_phase3.md) — **Disassembler unification Phase 3 complete (2026-04-27)**: db.rs split into `ingest_instructions` + `write_analysis_results`; new `target_hex` column on instructions; `sql_views.rs` defines 5 additive views; new `--analyze=rust|sql|both` flag (default rust). Cross-check confirms Rust and SQL agree on 299,615 branch xrefs; reachability: 7,557/12,156 functions (62%) reachable from entry. Two bugs found+fixed: kind-tag mismatch (xrefs.kind uses short `br`/`j`/`call`, not long names) and reachability seed-collapse.
|
||||
- [project_xenia_rs_disasm_unify_phase2.md](project_xenia_rs_disasm_unify_phase2.md) — **Disassembler unification Phase 2 complete (2026-04-27)**: `iter_disasm` iterator in xenia-cpu yields `DisasmItem`s; `enrich_section` adds analysis context; 3 sinks (text/JSON/DuckDB) consume `RichDisasmItem`. New `xenia dis --json` flag. db.rs and formatter.rs both drive through the iterator. End-to-end smoke verified: 1.87M rows match between DB and JSONL.
|
||||
- [project_xenia_rs_disasm_unify_phase1.md](project_xenia_rs_disasm_unify_phase1.md) — **Disassembler unification Phase 1 complete (2026-04-27)**: single source of truth in `xenia-cpu/disasm.rs` (`format` returns `DisasmText`); analysis `ppc.rs` collapsed 1374→30 LOC shim; `DecodedInstr` unchanged at 8 bytes; silent VMX128 bit-position bug fixed. Phases 2-4 (iterator+sinks, ingest/analyze split + SQL views, fixture goldens) pending.
|
||||
- [project_xenia_rs_m3_realpar_step_08.md](project_xenia_rs_m3_realpar_step_08.md) — **M3 real-par Step 08 / SESSION COMPLETE (2026-04-27)**: real per-HW-thread parallelism landed. N=6 workers + coord + 7-party phaser. 430 tests; 4 lockstep combos match golden; --parallel boots sylpheed to VdSwap=2 in 57s; 20× stress passed. **Perf gate NOT met** — --parallel ~24× slower than lockstep (target was 1.5× faster); deferred parking (Step 05) is the next session's first task.
|
||||
- [project_xenia_rs_m3_realpar_step_06_07.md](project_xenia_rs_m3_realpar_step_06_07.md) — **M3 real-par Step 06+07 (2026-04-27)**: stress harness (parallel_stress.rs) — 20×@5M passed; perf gate measured — 24× slowdown vs lockstep. parallel_stress_long (100×@50M) wired but #[ignore]-gated (impractical at current perf).
|
||||
- [project_xenia_rs_m3_realpar_step_05.md](project_xenia_rs_m3_realpar_step_05.md) — **M3 real-par Step 05 (2026-04-27)**: slot-wake parking attempted but DEFERRED. TOCTOU race between coord's mask publish and worker's mask read across round boundaries — the phaser counter wrapped, B2 timed out. Reverted to Step 04 design (workers always arrive at B1). Documented 3 race-free alternatives for follow-up.
|
||||
- [project_xenia_rs_m3_realpar_step_04.md](project_xenia_rs_m3_realpar_step_04.md) — **M3 real-par Step 04 (2026-04-27)**: real N=6 workers + main-thread coordinator + 7-party phaser via thread::scope. 5 lockstep combos match golden; --parallel digest diverges ~7 instr at -n 2M (expected); -n 30M --parallel reaches VdSwap=2 with halts==0. ~18x slower than lockstep (Step 05+07 will address).
|
||||
- [project_xenia_rs_m3_realpar_step_03.md](project_xenia_rs_m3_realpar_step_03.md) — **M3 real-par Step 03 (2026-04-26)**: run_execution_parallel with per-round drop/reacquire around step_block; --parallel branch routes through it. Single worker; 430 tests; 6 golden combos match; sylpheed -n 30M --parallel reaches VdSwap=2 (3866ms).
|
||||
- [project_xenia_rs_m3_realpar_step_02.md](project_xenia_rs_m3_realpar_step_02.md) — **M3 real-par Step 02 (2026-04-26)**: per-slot body split into worker_prologue + worker_epilogue, WorkerCtx owns per-HW-slot block+decode cache. Lockstep bit-identical; 430 tests; 6 golden combos match.
|
||||
- [project_xenia_rs_m3_realpar_step_01.md](project_xenia_rs_m3_realpar_step_01.md) — **M3 real-par Step 01 (2026-04-26)**: coord_pre_round/idle_advance/post_round + RoundCtl carved out of run_execution. Pure motion refactor; 430 tests pass; all 6 golden combos match.
|
||||
- [project_xenia_rs_m3_followup_real_parallelism_plan.md](project_xenia_rs_m3_followup_real_parallelism_plan.md) — **HAND-OFF (2026-04-26)**: precise design for the N=6 spawn follow-up session. Includes worker-loop pseudocode, coordinator-thread responsibilities, 9 specific concurrency hazards to handle, ~250-350 line size estimate, and the verification matrix the session must pass. Read this first before starting M3-real-parallelism work.
|
||||
- [project_xenia_rs_m3_step_08_verification.md](project_xenia_rs_m3_step_08_verification.md) — **M3 session complete (2026-04-26)**: phaser, per-thread block caches, --parallel spawn (N=1 substrate), reservation table activation, full verification. 411 tests pass; all 6 flag combos golden-match; sylpheed -n 30M --parallel reaches VdSwap=2 with halts==0. Per-step memory files: project_xenia_rs_m3_step_03_04_kernel_wrap_spawn.md, project_xenia_rs_m3_step_07_reservation_activation.md, project_xenia_rs_m3_step_08_verification.md. N=6 actual parallelism deferred per the followup memo.
|
||||
- [project_xenia_rs_concurrency_m3_progress.md](project_xenia_rs_concurrency_m3_progress.md) — earlier (superseded) M3 status doc; kept for context but the step-files are authoritative.
|
||||
- [project_xenia_rs_concurrency_m2_progress.md](project_xenia_rs_concurrency_m2_progress.md) — **M2 substantively complete** (2026-04-26): ReservationTable, ThreadRef gen-packing, atomic bump allocators, per-slot pending_local_irq, --reservations-table flag. M2.6/M2.7 (KernelStateInner + per-slot Mutex<HwSlot>) deferred to M3. 405 tests pass; sylpheed -n 2M golden matches all flag combos.
|
||||
- [project_xenia_rs_concurrency_m1_progress.md](project_xenia_rs_concurrency_m1_progress.md) — **M1 complete** (2026-04-26): default GPU backend is threaded; DrainFence RPC + parker + fence helpers all live; 395 tests pass; sylpheed -n 2M golden matches both modes; VdSwap=1/=2 fire end-to-end.
|
||||
- [project_xenia_rs_current_state.md](project_xenia_rs_current_state.md) — **start here** — where Sylpheed boot sits now, active blockers, investigation tools, memory caveats
|
||||
- [project_xenia_rs_scheduler.md](project_xenia_rs_scheduler.md) — **scheduler architecture (post-2026-04-23 refactor)** — 6 HW slots + per-slot runqueues, ThreadRef identity, bind-and-migrate affinity
|
||||
- [project_xenia_rs_ui.md](project_xenia_rs_ui.md) — stable architecture: threading bridge, GPU pipeline, MMIO, scheduler, HLE primitives, HUD, observability
|
||||
- [project_xenia_rs_cli.md](project_xenia_rs_cli.md) — CLI commands, flags, env vars, DB table layering
|
||||
- [project_xenia_rs_desktop_app.md](project_xenia_rs_desktop_app.md) — desktop app UI/UX (disasm/debugger/analyzer share one workspace)
|
||||
- [project_xenia_rs_edram_resolve_gap.md](project_xenia_rs_edram_resolve_gap.md) — TILE_FLUSH byte copy now lands (clear-resolve + bitwise-equivalent 32bpp); file lists smaller remaining gaps + backlog order
|
||||
- [project_xenia_rs_duckdb.md](project_xenia_rs_duckdb.md) — analysis DBs are **DuckDB**, not SQLite despite `.db` extension — use `python3 -c "import duckdb; ..."`
|
||||
- [project_xenia_rs_perf_tier4.md](project_xenia_rs_perf_tier4.md) — Tier-4 perf landed (2026-04-25): MMIO fast-reject + basic-block cache + GPU pacer; 318→136 ms (2.3×); `XENIA_FORCE_PER_INSTR=1` env var for A/B
|
||||
- [project_xenia_rs_handle_audit.md](project_xenia_rs_handle_audit.md) — **2026-04-25 session**: `--trace-handles` audit harness landed, original HLE sync gap no longer reproduces at -n 500M, MSAA averaging + 64bpp source/clear-resolve in resolve.rs, wgpu RT readback deferred (foundation in place)
|
||||
Reference in New Issue
Block a user