Repository navigation
gate(closure): l'auteur d'un dossier est lu en GraphQL et compare a une liste en orthographe REST — une App de lane est refusee #21818
Description
Constat (mesuré firsthand le 2026-10-21 sur ai-01)
Le gate de fermeture (scripts/check_closure_dossier.py) lit l'auteur d'un commentaire en GraphQL (gh issue view --json comments), alors que le gate de prévalidation adjointe (scripts/check_adjoint_prevalidation.py) le lit en REST (gh api repos/<repo>/issues/<n>/comments). Les deux surfaces ne rendent pas le même login pour un acteur de type Bot :
Mesure directe (commentaire github-actions sur #21390, jsboige en jeton épinglé) :
| Surface | login |
type |
|---|---|---|
GraphQL (author { __typename login }) |
github-actions (sans suffixe) |
__typename = Bot |
REST (user) |
github-actions[bot] (avec suffixe) |
type = Bot |
Or ACCEPTED_DOSSIER_AUTHORS (scripts/gh_identity.py) est écrit en orthographe REST : coursia-lane-po-2026[bot]. Le gate de fermeture compare donc l'orthographe GraphQL à l'orthographe REST et refuse un dossier pourtant légitime.
Symptôme rapporté par la lane secrétaire (myia-po-2028:CoursIA-3, cycle 18, msg-20261021T115421-yhb5bd) :
comment author 'coursia-lane-po-2026' is not an accepted dossier author
Une App de lane est donc inutilisable pour le gate de fermeture, alors que son propre bucket REST est intact — alors même que le bucket REST du login partagé jsboige tombe à 0 en moins de 60 s après chaque reset horaire (enjeu #17437).
Effet de bord de la même divergence : _is_neutral_comment teste login.endswith("[bot]") pour ignorer les commentaires de bots ; sous l'orthographe GraphQL, ce test ne reconnaît jamais un bot, et un commentaire de bot posté après le dossier peut être lu comme une péremption du dossier.
Correction attendue
- Normaliser une seule fois, dans
scripts/gh_identity.py(point de passage unique, les deux gates y comparent l'auteur) : le login d'un acteur de typeBotest rendu en orthographe REST (login[bot]). - Exiger le type de l'acteur pour cette reconstruction :
__typename == "Bot"(GraphQL) outype == "Bot"(REST). Sans cette exigence, un compte utilisateur nommé comme le slug de l'App (coursia-lane-po-2026, sans suffixe) passerait le gate dès lors qu'on se contente d'ajouter la seconde orthographe à la liste. - Aligner la surface de lecture du gate de fermeture sur celle qui porte déjà l'orthographe et le type (REST), ou lire
author { __typename login }en GraphQL — dans les deux cas, passer par la normalisation unique.
Critères d'acceptation
- Un dossier posté sous une App de lane (
coursia-lane-po-2026[bot]) est accepté parscripts/check_closure_dossier.py(contrôle positif). - Un commentaire d'un compte utilisateur homonyme (
coursia-lane-po-2026,__typename = User/type = User) est refusé (contrôle négatif) : la reconstruction du suffixe ne doit dépendre que du type de l'acteur, jamais de la forme du login. - Non-régression des comptes humains :
jsboigereste accepté, un compte humain quelconque reste refusé. - La normalisation est exercised par les deux gates (l'un lit en REST, l'autre en GraphQL) sans duplication de la liste des auteurs acceptés.
Refs
- GitHub Apps par lane : les comptes machine sont bridés au tarif anonyme (60 req/h, GraphQL 0) et hors-limite CGU #17437 (Apps par lane), Le gate de Phase 4 n'accepte qu'UN auteur de dossier : troisieme plafond de debit, mesure sous rate-limit secondaire #17020 (débit d'auteurs de dossier), outillage(adjoint): post_dossier en REST pur -- emission de dossier sous limite GraphQL secondaire #19505 (émission de dossier en REST pur)
- Signalement :
msg-20261021T115421-yhb5bd(secrétaire,myia-po-2028:CoursIA-3) - Dispatch :
msg-20261021T120542-pv4hx3(coordinateurmyia-ai-01:CoursIA)
Activity
jsboige commentedon Oct 21, 2026
[DELIVERED] lane myia-ai-01:CoursIA-2 -- PR #21819
Les quatre criteres de l'issue sont couverts.
La divergence est mesuree firsthand sur ai-01 (2026-10-21, commentaire
github-actionssur #21390) : GraphQL rendlogin = "github-actions"avec__typename = "Bot", REST rendlogin = "github-actions[bot]"avectype = "Bot".ACCEPTED_DOSSIER_AUTHORSest ecrit en orthographe REST, donc le gate de fermeture (lecture GraphQL) refusait une App de lane que le gate adjoint (lecture REST) acceptait.Le correctif normalise une seule fois, dans
scripts/gh_identity.py(normalize_author_login,author_is_bot,is_accepted_dossier_author) : point de passage unique partage par les deux gates. La reconstruction du suffixe exige le type de l'acteur (__typename == "Bot"en GraphQL,type == "Bot"en REST), jamais la forme du login -- un compte utilisateur nomme comme le slug de l'App reste donc refuse. Un auteur de type inconnu n'est pas un bot (le doute profite au refus).Le gate de fermeture lit maintenant ses commentaires en REST, qui porte deja l'orthographe et le type en une seule surface ; le gate adjoint passe par la meme normalisation (idempotente sur du REST). Effet de bord corrige : le test
login.endswith("[bot]")qui ignore les commentaires de bots ne pouvait jamais reconnaitre un bot sous l'orthographe GraphQL.Tests : 49 verts dans
test_check_closure_dossier.py(dont 6 nouveaux -- controle positif App sur le chemin de lecture reel, controle negatif du compte utilisateur homonyme, non-regression des comptes humains, partage du point de normalisation), 260 verts danstest_check_adjoint_prevalidation.py+test_gh_identity.py. Verification sur issues reelles via le nouveau chemin REST : KEEP sur #19969 et #18941.fix(gate,#21818): l'auteur d'un dossier est normalise une seule fois …