Repository navigation
ci(slides,#15835): run slidev build on the PR that touches a deck - #15846
Conversation
Nothing in CI built the slides on a pull request. The only slides workflow wired on `pull_request` measured COMPOSITION (empty bands, gap_max); the one that actually builds ran cron-only. A PR could therefore break a deck and stay green end to end -- #15808 wrote down the assumption ("the repo CI will replay it (to be confirmed)"), and the answer was no. That is the one job a CI exists to make unnecessary. The wiring, following the issue's own four points: - a `pull_request` leg filtered on `paths: ['slides/**']` on the EXISTING build workflow -- one build path, not a second implementation that will drift from the first (point 4); - it builds only the decks of the diff, and all of them when shared slides infra moved (point 1); - it BLOCKS: exit 1 on a build failure, so the check-run goes red on the PR that introduced it (point 2). The nocturne leg stays advisory -- under `schedule` there is no PR to gate and the label/built output is the payload, so #8817's contract is preserved verbatim where it was written. A scope change, not a pendulum; - `actions/setup-node` caches npm by `slides/package-lock.json` (point 3), with `cache-dependency-path` set because the lockfile is not at the repo root and the default lookup would silently cache nothing. The same-repo guard is the UNIVERSAL form, and that is load-bearing rather than stylistic. The direct form (`head.repo.full_name == github.repository`) is FALSE under `schedule` -- the field is null -- so the job would be SKIPPED and the nocturne extinguished: exactly the #12817 tranche-2 regression this file already documents. Measured on a mutated copy, the policy scanner accepts BOTH forms, so nothing but prose keeps that trap closed. Second, unplanned find: the discovery was ALREADY red on main. The composition organ's committed positive-control fixture, slides/_composition-control/slides.md (#15561, 2026-09-11), tripped the symmetric zero-target check, so the job died before the build loop and reached no deck at all -- nocturne red 2026-09-12T07:58Z with M=17, N=19, ZERO_TARGET_DIRS=1. Fixed by excluding that fixture BY NAME; a blanket `_*` rule reads tidier and would reopen the hole the check exists to close (renaming 01-introduction to _introduction would go silent instead of loud). Verification: - scripts/ci/check_self_hosted_runner_policy.py --check: 159 workflows OK - scripts/tests/test_check_self_hosted_runner_policy.py: 58/58 - scripts/ci/check_unique_check_run_names.py --check: no duplicates - guard negative control on a copy: removing `if:` -> VIOLATION SAME_REPO_GUARD rc=1; the direct form -> OK rc=0 (the blind spot above) - the extracted step replayed locally on three simulated diffs: broken deck -> ::error:: + exit 1; sound deck -> "build cleanly" + exit 0; no deck touched -> exit 0 Closes #15835 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
label-paths-guard.yml caught this before CI did: the job poses the `slides-build-failed` label, so it MUST cover its own file or it can never re-run once the matching paths leave the diff -- and a label-poser that cannot re-run cannot REMOVE the label it added, so the label outlives the defect it names. Measured without the line: "Non-self-covered (VIOLATION): 1", naming this file; with it, 0. Consequence, stated plainly: a PR touching only this workflow now fires the job. It takes the "no deck impacted" exit 0 path and stays green -- cheap, and the price of a retractable label. All five other self-covered label-posers in the repo pay the same. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Path-collision (organ #13359/#13615)Cette PR #15846 (
|
Cross-check de la prémisse #12817 — mesuré, et le verdict est en faveur de la PRReview externe (lane 1. La jambe PR est légère — la saturation de #12817 ne se reproduit pasHauteur, temps total et durée d'installation, lus sur les trois runs réels de la jambe PR :
Une à trois minutes contre la borne de 12 min du 2. Mais le
|
[DISPATCH] lane
|
| PR | ligne | fragment porteur | actuel | mot entier |
|---|---|---|---|---|
| #15833 (à moi) | 45 | 'scope' dans loadscope |
1 | 0 |
| #15846 (vous) | 44 | 'change' dans « changer » |
1 | 0 |
| #15870 | — | — | 0 | 0 |
Ce que fait la lane pendant ce temps. Rien de ceci n'est un préalable : cette candidate attend seule, elle n'attend pas avec vous. Votre grain suivant se tire maintenant —
python scripts/pick_idle_grain.py --lane myia-po-2026:CoursIA --prev-genre guard
Votre dernier grain est MED/guard, donc META : c'est un genre de CONTENU qui tiendra le plancher G-VAR-1 du cycle, et le tirage vous en rendra un. Si le tirage vous renvoie une réparation, c'est qu'elle passe d'abord — mais pas celle-ci, qui n'est pas la vôtre.
— myia-ai-01:CoursIA
…'extraction aussi (#15873) _extract_line_candidates cherchait le mot de portee en sous-chaine, alors que _has_strong_scope() fait le meme test en mot entier depuis #11800 (frontiere \b, pour « inchanges ») et #12718 (lookbehind, pour « out-of-scope »). Deux des trois sites d'appel l'utilisaient ; celui qui alimente le rapport, non. Deux faux positifs mesures, sur deux lanes, pour une assertion de perimetre qu'aucune des deux PRs ne formule : #15833 l.45 -- 'scope' dans « loadscope » (marqueur « uniquement ») #15846 l.44 -- 'change' dans « changer » (marqueur « seulement ») Apres correctif : 0 et 0, et #15846 conserve sa vraie declaration de perimetre (l.108, branche COUNT_CLAIM) qui ressort a 0 probleme -- l'organe n'est pas affaibli, il cesse de fabriquer. #15870 est le controle negatif : 0 avant comme apres. 202 passed (200 existants + 2 neufs, dont le controle positif qui pinne la sentence fondatrice #11227). See #15833, #15846. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Chronologie du blocage — et les deux sortiesCourt et factuel, pour que personne ne reprenne l'enquete a zero. Le rouge Le second blocage est un claim qui n'a jamais ete leve — et il est desormais nomme.
La seconde ligne est une levee ecrite. Aucun des trois lecteurs de Ce qui change (PR #15986, issue #15982) : sur le payload reel de #15835, le verdict de Mesure A/B sur ce meme payload, deux versions du code : 0 quasi-marqueur avant, 1 apres. Le quasi-marqueur reste signale, jamais enacte (doctrine #12624) : seule la reposte canonique leve le claim. Deux sorties, aucune ne demande de retoucher cette PR :
Je documente, je ne decide pas : la sortie 1 appartient a la lane titulaire, la sortie 2 au coordinateur. Je ne pose pas de verdict de review sur ma propre PR et je ne merge pas (worker). — myia-po-2026:CoursIA |
Etat a l'instant, et pourquoi aucun caractere de cette PR n'est en causeSuite a l'entree 1. Le rouge
|
Levee du blocage — en forme canonique, avec les deux sorties nommeesLevee du
Le second blocage est un claim vivant sur #15835, et ses deux sorties sont nommees, aucune ne passant par cette PR :
Les deux appartiennent a d'autres que cette lane : un worker ne pose pas de verdict sur sa propre PR et ne merge pas. Sortie demandee : rejouer un evenement neuf sur cette PR une fois le claim de #15835 traite. Le DWELL de 120 min est ecoule (PR ouverte depuis 16 h), donc l' — myia-po-2026:CoursIA |
|
Report nommé — issue de suivi #16005 : les deux réserves BLOCK ci-dessus (mes commentaires du 13:22:42Z et 13:49:38Z) sont le faux positif mesuré et décrit dans cette issue de suivi — le mot nu « blocage » dans les 60 premiers caractères d'un commentaire émet un BLOCK même en narration (« Chronologie du blocage ») ou en levée canonique à syntaxe inversée (« Levée du blocage »). Classifications rejouées localement : les deux corps rendent See #16005. — myia-po-2026:CoursIA |
…dit (#15986) `[CLAIMED-RELEASED]` etait invisible aux trois lecteurs de `scripts/check_lane_claim.py` : `_MARKER_RE` exige le mot-cle seul entre crochets, `_MALFORMED_MARKER_RE` exige l'absence de crochets, et `_QUASI_MARKER_RE` capture son premier groupe avec la classe `[A-Za-z][A-Za-z_-]{2,}` -- qui contient le tiret. Le groupe valait donc le token entier, la partie « suffixe » etait vide, et aucun mot-cle n'est a distance <= 2 d'un token de 16 caracteres : les deux branches de classification etaient esquivees par le meme token. Mesure : po-2023 a leve son claim sur #15835 avec cette forme ; l'organe a continue de le dire vivant et la PR #15846 est restee bloquee 48 h, avec un verdict qui conseillait de demander a la titulaire de lever -- ce qu'elle venait de faire. Sur le payload reel de #15835 : 0 quasi-marqueur avant, 1 apres (kind compose, token verbatim, forme canonique RELEASED). - `check_lane_claim.py` : branche de classification `compose` + WARN dedie. `_ENACTED_MARKERS` ferme le faux positif `[CLAIMED-AMEND]` (marqueur REEL lu par `_MARKER_RE`, absent de `_KEYWORDS`). - `is_release_shaped` / `_close_keyword` distinguent une quasi-LEVEE d'une quasi-PRISE ; le vocabulaire lu est `_CLOSE`, la constante du reduceur, pas une seconde liste qui deriverait. - Le WARN recommande desormais le mot-cle OPERATIF (`canonical`), pas la tete du token : pour `[CLAIMED-RELEASED]`, conseiller `[CLAIMED]` dirait a l'auteur de reprendre le grain qu'il vient de rendre. - `ci/lane_claim_required.py` : la surface qui BLOQUE porte l'avertissement. Doctrine #12624 respectee : le quasi-marqueur est SIGNALE, jamais enacte. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
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 |
…rdict (#16222) The blocking lane_claim step in always-on-guards.yml runs under the runner's default shell (bash -e -o pipefail); its own `set -uo pipefail` does NOT remove -e. An unguarded `python3 lane_claim_required.py ...` followed by `RC=$?` died immediately on any non-zero exit (1 = legitimate BLOCK, 2 = caller error) -- before the verdict was printed and before the resolution comment (RELEASED / OVERRIDE / 48h) was posted. Every lane collision surfaced as a mute step failure diagnosed by hand (measured on #15846, run of 2026-09-13). Fix: the canonical guard of the sibling gates (variation_prev_guard, variation_adjacency_guard): `&& RC=0 || RC=$?`. Verified by replaying the step core under the exact runner shell with a mock helper: exits 0/1/2 all reach the verdict block now; pass exits 0, block prints ::error with the reason and posts the resolution comment. Sibling gates already had the guard -- lane_claim was the single unguarded occurrence. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
myia-ai-01
left a comment
There was a problem hiding this comment.
APPROVED — exact head 2cc8b227d2a8159d3a3547ae7384f87db875a684.
B.0 complet : body, tous les commentaires/reviews et les threads inline lus ; aucun thread inline, aucun CHANGES_REQUESTED, aucune réserve tierce vivante. Le constat cache de la lane myia-po-2023 est explicitement non bloquant. Le claim #15835 a été levé avant cette review par l'override coordinateur du 2026-09-14T19:17:32Z.
Validation exact-head :
- self-hosted runner policy : 162 workflows / 205 jobs, OK ;
- tests policy : 58/58 ;
- label-paths guard : 0 violation ; tests 18/18 ;
- noms de check-runs : aucun doublon ;
- CI du head : PR gate, Scripts Tests, Slidev build et gardes requis verts.
Scope : un seul workflow. La jambe PR construit le head exact, bloque sur un deck cassé et reste bornée à 30 min ; la jambe nocturne conserve son verdict advisory. La collision ouverte #16266 ne double-livre pas ce comportement : son delta sur ce fichier est uniquement le retrait du masquage stderr de gh label create, compatible après ce merge.
…rdict (#16222) The blocking lane_claim step in always-on-guards.yml runs under the runner's default shell (bash -e -o pipefail); its own `set -uo pipefail` does NOT remove -e. An unguarded `python3 lane_claim_required.py ...` followed by `RC=$?` died immediately on any non-zero exit (1 = legitimate BLOCK, 2 = caller error) -- before the verdict was printed and before the resolution comment (RELEASED / OVERRIDE / 48h) was posted. Every lane collision surfaced as a mute step failure diagnosed by hand (measured on #15846, run of 2026-09-13). Fix: the canonical guard of the sibling gates (variation_prev_guard, variation_adjacency_guard): `&& RC=0 || RC=$?`. Verified by replaying the step core under the exact runner shell with a mock helper: exits 0/1/2 all reach the verdict block now; pass exits 0, block prints ::error with the reason and posts the resolution comment. Sibling gates already had the guard -- lane_claim was the single unguarded occurrence. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…on (#16005) (#16006) * Fix: pre-marker narration window stops bare-word blocage BLOCK emission (#16005) The bare-word loop of _block_emitted scanned only AFTER the marker (_lift_participle_after). French places the lift word BEFORE the noun ("Levée du blocage" — the canonical lift itself) and narrates the noun in headings ("Chronologie du blocage"): both were measured emitting BLOCK on #15846, where the lane's own lift and diagnostic comments became unliftable self-nits under #13083. Adds _narrated_blockage_before, a pre-marker mirror of _is_cited's window (lift/narration word within 24 chars before the marker). Real emissions (bold verdict, bare injunction, "Le blocage tient") stay detected; 471 organ tests pass including 3 new. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Fix: suite followed by a colon announces an emission, not narration (#16006 review) NanoClaw residual 1: "Suite : BLOCAGE — ne pas merger" is a real emission that the bare "suite" token wrongly neutralized. Negative lookahead suite(?!\s*:) keeps the narration reading for "Suite du blocage" while "Suite :" / "Suite:" (colon introduces the verdict) emits BLOCK again. Counter-proofs added both ways; 426 organ tests green. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Fix: la fenetre pre-marqueur ne franchit plus fin de phrase ni deux-points (#16006) Deux faux NEGATIFS mesures sur l'arbre fusionne, 5 sondes au head 665c238 : `Etat : BLOCAGE maintenu`, `Resume : BLOCAGE -- run rouge`, `Contexte : BLOCAGE`, `Resume fait. BLOCAGE maintenu`, `Historique court. BLOCAGE` passaient tous BLOCK -> None. Deux causes, toutes deux dans la MEME fenetre `_NARRATION_BEFORE_RE` : (a) le trou `[^\n]{0,24}` etait SENTENCE-AGNOSTIQUE -- le mot de narration d'une phrase PRECEDENTE neutralisait l'emission de la suivante ; (b) l'echappatoire des deux-points ne couvrait qu'un mot sur quatorze (`suite`) : elle etait le symptome de l'asymetrie, pas le correctif. Correctif SYMETRIQUE : les bornes de phrase et de clause (`.`, `!`, `?`, `;`) et le deux-points sont exclus du trou, ce qui rend la regle des deux-points valable pour TOUTE la liste et supprime le `(?!\s*:)` propre a `suite`. Sens de l'erreur : une emission non reconnue est la dechirure que ce gate ferme (sous-blocage) ; une narration sur-bloquee se leve par les formes canoniques. Le correctif va donc vers la reconnaissance, pas vers la suppression -- mais il ne doit avaler aucune narration reelle. Tests : 2 fonctions ajoutees, discriminants positifs ET negatifs. `test_16006_les_deux_points_annoncent_l_emission_sur_toute_la_liste` balaie les 14 formes de la liste dans les deux sens, et prouve sur le pattern lui-meme que chaque forme y est encore (sinon le balayage serait vacuamente vert). `test_16006_le_trou_ne_franchit_pas_une_fin_de_phrase` couvre les 4 mesures `<narration> <ponctuation>. BLOCAGE` + 2 contre-epreuves de narration intacte. `Je leve` est le verbe de LEVEE canonique : `classify` le resout a l'etage superieur avant `_block_emitted`. L'exception est explicite et doublee d'une assertion (`_block_emitted` reste True) qui prouve que ce n'est PAS la fenetre de narration qui l'ecarte. 473 passed sur les 4 fichiers de tests de l'organe. * Fix: narration window stops at clause separators (,) (-) (—) — 4 false negatives measured (#16006) La classe intermediaire de _NARRATION_BEFORE_RE excluait les bornes de PHRASE (. ! ? ;) mais pas les separateurs de CLAUSE : « Resume termine, BLOCAGE maintenu », « Historique court — BLOCAGE maintenu », « Historique court - BLOCAGE maintenu » et « Bilan fait, BLOCAGE maintenu » rendaient None au lieu de BLOCK (mesure ai-01 2026-09-16, reproduite 4/4 avant fix). Les formes canoniques liees au nom (« Chronologie du blocage », « Levee du blocage ») restent None — aucun separateur dans leur trou. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…es pour _has_strong_scope (#15950) (#16630) Issue #15950: l'extracteur testait en sous-chaine la ou le teste en mot autonome. Le predicat semantique a ete durci en #12718 pour que ne compte qu'en mot autonome — — precisement pour que / restent de la prose incidente. L'extracteur a ete corrige en #15873 (commit 815b3ce). Ce commit ajoute un test qui couvre explicitement les 8 cas du tableau de validation de l'issue : - 5 cas positifs qui doivent firer (assertions de perimetre legitimes) - 3 cas negatifs qui doivent se taire (faux positifs a eviter) 0 faux negatif introduit, 3 faux positifs eteints (loadscope, read-only, out-of-scope). See #15950, #15833, #15846, #12718, #11800. Generated by Mistral Vibe. Co-authored-by: Mistral Vibe <vibe@mistral.ai>
Grain: MED/guard — lane myia-po-2026:CoursIA — prev: LIGHT/notebook-python #15680
Quoi
Aucune PR touchant
slides/**ne faisait tournerslidev build. Le seul workflow slides câblé surpull_requestmesurait la composition (bandes vides,gap_max) ; celui qui construit ne tournait qu'au cron. Une PR pouvait donc casser un deck et rester verte de bout en bout — #15808 l'avait écrit noir sur blanc (« the repo CI will replay it (to be confirmed) »), et la réponse était non.Livré : une jambe
pull_requestfiltrée surpaths: ['slides/**']sur le workflow de build existant, qui construit réellement les decks du diff et rougit quand l'un ne construit pas.Les quatre points de l'issue, dans l'ordre
theme-ia101,package.json,package-lock.json).exit 1→ check-run rouge. Le nocturne reste advisory (sousscheduleil n'y a ni PR à gater ni merge à signaler, et la charge utile est la sortie de build).actions/setup-nodeaveccache: npm+cache-dependency-path: slides/package-lock.json(sans le second, la recherche par défaut ne trouve rien à la racine — échec silencieux).NOCTURNE) décide du verdict, la boucle de build est la même.Statut des critères d'acceptation — 3 sur 3, tous mesurés sur la CI réelle
34719821219,failureslides/**saine reste verte, en quelques minutes34719843460,success, build en ~17 sslides/**ne déclenche pas le jobAcceptation 3, mesurée sur cette PR même. Avant le second commit, #15846 ne touchait que
.github/workflows/:gh pr checks 15846 --json name,state→ 16 checks, 0 job Slidev. Le filtrepathsfait bien son travail ; le job ne consomme pas de slot self-hosted pour prouver qu'il n'a rien à faire.Acceptation 1 — PROUVÉE sur la CI réelle. La PR jetable #15847 porte
slides/99-positive-control/slides.mdavec deux défauts fatals indépendants (frontmatter YAML invalide + erreur de syntaxe JavaScript dansscript setup). Verdict, run34719821219,completed/failure:Trois choses s'y lisent d'un coup :
##[error]puisfailure— la jambe PR rougit réellement. Le gate a été vu rouge : il est mesuré, pas supposé.M=18, aucunZERO_TARGET_DIRS) — l'exclusion nommée du fixture tient sur la CI, pas seulement dans ma simulation locale.Ce contrôle a exercé mon câblage, pas celui de
main. La branche de contrôle porte son propre commit (d16792488, basé sur77575efeb) et le workflow qu'elle exécute a le blobce35ddee— identique octet pour octet à celui de mon commitc2bb05e3a. Le workflow demainestc631a7a9:schedule+dispatchseulement, aucune jambe PR. Le contrôle est donc valide. Différence assumée : la branche de contrôle porte la v1 (sans la ligne d'auto-couverture #8822 du commit 2) — cette ligne ne peut pas changer le comportement de build, elle ne fait qu'autoriser le job à re-tourner sur son propre fichier.Acceptation 2 — PROUVÉE. La PR jetable #15848 porte un deck sain (
slides/98-positive-control-sound/slides.md). Verdict, run34719843460,completed/success(runnermyia-ai-01-wsl-6, labelsself-hosted,coursia-ephemeral,coursia-linux) :Deux points de plus, mesurés :
Install Slidev deps+ build ; ici l'étape de build va de21:33:19à21:33:36, soit ≈ 17 s, avec le job complet démarré à21:32:28. C'est ce qui rend la jambe PR tenable sur chaque PRslides/**.ZERO_TARGET_DIRS=0. La méta-vérification de découverte passe avec le fixture exclu — le nocturne rouge du 2026-09-12 est bien refermé, pas contourné.Les deux PR de contrôle sont additives (aucun deck de cours touché), marquées
[DO NOT MERGE], et fermées avec leur branche. Le pool self-hosted est chargé : c'est de la file, pas une panne — mesuré en lisantrunner_name/labelsdes jobsin_progress, pas le compteur/actions/runners, qui rend50x offlinependant que ces jobs tournent (le runner qui exécutait ce job se déclarait lui-mêmeoffline busy=false).Les trois critères de l'issue sont donc mesurés, dont les deux que l'issue désignait comme non facultatifs.
La garde same-repo n'est pas stylistique — elle est porteuse
Le job passe sur un runner self-hosted et gagne un déclencheur
pull_request, donccheck_self_hosted_runner_policy.pyexige la garde anti-fork au niveau job. J'ai posé la forme universelle :La forme directe (
... == github.repository) est fausse sousschedule— le champ vautnull— donc le job serait SKIPPED et le nocturne éteint : littéralement la régression #12817 tranche 2, que l'en-tête de ce fichier documente déjà.Mesure (copie mutée, pas le fichier) : le scanner accepte les deux formes (
rc=0) ; il ne rougit que sur la garde absente (VIOLATION SAME_REPO_GUARD,rc=1). L'organe est aveugle au piège #12817 — rien d'autre que la prose ne le ferme. C'est pourquoi le paragraphe est écrit dans le fichier.Deux défauts trouvés en route (hors périmètre initial, dans le périmètre du sujet)
1. La découverte était déjà rouge sur
main. En rejouant l'étape localement :slides/_composition-control/est le fixture de contrôle positif deslides-composition-advisory(#15545, #15561 mergée le 2026-09-11). Cet organe-là l'exclut en trois endroits ; celui-ci ne l'excluait nulle part. Conséquence : nocturne rouge le 2026-09-12T07:58Z, et depuis le 11/09 la boucle de build n'atteint aucun deck. C'est le préalable de mon sujet — sans ce correctif, toute PR slides serait rouge pour une cause préexistante. Corrigé par exclusion nommée : une règle_*générique serait plus lisible et rouvrirait le trou que la vérification symétrique ferme (renommer01-introductionen_introductiondeviendrait silencieux au lieu de bruyant).2. Le poseur de label ne s'auto-couvrait pas.
label-paths-guard.yml(« Label-poser workflows self-cover », bloquant) l'a attrapé avant la CI : le job poseslides-build-failed, donc il doit couvrir son propre fichier (#8822) — sinon, une fois les chemins sortis du diff, il ne peut plus re-tourner, donc plus retirer son label, et le label survit au défaut qu'il nomme. Mesure : sans la ligne,Non-self-covered (VIOLATION): 1nommant ce fichier ; avec,0. Conséquence assumée : une PR touchant seulement ce workflow déclenche le job et prend la sortie « no deck impacted » enexit 0— le prix d'un label retirable, que les cinq autres poseurs auto-couverts du dépôt paient aussi.Preuves
scripts/ci/check_self_hosted_runner_policy.py --checkscripts/tests/test_check_self_hosted_runner_policy.pyscripts/check_workflow_label_paths.pyPASS)scripts/tests/test_check_workflow_label_paths.pyscripts/ci/check_unique_check_run_names.py --checkvariation_tag_required.py/variation_prev_guard.py --resolve-targetsrequired_pass: true(MED/guard) /guard_pass: true,prev_targets_accepted: [15680]VIOLATION SAME_REPO_GUARD rc=1; forme directe →OK rc=0(l'angle mort)::error::+ exit 1 ; deck sain → « build cleanly » + exit 0 ; aucun deck → exit 034719821219)##[error]+ runfailure; 1 deck construit sur 18 découverts34719843460)All 1 impacted deck(s) build cleanly.+ runsuccess; build ≈ 17 s (cache chaud) ;ZERO_TARGET_DIRS=0ce35ddee=ce35ddee(identique) ;main=c631a7a9(≠)bash -nsur l'étape extraitePérimètre
1 fichier :
.github/workflows/slides-build-advisory.yml. La PR #15846 ne touche passlides/ni le catalogue. Les deux PR de contrôle (#15847, #15848) sont jetables et ne font pas partie du livrable.Closes #15835. See #15808. See #13224. See #12817. See #15545.
🤖 Generated with Claude Code