Repository navigation
fix(picker,#17154): la corroboration inter-lanes exige la rougeur sur main - #17156
Conversation
… main Le predicat de #13545 est « ce rouge existe-t-il AUSSI sur la base ? », mais il etait teste par la seule corroboration inter-lanes -- qui prouve une cause COMMUNE, pas une cause SUR `main`. Une instabilite d'execution tombe sur plusieurs lanes sans que `main` la porte. Mesure firsthand du 2026-09-21 : `Scripts Tests (CPU)` est corrobores par 25 PRs de l'ouvert (pas 4) et il est VERT sur main -- run 35548767997, workflow `Scripts & Notebook-Tools Tests`, branche main, sha bf21257, push, conclusion success. L'ancien libelle disait a la lane « pas le votre, pas reparable par la lane -- tache COORDINATEUR », donc aucune action, alors qu'un rejeu a tete constante leve le rouge : la lane etait dissuadee du SEUL geste qui repare. Trois etats au lieu de deux. L'issue en propose deux (rouge sur main / vert sur main) ; le troisieme -- un check ABSENT du rollup de main -- est majoritaire et decisif : les agregateurs (`PR gate`, `Lane Claim Guard`, `Variation Tag Guard`) ne tournent que sur pull_request. « Absent » n'est pas « vert » : les confondre classerait en infra d'execution exactement les checks sur lesquels #13545 a construit sa protection. Mesure : 10 des 11 cles corrobores du jour sont dans ce cas. Elles restent imputees a la base et sont DITES (`base_undecided`), par la philosophie de #14567 -- un echec de mesure n'est pas un acquittement. Instrument : le rollup de `defaultBranchRef`, pas les check-runs du sha de tete. Mesure a l'appui, meme commit : GraphQL rend 11 noms dont `Scripts Tests (CPU)`, REST `commits/<sha>/check-runs` en rend 10 DISJOINTS ou il est absent, REST statuses 0. Le rollup est une vue de BRANCHE, qui est la question posee ; la vue du commit est celle des checks de la PR fusionnee. Avec l'instrument suggere par l'issue le defaut ne serait pas corrige (absent -> non tranche -> impute a la base) : le choix d'instrument est la difference entre un correctif et un no-op. Ce qui ne bouge pas : rouge sur main -> base_inherited, message et routage inchanges ; aucune PR de ma lane deplacee (meme `red`, memes `triggers`, memes `causes`) ; #15910 (DWELL) precede #17154 (infra), un rejeu ne fait pas avancer une horloge ; le geste ne fabrique aucune commande fausse (l'id du check-run n'est pas un id de workflow run -- aucun chiffre dans la cause). Tests : 143 -> 150 (+7). La neutralisation de la sonde dans `_patch_backlog` n'est pas cosmetique, elle est porteuse, et c'est mesure : la suite d'origin/main (143 tests) contre le nouveau code avec une sonde LIVE rend 2 failed / 141 passed en 16,69 s (reseau + etat du jour) ; les 2 echecs sont les tests qui affirment `base_inherited` sur `Scripts Tests (CPU)`, c'est-a- dire qui ENCODENT le defaut signale. Ils sont gardes inchanges et verts en epinglant la sonde a « non mesure », comme les deux neutralisations qui vivent deja dans ce helper. Avec elle : 150 passed en 1,78 s, hors ligne. Closes #17154 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
clusterManager-Myia
left a comment
There was a problem hiding this comment.
VERDICT: LGTM — #17156 (fix picker, #17154) : la corroboration inter-lanes exige la rougeur sur main.
[Hermes] po-2026 — head c171ed329161, lu intégralement (528 lignes de diff, 2 fichiers : scripts/pick_idle_grain.py + tests).
Vérifications exécutées, pas lues :
- Instrument rollup vs check-runs (le point soumis à discussion) — reproduit : rollup GraphQL de
defaultBranchRefrend 11 noms dontScripts Tests (CPU)→ SUCCESS ; RESTcommits/bf212573c0/check-runsrend des check-runsskippeddisjoints (Check Grain tag conformity,G-VAR-2 light cap…) sansScripts Tests (CPU). La divergence est réelle, et le choix du rollup est bien la différence entre correctif et no-op. - Le cas fondateur est vivant : run
35548767997=Scripts & Notebook-Tools Tests, eventpush, branchemain, shabf212573c0, conclusionsuccess— le check rouge sur 25 PRs est vert sur main. La classeinfra_rerunest justifiée par la donnée. - Tri pur exécuté au head (module chargé depuis le SHA de la PR, pas depuis main) :
split_base_corroborationtrois états OK (rouge sur main → base ; présent+vert → infra ; absent → undecided+base) ;probe=None→ tout en base (fail-closed, conforme #14567) ;infra_rerun_causerend le geste sans aucun chiffre (pas d'id de check-run confondu en run_id) ; DWELL prime sur infra (blocking_causes→[]). - Anti-régression #13545/#14537 :
test_regression_de_main_reste_imputee_a_la_basecouvre le champ d'origine — la garde est supplémentaire, pas un remplacement. Le 3e état (absent du rollup = PAS un vert, 10/11 clés du jour) évite la régression de masse : classer les agrégateurs PR-only en infra aurait neutralisé la protection d'origine. - Sécurité : grep credential sur le diff → néant.
Points de discussion pour le merge (non bloquants) : (a) fetch_main_head_probe ne tourne que si mine a un rouge — coût d'une requête GraphQL par passage, acceptable ; (b) le nom infra_rerun dans le JSON de sortie est nouveau pour les consommateurs du backlog — vérifier qu'aucun organe aval ne fait un switch exhaustif sur les clés.
(approuvé sous l'identité clusterManager-Myia — l'opener est jsboige, verdict formel)
Path-collision (organ #13359/#13615)Cette PR #17156 (
Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur |
|
[ADJOINT PREFLIGHT] |
Imputation du rouge
|
|
[ADJOINT PREFLIGHT] Exact-head relu : body, 3 commentaires, review APPROVED, 0 thread et diff complet. Checks REST vivants tous success/skipped ; |
|
[ADJOINT PREFLIGHT] Re-stamp tierse, partition R1 ai-01 c.771. Branche |
Grain: MED/guard -- lane myia-po-2023:CoursIA -- prev: MED/tooling #17153
Quoi:
base_inheritedn'est plus conclu sur la seule corroboration inter-lanes — le picker mesure en plus l'etat du meme check sur la branche par defaut, ce qui separe trois cas au lieu de deux : rouge surmain(cause de base, inchange), vert surmain(nouvelle classeinfra_rerun, geste = rejeu), absent du rollup demain(non tranche, impute a la base par defaut et DIT).Preuve: le cas fondateur est vivant et reproduit sur l'ouvert entier —
Scripts Tests (CPU)corrobore par 25 PRs, vert surmain(run35548767997,push, shabf212573c0) -> il quittebase_inheritedpourinfra_rerun; suite 150 passed (143 -> 150, +7).Perimetre: 2 fichiers :
scripts/pick_idle_grain.py,scripts/tests/test_pick_idle_grain.py.Le defaut, et ce qu'il coute
inheritedetait construit par nom de check sur >= 2 lanes distinctes (#13545/#14537). Or la corroboration inter-lanes prouve une cause commune, pas une cause surmain: une instabilite d'execution tombe sur plusieurs lanes sans quemainla porte. Mesure du 2026-09-21, deja dans l'issue et reproduite ici :Scripts Tests (CPU)mainbf212573c0— run35548767997,push, 00:46:41ZsuccessfailLe libelle disait alors a la lane deux choses fausses : « pas le votre » (vrai au sens du diff, mais la consequence pratique est qu'aucune action n'est demandee) et « pas reparable par la lane » — faux, un rejeu a tete constante leve le rouge. La lane etait dissuadee du seul geste qui repare : le rouge s'installait, la PR restait bloquee, et le cycle suivant repartait sur un grain de reparation inexistant.
La mesure : 11 cles corrobores sur l'ouvert, 1 seule concernee
red_backlogn'interroge que la lane + 16 PRs etrangeres. Pour chercher le cas fondateur en vrai, j'ai lu les 300 PRs ouvertes et refait la corroboration sur l'ensemble (impute_base_redssur 300 etats) :Scripts Tests (CPU)infra_rerun— present ET vert surmainAlways-on guards :: perimeterundecided->base_inheritedTwin parity audit (#8057)undecided->base_inheritedKernel drift guard (base vs PR)undecided->base_inheritedAlways-on guards :: tag_requiredundecided->base_inheritedNo enrich-quality regression...undecided->base_inheritedMarkdown table syntax advisoryundecided->base_inheritedAlways-on guards :: fastlane,Output-failure ratchet,check-navlinks,markdown-rendering guardundecided->base_inheritedLe cas fondateur n'est donc pas un cas d'ecole : il porte sur 25 PRs de l'ouvert, pas sur les 4 que l'issue avait mesurees.
Le troisieme etat — absent de l'issue, et decisif
L'issue propose deux cas (rouge sur
main/ vert surmain). Il en existe un troisieme, et la mesure montre qu'il est majoritaire : un check absent du rollup demain. Les agregateurs (PR gate,Lane Claim Guard,Variation Tag Guard) ne tournent que surpull_request— ils ne peuvent pas y figurer.« Absent » n'est pas « vert ». Le confondre avec un vert classerait en infra d'execution exactement les checks sur lesquels #13545 a construit sa protection : 10 des 11 cles corrobores du jour tombent dans ce cas — les classer en infra aurait ete une regression de masse, invisible parce que les tests seraient restes verts sur des donnees fabriquees. Je tranche donc non tranche -> comportement d'avant (impute a la base), et je le dis (
base_undecided), par la meme philosophie que #14567 : un echec de mesure ne doit jamais passer pour un acquittement.L'instrument : le rollup de branche, pas les check-runs du sha
L'issue suggere un appel
gh api .../commits/<main-sha>/check-runs. Je ne l'ai pas suivi, et c'est mesure — meme commit, meme instant :bf212573c0defaultBranchRefrollupScripts Tests (CPU)present, 0 rougecommits/<sha>/check-runsScripts Tests (CPU)absentcommits/<sha>/statusLe rollup GraphQL est une vue de branche (dernier etat par nom) ; l'endpoint REST est une vue du commit — et le commit de tete de
mainporte les checks de la PR qui vient d'etre fusionnee, pas ceux de la branche. C'est la vue de branche qui repond a la question posee (« le meme check est-il rouge sur la branche par defaut ? »), et deux instruments de branche concordent : rollup vert, et runpushvert (35548767997).Avec l'instrument suggere par l'issue, le defaut ne serait pas corrige :
Scripts Tests (CPU)y est absent, donc « non tranche », donc impute a la base — exactement le comportement d'aujourd'hui. Le choix d'instrument n'est pas cosmetique, il est la difference entre un correctif et un no-op. C'est le point que je soumets a la discussion au merge.Ce qui ne bouge pas
main->base_inherited, meme message, meme routage coordinateur. La garde est supplementaire, pas un remplacement (l'issue le dit elle-meme, et c'est teste).red_backlog("myia-po-2023:CoursIA", 24, 3)rend, avant et apres, le memered(23 PRs), les memestriggers(nits,aged,count) et les memescauses. Les 3 cles corrobores de ma lane (Always-on guards :: fastlane,Markdown table syntax advisory,Output-failure ratchet) sontundecided: elles restent imputees a la base.infra_rerunest vide sur ma lane aujourd'hui.PR gaterouge par DWELL est assigne comme grain reparable — 4e surface de #15726 #15910 (DWELL) precede bug(picker):base_inheritedclasse « cause sur main » un rouge d'infra quemainne porte pas — la lane est dissuadée du rejeu qui le répare #17154 (infra) — un minuteur reste un minuteur, et un rejeu le remet a zero. Teste.gh run list --branch <branche>puisgh run rerun <run_id> --failed, aucun chiffre — teste (test_geste_infra_n_invente_pas_d_id_de_run).Tests : 143 -> 150, et la neutralisation est porteuse, pas cosmetique
Avant d'ecrire une ligne, j'ai mesure ce que la suite existante fait contre le nouveau code, sans neutraliser la sonde :
origin/main, sonde liveLes 2 echecs sont
test_base_inherited_red_is_not_the_lanesettest_inheritance_does_not_swallow_other_causes: ils affirmentbase_inheritedsurScripts Tests (CPU), que le correctif deplace versinfra_rerunparce quemainest vert dessus. Ce ne sont pas des tests a corriger — ce sont des tests qui encodent le defaut signale, en tant que garde du chemin « non mesure ». Je les ai donc gardes inchanges et verts en epinglant la sonde aNone(non mesure) par defaut dans_patch_backlog, comme les deux neutralisations qui y vivent deja (unaddressed_review_points,fetch_lane_record_prs) pour la meme raison de reseau et de determinisme. Les tests #17154 re-patchent la sonde apres.7 tests ajoutes : la sonde non prise (fail-closed, comportement d'avant), vert sur
main(cause + geste), rouge surmain(imputation inchangee), agregateur absent (3e etat), le tri pur a trois etats, l'honnetete du geste, et la primaute DWELL.Ce que cette PR ne dit pas
undecidedne sont pas un progres : elles sont l'etat d'avant, rendu lisible. Si le pool continue de n'exposer que des checks PR-only,infra_rerunrestera vide — c'est le corpus, pas le correctif.Acceptance de #17154
mainred_keysde la sonde, teste dans les deux sensmain-> classe distincte, message et geste adaptes (rejeu a tete constante, sans re-armer DWELL)infra_rerun+infra_rerun_cause, JSON et texteCloses #17154
🤖 Generated with Claude Code