37. Kontrola, jejíž runner si repozitář nemůže obstarat na požádání, se plánuje na požádání, aby verdikt dorazil
Kontext
ADR 6 dalo tomuto repozitáři jeden požadovaný stav: ci, job, který běží vždy, potřebuje každý další job a je zelený jen tehdy, když uspěl každý gate vybraný plánem. Návrh je správný a přestal fungovat z důvodu, který žádný gate nemohl nahlásit.
Naměřeno 2026-09-10. Čtyři validační běhy masteru — 67ec7c2aa, c08c44733, 31285bdf5, beaee8654 — seděly v queued, nejstarší sedm hodin. Uvnitř nich každá linuxová úloha skončila; v běhu 31285bdf5 jich pět selhalo. Tři úlohy nikdy nezačaly: bench, macos a install (macos-latest), všechny na macos-latest. ci potřebuje všechny tři, takže ci neběželo, takže se nehlásilo nic — a kontrola, která nikdy nehlásila, a kontrola, která hlásila zeleně, jsou v rozhraní, na které se člověk dívá, tatáž absence. Master takto přenesl pět defektů přes noc.
Čekání to nevyřešilo. Tento repozitář pushuje na master zhruba každých sedm minut v den integrace; sada macOS běží asi 106 minut; každý běh žádá o tři úlohy macOS a žádají o ně i běhy pull requestů, protože třídy, které vybírají macos, jsou crate, shell nástroj, distribuce a pipeline — téměř každá změna. Poptávku takového tvaru sdílený pool macOS neobslouží při žádné hloubce fronty, takže kontroly nic nechránily: za celý ten den nedoběhla jediná.
Zvlášť a ve stejné podobě: úloha nasazení Pages počítala s pěti minutami na práci, která zahrnuje čekání na vlastní sestavení Pages od GitHubu. To trvalo 33, 121, 204 a 338 sekund při čtyřech nasazeních toho dne; úloha byla v 13:56:12 uprostřed čekání zabita, přestože publikace byla hotová už v 13:52:20, a GitHub hlásí úlohu zabitou svým timeoutem jako cancelled. Úspěšná publikace se četla jako neúspěšná.
Rozhodnutí
- Model označuje kontrolu, ne workflow. Kontrola v
.ai/repo/ci/gates.yamlmůže néston-demand: true.scripts/ci-plantakovou kontrolu vynechá z každého plánu, který o ni nepožádal — včetně plného plánu — a u každé kontroly zaznamená, že nebyla naplánována a proč;--on-demando ně žádá.impliesarequiresžádnou nemohou přinést do plánu, který o ni nepožádal. Pole je buď true, nebo chybí, a kontrola nemůže být zároveňalwaysaon-demand. - Nesou ji tři kontroly a společný mají runner, ne předmět:
macos,rust-benchainstaller-live(jejichž úloha je matice s větví pro macOS aneeds.<job>.resultje jedna hodnota přes obě větve). - Události, které si je mohou dovolit, o ně žádají. Noční plán,
workflow_dispatcha pull request označenýci:fullpředávají--on-demand; běžný push a obyčejný pull request ne. Plán se mění z týdenního na noční, takže kadence kontrol na macOS je den, ne nikdy. cije beze změny. Stále potřebuje každý job, který model jmenuje, a stále zčervená, když je některý z nich červený; při běžném pushi jsou ty tři přeskočeny, ne zařazeny do fronty, což mu umožňuje hlásit. Požadovat ho v pravidle větve zůstává nastavením vlastníka repozitáře.- Timeout omezuje jeden druh sekundy a který timeout zasáhne, je aritmetika. V
pages.ymlnesou řízené kroky vlastní minuty — to mění zaseknutí v selhání — a mez jobu je nastavena přísně větší než jejich součet. Ta nerovnost je rozhodnutím, ne čísla: krok zabitý vlastní mezí je selhaný krok a u sondy publikace, která jecontinue-on-error, hlášený; job zabitý mezí jobu jecancelledpřes všechny kroky najednou, včetně těch, které uspěly. Job s mezí rovnou součtu nebo pod ním způsobí, že zasáhne mez jobu, což nahlásilo dokončené nasazení jako selhání. Sonda publikace čeká deset minut místo čtyř, uvnitř kroku omezeného na jedenáct, aby přežila vlastní diagnostika skriptu — který commit web stále obsluhuje; job je omezen na pětadvacet nad řízeným rozpočtem, který.ai/repo/ci/pages.yamlklade na pětašedesát sekund, protože zbytek toho čísla je build Pages na GitHubu, o kterém tentýž soubor už říká, že se měří a nikdy nerozpočtuje.test/cases/26_ci_wiring.shdrží tu nerovnost.
Důsledky
- Verdikt existuje při každém pushi i každém pull requestu a lze ho vyžadovat.
- Regrese jen pro macOS se může dostat na master a být nalezena nočním během, ne při merge. To, co se nepřesouvá, jsou důkazy o nasazení při každém pushi:
pages-liveběží na Linuxu, není na vyžádání a při každém pushi stále čte publikovaný web; na noc se přesouvá jen instalační polovina té otázky, s větví macOS, s níž sdílí úlohu. To je kompromis, který tento záznam existuje pojmenovat. Je to menší ztráta, než se zdá: před touto změnou se kontroly macOS nedokončovaly vůbec, takže se při merge nic nezachytilo ani předtím. Revizor, který čeká potíže závislé na platformě — shellový nástroj, distribuce, práce cratu s procesy a soubory — označí pull requestci:fulla dostane je před merge. - Noční běh je ten, který je nese, takže ho musí někdo číst. Noční běh, který zčervená a nikdo ho nečte, je tatáž vada, jen o kadenci pomalejší.
scripts/ci-plan --fulluž neznamená „každou kontrolu“. Říká to ve svém řádku s důvodem ajust ci-fullpředává--on-demand, protože člověk, který chce všechno, myslí všechno.- „Triggers and concurrency“ z ADR 6 (týdenní plán) a jeho odrážka „Platforms“ (macOS v každém plném plánu) tento záznam mění, nenahrazuje: zbytek onoho rozhodnutí platí.
Zamítnuté alternativy
- Druhý verdikt jen pro Linux vedle
ci. Dorazil by, ale nechává úlohy pro macOS čekat ve frontě při každém pushi, takže kontroly zůstávají bez hlášení a fronta zůstává nasycená pro každé další spuštění; a dva stavy, jejichž názvy se liší jedním slovem, jsou způsob, jak se začne vyžadovat ten špatný. - Méně jobů na macOS na jeden push (sloučení kontroly měření výkonu do jobu macOS). Půlí číslo, které musí klesnout o dva řády. Výše uvedená aritmetika to nezajímá.
- Zvýšit timeouty a čekat. Úlohy čekaly ve frontě sedm hodin proti limitu 110 minut; žádný limit, který tento repozitář zapíše, nezmění, co dodává sdílený pool runnerů.
- Smazání gate pro macOS. Zachycují zde skutečnou opakující se třídu — bash 3.2 a BSD userland — a tento záznam mění jejich kadenci, ne obsah.
- Koupit kapacitu. Větší a placené runnery macOS od GitHubu nejsou ve frontě jako volný fond a obnovily by kontroly macOS na každý push bez změny jediného řádku modelu. To je alternativa, kterou tento záznam nesmí zamítnout: patří vlastníkovi repozitáře, stojí peníze, ne návrh, a je správnou odpovědí, pokud se níže uvedený kompromis ukáže bolestivým. Bude-li zvolena, změna zde je jedno pole — odebrat
on-demandze tří kontrol — a tento záznam je nahrazen, ne obcházen.