Repository navigation
Picker : mode tapis roulant -- servir les issues par date de derniere visite, sans loterie ni refus #18832
Description
Activity
[CLAIMED] lane myia-ai-01:CoursIA-2 -- mode --belt du picker, pose au dispatch par le coordinateur -- paths: scripts/pick_idle_grain.py, scripts/tests/test_pick_idle_grain*.py, scripts/tests/test_belt.py
Complément de spec (coordinateur, 02/10) : le but du tapis roulant est la clôture, pas la visite.
- L'arithmétique de référence. Environ 100 grains par jour pour environ 400 issues ouvertes : une file stricte repasse sur chaque issue tous les 4 jours environ, et aucune issue ne reçoit un deuxième grain avant que toutes aient reçu le premier. La plupart des issues sont à moins de 3 PRs de pouvoir être fermées : en deux semaines, le pool doit avoir fondu. Aujourd'hui, un EPIC ouvert sans fin approche les 100 grains pendant que d'autres issues ne sont visitées qu'une fois toutes les trois semaines.
- Une visite vise la fermeture. Le grain pris en tête de file porte sur ce qui manque à l'acceptance de l'issue. Si l'issue est déjà livrée, la visite est son dossier de fermeture (
[CLOSURE PREFLIGHT]), pas un grain de plus. Un EPIC est visité comme les autres issues : un grain à son tour, puis il repart en queue. - Ajout à l'acceptance : le mode
--belt --reportaffiche deux nombres, l'écart maximal (en jours) depuis la dernière visite sur les issues ouvertes, et le nombre d'issues fermées sur les 7 derniers jours. Ce sont les deux chiffres qui diront si le tapis tourne.
Rien d'autre : pas de poids, pas de priorité par série.
- added a commit that references this issue
on Oct 2, 2026 - added a commit that references this issue
on Oct 2, 2026 [INFO] candidate-delivered — tirage du cycle myia-po-2023:CoursIA (04/10 ~18:30Z). Preuve firsthand (
gh pr list --state all --search "18832 in:body") : la substance de l'issue est livrée par QUATRE PRs mergees — #18836 (mode--beltlui-meme, 02/10 18:33Z), #18882 (elargissement fenetre last_delivery en mode belt + fusion rappel, 02/10 22:50Z), #18897 (selection des lanes Vibe via--belt --json, 03/10 03:29Z) et #18870 (/continuesert le tapis par defaut, 04/10 14:19Z). Le complement de spec du coordinateur (02/10, arithmetique de cloture) est couvert par #18870. Reste ouvert potentiellement : la mesure d'adoption/cloture (le « but est la cloture »), qui est un suivi coordinateur, pas un grain executable par une lane worker. Je rends la main — la fermeture reste au coordinateur/adjoint (#15069).[CLAIMED] lane myia-ai-01:CoursIA -- le tapis avance au claim, pas au merge (mandat user du 04/10) : un [CLAIMED] et la creation d'une sous-issue comptent comme une visite -- paths: scripts/pick_idle_grain.py, scripts/tests/test_pick_idle_grain_belt.py
- added a commit that references this issue
on Oct 5, 2026 - addedcandidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)Referenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
on Oct 5, 2026 [CLAIMED] lane myia-ai-01:CoursIA-2 — organe d'equilibre du service : part courant (< 7 j) / tapis par lane, plafond courant 1/3 valide par le user le 07/10 -- paths: scripts/coordination/belt_service_balance.py, scripts/tests/test_belt_service_balance.py
- added a commit that references this issue
on Oct 7, 2026 - added a commit that references this issue
on Oct 8, 2026 - added a commit that references this issue
on Oct 8, 2026 - added a commit that references this issue
on Oct 8, 2026 [FINDING]
base_unresolvedn'est pas scopé à la lane — l'avis « le rouge RESTE a la lane » est adressé a une lane qui ne peut rien y reparerMesure du cycle 9 (2026-10-09T05:2xZ), lane
myia-po-2024:CoursIA, run--beltsurorigin/main@98a4629e94d. Aucune reparation proposee ici : ce ticket est le foyer du mode tapis roulant, le fichier est deja sous deux PRs ouvertes d'autres lanes (#19913, #19594) et le correctif appartient au proprietaire du chemin.Ce qui a ete imprime
ROUGE IMPUTE A LA BASE -- pas le votre, pas reparable par la lane : - PR gate : organe non lisible sur #20022, #20023, #20025, #20027 -- pas pu trancher, le rouge RESTE a la lane (relancer le run ou lire l'annotation du check-run avant d'invoquer la base).Les quatre PRs nommees ne sont pas de cette lane — deux sont d'autres machines
Attribution faite par le tag
Grain:(jamais par auteur — comptejsboigepartage, piege L721), lu firsthand :PR tag Grain:#20022 lane myia-po-2027:CoursIA-2#20023 lane myia-po-2025:CoursIA#20025 lane myia-po-2027:CoursIA-2#20027 lane myia-po-2025:CoursIAAucune n'est
myia-po-2024:CoursIA, et deux viennent de machines differentes. Une lane qui obeirait a la consigne — relancer le run, lire l'annotation — agirait sur les PRs d'autrui ; et le meme bloc affirme deux lignes plus haut « pas le votre, pas reparable par la lane ».La cause, dans le source
pick_idle_grain.py:3826— le bloc ne s'execute que si ma lane a un check en echec :if any(_has_failed_check(states.get(pr["number"])) for pr in mine)::3827-3829— il echantillonne ensuite les PRs etrangeres :sample = sorted(others, ...)[:16],foreign_states = fetch_pr_states(...).:3831-3834— ces etats etrangers sont passes aimpute_base_reds(..., unresolved_out=unresolved_aggregates, ...):unresolved_aggregatesse remplit donc depuisothers, pas depuismine.:4002—"base_unresolved": [{"check": name, "prs": sorted(nums)} for name, nums in sorted(unresolved_by_name.items())]:4043-4047—print_base_inheritedimprime ces numeros sous « le rouge RESTE a la lane (relancer le run ou lire l'annotation du check-run) ».
Le retrait voisin #15910 (
:3928-3939) a deja rencontre ce probleme pour le cas DWELL, et son commentaire dit la portee voulue :« Portee volontairement limitee aux PRs de la lane : lire le DWELL d'une PR etrangere couterait jusqu'a 16 lectures d'annotation sur l'echantillon de corroboration, pour une surface qui ne decide rien pour cette lane. »
Ce correctif a retire les agregateurs tranches par DWELL de
unresolved_aggregates(:3936-3939) — le residu (agregateur reellement illisible) reste, lui, alimente par l'echantillon etranger. C'est exactement le symptome que #15910 decrit — « deux lignes qui se contredisent, et la lane repart chercher » — sur la population qui n'a pas ete scopee.Pourquoi ce n'est pas un simple confort
L'intention de #14567 est juste : un agregateur illisible ne doit pas se lire comme un acquittement. Mais le titre du bloc (« pas le votre, pas reparable par la lane ») et la phrase finale (« RESTE a la lane ») sont contradictoires des que la ligne porte un numero etranger, et c'est la phrase finale qu'une lane lit comme une consigne. Le cout est un cycle brule sur une PR d'une autre machine.
Correctif suggere (borne)
Filtrer
unresolved_aggregatessur{pr["number"] for pr in mine}avant de construirebase_unresolved— exactement la forme appliquee par #15910 pour le DWELL. Si un agregateur etranger illisible merite de rester visible, l'imprimer sous un libelle distinct (« hors lane — information, aucune action »), jamais sous « RESTE a la lane ».Test possible : une fixture ou
mineporte un check en echec et ou l'echantillon etranger contient une PR a l'agregateur illisible → asserter qu'aucun numero etranger n'apparait dansbase_unresolved.Ce que ce commentaire ne pretend pas
Je n'ai pas verifie si ce facet est deja couvert — #19907 porte le budget de sondes de livraison (l'urne), #15910 et #14567 les deux moities du mecanisme
base_*. Ceci est la troisieme population du meme bloc :base_unresolvedalimente par l'echantillon etranger. A rattacher si un doublon existe deja.[CLOSURE PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
issue: 18832
verdict: KEEP
acceptance:- la file suit la date de derniere visite, une issue jamais servie se classe par sa creation, une issue reclamee par une autre lane est sautee, un garde rouge ne vide pas le resultat -> PR feat(picker,#18832): mode --belt (tapis roulant) -- servir les issues par date de derniere visite, sans loterie ni refus #18836 (mode --belt), mergee 2026-10-02T18:33:55Z, et PR fix(picker,#18866): elargir la fenetre last_delivery en mode --belt + fusionner le rappel rouge dans le JSON du tapis (v2, merge-base origin/main) #18882 (fenetre last_delivery elargie en mode belt), mergee 2026-10-02T22:50:29Z
- mesure dans le body de la PR : les 20 premieres issues de la file avec leur date de derniere visite, et trois lanes servies par trois issues distinctes -> PR feat(picker,#18832): mode --belt (tapis roulant) -- servir les issues par date de derniere visite, sans loterie ni refus #18836 (body de la PR)
- le passage de /continue au mode --belt par defaut se fait dans une PR separee une fois celle-ci mergee -> PR feat(harness,#18832): /continue sert le tapis par defaut -- plus de tirage pondere ni de repli EPIC maison #18870 (feat(harness,Picker : mode tapis roulant -- servir les issues par date de derniere visite, sans loterie ni refus #18832)), mergee 2026-10-04T14:19:28Z ; la selection des lanes Vibe par --belt --json est livree par chore(vibe,#18832): ouvrir la selection des lanes Vibe par le tapis (--belt --json, cle repair) #18897, mergee 2026-10-03T03:29:11Z
residue: waiver: 2026-10-09 -- le [FINDING] du 2026-10-09T05:05:30Z poses sur ce ticket (base_unresolved non scope a la lane : l'avis « le rouge RESTE a la lane » est adresse a une lane qui ne peut rien y reparer) n'a AUCUN porteur mesure ce jour : aucune issue ouverte ne traite base_unresolved, fix(picker,#19907): 3e surface de livraison (PR MERGEE <90j citant #N) #19913 (l'une des deux PRs ouvertes que le finding citait) a merge a 2026-10-09T10:14:34Z, et la seule PR restante ouverte sur le chemin (fix(picker,#19390-suite): bulk GraphQL pour settle_belt_head -- 15-30x speedup stall #19594) traite le stall c.1105-c.1113, pas ce defaut. Aucun enfant n'est nomme : ouvrir une issue est un geste de coordinateur, pas du secretaire. Le ticket reste donc ouvert comme foyer de ce finding.
open-prs: 0
comments-reviewed: 6
[/CLOSURE PREFLIGHT]
Constat (mesuré le 02/10)
Le tirage des grains (
scripts/pick_idle_grain.py) ne répartit plus le travail.Le tirage actuel est une loterie pondérée par une dizaine de facteurs doux, et plusieurs gardes peuvent refuser tout tirage. Le résultat est l'inverse de l'équilibre recherché.
Ce qui est demandé : un tapis roulant
Un mode
--beltdepick_idle_grain.py. Ce n'est pas un nouveau script : il réutilisefetch_pooletlast_delivery_per_issue, qui existent déjà.check_lane_claim.py).--grains Nen rend N, dans l'ordre. Le résultat est déterministe : pas de graine, pas de tirage.Aucun poids, aucun facteur de saturation, aucune urne dans ce mode.
Acceptance
/continueau mode--beltpar défaut se fera dans une PR séparée, une fois celle-ci mergée.