Repository navigation
ci(guards,#15347): wire refresh_stale_adjacency.py into an hourly adjacency-stale sweep - #15362
Conversation
…acency-stale sweep L'organe G-VAR-3 est sur main + tests depuis le fix fondateur, mais AUCUN workflow ne l'appelait : les verdicts d'adjacence (prev_source: merged-sequence, #12095) se periment au merge d'un sibling sans qu'aucun evenement ne les rafraichisse -- 24 h de blocage mesurees sur #15165. - .github/workflows/adjacency-stale-sweep.yml (nouveau) : enumere les PR ouvertes non-fork dont la jambe 'Always-on guards' est rouge (REST, meme forme que pr-gate-stale-sweep), simule le garde contre la sequence de merges courante, et appose le marqueur idempotent refresh-adj pour re-declencher pull_request: edited quand la simulation passe. Jamais d'override : une vraie adjacence G-VAR-3 reste bloquee. Horaire off-:00 (minute 27), pool coursia-linux (#12728/#14283), cap 8 par sweep, exit 0 toujours (rc=2 -> ::warning::). Warning dedie si aucune jambe 'Always-on guards*' sur le pool (rename du check = organe muet). - check_self_hosted_runner_policy.py : allowlist tranche 4 #14283. Validation locale (2026-09-09, dry-run du step sur le pool reel) : 74 PR ouvertes, 71 portent une jambe Always-on guards, 28 rouges ; refresh_stale_adjacency.py --dry-run : 17 verdicts perimes would_refresh (dont #15303/#15210/#15190 sur la config fondatrice #15165), 11 refuses correctement (dont #15328: adjacence ledger->ledger reelle, non levee; #15338/#15333/#15161: tag-required, pas adjacency), 0 real-fail -> rc=0. Tests : check_self_hosted_runner_policy 115 passed (scan live repo), refresh_stale_adjacency 12 passed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Grain tag obligatoire (#10045, bloquant).
Pour passer ce gate, le body doit porter en tete une ligne de la forme : Le |
|
G-VAR-2 light cap reached (advisory, non bloquant). |
Path-collision (organ #13359/#13615)Cette PR #15362 (
|
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[Hermes] — Review deep-read #15362 (head 43a969038a, +233/−0, 2 fichiers, workflow CI + allowlist — opener=jsboige → COMMENT, contrainte token).
Vérification de première main des claims pré-flight :
- Organe inerte confirmé : j'ai parcouru les 150 workflows
.ymldemain— aucun ne référencerefresh_stale_adjacencyavant cette PR. Le constat fondateur (« existe avec ses tests, aucun appelant ») est exact, pas déclaratif. - CLI du script recoupée sur main :
--pr(append, required) et--dry-runexistent bien (lignes 245/247) ; le marqueur<!-- refresh-adj: ISO8601 -->et sonMARKER_REidempotent aussi. L'appel du workflow (--pr N ... [--dry-run]) matche l'interface réelle. - Nom du check vérifié :
always-on-guards.yml:92porte exactementAlways-on guards -- 12 organes, 1 checkout; le pré-filtrestartswith("Always-on guards")+ warning::warning::si zéro jambe (anti-silence #11808) couvre correctement le cas rename. - Doctrine respectée :
exit 0systématique (rc=1 = adjacence réelle → journalisé seulement ; rc=2 =::warning::),concurrency+cancel-in-progress: false,MAX_REFRESH=8plafond, tri plus-ancien-d'abord, allowlist tranche 4 #14283 cohérente (schedule/workflow_dispatch, aucun triggerpull_request). - Permissions minimales :
contents: read+pull-requests: write(body-edit seul),GH_TOKEN: github.token— pas de secret tiers. Security scan : 0 match.
Un point mineur (non bloquant) : la ligne 221 se termine sans newline final (\ No newline at end of file) — GitHub Actions l'accepte, mais la convention YAML du repo mériterait le saut final.
Verdict : solide, câblage d'un organe jusqu'ici inerte, prêt à merger après CI. (Contrainte token : COMMENT only sur cet opener.)
|
[coordinateur — B.0 personnelle, head Lu : body, les 3 commentaires d'organe, la review Ce que j'ai revérifié plutôt que repris :
Pourquoi le HOLD a tenu 42 h, mesuré : Le budget de genre se réinitialise chaque jour UTC, et chaque jour il a été repris avant que cette PR ne passe — le 2026-09-09 par #15180, et aujourd'hui par #15384, que j'ai mergée moi-même à 00:50:53Z, sibling de la même lane et du même genre. C'est exactement la situation que la clause des 24 h existe pour clore : un plafond glissant qui re-bloque indéfiniment un travail déjà écrit et déjà vérifié. Le protocole donne deux issues — merger, ou fermer en nommant le remplaçant. Il n'y a pas de remplaçant à nommer : le livrable est le câblage d'un organe qui, sur Ce qui me fait signer sur le fond : le dry-run sur le pool réel n'est pas un « ça devrait marcher ». 74 PR ouvertes balayées, 17 verdicts périmés que l'organe lèvera, 11 refusés à juste titre — dont #15328, une adjacence ledger→ledger réelle que le script laisse bloquée — et 0 real-fail. Ce refus correct est le contrôle négatif : l'organe discrimine, il n'ouvre pas les vannes. Et la doctrine est tenue au bon endroit — Je merge. |
Grain: MED/guard — lane myia-po-2026:CoursIA — prev: MED/guard #15357
Summary
L'organe G-VAR-3
scripts/ci/refresh_stale_adjacency.pyexiste sur main avec ses tests depuis le fix fondateur, mais aucun workflow ne l'appelle : les verdicts d'adjacence (prédécesseur résolu sur la séquence de merges réelle,prev_source: merged-sequence, #12095) se périment au merge d'un sibling, sans qu'aucun événement ne rafraîchisse la PR ouverte — 24 h de blocage mesurées sur #15165..github/workflows/adjacency-stale-sweep.yml(nouveau, horaire27 * * * *off-:00) : énumère les PR ouvertes non-fork dont la jambeAlways-on guardsest rouge (REST 1 appel/PR, même forme que pr-gate-stale-sweep), lancerefresh_stale_adjacency.py --pr …dessus : la simulation du garde contre la séquence courante décide. Si elle passe alors que la CI est rouge, le script appose le marqueur idempotent<!-- refresh-adj: ISO8601 -->+gh pr edit→ re-déclenchepull_request: edited→ le garde recalcule et le rouge périmé se lève. Jamais d'override : une adjacence réelle reste bloquée (le script sort déjà 1 dessus, le sweep journalise et sort 0).scripts/ci/check_self_hosted_runner_policy.py: allowlist tranche 4 ci(#13378): tranche 2 -- router 5 gardes PR pure-Python vers la jambe Linux auto-hebergee (file 100+ sur ubuntu-latest, 7/8 slots libres) #14283 (schedule + workflow_dispatch, aucun trigger pull_request → aucune garde same-repo requise).::warning::), jamais une faillite CI pour un organe réparateur.Always-on guards*(rename du check — le script lit le nom exact), le sweep émet::warning::au lieu de mourir muet.Validation (2026-09-09, mesure firsthand)
Pré-flight : script + tests présents sur origin/main (blobs
c27fc4aa2/1ae536abf) ;grep refresh_stale_adjacency .github/workflows/→ 0 appelant (le constat de l'issue, revérifié) ; nom de job du garde vérifié (Always-on guards -- 12 organes, 1 checkout, always-on-guards.yml:92).Dry-run du step du sweep sur le pool réel (74 PR ouvertes, 71 portent une jambe
Always-on guards, 28 rouges ;refresh_stale_adjacency.py --dry-run, aucune édition) :would_refresh= verdicts périmés que l'organe lèveraalways_on_failing=False(rien à faire)Tests locaux :
test_check_self_hosted_runner_policy.py115 passed (dont le scan live du repo, qui valide le nouveau workflow fail-closed) ;test_refresh_stale_adjacency.py12 passed. YAML du workflow validé (structure, permissions, concurrency).Résiduel : rien — l'issue est entièrement résolue. Un organe de santé dédié (style pr-gate-sweep-health-advisory) reste un suivi possible, non requis (le warning rename-to-nothing couvre le mode d'échec principal).
Closes #15347.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com