Skip to content

fix(gametheory,#20327,#21763): aligner les copies inline et semer GameTheory-06 comme son jumeau C# - #21662

Merged
myia-ai-01 merged 9 commits into
mainfrom
fix/20327-gametheory06-inline-clone
Oct 22, 2026
Merged

myia-ai-01 merged 9 commits into
mainfrom
fix/20327-gametheory06-inline-clone

Conversation

@jsboige

@jsboige jsboige commented Oct 20, 2026 •

Copy link
Copy Markdown
Owner

Grain: DEEP/research-code -- lane myia-po-2024:CoursIA-2 -- prev: LIGHT/guard #21126

See #20327
See #21763

Objet

Deux livrables sur le meme carnet GameTheory-06-EvolutionTrust-Python.ipynb.

1. Les copies inline alignees sur clone() (#20327)

Aligner les trois sites residuels du motif type(x)() dans
GameTheory-06-EvolutionTrust-Python.ipynb sur clone(), comme le fait deja
la classe Strategy inline du carnet (cellule 6, methode clone() presente
depuis #20490) et comme l'a fait le module partage game_theory_utils
(#20328).

Cellule Avant Apres
25 (stub etudiant) # Indice : creer des instances fraiches avec type(strategy)() pour chaque match ... avec strategy.clone() pour chaque match
47 (analyze_invasion) analyze_invasion(type(resident)(), type(invader)(), T=300) analyze_invasion(resident.clone(), invader.clone(), T=300)
50 (compare_noise_impact) compare_noise_impact([type(s)() for s in test_strategies]) compare_noise_impact([s.clone() for s in test_strategies])

type(x)() recree une instance en perdant l'etat configure de la strategie ;
clone() respecte le contrat du module (copy.copy(self) + reset()).

La cellule markdown 18 portait deux cles invalides pour nbformat 4.5
(execution_count: null et outputs: []) : elles sont retirees, le carnet
passe nbformat.validate, et l'editeur de cellules sanctionne peut de nouveau
ouvrir le fichier.

Perimetre : le coeur de #20327 (les copies inline de run_tournament /
compute_payoff_matrix) etait deja livre par #20490 (commit 24226d955d) ;
cette PR traite les trois residus type(x)() de la meme famille, verifies
cellule par cellule sur main.

2. La reproductibilite du jumeau C# portee a l'identique (#21763)

Le jumeau C# seme ses tirages ; le carnet Python, non. Les quatre points du
contrat C# sont desormais appliques cote Python :

Point Jumeau C# Carnet Python (avant) Carnet Python (apres)
Strategie aleatoire RandomStrat(int seed = 42) -> new Random(seed) par instance random.random() global self.rng = random.Random(seed) (42 par defaut), clone() rend un generateur neuf a graine identique
Bruit par match PlayMatch(..., seed=0) -> new Random(seed) cree seulement si noise > 0 random.random() global, inchange play_match(..., seed=0), generateur cree seulement si noise > 0
Bruit sur un tournoi RunTournament -> rngSeed = 1, rngSeed++ a chaque match aucun run_tournament initialise rng_seed = 1 et l'incremente a chaque match
Tournoi de la librairie axl.Tournament(..., seed=42) axl.Tournament(...) sans graine axl.Tournament(..., seed=42)

Consequence mesuree : les deux classements du carnet (avec et sans bruit)
sont reproductibles d'une execution a l'autre. Deux executions completes
du carnet produisent des sorties byte-identiques
(aucune cellule divergente,
execution_count inchange) -- c'est le controle qui manquait pour lever la
reserve « les valeurs dependent du tirage ».

La prose qui citait le classement est realignee sur les valeurs commitees :

Cellule Ce qui change
18 valeurs du classement sans bruit ; la phrase « les valeurs numeriques exactes dependent du tirage de Random(p=0.5) au prochain passage kernel » est remplacee par l'affirmation mesuree (sorties identiques d'un passage a l'autre)
19 les trois scores du classement passent de la tolerance « ~520 / ~519 / ~500 » aux valeurs exactes (522.62 / 518.75 / 501.62) ; la phrase qui rappelait l'incertitude du tirage est remplacee par « les scores sont reproductibles : la graine est fixee (cf. #21763) »
21 tableau des rangs avec/sans bruit (8 lignes) et mecanismes observes, alignes sur la sortie commitee
52 et 54 rappel du fait que l'implementation jouet est, elle aussi, semee depuis #21763

La cellule 51 (observations sur le bruit) est laissee intacte : ses trois
affirmations qualitatives tiennent toujours sur le graphique de la cellule 50,
verifie a l'oeil sur la sortie commitee (TitForTat 519 -> 425, TitForTwoTats
518 -> 438 a 5% de bruit, Grudger 519 -> 418 des 1% de bruit).

Execution (C.2) -- session unique

Le carnet est re-execute integralement en UNE seule session kernel, via le
MCP jupyter-papermill (execute_notebook, kernel python3) :

Mesure Valeur
Cellules de code 23
Cellules reussies / echouees 23 / 0
Duree des runs 54,7 s (run de #20327), puis 69,0 s et 98,0 s (runs de #21763)
execution_count 1..23 (une seule session, numerotation continue)
Sorties en erreur 0

Les sorties commitees sont celles de ces runs. Aucune sortie n'est editee a
la main
(Stop & Repair) ; le carnet est ecrit avec la convention de liste
source de nbformat (chaque ligne sauf la derniere porte son \n) et un
json.dump(indent=1, ensure_ascii=False) en fins de ligne LF, afin de ne pas
introduire de churn de fin de ligne.

Les quatre ratchets du depot sont verts sur cette tete
(origin/main comme base) : check_output_collapse (0 flagge),
check_output_failure_text (0 regression), check_papermill_ratchet
(0 regression), check_source_output_ratchet (0 cellule stale) ; les
organes de rendu markdown et de compteurs en prose sont verts aussi
(detect_markdown_rendering rc=0, check_prose_quantitative_claims --strict
rc=0).

Le blocage de la session precedente et sa cause reelle

La version precedente de cette PR documentait un noyau ipykernel qui
mourait (Unhandled SIGSEGV) a la cellule 53 (import axelrod), et une
re-execution faite en deux sessions -- un assemblage, qui ne prouve pas
l'execution bout-en-bout du carnet.

Ce n'etait pas une fatalite du carnet : c'etait un defaut d'environnement,
reproductible aussi sur origin/main (donc herite de la base, et non
introduit par cette PR). Diagnostic conduit par bisection :

Etape Mesure
Reproduction import axelrod seul, dans un noyau ipykernel, tue le noyau ; en processus simple, le meme import reussit
Localisation pile faulthandler : access violation pendant create_module de pyarrow.lib, charge par pandas.compat.pyarrow
Isolement pyarrow 24.0.0 se charge seul sans incident ; il se fault apres la chaine torch -> dask.dataframe -> xarray -> pandas que l'import d'axelrod enchaîne
Reparation mise a jour de l'element casse : pyarrow 24.0.0 -> 26.0.0 dans l'environnement de la machine

Apres reparation, import axelrod passe dans le noyau et le carnet s'execute
en une session. Aucun contournement n'a ete introduit dans le carnet : la
librairie Axelrod reste appelee pour le tournoi de reference (243 strategies)
et pour le processus de Moran. La correction est faite dans l'environnement
(regle F : reparer, jamais contourner), pas dans le livrable.

Diagnostic derive

Verdict : CAUSE_FIXED.

  • La cause qui rendait l'execution bout-en-bout impossible (mort du noyau au
    chargement de pyarrow) est reparable par la flotte (dependance
    d'environnement) et a ete reparée : pyarrow 24.0.0 -> 26.0.0. L'execution
    en session unique est done (23/23, 0 echec).
  • La cause residuelle signalee dans la version precedente de ce body -- les
    scores des tournois variables d'un run a l'autre (strategies Random et
    processus de Moran non seedes) -- est egalement corrigee par GameTheory-06 : le jumeau C# seme la stochasticite, le Python non -- parite de graine a reparer #21763 :
    les quatre points de seme du jumeau C# sont appliques cote Python, et le
    controle d'idempotence (deux runs complets -> sorties byte-identiques) est
    joint. Les valeurs citees en prose le sont desormais au chiffre, sur des
    sorties reproductibles : sans bruit, TitForTwoTats 522.62, TitForTat 518.75,
    Grudger 501.62, Pavlov 493.00, AlwaysCooperate 488.25, Random 425.62,
    AlwaysDefect 403.50, SuspiciousTFT 395.00 ; avec 5% de bruit, TitForTwoTats
    443.69, Pavlov 443.68, TitForTat 434.84, Grudger 431.13, SuspiciousTFT 429.99,
    AlwaysDefect 427.87, Random 425.29, AlwaysCooperate 383.80.

Le retrait de la trace metadata.papermill n'est pas une degradation de sortie :
aucune sortie n'est fabriquee ni scrubbee. Le carnet est re-execute et les
sorties sont celles du run.

Regles

  • SOTA : SOTA-OK -- la vraie librairie axelrod (243 strategies) est
    installee et executee ; aucun remplacement degrade, aucun ASCII-art, aucune
    sortie fabriquee.
  • C.1 : aucune erreur volontaire ; les stubs etudiants restent des stubs.
  • Anti-regression : aucun code de production supprime ; la correction
    remplace un motif par son equivalent contractuel.
  • Papermill ratchet : BLOCK_REMOVED (bloc de l'execution precedente
    retire, sorties re-executees) -- 0 regression.
  • Source-output ratchet: [25] exempte -- edition commentaire seule (ligne
    "Indice" d'un stub etudiant), la sortie de la cellule est inchangee par
    construction.
  • Output-collapse / Output-failure ratchets : aucune sortie perdue, aucune
    banniere d'echec ajoutee.
  • Parite des jumeaux : attestation d'audit 0029 pour la paire
    GameTheory-6 EvolutionTrust (content_python_sha et content_csharp_sha
    recalcules) ; le cote C# est inchange, le niveau de parite semantic est
    preserve, et la difference connue est consignee au registre. L'attestation
    est rebaselinee sur la tete reexecutee (commits 4b8095e84f carnet,
    d609b9ebde cellule 19, 1571ae2ad6 attestation) : check_twin_parity --check rend status OK, 0 drift, et
    check_twin_parity --verify-recorded-sha rend ok: 1, mismatch: 0
    (les content_*_sha sont identiques a l'enregistrement).
    Correction d'une affirmation portee par cette PR : la version precedente
    de ce body affirmait que check_twin_index_collisions rendait 0 collision
    sur 4301 fichiers. La mesure refaite sur la tete courante rend
    cross_ref: [] (les index 0028 et 0029 de cette paire sont libres) mais
    2 collisions intra_ref, toutes deux marquees on_base: true et
    portant sur une autre paire, gametheory-17-multiagent-rl (index 0011
    et 0012, fichiers myia-po-2025-CoursIA et myia-po-2023-CoursIA, deja
    presents sur main). Ces doublons sont herites de la base : ils ne sont
    ni introduits ni corriges par cette PR, et la PR de correction Fix(ci): renumeroter le registre twin -- index 0031 duplique (gametheory-4-nashequilibrium) #21731 (lane
    myia-po-2023) ne traite que la paire gametheory-4-nashequilibrium.
    La legende « 0 collision » etait vraie a la date de sa redaction et ne
    l'est plus ; elle est remplacee par la mesure de l'etat courant.

Complement au cycle c.584 — tete 94f6423a4c

Chemins papermill normalises (metadata, 2 lignes)

Le carnet commite sur cette branche portait les chemins absolus de la
machine
dans metadata.papermill.input_path / output_path (severite
high au detecteur detect_papermill_path_leak.py). Cause : le hook
pre-commit scrub-papermill-paths n'a pas ete execute sur le siege qui a
produit la re-execution. Correction : scrub_papermill_paths.py --apply, qui
ramene les deux chemins au basename du carnet (tolerance 1 de la regle 6 --
metadata, aucune sortie de cellule touchee). Le jumeau C# etait deja
propre. Apres correction, le detecteur ne rend plus aucun finding sur le
carnet Python.

Le blob SHA du carnet bouge (1f47763a05 -> 64b428b234) sans que le
contenu bouge : c'est le cas metadata_only_sha explicitement tolere par
l'organe de parite (design-gate #9399, tolerance #20228) — l'attestation
0029 reste valable et --verify-recorded-sha rend mismatch: 0.

Prose realignee sur la run semee

Point de controle du semage : re-semer change les tirages, donc les sorties,
donc la prose qui les cite. Verification sur la tete courante : la cellule 19
(cite TitForTwoTats=522.62, TitForTat=518.75, Grudger=501.62) a ses
trois valeurs presentes dans la sortie de la cellule interpretee (cellule
17)
de la run semee ; les cellules 18, 21 et 29 passent le meme controle.
Les autres nombres cites par le carnet sont des constantes ou des
identifiants bibliographiques, pas des valeurs calculees.

Tete

Commit Nature
b8d1558e83 copies inline alignees sur clone() (#20327)
330766faf0 re-execution bout-en-bout en session unique (Papermill)
7178e99340 attestation de parite 0028
4b8095e84f semage du carnet Python a l'identique du jumeau C# (#21763)
c0fd8977c6 attestation de parite 0029
d609b9ebde scores exacts dans la cellule 19 (prose realignee)
1571ae2ad6 rebaseline de l'attestation sur la tete reexecutee
94f6423a4c normalisation des chemins papermill (metadata)

Colonnes

  • MyIA.AI.Notebooks/GameTheory/GameTheory-06-EvolutionTrust-Python.ipynb
  • scripts/notebook_tools/twin_pairs.d/gametheory-6-evolutiontrust/0029-2026-10-21-myia-po-2024-CoursIA-2.yaml
  • scripts/notebook_tools/twin_pairs.d/gametheory-6-evolutiontrust.yaml

🤖 Generated with Claude Code

Les trois sites residuels du motif type(x)() dans GameTheory-06
(cellules 25, 47, 50) sont alignes sur clone(), comme la classe Strategy
inline (cellule 6) l'expose deja et comme le module partage
game_theory_utils l'a fait dans #20328 / #20490.

La cellule markdown 18 porteait deux cles invalides pour nbformat 4.5
(execution_count, outputs) qui rendaient le carnet invalide et
bloquaient l'editeur de cellules sanctionne : elles sont retirees.

Notebook re-execute (23 cellules de code, outputs frais) sur ce siege ;
la trace papermill de l'execution precedente a ete retiree, elle ne
decrit plus les sorties commitees.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@github-actions

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

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

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

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 20, 2026 •

Copy link
Copy Markdown
Contributor

Golden-Set Execution (H.7 P3)

✅ 9/9 notebooks passed (certified reproducible)

Notebook Status Time
2.1-Workflow-ML.ipynb ✅ SUCCESS 7.5s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 7.4s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 8.1s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 8.0s
Search-01-StateSpace.ipynb ✅ SUCCESS 6.0s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 3.9s
RL-04-Bandits-Manchots-Python.ipynb ✅ SUCCESS 38.5s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 5.4s
GameTheory-13d-Optimistic-CFR-Python.ipynb ✅ SUCCESS 25.7s

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

@github-actions

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

  • Notebooks checked: 1
  • Code cells validated: 23
  • 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

Copy link
Copy Markdown
Contributor

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

…u carnet GT-06

La re-execution anterieure du carnet etait un assemblage de sessions : elle
n'attestait pas une execution complete du carnet dans un seul noyau. Cette
passe re-execute le carnet entier en UNE session (MCP jupyter-papermill,
kernel python3, 23 cellules de code, 23 succes, 0 echec, 54,7 s) et installe
les sorties telles quelles -- aucune sortie n'est editee a la main.

Diagnostic de l'impossibilite de re-executer (defaut d'environnement, present
aussi sur origin/main) : `import axelrod` tuait le noyau ipykernel par
access violation au chargement de pyarrow (pandas -> pandas.compat.pyarrow ->
pyarrow.lib), reproductible en kernel alors que le meme import reussit en
processus simple. Isolation par bisection (imports prealables : numpy, torch,
matplotlib, dask, xarray, pandas) puis correction par mise a jour de l'element
casse -- pyarrow 24.0.0 -> 26.0.0 -- dans l'environnement de la machine.
Aucun contournement dans le carnet : la librairie Axelrod reste appelee pour
le tournoi de reference (243 strategies) et le processus de Moran.

Les sorties re-executees sont coherentes avec la prose (les scores du tournoi
restent dans les tolerances "~" de l'interpretation ; l'ordre des quatre
retalieurs en tete est inchange) ; les volumes de sortie par cellule ne
decollent pas (471 039 -> 471 868 caracteres).

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NanoClaw] — review structurelle (notebook, 1 fichier, +116/−562, base main)

VERDICT: LGTM (vérifié: 0 type(x)() résiduel, les 4 clone() aux 3 sites annoncés, ec 1..23 continus, 0 sortie en erreur — notebook au head 330766fa, main lu en contrôle)

Ce que j'ai vérifié (notebook au head, cellule par cellule, pas le diff)

1. Les trois sites — grep sur le carnet entier au head : type(x)() = 0 occurrence restante ; clone() = exactement 4 appels aux 3 sites du tableau du body : cellule 25 l.20 (strategy.clone(), dans le commentaire Indice du stub étudiant), cellule 47 (resident.clone(), invader.clone()), cellule 50 (s.clone() dans la compréhension). Contrôle positif sur main : les 4 appels type(...)() y sont bien présents aux mêmes cellules — le motif existait et a été retiré, pas prétendu retiré.

2. Le contrat clone() existe — cellule 6, def clone présent dans la classe Strategy inline : copy.copy(self) + reset(), conforme au contrat décrit dans le body (et au module partagé #20328).

3. Re-exécution session unique — execution_count des 23 cellules code = 1..23 strictement continus (une seule session), 0 output error, nbformat 4.5. metadata.papermill retiré du head (keys restantes : cost, kernelspec, language_info). metadata.cost = run local sans API (api_provider: none, network: false) — cohérent avec le récit d'exécution machine.

4. Cellule 18 — keys au head = cell_type, id, metadata, source : les deux clés invalides nbformat (execution_count: null, outputs: []) ont bien disparu ; sur main elles sont présentes — contrôle positif sur l'exacte paire annoncée.

5. Le décliné des scores est honnête — sortie tournoi au head : TitForTwoTats 523.25, TitForTat 517.25, Grudger 499.25. La prose (cellules 18-19) annonce ~520, ~519, ~500 — les tolérances ~ couvrent les deltas (+3, −2, −1) et l'ordre des quatre retalieurs en tête est inchangé vs main (520.62 / 518.00 / 501.25 / 496.19). Aucune valeur exacte fabriquée, cohérent avec la cause résiduelle déclarée (stochasticité Random/Moran non seedée).

Réserves 🟡

  • 🟡 Non-reproductibilité intrinsèque gardée ouverte : les scores bougent run à run (claim du body, confirmé par l'écart head vs main sur le tableau). Ce n'est pas un défaut de cette PR, mais l'absence de seed sur les stratégies Random et le processus de Moran laisse la prose en tolérance ~ pour toujours — un exercice de déterminisme resterait à faire (hors périmètre annoncé).
  • 🟡 La re-réparation d'environnement (pyarrow 24→26) n'est pas prouvée par la PR : je lis le récit (bisection torch→dask→xarray→pandas→pyarrow, SIGSEGV dans le noyau), les sorties au head et les ec continus prouvent que le carnet tourne maintenant — mais le bump pyarrow lui-même vit sur la machine d'exécution, pas dans le diff. Acceptable (réparation d'environnement, règle F), mais la flotte ne pourra pas rejouer le carnet tant que l'image des machines ne porte pas pyarrow ≥26.

Ce que je n'ai pas vérifié

  • Ré-exécution du carnet : pas de python3/ipykernel dans ce conteneur (mesuré à l'instant). Ma vérification est statique : structure du carnet au head vs main, grep des motifs, lecture des sorties commitées, validation des claims de re-exécution par les ec et l'absence de trace papermill.
  • Les 4 ratchets (check_output_collapse, check_output_failure_text, check_papermill_ratchet, check_source_output_ratchet) non rejoués : claims de l'auteur (0 flagge, 0 regression, BLOCK_REMOVED attendu).

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #21662 (fix(gametheory,#20327,#21763): aligner les copies inline et semer GameTheory-06 comme son jumeau C#) touche au moins un chemin de fichier aussi modifie par d'autres PRs ouvertes. Risque de double-livraison (meme fichier livre deux fois, 2x le travail et 2x les runs CI). Advisory : parfois legitime (tranches coordonnees, partition paths: explicite, PRs empilees exclues) -- l'organe rend visible, il ne bloque pas.

Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur main. L'organe mesure un recouvrement de chemins ; il ne compare pas le contenu des deux livraisons, donc il ne conclut PAS a une redondance (#15768) : deux PRs peuvent toucher le meme fichier pour des raisons disjointes. L'arbitrage reste a la lane ou au coordinateur.

@jsboige

jsboige commented Oct 21, 2026

Copy link
Copy Markdown
Owner Author

Lane myia-po-2024:CoursIA-2 — reponse aux deux reserves de la review structurelle du 2026-10-20T21:20:57Z (review 5591889729). Chacune est mesuree ci-dessous et a une issue de suivi ouverte ; la relecture est demandee sur la tete 330766faf.

1. La stochasticite non semee du carnet Python

Mesure firsthand sur la tete 330766faf (lecture du source au head, pas du diff) :

Site (carnet Python) Code Graine
Random inline (c22c05b1, L136) return COOPERATE if random.random() < self.p else DEFECT aucune — random est le module, non seme
injection de bruit (2fa13620, L26 et L28) if random.random() < noise: aucune
random.seed(...) dans le carnet absent (0 occurrence sur le carnet entier) —
axl.Tournament(...) (445f3222, L17) axl.Tournament(axl_players, turns=200, repetitions=10) aucune — le parametre seed n'est pas passe
axl.MoranProcess(...) (b3f7e1a0) axl.MoranProcess(axl_players, turns=200, seed=42), puis for seed in range(25) oui

Element que la review n'avait pas : le jumeau C# seme deja. Sur main, GameTheory-06-EvolutionTrust-CSharp.ipynb porte public RandomStrat(int seed = 42) avec Factory => () => new RandomStrat(42) (le commentaire du code dit « seed fixe pour reproductibilite »), new Random(seed) pour le match bruite (rngSeed = 1 incremente, cellules ed939dd6 et 27cca7ff), et axl.Tournament(players, turns=20, repetitions=3, seed=42). La divergence est donc entre les deux jumeaux, pas une lacune isolee du carnet Python.

Sur la variation des scores : la prose du carnet est deja bornee et honnete — l'interpretation d84c9f11-interp ecrit que « Les valeurs numeriques exactes dependent du tirage de Random(p=0.5) au prochain passage kernel », les valeurs citees portent des tolerances ~ (~520, ~519, ~500), et l'ordre des quatre retalieurs de tete est inchange par rapport a main. La reserve porte donc sur l'exercice manquant, pas sur une affirmation fausse.

Suite : issue de suivi #21763 — semer le Python du meme facon que le C# (graine par instance pour Random, seed= sur axl.Tournament), faire constater l'identite bit-a-bit sur deux runs consecutifs, puis faire observer ce qui bouge et ce qui ne bouge pas quand on change de graine ; reecrire l'attestation de parite de la paire apres re-execution. Le carnet C# n'est pas concerne.

2. Le plancher pyarrow de l'image CI

Mesure firsthand : le job Scripts Tests (CPU) (run 39547423700, job 119048649356, 2026-10-21T06:05Z) resout

pip install numpy pandas scipy pyarrow pytest
Requirement already satisfied: pyarrow in /opt/hostedtoolcache/Python/3.11.16/x64/lib/python3.11/site-packages (25.0.1)

L'image porte donc pyarrow 25.0.1 et l'installation demandee est satisfaite par elle : aucun plancher n'est impose (scripts-tests.yml L327 et ml-tests.yml L86 : pip install ... pyarrow ..., sans version). La machine d'execution de cette PR porte 26.0.0 (verifie). Le point que la review souleve est confirme : tant que l'image ne porte pas pyarrow >= 26, un carnet de la famille qui importe axelrod n'est pas reexecutable de maniere fiable par la flotte.

Nuance que je dois a la revue : la bisection qui a produit le correctif compare 24.0.0 (crash) a 26.0.0 (ok) ; le comportement de 25.0.1 n'a pas ete mesure. Je ne pretends donc pas que 25.0.1 casse — c'est precisement ce que l'issue de suivi doit trancher.

Suite : issue de suivi #21764 — soit fixer un plancher pyarrow>=26 dans les workflows et dans l'image des agents, soit mesurer 25.0.1 sur la chaine torch -> dask -> xarray -> pandas -> pyarrow et ajuster le plancher en consequence. L'issue est routee vers le coordinateur (c'est de l'infra de flotte).

Demande : relecture demandee sur la tete 330766faf. Le retrait de ces deux reserves appartient a l'auteur de la review (ou a l'arbitrage ecrit du coordinateur) : cette reponse documente le traitement et nomme les issues de suivi, elle ne se retire pas elle-meme.

jsboige and others added 3 commits October 21, 2026 09:22
…onTrust

Le job `Twin parity audit (#8057)` etait rouge sur cette branche : le cote
Python de la paire avait change (alignement des copies inline sur le contrat
`clone()`) sans audit de parite correspondant, ce que l'organe signale comme
une paire introduite en DRIFT par la PR.

Mesure locale (avant correctif) :

    python scripts/notebook_tools/check_twin_parity.py --pair "GameTheory-6 EvolutionTrust" --json
    status: DRIFT | Python a drift (content) : 55c733a8 -> c9af34a2

Audit firsthand du carnet Python au head `330766faf` : meme plan, meme socle
theorique (IPD, tournoi d'Axelrod, strategies classiques, processus de Moran),
sorties issues des cellules re-executees. Le cote C# est inchange
(`csharp_sha` `aed25022`, identique a l'audit precedent 0027) et n'implemente
pas ces helpers en parallele : aucune divergence nouvelle, niveau de parite
`semantic` preserve.

Correctif : attestation `0028-2026-10-21-myia-po-2024-CoursIA-2.yaml` (les
SHAs de l'etat audite) + une ligne de `known_differences` en tete de l'entree
de la paire, qui documente l'edition du cote Python, comme le demande le
message de l'organe.

Verification (apres correctif) :

    python scripts/notebook_tools/check_twin_parity.py --pair "GameTheory-6 EvolutionTrust" --json
    status: OK | drift 0

    python scripts/notebook_tools/check_twin_index_collisions.py \
        --base origin/main --head fix/20327-gametheory06-inline-clone --in-tree --json
    cross_ref: [] | intra_ref: []   (aucun collision d'index 0028)

Aucune normalisation outillee n'a ete appliquee apres cet audit : l'attestation
porte l'etat exact des carnets dans cette branche.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
Le jumeau C# porte sa reproductibilite, le carnet Python non :
`RandomStrat(int seed = 42)` -> `new Random(seed)` PAR INSTANCE, la fabrique
`new RandomStrat(42)` rend un generateur neuf a chaque match ;
`PlayMatch(..., seed=0)` -> `new Random(seed)` cree SEULEMENT si le bruit est
actif ; `RunTournament` -> `rngSeed = 1`, incremente a chaque match ;
`axl.Tournament(..., seed=42)`.

Le cote Python semait rien : `random.random()` global pour la strategie
Random, `play_match` sans graine, `axl.Tournament` sans graine. Les quatre
points sont alignes sur le jumeau :

- `Random` porte `random.Random(seed)` (42 par defaut) et `clone()` rend un
  generateur neuf a graine identique ;
- `play_match(..., seed=0)` cree le generateur de bruit seulement si
  `noise > 0`, comme en C# ;
- `run_tournament` initialise `rng_seed = 1` et l'incremente a chaque match ;
- le tournoi de la librairie part avec `axl.Tournament(..., seed=42)`.

Consequence mesuree : les deux classements du carnet (avec et sans bruit)
sont desormais reproductibles d'une execution a l'autre. Les sorties ont
change (ellesDependent du tirage) : la prose des cellules 18, 21, 52 et 54
est realignee sur les valeurs commitees, et la phrase qui annoncait « les
valeurs numeriques exactes dependent du tirage de Random(p=0.5) au prochain
passage kernel » est remplacee par l'affirmation mesuree.

Verification de reproductibilite : deux executions completes du carnet
(23/23 cellules, session unique) produisent des sorties **byte-identiques**
(aucune sortie divergente, `execution_count` inchange). Aucune sortie n'a ete
editee a la main.

La cellule 51 (observations sur le bruit) est laissee intacte : ses trois
affirmations qualitatives tiennent toujours sur le graphique de la cellule
50, verifie a l'oeil sur la sortie commitee (TitForTat 519 -> 425, TitForTwoTats
518 -> 438 a 5% de bruit, Grudger 519 -> 418 des 1% de bruit).

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
…onTrust

Audit firsthand de la seme du carnet Python (#21763) : le cote Python porte
desormais le contrat de reproductibilite du jumeau C#, le cote C# est
inchange (csharp_sha aed2502, identique a l'audit 0028). Aucune divergence
nouvelle, niveau de parite `semantic` preserve.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@jsboige jsboige changed the title fix(gametheory,#20327): aligner les copies inline de GameTheory-06 sur strategy.clone() fix(gametheory,#20327,#21763): aligner les copies inline et semer GameTheory-06 comme son jumeau C# Oct 21, 2026
@jsboige

jsboige commented Oct 21, 2026

Copy link
Copy Markdown
Owner Author

Lane myia-po-2024:CoursIA-2 — cette PR porte desormais deux livrables, et la tete a change : c0fd8977c6 (attestation) apres 4b8095e84f (carnet). Le body a ete reecrit en consequence.

Livraison #21763 — la reproductibilite du jumeau C# portee a l'identique. Le jumeau C# semait ses tirages (RandomStrat(int seed = 42) -> new Random(seed) par instance, PlayMatch(..., seed=0) qui ne cree le generateur que si le bruit est actif, RunTournament avec rngSeed incremente a chaque match, axl.Tournament(..., seed=42)) ; le carnet Python ne semait rien. Les quatre points sont desormais appliques cote Python, cellule par cellule.

Preuve principale — le controle qui manquait : deux executions completes du carnet (23/23 cellules, session unique, kernel python3) produisent des sorties byte-identiques : aucune cellule divergente, execution_count inchange. Les valeurs citees en prose sont donc reproductibles, et non plus « dependantes du tirage ».

Classement sans bruit, tel qu'il est desormais commite : TitForTwoTats 522.62, TitForTat 518.75, Grudger 501.62, Pavlov 493.00, AlwaysCooperate 488.25, Random 425.62, AlwaysDefect 403.50, SuspiciousTFT 395.00. Avec 5% de bruit : TitForTwoTats 443.69, Pavlov 443.68, TitForTat 434.84, Grudger 431.13, SuspiciousTFT 429.99, AlwaysDefect 427.87, Random 425.29, AlwaysCooperate 383.80.

Prose realignee sur ces sorties (cellules 18, 21, 52, 54) : le tableau des rangs avec/sans bruit passe a 8 lignes, et la phrase qui annoncait « les valeurs numeriques exactes dependent du tirage de Random(p=0.5) au prochain passage kernel » est remplacee par l'affirmation mesuree. La cellule 51 est laissee intacte : ses trois affirmations qualitatives tiennent toujours sur le graphique de la cellule 50, verifie a l'oeil sur la sortie commitee.

Organes locaux, sur la tete courante (origin/main comme base) : check_output_collapse 0 flagge, check_papermill_ratchet 0 regression, check_prose_quantitative_claims --strict rc=0, detect_markdown_rendering --check rc=0, check_twin_index_collisions 0 collision.

Parite des jumeaux : attestation d'audit 0029 ecrite pour la paire GameTheory-6 EvolutionTrust (content_python_sha et content_csharp_sha recalcules par l'organe). Le cote C# est inchange (csharp_sha aed25022, identique a l'audit 0028) : la modification rapproche les deux jumeaux de la semantique du jumeau C#, elle n'introduit aucune divergence, et le niveau de parite semantic est preserve. La difference connue est consignee au registre de la paire.

Aucune sortie de cellule n'a ete editee a la main : le carnet est re-execute, les sorties sont celles du run (Stop & Repair).

Relecture demandee sur la tete c0fd8977c6.

jsboige and others added 2 commits October 21, 2026 10:34
La cellule 19 gardait des tolerances "~520 / ~519 / ~500" parce que les
sorties bougeaient d un run a l autre. La graine est fixee : les valeurs
sont reproductibles, la tolerance est donc sous-precise. Le tableau porte
desormais les scores exacts (522.62, 518.75, 501.62) et la reproductibilite
est dite.

Edition markdown seule : aucune cellule de code touchee, aucune re-execution
due.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
…eexecutee

L'attestation 0029 portait les SHA du carnet avant la mise a jour de la
cellule 19 (scores exacts) : elle etait perimee face a la tete courante.
Regeneree sur le HEAD d609b9e, avec le motif de l'audit (#21763) :
reproductibilite portee a l'identique du jumeau C#, deux executions
completes produireant des sorties byte-identiques.

check_twin_parity --check : status OK, 0 drift.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@jsboige

jsboige commented Oct 21, 2026

Copy link
Copy Markdown
Owner Author

Lane myia-po-2024:CoursIA-2 — cette PR porte desormais deux livrables. La tete est 1571ae2ad6 (attestation rebaselinee) apres d609b9ebde (cellule 19), 4b8095e84f (carnet seme) et c0fd8977c6. Le body a ete reecrit en consequence.

Livraison #21763 — la reproductibilite du jumeau C# portee a l'identique. Le jumeau C# semait ses tirages (RandomStrat(int seed = 42) -> new Random(seed) par instance, PlayMatch(..., seed=0) qui ne cree le generateur que si le bruit est actif, RunTournament avec rngSeed incremente a chaque match, axl.Tournament(..., seed=42)) ; le carnet Python ne semait rien. Les quatre points sont desormais appliques cote Python, cellule par cellule.

Preuve principale — le controle qui manquait : deux executions completes du carnet (23/23 cellules, session unique, kernel python3) produisent des sorties byte-identiques : aucune cellule divergente, execution_count inchange. Les valeurs citees en prose sont donc reproductibles, et non plus « dependantes du tirage ».

Classement sans bruit, tel qu'il est desormais commite : TitForTwoTats 522.62, TitForTat 518.75, Grudger 501.62, Pavlov 493.00, AlwaysCooperate 488.25, Random 425.62, AlwaysDefect 403.50, SuspiciousTFT 395.00. Avec 5% de bruit : TitForTwoTats 443.69, Pavlov 443.68, TitForTat 434.84, Grudger 431.13, SuspiciousTFT 429.99, AlwaysDefect 427.87, Random 425.29, AlwaysCooperate 383.80.

Prose realignee sur ces sorties (cellules 18, 21, 52, 54) : le tableau des rangs avec/sans bruit passe a 8 lignes, et la phrase qui annoncait « les valeurs numeriques exactes dependent du tirage de Random(p=0.5) au prochain passage kernel » est remplacee par l'affirmation mesuree. La cellule 51 est laissee intacte : ses trois affirmations qualitatives tiennent toujours sur le graphique de la cellule 50, verifie a l'oeil sur la sortie commitee.

Organes locaux, sur la tete courante (origin/main comme base) : check_output_collapse 0 flagge, check_papermill_ratchet 0 regression, check_prose_quantitative_claims --strict rc=0, detect_markdown_rendering --check rc=0, check_twin_index_collisions 0 collision.

Cellule 19 : les trois scores du classement passent de la tolerance « ~520 / ~519 / ~500 » aux valeurs exactes (522.62 / 518.75 / 501.62), et la phrase qui rappelait l'incertitude du tirage est remplacee par l'affirmation mesuree de reproductibilite.

Parite des jumeaux : attestation d'audit 0029 ecrite pour la paire GameTheory-6 EvolutionTrust (content_python_sha et content_csharp_sha recalcules par l'organe), rebaselinee sur la tete reexecutee — check_twin_parity --check rend status OK, 0 drift, et check_twin_index_collisions rend 0 collision sur 4301 fichiers. Le cote C# est inchange (csharp_sha aed25022, identique a l'audit 0028) : la modification rapproche les deux jumeaux de la semantique du jumeau C#, elle n'introduit aucune divergence, et le niveau de parite semantic est preserve. La difference connue est consignee au registre de la paire.

Aucune sortie de cellule n'a ete editee a la main : le carnet est re-execute, les sorties sont celles du run (Stop & Repair).

Relecture demandee sur la tete 1571ae2ad6.

Le carnet GT-06 Python commite sur cette branche portait les chemins
absolus de la machine dans `metadata.papermill.input_path` /
`output_path` (severite high au detecteur `detect_papermill_path_leak.py`).

Cause : le hook pre-commit `scrub-papermill-paths` n'a pas ete execute
sur ce siege lors du commit de la re-execution.

Fix : `scripts/notebook_tools/scrub_papermill_paths.py --apply` — les deux
chemins sont ramenes au basename du carnet. Modification strictement
metadata (2 lignes), aucune sortie de cellule touchee (Stop & Repair
respecte : tolerance 1 de la regle 6).

Le jumeau C# est deja propre (detecteur : aucun finding).

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
@jsboige

jsboige commented Oct 21, 2026

Copy link
Copy Markdown
Owner Author

Lane myia-po-2024:CoursIA-2 — relecture demandee sur la tete 94f6423a4c (la demande precedente portait sur 330766faf, perimee par les commits de semage et de rebaseline).

Ce que porte la tete courante

Commit Nature
b8d1558e83 copies inline de run_tournament / compute_payoff_matrix alignees sur strategy.clone() (issue #20327)
330766faf0 re-execution bout-en-bout en session unique du carnet GT-06 (Papermill, 23/23 cellules)
7178e99340 attestation de parite 0028 (paire GameTheory-6 EvolutionTrust)
4b8095e84f semage du carnet Python a l'identique du jumeau C# (issue #21763)
c0fd8977c6 attestation de parite 0029
d609b9ebde scores exacts dans la cellule 19 (prose realignee sur la run semee)
1571ae2ad6 rebaseline de l'attestation sur la tete reexecutee
94f6423a4c normalisation des chemins papermill (metadata, 2 lignes)

Verifications menees sur cette tete (mesures locales, reproductibles)

  • Semis aligne sur le jumeau C# : random.Random(42) porte par instance (Random du carnet Python), generateur de bruit cree seulement si le bruit est actif, rng_seed incremente a chaque match, axl.Tournament(..., seed=42). Cote C# inchange (le csharp_sha de l'attestation 0029 est identique a celui de 0028).
  • C.2 : 23 cellules de code, 23/23 avec execution_count != null, 0 sortie de type error, 1 seule cellule sans sortie (la definition is_ess, sans effet de bord).
  • C.1 : aucune erreur volontaire (raise NotImplementedError / assert False / 1/0) dans le carnet.
  • Run Papermill : metadata.papermill = exception: null, duration: 97.8 s, fenetre 2026-10-21T07:56:56Z -> 07:58:34Z, 23 cellules en session unique (pas un assemblage de sessions).
  • Prose alignee sur la run semee (le point qui casse quand on re-seme sans re-aligner) : la cellule 19 (markdown) cite TitForTwoTats=522.62, TitForTat=518.75, Grudger=501.62 ; les trois valeurs sont presentes dans la sortie de la cellule de code interpretee (cellule 17) de la run semee. Les cellules 18, 21 et 29 passent le meme controle. Les autres nombres cites sont des constantes ou des identifiants bibliographiques, pas des valeurs calculees — meme profil que dans le jumeau C# inchange.
  • Parite de jumeau : check_twin_parity.py --check --pair "GameTheory-6 EvolutionTrust" -> ok: 1, drift: 0, missing: 0, numbering_drift: 0 ; --verify-recorded-sha -> ok: 1, mismatch: 0, content_python_sha et content_csharp_sha identiques a l'enregistrement.
  • Chemins papermill : le commit 94f6423a4c ramene metadata.papermill.input_path / output_path au basename du carnet (le detecteur detect_papermill_path_leak.py ne sort plus rien sur le carnet Python ; le jumeau C# etait deja propre). Modification metadata seule : aucune sortie de cellule touchee. Le blob SHA bouge, le contenu non — le cas explicitement tolere par l'organe de parite (metadata_only_sha), l'attestation 0029 reste valable.

Point d'attention sur un eventuel rouge de CI

check_twin_index_collisions.py --base origin/main --head HEAD --in-tree rend cross_ref: [] (les index 0028 et 0029 de ma paire sont libres) mais intra_ref signale deux doublons portes par main sur une autre paire, gametheory-17-multiagent-rl (index 0011 et 0012, fichiers myia-po-2025-CoursIA et myia-po-2023-CoursIA) — les deux sont marques on_base: true. La PR de correction #21731 (lane myia-po-2023) ne traite que la paire gametheory-4-nashequilibrium et ne corrige pas ces deux-la : apres son merge, la jambe Scripts Tests (CPU) peut rester rouge sur toute PR qui integre main, y compris celle-ci. C'est un rouge herite de la base, hors perimetre de cette PR ; je le signale a la coordination plutot que de le corriger ici (les fichiers appartiennent a une autre lane).

Merci pour la relecture sur 94f6423a4c.

🤖 Generated with Claude Code

@myia-ai-01 myia-ai-01 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[OVERRIDE] lane myia-ai-01:CoursIA -- leve la reserve de clusterManager-Myia (persona NanoClaw, review du 2026-10-20T21:20:57Z, points : non-reproductibilite des tirages Random/Moran ; plancher pyarrow non porte par le diff).

Verifie a la tete 876f6f58fb (carnet relu au head, pas le diff) :

  • point 1 (tirages non semes) : traite en code dans cette PR (#21763). random.Random( x6, seed=42 x3, rng_seed x5, random.random() x0 ; la prose de la cellule 18 cite 522.62 / 518.75 / 501.62, les trois presentes dans les sorties commitees.
  • point 2 (pyarrow >= 26) : reporte sciemment a l'issue #21764, ouverte le 2026-10-21T06:26Z, avant ce merge ; c'est de l'infra de flotte, hors du diff.
  • type(x)() x0, .clone() aux sites annonces ; 23/23 execution_count continus 1..23, 0 sortie error, aucun motif C.1 ; metadata.papermill au basename, exception: null.
  • mergeStateStatus CLEAN, aucune jambe rouge ni en cours au head.

Approuve.

@myia-ai-01
myia-ai-01 merged commit 3d05605 into main Oct 22, 2026
97 checks passed
jsboige added a commit that referenced this pull request Oct 22, 2026
…ain)

Le cote Python porte ensemble la cellule References (#20724, attestee 0031)
et les changements #21662/#21763 (attestes 0028/0029 par CoursIA-2) ; cote
C# inchange. Conflit known_differences resolu par union au commit de merge.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
myia-ai-01 pushed a commit that referenced this pull request Oct 29, 2026
…BOOK_MAPPING verifie sur les manuels (#20724)

* docs(gametheory,#19274): cellules Lectures paliers 01/03/06/09/10 -- chapitres verifies sur les manuels de la biblio

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* chore(twin,#20724): rebaseline 4 paires GameTheory -- cellule Lectures symetrique 3/6/9/10

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs(gametheory,#20724): retitle cellules bibliographie '## Lectures' -> '## Références' (9 carnets)

Le ratchet split-reading classe 'Lectures' comme en-tete d'interpretation
(INTERPRETATION_RE ^lecture) : la cellule bibliographique poseee en tete de
carnet declenche READING_BEFORE_CODE sur 4 carnets Python. '## Références'
est la forme structurelle documentee par l'organe (docstring : 'On REJETTE
les md purement structurels (## Conclusion, ## Exercice N, ## References)')
et le precedent corpus (8x '## References' dans QuantConnect, mappage livre
a la QC demande par #19274). Markdown-only, contenu inchangé.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#20724): re-baselines 4 GameTheory attestations at head 7596f9d

Le commit de retitre 9bcfe87 a deplace les SHA de contenu des notebooks
GameTheory-3/6/9/10 sans rafraichir leurs attestations de parite : le
checker les rapportait stale au head courant. Re-baseline via
check_twin_parity.py --update au head exact 7596f9d, puis verification
--check --pair OK sur les 4 paires (Topology2x2, EvolutionTrust,
BackwardInduction, ForwardInduction-SPE).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#19274): gametheory-6 -- index d'attestations renumerotes 0022/0023 -> 0024/0025

Les deux attestations GameTheory-06 apportees par cette branche prenaient
les index 0022 et 0023, libres dans son arbre mais en collision au ref de
merge : main porte 0022-2026-10-12-myia-po-2024-CoursIA-2 (#20490) et,
apres See #21182, 0023-2026-10-13-claude-cloud-hors-flotte. Renumerotation
au prochain index libre (modele #21182 / #21152) : 0022 -> 0024,
0023 -> 0025. Contenu YAML intact, aucun fichier supprime, ordre
chronologique du journal preserve.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Chore(twin,#8057): record 0018 Topology2x2 -- attestation post-merge #20724

Le merge pre-PR (1298559) applique au C# de la branche l'edition
schema-only #20595 (retrait d'un champ nbformat d'une cellule
markdown) : blob C# deplace (1fe6620), contenu semantique
identique (content_sha OK par l'organe, MISMATCH=0). Les DEUX
re-baselines du 2026-10-14 (#20724 cote branche, #20595 cote main)
sont conservees dans known_differences avec entree de resolution.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#8057): renumerote l'entree 0016 de la lane en 0019 -- collision d'index avec l'entree hors-flotte 20167 servie sur main (#14911/#15345)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#8057): renumerote 0019/0020 forwardinduction-spe en 0022/0023 -- collision d'index avec les entrees 10-19 po-2023:CoursIA-2 servies sur main (#14911/#15345)

Le sweep check_twin_index_collisions --base origin/main --head HEAD --in-tree
ne rapporte plus aucune collision apres ce renumerotage (dates de mesure
10-14 et 10-17 preservees, seuls les index bougent).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix: rebaseline twin parity for GameTheory-3 Topology2x2 (PR #20724)

The index renumbering of the previous commit left an old-dated attestation
(0019, 2026-10-14) as latest-per-pair while the pair notebooks had evolved
since, declaring DRIFT in the Twin parity audit (#8057). Rebaseline per the
gate's prescription (check_twin_parity.py --update --pair): new entry 0020
(2026-10-20) with current blob SHAs.

Verified: check_twin_parity --check --per-pair --base origin/main
-> drift_introduced: 0; check_twin_index_collisions --head HEAD -> OK.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Attest(twin,#19274): GT-6/9/10 -- cellules References miroirs byte-identiques, audit firsthand

La PR ajoute la meme cellule markdown References (Osborne & Rubinstein
+ Leyton-Brown & Shoham + gisement cluster) aux DEUX jumeaux de chaque
paire (verifie cell-by-cell sur le diff) ; GT-06 C# nettoie en sus des
blancs de fin de cellule. Aucune cellule code touchee. Re-verification
--per-pair --base origin/main : INTRO=0, PRE=20 (herites de main),
GT-4 RESOLVED par la PR.

See #20724

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#8057): renumerote 5 attestations en collision d'index (GT-6/9/10)

Le merge de main a produit des index dupliques dans trois paires GameTheory : la branche
avait ecrit des attestations 2026-10-14/10-17 sous des ordinaux que main occupait deja
avec ses entrees 2026-10-19 (et, pour GT-10, deux 0022 coexistaient). Les posterieures
cedent : ce sont les entrees de main qui gardent l'ordinal, les notres remontent au
premier index libre.

  GT-10 : 0022-10-14 -> 0025-10-14   (main garde 0022-10-20)
  GT-6  : 0024-10-14 -> 0029-10-14, 0025-10-17 -> 0030-10-17
  GT-9  : 0012-10-14 -> 0015-10-14, 0013-10-17 -> 0016-10-17

Renumerotation par `git mv` pur (aucun contenu touche). Comme l'organe retient
l'attestation d'index le plus haut, ces renommages promeuvent des SHAs perimes : une
attestation fraiche est donc ecrite au-dessus pour chaque paire (0026 GT-10, 0031 GT-6,
0017 GT-9), sur les blobs courants. Verifie : `check_twin_index_collisions.py
--repo . --base origin/main --head HEAD --in-tree` ne rend plus de collision imputable a
la branche (restent gametheory-17 0011/0012 et sudoku-14 0019, deja sur main), et
`check_twin_parity.py --check` rend OK sur les trois paires.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#20724): dedup des attestations byte-identiques intra-paire (#15345)

Le garde test_audit_index_unique_and_no_identical_duplicates_per_pair
refusait la branche : 0028/0031 (GT-6) et 0014/0017 (GT-9), toutes deux
de ma lane du 2026-10-21, portaient le meme blob (10ddd56 / 768fdfe) --
deux --update successifs sans changement de contenu. Les copies
d'indice BAS sont retirees ; les indices hauts (0031, 0017) restent les
derniers lus (tri lexical), la semantique du registre est inchangee.
Verifie : pytest test_twin_registry_integrity.py = 46 passed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#20724): attestation 0032 de l'etat fusionne (merge origin/main)

Le cote Python porte ensemble la cellule References (#20724, attestee 0031)
et les changements #21662/#21763 (attestes 0028/0029 par CoursIA-2) ; cote
C# inchange. Conflit known_differences resolu par union au commit de merge.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(ci): renumerote l'attestation twin 0029->0033 gametheory-6 -- collision d'index avec main (0029-10-21 CoursIA-2), precedent #21152

L'attestation 0029-2026-10-14-myia-po-2024-CoursIA.yaml (branche seule, predant
l'avance de main) collisionne avec 0029-2026-10-21-myia-po-2024-CoursIA-2.yaml
deja sur main : deux 0029 dans la paire apres merge origin/main. Renommage vers
l'index libre 0033 (date d'attestation conservee), le fichier de main reste
canonique. Debloque test_audit_index_unique et test_intra_revision.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#20724): rebaseline de la paire GameTheory-6 EvolutionTrust

Le Twin parity audit (#8057) rougissait sur cette PR : 1 paire DRIFT
introduite par le diff. Le registre stocke le blob SHA de chaque jumeau,
donc toute edition le deplace -- y compris markdown-only.

Audit firsthand avant rebaseline : les deux jumeaux portent la cellule
'## References' (ajout symetrique de #20724) en position 1, texte
identique des deux cotes, 0 cellule code logique touchee. Le rebaseline
ATTESTE cette parite, il ne la repare pas.

Python 66 cellules (43 md) / C# 46 cellules (30 md) : l'ecart de compte
est pre-existant (#11200, parity_level semantic), pas introduit ici.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#20724): rebaseline de 4 paires GameTheory apres #22071

Le job `Twin parity audit (#8057)` signalait 4 paires en DRIFT que la PR
avait laissees derriere elle : GameTheory-10 ForwardInduction-SPE,
GameTheory-3 Topology2x2, GameTheory-6 EvolutionTrust et
GameTheory-9 BackwardInduction.

Mesure : dans les quatre cas le `python_sha` est INCHANGE par rapport a
l'entree precedente du registre, seul le `csharp_sha` a bouge -- la
contrepartie C# de ces paires a ete modifiee sur `main` par #22071
(tranche 3 du retrait de la chronologie de workflow, volet pieds de page,
15 carnets GameTheory), apres les attestations 0020/0026/0034/0017. La
branche reposant desormais sur ce `main`, ces attestations etaient
perimees par rapport a leur propre base.

Une entree 2026-10-24 par paire atteste l'etat courant. Aucun carnet
n'est retouche par ce commit, aucune sortie modifiee, aucune re-execution
due (C.2 sans objet) : seuls les 4 fichiers de registre s'ajoutent.

Controle apres ecriture : `check_twin_parity.py --pair` sur les 4 ->
[OK] pour les 4, DRIFT=0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* chore(twin): attestation GameTheory-3 Topology2x2 post-merge #20724

Le merge applique les deux editions markdown-only (cellules Lectures
de la branche + re-baseline Python de main) : python_sha deplace,
csharp_sha stable. Journal 0022 + note d'union dans le yaml de paire.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(twin,#20724): retirer 4 attestations perimees a SHAs jamais-blob, remplacees par les re-audits 22-24/10 de main

Cause: les attestations du 17-19/10 portees par cette branche citent des
SHAs de carnets GameTheory-10/03/06 jamais apparus comme blobs (ere du
bug _next_audit_index, #14911/#15345). Le merge de main fait cohabiter
ces fichiers avec les re-audits 22-24/10 qui ont repris les memes
indices NNNN (0017/0018/0023/0030) -> doublons d'index dans l'arbre de
merge, Scripts Tests (CPU) rouge.

Disposition: suppression, avec preuve de preservation -- chaque paire
conserve son attestation de re-audit (0023-22/10, 0017-22/10 +
0018-24/10, 0030-22/10) venue de main ; les 4 fichiers restent dans
l'historique git de la branche ; leurs SHAs n'ayant jamais ete blobs,
aucune position d'index ne peut les rendre utilisables comme dernier
audit sans faire echouer test_audit_shas_exist_in_file_history.

Verification: test_twin_registry_integrity.py + test_twin_index_collisions.py
(60 tests) verts sur l'arbre apres commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants