68. Důkazy CI se uchovávají tam, kde běh proběhl, a publikují s commitem, který dokazují
Kontext
ADR 41 učinilo z důkazu tvrzení zaznamenané provedení s commitem, digestem a původem a uchovávalo nejnovější provedení každého testu v .ai/repo/evidence/ledger.json. Jako původ jmenovalo ci. Nikdy ho nic nezaznamenalo.
Naměřeno 2026-09-15 na c3f20da: kniha držela šest provedení, každé local, nejnovější z 2026-09-12. Ze 173 tvrzení matice bylo 149 not_run a 14 stale. Behaviorální sada běžela při každém pushi na master a zapsala suite.tsv, což CI držela čtrnáct dní jako artefakt časování a nikdo to nezaznamenal; cargo test vypsalo své výsledky do logu; úloha pokrytí nahrála export llvm-cov, který četla jen kontrola. Důkazy existovaly při každém běhu a repozitář nemohl čtenáři ukázat nic z toho.
Tři omezení rozhodují, kde mohou důkazy z CI žít:
- Běh jej nemůže commitnout. Běh, který zapisuje knihu a pushuje ji na master, potřebuje zapisovatele mimo ochranu větve, přidává commit na každý merge do trunku, který se už hýbe každých pár minut, a commit, který přidá, není commit, který dokázal.
- Web se publikuje dřív, než sada skončí.
pages.ymlje rychlá cesta: push na master je veřejný během minut, zatímco sada trvá přes hodinu. Stránka sestavená pro commit X nemůže obsahovat důkazy o X, když se publikuje. - Publikace má jeden plánovač.
test/cases/97_pages_fast_path.shodmítá spouštěčworkflow_runnapages.yml, protože řetězení přes jiný workflow staví před publikaci druhý plánovač.
Rozhodnutí
Důkazy CI jsou artefaktem běhu, který je vytvořil. Job z validate.yml, evidence, čte zprávy, které po sobě nechaly sada, crate a joby pokrytí, a předává je scripts/ci/evidence-collect. Zaznamenává provedení přes majordomus evidence record --origin ci a odvozuje zprávu přes majordomus evidence show. Shrnuje pokrytí přes scripts/rust-coverage --summary-json a zapisuje manifest jmenující commit, běh, výsledky a co chybělo. Adresář se uchovává jako artefakt evidence po devadesát dní. Sledovaná kniha zůstává tím, čím ji učinilo ADR 41, důkazem toho, kdo zapisuje do stromu. Důkazy CI se do ní necommitují.
Provedení jmenuje běh, ve kterém proběhlo. Execution získává volitelné run: poskytovatele, identifikátor běhu, jeho pokus, workflow, job a adresu, kterou čtenář následuje. Adresa je ta, kterou poskytovatel dal, když běh proběhl, ne ta, kterou později sestaví šablona. Sestavuje ji adaptér (RunRef::from_env čte prostředí GitHub Actions) a jen pro původ ci: lokální záznam pořízený uvnitř shellu CI stále není důkazem toho jobu. Řádky zaznamenané před tím run nenesou, proto se verze knihy nemění.
Web publikuje nejbližší důkazy, které má, a říká, jak jsou blízko. scripts/pages evidence běží před sestavením, najde artefakt evidence validace masteru zaznamenaný proti publikovanému commitu nebo jeho nejbližšímu předku a zapíše site/data/evidence.json. Stejně jako site/data/build.json je tento soubor vstupem jednoho nasazení a nikdy se necommituje. Důkaz publikovaného commitu je current. Důkaz předka se publikuje jako zastaralý, se jmény commitů a změněných souborů mezi nimi. Žádný důkaz se publikuje jako nedostupný, s důvodem. Žádné z tří nebrání publikaci. Vyloučeno je jediné: důkaz staršího commitu ukázaný, jako by dokazoval tento.
Obnovení je dispatch, ne řetěz. Poté, co si ponechá artefakt, úloha evidence při pushi na master dispatchuje pages.yml, pokud je její commit stále špičkou masteru. Tato publikace najde důkazy o svém vlastním commitu a řekne current. Pokud master postoupil, nic se nedispatchuje: publikace novějšího commitu už tyto důkazy ukazuje jako zastaralé a vlastní běh novějšího commitu je obnoví. pages.yml zůstává spouštěno samotným pushem a dispatchovaný běh už čeká na běžící publikaci místo jejího zrušení.
Odkaz na běh se rozhoduje offline. scripts/ci/link-check odmítá odkaz, který nelze vyřešit bez sítě. Nyní přijímá právě jeden odkaz na Actions: běh jmenovaný vlastním důkazem publikace, který existuje, protože ten důkaz vytvořil.
Důsledky
- Čtenář
/evidence/vidí, co CI spustilo, výsledky, pokrytí crate, commit a běh a zda cokoli z toho popisuje commit, ze kterého byl web sestaven. pages.ymlzískáváactions: read, odůvodněno v případu, který pinuje jeho oprávnění.- V rušné hodině se master pohybuje rychleji než sada, takže většina publikací ukazuje zastaralé důkazy. To je pravdivý stav trunku, který předbíhá své ověřování, a stránka to říká, místo aby to skrývala.
- Úlohu
evidenceverdiktcinepotřebuje. Rozbitý sběrač způsobí, že web hlásí „unavailable“, což je vidět, ale merge nezastaví. Udělat z něj kontrolu je samostatné rozhodnutí.
Co toto zatím nerozhoduje
Subjekt, ke kterému ověření patří kromě tvrzení (funkce, příkaz, nástroj MCP, pravidlo), pokrytí připsané takovému subjektu, panel ověření na jejich stránkách a pohled Cockpitu na tytéž důkazy. Každé čte artefakt, který toto rozhodnutí vytváří, a žádné z nich jím není vytvořeno.