Closes the page's one explicitly outstanding result. Run in sylph-ci:local (rustc 1.98.1, byte-identical to the runner) with the disc present and --no-fail-fast: 45 suites, 367 passed, 1 failed, 14 ignored. The +9 against the disc-less #35 run (377) is exactly #35's nine imports.rs unit tests. The single failure is ui_prm_primitives_disc, red on main since #23 and bisected there, not introduced by #32. Records the three things that stopped the number being obtained, as rules: --no-fail-fast (an earlier run silently covered half the workspace), a memory cap sized to the host (the default 7 GB OOM-kills slb_leading_segment_disc on this machine with the disc mounted), and a ~36 GB disk budget for a cold target volume. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
33 KiB
Consolidating six repositories into two
Set by the human, 2026-09-13. The end state is two repositories:
| repo | holds |
|---|---|
Sylpheed |
everything — the port, the RE corpus, every tool |
Xenia-Canary (our fork) |
the emulator and oracle, with our instrumentation |
Everything else is retired. This page is the ordered how, with a gate after each phase, and a ledger of what was checked rather than assumed.
⚠️ Most paths on this page do not resolve in this repository, on purpose.
They name files in xenia-rs, xex2tractor, xenia-canary and the project
root — the things being moved in. A citation checker pointed at
docs/agents/ will flag every one of them until the phases below are done, and
that is the correct reading: each unresolved path here is work outstanding.
📌 Two decisions from the human frame the whole plan:
"The emulator is dead and can be dropped altogether. But the DuckDB generator should still be a useful tool… We probably can move it into a standalone tool under Sylpheed."
"xex2tractor was an early attempt and is long dead too… you may want to scan and compare the tools for anything that is in xex2tractor only."
Where things stand
| repo | server | local tree | tracked | disposition |
|---|---|---|---|---|
| Sylpheed | 598 MB | 33 GB | 131 MB / 1470 files | the target |
| Xenia-Canary | 71 MB | 20 GB | — | the keeper — ⚠️ dirty |
| Syplheed-Reborn | 103 MB | 1.4 GB | 100 MB / 787 files | ✅ absorbed → archive |
| Sylpheed-Godot | 0.4 MB | 99 MB | 0.3 MB / 39 files | ✅ absorbed → archive |
| xenia-rs | 9 MB | 1.2 GB | 61 MB | harvest the DB tool → archive |
| xex2tractor | 0.3 MB | no clone | — | harvest four things → archive |
Sylpheed has two root commits — feat: initialise workspace (2026-03-25,
Reborn's) and scaffold the Godot port (2026-08-28). Both histories were
grafted in, not copied, which is why the absorption checks below pass.
The ledger — what was verified, and how
Nothing here is inference. Each row is a command that was run on 2026-09-13.
| claim | method | result |
|---|---|---|
| Reborn fully absorbed | all 21 remote + 8 local branch tips vs Sylpheed/main |
every one an ancestor |
| Sylpheed-Godot absorbed | both branch tips, + the root-commit graft | every one an ancestor |
agent-backups/ redundant |
git bundle list-heads, 23 refs across 4 bundles |
all present in Sylpheed |
3 unpushed pi/* branches redundant |
git patch-id --stable, per commit |
all 4 patches on main |
| nothing lives outside git | issues / PRs / releases / wikis, all six repos | 0 everywhere but Sylpheed |
| the DB tool is separable | git grep "use xenia_cpu::" in xenia-analysis |
three symbols |
🔴 What the ledger found that a naive plan would have destroyed
- The F1 instrument exists in one place, uncommitted.
xenia-canaryhas two dirty files —hid/file/file_input_driver.h(--pad_file_repeat) andapp/xenia_main.cc— plus 4 unpushed commits onsylpheed-reand a branch,audit-handle-lifecycle-probes, contained in no remote at all. That patch is the instrument behindREPEAT_DELAY/REPEAT_INTERVAL, now shipped in the port. Its own finding page says "not yet upstreamed." - xenia-rs has 4 unpushed branches —
iterate-4B/ui-perf,4C/jit,4D/parallel,4E/native-threads. Dropping the emulator is a decision; dropping work that was never backed up is a different act. - The tool is not on
master.xenia-rs/masterlast moved 2026-06-15; the DuckDB and disassembler work is onorigin/iterate-4A/apu-xma-stage1(2026-09-10, +22 commits). Extract from the default branch and you get a three-month-old tool.
Phase 0 — Secure the single-copy work ✅ DONE
Before touching anything else. One git checkout in xenia-canary ends the
reproducibility of a measurement that is already live in the port.
- Commit
file_input_driver.h+xenia_main.cconsylpheed-re. - Push
sylpheed-re(4 + 1 commits) andaudit-handle-lifecycle-probes. Resolve the✅ There is none.third_party/DirectXShaderCompilersubmodule drift.git submodule statusshows no+: the checked-out commit matches the recorded one. Themingit statusis nested submodule dirt — DXC's ownexternal/SPIRV-HeadersandSPIRV-Tools— which is upstream's business and must not be committed here.
Gate — and the first version of it was wrong. It compared each local branch to a remote by SHA, and reported seven safe branches as unpushed: a branch that is an ancestor of a pushed branch is already preserved. A check that goes red for something unactionable is the failure this repo keeps naming, so the gate tests what it means — reachability:
git for-each-ref --format='%(refname:short)' refs/heads | while read b; do
s=$(git rev-parse "$b"); found=""
for r in $(git for-each-ref --format='%(refname:short)' refs/remotes); do
git merge-base --is-ancestor "$s" "$r" 2>/dev/null && { found=$r; break; }
done
[ -n "$found" ] || echo "🔴 $b NOT REACHABLE from any remote"
done
✅ PASSED 2026-09-13 — 8e63a9542 commits the instrument; sylpheed-re and
audit-handle-lifecycle-probes pushed; all 14 local branches reachable.
Phase 1 — Make the archive honest ✅ DONE
Push xenia-rs iterate-4B/ui-perf, 4C/jit, 4D/parallel, 4E/native-threads.
They are being retired, not rescued. But a retired branch that was never pushed is not retired — it is deleted, quietly, by someone who thought it was safe.
Gate: the same loop, run in every repo, prints nothing.
✅ PASSED 2026-09-13 — all four pushed (32 / 52 / 56 / 59 commits ahead of
master). The loop is clean in all five repos except pi/clippy,
pi/clippy-clean and pi/reauth3 in Sylpheed, which are unreachable by
ancestry and redundant by patch-id — the ledger's reason, and Phase 7's
disposal. The gate is right to flag them; they are the one case where the
answer lives outside it.
Phase 2 — Harvest xex2tractor, then retire it ✅ DONE (PR #30)
Four things exist only there.
| take | why |
|---|---|
| XEX2 devkit + XEX1 retail master keys | xenia-xex hardcodes retail only; devkit is present but #[allow(dead_code)] and XEX1 is absent. xex2tractor tries all three in a validating loop. |
extract -r |
🔴 RUN, AND THE INFERENCE WAS WRONG — see the gate below. Optional, and dangerous if it is ever mistaken for the .pe. |
doc/xex2_format.md (39 KB) and doc/xbox360_exports.json (938 KB, 2,913 exports across xboxkrnl / xam / xbdm) |
byte-identical to untracked loose copies in the project root. Tracked by no repo. |
LICENSE (MIT) |
Sylpheed has none. |
Leave everything else: xenia-xex is ahead on resources.rs (XDBF/XACH),
pdata.rs, tls.rs, basic zero-fill compression, and the analysis layer.
Gate — ✅ RUN 2026-09-13, and it corrected this page in two directions.
extract (xex2tractor, no -r) ✅ IDENTICAL to the project .pe
extract -r (xex2tractor) ❌ differs — 1,903 bytes over 273 runs
extract (xenia-rs, iterate-4A) ✅ IDENTICAL — and .xex.json identical too
Right: the .pe is an xex2tractor extract. Hash-for-hash.
Wrong: it was made without -r. The project's .pe is the plain
decrypted-and-decompressed image, imports unresolved — and -r's 1,903
differing bytes sit in the import thunk region from VA 0x82000600.
🔴 So the dependency this gate existed to protect does not exist. This page
claimed "drop this and the file every .pe-offset citation depends on can
never be rebuilt." It can: xenia-rs extract, the tool Phase 3 keeps,
reproduces it byte-for-byte — along with the loose .xex.json, which turns out
to have come from xenia-rs, not xex2tractor.
⚠️ And -r must never become the .pe. It writes into the image, so a .pe
built with it would silently invalidate every byte-offset citation in
docs/re/. If resolved-import disassembly is ever wanted, it is a separate
artifact under a different name, never a replacement.
That leaves xex2tractor's unique list at three items, none urgent — the two master keys, the two doc assets, and the licence. The doc assets are now the only reason to visit that repository.
📌 Learned in passing: iterate-4A builds clean (xenia-app, one unused
variable warning), so Phase 3's source is not bit-rotted — and it needs
libavutil-dev and friends via ffmpeg-sys-next, dragged in by the emulator's
XMA audio. The standalone tool sheds a C library the CI image did not have.
Phase 3 — Lift the DB tool out of the emulator ✅ DONE (PR #32)
From origin/iterate-4A/apu-xma-stage1, never from master.
xenia-analysis 10,658 db, vtables, jumptables, func, xref, rtti,
strings, xdbf, static_init, demangle, sql_views
disasm slice of cpu 3,681 disasm.rs + decoder.rs + opcode.rs (of 21,813)
xenia-xex 2,018 header, loader, lzx, pe, pdata, tls, resources
xenia-vfs 444 so it reads an ISO, not just a loose .xex
xenia-types 361
───────
≈17,200 of ~71,000
The coupling is exactly three symbols — decoder::decode, disasm::DisasmItem,
disasm::format. Interpreter, JIT, scheduler, VMX, block cache, reservations:
none of it is reachable from the generator.
xenia-xex declares xenia-memory and xenia-types as dependencies and has
zero use of either. Probably droppable — confirm by compiling, do not
assume.
Travelling with it: zq.py, tests/db_schema_golden.rs,
tests/disasm_goldens.rs, examples/decode_table_check.rs.
Two corrections to make during the move, not after:
- the CLI help says "SQLite database" in two places. It is DuckDB
(
duckdb = { workspace = true }). zq.py's documented escape hatch — "the engine vtable / rdata is NOT in the DB … read it from guest memory withxenia-rs exec --dump-addr" — dies with the emulator. Replace it with Canary's dump or a direct read of the.peatVA − 0x82000000, and say which, in the file.
Gate — ✅ PASSED 2026-09-13. Schema a superset (22 new tables, none
lost). instructions 1,865,751, pdata_entries, imports, sections and all
three eh_* identical to the row; most others slightly higher. Two tables drop
~1.8 M and it is not a loss — the xref delta is entirely ind_call
(everything else nets +1,512), and the new schema records why: 6,556 sites
truncated=true carrying 1,801,075 candidates against 427 untruncated
producing 4,199 rows. The old database materialised a cross product.
Phase 4 — Prune the captures, and give docs/re/ the check docs/port/ has ✅ DONE (PR #33)
docs/re/captures/ is 257 files / 117.6 MB, and it is not junk. Measured:
193 (81.2 MB) cited by a docs/re page, or opened by a tool
64 (36.5 MB) referenced by nothing
🔴 Two are test fixtures and cargo test opens them:
crates/sylpheed-formats/tests/ui_paint_order_disc.rs → captures/title-screen-oracle.png
crates/sylpheed-formats/tests/unit_layout_disc.rs → captures/stage02-live-unit-definitions-deep.txt
Sixteen more tools under tools/port/ and tools/re-capture/ read from there.
Do:
- ✅ DONE —
tools/re/check-capture-citations, the mirror oftools/port/check-citations, which has only ever checkeddocs/port/*.md. It reports two classes — a capture nothing cites, and a page citing a capture that was never committed. It needs a--selftestthat plants one of each, or it is not a check. - ✅ DONE — and there was
10ONE. Eight of the ten were directory references that resolve; one was sentence punctuation in the regex. The real one,live-submenu-unidentified.png, had been committed and then deleted on 2026-08-30 while the page kept citing it and kept making the claim it backs. Restored, not de-linked. - ✅ DONE — 46, not 64. Two are opened by filename from
screen_match.py, and sixteen sit inside directories that pages cite as directories. 30.7 MB out of the checkout.
⚠️ An orphan is not automatically waste. It may be evidence a page should have cited, and the page is the thing that is wrong. Fix the citations before deleting, or step 3 silently ratifies every omission in step 2.
📌 Going forward the class that matters is not captures-vs-code:
| evidence — a screenshot a finding points at | belongs beside the finding, as the convention says |
run output — .jsonl, .log, .csv |
the same class as xenia-rs's audit-runs/, which this plan drops |
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:
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.pyhardcoded/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 aduckdbexception with nothing saying why. Fixed in PR #35 (38cc170):$SYLPH_XEXDB→<repo root>/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 stalexenia-rs disregeneration hint is nowsylph-xexdb dis. SCHEMA.mdis still headed "xenia-analysisschema reference" and citesxenia-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:499and:874still 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:
re-run the containment check at that moment — not from this page's ledger,
which will be days old — then archive read-only on Gitea, and only then delete
the local clone.
Archive before delete, and leave them archived. The check proves the commits are reachable. It does not prove nobody will want the repository boundary back.
⚠️ The fork: history rewrite, or not
Dropping files in Phase 4 reclaims no space. The 118 MB is in history — 512
distinct blobs, 120.5 MB — and git rm leaves every byte in .git (590 MB
local, 598 MB on the server). Only a rewrite reclaims it, and it has a hard
blocker:
# crates/sylpheed-export/Cargo.toml:84
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
— 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.
📌 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/targetalone 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-pindependency first.
This is a decision, not a default. Whichever is chosen, record it here.
Phase 6 — Adopt the orphan assets ✅ DONE (PR #34)
Tracked by nobody today, and tools or references by the two-repo rule:
| asset | → |
|---|---|
ppc-manual/ — 397 files, including generator/generate_manual.py |
Sylpheed |
docs/ppc_instructions.{json,md}, docs/xbox360_exports.*, docs/xex2_format.md |
Sylpheed docs/ |
docs/CROSS_BUILD_SETUP.md (58 KB) |
Canary — it builds Canary |
run-canary.sh |
Sylpheed tools/ |
ai-agent-*.md ×4 (56 KB) |
Sylpheed docs/, or discard — human's call |
scratch/xbg7/extract.py — clean-room XBG7 scanner |
superseded by sylpheed_formats::mesh; keep as history or drop |
Sylpheed-try/…/examples/_voice_span.rs — 46-line untracked probe |
keep or drop |
Phase 7 — Intended drops ⬜ NOT STARTED
Stated so that nothing is dropped by omission.
| drop | size | why it is safe |
|---|---|---|
agent-backups/ |
687 MB | all 23 refs verified present in Sylpheed |
stock-oracle/ |
34 MB | two Canary binaries, rebuildable from source |
root canary_*.log / .stdout / .stderr |
~15 MB | run output |
vkd3d-proton.cache |
15 KB | runtime cache |
xenia-rs audit-runs/ |
57 MB, 41 files | already .gitignored; iterate-4A deleted 40 of 41 |
local pi/clippy, pi/clippy-clean, pi/reauth3 |
— | all 4 patches on main, by patch-id |
Sylpheed/target/ |
32 GB | build output; the host is at 83 % |
texcompare/ (14 MB), ship_render/ (64 KB) |
— | tool output — confirm no docs/re/ page cites them first |
| the xenia-rs emulator | ~54k LOC | the human's decision: superseded by Canary |
▶️ STATUS 2026-09-13 — paused here, for the other machine to finish
Six of eight phases are done and pushed. Everything below is committed; nothing is left in a working tree. Five pull requests are open and none has been merged — merging is the human's, and #32 contains #30 and #31.
| phase | state | where |
|---|---|---|
| 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 |
| 6 adopt the orphan assets | ✅ done | PR #34 chore/adopt-orphan-assets, + Canary 99cc72662 |
| — containers and agents | ✅ done | PR #31 docs/containers-setup |
| 5 archive the four repos | ⬜ open — needs the human | |
| 7 intended drops | ⬜ open — partly needs the human |
🔴 Five claims on this page were wrong. Read these before trusting the rest.
- "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 a sentence with the full stop pulled into the match. The figure is corrected in Phase 4 below and in PR #33. extract -ris not how the.pewas made, and nothing depends on it — Phase 2's gate, run.- The Phase 0 gate compared branches by SHA and called seven safe branches unpushed. It tests reachability now.
- There is no DXC submodule drift. The
mis nested submodule dirt. - Phase 0 did not secure all the single-copy work, and its gate could not
have: it walks
refs/heads, and 468 uncommitted lines inxenia-rshave no ref. Secured 2026-09-14 — see the section above Phase 5.
What the other machine should do next
Before anything: merge or decide on the open PRs
#30 harvest/xex2tractor-assets reference files + LICENSE
#31 docs/containers-setup container and agent setup
#32 feat/xexdb-tool the DuckDB tool ⚠️ CONTAINS #30 and #31
#33 fix/capture-citations the docs/re check + prune
#34 chore/adopt-orphan-assets PPC manual + canary launcher
⚠️ #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.
✅ 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:
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_GBsized to the host — the default 7 is half of the agent box. On this 31 GB machine, with the disc mounted,slb_leading_segment_discis 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-targetvolume. It took this host from 90 % to 95 %; it has been deleted since. And a desktop package update that upgradescontainerd.iorestartsdockerd, 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 check at that moment — days will have passed and branches may have moved:
for repo in Syplheed-Reborn Sylpheed-Godot xenia-rs xex2tractor; do
# every ref of $repo must be an ancestor of a Sylpheed ref
done
Then archive read-only on Gitea. 🔴 Do not delete any repository. Archiving is reversible; deletion is not, and it is the human's call, separately, later. Nothing outside git needs migrating — issues, PRs, releases and wikis are zero in all four (verified).
The history-rewrite fork is still open and still recommended AGAINST: the
118 MB is in history, and crates/sylpheed-export/Cargo.toml depends on this
repo by tag (formats-pin-2026-09-01, pinned in Cargo.lock). A rewrite
invalidates all 8 tags, every SHA, PR #23's merge and both agents' clones.
Phase 7 — the drops
All verified, none done — they are deletions on the human's disk:
agent-backups/ 687 MB 23 refs verified present in Sylpheed
Sylpheed/target/ 32 GB build output; the host is at 83 %
stock-oracle/ 34 MB two Canary binaries, rebuildable
root canary_*.log 15 MB run output
xenia-rs audit-runs/ 57 MB already .gitignore'd; iterate-4A deleted 40 of 41
pi/clippy, pi/clippy-clean, pi/reauth3 all 4 patches on main, by patch-id
texcompare/ (14 MB), ship_render/ confirm no docs/re/ page cites them first
Still the human's, untouched
ai-agent-*.md ×4 (56 KB), scratch/xbg7/extract.py, _voice_span.rs, and the
retention question: all six repos are private=False, and docs/re/captures/
is ~87 MB of game screenshots in a public repository.
What each finished phase actually produced
- Phase 2 —
docs/reference/{xex2-format.md, xbox360-exports.*, ppc-instructions.*}and an MITLICENSE; this repo had none. The first two are byte-identical to xex2tractor's, verified withcmp. - Phase 3 —
sylpheed-xex+sylpheed-ppc+sylpheed-xexdb, ≈17,200 lines of ~71,000, coupled to the emulator by three symbols. The gate: a regenerated database whose schema is a superset, withinstructions,pdata_entries,imports,sectionsandeh_*identical to the row. The two −1.8 M deltas are themax_indirect_candidatesceiling, recorded by the tool as 6,556 truncated sites standing for 1,801,075 candidates — checked, not assumed: the xref delta is entirelyind_call.build.rsno longer reads a sibling checkout, and a missing export table now fails instead of silently producing a database with no import names. - Phase 4 —
tools/re/check-capture-citations, 212 captures all cited, 46 orphans dropped. It caught its own damage twice: two "orphans" are opened by filename fromscreen_match.py, and the first prune emptied two directories that pages cite as directories. - Phase 6 —
tools/ppc-manual/(393 files) and a rewrittentools/run-canary.sh; the old one pointed at a symlink Wine cannot resolve and hardcoded one machine's paths. The fullCROSS_BUILD_SETUP.mdwent to Canary, where the tracked copy was a 6.8 KB stub of a 59 KB guide.
The method, if you only read one thing
Every claim on this page that was reasoned turned out wrong, and every one that was run held. The gates are the point: Phase 2's gate refuted its own premise, Phase 3's proved the two alarming row deltas were an improvement, and Phase 4's check caught a deletion I had just made. Run them again rather than trusting the results recorded here.
Still open, for the human
- Retention. The
.iso(7.6 GB),.pe,.xex.jsonandsylph_extract/(6.2 GB) stay on disk and out of git. Butdocs/re/captures/is 118 MB of game screenshots inside a public repository, about to be joined by a 938 KB export database, and all six repos areprivate=False. Worth choosing rather than inheriting. - The history fork in Phase 5.
ai-agent-*.md,scratch/,_voice_span.rs— keep or drop.