Zdůvodnění
Každá relace potřebuje derive, než může commitovat. Sdílený MacBook jej pod zátěží zvládá až za hodinu, nečinný clusterový stroj za zhruba deset minut. Relace proto derive přesouvaly skriptem mimo repozitář, který nesl adresy hostů ve svém zdrojovém kódu. Jeho zámek na hostu byl until mkdir lock; do sleep 15; done. To je závod, ne fronta: 2026-10-11 v 00:18Z čekalo pět relací na lundře, ta nejstarší 2 h 12 min, zatímco pozdější příchozí brali zámek před ní. V 00:25Z na druhém MacBooku ruční derive přestavěl sdílený build adresář pod běžícím přesunutým derive. Stage C odmítla s hláškou „this executable is not of this tree's generation“.
Konvence ve skriptu v domovském adresáři je taková, kterou nikdo nerecenzuje, netestuje ani nenajde. Offload je nyní příkaz spustitelného souboru a jeho hostitelé jsou objektem vrstvy.
Požadované chování
- Hostitelé, jejich soubory identity ssh, minimum volného místa, cesty fronty a rozvržení na hostiteli se čtou z deklarace
derive-offload(.ai/repo/offload/*.yaml, schémaderive-offload/v1) a odnikud jinud. - Host se vybere jen tehdy, když odpovídá a má alespoň své minimum volného místa. Z nich se vybere ten s nejméně běžícími nebo čekajícími derives a při shodě vyhrává host deklarovaný první.
- Čekající na hostu berou jeho zámek v pořadí příchodu. Lístek, jehož držitelský proces je mrtvý, odstraní ten, kdo si jej všimne. Zámek, jehož držitelé jsou všichni mrtví, se nahlas získá zpět, a na zámek bez souboru držitele ke kontrole se čeká.
- Každý derive se staví ve vlastním build adresáři, naklonovaném ze sdíleného a odstraněném po skončení.
- Přenáší se worktree tak, jak je, a rozpracovaný merge putuje s oběma rodiči. Nesledované soubory a nevyřešený merge se odmítnou dřív, než se cokoli přenese. Derive, který maže sledovaný soubor, se odmítne dřív, než se cokoli aplikuje. Nic se necommituje ani nepushuje.
Chování při selhání
Odmítnutí říká, co dělat, a skončí kódem, který pro něj uvádí docs/OFFLOAD.md. Hostitel, na něhož se nelze zeptat, se přeskočí s uvedením důvodu. Když žádný nezbyde, příkaz odmítne kódem 12 místo odvozování zde. Derive spuštěný ručně na hostiteli nebo ručně vzatý zámek je mimo vynucování tohoto pravidla a znění pravidla zakazuje obojí.
Ověření
apps/majordomus-cli/tests/offload.rs dokazuje tato chování, se skutečnými procesy držitelů a hosty, které jsou adresáře dosažené přes lokální náhradu ssh:
- pořadí příchodu, ačkoli později příchozí čekající začal čekat první;
- lístek mrtvého čekatele, který neblokuje;
- mrtvý zámek je získán zpět a na neověřitelný zámek se čeká;
- volba hostitele, která přeskočí hostitele, který je vypnutý nebo pod svým minimem;
- staged, necommitnutý round trip;
- druhý rodič mergeje ponechán;
- každé odmítnutí;
- souběžné sestavení do sdíleného adresáře, které nenahrazuje spustitelný soubor derive.
Každá z těchto mutací ji shodí: zámek převzatý bez ohledu na pozici, ponechané mrtvé tikety a build adresář nasměrovaný na sdílený.