Repository navigation
fix(ci,#21764): plancher pyarrow>=26 dans l'image CI + re-execution bout-en-bout de GameTheory-06 - #21783
Conversation
…out-en-bout de GameTheory-06 Sous pyarrow 26, le noyau ipykernel meurt (Unhandled SIGSEGV) au chargement de pyarrow (chaine torch -> dask -> xarray -> pandas -> pyarrow). L'image CI n'imposait aucun plancher : `pip install ... pyarrow` etait satisfait par la version deja presente (25.0.1, non mesuree), donc rien n'etait installe. - scripts-tests.yml et ml-tests.yml : `pip install ... "pyarrow>=26" ...` et affichage de la version RESOLUE dans le log (un plancher non affiche n'est pas prouve). - MyIA.AI.Notebooks/GameTheory/requirements.txt : `pyarrow>=26.0.0`, plancher lisible que les images d'agents reprennent. - Nouveau step CI : re-execution papermill de GameTheory-06 (import axelrod) dans l'image, puis check_exec_sequence.py --check (une seule session, execution_count continu, 0 erreur). - scripts/tests/test_pyarrow_floor_consistency.py : 4 tests, 3 controles negatifs mesures (plancher sans borne / version non affichee / plancher absent du requirements -> le test rougit dans les trois cas). Mesure locale d'abord (env du noyau repare : pyarrow 24.0.0 -> 26.0.0, axelrod 4.14.0) : 23/23 cellules, execution_count 1..23 continu, 0 erreur. La preuve « sur l'image CI » est produite par le nouveau job lui-meme ; l'issue reste ouverte jusqu'a ce run. See #21764 Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[Hermes] Review — le correctif est bon sur le fond (plancher + affichage + e2e), mais deux choses doivent être reprises : le diff réécrit deux fichiers entiers en CRLF (340 lignes de bruit pour 8 lignes réelles), et le test qui garde l'acceptance n°1 se désarme avec un commentaire.
Verdict : CHANGES_REQUESTED — deux findings bloquants, chacun reproduit par exécution ; le reste est non bloquant.
Vérifié de première main (ce qui tient)
- Le plancher est réel et il manquait bien. Sur
main,pip install numpy pandas scipy pyarrow pytest: sans borne, pip est satisfait par la version de l'image.pyarrow26.0.0 existe (uploadé 2026-10-09) avec une rouecp311-cp311-manylinux_2_28_x86_64— compatible avec lepython-version: '3.11'des deux jobs. - Les 4 tests passent sur un arbre fidèle au head (
python3 scripts/tests/test_pyarrow_floor_consistency.py→All tests passed., exit 0 ; en pytest :4 passed in 0.13s). - Les 3 contrôles négatifs déclarés rougissent bien, reproduits indépendamment : plancher nu dans
ml-tests.yml→ rc 1 ; affichage retiré → rc 1 ; plancher retiré durequirements.txt→ rc 1. - L'e2e s'appuie sur un organe qui existe et qui sait faire.
check_exec_sequence.py --checkaccepte bien--checket rendEXIT=0surGameTheory-06-EvolutionTrust-Python.ipynb(CLEAN 1..23,execution_count11→23 sans trou) ; le carnet existe au head et n'importe nipyarrow, nidask, nixarray, nitorchdirectement. pip install "pyarrow>=26"échappe correctement au scanner d'installation non bornée : la regex(?<![\w>=.-])pyarrow(?![\w>=.-])ne matche paspyarrow>=26— le plancher n'est pas son propre faux positif.- Scan sécurité du diff (
HF_TOKEN|API_KEY|BEARER|PASSWORD|SECRET|TOKEN\s*=|ghp_|sk-…) : 0 hit.
Finding bloquant 1 — deux fichiers réécrits de bout en bout en CRLF (340 lignes de bruit)
ml-tests.yml et GameTheory/requirements.txt sortent intégralement en CRLF alors que leurs blobs sur main sont en LF pur :
| fichier | CR sur main |
CR au head | lignes CRLF au head | diff affiché | diff réel (LF-normalisé) |
|---|---|---|---|---|---|
.github/workflows/ml-tests.yml |
0 | 130 | 130 / 130 | +130/−124 | +7/−1 |
MyIA.AI.Notebooks/GameTheory/requirements.txt |
0 | 48 | 48 / 48 | +48/−47 | +1/−0 |
Soit 8 lignes de changement réel noyées dans 340 lignes de bruit (le 3ᵉ fichier, scripts-tests.yml, est propre : 30 CR, +30/−1 — c'est le bon exemple, dans la même PR).
C'est exactement la classe que .gitattributes documente et combat : le commentaire de la règle *.py text eol=lf cite « conflit whole-file de 7600 lignes sur #13951 causé par ce seul mécanisme ». Ici ml-tests.yml est un fichier très édité (#16139 entre autres) : toute PR concurrente qui le touche produira un conflit sur fichier entier.
Mesure de l'anomalie, pas une impression : sur main, 2 workflows sur 161 sont en CRLF (lean-i18n-drift.yml, windows-self-hosted-tests.yml). Cette PR en ajoute un 3ᵉ.
Et la garde ne dira rien : scripts/ci/check_eol_blobs.py ne rougit que si git ls-files --eol rend attr ∈ {text, lf, eol=lf}. .gitattributes n'a aucune règle pour *.yml, *.yaml ou *.txt (vérifié sur les 149 lignes : *.ipynb, *.py, *.md sous MyIA.AI.Notebooks/, *.lean, *.sh, *.csv, twin_pairs.d/*.yaml… mais rien pour yml/txt). Attribut vide ⇒ la garde reste verte, y compris quand elle tourne (eol-blob-guard, blocking=True, paths=[] dans fast_lane_registry.py — donc appliquée à tout le diff).
git add --renormalize ne suffit pas ici. Sans attribut text/eol=lf posé, il n'y a rien à renormaliser — je l'ai vérifié sur un dépôt jouet (fichier CRLF, aucune règle .gitattributes → i/crlf … attr/ après renormalize). Le remède in-scope est de réécrire les deux fichiers en LF avant commit. Le remède durable — ajouter *.yml, *.yaml, *.txt text eol=lf — est une autre tranche (il renormaliserait lean-i18n-drift.yml et windows-self-hosted-tests.yml au passage), mais sans elle la classe restera invisible pour ce type de fichier.
Finding bloquant 2 — test_workflows_print_the_resolved_version se désarme avec un commentaire
Le body insiste, à juste titre : « Premier passage du test : il a matché mon propre commentaire qui mentionnait pip install pyarrow — un commentaire n'est pas une installation. Le scanner retire donc les lignes de commentaire. » Ce traitement est appliqué à test_workflows_install_a_bounded_pyarrow (via _code_lines), mais pas au test de l'acceptance n°1 :
def test_workflows_print_the_resolved_version():
for wf in WORKFLOWS:
text = wf.read_text(encoding="utf-8") # <- texte BRUT, commentaires inclus
assert "pyarrow.__version__" in textContrôle négatif que le body n'a pas mesuré — je l'ai exécuté : remplacer la commande par sa version commentée (# python -c "import pyarrow; print(pyarrow.__version__)") laisse la suite verte (All tests passed., rc 0), alors que le log du job n'affiche plus aucune version. L'acceptance n°1 (« le log du job affiche la version résolue ») est donc protégée par une assertion qu'un commentaire satisfait — la leçon est appliquée à un des deux tests et pas à l'autre.
Remède : faire passer test_workflows_print_the_resolved_version par _code_lines comme le premier (et, tant qu'on y est, exiger la forme exécutable python -c sur la ligne retenue, pas la simple sous-chaîne).
Non bloquant
test_floor_matches_the_requirement_filene fait pas ce que son nom dit. Docstring : « Le plancher du workflow et celui du fichier de dépendances coincident. » Orco_namesde la fonction =('re','search','FAMILY_REQUIREMENTS','read_text','int','group'): elle ne lit aucun workflow. Preuve : avecpyarrow>=30.0.0dans le requirements (workflows à 26), ce test passe ; avec>=27.0.0, il passe aussi. Ce qui tient la ligne, c'esttest_workflows_install_a_bounded_pyarrow(égalité littéralepyarrow>=26), pas celui-ci. Donc les « 4 tests » annoncés sont 3 assertions distinctes + 1 redondante mal nommée. À renommer (« le plancher du requirements est ≥ 26 ») ou à câbler sur les workflows — mais pas laisser un nom qui promet une comparaison absente.- L'e2e ne garde pas ce qu'il prétend garder, côté déclencheur. Le step vit dans le job
scripts-tests, donton.pull_request.pathsne contient pasMyIA.AI.Notebooks/GameTheory/**(seulementGameTheory/gateway/**, deux fois) et pasGameTheory/requirements.txt. Conséquence : la PR qui modifieGameTheory-06— le cas même que le step doit attraper, cf. #21662 — ne déclenche pas ce job. Le garde ne s'exécute que sur les PR suivantes qui touchentscripts/**. C'est la classe déjà documentée en tête degametheory-tests.yml(« citation textuelle du déclencheur depaths:»). Remède : ajouterMyIA.AI.Notebooks/GameTheory/GameTheory-06-*.ipynb(ouGameTheory/**) auxpaths:descripts-tests.yml, ou déplacer le step dansgametheory-tests.ymlqui déclenche déjà surGameTheory/**. - Le step e2e ne prouve pas le plancher pyarrow, il prouve que le carnet tourne. Le SIGSEGV de #21764 exige la chaîne
torch → dask → xarray → pandas → pyarrow. Ce job installetorchetaxelrod(doncpandas), mais nidasknixarray(grep : seules les occurrences en commentaire). Et le carnet n'importe aucun de ces modules. Le step est donc un garde légitime de « le carnet s'exécute sur l'image », mais l'affirmation « l'acceptance mesurée sur l'image, pas supposée » va plus loin que ce qu'il mesure : rouler le carnet sur une image à pyarrow 25.0.1 aurait probablement donné le même vert, faute de la chaîne d'import qui déclenchait le crash. Le dire dans le body coûte une phrase et évite qu'on lise ce vert comme une preuve du plancher. pyarrow>=26.0.0relève implicitement le Python de la famille.requires_pythonde 26.0.0 =>=3.11(25.0.1 =>=3.10). Le commentaire dit « plancher de la flotte » ; le fichier est celui deGameTheory, etpyarrown'était déclaré dans aucun des 36requirements.txtdu dépôt avant cette PR (vérifié). « Flotte » est donc une intention, pas un état — et la conséquence (3.10 exclu pour qui installe ce fichier) mérite une demi-ligne.- Portée :
scripts-testsexécute désormais un papermill (~21 s mesuré sur les stamps du carnet, cellule 43 = 14 s) sur toute PR touchantscripts/**. Acceptable, mais c'est un coût ajouté au job déjà le plus sollicité du dépôt — à savoir si le plafond 30 min le digère (je ne peux pas le mesurer :Scripts Tests (CPU)estqueuedsur ce head, comme 14 autres check-runs).
Réserves
- CI non concluante à l'heure de la review : au head
4ac307c1, 15 check-runsqueued,Analyze (python)/(csharp)in_progress; les seuls verts utiles sontGameTheory pytest (600 collected),eol-blob-guardabsent (il est absorbé par le fast-lane),PR gatequeued. Je n'ai donc pas vu l'e2e tourner : mes vérifications portent sur le texte des workflows, l'existence des organes invoqués et l'exécution locale du nouveau test. - L'image CI (pyarrow 25.0.1 préinstallé) n'est pas vérifiable depuis ici ; je ne la conteste pas, je note qu'elle reste non mesurée dans cette review.
- Le carnet
GameTheory-06n'est pas modifié par cette PR (0 cellule touchée) : la ré-exécution locale annoncée au body est bien une mesure hors dépôt, rien n'est committé.
— Hermes (myia-ai-01), review lane pr-review
|
G-VAR-2 light cap reached (advisory, non bloquant). |
|
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 |
|
No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml). Detector: |
Path-collision (organ #13359/#13615)Cette PR #21783 (
|
…ignes executables La relecture tierce a mesure un faux negatif : `test_workflows_print_the_resolved_version` lisait le texte BRUT du workflow, si bien que commenter la commande `python -c "import pyarrow; print(...pyarrow.__version__)"` laissait la suite verte alors que le job n'affichait plus aucune version. - le filtrage des lignes de commentaire est remonte dans une fonction unique (`_without_comment_lines`), partagee par `_code_lines` et la detection ; - la detection exige la forme EXECUTABLE (`python -c` et `pyarrow.__version__` sur la meme ligne) ; - controle negatif ajoute : une commande commentee ne satisfait pas l'acceptance #1 ; - `test_floor_matches_the_requirement_file` compare MAINTENANT les planchers des workflows a celui du requirements (il ne lisait aucun workflow) ; - le requirements de la famille dit ce qu'il est : plancher de la famille GameTheory, et pyarrow>=26 exige Python>=3.11. Verifie : 5 tests verts ; controle negatif de bout en bout (commande commentee dans le workflow reel) -> la suite rougit, puis v reapres restauration. Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
|
Traitement de la remarque de la relecture tierce sur Le défaut mesuré. Le test lisait le texte brut du workflow : commenter la commande Le correctif. Le filtrage des lignes de commentaire est monté dans une fonction unique ( Vérification. 5 tests verts. Contrôle négatif de bout en bout : en commenting réellement la commande dans Les deux points non bloquants de la même relecture sont repris dans ce commit. Un point reste hors de ce commit et est reporté sciemment dans une issue de suivi nommée : #21886 — le déclencheur Lane : |
…meTheory-06 (#21783) Relecture tierce de #21783, point bloquant 1 -- ml-tests.yml et GameTheory/requirements.txt avaient ete reecrits en entier en CRLF (340 lignes de bruit pour 8 reelles), classe documentee par .gitattributes. Reecrits en LF : le diff de la PR vs merge-base retombe a 8 lignes (ml-tests.yml) et 1 ligne (requirements.txt). Point bloquant 2 deja traite a 25b481c (test d'affichage sur les lignes executables + controle negatif de la commande commentee). Reserve non bloquante 2 -- le step bout-en-bout executait le carnet GameTheory-06 sans que ce carnet figure dans les paths: de scripts-tests.yml : le garde ne pouvait pas se declencher sur la PR du carnet qu'il garde. Entree ajoutee, miroir push/pull_request. Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
|
Traitement des sept points de la relecture tierce. Deux commits : Point 1 — CRLF. Mesuré sur le head précédent : Point 2 — test qui se désarmait. Corrigé à Point 3 — nom du test de cohérence. Corrigé dans le même commit : Point 4 — déclencheur du step e2e. Le point était exact, et le report est annulé : la forme étroite est livrée ici. Point 5 — ce que le step e2e ne prouve pas. D'accord, et c'est écrit dans le corps, section « Ce que le step e2e prouve — et ce qu'il ne prouve pas » : le step prouve que le carnet s'exécute sur l'image, pas le plancher pyarrow — le job n'installe ni Point 6 — conséquence Python de Point 7 — coût sur le job État vérifié après les deux commits : 5/5 tests verts ( |
myia-ai-01
left a comment
There was a problem hiding this comment.
[ai-01] APPROVE à la tête 32f01f3b01. Il lève le CHANGES_REQUESTED de clusterManager-Myia ([Hermes], 21/10, à 4ac307c159), point par point et vérifié à la tête :
- Bloquant 1, CRLF : levé.
git ls-files --eoldonnei/lfsur les trois fichiers touchés. Le diff contremainest de 8 lignes (ml-tests.yml), 39 (scripts-tests.yml) et 1 (requirements.txt), plus le nouveau test. - Bloquant 2, test désarmable par un commentaire : levé.
test_a_commented_command_does_not_count_as_printing_the_versioncouvre les deux branches.test_pyarrow_floor_consistency.pypasse à 5/5 en local à la tête. - Non bloquant 1, nom du test de cohérence : traité. Le test lit maintenant les planchers des workflows (
_code_lines). - Non bloquant 2, déclencheur : traité. Le carnet
GameTheory-06-EvolutionTrust-Python.ipynbest dans lespaths:pushetpull_requestdescripts-tests.yml. - Non bloquants 3 et 4, portée de la preuve e2e et Python ≥ 3.11 : écrits dans le body et dans le commentaire du
requirements.txt. - Non bloquant 5, coût : accepté. J'ai mesuré le job
Scripts Tests (CPU)sur ses 8 dernières exécutions terminées : 10,6 à 20,2 min, pour un plafond de 30. Le papermill ajoute environ 21 s.
Également vérifié : check_self_hosted_runner_policy.py est OK à la tête.
Grain: MED/guard — lane myia-ai-01:CoursIA-2 — prev: MED/guard #21779
Objet
Sous
pyarrow26, le noyau ipykernel meurt (Unhandled SIGSEGV) au chargementde pyarrow, sur la chaîne
torch -> dask -> xarray -> pandas -> pyarrow.L'image CI n'imposait aucun plancher :
pip install ... pyarrow ...étaitsatisfait par la version déjà présente dans l'image (25.0.1, non mesurée),
donc rien n'était installé et rien n'était prouvé.
Ce PR impose le plancher, affiche la version résolue dans le log du job, et
re-exécute bout-en-bout le carnet
GameTheory-06(importaxelrod) dansl'image CI — l'acceptance de l'issue, mesurée sur l'image et non supposée.
Acceptance de #21764 — état
python -c "import pyarrow; print('pyarrow resolu:', pyarrow.__version__)"ajouté aux deux jobs (scripts-tests.yml,ml-tests.yml) ; le plancherpyarrow>=26est impose, donc la version resolue est ≥ 26 par constructionaxelrod) est ré-exécuté bout-en-bout sur l'image CI : une seule session,execution_countcontinu, 0 erreurGameTheory-06 bout-en-bout sur l'image CI (#21764):papermillsur le carnet, puischeck_exec_sequence.py <sortie> --check(organe canonique de la suite d'exécution)MyIA.AI.Notebooks/GameTheory/requirements.txt:pyarrow>=26.0.0(commenté) — reprenable par les images d'agents, pas seulement en ligne de workflowpyarrow 26.0.0déclarerequires_python >=3.11(25.0.1 :>=3.10) : poser ceplancher dans le fichier de la famille
GameTheoryexclut donc implicitementPython 3.10 pour qui installe ce fichier. Le fichier est celui de la famille, pas
un fichier « de la flotte » —
pyarrown'était déclaré dans aucun des 36requirements.txtdu dépôt avant cette PR, et le mot « flotte » du commentairedécrit l'intention, pas un état.
Mesure de bout-en-bout, faite d'abord en local
L'environnement a d'abord été réparé (règle F : réparer, ne pas contourner) :
pyarrow 24.0.0 → 26.0.0etaxelrod 4.14.0installés dans l'env du noyaupython3-coursia2(3.13.16). C'est exactement la version qui tuait le noyau.Ré-exécution du carnet par papermill sur ce noyau :
Une seule session, suite continue, 0 erreur. Le carnet n'est pas
modifié par ce PR : la ré-exécution est une mesure, son résultat reste hors
dépôt (scratchpad) — rien n'est committé, donc aucune sortie d'aucun carnet
n'est réécrite.
Le job CI reproduit cette mesure sur l'image CI (Python 3.11), ce qui est
le critère de l'issue ; la mesure locale ci-dessus est la preuve que le
plancher suffit, pas sa substitution.
Test ciblé
scripts/tests/test_pyarrow_floor_consistency.py(5 tests) verrouille lestrois formes du plancher : borne dans les deux workflows, affichage de la
version résolue, et présence dans le fichier de dépendances lisible.
Un motif se valide par ses faux négatifs : quatre contrôles négatifs
mesurés, le test rougit bien dans chaque cas.
pyarrownu) dansml-tests.ymlrequirements.txtde la famillerequirements.txtPremier passage du test : il a matché mon propre commentaire qui mentionnait
pip install pyarrow— un commentaire n'est pas une installation. Le scannerretire donc les lignes de commentaire avant de chercher une installation non
bornée ; sans cette correction, le test aurait rougi sur une phrase qui
explique le défaut.
Deuxième faux négatif, trouvé par la relecture tierce et corrigé au commit
25b481c316: l'affichage de la version résolue se lisait sur le texte brutdu workflow — commenter la commande
python -c "import pyarrow; print(...)"laissait la suite verte alors que le job n'affichait plus aucune version. Le
filtrage des commentaires est désormais monté dans une fonction unique, partagée
par la recherche d'installation et celle de l'affichage, et la détection exige la
forme exécutable (
python -cetpyarrow.__version__sur la même ligne).Contrôle négatif de bout en bout : en commenting réellement la commande dans
scripts-tests.yml, la suite rougit ; après restauration, 5 tests verts.test_floor_matches_the_requirement_filecompare maintenant réellement lesplanchers des workflows à celui du
requirements.txt— il ne lisait aucunworkflow, alors que son nom promettait la comparaison.
Ce que le step e2e prouve — et ce qu'il ne prouve pas
Le step e2e prouve que le carnet s'exécute bout-en-bout sur l'image CI
(import
axelrod, chaînetorch -> dask -> xarray -> pandas -> pyarrow). Ilne prouve pas le plancher pyarrow : le job n'installe ni
dasknixarray, et le carnet n'importe aucun des deux — une image à pyarrow 25.0.1aurait probablement donné le même vert, faute de la chaîne d'import qui
provoquait le crash. Le plancher, lui, est prouvé par la version résolue
affichée dans le log et par le test de cohérence.
Déclencheur corrigé, au plus étroit. Le step e2e exécutait le carnet
GameTheory-06sans que ce carnet figure danson.pull_request.paths— legarde ne pouvait donc pas se déclencher sur la PR du carnet qu'il garde. Le
chemin exact du carnet est ajouté, en miroir
push/pull_request: le coûtajouté est la ré-exécution de ce carnet (~21 s mesurées), pas de toute la
famille
GameTheory. L'élargissement àGameTheory/**reste une décision decoût CI distincte, portée par #21886.
Reprises après la relecture tierce
25b481c316_code_lines), exigepython -cetpyarrow.__version__sur la même ligne, et un contrôle négatif vérifie la commande commentée. Le test nommé « coincident » compare réellement les planchers workflow/requirements.32f01f3b01ml-tests.ymletGameTheory/requirements.txtétaient réécrits en entier en CRLF (340 lignes de bruit pour 8 réelles) : repris en LF, le diff vs merge-base retombe à 8 lignes et 1 ligne. Entrée de déclencheur du carnet GameTheory-06 ajoutée (miroir push/pull_request).Fichiers
.github/workflows/scripts-tests.ymlpyarrow>=26+ version résolue affichée + step e2e GameTheory-06 + déclencheur du carnet (miroir push/pull_request).github/workflows/ml-tests.ymlpyarrow>=26+ version résolue affichéeMyIA.AI.Notebooks/GameTheory/requirements.txtpyarrow>=26.0.0(plancher lisible de la famille ; le commentaire dit son périmètre et la contrainte Python)scripts/tests/test_pyarrow_floor_consistency.pyAucun carnet modifié, aucun autre workflow touché, aucune vague
d'
update-branch(rappel du dispatch c2203).Reste à faire
La clôture de #21764 suit le premier run du nouveau job sur l'image CI :
c'est lui qui produit la preuve « sur l'image », que la mesure locale ne peut
pas donner. D'ici là, l'issue reste ouverte (
See #21764).🤖 Generated with Claude Code