139. Worktree sdílejí to, co cargo cestou kompiluje, a drží si vlastní hotové artefakty
Kontext
ADR 0055 učinilo z disku měřenou veličinu a dalo každému worktree vlastní target/, uvolňovaný predikátem, jakmile větev přistála. To omezilo akumulaci, ale ne duplikaci: každý worktree kompiluje tytéž závislosti do vlastního adresáře a jeden studený build je 2,45 GiB (naměřeno 2026-09-12). Dne 2026-10-11 byl stroj o 2 GB pod hranicí 5120 MB, která odmítá build, a odmítnutý build byl další kopie závislostí, které už jiný worktree zkompiloval.
Na stole byly dva způsoby sdílení.
Sdílený CARGO_TARGET_DIR repozitář dnes podporuje a řada skriptů ho už toleruje. Sdílí ale i hotový spustitelný soubor: worktree, který stavěl naposledy, přepsal debug/majordomus, takže kontrola mj_rust_stale vlastního worktree, jeho MAJORDOMUS_BIN výpůjčníci i server držící lease najdou binárku jiné větve pod cestou, která o ní nic neříká. To je selhání, o kterém byl napsán project.reclaim-only-what-you-own, vyrobené konstrukcí.
sccache byl na tomto stroji měřen jako alternativa a mezi dvěma různými cílovými adresáři nedal žádný zásah cache (0 zásahů, 28 minutí při dvou sestaveních serde a regex); přestavba do téhož adresáře zasáhla. Zůstává volitelný a není součástí tohoto rozhodnutí.
Cargovo build.build-dir rozděluje dvě věci, které adresář cíle drží: mezivýsledky (jednotky závislostí, otisky, inkrementální stav) jdou do build-dir a hotové artefakty do target-dir. Toolchain, který tento repozitář připíná (1.98.1), je přijímá bez -Z, což bylo ověřeno; release, který to stabilizoval, ověřen nebyl.
Rozhodnutí
.cargo/config.toml nastavuje build.build-dir na jeden adresář v domovu cargo, {cargo-cache-home}/build-shared/majordomus, a nenastavuje target-dir. Každý worktree tak závislost zkompiluje jednou a drží si vlastní target/ obsahující jen vlastní hotové artefakty.
Umístění je pod domovem cargo, protože commitnutý soubor nemůže obsahovat relativní cestu, která je správná v každé hloubce worktree (<repo>-wt/feat/x a <repo>-wt/x se liší), a absolutní by jmenovala stroj nějakého člověka.
Adresář nepatří žádnému worktree, takže jej predikáty ADR 0055 po worktree nemohou klasifikovat. scripts/reap-orphans jej čte z deklarace samotného checkoutu, měří jej spolu s worktrees, omezuje na 6144MB (MAJORDOMUS_SHARED_BUILD_CAP_MB, dva studené buildy) a pod --reclaim jej odstraní celý, když překročí hranici a neběží žádný proces cargo ani rustc. Je regenerovatelný, takže cena chybného odstranění je jedno přebuildování závislostí a nemůže to být ani bajt autorského zdroje. Checkout, který nedeklaruje build-dir, nemá nic k získání zpět, takže fixture ani adoptér nikdy nejsou předmětem akce kvůli výchozí hodnotě.
Zamítnuté alternativy
- Sdílený
CARGO_TARGET_DIR. Sdílí spustitelný soubor, jako výše. - sccache jako mechanismus. Nebyl změřen žádný zásah napříč adresáři; přidává démona a druhou cache, kterou je třeba omezit.
- Symlink
target-dirna worktree. Test vlastnictví z ADR 0055 správně odmítá považovat symlinkovaný adresář za vlastní adresář worktree, takže by se ho reaper nikdy nedotkl. - Klíč politiky, který generuje
.cargo/config.toml. V konečném důsledku lepší — jedna deklarace pod.ai/a vygenerovaná projekce — a změna generátoru v Rustu; je to navazující krok a konfigurační soubor mezitím nese tu jednu řádku.
Důsledky
- Studený build druhého worktree znovu použije závislosti prvního: naměřeno 11 s na 1 s na fixtuře se dvěma závislostmi (
test/cases/1022). Úspora samotného repozitáře změřena nebyla a je to číslo, které je třeba přečíst po týdnu používání. - Závislosti jsou sdílené. Zda se crate workspace také kompiluje jednou na worktree, nebylo změřeno; očekává se to, protože identita zdroje cesty zahrnuje jeho cestu.
- Sestavení sdílející adresář se serializují na souborovém zámku cargo: dva worktree sestavující najednou na sebe čekají. To je cena a
deriveuž běží po jednom. Doplněno 2026-10-13. Věta počítala s jedním builderem. Spouštěč commit hooku, lintery, testy i sestavení dokumentace spouštějí cargo také, v každém worktree, a toho dne jeden z nich čtrnáct minut mlčky stál za zámkem, protože--quietodstraňuje řádek, v němž cargo hlásí, že je blokováno. Cena je nyní omezená, ne přijatá: sestavení čeká nejvýšeMAJORDOMUS_BUILD_LOCK_WAITsekund, řekne, za čím čekalo, a pak se sestaví ve vlastním adresáři stromu (mj_cargo_bounded,project.a-build-never-waits-in-silence-on-anothers-lock). Sdílení zůstává výchozí a je to, co sestavení dostane, když nikdo nepřekáží; soukromý adresář je cena za nečekání, placená jen sestavením, které by čekalo. - Meziprodukty jsou na jednom místě, takže
cargo cleanve worktree čistí jeho artefakty a ne sdílený adresář, což pravidlo vlastnictví chce. - Sdílený adresář je mimo každý checkout, takže odstranění worktree ho nikdy neuvolní; jen mez reaperu. To je nová akumulace a její míra, práh i redukce jsou pojmenovány v
project.worktrees-share-build-intermediates. - Dokázáno pomocí
test/cases/1022_worktrees_share_build_intermediates.sh.