Constat mesuré (po-2023:CoursIA, 2026-10-08)
scripts/check_run_state.py résout le head d'une PR par gh pr view --json headRefOid, c'est-à-dire par GraphQL. Sous throttle GraphQL, l'instrument entier meurt :
$ python scripts/check_run_state.py --pr 19912
instrument error: gh pr view 19912 --repo... -> 1: GraphQL: API rate limit already exceeded for user ID 3159389.
Alors que core est ouvert — rate_limit rendait core 5000/5000, graphql 4461/5000 — et que le même champ est servi par REST :
$ gh api repos/jsboige/CoursIA/pulls/19912 --jq .head.sha
359ea17fa33b3770346c091aa024c182876d6f5c
Pourquoi ce n'est pas cosmétique : l'échec d'instrument est lu comme un défaut de PR
scripts/pick_idle_grain.py appelle cet organe. Le 2026-10-08, il a classé trois PR de la même lane en :
ROUGE IMPUTE A LA BASE -- pas le votre, pas reparable par la lane : PR gate : organe non lisible sur #19910, #19912, #19913, #19916, #19917, #19923 -- pas pu trancher, le rouge RESTE a la lane
Une panne de transport y devient une catégorie de diagnostic sur la PR. Le coût est double : le picker ne peut plus classer, et la lane lit « le rouge reste à la lane » là où il n'y a aucun rouge à lire.
Ce que le correctif rétablit, mesuré
REST en tête, GraphQL en repli. Après le correctif, les trois PR se lisent :
| PR |
avant |
après |
| #19912 |
instrument error |
101 jambes / 101 noms — dont un vrai [RED] Always-on guards -- 16 organes, 1 checkout: failure @12:10:46Z |
| #19913 |
instrument error |
4 jambes / 4 noms |
| #19917 |
instrument error |
20 jambes / 20 noms, vertes |
Le correctif s'est payé au premier run : le rouge réel de #19912 était invisible tant que l'organe était mort. Un instrument qui tombe ne dit pas seulement « je ne sais pas », il retire ce qu'il aurait vu.
Portée
Les deux chemins rendent le même SHA : REST en tête parce que c'est le transport qui survit au throttle qui a produit le défaut ; GraphQL garde en repli pour le cas inverse (endpoint pulls indisponible ou jeton sans scope). Ce n'est pas un choix de source, c'est une redondance de transport.
Trois tests ajoutés, dont le fondateur (GraphQL throttlé, REST debout) et le cas inverse (REST tombé, GraphQL debout), plus un contrôle négatif : les deux chemins tombés doivent lever, pas rendre un SHA vide — pour que l'échec ne redevienne pas silencieux.
Sans parent : defaut d'instrument de coordination (scripts/), non rattache a une serie pedagogique.
Constat mesuré (po-2023:CoursIA, 2026-10-08)
scripts/check_run_state.pyrésout le head d'une PR pargh pr view --json headRefOid, c'est-à-dire par GraphQL. Sous throttle GraphQL, l'instrument entier meurt :Alors que
coreest ouvert —rate_limitrendaitcore 5000/5000,graphql 4461/5000— et que le même champ est servi par REST :Pourquoi ce n'est pas cosmétique : l'échec d'instrument est lu comme un défaut de PR
scripts/pick_idle_grain.pyappelle cet organe. Le 2026-10-08, il a classé trois PR de la même lane en :Une panne de transport y devient une catégorie de diagnostic sur la PR. Le coût est double : le picker ne peut plus classer, et la lane lit « le rouge reste à la lane » là où il n'y a aucun rouge à lire.
Ce que le correctif rétablit, mesuré
REST en tête, GraphQL en repli. Après le correctif, les trois PR se lisent :
instrument error101 jambes / 101 noms— dont un vrai[RED] Always-on guards -- 16 organes, 1 checkout: failure @12:10:46Zinstrument error4 jambes / 4 nomsinstrument error20 jambes / 20 noms, vertesLe correctif s'est payé au premier run : le rouge réel de #19912 était invisible tant que l'organe était mort. Un instrument qui tombe ne dit pas seulement « je ne sais pas », il retire ce qu'il aurait vu.
Portée
Les deux chemins rendent le même SHA : REST en tête parce que c'est le transport qui survit au throttle qui a produit le défaut ; GraphQL garde en repli pour le cas inverse (endpoint
pullsindisponible ou jeton sans scope). Ce n'est pas un choix de source, c'est une redondance de transport.Trois tests ajoutés, dont le fondateur (GraphQL throttlé, REST debout) et le cas inverse (REST tombé, GraphQL debout), plus un contrôle négatif : les deux chemins tombés doivent lever, pas rendre un SHA vide — pour que l'échec ne redevienne pas silencieux.
Sans parent : defaut d'instrument de coordination (
scripts/), non rattache a une serie pedagogique.