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>
3.2 KiB
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.