You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(picker): base_inherited classe « cause sur main » un rouge d'infra que main ne porte pas — la lane est dissuadée du rejeu qui le répare #17154
pick_idle_grain.py déclare Scripts Tests (CPU)« imputé à la base — pas le vôtre, pas réparable par la lane — tâche COORDINATEUR » sur la foi d'une corroboration ≥ 2 lanes distinctes (règle #13545/#14537, implémentée autour de scripts/pick_idle_grain.py:2076 et exposée dans base_inherited).
Or main est vert sur cette jambe. La corroboration inter-lanes ne prouve pas une cause commune sur main ; elle prouve une cause commune, qui peut être une instabilité d'exécution.
Le second cas est déjà tracké (#16288, OPEN). Le premier ne l'est pas.
Conséquence mesurée, et pourquoi ce n'est pas cosmétique
Le libellé dit à la lane deux choses fausses dans ce cas :
« pas le vôtre » — vrai au sens du diff, mais la conséquence pratique est qu'aucune action n'est demandée ;
« pas réparable par la lane » — faux : un gh run rerun <run_id> --failed à tête constante lève le rouge. Vérifié le 2026-09-21 sur fix(#17066): Search-09d — retitrer 10 lectures uniformes (tranche 17) #17144 : après rejeu, le PR gate rend [pr-gate] settled: 81 check(s) green, et le seul rouge restant est le minuteur DWELL.
La lane est donc dissuadée du seul geste qui répare. Le rouge s'installe, la PR reste bloquée, et elle finit par remonter dans le red du picker comme grain de réparation — c'est-à-dire que le cycle suivant de la lane est consommé à re-découvrir un rouge qu'un rejeu aurait levé. C'est le mécanisme même du « résidu de vieilles PRs » que le prompt /continue décrit.
Cause précise dans l'organe
inherited est construit par nom de check sur ≥ 2 lanes distinctes. Aucune des deux mesures décisives n'est prise :
l'état du même check sur la tête de la branche par défaut (main) — mesurable, et ici concluant :
la nature du rouge (une mort de runner et un kill watchdog ne sont pas des verdicts de test).
Le commentaire du code assume d'ailleurs l'ambiguïté pour un cas voisin (#15764, ligne ~2096) : « la coexistence d'un constituant COUPÉ dans le rollup n'établit PAS la causalité ». Le même raisonnement s'applique ici : plusieurs PRs qui tombent ensemble n'établissent pas que la cause est sur main.
Correctif proposé
Avant de classer un nom de check en base_inherited, exiger en plus de la corroboration ≥ 2 lanes que le même check soit rouge sur la tête courante de main :
rouge sur main → base_inherited (formulation actuelle, correcte : cause sur la branche par défaut, réparateur unique = coordinateur) ;
vert sur main → infra d'exécution : classe distincte, avec le message et le geste adaptés — « rejeu de la jambe (gh run rerun <run_id> --failed), à tête constante, sans ré-armer DWELL ». Ne pas router vers le coordinateur, qui n'a rien à réparer.
Un seul appel gh api .../commits/<main-sha>/check-runs fournit la mesure.
Elle ne prétend pas que tous les base_inherited sont faux : seul le cas où main est vert est mesuré faux.
Elle ne chiffre pas l'étendue : je n'ai mesuré que les PRs de ma lane et trois de la liste de corroboration rendue par le picker. Aucun compte flotte n'est publié ici plutôt qu'un compte non mesuré.
Symptôme
pick_idle_grain.pydéclareScripts Tests (CPU)« imputé à la base — pas le vôtre, pas réparable par la lane — tâche COORDINATEUR » sur la foi d'une corroboration ≥ 2 lanes distinctes (règle #13545/#14537, implémentée autour descripts/pick_idle_grain.py:2076et exposée dansbase_inherited).Or
mainest vert sur cette jambe. La corroboration inter-lanes ne prouve pas une cause commune surmain; elle prouve une cause commune, qui peut être une instabilité d'exécution.Mesure firsthand (2026-09-21)
Scripts Tests (CPU)mainbf212573c0(run 35548767997, 00:46:41Z)successfailfailfailfailDeux annotations de check-run, tirées de deux PRs distinctes, montrent que les causes sont d'exécution, pas de code :
The self-hosted runner lost communication with the server. Verify the machine is running and has a healthy network connection.XDIST-WATCHDOG: zero octet emis pendant la fenetre (ni ligne ni fragment) -- le master etait vivant mais n'attendait pas du travail, signature #16288 ; kill du groupe de processus+XDIST-WATCHDOG: workers morts : gw3Le second cas est déjà tracké (#16288, OPEN). Le premier ne l'est pas.
Conséquence mesurée, et pourquoi ce n'est pas cosmétique
Le libellé dit à la lane deux choses fausses dans ce cas :
gh run rerun <run_id> --failedà tête constante lève le rouge. Vérifié le 2026-09-21 sur fix(#17066): Search-09d — retitrer 10 lectures uniformes (tranche 17) #17144 : après rejeu, lePR gaterend[pr-gate] settled: 81 check(s) green, et le seul rouge restant est le minuteurDWELL.La lane est donc dissuadée du seul geste qui répare. Le rouge s'installe, la PR reste bloquée, et elle finit par remonter dans le
reddu picker comme grain de réparation — c'est-à-dire que le cycle suivant de la lane est consommé à re-découvrir un rouge qu'un rejeu aurait levé. C'est le mécanisme même du « résidu de vieilles PRs » que le prompt/continuedécrit.Cause précise dans l'organe
inheritedest construit par nom de check sur ≥ 2 lanes distinctes. Aucune des deux mesures décisives n'est prise :main) — mesurable, et ici concluant :Le commentaire du code assume d'ailleurs l'ambiguïté pour un cas voisin (
#15764, ligne ~2096) : « la coexistence d'un constituant COUPÉ dans le rollup n'établit PAS la causalité ». Le même raisonnement s'applique ici : plusieurs PRs qui tombent ensemble n'établissent pas que la cause est surmain.Correctif proposé
Avant de classer un nom de check en
base_inherited, exiger en plus de la corroboration ≥ 2 lanes que le même check soit rouge sur la tête courante demain:main→base_inherited(formulation actuelle, correcte : cause sur la branche par défaut, réparateur unique = coordinateur) ;main→ infra d'exécution : classe distincte, avec le message et le geste adaptés — « rejeu de la jambe (gh run rerun <run_id> --failed), à tête constante, sans ré-armer DWELL ». Ne pas router vers le coordinateur, qui n'a rien à réparer.Un seul appel
gh api .../commits/<main-sha>/check-runsfournit la mesure.Ce que cette issue ne dit pas
mainreste correctement détectée par corroboration. Elle demande une garde supplémentaire, pas un remplacement.base_inheritedsont faux : seul le cas oùmainest vert est mesuré faux.Références
scripts/pick_idle_grain.py—inherited/base_inherited(≈ lignes 2076, 2616, 2625-2643)PR gaterouge par constituantcancelledest assigne comme grain reparable — 3e surface de #15726 #15763, fix(picker,#15763): un agregateur rouge par constituants coupes n'est plus assigne comme reparable #15764 — cas voisins où la causalité d'un agrégateur est explicitement refusée