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>
89 lines
4.3 KiB
Markdown
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.
|