Files
xenia-rs/audit-runs/phase-c-first-divergence/summary.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

4.3 KiB

Phase C — first-divergence audit summary

Date: 2026-05-13. Outcome: The Phase B image_loaded_sha256 δ-content-STOP is a false positive caused by an over-strict invariant. Both engines load the XEX into byte-identical content modulo legitimate engine-specific import-thunk patches. Fix is in the comparison framework; no engine bug exists at this layer.

Three numbers

metric value
bytes in XEX image 9568256
bytes differing canary↔ours (raw) 3704
bytes differing canary↔ours (canonical, imports masked) 0

The path

  1. Ground truth: tools/xex-extract is a Rust offline XEX2 decoder, independent of both engines. Its .pe output sha256 is 9be5f5621c517c78a451245eca25d54388af741ed20e669b2f78438aaa429e72. Provenance verified by independent layout sampling.
  2. Re-snapshot both engines with --phase-b-dump-section-content (this session added: ~22 LOC ours, ~22 LOC canary, behind existing cvar — default off, inert).
  3. first-diff.py — masks XEX import slots (4 bytes per record_type=0, 16 bytes per record_type=1, 3920 bytes total / 398 slots) and compares. Outcome: canary canonical == ours canonical == .pe canonical = 62c51908e2df705583fe81a084f39bd399196f9000cfa7bffd56127b41a4ab96.
  4. diff_state.py — added --xex-json flag + canonical-hash invariant. STOP invariant downgraded from raw image_loaded_sha256 match to canonical match. Backward-compat: when --xex-json is omitted OR image.bin is missing, old behavior preserved.

Why this is an instrumentation fix, not an engine fix

  • canary patches record_type=0 import slots with 0xDEADC0DE poison.
  • ours patches record_type=0 slots with 0x00000000.
  • canary overwrites record_type=1 thunks with sc/blr/nop/nop host-shim bytes.
  • ours leaves record_type=1 thunks as the .pe template (HLE dispatch occurs at the JIT call site, not by overwriting thunk bytes).

These are valid engine implementation choices for the same semantic behavior. The XEX-decode pipeline (AES decrypt + LZX decompress + section layout + applied relocations) produces byte-identical output in both engines and is verified against the third-party offline decoder.

Files in this directory

file purpose
summary.md This file.
ground-truth.md Provenance + verification of the .pe third reference.
classification.md First byte-diff classification + canonicalization rationale.
first-diff.py The first-byte-diff tool (raw + canonical + vs .pe).
first-diff-report.md Output of first-diff.py on snap-001.
post-fix-diff-report.md Output of updated diff_state.py with --xex-json.
post-fix-diff-report.json Same, machine-readable.
fix.diff Summary + content of the actual changes landed.
re-validation.md Per-gate evidence (3 cvar-off runs, re-snap, Phase A re-diff).
snap-001/ Fresh canary + ours snapshots with content dump.
snap-002/ Reproducibility test re-snapshot for ours.
phase-a/ Phase A re-diff event logs + report.
digest-cvaroff-{1,2,3}.json Determinism reproducibility runs.

Cascade vs prediction

predicted actual
A (first byte-diff localized + classified) ~85% (off=0x600, .rdata, import slot)
B (ground truth identified) ~70% (.pe via xex-extract, verified)
C (wrong engine + bug found) ~55% no engine bug — fix in comparison framework
D (fix lands + image-load matches) 35-45% canonical hash matches
D' (kernel.call prefix extends) ~55% unchanged at 113 (expected — no engine change)

Cascade C resolves to "instrumentation bug, not engine bug" — an outcome the brief anticipated via tripstone #2 ("Import thunks are legitimately engine-specific... canonicalize and re-find first diff").

What Phase C+1 should do

  1. The remaining 68 advisory divergences in post-fix-diff-report.md are all downstream of allocator strategy or kernel-object population differences. ε-class (allocator drift) is documented as catalog-only.
  2. The real first runtime divergence per Phase A's diff is at tid_event_idx=113: KeQuerySystemTime return_value: canary=0 ours=1880095840. This is a kernel-call semantic divergence and is the natural Phase C+1 target.