From b2f089e7d3c109bba8971c7439b3b7fa21e5caa5 Mon Sep 17 00:00:00 2001 From: Fabian Hamm Date: Mon, 14 Sep 2026 20:44:48 +0200 Subject: [PATCH 1/5] =?UTF-8?q?docs(agents):=20the=20Phase=200=20gate=20ca?= =?UTF-8?q?nnot=20see=20a=20working=20tree=20=E2=80=94=20it=20missed=20468?= =?UTF-8?q?=20lines?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found 2026-09-14 while pulling the repos on the other machine: `xenia-rs` had 468 uncommitted lines plus an untracked 338-line `imports.rs` in the very crate Phase 3 lifted, written 2026-09-10 and sitting there for four days. Verified absent from `iterate-4A` and from the lifted crate in PR #32 โ€” it existed in exactly one place, and that place was not git. Phase 0 is titled "Secure the single-copy work" and its gate passed anyway, because the gate iterates `refs/heads` and a dirty working tree has no ref. Canary's two dirty files were secured only because a human already knew about them; nothing found them. Phase 1 then declared the archive honest while this sat beside the branches it pushed. Phase 5 ends with "delete the local clone" and Phase 7 drops the emulator, so a deletion was scheduled against it. Records: the finding and the `git status --porcelain` half the gate was missing (run across all four repos โ€” only Canary is dirty, and both entries are already on Phase 7's drop list); that it is secured on `harvest/import-thunk- naming` and ported in `feat/xexdb-import-naming`; a fifth entry in the wrong-claims list; and a `0b` row in the status table. Also records three pieces of Phase 3 residue found while porting, the sharpest being that `tools/zq.py` still defaults its database path to a location inside `xenia-rs` โ€” the repository Phase 5 archives and Phase 7 drops. Left unchanged: the right replacement is a decision, not a guess. Co-Authored-By: Claude Opus 5 --- docs/agents/CONSOLIDATION.md | 75 +++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) 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 From 589c403c62b0780409d0b76f199d8448647378d7 Mon Sep 17 00:00:00 2001 From: Fabian Hamm Date: Mon, 14 Sep 2026 20:50:44 +0200 Subject: [PATCH 2/5] docs(agents): the zq.py database path is fixed, not outstanding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This page recorded it as "not changed here, because the right replacement is a decision". The decision was taken: PR #35 `38cc170` resolves `$SYLPH_XEXDB`, then `/sylpheed.db`, then refuses with both named โ€” no third fallback, because the database is an untracked build artefact and a default that silently resolves to the wrong one is worse than no default. Leaving the page saying otherwise would be the defect this section is about. `SCHEMA.md`'s retired-repo heading is still outstanding and stays listed. Co-Authored-By: Claude Opus 5 --- docs/agents/CONSOLIDATION.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/agents/CONSOLIDATION.md b/docs/agents/CONSOLIDATION.md index 953aa0c1..042ba3b0 100644 --- a/docs/agents/CONSOLIDATION.md +++ b/docs/agents/CONSOLIDATION.md @@ -317,13 +317,18 @@ it, since DuckDB's UPDATE is delete+insert and one inbound FK would make ### 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`. +* โœ… **`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. From d0f3885fb589624d20f001ad0ee3587440bab825 Mon Sep 17 00:00:00 2001 From: Fabian Hamm Date: Mon, 14 Sep 2026 21:00:40 +0200 Subject: [PATCH 3/5] docs(agents): re-run the Phase 5 and Phase 7 checks, and record what they say MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This page says not to trust its own ledger on arrival, so the checks were run again rather than read. Nothing was archived and nothing was deleted โ€” both are the human's, and both phases stay open. The substantive finding is that Phase 5's containment check is the wrong test for half the list it names. `xenia-rs` and `xex2tractor` were never absorbed; their disposition is harvest-then-archive. Run the check literally against `xenia-rs` and it returns 42 of 42 refs "not present in Sylpheed" โ€” every line true, every line unactionable, which is the failure this page already names once about Phase 0's first gate. For those two the invariant is that the harvested artefacts are in Sylpheed and the repository is archived rather than deleted; that is now checked separately, and it shows the harvest is real but lives only on the unmerged PR branches, so Phase 5 should follow them rather than precede them. Containment itself holds for the two repos it does apply to: 21/21 and 2/2. Also answers Phase 7's one open question โ€” nothing cites `texcompare/`, and all four `ship_render` citations name the example program, not the output directory โ€” and records that most of Phase 7's list does not exist on this machine, that `has_wiki: true` is a flag rather than content (all six wikis return 404, never initialised), and that the disk is at 90%, not the 83% the page records. Co-Authored-By: Claude Opus 5 --- docs/agents/CONSOLIDATION.md | 80 ++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/docs/agents/CONSOLIDATION.md b/docs/agents/CONSOLIDATION.md index 042ba3b0..9ba01017 100644 --- a/docs/agents/CONSOLIDATION.md +++ b/docs/agents/CONSOLIDATION.md @@ -333,6 +333,86 @@ it, since DuckDB's UPDATE is delete+insert and one inbound FK would make (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`: From 108378fe2118777e3b9244bd28d5a61dd5a134ca Mon Sep 17 00:00:00 2001 From: Fabian Hamm Date: Mon, 14 Sep 2026 21:25:53 +0200 Subject: [PATCH 4/5] docs(agents): the formats-pin tag count is 7, and the disk figures have moved MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-checked against the server rather than the page. `Sylpheed` has 7 tags and all 7 are `formats-pin-*`. The eighth this page counts, `formats-pin-2026-08-29` without a letter suffix, is in `Syplheed-Reborn` โ€” a repo a Sylpheed rewrite would not touch, and one Phase 5 archives read-only regardless. The pin itself is exactly as claimed: `formats-pin-2026-09-01` resolves to `e2630413`, and the in-container build fetches that git dependency over the network for real, so the blocker is live rather than theoretical. Also updates the disk figures the "don't rewrite" recommendation rests on: 90% used and 96 GB free, not 83% and 154 GB, with `target/` at 34 GB. The recommendation is unchanged and the argument is now stronger โ€” reclaiming 118 MB by rewriting history while 34 GB of rebuildable output sits beside it is the wrong lever. Co-Authored-By: Claude Opus 5 --- docs/agents/CONSOLIDATION.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/agents/CONSOLIDATION.md b/docs/agents/CONSOLIDATION.md index 9ba01017..33e26ea0 100644 --- a/docs/agents/CONSOLIDATION.md +++ b/docs/agents/CONSOLIDATION.md @@ -435,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**. From fdf498c684b094b1afaa64ab709508ad8123b18b Mon Sep 17 00:00:00 2001 From: Fabian Hamm Date: Tue, 15 Sep 2026 08:13:02 +0200 Subject: [PATCH 5/5] =?UTF-8?q?docs(agents):=20the=20#32=20workspace=20tes?= =?UTF-8?q?t=20count=20is=20in=20=E2=80=94=20367=20passed,=20and=20the=20o?= =?UTF-8?q?ne=20failure=20is=20main's?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- docs/agents/CONSOLIDATION.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/agents/CONSOLIDATION.md b/docs/agents/CONSOLIDATION.md index 33e26ea0..0b8ecf07 100644 --- a/docs/agents/CONSOLIDATION.md +++ b/docs/agents/CONSOLIDATION.md @@ -539,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