64. Deklarovaný nástroj má verzi a nesoulad je nález
Kontext
catharsis-as-a-service připíná generátor, který ho sestavuje: .zola-version obsahuje 0.23.6 a scripts/validate.sh odmítne běžet s jakoukoli jinou verzí — záměrně, protože výstup generátoru statických webů se mezi patch vydáními mění a HTML validace repozitáře je přesná. Dne 2026-09-14 měl stroj 0.23.4, Homebrew nabízel 0.23.5 a kontrola se zastavila hned prvním krokem. Každá další kontrola v tom repozitáři byla nedosažitelná, dokud pin nebyl splněn.
Recept, který ho splňuje, existuje a je přesný: .github/actions/setup/action.yml stáhne zola-v${version}-x86_64-unknown-linux-gnu.tar.gz ze stránky releasů a zkontroluje ho proti zaznamenanému SHA-256. Tuto znalost má CI a nikdo jiný. Relace připnutí splnila tím, že přečetla workflow, přeložila ho na lokální architekturu a stáhla tarball ručně do scratch adresáře — soukromý akt, který nezanechal žádnou stopu, nic nenaučil dalšího workera a je důvodem, proč toto rozhodnutí existuje.
Majordomus už modeluje deklarované toolchainy: apps/majordomus-cli/src/environment/toolchain.rs detekuje rust, node, just, python, go, elixir a deno podle značek, které tyto ekosystémy používají, a každý typuje jako {declared, declared_by, installed, availability}. Dvě věci vyjádřit nedokáže:
ToolchainAvailabilityjeInstalled | Missing | Unknown. Repozitář, který deklaruje node 22 na stroji s node 18, hlásíInstalled. Neexistuje stav nesouladu, tedy ani nález nesouladu, a jediná existující diagnostika se spustí, jen když binárka úplně chybí.- Tabulka detektorů je v Rustu. Repozitář, který připíná binárku, jíž tabulka nezná — zola, terraform, domácí nástroj — ji nemá jak vůbec deklarovat.
majordomus envnevidí pin, který zastaví sestavení.
Rozhodnutí
Deklarovaná verze, která se liší od nainstalované, je vlastní stav. ToolchainAvailability získává Mismatch { declared, installed } a doctor ji hlásí jako nález, se souborem, který ji deklaroval, a verzí, která odpověděla.
Repozitář může deklarovat nástroj, o kterém tento nástroj nikdy neslyšel. Deklarace jsou data ve vlastní vrstvě repozitáře: binárka, soubor, který nese verzi, jak ji přečíst, a sonda, která se instalované binárky ptá, čím je (zola --version, pole 2). Detekce přestává být tabulkou v Rustu, kterou je nutné rozšiřovat pro každý ekosystém, a stává se tabulkou, kterou tento nástroj dodává plus to, co přidá repozitář.
Deklarace může nést recept, který ji splňuje, a Majordomus jej nikdy nespouští. Pole how — vzor URL, digest, příkaz — nález vypíše a spustí jej člověk. Tím končí selhání, které si rozhodnutí vynutilo (recept uzamčený uvnitř akce CI), aniž by se z řídicí dozorové vrstvy stal správce balíčků, který by potřeboval síť, model důvěry a místo pro binárky, z čehož nic nemá a mít nemá.
Nesoulad je poradní a fatální ho smí učinit jen kontrola samotného repozitáře. Pin někdy záměrně zaostává za strojem; nástroj hlásí, kontrola odmítá. Je to stejné dělení jako všude jinde: Majordomus říká, co je pravda, repozitář rozhoduje, co je fatální.
Zamítnuté alternativy
Nainstalovat deklarovaný toolchain. Je to zřejmý další krok a je to jiný produkt. Stahování a spouštění binárek na vývojářově stroji vyžaduje model důvěry, kterému se tento nástroj záměrně vyhnul (project.no-network-no-eval), a každý ekosystém už má správce verzí, který to dělá lépe.
Přečíst workflow CI a připnutí se naučit odtud. Workflow je projekce toho, co repozitář vyžaduje, ne jeho výrok, a doktrína tohoto repozitáře je, že sémantická definice opakovaná napříč projekcemi je vada návrhu (ADR 0004). Deklarace patří do vrstvy; CI ji čte také.
Brát nesoulad jako Missing. Čte se to jako lež na jediném místě, kam se člověk dívá, když kontrola zastaví: binárka tam je, na PATH, a odpovídá. Diagnostika, která špatně popisuje, co našla, je horší než žádná diagnostika.
Důsledky
majordomus env a doctor získávají třídu zjištění, která se spustí na strojích, které dosud fungovaly bez problémů; to je zamýšlený účinek a jednou bude hlučný.
Detektor toolchainu se stává zčásti daty, což znamená schéma pro něj, a repozitář, který napíše špatnou sondu, dostane špatnou odpověď — omezeno tím, že sonda je příkaz jen pro čtení, který si repozitář zvolil spustit proti vlastní binárce.
Znalost, jak splnit pin, se přesune z CI do vrstvy, kde ji další pracovník — člověk či ne — najde zeptáním se nástroje, který mu právě řekl, že verze je špatná.