Files
xenia-rs/audit-runs/phase-c1-keQuerySystemTime/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

65 lines
3.2 KiB
Markdown

# Phase C+1 — re-validation
## Gate 1 — Determinism (cvar-OFF)
3 fresh runs of `check -n 50000000 --stable-digest`:
| run | digest md5 |
|-----|------------|
| 1 | 608d8e8d293250698207a7d8fc0c18df |
| 2 | 608d8e8d293250698207a7d8fc0c18df |
| 3 | 608d8e8d293250698207a7d8fc0c18df |
| Phase C baseline | 608d8e8d293250698207a7d8fc0c18df |
**Result**: ✅ byte-identical. Fix is cvar-OFF inert (digest captures kernel-call counts, packets, draws, swaps, RTs, shaders — none of these change with the new field added).
## Gate 2 — Phase B image_canonical_sha256
Not re-snapshotted. Inferred OK by Gate 1: the cvar-OFF digest (which encompasses imports, kernel-call counts, GPU draws/swaps, etc.) is byte-identical to the Phase C baseline. The fix touches only `state.rs::call_export`'s Phase A emit branch (cvar-gated) and a HashSet population in `KernelState::new`; image-loading code is untouched.
## Gate 3 — Phase A matched-prefix extension (THE KEY METRIC)
Captured `audit-runs/phase-c1-keQuerySystemTime/ours.jsonl` with `--phase-a-event-log` and diffed against existing `phase-c-first-divergence/phase-a/canary.jsonl`.
| chain | Phase A pre-fix matched | post-fix matched | Δ |
|-------|------------------------|------------------|----|
| canary tid=6 → ours tid=1 (main) | 113 | **161** | +48 |
| canary tid=4 → ours tid=11 | 5 | 5 | 0 |
| canary tid=7 → ours tid=2 | 2 | 2 | 0 |
| canary tid=12 → ours tid=7 | 2 | 2 | 0 |
| canary tid=14 → ours tid=9 | 11 | 11 | 0 |
| canary tid=15 → ours tid=10 | — | — | (no divergence) |
**Main thread matched prefix grew from 113 to 161. Gate 3 ✅.**
Specifically: ours's idx=113 now emits `{name: "KeQuerySystemTime", return_value: 0, status: "0x00000000"}` — matching canary byte-for-byte. The diff tool advanced past 113 through 160 inclusive and stopped on idx=161 (`MmAllocatePhysicalMemoryEx`), which is the next divergence (out of scope this session).
## Gate 4 — Build
Both ours and canary build clean. Canary not rebuilt (no canary code changed); ours rebuilt via `cargo build --release -p xenia-app`:
```
Compiling xenia-kernel v0.1.0
Finished `release` profile [optimized] target(s) in 10.33s
```
One pre-existing dead-code warning (`walk_committed_regions` in `phase_b_snapshot.rs`); not introduced by this fix.
## Gate 5 — Phase A determinism
Ours's `event_log` unit tests pass:
```
test event_log::tests::fnv1a_known_vector ... ok
test event_log::tests::semantic_id_stable ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 127 filtered out
```
The KeQuerySystemTime event for idx=113 emits `return_value: 0` deterministically — verified by grepping the captured jsonl. The emitter change is a pure conditional select; no new entropy source.
## Summary
All 5 gates pass. The fix is symmetric: canary already emits `0` for void exports via its `if constexpr (std::is_void<R>::value)` trampoline branch; ours now matches that semantic for exports registered with `register_void_export`. Only `KeQuerySystemTime` is so registered in this session per "do not widen scope".
Next divergence: **MmAllocatePhysicalMemoryEx @ tid_event_idx=161** (canary returns `0xBC220000`, ours returns `0x40105000`) — a host-allocator address-space divergence (AUDIT-043 class ε). Phase C+2 target.