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

89 lines
4.3 KiB
Markdown

# 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.