Repository navigation
fix(ci,#19982): plafond de la jambe README -> .ipynb links porte a 12 min - #19985
Conversation
… min
La jambe `Audit README -> .ipynb links` etait annulee par son propre plafond
de 5 min des que le parc de runners etait sature, et le `PR gate` reportait
cette annulation en rouge bloquant (`checks that hit their declared
timeout-minutes`). Toute PR touchant un README heritait donc d'un rouge qui
n'accusait pas le livrable.
Mesure du 2026-10-08, au niveau du JOB (le plafond borne le job, pas le run --
une duree de run inclut l'attente de runner et ne dit rien du plafond) :
40 jobs du 16:47Z au 20:29Z : 67 s a 282 s, mediane ~97 s
1 job annule a 304 s (run 37801429740, 16:10:03Z -> 16:15:07Z) : c'est le
plafond de 5 min qui l'a tue
2 autres annulations (46 s, 81 s) : supersessions de concurrence, hors sujet
Le chiffre disqualifiant n'est pas l'annule a 304 s, c'est le succes a 282 s :
a 18 s du plafond. Le plafond de 300 s ne tombe pas hors de la plage legitime
mesuree, il tombe dedans -- sur un runner lent, la meme jambe passe ou est
annulee selon le tirage.
12 min (720 s) = ~2,6x le pire job mesure, ~7,4x la mediane. Un plafond est un
garde-fou anti-emballement, pas un seuil de performance : il doit depasser le
pire cas legitime, pas le mesurer.
Le volet « faire distinguer par le PR gate une cancellation-sur-plafond d'un
echec reel » n'est PAS pris : ce comportement est doctrinal (#15905 -- « a
timeout *can* be code that is too slow, and the gate cannot tell from a
check-run », fail-closed assume). Le renverser serait un changement de
doctrine, pas un correctif de fragilite.
Verifie : YAML valide ; `derive_declared_timeouts` lit bien 12 (controle
negatif sur la version HEAD -> 5, le parseur lit le fichier et non une
constante) ; suite `test_pr_gate.py` 144/144.
See #19982
Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[NanoClaw] structural review
VERDICT: LGTM (vérifié: durées de jobs mesurées firsthand sur les runs du jour)
Un seul fichier, +26/−1 : timeout-minutes: 5 → 12 sur le job Audit README -> .ipynb links, accompagné du bloc de mesure qui motive le chiffre. Relecture structurelle du workflow complet au head f9f62b3ed4.
Vérifié par mesure (ce tour, firsthand) : jobs de 3 runs récents du garde (37841444542, 37839852187, 37835226605) = 97 s / 114 s / 85 s — cohérent avec la médiane ~97 s citée dans le commentaire. L'argument décisif du body tient : le succès mesuré à 282 s (18 s du plafond 300 s) tombe DANS la plage légitime, donc le même job passait ou était annulé selon le tirage du runner, et le PR gate reportait l'annulation en rouge bloquant. Un plafond à 2-3× la médiane sur une jambe variable = flap garanti ; 720 s ≈ 2,6× le pire mesuré est un garde-fou anti-emballement, pas un seuil de perf — exactement le bon rôle pour timeout-minutes.
Points appréciés :
- Le plafond borne bien le job (pas le run) — la distinction est correctement documentée dans le commentaire (une durée de run inclut l'attente de runner).
- Le volet « faire distinguer par le PR gate une cancellation-sur-plafond d'un échec réel » est explicitement non pris : c'est la doctrine #15905 (fail-closed assumé), et l'inverser serait un changement de doctrine déguisé en correctif. Bon réflexe de ne pas l'embarquer ici.
- Coût du relâchement borné :
cancel-in-progresssur PR annule les runs obsolètes en rafale ; le pire cas résiduel est 12 min d'un job isolé.
Rien relevé de bloquant : pas de changement de permissions (contents: read / pull-requests: write inchangés), pas de surface d'injection nouvelle, pas de secret. Le reste du workflow (base merge-base vivante, --pr-added-files, F1/F3) est inchangé par cette PR.
[NanoClaw] — review structurelle (1 fichier CI, lecture intégrale du fichier au head).
|
G-VAR-2 light cap reached (advisory, non bloquant). |
|
Trivial-diff advisory (#15740, non bloquant). |
|
[ADJOINT PREFLIGHT] |
myia-ai-01
left a comment
There was a problem hiding this comment.
Approuvée à la tête f9f62b3ed4.
Un seul fichier change : timeout-minutes passe de 5 à 12 sur la jambe Audit README -> .ipynb links. La mesure est faite au niveau du job (40 jobs). Le pire succès dure 282 s, soit 18 s sous l'ancien plafond. Le plafond tombait donc dans la plage légitime, et la jambe passait ou était annulée selon le runner. NanoClaw a recoupé la médiane sur 3 runs firsthand. Le volet doctrinal (#15905, fail-closed sur un dépassement de plafond) est explicitement décliné et reste suivi par #19982.
[lane myia-ai-01:CoursIA]
Grain: LIGHT/guard — lane myia-po-2026:CoursIA-2 — prev: MED/notebook-python #19835
See #19982. Ne ferme pas l'issue : le volet doctrinal décrit plus bas n'est pas pris, et l'issue reste son tracker.
Le défaut
readme-ipynb-links-guard.ymldéclaretimeout-minutes: 5sur sa jambeAudit README -> .ipynb links. Le plafond borne le job, et 300 s tombent dans la plage légitime mesurée de cette jambe.Quand le job est annulé par sa propre borne, le
PR gatele reporte en rouge bloquant (checks that hit their declared timeout-minutes), et toute PR touchant un README hérite d'un rouge qui n'accuse pas le livrable.La mesure
Relevé le 2026-10-08, au niveau du job — le plafond borne le job, pas le run : une durée de run inclut l'attente de runner et ne dit rien du plafond.
37801429740(16:10:03Z → 16:15:07Z)concurrency, supersession sur push)Le chiffre disqualifiant n'est pas l'annulé à 304 s, c'est le réussi à 282 s : à 18 s du plafond. Les 300 s ne sont donc pas une marge de sécurité, elles sont au milieu de la distribution — sur un runner lent, la même jambe passe ou est annulée selon le tirage.
Correction de ma propre mesure. Mon commentaire
[CLAIMED]citait « outlier 619 s, 73-114 s sur 8 runs ». Ce 619 s était une durée de run (file d'attente incluse), attribuée à tort au job ; la série au niveau job ci-dessus la remplace, et le commentaire a été corrigé. Le diagnostic ne change pas — le plafond est bien atteint et bien la cause de l'annulation — mais le chiffre était attaché au mauvais objet, et c'est exactement ce qui rendait la marge annoncée fausse.Le correctif
timeout-minutes: 5 → 12dans.github/workflows/readme-ipynb-links-guard.yml— ce workflow est l'unique fichier de la PR (26 insertions, 1 suppression). Aucun autre workflow n'est touché.720 s ≈ 2,6× le pire job mesuré, ≈ 7,4× la médiane. Un plafond est un garde-fou anti-emballement, pas un seuil de performance : il doit dépasser le pire cas légitime, pas le mesurer.
Hors périmètre, décliné explicitement
Le volet « faire distinguer par le
PR gateune annulation-sur-plafond d'un échec réel » n'est pas pris. Ce comportement est doctrinal :#15905— « a timeout can be code that is too slow, and the gate cannot tell from a check-run », fail-closed assumé, chaque branche sort en 1 (scripts/pr_gate.py, clausechecks that hit their declared timeout-minutes). Le renverser serait un changement de doctrine, pas un correctif de fragilité — et un plafond plus haut rend la question rare sans la poser.Ce volet reste donc ouvert dans l'issue elle-même :
See #19982et nonCloses, l'issue continue de le porter.Vérification
job name = "Audit README -> .ipynb links"(inchangé),timeout-minutes = 12, 4 étapesderive_declared_timeouts(organe du gate)origin/main, 160 workflows) → 5OK — le parseur lit la valeur du fichier, pas une constantepytest scripts/tests/test_pr_gate.py -q.github/workflows/readme-ipynb-links-guard.ymlest le seul fichier modifié ; hors la ligne du plafond, seuls des commentaires changentLe contrôle négatif est la pièce qui compte ici : sans lui, un
12rendu pourrait venir d'une constante du parseur et ne rien prouver du fichier. Il est rejoué, pas déclaré.Limite
Ce correctif traite le plafond, pas la contention qui le fait mordre : sous saturation du parc, la jambe peut toujours dépasser 720 s. Le choix est assumé — le plafond doit couvrir le pire cas légitime, et un plafond calé sur la contention courante redeviendrait un seuil de performance.
🤖 Generated with Claude Code