diff --git a/docs/agents/CONSOLIDATION.md b/docs/agents/CONSOLIDATION.md index cb9f02af..953aa0c1 100644 --- a/docs/agents/CONSOLIDATION.md +++ b/docs/agents/CONSOLIDATION.md @@ -259,6 +259,75 @@ deleting, or step 3 silently ratifies every omission in step 2. The two `.jsonl` mission-state dumps alone are 4.3 MB, and one is an orphan. +## 🔴 A gate that walks `refs/heads` cannot see a working tree + +**Found 2026-09-14, on the other machine, while pulling the repos.** `xenia-rs` +had **468 uncommitted lines plus an untracked 338-line `imports.rs`** sitting in +`crates/xenia-analysis` — the very crate Phase 3 lifted. Written 2026-09-10 +21:01–21:23; found four days later. + +It existed in exactly one place, and that place was not git: + +| | `imports.rs` | `import_address` | `zq.py impcalls` | +|---|---|---|---| +| PR #32, the lifted crate | ✗ | ✗ | ✗ | +| `iterate-4A` (committed) | ✗ | ✗ | ✗ | +| **xenia-rs working tree** | **✓** | **✓ (4 files)** | **✓** | + +**Phase 0 is titled "Secure the single-copy work" and its gate passed anyway**, +because the gate tests branch *reachability* — it iterates `refs/heads`. A dirty +working tree has no ref. Canary's two dirty files were secured only because a +human already knew they were there; nothing *found* them. Phase 1 then pushed +xenia-rs's four branches and called the archive honest while this sat beside them. + +Phase 5 ends with *"delete the local clone"* and Phase 7 drops the emulator, so +this had a deletion scheduled against it. + +**The gate needs a second half. Before archiving or deleting anything:** + +```bash +for d in Sylpheed sylpheed-reborn xenia-rs xenia-canary; do + n=$(git -C "$d" status --porcelain | wc -l) + [ "$n" = 0 ] || echo "🔴 $d has $n uncommitted path(s)" +done +``` + +Run 2026-09-14 across all four: only `xenia-canary` is dirty, and both entries +(`build-cross/`, `vkd3d-proton.cache`) are already on Phase 7's drop list. + +✅ **Secured** — `xenia-rs` branch **`harvest/import-thunk-naming`** @ `b4f19f1`, +pushed. Committed exactly as found, not cleaned up: editing it first would have +destroyed the thing being preserved. `cargo check -p xenia-analysis` = **0**. + +✅ **Ported** — **PR (new)** `feat/xexdb-import-naming`, stacked on #32. The +lift's base is exactly the harvest's parent, so every file merged three-way: +**10 conflicts, all of them caused by the lift's reformatting pass** — 9 are the +harvest's additions landing inside blocks rustfmt had rewrapped (so the content +is kept and re-indented to the lift's style), and **1 is genuinely semantic**: +insertion *order*, because `xdbf_achievements.image_id` is now an FK onto +`xdbf_images(id)`, so the image rows must be inserted first. The conflict there +was the stale copy of the block left at its old position. `cargo test -p sylpheed-xexdb` 10/0, clippy and fmt clean. + +📌 Two things it carries, both absent from #32 as lifted: import-thunk +recognition (disassembly says `xboxkrnl.exe::RtlEnterCriticalSection` instead of +`.long 0x01010194`), and **16 schema-wide foreign keys** — with `functions` +deliberately excluded and the golden test now *asserting* zero inbound FKs onto +it, since DuckDB's UPDATE is delete+insert and one inbound FK would make +`functions.name` un-updatable and break `apply_re_symbols.sql`. + +### Phase 3 residue found while porting + +* 🔴 **`tools/zq.py:48` hardcodes `/home/fabi/RE - Project Sylpheed/xenia-rs/sylpheed.db`** + — a default path *inside the repository Phase 5 archives and Phase 7 drops*. + Not changed here, because the right replacement is a decision (env var, + workspace-relative, or required argument) rather than a guess. +* `tools/zq.py:52` still tells the user to regenerate with `xenia-rs dis`, the + retired binary. `SCHEMA.md` is still headed *"`xenia-analysis` schema + reference"* and cites `xenia-rs dis --db`. +* Phase 3's "says SQLite, is DuckDB" correction **was** made where it counts + (README and the binary's module doc both say DuckDB), but two inline comments + at `sylph-xexdb.rs:499` and `:874` still say SQLite. + ## Phase 5 — Verify the invariant, then archive ⬜ **NOT STARTED** For each of `Syplheed-Reborn`, `Sylpheed-Godot`, `xenia-rs`, `xex2tractor`: @@ -335,6 +404,7 @@ been merged** — merging is the human's, and #32 contains #30 and #31. |---|---|---| | **0** secure single-copy work | ✅ done | Canary `8e63a9542`, `sylpheed-re` + `audit-handle-lifecycle-probes` pushed | | **1** make the archive honest | ✅ done | xenia-rs `iterate-4B/4C/4D/4E` pushed (32/52/56/59 commits) | +| **0b** the dirt the gate could not see | ✅ done 2026-09-14 | xenia-rs `harvest/import-thunk-naming` `b4f19f1`, ported in `feat/xexdb-import-naming` | | **2** harvest xex2tractor | ✅ done | **PR #30** `harvest/xex2tractor-assets` | | **3** lift the DB tool | ✅ done | **PR #32** `feat/xexdb-tool` | | **4** captures + the missing check | ✅ done | **PR #33** `fix/capture-citations` | @@ -343,7 +413,7 @@ been merged** — merging is the human's, and #32 contains #30 and #31. | **5** archive the four repos | ⬜ **open — needs the human** | | | **7** intended drops | ⬜ **open — partly needs the human** | | -## 🔴 Four claims on this page were wrong. Read these before trusting the rest. +## 🔴 Five claims on this page were wrong. Read these before trusting the rest. 1. **"10 dangling citations" was ONE.** Eight were *directory* references, which resolve and are simply absent from `git ls-tree`; one was a path at the end of @@ -354,6 +424,9 @@ been merged** — merging is the human's, and #32 contains #30 and #31. 3. **The Phase 0 gate compared branches by SHA** and called seven safe branches unpushed. It tests reachability now. 4. **There is no DXC submodule drift.** The ` m` is *nested* submodule dirt. +5. **Phase 0 did not secure all the single-copy work**, and its gate could not + have: it walks `refs/heads`, and 468 uncommitted lines in `xenia-rs` have no + ref. Secured 2026-09-14 — see the section above Phase 5. ## What the other machine should do next