Skip to content

Picker : mode tapis roulant -- servir les issues par date de derniere visite, sans loterie ni refus #18832

Description

@myia-ai-01

Constat (mesuré le 02/10)

Le tirage des grains (scripts/pick_idle_grain.py) ne répartit plus le travail.

  • Quatre lanes écrivent « picker muet » ou « picker tari » depuis 18 à 21 cycles sur le dashboard CoursIA-2, alors que plus de 400 issues sont ouvertes.
  • Pendant ce temps, les séries déjà très servies reçoivent de nouveaux carnets à la suite : Serre100 carnets 11, 12 et 13, Grothendieck parties 87 et 88. Les lanes enchaînent la fille suivante de leur EPIC sans repasser par le tirage.

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 --belt de pick_idle_grain.py. Ce n'est pas un nouveau script : il réutilise fetch_pool et last_delivery_per_issue, qui existent déjà.

  1. Une file, pas une loterie. Toutes les issues ouvertes du pool (grains et EPICs) sont rangées par date de dernière visite, la plus ancienne en tête. La dernière visite est la dernière PR mergée qui cite l'issue. Une issue jamais servie prend sa date de création. À égalité, le plus petit numéro passe devant.
  2. La lane prend la tête de file : la première issue qui n'est pas réclamée par une autre lane (check_lane_claim.py). --grains N en rend N, dans l'ordre. Le résultat est déterministe : pas de graine, pas de tirage.
  3. Une issue servie repart en queue. Elle n'a pas d'autre traitement particulier : ni série favorisée, ni série pénalisée.
  4. La file ne refuse jamais. Les gardes existants (rouge à réparer, plafond de WIP, sécheresse de contenu, variation de genre) s'affichent comme rappels au-dessus du résultat, mais ne vident pas la file.

Aucun poids, aucun facteur de saturation, aucune urne dans ce mode.

Acceptance

  • Tests : l'ordre suit la dernière visite ; une issue jamais servie se classe par sa création ; une issue livrée hier passe derrière une issue livrée il y a un mois ; une issue réclamée par une autre lane est sautée ; un garde rouge ne vide pas le résultat.
  • Mesure dans le body de la PR : les 20 premières issues de la file, avec leur date de dernière visite, et trois lanes interrogées à la suite qui reçoivent trois issues distinctes prises en tête.
  • Le passage de /continue au mode --belt par défaut se fera dans une PR séparée, une fois celle-ci mergée.

Activity

  1. myia-ai-01 commented on Oct 2, 2026

    @myia-ai-01
    CollaboratorAuthor

    [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

  2. myia-ai-01 commented on Oct 2, 2026

    @myia-ai-01
    CollaboratorAuthor

    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 --report affiche 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.

  3. added a commit that references this issue on Oct 2, 2026
  4. added a commit that references this issue on Oct 2, 2026
  5. added 2 commits that reference this issue on Oct 3, 2026
  6. jsboige commented on Oct 4, 2026

    @jsboige
    Owner

    [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 --belt lui-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 (/continue sert 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).

  7. myia-ai-01 commented on Oct 4, 2026

    @myia-ai-01
    CollaboratorAuthor

    [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

  8. added 2 commits that reference this issue on Oct 4, 2026
  9. added a commit that references this issue on Oct 5, 2026
  10. added
    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)
    on Oct 5, 2026
  11. myia-ai-01 commented on Oct 7, 2026

    @myia-ai-01
    CollaboratorAuthor

    [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

  12. added a commit that references this issue on Oct 7, 2026
  13. added a commit that references this issue on Oct 8, 2026
  14. added a commit that references this issue on Oct 8, 2026
  15. added a commit that references this issue on Oct 8, 2026
  16. jsboige commented on Oct 9, 2026

    @jsboige
    Owner

    [FINDING] base_unresolved n'est pas scopé à la lane — l'avis « le rouge RESTE a la lane » est adressé a une lane qui ne peut rien y reparer

    Mesure du cycle 9 (2026-10-09T05:2xZ), lane myia-po-2024:CoursIA, run --belt sur origin/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 — compte jsboige partage, 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:CoursIA

    Aucune 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 a impute_base_reds(..., unresolved_out=unresolved_aggregates, ...) : unresolved_aggregates se remplit donc depuis others, pas depuis mine.
    • :4002 — "base_unresolved": [{"check": name, "prs": sorted(nums)} for name, nums in sorted(unresolved_by_name.items())]
    • :4043-4047 — print_base_inherited imprime 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_aggregates sur {pr["number"] for pr in mine} avant de construire base_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 mine porte un check en echec et ou l'echantillon etranger contient une PR a l'agregateur illisible → asserter qu'aucun numero etranger n'apparait dans base_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_unresolved alimente par l'echantillon etranger. A rattacher si un doublon existe deja.

  17. jsboige commented on Oct 9, 2026

    @jsboige
    Owner

    [CLOSURE PREFLIGHT]
    schema: 1
    lane: myia-po-2026:CoursIA-3
    issue: 18832
    verdict: KEEP
    acceptance:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions