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>
102 lines
5.6 KiB
Markdown
102 lines
5.6 KiB
Markdown
# Phase C+12 re-validation (cold-vs-cold)
|
||
|
||
## Cache-wipe protocol (CORRECTED from C+11.1)
|
||
|
||
The Phase C+11.1 protocol wiped `~/.local/share/Xenia/cache`, but
|
||
the Windows-debug canary running under wine actually stores its
|
||
cache at `xenia-canary/build-cross/bin/Windows/Debug/cache/` (the
|
||
binary directory; verified by canary's `Storage root: Z:\...\build-
|
||
cross\bin\Windows\Debug` startup log). C+12's effective wipe targets
|
||
the binary directory.
|
||
|
||
Step-by-step (the protocol used here):
|
||
|
||
1. Backup canary's binary-dir cache:
|
||
`tar -czf /tmp/canary-binary-cache-backup.tar.gz -C
|
||
xenia-canary/build-cross/bin/Windows/Debug cache`
|
||
(4.7 MB, 23 files). Copy to
|
||
`audit-runs/phase-c12-NtQueryFullAttributesFile/
|
||
canary-binary-cache-pre-wipe.tar.gz`.
|
||
2. Wipe both engines' caches:
|
||
* `find xenia-canary/build-cross/bin/Windows/Debug/cache -mindepth 1 -delete`
|
||
* `find xenia-canary/build-cross/bin/Windows/Debug/cache0 -mindepth 1 -delete`
|
||
* `find xenia-canary/build-cross/bin/Windows/Debug/cache1 -mindepth 1 -delete`
|
||
* `find ~/.local/share/xenia-rs/cache -mindepth 1 -delete`
|
||
3. Cold ours run:
|
||
`./xenia-rs/target/release/xrs-c12 exec --phase-a-event-log
|
||
/tmp/ours-cold-c12-v2.jsonl -n 50000000 "<ISO>"`
|
||
(~3 s wallclock).
|
||
4. Cold canary run (background, killed after 5M+ canary events):
|
||
`cd xenia-canary/build-cross/bin/Windows/Debug &&
|
||
/usr/bin/wine ./xc-c12.exe --mute=true
|
||
--phase_a_event_log_path=canary-cold-c12-v2.jsonl "<ISO>"`
|
||
Killed via `wineserver -k` after ~120 s wallclock once the jsonl
|
||
reached ~6 M lines (250 k tid=6 events buffered).
|
||
5. Truncate canary jsonl per-tid (cap tid=6 at 250 k, other tids at
|
||
20 k) to keep the diff tractable. Truncated file is 119 MB / 533 k
|
||
lines (kept) — the differ runs on this.
|
||
6. Diff:
|
||
`python3 xenia-rs/tools/diff-events/diff_events.py
|
||
--canary <truncated> --ours /tmp/ours-cold-c12-v2.jsonl
|
||
--out /tmp/diff-c12-cold-v2.md`.
|
||
7. Restore canary's binary-dir cache from backup so future runs
|
||
keep the oracle intact.
|
||
|
||
## Canonical post-C+12 cold-vs-cold matched-prefix table
|
||
|
||
| canary_tid | ours_tid | matched | canary_total | ours_total | first_divergence_at | notes |
|
||
|---|---|---|---|---|---|---|
|
||
| 6 | 1 | **103862** | 250000 | 108471 | 103862 | **main chain — +1458 events vs C+11.1**. New divergence: NtCreateFile `game:\dat\files.tbl` returns canary=STATUS_OBJECT_NAME_NOT_FOUND (0xC0000034) / ours=STATUS_SUCCESS (synth-empty stub for missing disc files; AUDIT-006 fallback). |
|
||
| 4 | 11 | 9 | 20000 | 9 | — | sister — no divergence within the 9 ours events |
|
||
| 7 | 2 | 29 | 29 | 30 | — | sister — no divergence within the 29 canary events |
|
||
| 12 | 7 | 2 | 10532 | 3 | 2 | sister — pre-existing KeWaitForSingleObject return (TIMEOUT/SUCCESS); NOT regressed |
|
||
| 14 | 9 | 39 | 20000 | 75 | 39 | sister — pre-existing XAudio init divergence; NOT regressed |
|
||
| 15 | 10 | 15 | 20000 | 15 | — | sister — no divergence within the 15 ours events |
|
||
|
||
## Gate matrix
|
||
|
||
| gate | result | notes |
|
||
|---|---|---|
|
||
| Build (cargo build --release) | PASS | 1 unrelated `dead_code` warning, no errors |
|
||
| Kernel tests (172 → 177) | PASS | 5 new C+12 tests, all pass |
|
||
| Full workspace tests | PASS | 702 tests pass (sum of all crates) |
|
||
| Determinism — 3× cold stable-digest | PASS | `ad4f74ee324fdedb0bfdd4cc4c6468e9` (all 3) — IDENTICAL to C+11.1 baseline |
|
||
| `--stable-digest` digest unchanged | PASS | C+12 fix is observation-only on the stable counters |
|
||
| Phase B `image_loaded_sha256` | PASS | `ea8d160e9369328a5b922258a92113efb8d7ce3e1a5c12cc521e375985c91c18` unchanged |
|
||
| Cold-vs-cold matched prefix | PASS | **102404 → 103862 (+1458)** on main chain |
|
||
| Sister-chain regression check | PASS | All 5 sister chains unchanged |
|
||
|
||
## Source data
|
||
|
||
| file | size | notes |
|
||
|---|---|---|
|
||
| `canary-cold.jsonl` | 1.4 GB | full canary cold run, 6.0 M lines (post-kill) |
|
||
| `canary-cold-tid6-250k.jsonl` | 119 MB | per-tid truncated for diff (tid 6: 250 k, others: 20 k cap) |
|
||
| `ours-cold.jsonl` | 28 MB | ours cold run, 121 k tid=1 events |
|
||
| `diff-cold-vs-cold.md` | 8 KB | the `diff_events.py` output |
|
||
| `canary-binary-cache-pre-wipe.tar.gz` | 4.7 MB | canary's 23-file oracle preserved before wipe (binary-dir!) |
|
||
| `digest-cold-stable-{1,2,3}.json` | <1 KB each | 3 determinism runs, identical hash |
|
||
| `phase-b-snap/ours/` | ~5 MB | Phase B 5-file snapshot with `image_loaded_sha256` |
|
||
|
||
## Notes
|
||
|
||
* The +1458-event advance lands at a new tid=6 divergence:
|
||
`NtCreateFile game:\dat\files.tbl` returns SUCCESS in ours because
|
||
the disc dump doesn't ship this file but ours's `open_vfs_file`
|
||
fallback synthesizes a 0-byte file (see `exports.rs:1399-1422`),
|
||
while canary returns `STATUS_OBJECT_NAME_NOT_FOUND` since it has
|
||
no equivalent stub. This is a long-standing intentional fallback
|
||
(rationale: "synthesize empty file lets the game's existence
|
||
probe succeed for files the rip lacks") that now becomes the
|
||
next divergence target.
|
||
* The synth-empty fallback was originally introduced to prevent
|
||
`XamShowDirtyDiscErrorUI` on missing disc files — removing it
|
||
outright might regress past audits. Phase C+13 should investigate
|
||
whether Sylpheed actually needs the file or whether the dirty-disc
|
||
path is now correctly gated by other logic.
|
||
* Stable digest unchanged confirms the C+12 fix is a **pure observation
|
||
change**: the in-memory entry tree and the `nt_query_full_attributes_
|
||
file` rewrite affect only the kernel's response on `cache:` lookup
|
||
probes, not the per-instruction execution path observed by the
|
||
digest. The 1458-event advance is the kernel-export-side effect.
|