Repository navigation
Fix(ci): un rc pytest de collecte imprime un verdict de contenu SRC_DRIFT (hot_subset, always-on-guards) #22435
Description
Part of #10416 (motif « un garde aveugle a son SUJET »).
Le defaut
.github/workflows/always-on-guards.yml (etape Hot-subset ratchet translation SRC_DRIFT, id hot_subset, l.1361-1376) imprime un verdict de contenu quelle que soit la raison du code retour non nul :
python -m pytest scripts/translation/tests/test_hot_subset_ratchet.py -q && RC=0 || RC=$?
if [ "$RC" -ne 0 ]; then
echo "::error::Hot-subset ratchet : SRC_DRIFT sur un grain de traduction deposee ou definition du hot-subset derive. ..."
exit 1
fiOr pytest distingue deja ces cas par son code retour : 1 = des tests ont echoue (le seul qui dise quelque chose du contenu), 2 = execution interrompue (erreur de collecte, ImportError), 3 = erreur interne, 4 = erreur d'usage. Un rc 2 signifie que la mesure n'a pas eu lieu — la PR n'a pas ete testee.
Mesure (2026-10-25)
Le meme faux verdict a ete releve sur deux PR distinctes, et refute localement a la tete exacte :
| PR | tete | jambe CI | repro locale sur cette tete |
|---|---|---|---|
| #22130 | 402871d9cc |
Always-on guards — Hot-subset ratchet : SRC_DRIFT |
2 passed in 29.72s |
| #22264 | 07885aafc8 |
Always-on guards — Hot-subset ratchet : SRC_DRIFT |
2 passed in 28.47s |
La cause materielle, lue dans le log du step et non dans son annotation : ImportError: cannot import name 'TerminalFormatter' from 'pygments.formatters.terminal' dans le toolcache partage /opt/hostedtoolcache/Python/3.11.17/x64/lib/python3.11/site-packages — la meme jambe reussit sur une machine au toolcache sain (myia-ai-01-wsl-5), et echoue sur celles qui portent le 3.11.17 empoisonne (myia-po-2027-linux-docker-1, myia-ai-01-wsl-3).
Consequence : deux PR vertes sur leur contenu portent un rouge qui nomme une derive de traduction inexistante, et le gate PR gate qui agrege cette jambe les bloque.
Correctif propose
Distinguer les deux regimes, en suivant le precedent maison de #8819 (lean-visibility-advisory.yml : « a echoue -- non mesure, pas sans defaut », ::warning:: + exit 0) :
- rc 0 : vert ;
- rc 1 : verdict de contenu, rouge, message actuel inchange ;
- rc >= 2 : la mesure n'a pas eu lieu.
::warning::explicite qui dit que ce n'est pas un verdictSRC_DRIFT, puis :- si la PR touche l'organe lui-meme (
scripts/translation/**,scripts/notebook_tools/**), la cause est attribuable a la PR → rouge, en le disant ; - sinon cause environnementale →
UNMEASURED, non bloquant, signale sans mentir.
- si la PR touche l'organe lui-meme (
Le git diff --name-only <base>...HEAD ne coute aucun reseau ici : le workflow checkout en fetch-depth: 0 (les arbres sont deja la, blob:none ne concerne que les blobs).
Acceptance
- un rc 2 ne produit plus le message
SRC_DRIFT; - un rc 1 continue de bloquer avec le message actuel ;
- un rc 2 sur une PR qui touche
scripts/translation/**bloque, en nommant la cause attribuable ; - le commentaire de l'etape dit lequel des trois regimes a parle.
Portee non couverte ici
Les deux autres jambes de la meme PR (#22264) tombent sur fetch-pack: invalid index-pack output / early EOF / exit 128 — echec de checkout sur clone partiel, classe distincte, a traiter separement.
Activity
jsboige commentedon Oct 25, 2026
[CLAIMED] lane myia-po-2024:CoursIA -- paths: .github/workflows/always-on-guards.yml
Grain: MED/guard — lane myia-po-2024:CoursIA — prev: MED/notebook-python #22471
Je prends les quatre points d'acceptation : rc 2 (et au-dela) cesse d'imprimer un verdict de contenu, rc 1 continue de bloquer avec le message actuel, rc 2 sur une PR qui touche
scripts/translation/**ouscripts/notebook_tools/**bloque en nommant la cause attribuable, et le commentaire de l'etape dit lequel des trois regimes a parle. Le correctif sera verifie par execution locale de l'etape sur les trois codes retour, pas par lecture.Fix(ci,#22435): le ratchet hot-subset distingue non-mesure et verdict…
jsboige commentedon Oct 25, 2026
[DELIVERED] lane myia-po-2024:CoursIA -- PR #22472
Les quatre points d'acceptation, mesures sur la tete
2c616b64229:NON MESUREsort en::warning::+ exit 0 et dit explicitement « ce n'est PAS un SRC_DRIFT » (cas fondateurs Fix(notebooks,#13410): fusionner 2 paires de lectures scindees (GameTheory) #22130, Add(quantconnect,#17040): densite pedagogique QC-Py-28c (1053->1220) et Kelly_companion-Fractional (660->1251) #22264).VERDICT DE CONTENU).scripts/translation/**ouscripts/notebook_tools/**bloque enNON MESURE ATTRIBUABLE, en nommant les fichiers du diff.MESURE-VERT/VERDICT DE CONTENU/NON MESURE(+ATTRIBUABLE/ATTRIBUTION INDECISE).La preuve n'est pas une relecture de prose : cinq nouveaux tests executent le corps de l'etape extrait du YAML (stubbe, sans reseau) — c'est le defaut d'origine que le shell disait autre chose que ce qu'il mesurait.
11 passedsurscripts/tests/test_hot_subset_ratchet_wiring.py,2 passedsur le ratchet lui-meme (rc 0 = regime nominal demain).Fix(ci,#22435): regime hot-subset exporte vers l'agregat + second che…
Docs(ci,#22435): enumerer le rc 5 (aucun test collecte) dans le comme…
Fix(ci,#22435): le ratchet hot-subset distingue non-mesure et verdict…
test(ci,#22435): adapter le harnais hot-subset a l'implementation sur…
Fix(ci,#22435): un rc pytest de collecte n'imprime plus un verdict de…