I1520 — Krok, kterému dojde čas, to řekne sám
Přimět krok CI, který překročí svůj čas, aby hlásil selhání jmenující mez a uplynulý čas, místo aby ho job zabil a GitHub ho ohlásil jako zrušení, které každý čtenář v tomto repozitáři bere jako ne-selhání.
HOTOVO vlna 0 · p1 · profil implementation · bezpečné souběžně
Součást development-runtime — The runtime has a development surface.
Cíl
Přimět krok CI, který překročí svůj čas, aby hlásil selhání jmenující mez a uplynulý čas, místo aby ho job zabil a GitHub ho ohlásil jako zrušení, které každý čtenář v tomto repozitáři bere jako ne-selhání.
Proč
Krok 'audit the UI in a browser' v úloze site byl zabit přesně na limitu 50 minut timeout-minutes své úlohy na masteru na 6a8d47a47 (01:14 až 02:04), na 70685d473 (23:13 až 00:03) a v obou bězích integrační větve #310 — tři po sobě jdoucí běhy, každý na vteřinu přesně, a nic nebylo nikdy červené. GitHub hlásí úlohu zabitou vlastním limitem jako `cancelled` a `cancelled` je to, co kontroly, souhrny a tři relace za jednu noc četly jako 'není selhání'. Já sám jsem to tak četl hodinu předtím, než jsem to změřil.\n\nPříčina byla v nástroji. scripts/ci/timed počítal uplynulý čas po návratu příkazu, takže příkaz, který se nikdy nevrátil, nebyl nikdy změřen a nikdy nevznikl řádek, který by říkal opak. Jediné, co mohlo problém ohlásit, bylo to, co problém znemožnil spustit. To je ta třída: verdikt bez měření za sebou, stejná rodina jako english-only-check, který padl na vlastním regulárním výrazu a oznamoval, že každý soubor je anglicky, a coverage-differential, který byl deklarován, plánován, jmenován v if: úlohy a nevolal ho žádný krok.
Aktuální stav
Všech 13 timeout-minutes v .github/workflows/validate.yml je na úrovni úlohy; žádný krok nenese vlastní hranici. scripts/ci/timed měří až po faktu a nemůže hlásit krok, jehož dokončení nikdy neviděl. Audit UI je nad hranicí své úlohy a je tomu tak, jak daleko sahá retence běhů.
Cílový stav
Každý měřený krok deklaruje mez menší než mez své úlohy, takže uprchlý krok vždy prohraje závod se svou vlastní zprávou; řádek časování se zapíše i když mez zabere, protože právě tehdy je jediným důkazem; a kontrola drží tento vztah, takže nový krok nelze přidat bez meze.
Rozsah
- scripts/ci
- .github/workflows
- .ai/repo/ci
- test/cases
Mimo rozsah
- Zrychlení auditu UI nebo rozhodování, jaká má být jeho hranice. Toto mění tichý kill na pojmenované selhání; jaká je správná hranice, je samostatné a uvážené rozhodnutí.
- Součet mezí kroků úlohy. Několik kroků se stále může sečíst přes mez své úlohy a být zabito společně; mez úlohy zůstává záchranou, jakou vždy byla.
Závislosti
Žádné. Tento úkol je kořenem grafu.
Kritéria přijetí
- Krok nad svou mezí skončí nenulovým kódem se zprávou jmenující mez a uplynulý čas
- Řádek časování se zapíše, když se spustí limit, nejen když se příkaz vrátí
- Každé volání scripts/ci/timed deklaruje mez přísně menší než timeout-minutes jeho jobu
- Kontrola odmítne časovaný krok bez meze a takový, jehož mez dosahuje meze jeho úlohy
Validace
- bash scripts/ci/step-bound-check
- bash test/run.sh 349_a_step_reports_its_own_time
Požadované důkazy
- a_step_over_its_bound_reports_it
- no_step_can_be_killed_by_its_job_first
Důkazy
| pokrývá | typ | command | výsledek | u commitu |
|---|---|---|---|---|
| a_step_over_its_bound_reports_it | test | bash test/run.sh 349_a_step_reports_its_own_time | ok na b4a781c668: krok, kterému dojde čas, to ohlásí a jeho řádek časování se zapíše; oprava je b3e261428b | b4a781c |
| no_step_can_be_killed_by_its_job_first | test | scripts/ci/step-bound-check | exit 0 na b4a781c668: každý měřený krok je omezen pod svou úlohou | b4a781c |
Riziko
Tím se job site stává červeným místo zrušeného, hlasitě a při každém běhu, dokud audit UI neskončí v mezích nebo někdo mez s důvodem nezvýší. To je zamýšlený účinek a stojí za to to říct jasně: tichý kill se vyměňuje za viditelné selhání, ne za opravu.
Časová osa
- zahájeno
- 2026-09-15
- ověřeno
- 2026-10-07T13:27:27Z
- dokončeno
- 2026-10-07T13:27:30Z
Tato tři pole, důkazy výše a stav závislostí jsou vše, z čeho se stav skládá. Neexistuje žádné pole stavu, které by s nimi mohlo být v rozporu.
Kanonický záznam: .ai/repo/project/issues/I1520.yaml. Přečtěte jej zpět pomocí majordomus plan show I1520.