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
picker: un PR gate rouge par DWELL est assigne comme grain reparable — 4e surface de #15726 #15910
Un PR gate rouge par DWELL (plancher de 120 min, aucun check fils en echec) est assigne a une lane comme grain de reparation en premiere action. La lane brule son cycle a chercher dans son diff un defaut qui n'y est pas — et qui n'existe pas : la cause est un minuteur, que seul l'ecoulement du temps leve.
C'est la quatrieme surface du meme mecanisme que #15726 (apres #15748, #15763 et #15769). #15763 la nomme et la met explicitement hors de son perimetre :
« Il ne traite pas non plus le DWELL — l'autre cause non-reparable qu'un PR gate rouge peut porter (un minuteur, pas un defaut). pr_gate.py la phrase deja correctement dans son message ; la rendre lisible cote picker demande de lire le texte du check-run, pas sa conclusion. A traiter separement. »
DWELL -- tete du 2026-09-13T03:45:13Z, 8 min -- ... reste 112 min
0
Ce que le picker a rendu (sortie 0) :
GRAIN DU CYCLE -- lane myia-po-2024:CoursIA : reparer ses propres PRs.
Motif : la lane porte 3 PR(s) bloquee(s) simultanees (seuil 3).
#15888 ouverte depuis 2 h -- ...
check requis en echec : PR gate
#15902 ouverte depuis 1 h -- ...
check requis en echec : PR gate
#15895 ouverte depuis 1 h -- ...
check requis en echec : PR gate
Et, dans la meme sortie :
ROUGE IMPUTE A LA BASE -- pas le votre, pas reparable par la lane :
- PR gate : organe non lisible sur #15866, #15869, #15877, #15886, #15887, #15888
-- pas pu trancher, le rouge RESTE a la lane
Le controle negatif est dans la meme journee. Le plancher de #15888 est ecoule a 03:43:55Z ; un gh run rerun <run gate> (pas un push — il ne cree pas de tete) a rendu success immediatement, et mergeStateStatus est passe BLOCKED -> CLEAN. Sur la seconde execution du picker, #15888 a disparu de la liste « organe non lisible » (#15866 y a disparu aussi, un autre plancher ayant expire entre-temps). Le seul changement etait l'ecoulement du temps : la liste se vide toute seule.
Le mecanisme, ligne a ligne
AGGREGATOR_CHECK_NAMES = {"PR gate"} (l.1093) fait de PR gate un agregateur.
Pour un agregateur, failed_check_keys (l.1224-1242) ne rend pas le nom du check mais les organes nommes par la banniere ::error::Organes bloquants en echec : ..., lue par fetch_check_organs (l.1196-1221) via _ORGAN_BANNER_RE (l.1097).
Un DWELL n'a aucun organe en echec, donc aucune banniere : fetch_check_organs rend [] (l.1214-1221), et failed_check_keys rend [] pour cet agregateur. Le fail-closed de l.1230-1232 est correct dans son intention (« un agregateur ne peut pas corroborer sur la seule foi de son nom ») mais il ne distingue pas « je n'ai pas pu lire » de « il n'y avait rien a lire ».
Consequence 1 — la ligne « organe non lisible … le rouge RESTE a la lane » (print_base_reds, l.1885). Le message est litteralement vrai et semantiquement faux : l'absence de banniere est le signal, pas une panne d'instrument.
Consequence 2 — blocking_causes compte le FAILURE requis comme reparable par la lane, donc la PR entre dans red et le declencheur count (« rouges simultanees », l.2010, seuil RED_COUNT_DEFAULT) fait basculer tout le cycle sur une reparation inexistante. Trois PRs poussees dans la meme fenetre de 2 h suffisent a declencher P0 par le seul minuteur de dwell.
Pourquoi ce n'est aucune des surfaces deja traitees
geste de la lane ; ici le plancher court normalement
pr_gate.pydit deja le bon verdict — <pr-gate> DWELL -- tete du ..., N min -- plancher 120 min, reste M min (merge_dwell.py, l.142-148), et le rend dans l'annotation du check-run. Le texte existe, il est date, il porte l'echeance. Le picker ne le consomme pas.
Le precedent, dans le picker lui-meme
file_saturation (#12830) est exactement la meme forme : un troisieme etat de mergeStateStatus: BLOCKED qui n'est pas un rouge reparable, diagnostique comme tel (l.1387-1398, avec son geste « commenter la PR + --ignore-red ») et distingue des rouges de substance. Le DWELL demande la meme chose — un quatrieme etat, avec l'echeance pour information au lieu d'un geste de reparation.
Acceptance
Un PR gate requis rouge dont l'annotation porte un verdict DWELL est classe NON REPARABLE par la lane et auto-resolvant, avec l'echeance (tete + plancher) citee dans la sortie.
Il n'est plus rapporte comme « organe non lisible » : l'absence de banniere d'organe sur un DWELL est un signal, pas une panne de mesure.
Fail-closed dans le bon sens : des qu'un constituant porte un vrai rouge (FAILURE/ACTION_REQUIRED/ERROR), la PR reste reparable par la lane et compte dans le seuil. On ne dispense jamais d'une reparation reelle.
Un agregateur ne peut pas etre sa propre preuve de DWELL sur la seule foi de son nom : la lecture vient de l'annotation, jamais de la conclusion.
Les tests existants de scripts/tests/test_pick_idle_grain.py ne regressent pas.
Le fichier scripts/pick_idle_grain.py est tenu par trois PRs ouvertes au moment de la redaction (#15764 ai-01, #15778 po-2023, #15813 po-2023) : un fix de cette surface doit etre sequence apres elles, ou porte par le titulaire du claim.
Mesure faite au 2026-09-13T04:05Z — lane myia-po-2024:CoursIA.
Le defaut
Un
PR gaterouge par DWELL (plancher de 120 min, aucun check fils en echec) est assigne a une lane comme grain de reparation en premiere action. La lane brule son cycle a chercher dans son diff un defaut qui n'y est pas — et qui n'existe pas : la cause est un minuteur, que seul l'ecoulement du temps leve.C'est la quatrieme surface du meme mecanisme que #15726 (apres #15748, #15763 et #15769). #15763 la nomme et la met explicitement hors de son perimetre :
Cette issue est ce traitement separe.
Mesure firsthand — 2026-09-13, cycle
myia-po-2024:CoursIATrois PRs de la lane, toutes verts hors
PR gate, toutes en DWELL :check-runscomplet)PR gateDWELL -- tete du 2026-09-13T01:43:55Z, 9 min -- plancher 120 min, reste 111 minDWELL -- tete du 2026-09-13T02:32:00Z, 8 min -- ... reste 112 minDWELL -- tete du 2026-09-13T03:45:13Z, 8 min -- ... reste 112 minCe que le picker a rendu (sortie 0) :
Et, dans la meme sortie :
Le controle negatif est dans la meme journee. Le plancher de #15888 est ecoule a
03:43:55Z; ungh run rerun <run gate>(pas un push — il ne cree pas de tete) a rendusuccessimmediatement, etmergeStateStatusest passeBLOCKED -> CLEAN. Sur la seconde execution du picker, #15888 a disparu de la liste « organe non lisible » (#15866 y a disparu aussi, un autre plancher ayant expire entre-temps). Le seul changement etait l'ecoulement du temps : la liste se vide toute seule.Le mecanisme, ligne a ligne
AGGREGATOR_CHECK_NAMES = {"PR gate"}(l.1093) fait dePR gateun agregateur.failed_check_keys(l.1224-1242) ne rend pas le nom du check mais les organes nommes par la banniere::error::Organes bloquants en echec : ..., lue parfetch_check_organs(l.1196-1221) via_ORGAN_BANNER_RE(l.1097).fetch_check_organsrend[](l.1214-1221), etfailed_check_keysrend[]pour cet agregateur. Le fail-closed de l.1230-1232 est correct dans son intention (« un agregateur ne peut pas corroborer sur la seule foi de son nom ») mais il ne distingue pas « je n'ai pas pu lire » de « il n'y avait rien a lire ».print_base_reds, l.1885). Le message est litteralement vrai et semantiquement faux : l'absence de banniere est le signal, pas une panne d'instrument.blocking_causescompte le FAILURE requis comme reparable par la lane, donc la PR entre dansredet le declencheurcount(« rouges simultanees », l.2010, seuilRED_COUNT_DEFAULT) fait basculer tout le cycle sur une reparation inexistante. Trois PRs poussees dans la meme fenetre de 2 h suffisent a declencher P0 par le seul minuteur de dwell.Pourquoi ce n'est aucune des surfaces deja traitees
cancelledCANCELLEDFAILURE, avec un motif ecritpr_gate.pyphrase mal un depassement de timeoutpr_gate.pyphrase juste ; c'est le picker qui ne lit pas son texteoutput.title = nullsur conclusion en echecupdate-branchpr_gate.pydit deja le bon verdict —<pr-gate> DWELL -- tete du ..., N min -- plancher 120 min, reste M min(merge_dwell.py, l.142-148), et le rend dans l'annotation du check-run. Le texte existe, il est date, il porte l'echeance. Le picker ne le consomme pas.Le precedent, dans le picker lui-meme
file_saturation(#12830) est exactement la meme forme : un troisieme etat demergeStateStatus: BLOCKEDqui n'est pas un rouge reparable, diagnostique comme tel (l.1387-1398, avec son geste « commenter la PR +--ignore-red») et distingue des rouges de substance. Le DWELL demande la meme chose — un quatrieme etat, avec l'echeance pour information au lieu d'un geste de reparation.Acceptance
PR gaterequis rouge dont l'annotation porte un verdictDWELLest classe NON REPARABLE par la lane et auto-resolvant, avec l'echeance (tete + plancher) citee dans la sortie.count(feat(genai,#15597): 04-15 MERT2 embeddings — similarite, retrieval FullSong, sondes lineaires (livrable 2/3) #15888/docs(lean,#15892): exposer le chemin de découverte prover de StableMarriage (sans changement mathématique) #15895/feat(genai,#15597): 04-16 SheetSage2 — transcription audio vers partition ABC (livrable 3/3) #15902 n'en declenchaient aucun autre).FAILURE/ACTION_REQUIRED/ERROR), la PR reste reparable par la lane et compte dans le seuil. On ne dispense jamais d'une reparation reelle.scripts/tests/test_pick_idle_grain.pyne regressent pas.Note de sequencement
Le fichier
scripts/pick_idle_grain.pyest tenu par trois PRs ouvertes au moment de la redaction (#15764ai-01,#15778po-2023,#15813po-2023) : un fix de cette surface doit etre sequence apres elles, ou porte par le titulaire du claim.Mesure faite au 2026-09-13T04:05Z — lane
myia-po-2024:CoursIA.