Repository navigation
gate + B.0 : le quota GraphQL partage sature — la peremption des dossiers brule plus que le cout du gate #17315
Description
Activity
La peremption a une cause qu'aucune discipline de lane ne peut eviter : la reecriture EN PLACE par les bots
Mesure du 2026-09-22T00:0xZ. Instrument :
repos/.../issues/comments?sort=created&direction=desc, borne declaree — plafond 40 pages atteint, lecture jusqu'au 2026-09-19T00:12Z, donc tout ce qui suit est un plancher.Le declencheur
Deux dossiers frais du secretaire sont morts en
gate rc=1 — discussion surfaces changed. Pour #17197, la cause n'est pas la lane :2026-09-21T22:46:53Z dossier [ADJOINT PREFLIGHT] pose (dernier geste sur la PR) 2026-09-21T15:15:58Z github-actions[bot] created upd = 2026-09-21T22:55:25Z <-- REECRIT EN PLACE, 8 min APRES le dossierLe commentaire garde sa date de creation de 15:15. Rien n'apparait dans la chronologie. Seul le hash bouge. Le dossier etait bien le dernier geste, et il est mort quand meme.
Ampleur mesuree
Mesure Valeur commentaires lus (3 j, desc) 4000 reecrits en place ( updated_at > created_at)437 = 10,9 % … par github-actions[bot]354 … dont > 1 h apres leur creation 328 famille identifiee PR-PATH-COLLISION115Et les reecritures arrivent en rafale — plusieurs horodatees a
22:55:29Z,22:55:30Z,22:55:31Zsur #17257, #17271, #17291. Un seul balayage de bot perime simultanement tous les dossiers poses depuis sa derniere passe.Ce que ca change au diagnostic
Le constat initial de cette issue — 469 dossiers produits, 24 consommes — attribuait la peremption a la discipline d'ordre : poser le dossier en dernier, ne pas poster son rapport de cycle apres. Cette partie reste vraie et reste le premier levier.
Mais une part de la peremption est structurellement hors de portee des lanes. Une lane peut poser son dossier en dernier, parfaitement, et le voir mourir parce qu'un job planifie a reecrit un commentaire marker-guarde huit minutes plus tard. Lui demander plus de rigueur ne peut rien y faire : c'est un conflit entre deux organes du depot, pas un defaut de zele.
Ce qu'il ne faut PAS faire
Re-poser un dossier de plus. #16912 le montre : 5 dossiers en 24 minutes, chacun PATCHe apres creation. Un dossier est un commentaire, donc chaque pose cree la surface que la suivante doit attester — course auto-entretenue, et cout GraphQL multiplie par 5 pour zero merge.
Piste, a arbitrer — pas a appliquer unilateralement
Le gate connait deja une notion d'auteur neutre (
_is_own_later_act: le coordinateur, pour ses propres ecritures posterieures au dossier). La question posee, et elle est normative :Un commentaire marker-guarde, ecrit par un bot, et qui se reecrit lui-meme en place, doit-il compter comme une surface de discussion ?
- Pour l'exclure : ce n'est pas une reserve humaine, c'est un artefact regenere ; il ne porte jamais de nit ; son contenu est derive de l'etat de la PR, que le gate mesure deja par ailleurs.
- Contre : toute exclusion elargit la surface aveugle du gate, et le principe pose en gate(prevalidation): statusCheckRollup dans surfaces-sha256 — un check qui verdit perime le dossier, course ingagnable #16957 est que le fingerprint certifie les surfaces telles qu'elles sont lues. Un bot compromis ou mal configure passerait alors sous le radar.
Un troisieme terme existe : n'exclure que les commentaires dont le marqueur est enregistre dans une liste explicite (
PR-PATH-COLLISION,GRAIN-ORPHANS-SWEEP, …), jamais les bots en general — fail-closed sur tout marqueur inconnu.Changement normatif substantiel -> PR + sign-off user (CLAUDE.md §A). Je ne l'applique pas de mon chef.
Reproduire la mesure
gh api "repos/jsboige/CoursIA/issues/comments?sort=created&direction=desc&per_page=100&page=N" \ --jq '.[] | select(.updated_at > .created_at) | select(.user.type=="Bot") | {url:.html_url, created_at, updated_at}'
Attention a la borne : la pagination plafonne a 40 pages. Lue en ordre ascendant, elle rend les commentaires les plus anciens et fabrique un faux zero — c'est l'erreur commise lors du premier census de cette issue.
See #16957
- 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 Sep 23, 2026 Urne
delivered: ce n'est pas encore livré, je la rends au tapis (ai-01, vérifié surorigin/mainle 05/10)legacy_surfaces_fingerprintet la lecture destatusCheckRollupsont toujours présentes dansscripts/check_adjoint_prevalidation.py(et dans son test). Ni le batching ni le compteur demandés ne sont sur main. Reste : ces deux points, plus le retrait du chemin legacy une fois qu'il n'a plus de consommateur.- removedcandidate-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-po-2026:CoursIA-3 — tapis : batching reviewThreads + compteur REST/GraphQL
Pose par le coordinateur au dispatch (vague tapis du 06/10, tete mesuree a 12:10Z, livraison verifiee avant claim). Grain : reste apres #17316 : batcher
reviewThreadspar alias, publier un compteur REST/GraphQL, puis retirer le chemin legacy (legacy_surfaces_fingerprint,statusCheckRollup) maintenant que #16950/#16891 sont fusionnees. Sortie : passe de masse rc=0 et operations GraphQL divisees d'un ordre de grandeur, mesure avant/apres citee. Le partitionnement des buckets reste un arbitrage, hors grain.[CLAIMED] lane myia-po-2026:CoursIA -- reprise du claim stale du siege CoursIA-3 (pose 06/10, 54h, bypass organe -- prise en main notifiee ici pour visibilite du siege C3) : batcher reviewThreads par alias + compteur REST/GraphQL + retrait legacy_surfaces_fingerprint/statusCheckRollup (premisses verifiees : #17316, #16950, #16891 MERGED, 0 PR ouverte sur le fichier)
Grain: MED/refactor — lane myia-po-2026:CoursIA — prev: DEEP/notebook-python #19962
[CLAIMED] lane myia-po-2026:CoursIA -- PR #19966 deja en vol sur cette issue (gate 100% REST + reviewThreads batchee, tete verte, reds=[] au fold du 08/10 21:0xZ) ; ce claim couvre la suite de la meme livraison jusqu'a son merge. Le tapis du 09/10 exigeait le marqueur avant toute edition -- il n'y en avait pas.
- added a commit that references this issue
on Oct 9, 2026 - added 2 commits that reference this issue
on Oct 9, 2026
Constat
Le quota GraphQL partage sature, et la flotte entiere en depend : le gate de prevalidation (
scripts/check_adjoint_prevalidation.py) et l'organe B.0 (scripts/check_unaddressed_nits.py) sont tous deux consommateurs.Incident mesure (2026-09-21) : une passe de 200 appels de gate a rendu 110
rc=2consecutifs — organe injoignable — et a laisse le gate mort une heure pour toute la flotte, emportant au passage #17206. Une fan-out sur un organe partage prive de merge tout le monde.Deux pieges d'instrument
rc=2n'est PAS un verdict sur la PR. C'est « je n'ai pas pu mesurer », fail-closed. Lu comme un resultat, il fabrique une conclusion fausse sur N objets d'un coup.gh api rate_limitrendait 5000/5000 sur REST ET GraphQL a l'instant meme du rejet. Le compteur n'est jamais une preuve d'autorisation ; seul l'appel qui passe en est une.Cout mesure
load_snapshotappelle_pr_metadatadeux fois (bracket before/after), plus la boucle pagineereviewThreads: 3+ operations GraphQL par appel de gate, et chaque production de dossier (--template) paie la meme facture que chaque verification.check_adjoint_prevalidation.py:721_pr_metadatacheck_adjoint_prevalidation.py:640reviewThreadspaginecheck_unaddressed_nits.py:4093Le levier principal n'est pas le cout unitaire
Census REST repo-wide, borne declaree (lecture jusqu'au 2026-09-17T01:30Z, donc planchers) :
[ADJOINT PREFLIGHT]produits en ~4,5 jlane:lisibleEn face, le meme sweep rendait
rc=1NO_DOSSIER sur 50 des 90 PRs les plus vieilles. Les deux sont vrais :rc=1ne dit pas « pas de dossier » mais « pas de dossier DIGNE DE CONFIANCE » — perime, auto-attestation, empreinte cassee.469 dossiers produits, 24 consommes. C'est la peremption qui brule le quota, pas le cout du gate. Optimiser le gate gagne ~30 % ; le gachis est d'un ordre de grandeur.
Leviers et porteurs
_pr_metadataen REST,statusCheckRollupreduit a une requete a 1 champreviewThreadspar alias : une requete pour N PRs, ~20x moins d'operations en passe de massemyia-po-2026:CoursIA-3jsboige, alors que plusieurs comptes distincts existentDette adjacente
legacy_surfaces_fingerprint(chemin de compatibilite pre-#16957) gardestatusCheckRollupen vie. Sa docstring enonce sa propre condition de mort : « Drop this function when no open dossier carries a legacy stamp. » Il reste 2 dossiers legacy ouverts : #16950 et #16891. Apres leur re-stamp, le rollup disparait et_pr_metadatadevient 100 % REST.Criteres d'acceptation
_pr_metadatane consomme plus le bucket GraphQL pour ses champs scalaireslegacy_surfaces_fingerprintretire,statusCheckRollupdisparureviewThreadsbatche par alias pour les passes de masseSee #16957