You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ci(lean): le retarget d'une PR empilee vers main n'arme pas son CI Lean -- 30 workflows gates sur branches:[main], aucun n'inclut 'edited' #15652
Relevé en traitant le point de review Hermes sur la PR #15600 (tranche 2 socle Alexander, #14962) : « CI Lean knot_lean non encore rendu au head ef5fc4391a — 0 check-run Lean visible ». Le point était exact. En cherchant pourquoi, la cause n'est ni le code de la PR ni le filtre paths : c'est la combinaison branches: [main] + les types par défaut de pull_request, sur une PR empilée.
Mesure
Sur la PR #15600, la chronologie est établie par l'API, pas par déduction :
Instant (UTC)
Événement
Source
2026-09-11T13:05:12Z
PR créée, base = branche sœur (PR #15596), pas main
createdAt
2026-09-11T13:05:16Z
Lean i18n sibling drift se déclenche (ce workflow n'a pas de filtre branches:)
la PR enfant est retargettée vers main — événement base_ref_changed
timeline, acteur myia-ai-01
2026-09-11T19:08:55Z
always-on-guards se re-déclenche, lean-knot.yml toujours pas
runs 34637249752/34637249806
Les deux verrous se lisent directement dans le fichier :
on.pull_request.branches: [main] — à la création, la base d'une PR empilée est sa branche parente, donc le workflow est hors de son périmètre déclaré ;
on.pull_requestsans clé types: — les types par défaut sont opened, synchronize, reopened. Le retarget vers main émet edited, qui n'y figure pas.
Le second verrou est le plus gênant : c'est précisément l'événement qui rend la PR éligible au premier filtre. Le premier tir exclut, le second ne rattrape pas — la PR empilée n'a jamais son CI Lean, sauf nouveau commit poussé.
Contrôle positif et réfutation du filtre paths
paths n'est pas en cause. La PR feat(lean,#14962): fait de Fox — paire de dessus dans une classe d'arcs + somme de ligne nulle (FR+EN) #15596 touchait exactement les deux mêmes fichiers (knot_lean/Knots/Conway.lean, knot_lean/Knots/Conway_en.lean) avec main pour base dès l'ouverture : lean-knot.yml s'est déclenché dessus au SHA 7d4750c9ed2f (run 34598985311, 2026-09-11T12:27:15Z, succès). Le motif knot_lean/**.lean couvre donc bien ces fichiers, sous-dossier compris.
Contrôle positif du type edited.always-on-guards.yml déclare types: [opened, synchronize, edited, reopened] et n'a pas de filtre paths:. Il s'est re-déclenché 2 s après le retarget, sur le même head. C'est la démonstration que le retarget émet bien un événement que les workflows sans edited ignorent.
Portée
30 workflows lean-*.yml portent branches: [main] dans leur bloc pull_request, et aucun n'inclut edited dans ses types (29 sans clé types:, 1 qui les énumère sans edited) :
Sont donc concernés tous les lakes Lean du dépôt, pas seulement knot_lean. La même mesure s'applique à tout workflow de PR combinant branches: [main] et paths: — le périmètre exact au-delà de lean-* reste à relever.
Impact : une PR Lean empilée dont la base est mergée avant que l'enfant ne soit re-poussé traverse tout son cycle de review sans aucun CI Lean. Le reviewer voit « 0 check-run Lean » et, comme Hermes l'écrit lui-même, ne peut prononcer l'approbation sur la partie vérifiable statiquement que « à réception d'exécution ». Le gate ne tourne pas sur la chose qu'il vérifie — la classe exacte que les commentaires de lean-knot.yml documentent déjà pour #8712 et #8722.
Correctif proposé
Deux options, à trancher côté coordination (design gate, pas une décision de lane) :
(a) Ajouter edited aux types: des workflows concernés. Ciblé, mais 30 fichiers à toucher, et le workflow se re-déclenche à chaque édition de body/titre — à confirmer comme non gênant.
(b) Retirer branches: [main] là où paths: scope déjà le workflow. C'est le raisonnement déjà appliqué à always-on-guards.yml (« PAS de paths: ici », et pas de filtre branches: — un organe qui doit voir toutes les PR de la flotte). Élargit le déclenchement à toute base, ce qui est le comportement voulu pour un enfant de stack, mais déclenche aussi sur les PRs dont la base est une branche longue.
Les deux se valident par la même expérience.
Acceptance
Le mécanisme est nommé dans le corps de lean-knot.yml (le fichier documente déjà ses trous de déclenchement ; celui-ci manque).
Expérience de validation : ouvrir une PR empilée (base ≠ main) touchant un *.lean du lake visé, merger la base, retargetter l'enfant vers main — le workflow Lean doit se déclencher sur le retarget, sans nouveau commit.
Le périmètre réel est relevé (au-delà de lean-*, tout workflow de PR à la fois gaté sur branches: [main] et sur paths:).
Si l'option (b) est retenue, vérifier qu'un même lake ne reçoit pas deux runs concurrents quand une PR empilée et sa parente sont toutes deux ouvertes.
Périmètre
.github/workflows/lean-*.yml (30 fichiers au relevé du 2026-09-11). Sujet d'infrastructure CI distinct de la PR #15600 elle-même, d'où cette issue plutôt qu'une correction embarquée dans une tranche Lean.
En attendant, lean-knot.yml porte workflow_dispatch: — un run a été déclenché à la main sur la branche de la PR #15600 pour obtenir la preuve demandée par Hermes (run 34651449947). C'est un contournement manuel, pas une réparation : il ne se reproduit pas tout seul à la prochaine PR empilée.
Origine
Relevé en traitant le point de review Hermes sur la PR #15600 (tranche 2 socle Alexander, #14962) : « CI Lean
knot_leannon encore rendu au headef5fc4391a— 0 check-run Lean visible ». Le point était exact. En cherchant pourquoi, la cause n'est ni le code de la PR ni le filtrepaths: c'est la combinaisonbranches: [main]+ les types par défaut depull_request, sur une PR empilée.Mesure
Sur la PR #15600, la chronologie est établie par l'API, pas par déduction :
maincreatedAtLean i18n sibling driftse déclenche (ce workflow n'a pas de filtrebranches:)34602337330lean-knot.ymlne se déclenche pasmainmergedAtmain— événementbase_ref_changedmyia-ai-01always-on-guardsse re-déclenche,lean-knot.ymltoujours pas34637249752/34637249806Les deux verrous se lisent directement dans le fichier :
on.pull_request.branches: [main]— à la création, la base d'une PR empilée est sa branche parente, donc le workflow est hors de son périmètre déclaré ;on.pull_requestsans clétypes:— les types par défaut sontopened, synchronize, reopened. Le retarget versmainémetedited, qui n'y figure pas.Le second verrou est le plus gênant : c'est précisément l'événement qui rend la PR éligible au premier filtre. Le premier tir exclut, le second ne rattrape pas — la PR empilée n'a jamais son CI Lean, sauf nouveau commit poussé.
Contrôle positif et réfutation du filtre
pathspathsn'est pas en cause. La PR feat(lean,#14962): fait de Fox — paire de dessus dans une classe d'arcs + somme de ligne nulle (FR+EN) #15596 touchait exactement les deux mêmes fichiers (knot_lean/Knots/Conway.lean,knot_lean/Knots/Conway_en.lean) avecmainpour base dès l'ouverture :lean-knot.ymls'est déclenché dessus au SHA7d4750c9ed2f(run34598985311, 2026-09-11T12:27:15Z, succès). Le motifknot_lean/**.leancouvre donc bien ces fichiers, sous-dossier compris.edited.always-on-guards.ymldéclaretypes: [opened, synchronize, edited, reopened]et n'a pas de filtrepaths:. Il s'est re-déclenché 2 s après le retarget, sur le même head. C'est la démonstration que le retarget émet bien un événement que les workflows sanseditedignorent.Portée
30 workflows
lean-*.ymlportentbranches: [main]dans leur blocpull_request, et aucun n'inclutediteddans ses types (29 sans clétypes:, 1 qui les énumère sansedited) :Sont donc concernés tous les lakes Lean du dépôt, pas seulement
knot_lean. La même mesure s'applique à tout workflow de PR combinantbranches: [main]etpaths:— le périmètre exact au-delà delean-*reste à relever.Impact : une PR Lean empilée dont la base est mergée avant que l'enfant ne soit re-poussé traverse tout son cycle de review sans aucun CI Lean. Le reviewer voit « 0 check-run Lean » et, comme Hermes l'écrit lui-même, ne peut prononcer l'approbation sur la partie vérifiable statiquement que « à réception d'exécution ». Le gate ne tourne pas sur la chose qu'il vérifie — la classe exacte que les commentaires de
lean-knot.ymldocumentent déjà pour#8712et#8722.Correctif proposé
Deux options, à trancher côté coordination (design gate, pas une décision de lane) :
editedauxtypes:des workflows concernés. Ciblé, mais 30 fichiers à toucher, et le workflow se re-déclenche à chaque édition de body/titre — à confirmer comme non gênant.branches: [main]là oùpaths:scope déjà le workflow. C'est le raisonnement déjà appliqué àalways-on-guards.yml(« PAS depaths:ici », et pas de filtrebranches:— un organe qui doit voir toutes les PR de la flotte). Élargit le déclenchement à toute base, ce qui est le comportement voulu pour un enfant de stack, mais déclenche aussi sur les PRs dont la base est une branche longue.Les deux se valident par la même expérience.
Acceptance
lean-knot.yml(le fichier documente déjà ses trous de déclenchement ; celui-ci manque).main) touchant un*.leandu lake visé, merger la base, retargetter l'enfant versmain— le workflow Lean doit se déclencher sur le retarget, sans nouveau commit.lean-*, tout workflow de PR à la fois gaté surbranches: [main]et surpaths:).Périmètre
.github/workflows/lean-*.yml(30 fichiers au relevé du 2026-09-11). Sujet d'infrastructure CI distinct de la PR #15600 elle-même, d'où cette issue plutôt qu'une correction embarquée dans une tranche Lean.En attendant,
lean-knot.ymlporteworkflow_dispatch:— un run a été déclenché à la main sur la branche de la PR #15600 pour obtenir la preuve demandée par Hermes (run34651449947). C'est un contournement manuel, pas une réparation : il ne se reproduit pas tout seul à la prochaine PR empilée.