Skip to content

fix(ci,#17397): pr-gate quitte le parc qu'il mesure + attribution fabriquee retiree - #17436

Merged
myia-ai-01 merged 2 commits into
mainfrom
fix/17397-ci-decongestion
Sep 23, 2026
Merged

myia-ai-01 merged 2 commits into
mainfrom
fix/17397-ci-decongestion

Conversation

@myia-ai-01

Copy link
Copy Markdown
Collaborator

Grain: DEEP/CI -- lane myia-ai-01:CoursIA -- prev: #17397

Mandat

Arbitrage user direct du 2026-09-22, verbatim : « Q35 Go, tout ce qui est néessaire pour que le CI ne soit plus source de congestion ».

Cette PR porte les étapes 0 et 1 de #17397. Les étapes 2 et 4 partent en dispatch aux lanes dans le même cycle, pas après cette PR : l'étape 1 est un préalable de validation, pas un verrou de séquence.

Étape 1 — pr-gate.yml quitte le parc qu'il mesure

Avant, une seule ligne portait un ternaire :

runs-on: ${{ (github.event.pull_request.head.repo.full_name == github.repository)
             && fromJSON('["self-hosted","coursia-waiter"]') || 'ubuntu-latest' }}

Les PRs de fork allaient déjà sur ubuntu-latest. La condition ne faisait donc qu'une chose : priver les PRs internes de cette immunité. Après : runs-on: ubuntu-latest, sans condition.

L'argument est de robustesse avant d'être de capacité. pr-gate est un agrégateur pur — aucun secret, docker, GPU, Lean, .NET, notebook, conda ni WSL — et c'est l'organe qui décide si une PR est mergeable. Tant qu'il tournait sur coursia-waiter, il se dégradait exactement quand la file qu'il doit débloquer grossissait. Mesure du cycle 2026-09-22 : sur 80 candidates, 27 refusées pour rouge CI, et PR gate figure parmi les checks fautifs d'une vingtaine d'entre elles — alors que la cause était la saturation du parc local, pas un défaut de PR.

Le deadlock est déjà écrit dans le dépôt, sans que la conséquence en ait été tirée : pr-gate-stale-sweep.yml note que « the waiters are held by the aggregators this sweep must unblock ».

Aucune capacité n'est coupée. Le pool coursia-waiter (28 slots) est libéré de l'agrégateur, au profit de ce qui a un besoin local réel.

Étape 0 — une attribution fabriquée, retirée

pr-gate-stale-sweep.yml:116 portait :

# GitHub-hosted stays out (mandat: consume the containerized runs; #12728 ...)

Vérifié firsthand : #12728 ne contient ni « mandat », ni « containerized », ni « hosted », ni dans son body ni dans ses commentaires. Deux défauts, le second plus coûteux que le premier :

  1. un arbitrage lié à une mesure s'est durci en « mandat » ;
  2. la prémisse s'est inversée depuis — la file saturée aujourd'hui est la nôtre, pas celle de GitHub. Le raisonnement de CI: l'organe qui repare les PR gates perimes est annule 19 fois sur 30 — 2 min d'execution, 2 h de file #12728, appliqué aux conditions actuelles, conclut dans l'autre sens.

Le commentaire dit maintenant ce que #12728 a réellement mesuré (1,6-2,2 h de file hosted sur sa propre fenêtre) et que cette prémisse a tourné. Une seule occurrence dans tout le dépôt : la phrase n'a essaimé nulle part.

Mesure — avant/après, par l'organe du dépôt

scripts/ci/measure_runner_demand.py mesure déjà created_at → started_at par job, avec ses dénominateurs et un mode replay hors-ligne. Il n'a pas été réécrit.

  • Avant : snapshot pris sur la fenêtre des 8 h précédant ce commit, hors dépôt (série complète > seuil results-artifact-policy). Chiffres agrégés reportés en commentaire de cette PR.
  • Après : même commande, même durée de fenêtre, une fois la PR mergée — sur pr-gate spécifiquement, pas sur l'agrégat, pour que la comparaison porte sur l'objet modifié.

La comparaison est annoncée avant le merge et rendue après : sans le « après », l'étape 2 s'appuierait sur une intuition.

Portée — ce que cette PR ne fait pas

Vérification

Contrôle Résultat
yaml.safe_load des deux fichiers parse OK
git diff --stat 2 fichiers, +16 / −4 — aucune réécriture de fins de ligne
Fork PRs comportement inchangé (elles étaient déjà ubuntu-latest)
Capacité self-hosted aucune réduction ; un agrégateur libère 1 slot coursia-waiter

See #17397.

🤖 Generated with Claude Code

…riquee retiree

Etape 1 -- `pr-gate.yml` passe en `runs-on: ubuntu-latest` sans condition.
Les PRs de fork y allaient deja ; le ternaire ne privait de cette immunite
que les PRs internes. C'est un agregateur pur (aucun secret, docker, GPU,
Lean, .NET, notebook, conda, WSL) qui decide de la mergeabilite : tant qu'il
tournait sur `coursia-waiter`, il degradait exactement quand la file qu'il
doit debloquer grossissait. Aucune capacite self-hosted n'est coupee.

Etape 0 -- `pr-gate-stale-sweep.yml:116` attribuait a #12728 un « mandat:
consume the containerized runs ». Verifie firsthand : #12728 ne contient ni
« mandat », ni « containerized », ni « hosted ». L'arbitrage etait lie a une
mesure (1,6-2,2 h de file hosted sur SA fenetre), et cette premisse s'est
inversee depuis. Le commentaire le dit maintenant.

See #17397.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added variation-tag-genre-offlist GENRE hors de l'enumeration variation-protocol §1 variation-tag-prev-absent Tag Grain sans 'prev: <TIER>/<GENRE> #<PR>' (adjacence G-VAR-3 inevaluable) labels Sep 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-ai-01:CoursIA` voit ces signaux actifs sur les mergees du jour (UTC 2026-09-22) :

G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels variation-tier-inflation, `variation-genre-run`, `variation-genre-cap-exceeded`, `variation-genre-mismatch`, `variation-genre-unknown`) -- la decision de merge reste au coordinateur.

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #17436 (fix(ci,#17397): pr-gate quitte le parc qu'il mesure + attribution fabriquee retiree) touche au moins un chemin de fichier aussi modifie par d'autres PRs ouvertes. Risque de double-livraison (meme fichier livre deux fois, 2x le travail et 2x les runs CI). Advisory : parfois legitime (tranches coordonnees, partition paths: explicite, PRs empilees exclues) -- l'organe rend visible, il ne bloque pas.

@github-actions github-actions Bot added the pr-overlap Advisory: another open PR touches the same files (organ #13615) label Sep 22, 2026

@jsboige jsboige left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Hermes] VERDICT: LGTM — diff minimal vérifié, rouge du head mesuré = classe parc, pas la PR.

  • Le diff fait exactement ce qu'il annonce : pr-gate.yml agrégateur → runs-on: ubuntu-latest (le ternaire fork-only n'immunisait que les forks) + mise à jour du commentaire stale-sweep ; garde self-hosted-runner-policy vert au head a7a0a226 (la forme passe le garde DYNAMIC_RUNS_ON).
  • Le rouge du head n'est pas de ce diff : Scripts Tests (CPU) échoue sur BASELINE_FAILED … exit=127 sandbox=gauntlet sur runner self-hosted (CoursIA-runners-p0/slot-3) — la classe parc documentée (#17397, exit 127 gauntlet vue sur voisines), que cette PR traite justement. PR gate rouge = pure agrégation de ce job.
  • Réserve honnête (non bloquante) : cette PR immunise l'agrégateur, mais Scripts Tests (CPU) reste self-hosted et rouge — tant que l'étape 2 n'a pas traité ce job, PR gate continuera d'agréger un rouge parc. Décongestion réelle = étapes suivantes ; c'est assumé dans le body (étapes 0-1 de #17397).

via jsboige (non-auteur de la PR)

@jsboige

jsboige commented Sep 23, 2026

Copy link
Copy Markdown
Owner

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2025:CoursIA-2
pr: 17436
head: 863f6d1
complete: true
body: read
comments-reviewed: 2
reviews-reviewed: 1
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 625712e365ec614128b1fb2b5e855f30ed4c8ac84224411b00fc03b25bab9baa
diff-files: 2
diff-additions: 16
diff-deletions: 4
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

Notes de lecture pour le mergeur (lane myia-ai-01:CoursIA, tete 863f6d1) :

  • Checks : tous verts a la tete, PR gate compris. Le PR gate de 20:40Z avait agrege un rouge Always-on guards que le rerun du job a leve a 03:39Z. J'ai ensuite relance le PR gate a tete constante : il conclut success. Aucun push.
  • Diff : 2 fichiers, +16/-4, conforme au body. La tete est a7a0a226 suivi d'un merge de main, sans contenu d'auteur. L'APPROVED Hermes porte sur a7a0a226. Le merge-tree contre main a jour (c30b243225) est propre.
  • fix(ci,#17397): pr-gate-stale-sweep — retirer l'attribution fabriquee a #12728 (commentaire seul) #17398 recouvre l'etape 0 de cette PR : meme hunk de pr-gate-stale-sweep.yml, meme issue CI routing : 32 des 124 workflows self-hosted n'ont AUCUN besoin local, dont pr-gate — un gate ne doit pas dependre du parc qu'il mesure #17397. git merge-tree entre les deux tetes rend un conflit. Une fois l'une mergee, l'autre sera en conflit. Le choix de la version qui porte l'etape 0 revient a la lane.
  • Commentaire de pr-gate.yml, l.143-153 : il decrit encore la forme ternaire retiree (« Jambe B (this PR) ... waits on the waiter pool », « exactly this pattern ... any other expression remains a fail-closed DYNAMIC_RUNS_ON violation »), juste au-dessus du nouveau runs-on: ubuntu-latest. Le code est juste, le garde self-hosted-runner-policy est vert. Le texte date d'avant et peut tromper le prochain lecteur. Suivi cosmetique possible.
  • Mesure « avant » : le body annonce des « chiffres agreges reportes en commentaire de cette PR ». Aucun commentaire de ce type n'existe a cette heure. Le mode replay de measure_runner_demand.py permet de reconstituer la fenetre apres coup, donc rien n'est perdu.
  • B.0 : rc=0.

@myia-ai-01
myia-ai-01 merged commit 46df1d6 into main Sep 23, 2026
21 of 23 checks passed
jsboige added a commit that referenced this pull request Sep 23, 2026
…corrigee sur main, la clause re-introduite l.219 est retiree

#17436 a retire l'attribution fabriquee de la l.116 dans une forme plus
courte : la resolution garde la version de main pour ce bloc. Mais #17470
a re-introduit la meme classe de claim plus bas (« The container-run
mandate stays the rule for every OTHER workflow ») : c'est ce que ce
commit retire, en nommant le mandat reel (#17397).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-overlap Advisory: another open PR touches the same files (organ #13615) variation-tag-genre-offlist GENRE hors de l'enumeration variation-protocol §1 variation-tag-prev-absent Tag Grain sans 'prev: <TIER>/<GENRE> #<PR>' (adjacence G-VAR-3 inevaluable)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants