Co to znamená
docs/CLAIMS.yaml váže tvrzení na test cestou a cesta, která se vyřeší, dokazuje jen to, že soubor existuje. Neříká, že se případ někdy spustil, proti jaké revizi, s jakým výsledkem ani zda se výsledek stále uplatňuje. Až do tohoto podsystému byl status: guaranteed vedle test: test/cases/84_distribution_model.sh vykreslován na veřejném webu jako záruka jen na základě toho, že soubor existuje, a nic v repozitáři se nedalo zeptat jinak.
Důkaz je zde provedení: jeden zaznamenaný běh jednoho testu, nesoucí původ, který běh sám neměl — výsledek, dobu v celých sekundách, plný commit, nad kterým běžel, zda ten commit popisoval strom, sha256 vlastního zdroje testu v daném čase, kdy byl zaznamenán, kde běh proběhl a příkaz, který jej vytvoří znovu. Repozitář drží poslední provedení každého testu ve sledované knize a spojení té knihy s maticí odpovídá, co lze za každé tvrzení poctivě říci. Tvrzení, jehož test nikdo nikdy nespustil, se čte not_run, místo aby zdědilo záruku z existence souboru.
Princip
Tři objekty a jedno odvození v apps/majordomus-cli/src/evidence/.
TestId je stabilní identita testu, počítaná z cesty, kterou tvrzení už jmenuje. test/cases/84_distribution_model.sh je případ, který test/run.sh zná jako suite:84_distribution_model; apps/majordomus-cli/tests/why.rs je binárka, kterou spouští cargo test --test why. Obě podoby v repozitáři už existovaly, takže TestId::of jmenuje spojení a nic jiného: matice nezískala žádné pole, žádné tvrzení se nemigrovalo a přidání třetího runneru je varianta a větev v jedné funkci, nikoli konfigurační soubor — runner, který nic nespouští, je runner, jehož výsledky nelze nikam zaznamenat. Cesta, kterou žádný runner neřídí, ať je to šablona, fixture, knihovna nebo vnořená cesta pod test/cases/, kterou runner nevyčísluje, nejmenuje žádný test a tvrzení se čte jako unrunnable, místo aby se počítalo jako pokryté. Vlastní zástupný symbol matice pro nic, -, v uvozovkách či bez nich, se čte jako no_test.
Execution je jeden zaznamenaný běh a Ledger — .ai/repo/evidence/ledger.json, sledovaný JSON, jeden záznam na test — drží ten nejnovější z nich. evidence::report spojuje tvrzení, která drží index, s provedeními, která drží ledger, při každém čtení a rozhoduje o jednom ze sedmi stavů na tvrzení: proven, inputs_unchanged, stale, failing, not_run, unrunnable, no_test. Spojení se nikdy nezapisuje, takže neexistuje druhé místo, kde by se stav důkazu uložil a zastaral, a žádná ze schopností pro důkazy ho necachuje.
evidence record čte, co běhy už zapsaly — TSV report sady pod MJ_TEST_REPORT, výstup cargo test — a do každého výsledku přenáší, co jeho běh změřil. Zaznamenává; nic nerozhoduje. Jen rozpoznané úspěšné projití něco dokazuje a slovo výsledku, které nikdo nezná, je error, nikoli tiše dobrý výsledek; v modelu záměrně není výsledek not_run, protože to je absence provedení, ne provedení, které test měl, a zapisovač, který by ho uměl zapsat, by mohl nechat „toto neběželo“ počítat mezi věci, které běžely. Strom bez commitu, který by šlo pojmenovat, se odmítne, protože běh tam zaznamenaný by nenesl žádný původ. Poškozený řádek reportu se odmítne, ne přeskočí: tiše zahozený případ nechá tvrzení číst not_run po běhu, který jej spustil, což je lež v bezpečném směru a stále lež. Výsledek pojmenovávající test, který tento checkout nemá, se hlásí jako neznámý a nezaznamenává se nikomu, protože to znamená, že se runner a matice rozešly.
Běh měří a záznamník nese. Vlastní měření běhu (evidence stamp, pojmenovávající jeho report) dává commit a strom, se kterými se provedení zaznamená, takže záznamník nikdy neručí za strom, který neviděl; report zaznamenaný bez něj nese strom unknown a nikdy nečte proven. Razítko měří checkout v okamžiku pořízení, po zapsání reportu, a ne strom, zatímco běh probíhal.
Jak to vidět
majordomus evidence show # every claim, its state, the run behind it
majordomus evidence show --state not_run # the claims nothing has ever run
majordomus evidence claim distribution-canonical-model
MJ_TEST_REPORT=suite.tsv bash test/run.sh
majordomus evidence stamp --report suite.tsv --out suite.provenance.json
majordomus evidence record --suite suite.tsv --provenance suite.provenance.json
Každý příkaz bere --format json. Repozitář, který nic nezaznamenal, to řekne a skončí kódem 0 — každé tvrzení se čte not run, což je pravda — protože repozitář, který nedokáže ohlásit absenci důkazů, by musel nehlásit vůbec nic.
Co nepokrývá
Není odolná proti manipulaci a nesmí se tak popisovat. Účetní kniha je sledovaný soubor; člověk do ní může zapsat "outcome": "pass" a recenzent uvidí diff. Zaznamenaný digest kupuje detekci zastarání, která přežije revert, ne odolnost proti padělání: spuštění, jehož zdroj testu už nehashuje na zaznamenanou hodnotu, nespustilo test, který tam je teď, ať commit říká cokoli. Kryptografický ceremoniál proti někomu, kdo může do tohoto repozitáře už commitovat, by byl ceremoniálem bez modelu hrozeb.
Výsledky nesoudí. Nic znovu nespouští test, nepřeinterpretuje výsledek ani nerozhoduje, že selhání bylo způsobeno prostředím, a nic tu nemůže učinit tvrzení pravdivým: stav proven říká, že test proti tomuto stromu prošel, a zda test skutečně testuje dané tvrzení, je otázka pro revizi, kterou drží pravidlo project.no-claim-without-test.
Neuchovává žádnou historii ani zachycený výstup. Ledger odpovídá na je toto tvrzení nyní dokázáno, což čte vždy jen nejnovější běh; záznam o tom, co se dělo v čase, je git nad tímto souborem, a megabajty logu běhu patří tam, kde běh proběhl.
Dnes do ní CI nic nezaznamenává. Job sady už TSV zapisuje a nahrává, ale zapsat důkazy CI do repozitáře vyžaduje commit, který běh pull requestu nesmí udělat, takže hlavní knihu zapisuje a commituje ten, kdo sadu spustí lokálně. Stavy jsou poctivé tak či tak: nezaznamenaný běh je nezaznamenaný běh.
Proč existuje
Kontrola odkazu a důkaz jsou dvě různé otázky a tento repozitář měl jen tu první. scripts/generate-site-data --check ověřovala, že se každá cesta source, implementation a test dá najít, takže rozbitý odkaz nemohl vzniknout, ale prázdnou záruku nešlo odhalit — právě to selhání, které pravidlo project.never-reported-is-not-green pojmenovává o úroveň výš. Zveřejnit větu jako zaručenou jen proto, že existuje soubor se správným názvem, je zelený odznak, jehož původ nelze prověřit, a přesně to si repozitář, jehož celý argument říká důkazy místo tvrzení, nemůže dovolit vydat.