145. Osobní vrstva nemění nic sdíleného: pokrývá ji vlastní exclude soubor gitu, kontroluje se tam, kde se nárokuje, a týmu se předává jedním příkazem
Kontext
majordomus init vytváří vrstvu, kterou repozitář vlastní. Její sledovaná polovina, .ai/repo/, je určena k commitu; řádek, který drží lokální polovinu mimo, je zapsán do sledovaného .gitignore; update zapisuje AGENTS.md, CLAUDE.md a GEMINI.md v kořeni; a doctor selhává, dokud README.md nejmenuje AGENTS.md. Každé z toho je změna toho, co sdílí celý tým.
To je správný způsob, jak nástroj adoptovat jako tým, a špatný jako jediný způsob, jak se s ním seznámit. Týmové rozhodnutí si zaslouží důkazy a důkazy plynou z používání. Vývojář, který chce nástroj vyzkoušet na skutečné práci — v repozitáři týmu, klienta nebo open-source projektu — musel měnit sdílené soubory, čímž se osobní zkouška změnila v návrh dřív, než bylo co navrhovat. Obejitím byl ručně psaný exclude soubor, který nic neověřovalo, mimo který zapisovaly update i capture install a skrz který program v Rustu nemohl číst: zjišťování se ptá gitu na sledované soubory, takže nesledovaná vrstva je vrstva bez souborů (--discovery filesystem existovalo a nic ho nepředávalo).
Rozhodnutí
-
Personal je způsob instalace, ne druhé rozložení.
majordomus init --personalvytvoří stejné soubory, jaké vytvoří obyčejný init, na stejných místech. Liší se to, čí jsou. Nic se nepřesouvá, takže každý příkaz, cesta a dokument znamená to, co dřív, a co se člověk naučí v personal módu, je to, co by dostal tým. -
Krytím je vlastní exclude soubor gitu. Vrstva je kryta ukotveným vzorem v
$GIT_COMMON_DIR/info/exclude, uvnitř označeného bloku, přičemž všechny ostatní řádky souboru zůstávají nedotčeny. Git tento soubor nikdy necommituje, nepushuje, neklonuje ani nestashuje a každý worktree repozitáře se řídí tím společným, proto se žádá o společný adresář, a ne o.git— v linked worktree je.gitsoubor. Sledovaný.gitignorese nezapisuje. -
Žádné nastavení neexistuje. Vrstva je osobní, když ji pokrývá blok exclude. Blok je zároveň mechanismus i záznam a čte se pokaždé, když se na něj zeptáme (
mj_personal_active), takže--extendosobní vrstvy zůstává osobním i bez příznaku. Nic neukládá režim, který by se mohl s repozitářem rozcházet. -
Každý zapisovatel mimo vrstvu kryje před zápisem.
updateacapture installvolají jednu ochranu (mj_personal_guard) pro každou cestu, kterou se chystají zapsat: přidá cestu a vedle ní název stagingu do bloku. Cesta, kterou git už sleduje, patří projektu a odmítá se dříve, než se cokoli zapíše, protože poloviční aktualizace je horší než žádná. Mimo osobní vrstvu ochrana nedělá nic, takže ji zapisovatel volá bezpodmínečně a neexistuje druhá cesta kódu, kterou je třeba držet v souladu. -
Tvrzení je ověřováno tam, kde vzniká, dvakrát, programy, které nesdílejí nic.
init --personalzaznamenágit status --porcelain --untracked-files=allpřed zápisem a skončí s kódem 10, pokud po něm nečte totéž.--personalinstalátoru spouštíinit --personala porovnává stav samo, před a po, aniž by cokoli zapsalo.doctordrží vrstvu u tvrzení při každém běhu a jmenuje soubor z ní, který byl přesto sledován; nežádáREADME.mdprojektu, aby bootstrap jmenoval, protože ta řádka by byla změnou sdíleného souboru. -
Objevování je odvozeno. Když je manifest na disku a index pro něj nemá položku, spustitelný soubor prochází pracovní strom, místo aby se ptal indexu (
discovery::layer_is_untracked). Ptá se gitu při každém startu. Žádný příznak si nemusí pamatovat launcher, hook ani konfigurace klienta MCP a vrstva commitnutá později se od té chvíle čte přes index. -
Předání týmu je jeden příkaz, a stále rozhodnutí člověka.
majordomus init --extend --sharedodstraní blok, přidá dva řádky.gitignore, které přidává běžný init, a vypíše cesty, které nyní patří repozitáři ke commitu. Nic necommituje. Od té chvíle je vrstva běžná.
Důsledky
Osobní vrstva patří jednomu člověku na jednom stroji. Nepřenáší se s klonem, pushem ani stashem, takže předávky na jiný stroj jdou přes mesh, nebo vůbec; kolega, který chce totéž, si nainstaluje vlastní. Průvodce to říká.
Osobní režim drží vrstvu stranou od toho, co repozitář sdílí; není to řízení přístupu ani způsob, jak obejít pravidla organizace o nástrojích. Soubory jsou na disku na očích a zda smí být nástroj na kódové základně použit, je rozhodnutí organizace, činěné tak, jak taková rozhodnutí činí.
Hooky pro commit a push osobní init neinstaluje o nic víc než běžný. .git/hooks/ je už lokální, takže tam lze přidat dva řádky, které doctor jmenuje; repozitář, jehož core.hooksPath ukazuje na sledovaný adresář, si ponechává vlastní hooky a doctor říká které.
scripts/derive a generate si drží svůj kontrakt — derive vidí to, co uvidí commit — což znamená, že osobní vrstva není zdrojem commitovaných projekcí. Nemá žádnou, kterou by commitovala, dokud se nesdílí.
Odmítnuté alternativy
- Režim zaznamenaný v manifestu nebo v politice. Dva zdroje pro jeden fakt: soubor by říkal personal, zatímco index říkal tracked, a něco by muselo rozhodnout, kdo vyhraje. Blok exclude si odporovat nemůže.
- Přesun vrstvy mimo pracovní strom (proměnná prostředí jmenující jiný adresář). Každá cesta v každém dokumentu, hooku a konfiguraci klienta by znamenala dvě věci a pracovník, který čte
.ai/README.md, by ji nenašel. - Zapsat
.gitignorea označit hoassume-unchanged. Změna je stále v pracovním stromu,git stash -ui checkout jiné větve na ni narazí a příznak se ztratí při dalším přepisu indexu. - Globální položka
core.excludesFile. Pokrývá.ai/v každém repozitáři na stroji, včetně těch, které svou vrstvu sledují.
Stav
Navrženo. Implementováno s pravidlem project.a-personal-layer-changes-nothing-shared, tvrzením personal-layer-changes-nothing-shared, případem 2979 a úkolem I2491.