diff --git a/docs/agents/CONSOLIDATION.md b/docs/agents/CONSOLIDATION.md index cb9f02af..0b8ecf07 100644 --- a/docs/agents/CONSOLIDATION.md +++ b/docs/agents/CONSOLIDATION.md @@ -259,6 +259,160 @@ 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` hardcoded `/home/fabi/โ€ฆ/xenia-rs/sylpheed.db`** โ€” a default + path *inside the repository Phase 5 archives and Phase 7 drops*, resolving on + exactly one machine and days from becoming a `duckdb` exception with nothing + saying why. **Fixed in PR #35 (`38cc170`):** `$SYLPH_XEXDB` โ†’ `/sylpheed.db` โ†’ a refusal naming both, with the repo-root path taken + relative to the *script* rather than the caller's cwd. **No fallback beyond + that, deliberately** โ€” the database is an untracked build artefact of a few + hundred MB, so there is nothing to fall back *to*, and a default that silently + resolves to the wrong database is worse than no default. Same shape as #16. + The stale `xenia-rs dis` regeneration hint is now `sylph-xexdb dis`. +* `SCHEMA.md` is still headed *"`xenia-analysis` schema reference"* and cites + `xenia-rs dis --db` โ€” the retired repo and binary. Not fixed. +* 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. + +## โ–ถ๏ธ The Phase 5 and Phase 7 checks, re-run 2026-09-14 on the second machine + +This page says *"Do not trust this page's ledger when you get there."* So the +checks were re-run rather than read. **No repository was archived and nothing was +deleted** โ€” both are the human's, and both stay open. What follows is only what +the checks now say. + +### Phase 5 ยท containment โ€” and the check the page asks for is wrong for half its list + +| repo | disposition | tips | contained in Sylpheed | +|---|---|---|---| +| `Syplheed-Reborn` | absorbed | 21 | **21 โœ…** | +| `Sylpheed-Godot` | absorbed | 2 | **2 โœ…** | + +๐Ÿ”ด **Phase 5 names four repos, but the containment check only means something for +the two that were *absorbed*.** `xenia-rs` and `xex2tractor` were never absorbed โ€” +their disposition is *harvest, then archive*. Run the check literally against +`xenia-rs` and it reports **42 of 42 refs "NOT PRESENT in Sylpheed"**, every line +true and every line unactionable. That is the failure this page already names once, +about Phase 0's first gate: *a check that goes red for something unactionable*. + +**For the two harvest repos the invariant is different** โ€” the harvested artefacts +are in Sylpheed, and the repository is *archived, not deleted*: + +| artefact | on `main` | on its PR branch | +|---|---|---| +| `docs/reference/xex2-format.md` | โœ— | โœ… #30 | +| `docs/reference/xbox360-exports.json` | โœ— | โœ… #30 | +| `LICENSE` | โœ— | โœ… #30 | +| `crates/sylpheed-xexdb` (32 files) | โœ— | โœ… #32 | +| `tools/zq.py` | โœ… | โœ… | + +โš ๏ธ **So the harvest is real but is not on `main` yet.** Archiving is still safe โ€” +the branches are pushed, and archiving is reversible โ€” but **Phase 5 should follow +the harvest PRs, not precede them**, or `main` alone does not carry what was +harvested. + +### Phase 5 ยท nothing lives outside git โ€” re-verified, still true + +| | issues | PRs | releases | wiki | +|---|---|---|---|---| +| the four retiring repos | **0** | **0** | **0** | none | +| `Sylpheed` | 36 | 19 | 0 | none | + +๐Ÿ“Œ `has_wiki: true` is the repository *feature flag*, not content โ€” +`/wiki/pages` returns **404 on all six**, i.e. no wiki was ever initialised. Read +the flag as content and you would report six wikis that do not exist. + +๐Ÿ“Œ All six repos are still **`archived: false`, `private: false`**. The retention +question this page leaves open is therefore unchanged and now has a number beside +it: `docs/re/captures/` is ~87 MB of game screenshots in a **public** repository. + +### Phase 7 ยท most of the drop list is not on this machine + +The list was measured on the agent box. Here: + +| item | page | this machine | +|---|---|---| +| `agent-backups/` | 687 MB | **absent** | +| `xenia-rs/audit-runs/` | 57 MB | **724 KB** | +| local `pi/clippy`, `pi/clippy-clean`, `pi/reauth3` | 3 branches | **0 โ€” not on this box** | +| `texcompare/`, `ship_render/` | 14 MB + 64 KB | **both absent** | +| root `canary_*.log` / `.stdout` / `.stderr` | ~15 MB | 1 file | +| `stock-oracle/` | 34 MB | 34 MB โœ… | +| `Sylpheed/target/` | 32 GB | **34 GB** โœ… | + +โœ… **Phase 7's one open question is answered.** It asks to *"confirm no `docs/re/` +page cites"* `texcompare/` or `ship_render/` before dropping them. Four citations +of `ship_render` exist โ€” and **all four name the example *program*, not the output +directory**: `cargo run --example ship_render` in `xbg7-mesh.md`, two in +`BACKLOG.md`, and the tracked `examples/ship_render.rs` itself. `texcompare` is +cited nowhere at all. The directories are droppable; the example is tracked code +and stays. (Same directory-vs-file distinction that made Phase 4's "10 dangling +citations" turn out to be one.) + +โš ๏ธ **Disk is tighter than this page records: 90 % used, 96 GB free** (the page says +83 %). `Sylpheed/target/` is 34 GB of that and is the only large item here โ€” but it +is a deletion on the human's disk, and rebuilding it is hours, so it stays until +asked for. + ## Phase 5 โ€” Verify the invariant, then archive โฌœ **NOT STARTED** For each of `Syplheed-Reborn`, `Sylpheed-Godot`, `xenia-rs`, `xex2tractor`: @@ -281,12 +435,23 @@ blocker: sylpheed-formats = { git = "โ€ฆ/Sylpheed.git", tag = "formats-pin-2026-09-01" } ``` -**The build depends on this repo by tag**, pinned in `Cargo.lock` to `#1cd5b8b1`. -A rewrite invalidates all 8 `formats-pin-*` tags, every commit SHA, PR #23's +**The build depends on this repo by tag**, pinned in `Cargo.lock` to `#1cd5b8b1` +โ€” re-checked 2026-09-14, and the pin is exactly right: `formats-pin-2026-09-01` +โ†’ `1cd5b8b1`, and the in-container build fetches it over the network for real. +A rewrite invalidates every `formats-pin-*` tag, every commit SHA, PR #23's merge, both agents' clones, and needs a force-push through branch protection. -* **Don't rewrite** (recommended): 118 MB on a host with 154 GB free, where - `Sylpheed/target` alone is 32 GB. The cost is not worth the blast radius. +๐Ÿ“Œ **The tag count is 7, not 8** โ€” server and local agree, and all 7 tags in +`Sylpheed` are `formats-pin-*`. The eighth, `formats-pin-2026-08-29` (no letter +suffix), lives in **`Syplheed-Reborn`**, which a Sylpheed rewrite would not +touch and which Phase 5 archives read-only anyway. It does not change the +decision; it is one fewer thing to re-cut. + +* **Don't rewrite** (recommended): 118 MB โ€” and the disk argument has moved. + The host is now at **90 %, 96 GB free** (this page said 83 % / 154 GB), and + `Sylpheed/target` alone is **34 GB**. Reclaiming 118 MB by rewriting history, + while 34 GB of rebuildable build output sits beside it, is still the wrong + lever. * **Do rewrite:** then it happens **here, in Phase 5** โ€” while tags are being re-cut and agents re-cloned anyway, so the disruption is paid once instead of twice. Re-point the `formats-pin` dependency **first**. @@ -335,6 +500,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 +509,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 +520,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 @@ -370,14 +539,33 @@ been merged** โ€” merging is the human's, and #32 contains #30 and #31. โš ๏ธ **#32 is stacked.** Merge #30 and #31 first, or merge #32 and close them โ€” its `build.rs` needs #30's export table, so they cannot be independent. -โณ **One result outstanding:** the workspace `cargo test` count for #32. `check`, -`clippy`, `fmt` and `wasm` are all 0; the test leg was interrupted twice by -branch switches and never reported cleanly. Run it and post the number: +โœ… **The workspace `cargo test` count for #32 โ€” reported 2026-09-15** (also posted +on #32). `sylph-ci:local`, rustc 1.98.1 byte-identical to the runner, head `6048829`: + +| | disc | suites | passed | failed | ignored | +|---|---|---|---|---|---| +| `docker/ci/run cargo test --workspace --no-fail-fast` | PRESENT | 45 | **367** | **1** | 14 | +| + #35, disc not mounted (as the runner) | ABSENT | 45 | 377 | 0 | 14 | + +The +9 is exactly #35's nine `imports.rs` unit tests. ๐Ÿ”ด **The one failure is `main`'s, +not #32's**: `ui_prm_primitives_disc` has failed since #23 (bisected; see #32's +description). It took three failures to get a number, and each one is now a rule: ```bash -docker/ci/run cargo test --workspace +SYLPH_CI_MEM_GB=14 docker/ci/run cargo test --workspace --no-fail-fast ``` +* **`--no-fail-fast`** โ€” without it the run stops at the first failing binary. An + earlier attempt reported "25 suites / 201 passed", which was half the workspace. +* **`SYLPH_CI_MEM_GB`** sized to the host โ€” the default 7 is half of the *agent box*. + On this 31 GB machine, with the disc mounted, `slb_leading_segment_disc` is + SIGKILLed: six threads each load a voice bank. Serial passes 10/10 under the + same 7 GB, so it is concurrency, not one allocation. +* **~36 GB of disk** for a cold `sylph-ci-target` volume. It took this host from + 90 % to 95 %; it has been deleted since. And a desktop package update that + upgrades `containerd.io` restarts `dockerd`, killing an in-flight run *and every + other container on the host* โ€” which is what ended the second attempt. + ### Phase 5 โ€” archive, and the history fork **Do not trust this page's ledger when you get there.** Re-run the containment