Zdůvodnění
Na jednom repozitáři pracuje několik relací najednou a každá potřebuje vlastní checkout vlastní větve. Git poskytuje linked worktree a cíl bere jako argument, takže každý volající rozhoduje, kam půjde — a třiapadesát z nich rozhodlo před tímto pravidlem jinak (ADR 0021). Nákladem nebyl nepořádek; bylo to, že žádný člověk ani agent nedokázal odpovědět „kde je větev X“ nebo „kam jde nová“, aniž by se podíval nebo si vymyslel, a odpověď, kterou je třeba pokaždé vymýšlet, se pokaždé vymyslí jinak.
Topologie rozhodnutí odstraňuje. Při dané identitě repozitáře — primárním checkoutu, čtené z common adresáře gitu a nikdy z aktuálního adresáře — a názvu branche existuje právě jedna cesta, a je to táž odpověď z primárního checkoutu, z propojeného worktree i z relace, která neví, kde byla spuštěna.
Požadované chování
- Odvození je jedna funkce dvou vstupů. Kontejner je sourozenec primárního checkoutu, jeho název adresáře s připojeným
-wt; worktree větve je název větve pod kontejnerem, jeden adresář na komponentu oddělenou/, hierarchie zachována.feature/providers/openai-streamingžije na<repo>-wt/feature/providers/openai-streaming. Nic se neslučuje, nehashuje, nečísluje ani nepřejmenovává. - Git je registr. Žádná sekce politiky, konfigurační soubor, tabulka ani seznam nezaznamenává kontejner ani cestu branche. Spustitelný soubor čte společný git adresář,
git worktree list --porcelainafor-each-ref, a vše ostatní odvozuje. Přidání branche nevyžaduje upravit nic nikde. - Primární checkout hostuje trunk. Trunk se zjišťuje — HEAD remote,
init.defaultBranch, jediný konvenční název, vlastní větev primárního checkoutu — a nikdy se nezapisuje napevno. Každá větev mimo trunk, která je checkoutnutá, má právě jeden worktree na své kanonické cestě. - Práce začíná nástrojem.
majordomus worktree create <branch>(neboensure) odvodí cíl, ověří název větve pravidly gitu, vytvoří větev z trunku, je-li nová, drží zámek worktree repozitáře, odmítne obsazený cíl nebo větev checkoutnutou jinde a ověří, co git zaregistroval. Holégit worktree add <path>je způsob, jak worktree skončí tam, kde ho nikdo nenajde. - Agent si cestu nevybírá. Před implementací zjistí aktuální větev, aktuální worktree, kanonický worktree a úkol, pokud ho větev jmenuje (
majordomus worktree status); nesoulad se opraví nástrojem, nikdy se neobchází pokračováním v primárním checkoutu nebo tam, kde relace náhodou začala. - Commit je střežen. Hook pre-commit se ptá
majordomus worktree guard, který odmítne commit feature větve odjinud než z její kanonické worktree a commit primárního checkoutu na větvi, která není trunk. Odpojené worktrees jsou vyňaty. Hook nenese žádnou vlastní logiku. - Worktree jinde je diagnóza a opraví ji jen migrace. Každý stav má stabilní kód (
worktree.path_mismatch,worktree.container_occupied,worktree.destination_conflict,worktree.ephemeral, ...), který nese příkazová řádka, API, MCP, Cockpit i testy, a ke každému nápravu.worktree migrate --planukáže přesuny a nic nemění;worktree migrateje provede. - Migrace je bezeztrátová, nebo to není migrace. Špinavý worktree se přesouvá tak, jak je — včetně změněných, staged, unstaged i untracked souborů — nikdy se neresetuje, nestashuje, nečistí ani se z něj nedělá checkout. Před každým přesunem a po něm se pořídí otisk a porovná se; krok se hlásí jako přesunutý, jen když jsou shodné, a rozdíl se hlásí jako selhání s uvedením, co se liší. Existující cíl se nikdy nepřepíše. Zamčený worktree čeká na odemčení. Detached worktree se nikdy nepřesouvá; scratch checkout relace (pod dočasným adresářem nebo
.claude/worktrees/) se hlásí a přesouvá jen na požádání. - Odstranění je explicitní a zachovává větev.
worktree removeodmítne neuloženou práci bez--force, nikdy se nedotkne primárního checkoutu a nikdy nesmaže větev. Způsobilost k úklidu — sloučeno do trunku, čisté nebo nevyzvednuté — je odvozený stav, na kterém jedná člověk. - Následují projekce. Čtyři schopnosti
worktree.*jsou deklarovány jednou a promítají se do MCP, HTTP, OpenAPI, Cockpitu a generované reference; příkazová řádka vykresluje tytéž typované odpovědi;-wtje napsáno jednou v cratu a kontrola v CI drží každý dokument a šablonu, které ji jmenují, u této konstanty.
Pravidlo platí pro celý repozitář. Kontextový dokument pod .ai/ k němu může přidávat a nesmí jej oslabit.
Chování při selhání
majordomus worktree guard skončí kódem 10 s diagnostikou a její nápravou; pre-commit hook předá exit kód dál, takže se commit neprovede. worktree status, list, topology, validate a doctor skončí kódem 10, dokud stojí diagnostika na úrovni chyby. worktree create odmítne s kódem 10, pojmenuje, co překáží, a nevytvoří nic. worktree migrate nechá krok zablokovaný nebo selhaný s jeho důvodem a skončí kódem 10, když některý krok nedoběhl; nic napůl přesunutého se nehlásí jako přesunuté.
scripts/ci/worktree-check shodí build, když se hook už neptá guardu, když se -wt objeví v cratu kdekoli jinde než v jedné konstantě, když dokument nebo šablona, které jmenují kontejner, nesouhlasí s konstantou, nebo když selže behaviorální případ.
Ověření
cargo test --manifest-path apps/majordomus-cli/Cargo.toml --test worktree (odvození, identita z každého adresáře, postavení, migrace špinavých worktrees s otisky, obyvatel kontejneru, konflikty, zámky, efemérní postavení, souběžnost, parita mezi příkazovou řádkou a registrem); test/cases/96_worktree_topology.sh (sestavený spustitelný soubor přes vlastní zapojení shellového nástroje: hook odmítá, doctor vidí záznam vynucování, migrace přesouvá a ověřuje); scripts/ci/worktree-check (kontrola).