Skip to content

Fix(GameTheory): ponts PythonNet de GT-06, GT-07, GT-13 et GT-17 sous Linux et macOS (hors flotte) - #18774

Merged
myia-ai-01 merged 1 commit into
mainfrom
claude/affectionate-mccarthy-6dvuea
Oct 3, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
claude/affectionate-mccarthy-6dvuea

Conversation

@jsboige

@jsboige jsboige commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Hors flotte : PR de la session cloud d'agnosticisme du mainteneur (branche claude/*, exemption #17713, rôle décrit dans docs/reference/agent-cloud-agnosticisme.md). Pas de tag Grain:, pas de lane. See #17654, sous l'EPIC de parité Linux #10643. Suite de #18694 (ponts Gambit et nashpy de GameTheory, mergée).

Summary

  • Quatre notebooks C# de GameTheory chargent CPython par pythonnet pour invoquer le moteur de référence de leur jumeau Python : axelrod (GT-06), pyspiel/OpenSpiel (GT-07, GT-13, GT-17).
  • Hors du poste Windows de la flotte, aucun ne trouvait de CPython utilisable :
    • GT-07, GT-13, GT-17 prennent PYTHONNET_PYDLL, sinon un chemin C:\…\python31x.dll codé en dur ;
    • GT-06 a une branche Linux et macOS, mais elle prend la première libpython3.* venue, sans vérifier qu'elle importe axelrod.
  • Mesuré sur un clone vierge Linux, PYTHONNET_PYDLL non définie, versions de main :
Notebook Échec sur main
GT-06 PythonException: No module named 'axelrod' (la libpython3.13 prise n'a pas axelrod)
GT-07 DllNotFoundException: Could not load C:\Users\…\Python311\python311.dll
GT-13 DllNotFoundException: Could not load C:\Python313\python313.dll
GT-17 DllNotFoundException: Could not load C:\Python313\python313.dll
  • Après correction, les quatre s'exécutent de bout en bout sous Linux. Les résultats calculés sont identiques à la base.

Changes

Code, dans la cellule du pont de chaque notebook :

  • La recherche existante est conservée telle quelle : PYTHONNET_PYDLL, puis le CPython Windows du poste de la flotte (GT-07, GT-13, GT-17), ou la recherche Windows de GT-06 (installations LOCALAPPDATA, racines Conda, dépendances natives).
  • Quand elle ne désigne aucun fichier existant, une nouvelle fonction InitPythonFromInterpreter(module) prend le relais :
    • elle lance le premier interpréteur, python3 puis python, qui importe le module visé (axelrod ou pyspiel) ;
    • il lui renvoie, par sysconfig, sa bibliothèque partagée (libpython3.x.so sous Linux, libpython3.x.dylib sous macOS, python3xx.dll sous Windows), son préfixe et son sys.path ;
    • le runtime embarqué reprend ce sys.path : un module installé dans un environnement virtuel est donc trouvé.
  • GT-06 : la branche Linux et macOS qui prenait la première libpython3.* est remplacée par ce repli. C'est elle qui chargeait un CPython sans axelrod.
  • Sous Windows, le poste de la flotte suit le même chemin qu'avant. Un poste Windows sans ce CPython passe par le repli au lieu d'échouer. Ce cas, comme macOS, découle du code et n'a pas été exécuté ici : seule la branche Linux l'a été.

Markdown, dans l'annexe de chaque pont (GT-06 cellule 43, GT-07 cellule 29, GT-13 cellule 28, GT-17 cellule 24) : les prérequis et la « Rejouabilité » décrivent le repli. Elles disaient de positionner PYTHONNET_PYDLL sur toute autre machine. Dans GT-17, la phrase réécrite reprend ses accents.

Registre de parité jumelle : les quatre notebooks appartiennent chacun à une paire. Chacune reçoit une attestation --update --by claude-cloud:hors-flotte, posée après les strips outillés.

Le diff compte 8 fichiers : les 4 notebooks et les 4 attestations (6 lignes chacune).

Diagnostic dérive

Comparaison cellule par cellule entre la base (flotte, Windows) et cette tête (clone vierge Linux), sur le texte des sorties, CRLF normalisés. language_info.version est inchangé (13.0).

Notebook Cellules code Sorties identiques Écarts
GT-06 16 14 cellule 0 : bandeau JavaScript de .NET Interactive, absent de la base dans cette cellule ; cellule 15 : en-tête NuGet (Installing → Installed Packages pythonnet, 3.1.0) et version de CPython
GT-07 11 9 cellule 0 : identifiants de session du bandeau ; cellule 10 : version de CPython
GT-13 11 9 cellule 0 : identifiants de session du bandeau ; cellule 10 : version de CPython, et le bandeau JavaScript que la base répétait dans la cellule du pont
GT-17 12 10 mêmes écarts que GT-13 (cellules 0 et 11)
  • (a) env/kernel : emplacement de la bibliothèque CPython, objet de la PR. S'y ajoutent la version de CPython (3.11 et 3.13 sous Windows, 3.11 ici), l'en-tête NuGet et les bandeaux de .NET Interactive. Verdict CAUSE_FIXED.
  • Les résultats calculés sont identiques à la base, au caractère près :
    • tournoi axelrod (GT-06, seed 42) : mêmes classements et mêmes scores ;
    • partie de Kuhn poker, infosets et CFR d'OpenSpiel (GT-07), avec la même version, pyspiel 2.0.1 ;
    • exploitabilité CFR 0.008226 (GT-13) ;
    • rollout gains=[-2, 2] (GT-17).
  • Aucune sortie n'a été touchée à la main.

Exécuté sous LANG=fr_FR.UTF-8, avec open_spiel 2.0.1 (la version des sorties de la base), axelrod 4.14.0, CPython 3.11 dans un environnement virtuel.

Verdict SOTA : SOTA-OK. Les vrais moteurs (axelrod, OpenSpiel) s'exécutent depuis .NET par pythonnet. Il n'y a ni substitution ni réimplémentation.

Organe-first. Rien n'est réimplémenté. La fonction ajoutée est une copie par notebook, comme la fonction ResolvePythonDll des notebooks MGS-22 à MGS-30. Proposition, laissée à l'arbitrage du mainteneur : 21 notebooks C# chargent CPython par pythonnet, chacun avec sa propre recherche. Un fichier partagé chargé par #load avec un chemin relatif explicite, sur le modèle de SvgChartHelper.cs, les alignerait tous. Il faut d'abord lui choisir un emplacement dans l'arbre.

Review Checklist

  • 1. Scope : recherche de la bibliothèque CPython dans quatre notebooks GameTheory, prose des annexes, attestations de parité.
  • 2. Post-fix validation, relancée après le dernier commit :
    • validate_pr_notebooks.py origin/main : PASS ;
    • check_output_failure_text.py origin/main : 0 regressed ;
    • check_output_collapse.py et check_source_collapse.py : 0 flagged ;
    • check_kernel_drift.py origin/main : 0 regression ;
    • check_prose_quantitative_claims.py --diff origin/main...HEAD --strict : OK ;
    • scripts/check_docs_links.py --check --base origin/main : 0 nouveau lien cassé ;
    • check_cell_source_parses.py --target-py 3.12 --pr-diff origin/main HEAD : 0 finding ;
    • check_twin_parity.py --per-pair --base origin/main --check : INTRO=0 ;
    • check_twin_parity.py --verify-recorded-sha : les quatre paires de la PR sont OK. Les 10 MISMATCH listés concernent d'autres paires et sont antérieurs à la PR ;
    • check_factual_mislabel.py : 0 anomalie. check_stale_claims.py : 0 sur GT-06, GT-13 et GT-17 ; 1 sur GT-07 (cellule 31, « écart résiduel ~0,0015 »), identique sur la base ;
    • check_split_reading_cells.py : clean ; check_interp_positioning.py : 0 ;
    • strip_machine_paths.py --scan : 0 ;
    • check_machine_dep_timing.py et scripts/check_markdown_claims_output.py : mêmes résultats sur la base et sur la tête.
  • 3. Pedagogical coherence : exercices et stubs inchangés. Le pont vers le moteur de référence, présenté comme vérification croisée, fonctionne désormais pour un lecteur sous Linux ou macOS.
  • 4. Real execution : notebook_tools.py execute <nb> --kernel .net-csharp sous Linux (dotnet-interactive 1.0.617701, PYTHONNET_PYDLL non définie, donc par le repli) : exec_count 1 à 16, 1 à 11, 1 à 11 et 1 à 12, 0 erreur. Puis strip_probe_banner.py --apply et scrub_papermill_paths.py --apply.
  • 5. Regression check : sous Windows, l'ordre de recherche et ses chemins sont inchangés ; le repli ne s'active que si aucun fichier n'a été trouvé.

Anti-regression

  • Pas de Lean/Coq touché.
  • Aucun test désactivé.
  • Code retiré : la seule branche supprimée est la recherche Linux et macOS de GT-06 (première libpython3.* trouvée). Sur un clone vierge, elle chargeait un CPython sans axelrod ; le repli la remplace.

Notebook-specific

  • Aucun raise NotImplementedError / assert False / 1/0 introduit.
  • Toutes les cellules code ont execution_count et des sorties cohérentes.
  • Seuls les notebooks dont une cellule source a changé sont committés (C.3).

Test plan

Sur un poste Linux ou macOS, avec .NET 9, dotnet-interactive 1.0.617701 et un environnement Python où pip install open_spiel axelrod a été exécuté, python3 désignant son interpréteur :

python scripts/notebook_tools/notebook_tools.py execute MyIA.AI.Notebooks/GameTheory/GameTheory-13-ImperfectInfo-CFR-CSharp.ipynb --kernel .net-csharp

La cellule du pont doit afficher CFR(kuhn_poker, 100 iters) : exploitabilite = 0.008226 puis PONT .NET -> OpenSpiel CFR : OK. Sur main, elle s'arrête sur DllNotFoundException. Même essai pour GT-06, GT-07 et GT-17.

Hors de cette PR :

  • SocialChoice-01 porte le même défaut, mais Retrait de la coquille repeated_games_lean + repointage des references vivantes (#4362) #18678 modifie déjà ce notebook.
  • SocialChoice-04 aussi, mais il s'arrête plus tôt sous Linux : le paquet NuGet Microsoft.Z3 (4.12.2, dernière version publiée) ne contient pas de bibliothèque native Linux (runtimes/ n'a que win-x64 et osx-x64). Les notebooks Z3.Linq contournent cela avec scripts/environment/z3-build-deploy.sh, pas ceux qui chargent Microsoft.Z3 directement. Ce sera une PR distincte.
  • Les autres notebooks C# qui chargent CPython par pythonnet (SL-1, Planners-9, Search-10, Sudoku-05, MGS-22 à MGS-30…) ont chacun leur propre recherche. Ils restent à mesurer de la même façon sous Linux.

Environnement de mesure : conteneur Linux x64, 4 threads, clone vierge, hors flotte.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VuVMY5fhzd5cQhzHiyvjka


Generated by Claude Code

… Linux et macOS

Les quatre notebooks C# chargent CPython par pythonnet pour invoquer
axelrod ou pyspiel. Hors du CPython Windows du poste de la flotte, ils
s'arretaient : chemin C:\ code en dur (GT-07, GT-13, GT-17), ou, pour
GT-06, une bibliotheque libpython prise sans verifier qu'elle importe
axelrod. La recherche existante est conservee ; quand elle ne designe
aucun fichier, le premier interpreteur (python3, puis python) qui importe
le module fournit sa bibliotheque, son prefixe et son sys.path,
environnement virtuel compris. Notebooks re-executes sous Linux.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VuVMY5fhzd5cQhzHiyvjka
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ Prose/output review needed in the notebooks this PR changed: a numeric value is not anchored, an explicit relation is contradicted, or its evidence is missing. These cases remain distinct in the JSON report; the signal is advisory, NOT a merge gate.

Scope = notebooks CHANGED in this PR, not the whole corpus. Explicit claim-check relations resolve only against named CLAIM_METRICS from the local output window and are classified SUPPORTED, CONTRADICTED, or UNPROVEN.
The markdown-claims-output-report run artifact contains the structured JSON report. See python scripts/check_markdown_claims_output.py --help for re-running locally.
Detector rationale: c.290 / c.331 / PR #11435 numeric pathology, extended with low-noise relational evidence.

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

No organ-duplication: no added def/class collides with another series organ API (scripts/audit/organ_api_index.yaml).

Detector: python scripts/audit/detect_organ_duplication.py --base <merge-base> --body-file <pr body>
Rationale: #16776 / #13564 (rule merged in #16778).

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ Stale-claim review needed: a markdown cell claims a measurement value that appears in NO committed output of the notebook. Advisory, NOT a merge gate — triage against the JSON artifact.

Scope = notebooks CHANGED in this PR, not the whole corpus. The stale-claim-report run artifact holds the structured JSON.
Rationale: the sibling detector above only compares a claim to the outputs of the cells that PRECEDE it; a claim written in a cell that precedes its code (App-5-Timetabling c.2/c.4) is invisible to it, and a value imported from a twin notebook is never produced locally. See python scripts/check_stale_claims.py --help.

@github-actions github-actions Bot added the variation-tag-missing PR sans tag Grain: <TIER>/<GENRE> (variation-protocol) label Oct 1, 2026
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

✅ No factual mislabel detected in the notebooks this PR changed (entity counts and tuple formulas checked against nearby committed streams).

Scope = notebooks CHANGED in this PR, not the whole corpus. The factual-mislabel-report run artifact holds the structured JSON.
Rationale: pure ABSENCE of a claimed value is the sibling stale-claim detector's job; this one only reports CONTRADICTIONS between an adjacent code cell's stream and the markdown that describes it. See python scripts/check_factual_mislabel.py --help.

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Notebook outputs-required (H.4 schema): PASS (every code cell carries an outputs: list)

@github-actions github-actions Bot added the consecutive-code-cells Modified notebook has >=2 consecutive code cells (#12797) label Oct 1, 2026
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

  • Notebooks checked: 4
  • Code cells validated: 50
  • Result: All passed

Checks: H.1 (no errors), H.3 (execution_count), C.1 (no banned patterns)
Non-Python kernels (.NET/Lean): C.1 + errors only (execution_count advisory)
QuantConnect notebooks: C.1 + errors only (require QC Cloud for execution)

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Golden-Set Execution (H.7 P3)

✅ 8/8 notebooks passed (certified reproducible)

Notebook Status Time
2.1-Workflow-ML.ipynb ✅ SUCCESS 3.5s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 3.6s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 4.9s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 4.2s
Search-01-StateSpace.ipynb ✅ SUCCESS 3.0s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 13.0s
rl_4_multi_armed_bandits.ipynb ✅ SUCCESS 21.1s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 4.0s

Pinned lockfile: scripts/notebook_tools/golden_set.lock.txt (H.7 P3, axe A #4208)

jsboige commented Oct 1, 2026

Copy link
Copy Markdown
Owner Author

Le rouge du PR gate sur la tête 910bb8764 vient d'une seule jambe enfant, annulée au plafond de 10 min avant que le ratchet ne s'exécute :

Check Run Runner Étape bloquée
Papermill ratchet (base vs PR) 36935795113 myia-po-2026-wsl-5 actions/checkout@v4 : le git fetch aboutit en 37 s, puis git checkout --force refs/remotes/pull/18774/merge reste muet de 22:36:50Z à l'annulation (22:46:12Z), un git-remote-https encore vivant à la fin

C'est la classe décrite dans #18225 (transport HTTPS bloqué sur un runner auto-hébergé de po-2026), indépendante du diff. Il n'existe pas encore de correctif à porter : #18225 est ouverte et aucune PR n'y est liée.

Le contrôle passe sur cette tête, mesuré localement : check_papermill_ratchet.py origin/main donne changed notebooks : 4, regressions : 0. Les autres jambes bloquantes sont vertes.

Relance : cette session n'en a pas le droit (rerun-failed-jobs renvoie 403 « Resource not accessible by integration »). Il faut rejouer la jambe enfant, pas le gate (#15905) :

gh run rerun 36935795113 --failed

Je garde la PR sous surveillance jusqu'au vert.


Generated by Claude Code

@github-actions github-actions Bot added the large-pr-no-review PR > seuil sans review (ni bot ni humaine) -- retire quand une review arrive (#11232) label Oct 2, 2026
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Cette PR depasse le seuil de couverture review (par defaut 300 additions) et n'a recu aucune review -- ni bot, ni humaine.

Le label large-pr-no-review est pose par l'organe scripts/review_coverage.py porte par l'issue #11232. Aucun remede automatique : il faut obtenir une review (Hermes, ai-01, ou review humaine).

Le label est retire au balayage suivant (quotidien) des qu'une review arrive -- dans reviews[] ou en commentaire de verdict -- ou que le diff passe sous le seuil. Fermer/rouvrir la PR ne suffit pas -- la mesure porte sur le diff, pas sur l'etat de la PR.

Seuil, historique et exceptions : cf. docs/reference/review-coverage-threshold.md.

@jsboige

jsboige commented Oct 3, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 18774
head: 910bb87
complete: true
body: read
comments-reviewed: 9
reviews-reviewed: 0
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 9386441c6c9c8d2946ec6d4f5ecd62f0d480298538059cdc8961e310a269750f
diff-files: 8
diff-additions: 2045
diff-deletions: 896
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

note: Dossier c384 sur PR #18774 (Fix(GameTheory): ponts PythonNet de GT-06, GT-07, GT-13 et GT-17 sous Linux et macOS). Hors flotte : PR de la session cloud d'agnosticisme du mainteneur (branche claude/*, exemption #17713, role documente dans docs/reference/agent-cloud-agnosticisme.md). Pas de tag Grain: attendu (exemption CLAUDE.md section "A qui ce fichier s'adresse"). Lane implicite = cloud-mainteneur (auto-attestation interdite, attestation tierce requise). MED/notebook-python (implicite -- fix substantiel mais cible), 8 fichiers : 4 notebooks C# GameTheory-06/07/13/17 + 4 YAML scripts/notebook_tools/twin_pairs.d/* (suite de #18694 MERGED, sous EPIC parite Linux #10643). Diff +2045/-896. PR gate SUCCESS 2026-10-02T02:22:44Z (PASS -- no failing checks, tete 910bb87). B.0 clear (0 nit non leve ; 1 commentaire non evalue jsboige 2026-10-01T22:47:51Z factuel sur un ratchet annule avant 10 min -- Papermill ratchet sans impact). Scope pass (8 fichiers : 4 .ipynb sous MyIA.AI.Notebooks/GameTheory/ et 4 .yaml sous scripts/notebook_tools/twin_pairs.d/, PAS sous .claude/, .github/, ni CLAUDE.md). domain: pass (substance notebook C# GameTheory, parite Linux/macOS). Substance mesuree first-hand via body : correction des branches PythonNet pour les 4 carnets C#, mesuree sur clone Linux vierge, les 4 carnets passent de bout en bout, resultats identiques a la base. Pas de revue formelle (0 review) -- ai-01 may merge direct ou poser APPROVED. crible de fond visuel non applicable (notebooks C# .NET, exécution selon c264 .NET execution policy).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

consecutive-code-cells Modified notebook has >=2 consecutive code cells (#12797) large-pr-no-review PR > seuil sans review (ni bot ni humaine) -- retire quand une review arrive (#11232) variation-tag-missing PR sans tag Grain: <TIER>/<GENRE> (variation-protocol)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants