62. Ověření se dokazuje proti commitu a dva pokusy, které si odporují, nejsou důkaz
Kontext
majordomus finish --verify-command spouští vlastní ověření projektu a v události task.finished zaznamenává přesně {"command": …, "exit": …, "seconds": …}. Běží v $MJ_ROOT — pracovním stromu tak, jak je, se vším, co v něm je — a k .ai/repo/evidence/ledger.json nikdy nedosáhne. ADR 0041 už rozhodlo, co je třeba k zapamatování jednoho běhu: výsledek, trvání, commit, proti kterému běžel, zda byl strom čistý, digest zdroje v té době, časové razítko, původ a příkaz, který jej reprodukuje, a „výsledek bez commitu je anonymní zelená a odmítá se v okamžiku zaznamenání“. Kontrakt dokončení zaznamenává anonymní zelené.
Dne 2026-09-14 ten rozdíl zviditelnila relace v catharsis-as-a-service. Tři workery sdílely jeden checkout jedné větve. npm run validate v tom stromu prošlo — a nedokázalo nic o žádném commitu, protože strom obsahoval necommitnuté soubory dvou dalších relací, z nichž jeden (vykreslený manifest náhledu) sám rozhodoval o tom, zda je kontrola červená, nebo zelená. Běh, který commit skutečně dokázal, byl jiný běh: git archive HEAD rozbalený do pracovního adresáře, kontrola spuštěná tam, 15 z 15 kroků a 110 ze 110 testů v prohlížeči. Stejný příkaz, stejný stroj, stejná minuta; jeden z těch dvou běhů byl důkazem o commitu a druhý důkazem o pracovním stole.
Stejná relace ukázala druhou polovinu. Sada prohlížeče proti nasazenému webu jednou selhala — 1 selhal, 109 prošlo — a před ním i po něm prošla dvakrát, 110 ze 110. Záznam, který drží jediný exit kód, by řekl failing nebo proven podle toho, který běh si náhodou ponechal, a obě věty by byly pravdivé o běhu a nepravdivé o softwaru.
Rozhodnutí
Ověření jmenuje, proti čemu běželo, a worktree není commit. Provedení nese source: worktree | export. export je strom commitu, zhmotněný z onoho commitu a ničeho jiného; běh worktree nese stav stromu, který už zaznamenává ADR 0041, a běh worktree nad špinavým stromem nedokládá nic o commitu, na kterém sedí. To je rozlišení, na které existující pole working_tree: clean | dirty | unknown jen naznačuje, aniž by podle něj mohlo jednat: čistý je pozorování o okamžiku, export je výrok o commitu.
finish --verify-command zaznamenává provedení v knize důkazů s původem z ADR 0041. Jedno úložiště. Událost task.finished si ponechává své shrnutí pro čtenáře knihy a provedení, které shrnuje, je záznam, který lze spojovat, stárnout a ratchetovat jako každý jiný.
Pokusy se počítají a pokusy, které si odporují, jsou vlastní výsledek. Jedno provedení může nést více než jeden pokus téhož příkazu na témže commitu a témže digestu. Všechny uspějí: proven. Všechny selžou: failing. Smíšené: flaky — což nikdy nic nedokazuje a není ani selháním stromu. To je nejmenší změna, která činí přerušovanost viditelnou, a zachovává odmítnutí historie běhů z ADR 0041: kniha stále drží nejnovější provedení na identitu a počet pokusů žije uvnitř něj.
finish --outcome completed odmítá při flaky. Ověření, které si odporuje, není dokončená úloha; výsledek je partial a poznámka říká, který pokus selhal, nebo se práce opraví. Odmítnutí je okamžik, kdy nestabilita někoho něco stojí, což je jediný způsob, jak se opraví.
Zamítnuté alternativy
Opakovat, dokud není zelená, a zelenou zaznamenat. Zelená se tím vyrábí. Každá flaky sada, která byla kdy tolerována, byla tolerována takto.
Držet úplnou historii běhů a posuzovat flakiness staticky. ADR 0041 historii odmítlo a odmítnutí stále platí — historie je build log s ambicemi. Počítadlo pokusů uvnitř posledního provedení odpovídá na jedinou otázku, na které při zaznamenávání záleží, a na nic jiného.
Vždy ověřovat proti exportu. Export stojí druhý úplný běh kontroly, což u repozitáře, který to motivoval, jsou minuty, a většina ověření během úlohy nejsou tvrzení o commitu. Běh, který commit dokazuje, musí být export: ten, který zaznamenává finish.
Odvodit export z working_tree: clean. Čistý strom v okamžiku běhu není stejné tvrzení jako vlastní strom commitu a rozdíl je přesně případ, který to způsobil — nesledované soubory tento příznak nevidí a byly rozhodujícím vstupem.
Důsledky
Je potřeba primitivum exportu a majordomus archive to není: archive pořizuje snímek indexu gitu pro distribuci, tohle potřebuje strom pojmenovaného commitu, zhmotněný někde na zahození. Disk, který to stojí, omezuje stejný predikát jako každý jiný výstup sestavení (project.accumulation-is-measured).
Ověření se zpomalí přesně v jednom bodě životního cyklu a nástroj nyní zná rozdíl mezi ověřením a zvykem.
finish získává odmítnutí, což znamená, že úloha může být nyní blokována vlastní nestabilitou. To je zamýšlená cena.