Le defaut
Le superviseur de runners tourne sur ai-01 sous le compte myia-ai-01. Ce compte ne peut pas obtenir de registration token : sans COURSIA_RUNNER_GH_ACCOUNT=jsboige, la boucle de slot tourne indefiniment sur un refus de 60 s en 60 s. La CI ne demarre jamais, et rien ne l'indique ailleurs que sur stderr du superviseur.
Mesure firsthand (2026-09-08, depuis ai-01)
POST repos/jsboige/CoursIA/actions/runners/registration-token
sous myia-ai-01 -> HTTP 403
sous jsboige -> token OK (longueur 29)
GET repos/jsboige/CoursIA/actions/runners
sous myia-ai-01 -> HTTP 403
Ce qui rend le diagnostic trompeur
| ce que GitHub repond |
ce qui est vrai |
| « You must have repository read permissions or have the repository runners fine-grained permission » |
myia-ai-01 a permission: write, role_name: write sur le depot |
| (implicite : il manque un scope) |
le token porte repo, workflow, read:org, gist |
Le compte a plus que ce que le message reclame, et echoue quand meme. La cause reelle est que les endpoints de runners self-hosted exigent l'admin du depot, pas le write -- le message d'erreur nomme la mauvaise exigence. Un operateur qui le lit litteralement va verifier des droits qui sont deja la, et conclure a un probleme de scope qui n'existe pas.
C'est aussi pourquoi la prescription qui circulait dans nos notes -- « faire de jsboige le defaut avec une erreur claire plutot qu'un blocage silencieux » -- etait a moitie fausse : le blocage n'est pas silencieux. #14259 a deja retire le 2>/dev/null de fetch_token, et la boucle affiche [slot N] token indisponible (droit admin gh ?) -- nouvelle tentative dans 60 s. Elle nomme meme la bonne hypothese. Ce qui manque n'est pas le message, c'est qu'il n'aboutit jamais.
Deux voies, a arbitrer -- elles ne s'equivalent pas
A. Donner l'admin a myia-ai-01. Supprime la dependance a un compte partage. Mais l'admin porte aussi la protection de branche et les reglages du depot : c'est une elevation reelle, pas un ajustement. Decision user.
B. Rendre l'epinglage obligatoire et le refus terminal. Garder jsboige comme compte de registration, mais : si aucun COURSIA_RUNNER_GH_ACCOUNT n'est defini et que le compte ambiant echoue au premier fetch, refuser de demarrer avec le diagnostic complet, au lieu de boucler. Une boucle infinie sur une cause structurelle est un faux « en cours » -- elle a la meme signature qu'une panne reseau transitoire, qui elle merite le retry.
Ma recommandation est B, avec un plafond de tentatives : la cause « le compte n'a pas le droit » ne se resout jamais toute seule, alors que « l'API est momentanement indisponible » se resout. Les distinguer par le code HTTP (403 -> terminal, 5xx/reseau -> retry) est le bon discriminant, et il est disponible.
Critere d'acceptance
Trouve en remettant la CI en service pour #15091.
Le defaut
Le superviseur de runners tourne sur ai-01 sous le compte
myia-ai-01. Ce compte ne peut pas obtenir de registration token : sansCOURSIA_RUNNER_GH_ACCOUNT=jsboige, la boucle de slot tourne indefiniment sur un refus de 60 s en 60 s. La CI ne demarre jamais, et rien ne l'indique ailleurs que sur stderr du superviseur.Mesure firsthand (2026-09-08, depuis ai-01)
Ce qui rend le diagnostic trompeur
myia-ai-01apermission: write,role_name: writesur le depotrepo,workflow,read:org,gistLe compte a plus que ce que le message reclame, et echoue quand meme. La cause reelle est que les endpoints de runners self-hosted exigent l'admin du depot, pas le
write-- le message d'erreur nomme la mauvaise exigence. Un operateur qui le lit litteralement va verifier des droits qui sont deja la, et conclure a un probleme de scope qui n'existe pas.C'est aussi pourquoi la prescription qui circulait dans nos notes -- « faire de
jsboigele defaut avec une erreur claire plutot qu'un blocage silencieux » -- etait a moitie fausse : le blocage n'est pas silencieux. #14259 a deja retire le2>/dev/nulldefetch_token, et la boucle affiche[slot N] token indisponible (droit admin gh ?) -- nouvelle tentative dans 60 s. Elle nomme meme la bonne hypothese. Ce qui manque n'est pas le message, c'est qu'il n'aboutit jamais.Deux voies, a arbitrer -- elles ne s'equivalent pas
A. Donner l'admin a
myia-ai-01. Supprime la dependance a un compte partage. Mais l'admin porte aussi la protection de branche et les reglages du depot : c'est une elevation reelle, pas un ajustement. Decision user.B. Rendre l'epinglage obligatoire et le refus terminal. Garder
jsboigecomme compte de registration, mais : si aucunCOURSIA_RUNNER_GH_ACCOUNTn'est defini et que le compte ambiant echoue au premier fetch, refuser de demarrer avec le diagnostic complet, au lieu de boucler. Une boucle infinie sur une cause structurelle est un faux « en cours » -- elle a la meme signature qu'une panne reseau transitoire, qui elle merite le retry.Ma recommandation est B, avec un plafond de tentatives : la cause « le compte n'a pas le droit » ne se resout jamais toute seule, alors que « l'API est momentanement indisponible » se resout. Les distinguer par le code HTTP (403 -> terminal, 5xx/reseau -> retry) est le bon discriminant, et il est disponible.
Critere d'acceptance
myia-ai-01obtient bien un token, et retirer l'epinglage devenu inutile.Trouve en remettant la CI en service pour #15091.