Skip to content

pick_idle_grain.py doit produire le cache v2 (open-prs-v2) des PRs ouvertes — enumeration complete au lieu de gh pr list --limit 200 #21757

Open

Description

@jsboige

Grain: MED/tooling — lane myia-ai-01:CoursIA-2 — prev: MED/guard #21749

Part of #21742

Objet

Le côté producteur du cache des PRs ouvertes : scripts/pick_idle_grain.py ecrit encore un cache héritage (liste JSON nue) dans CHECK_LANE_CLAIM_OPEN_PRS_JSON, alors que le lecteur (corrige par #21749) attend un enveloppe v2 qui porte la complétude de l'énumération.

Les deux moitiés ne parlent plus la même langue : après le merge de #21749, le cache produit par le tapis est lu comme absent.

Le défaut, mesuré

1. La liste est tronquée à la source. _build_open_prs_cache_for_belt() (scripts/pick_idle_grain.py:2496) fait :

gh pr list --state open --json number,title,headRefName,body,files,additions,deletions --limit 200

Mesure du 2026-10-21 sur jsboige/CoursIA : 362 PRs ouvertes, 200 dans la fenêtre → 162 PRs invisibles. Le cache écrit dans le tempfile porte donc une liste tronquée, et aucune marque de cette troncature.

2. Le lecteur v2 refuse ce cache — et le refuse à raison. #21749 introduisit _read_open_prs_cache() : une liste nue (format héritage) est traitée comme absente (elle ne porte aucune preuve de complétude), un cache v2 marqué complete: false lève OpenPrsIncompleteError → verdict UNKNOWN (fail-closed). C'est le comportement voulu : un cache tronqué ne doit pas pouvoir rendre un « Path is free ».

3. Conséquence : l'optimisation de #19643 est perdue. L'intérêt du cache de session était de fetch-er la liste une fois par passe de tirage et de la partager à tous les candidats (~6 s x N, N = 40+ candidats). Après #21749, chaque invocation de check_lane_claim.py retombe sur sa propre énumération complète (GraphQL paginé + refetch REST des PRs à liste de fichiers plafonnée) : N énumérations complètes au lieu d'une.

4. Le tapis a, lui aussi, un usage direct de cette liste tronquée. Au-delà du partage de cache, draw_unclaimed() s'appuie sur la liste des PRs ouvertes pour remplacer un candidat déjà couvert par une PR ouverte (#16589). Cette vérification-là consomme la liste tronquée : une PR ouverte hors fenêtre ne remplace pas son candidat, et la lane peut poser un claim sur un chemin déjà tenu — la classe exacte de collision que #21742 ferme côté lecteur.

Attendu

scripts/pick_idle_grain.py doit produire le format v2 (open-prs-v2), en réutilisant l'énumération complète déjà écrite par #21749 plutôt qu'en dupliquant un gh pr list --limit 200 :

# Attendu Critère
1 Le cache écrit par le tapis porte l'enveloppe v2 (format, complete, count, prs) _read_open_prs_cache() de #21749 le lit sans lever
2 L'énumération est complète (pagination GraphQL jusqu'à hasNextPage: false, + refetch REST des PRs dont la liste de fichiers est plafonnée) complete: true n'est écrit que si la complétude est établie, pas supposée
3 Une énumération incomplète (délai, plafond franchi, erreur) écrit complete: false avec son motif — jamais complete: true par défaut le lecteur lève OpenPrsIncompleteError → verdict UNKNOWN, jamais un « Path is free »
4 La vérification « PR ouverte couvre le candidat » (#16589) consomme la même énumération complète aucun candidat qui est couvert par une PR hors fenêtre ne peut être tiré
5 Aucun fetch dupliqué : le tapis réutilise l'énumération de #21749 au lieu de lancer son propre gh pr list une seule énumération par passe de tirage, pas une par candidat
6 Écriture atomique du cache (fichier temporaire + os.replace) un lecteur concurrent (le tapis appelle l'organe en parallèle) ne lit jamais un fichier à moitié écrit

Contrainte de séquence

Ne pas implémenter avant le merge de #21749 (arbitrage du coordinateur, DM du 2026-10-21) : le lecteur v2 doit exister avant qu'un producteur v2 soit écrit, sinon le contrat n'est pas testable de bout en bout.

Au moment d'éditer scripts/pick_idle_grain.py, vérifier d'abord l'occupation du chemin :

python scripts/check_lane_claim.py 21742 --lane myia-ai-01:CoursIA-2 --paths scripts/pick_idle_grain.py

Si une des PRs ouvertes le tient encore, attendre ; ne pas editer un chemin tenu.

Vérification attendue

Notes

Activity

  1. jsboige commented on Oct 21, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-ai-01:CoursIA-2 -- paths: scripts/pick_idle_grain.py, scripts/tests/test_pick_idle_grain.py

    Grain: MED/tooling — lane myia-ai-01:CoursIA-2 — prev: MED/guard #21749

    Issue fille de #21742 (côté producteur du cache des PRs ouvertes), ouverte à la demande du coordinateur (DM du 2026-10-21, point 3).

    Séquence : l'implémentation attend le merge de #21749 (le lecteur v2 doit exister avant qu'un producteur v2 soit écrit). Au moment d'éditer, vérifier l'occupation du chemin avec python scripts/check_lane_claim.py 21757 --lane myia-ai-01:CoursIA-2 --paths scripts/pick_idle_grain.py : si une PR ouverte le tient encore, attendre.

    Rien n'est modifié sur cette branche dans ce cycle : le claim est posé pour la suite, la livraison se fera après le merge de #21749.

  2. added a commit that references this issue on Oct 21, 2026
  3. myia-ai-01 commented on Oct 26, 2026

    @myia-ai-01
    Collaborator

    [CLAIMED] lane myia-ai-01:CoursIA-2 -- cache v2 des PRs ouvertes produit par le tapis, enumeration complete sans gh pr list --limit 200 (pose au dispatch par ai-01, tour du 26/10 12:33Z)

    (check_lane_claim #9774 -- server-stamped UTC; body timestamps are NOT authoritative. Release with [RELEASED] when your PR lands.)

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions