Source changes (dormant parity infra, retained from iterate 2.AI/2.AO): - xenia-kernel/exports.rs: nt_create_event manual_reset polarity + related event wiring - xenia-gpu/mmio_region.rs: D1MODE_VBLANK_VLINE_STATUS hardcode parity Also lands the audit-runs/ analysis notes (.md/.txt/.json digests) for the iterate 2.x VSync/0x10e8/0x1004 wedge investigation. Raw trace dumps (.jsonl/.gz/.csv/.stdout) and agent worktrees (.claude/) are gitignored as regenerable local artifacts — see memory + HANDOFF for the running findings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.1 KiB
Phase C+7 — re-validation
Gate table
| gate | result |
|---|---|
1. cvar-OFF determinism (3 runs, 50M, --stable-digest) |
PASS all 3 = c6d895829b4611964978990ae1cb8a6a (UNCHANGED from C+6½) |
1b. cvar-OFF determinism (2 runs, 200M, --stable-digest) |
PASS both = 8186841b38737f3cd1b3d2e91a35d108 (new 200M baseline) |
2. Phase B image_loaded_sha256 |
PASS ea8d160e9369328a5b922258a92113efb8d7ce3e1a5c12cc521e375985c91c18 matches baseline |
| 3. Phase A main matched prefix ≥ 102158 | PASS 102158 (preserved — no main-chain regression, no #23 redux) |
| 3b. Phase A sister chain tid=4→11 advances | PASS 5 → 9 (full alignment, no divergence in ours's 9-event window) |
| 3c. Phase A sister chain tid=7→2 advances | PASS 26 → 29 (full alignment, no divergence in canary's 29-event window) |
| 4. Both engines build clean | PASS ours: cargo build --release ok (pre-existing walk_committed_regions dead-code warning) |
| 5. Phase A emitter determinism (det fields only) | PASS 2 runs 90fb28202b70cb43a63def7a2f8b470d byte-identical |
| 6. Unit tests | PASS 146 → 152 (6 new, 0 modified, 0 regressed) |
Gate 1 — 50M determinism
c6d895829b4611964978990ae1cb8a6a digest-cvaroff-1.json
c6d895829b4611964978990ae1cb8a6a digest-cvaroff-2.json
c6d895829b4611964978990ae1cb8a6a digest-cvaroff-3.json
Digest is unchanged from C+6½ baseline. This is expected:
--stable-digest reports (instructions, imports, draws, swaps, unique_render_targets, shader_blobs_live, texture_cache_entries),
none of which are sensitive to KeSetEvent return-value within the 50M
horizon. Imports stay at 40470 (the KeSetEvent change moves no new
import call; only the return value of existing calls flips from 0 to
1). Draws stay at 0, swaps stay at 1.
Gate 1b — 200M stability
8186841b38737f3cd1b3d2e91a35d108 digest-cvaroff-200M-1.json
8186841b38737f3cd1b3d2e91a35d108 digest-cvaroff-200M-2.json
200M run is byte-deterministic across 2 runs. No 200M C+6½ baseline to compare against (none was captured), but the new digest is itself a regression marker for any future fix. Field values at 200M: imports=40470, draws=0, swaps=1 — same plateau as 50M.
Gate 3 — Phase A diff (all chains)
| chain | C+6½ XAM | C+7 | Δ |
|---|---|---|---|
| canary tid=6 → ours tid=1 (main) | 102158 | 102158 | 0 (preserved) |
| canary tid=4 → ours tid=11 | 5 | 9 | +4 (all ours events match) |
| canary tid=7 → ours tid=2 | 26 | 29 | +3 (all canary events match) |
| canary tid=12 → ours tid=7 | 2 | 2 | 0 (different bug — KeWaitForSingleObject=258 vs 0) |
| canary tid=14 → ours tid=9 | 39 | 39 | 0 (different bug — XAudio vs RtlEnterCS) |
| canary tid=15 → ours tid=10 | (no div) | (no div) | 0 |
Two sister chains advanced exactly as predicted by the C+6½ memory note. Main chain (XamTaskCloseHandle at 102158) is explicitly unchanged — the KeSetEvent fix doesn't touch the XamTaskHandle path; that divergence remains the next session's target.
Gate 5 — emitter determinism
Phase A emitter run twice over the same boot, with all
non-deterministic fields (host_ns, guest_cycle, engine,
deterministic) stripped:
90fb28202b70cb43a63def7a2f8b470d ours.jsonl
90fb28202b70cb43a63def7a2f8b470d ours-determ.jsonl
Byte-identical det fields. New emitter-det baseline replaces
C+6½'s 11a07772… — the return-value field is included in the
deterministic schema, and KeSetEvent's contribution flipped from 0
to 1 on every emit.
Gate 6 — unit tests
cargo test -p xenia-kernel --release — 152/152 pass. New 6
tests:
ke_set_event_returns_constant_one_on_unsignaled_auto_resetke_set_event_returns_constant_one_on_already_signaled_manual_resetnt_set_event_null_prev_ptr_returns_status_success_no_writent_set_event_valid_prev_ptr_writes_constant_one_and_returns_successnt_set_event_on_signaled_event_writes_oneke_set_event_post_fix_still_wakes_waiter
All existing 146 tests still pass — no regressions from the
return-value flip (other test bodies don't assert on the return
value of ke_set_event / nt_set_event).