# 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_reset` * `ke_set_event_returns_constant_one_on_already_signaled_manual_reset` * `nt_set_event_null_prev_ptr_returns_status_success_no_write` * `nt_set_event_valid_prev_ptr_writes_constant_one_and_returns_success` * `nt_set_event_on_signaled_event_writes_one` * `ke_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`).