Files
xenia-rs/audit-runs/phase-c5-NtWriteFile/re-validation.md
MechaCat02 ef93a4fa14 handoff: VSync/event-wedge fixes + iterate 2.A–2.BC research notes
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>
2026-06-05 07:19:08 +02:00

3.9 KiB

Phase C+5 — re-validation

Gate 1 — Determinism (cvar-OFF, ours)

3 fresh runs of check -n 50000000 --stable-digest:

run digest md5
1 c6d895829b4611964978990ae1cb8a6a
2 c6d895829b4611964978990ae1cb8a6a
3 c6d895829b4611964978990ae1cb8a6a
Stage-2 baseline (pre-C+5) d8a3d439c37d0436a12c3e01149d8fa8

Result: byte-identical across 3 runs. New baseline c6d89582… diverges from the Stage-2 baseline d8a3d439… — expected per Tripstone #4 ("a real return-value fix in ours likely shifts the boot trajectory; the baseline digest WILL change"). The fix flips NtOpenFile's reg read (r8 → r7) + adds an async_file_handles side table + adds a STATUS_PENDING branch to nt_write_file. The combined effect changes import counts from 40452 → 40470 (+18) because the game's downstream code reacts to the new async-style returns.

Gate 2 — Phase B image_canonical_sha256

Phase B snapshot captured to snap/ours/. image_loaded_sha256 = ea8d160e9369328a5b922258a92113efb8d7ce3e1a5c12cc521e375985c91c18, matches the Phase-A/B verify baseline. The fix touches only the kernel-export shim layer and the in-process file-handle table — no PE image bytes modified.

Gate 3 — Phase A matched-prefix extension (KEY METRIC)

Diffed audit-runs/phase-c5-NtWriteFile/ours.jsonl against the existing phase-c-first-divergence/phase-a/canary.jsonl.

chain C+3 (pre-C+5) C+5 (post) Δ
canary tid=6 → ours tid=1 (main) 102068 102132 +64
canary tid=4 → ours tid=11 5 5 0
canary tid=7 → ours tid=2 15 15 0
canary tid=12 → ours tid=7 2 2 0
canary tid=14 → ours tid=9 39 39 0
canary tid=15 → ours tid=10 (no div) (no div) 0

Main thread matched prefix grew from 102068 to 102132. Gate 3 .

The new first-divergence at idx=102132 is NtClose (canary) vs IoDismountVolumeByFileHandle (ours) — a call-name divergence indicating a different branch, that's the next Phase C+N target.

Gate 4 — Build

$ cargo build --release
   Compiling xenia-kernel v0.1.0
   Compiling xenia-app v0.1.0
    Finished `release` profile [optimized] target(s) in 6.34s

One pre-existing dead-code warning (walk_committed_regions); not introduced by this fix. Canary untouched.

Gate 5 — Phase A determinism (emitter)

Two cvar-ON captures of the same engine binary on the same ISO, md5-summing only deterministic fields (excluding host_ns):

ours.jsonl  (run 1, deterministic-fields-only)   388d394a92f6b26a44d549fb70ca95fa
/tmp/c5_pa_run2.jsonl (run 2, det-fields-only)   388d394a92f6b26a44d549fb70ca95fa

Byte-identical.

Gate 6 — Kernel unit tests

$ cargo test --release -p xenia-kernel
test result: ok. 144 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

3 new tests added (141 → 144):

  • nt_write_file_async_handle_returns_status_pending — file in async_file_handles returns STATUS_PENDING; IO_STATUS_BLOCK still records STATUS_SUCCESS.
  • nt_write_file_sync_handle_returns_status_success — file NOT in async_file_handles retains legacy STATUS_SUCCESS return.
  • nt_close_prunes_async_file_set — final handle close removes from the side-table.

Pre-existing cache_create_write_read_roundtrip updated to set FILE_SYNCHRONOUS_IO_NONALERT on its create_options stack slot so the created handle is sync (legacy STATUS_SUCCESS assertion preserved).

Summary

All 6 gates pass. Phase A main matched prefix grew from 102068 to 102132 (+64 events). Two interlinked engine defects fixed: (1) wrong register read in nt_open_file (r8 → r7); (2) missing async/sync tracking on file handles. Diff-tool unchanged. Canary unchanged.

Next divergence: NtClose vs IoDismountVolumeByFileHandle at tid_event_idx=102132 (call-name divergence — game branches into a different code path). Class likely (A) missing handler or upstream state divergence — Phase C+6 target.