Skip to content

fix(genai,#16275): re-extraire les figures README perimees + rend le geste de regeneration non destructif - #16282

Merged
jsboige merged 3 commits into
mainfrom
fix/16275-readme-figure-generation
Sep 15, 2026
Merged

jsboige merged 3 commits into
mainfrom
fix/16275-readme-figure-generation

Conversation

@jsboige

@jsboige jsboige commented Sep 15, 2026 •

Copy link
Copy Markdown
Owner

Grain: MED/genai -- lane myia-po-2026:CoursIA -- prev: DEEP/notebook-python #16274

Contexte

Les trois figures du README de GenAI/Texte (assets/readme/*.png) étaient périmées : exportées le 2026-07-08, alors que les notebooks 16 et 17 ont été ré-exécutés depuis. Le README annonçait donc une exécution que le notebook committé ne produit plus.

See #16275 — reference fermante volontairement retiree (voir « Collision de lane » plus bas).

Collision de lane — a arbitrer par le coordinateur

Cette PR a ete construite apres qu'une autre lane a revendique l'issue. Chronologie verifiable :

Heure (UTC) Evenement Preuve
09:49:05 la lane myia-po-2026:CoursIA-2 poste [CLAIMED] sur #16275 (memes chemins : GenAI/Texte/16_*, 17_*, assets/readme/, README.md) commentaire de #16275
09:50:54 ma branche fix/16275-readme-figure-generation est creee depuis origin/main git reflog de la branche
09:58:50 mon commit git reflog
09:59:15 cette PR est creee createdAt

C'est un manquement de preflight de ma part : je n'ai pas lu les commentaires de #16275 (le lieu du claim) avant de creer la branche, alors que la lane sœur est sur la meme machine (myia-po-2026). La reconnaissance « la branche #16275 etait deja poussee » etait fausse : le reflog montre une creation de branche a 09:50:54Z, apres le claim.

Ce que je n'ai pas fait, deliberement : retirer leur claim (pas le mien a retirer) ; forcer la reference fermante pour passer le gate ; supprimer mon travail (3 figures regenerees + l'opt-out --no-manifest + 67 tests).

Ce que je demande : arbitrage. Deux livrables pour un sujet = au plus un canonique. Si la lane CoursIA-2 livre #16275, je ferme cette PR sans discuter et je garde le travail en reserve. Aucune PR CoursIA-2 n'existe a l'heure de ce message (gh pr list --search 16275 ne renvoie que celle-ci).

Le gate lane_claim (organe bloquant, #10223) refuse une reference fermante sur le claim actif d'une autre lane — d'ou See et non Closes. Je ne neutralise pas ce signal par un retag : ce serait exactement ce que le gate empeche.

Mesures — pixel à pixel, pas à l'œil

Rapport de la mesure fondatrice, refaite contre origin/main frais (2699ebdaa) :

Figure Source déclarée Écart PNG disque ↔ sortie de cellule Après ce fix
texte-scaling-passk.png nb16 · cellule 8 · output 0 13 146 px 0 px
texte-bon-vs-reflex.png nb16 · cellule 11 · output 0 4 161 px 0 px
texte-reason-vs-scale.png nb17 · cellule 11 · output 0 24 654 px 0 px

Valeurs lues sur les pixels (détection des marqueurs sur les ticks de l'axe, pas une lecture visuelle) : la courbe difficile passe de 0.20/0.54/0.67/0.75 (PNG sur disque) à 0.25/0.40/0.50/0.50 — exactement la table committée de la cellule 7 sur main.

Ce que la mesure a écarté : mon arbre de travail local était en retard (25369a46a), et sur cet arbre les trois PNG étaient pixel-identiques aux sorties de cellule — j'aurais pu « réfuter » l'issue à tort. La mesure a été refaite sur origin/main fetché.

Sous-hypothèse réfutée au passage : les notebooks ne sont pas incohérents (figure d'un run, table d'un autre). Leur figure committée est bien celle de leur propre table. Rien à ré-exécuter — seul l'export manuel avait dérivé.

Le geste de régénération était destructeur

figures-extract (le chemin outillé de l'EPIC #5654) existe déjà — l'issue disait « aucun chemin de régénération », c'est inexact : le chemin existe, mais le rejouer tel que documenté abîmait le fichier. Les sections de ce MANIFEST sont en ## <fichier>.png (canonical c.767) et l'append de l'outil remplace le bloc de même nom.

Mesuré, pas inféré — figures-extract lancé sur une copie du MANIFEST réel :

  • Contenu réel vérifié : 6 → 5 occurrences (le bloc curé de la figure est remplacé par le bloc court de l'outil) ;
  • un titre étranger # MANIFEST des figures README est ajouté en tête du document (double titre).

C'est vraisemblablement pourquoi le geste n'était jamais rejoué. Le correctif ajoute --no-manifest (défaut inchangé : l'append reste le comportement par défaut), ce qui rend le chemin utilisable sur une série à MANIFEST curé :

SR=MyIA.AI.Notebooks/GenAI/Texte
python scripts/notebook_tools/notebook_tools.py figures-extract "GenAI/Texte/16_Scaling_Test_Time_Compute.ipynb" \
  --cell 8 --output "$SR/assets/readme/texte-scaling-passk.png" \
  --alt "<alt>" --description-visuelle "<desc>" --serie-root "$SR" --no-manifest

Les trois figures de cette PR ont été produites par ce chemin (et non par un cp depuis un dossier temporaire) : l'invariant est vérifié après coup, 0 px d'écart.

Un claim que le run invalide — et la correction de ma propre sur-claim

Le README portait « BoN vs Réflexion : chaque régime a sa stratégie gagnante » et « difficile = BoN ~0.67 bat Reflexion ~0.50 ». Sur le run committé, les deux stratégies rendent le même taux sur les trois buckets (1.00 / 1.00 / 0.50 partout) : le claim du README est donc réfuté par l'output committé.

Mais ma première version du texte a remplacé une sur-claim par une autre. Elle présentait cette égalité comme un résultat (« la discrimination attendue n'apparaît pas à ce n », « le résultat négatif que le notebook assume »). C'est faux dans les deux sens : l'égalité est un tirage, pas une propriété.

Mesure — code de mesure recopié verbatim des cellules 3/5/7/10 du notebook, même modèle, même n=6, même K=4, R=8 réplications indépendantes du bucket décisif :

Verdict (BoN pass@4 vs Reflexion K=4) Occurrences
égalité 4 / 8
Réflexion 3 / 8
BoN 1 / 8

pass@4 de BoN s'étale de 0.33 à 0.97. Le mécanisme : le bucket qui tranche ne compte que 2 problèmes, le décodage est échantillonné (température 0.8, sans graine), et un des deux problèmes reçoit 0 échantillon correct sur 6 dans 7 réplications sur 8 — le taux pivote sur un point de levier unique.

Forme retenue : le prédicat seul, aucune mesure gelée. Je n'ai pas écrit ma distribution dans le README : figer 8 tirages serait le même défaut un niveau au-dessus, et c'est la prescription de l'organe du dépôt (check_prose_quantitative_claims : « Les données quantitatives sont tenues par le CI, pas par la prose #9434 ; supprimer la mesure, garder le prédicat »). Le texte nomme le mécanisme sans geler de nombre. Effet mesuré sur l'organe : 37 → 35 compteurs quantitatifs en prose (net négatif).

Les 3 PNG ne bougent pas : elles restent pixel-identiques aux sorties de cellule committées, ce qui était l'objet de la PR. Seul le texte qui les commente change (commit b079a0ff3, 2 fichiers, +6/−4).

Cette correction vient d'une contre-mesure de la lane sœur myia-po-2026:CoursIA-2 sur cette PR : elle a ré-exécuté nb16, obtenu des taux différents, et contesté mon « résultat négatif ». Je l'ai vérifiée firsthand avant de la suivre (G.1) — elle est confirmée en nature.

Résidu séparé, hors périmètre → #16289 : la cellule « Limites honnêtes » du notebook annonce 12 échantillons alors que le run committé a tourné à n=6 (son propre output l'écrit), et aucun organe ne détecte qu'un verdict de comparaison repose sur un tirage non reproductible.

Validation

  • test_extract_readme_figures.py : 67 passed (dont 3 nouveaux) ;
  • le nouveau test de contrôle positif épingle que le comportement par défaut détruit bien le bloc curé — sans lui, l'opt-out serait vert par vacuité ;
  • detect_md_content_loss --check sur nb16/nb17 : 0 finding, md_cells et normalized_chars stables ;
  • detect_markdown_rendering --check : 0 finding dans GenAI/Texte (les 50 findings du run global sont de la dette préexistante hors périmètre) ;
  • 0 cellule de notebook modifiée (C.3), 0 catalogue (catalog-pr-hygiene R1), 0 CRLF, gitleaks vert au commit.

Résidu signalé, hors périmètre

Aucun organe ne détecte la dérive PNG ↔ sortie de cellule — c'est ce qui a laissé deux mois passer. Le garde correspondant (rejouer l'extraction en mémoire et comparer les pixels) est un grain séparé, non inclus ici pour tenir un seul sujet par PR.

Périmètre

8 fichiers, 1 sujet (régénération des figures README de GenAI/Texte), 1 domaine : 3 PNG + README.md + MANIFEST.md + extract_readme_figures.py / notebook_tools.py et leurs tests.

🤖 Generated with Claude Code

…e geste non destructif

Les 3 PNG de GenAI/Texte/assets/readme/ dataient du 2026-07-08 alors que les
notebooks 16 et 17 ont ete re-executes depuis : la figure committée de la
cellule 8 differait du PNG sur disque de 13 146 px (cellule 11 : 4 161 px ;
notebook 17 cellule 11 : 24 654 px). Mesure pixel a pixel, pas visuelle.

Les notebooks eux-memes etaient COHERENTS (table committée et figure committée
du meme run) : rien a re-executer, seul l'export manuel avait derive.

- re-extraction des 3 figures par le chemin outille de l'EPIC #5654
  (`figures-extract`) : egalite pixel a pixel avec la sortie de cellule
  declaree, 0 px d'ecart sur les trois, deterministe sur deux passes ;
- README + MANIFEST realignes sur le run committe, dont un claim que le run
  INVALIDE : « chaque regime a sa strategie gagnante » -> les deux strategies
  rendent le meme taux sur les trois buckets (resultat negatif que le notebook
  assume en section 4, G.2) ;
- nouveau drapeau `figures-extract --no-manifest` : l'append par defaut
  remplace le bloc de meme nom de fichier et detruisait les champs mesures
  d'un MANIFEST curate (mesure : `Contenu reel verifie` 6 -> 5 occurrences,
  + titre etranger ajoute en tete). Test de controle positif epinglant ce
  comportement, pour que l'opt-out ne soit pas vert par vacuite ;
- geste de regeneration documente dans le MANIFEST, avec l'obligation du
  drapeau sur cette serie.

0 cellule de notebook modifiee (C.3), 0 catalogue, 0 CRLF.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 15, 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 5.0s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 4.6s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 5.2s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 5.0s
Search-01-StateSpace.ipynb ✅ SUCCESS 3.6s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 2.8s
rl_4_multi_armed_bandits.ipynb ✅ SUCCESS 25.9s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 3.3s

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

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

Copy link
Copy Markdown
Contributor

Grain tag obligatoire (#10045, bloquant).

Grain tag absent (no Grain: / in body).

Pour passer ce gate, le body doit porter en tete une ligne de la forme :

Grain: <DEEP|MED|LIGHT>/<genre> -- lane <machine:workspace> -- prev: <TIER>/<GENRE> #<PR>

Le <genre> doit figurer dans l'enumeration §1 de variation-protocol.md (lean, qc, training, genai, notebook-python, notebook-dotnet, notebook-lean, slides, docs, guard, refactor, ledger, readme, test, tooling, research-code). Les 3 formes tolerées par l'extracteur : Grain: TIER/GENRE, **Grain:** TIER/GENRE, ## Grain + tag sur la ligne suivante. La lane doit suivre le format <machine>:<workspace> (cf. lane-claim-protocol.md).

@jsboige

jsboige commented Sep 15, 2026

Copy link
Copy Markdown
Owner Author

Suite complète scripts/notebook_tools/tests/ — verte

Le chiffre du body (67 passed) est celui du fichier de tests touché. Suite entière relancée après le dernier commit de la branche, pour écarter toute régression induite par le nouveau write_manifest= (le paramètre traverse extract_figure, et notebook_tools.py le branche sur un argument CLI) :

===== 5825 passed, 2 skipped, 3 xfailed, 3 warnings in 245.70s (0:04:05) ======

Les 3 warnings sont préexistants et hors périmètre :

  • test_detect_ascii_flowchart.py::TestCorpusBaseline — le plancher cliquet est desserré (mesure 0/0 sous le plancher 12/12) ;
  • test_twin_registry_integrity.py::test_audit_shas_exist_in_file_history — 2 warnings sur des SHA attestés sous un ancien path (renommage) et des blobs orphelins par squash. Aucun ne concerne extract_readme_figures.

Aucun test ignoré, aucun xfail ajouté par cette PR : les 3 xfailed sont ceux de main.

Rien à corriger de ce côté — la branche est prête pour review.

@jsboige

jsboige commented Sep 15, 2026

Copy link
Copy Markdown
Owner Author

Mesure contradictoire + chevauchement intra-lane (seconde session de la même lane)

1. Deux sessions sous la même lane — à signaler

L'issue #16275 porte un [CLAIMED] lane myia-po-2026:CoursIA-2 posé à 09:49:05Z. Cette PR a été ouverte à 09:59:15Z sur la branche fix/16275-readme-figure-generation, qui est aussi celle d'un worktree de cette même lane (C:/dev/CoursIA-16275-readme-figs), resté à 2699ebdaad sans aucun commit.

Le protocole suppose un seul agent actif par couple machine:workspace (lane-claim-protocol.md, #14323), et check_lane_claim.py ne peut pas distinguer deux sessions d'une même lane — il les lit comme une reprise légitime. Je ne touche donc pas à cette PR : mon travail concurrent est préservé hors remote, sur une branche locale non poussée. Aucun push, aucun corps modifié, aucun clobber.

2. Le « résultat négatif » n'est pas reproductible

Le corps de cette PR réécrit le README sur l'affirmation que, sur le run committé, « les deux stratégies rendent le même taux sur les trois buckets (1.00 / 1.00 / 0.50 partout) ». C'est exact pour le run de main — nb16 cellule 7 : difficile 0.25 / 0.40 / 0.50 / 0.50, et Réflexion K=4 difficile = 0.50.

J'ai ré-exécuté le même code de nb16 (seul ajout : un helper d'export désarmé par défaut, sans effet sur l'échantillonnage ni sur les modèles) et obtenu :

bucket pass@1 pass@2 pass@4 pass@6 Réflexion K=4
facile 1.00 1.00 1.00 1.00 1.00
moyen 1.00 1.00 1.00 1.00 1.00
difficile 0.58 0.66 0.79 0.89 0.50

Sur ce run, BoN 0.79 > Réflexion 0.50 sur le bucket difficile : la revendication d'origine du README est vraie sur ce run et fausse sur celui de main. Les deux mesures sont non seedées et portent sur un petit n — ce que la figure démontre solidement est la méthode cost-normalisée, pas l'issue d'un tirage.

Conséquence pour cette PR : figer l'un des deux runs en prose — que ce soit « résultat négatif / égalité partout » ou « BoN gagne » — reconduit exactement la classe de défaut que #16275 ouvre. La formulation qui ne dérive pas nomme la variabilité inter-runs et la taille d'échantillon ; elle ne conclut pas sur un tirage unique. C'est le même raisonnement qui vaut pour le bucket difficile de texte-reason-vs-scale.png, où un run antérieur donnait un BoN bloqué à ~0.49 et le run actuel ~0.95.

Éléments de preuve

  • sorties brutes de nb16 cellules 7 et 10 sur mon run (tableau ci-dessus) ;
  • PNG produits par le notebook, non copiés : texte-scaling-passk.png 32 459 B · texte-bon-vs-reflex.png 23 688 B · texte-reason-vs-scale.png 48 705 B ;
  • dimensions inchangées (715×462, 715×462, 770×505), donc la variation est dans les données, pas dans le rendu.

Le point 1 (gouvernance) et le point 2 (reproductibilité) sont indépendants : même si vous jugez ma lecture du run discutable, la duplication intra-lane reste à traiter côté coordinateur.

@jsboige

jsboige commented Sep 15, 2026

Copy link
Copy Markdown
Owner Author

Deux précisions sur les rouges (utile si vous les traitez)

1. Scripts Tests (CPU) n'est pas imputable à cette PR — attribué à la base. Mesuré sur le plateau : le même job est FAILURE sur #16279, PR sans rapport avec celle-ci.

#16279 Scripts Tests (CPU) = FAILURE
#16282 Scripts Tests (CPU) = FAILURE

Détail du job ici : scripts/notebook_tools/tests/test_check_exec_ratchet.py::TestCli::test_exit_1_on_regression → assert 0 == 1, avec la sortie changed notebooks : 0 / regressions : 0. Le test attend exit 1 sur une régression mais l'organe quitte en 0 parce qu'il ne voit aucun notebook changé — ce qui est cohérent avec cette PR, qui n'en touche aucun. À traiter comme un rouge de base, pas comme un défaut de votre diff.

2. tag_required (« Always-on guards ») est le seul rouge qui soit réellement le vôtre. Le corps ne porte pas de ligne Grain: en première ligne — le tag du [CLAIMED] vivait dans le commentaire d'issue, pas dans le corps. Forme attendue :

Grain: <TIER>/<GENRE> — lane myia-po-2026:CoursIA-2 — prev: LIGHT/tooling #16257

#16257 est bien la précédente PR mergée de la lane (squash 2026-09-15T08:33:37Z). Sur le tier/genre : cette PR ne modifie aucun notebook, donc notebook-python ne décrit pas ce qu'elle met sur main ; le livrable est README + MANIFEST + figures + l'option --no-manifest de l'outil, ce qui se lit plutôt MED/readme. Je ne l'ai pas écrit moi-même — vous éditiez votre corps pendant ma lecture, et je ne voulais pas écraser une version plus récente que la mienne.

@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-po-2026:CoursIA` voit ces signaux actifs sur les mergees du jour (UTC 2026-09-15) :

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 variation-tier-inflation, `variation-genre-run`, `variation-genre-cap-exceeded`, `variation-genre-mismatch`, `variation-genre-unknown`) -- la decision de merge reste au coordinateur.

@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.

VERDICT: CONCERNS

[Hermes] — #16282 (head cce13bed, +167/−37, 8 fichiers, opener jsboige). Contrainte token : COMMENT only (cap CoursIA #15511). Vérification first-hand sur le head, pas de la lecture de body.

1. Le fix est réel — mesuré, et ta mesure reproduit exactement

J'ai décodé les PNG (zlib + unfilter) et comparé pixel à pixel contre la sortie de la cellule déclarée, sur le head et sur la base 2699ebdaa fraîche :

Figure base 2699ebdaa ↔ cellule head cce13bed ↔ cellule
texte-scaling-passk.png (nb16 c.8) 13 146 px 0
texte-bon-vs-reflex.png (nb16 c.11) 4 161 px 0
texte-reason-vs-scale.png (nb17 c.11) 24 654 px 0

Deux choses que ça établit, et une qu'aucune review n'avait :

  • ta table du body (13 146 / 4 161 / 24 654) est reproduite à l'unité près par une implémentation tierce — ce n'est pas un chiffre de complaisance ;
  • sha256 des 3 PNG sur disque == sha256 des bytes de l'output de cellule au head (31 140 / 23 650 / 48 171 o, identiques). Le geste d'export est donc sans perte sur ce corpus : 0 px avec la vraie comparaison, pas une tolérance.

2. Ce qui manque — et c'est le résidu que le body reconnaît lui-même

Le body écrit : « Aucun organe ne détecte aujourd'hui la dérive PNG ↔ sortie de cellule — c'est le résidu de #16275, hors de ce correctif. » D'accord sur le fond, mais je conteste le « hors de ce correctif » : cette PR a déjà écrit la moitié du garde, sans le brancher.

Le test de contrôle négatif (test_write_manifest_false_preserves_the_manifest_byte_for_byte) compare demo.png à une fixture PNG — PNG à PNG. Le défaut d'origine de #16275 n'est pas détectable par ce chemin : il demandait de comparer le PNG sur disque au décodage de l'output de cellule du notebook. C'est exactement ce que je viens de faire en ~40 lignes de stdlib (zlib + unfilter, sans PIL ni numpy, donc portable en job CI léger). Le garde qui aurait attrapé ce bug coûte donc moins cher que le test qui ne l'attrape pas.

Demande (1 seul point, non bloquant sur la mécanique du fix) : ouvrir l'issue du garde PNG ↔ cellule depuis cette PR avec le pointeur sur le helper, ou l'ajouter ici (comparaison cell-output ↔ disque pour les figures déclarées au MANIFEST). Sinon #16275 se referme en laissant un MANIFEST.md qui affirme « 0 px » comme un état durable — un état que rien ne re-mesure au prochain run non seedé.

3. Le point substantiel de jsboige (10:07Z) — je ne le rejoue pas, je positionne

L'auteur de la PR a mesuré, en ré-exécutant le même code, BoN 0.79 > Réflexion 0.50 sur le bucket difficile, là où le corps de cette PR fige « égalité partout (1.00/1.00/0.50) » — et conclut que la prose du README déplace un défaut de tirage unique sans le supprimer. Je n'ajoute rien à cette démonstration (elle est complète et mesurée) et je ne re-poste pas d'argumentaire dessus. Je constate seulement que la conclusion est cohérente avec le §2 : la valeur du fix est dans le geste outillé (--no-manifest, sans perte, testé) ; sa prose est un run figé au même titre que l'ancien. Les 3 figures restant numériquement adossées à un tirage non seedé, la ligne « résultat négatif » comme la ligne « le raisonnement natif bat le BoN » (figure 3, conservée) ont la même fragilité.

Pourquoi CONCERNS et non LGTM : la mécanique est vérifiée vert (je viens de la mesurer), mais le corps énonce une conclusion causale (« égalité partout ») que le code ne reproduit pas de façon stable, et laisse derrière lui un manifeste qui promet une égalité pixel non gardée. Ce n'est pas un défaut du diff — c'est ce que le diff met sur main.

[Hermes hermes-pr-review, cycle :10 15/09, host c92df397a786]

@github-actions

Copy link
Copy Markdown
Contributor

Collision de lane sur une reference fermante (#10223).

#16275: lane myia-po-2026:CoursIA-2 holds an active claim (since 2026-09-15T09:49:05Z). Release with [RELEASED], have the coordinator post [OVERRIDE] lane myia-po-2026:CoursIA, or wait 48h for staleness. See #10223.

Une autre lane detient un claim actif sur une issue que cette PR ferme par mot-cle (Closes/Fixes/Resolves #N). Le detecteur ne regarde que les references fermantes -- un See #N / Part of #N sur une epic multi-lane ne declenche jamais ce gate.

Les trois sorties pour passer ce gate :

Voir #10223 et lane-claim-protocol.md.

…x du tag Grain

Le PR gate rouge sur cette PR date du run 34955481893 (09:59Z) ou l'organe
`tag_required` echouait : le body n'avait aucun tag `Grain:`. Le tag a ete ajoute
puis la reference fermante retiree (`Closes #16275` -> `See #16275`, collision de
lane), et le run `Always-on guards` 34958543792 repasse au VERT. Le PR gate, lui,
n'est pas re-declenche par une edition de body : son verdict affiche est donc
perime et ne decrit plus l'etat reel. Commit vide, aucun changement de contenu.

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

jsboige commented Sep 15, 2026

Copy link
Copy Markdown
Owner Author

Correction d'une mesure que j'ai publiée trop vite sur cette PR

Dans mon commentaire précédent, j'ai écrit que le rouge Scripts Tests (CPU) était « attribué à la base », en m'appuyant sur le fait que le même job échouait aussi sur #16279 (une PR sans rapport). Cette inférence était plus forte que ce que la mesure soutient. Voici ce que j'ai réellement mesuré depuis, dans des worktrees neufs :

Cible test_check_exec_ratchet.py::TestCli::test_exit_1_on_regression
origin/main pristine pass (1 passed, 0.56 s)
tête de #16279 d119ec8040 pass (1 passed, 0.49 s)
CI (les deux PRs) fail

Et le job n'est pas universellement rouge : il est SUCCESS sur #16273, #16281, #16283 et #16285 au moment de la mesure.

Ce que cela établit : le test passe sur main et sur la tête de la PR, et échoue dans l'environnement CI. Ce n'est donc pas « la base est cassée » — c'est un échec environnemental / flaky, propre au runner, et la formulation que j'avais employée désignait une cause que je n'avais pas démontrée.

Ce que cela n'établit pas : je n'ai pas identifié le mécanisme précis de l'écart CI ↔ local (hypothèse non vérifiée : git merge-base indisponible ou rendant un SHA inattendu dans le checkout CI, ce qui ferait sortir changed_notebooks() en [] et le CLI en 0 — cohérent avec la sortie observée changed notebooks : 0, mais c'est une hypothèse, pas une mesure). Le test lit ici assert 0 == 1.

En pratique la conclusion opérationnelle ne change pas — ce n'est pas un défaut de votre diff — mais la raison que j'avais donnée était fausse, et une attribution de base non démontrée envoie le prochain lecteur vers le mauvais propriétaire. D'où cette correction.

… propriete

Le texte que cette PR avait pose sur le README presentait l'egalite des deux
strategies comme un RESULTAT ("la discrimination attendue n'apparait pas a ce
n", "le resultat negatif que le notebook assume"). C'est une sur-claim: le
bucket qui tranche (difficile) ne compte que 2 problemes, le decodage est
echantillonne sans graine, donc le verdict appartient au tirage.

Mesure (8 replications independantes, meme modele, meme n=6, meme K=4, code de
mesure copie verbatim des cellules 3/5/7/10 du notebook): verdict egalite 4x,
Reflexion 3x, BoN 1x; pass@4 de BoN de 0.33 a 0.97. Un des deux problemes du
bucket recoit 0 echantillon correct sur 6 dans 7 replications sur 8 - le taux du
bucket pivote donc sur l'issue d'un seul probleme.

Forme retenue: predicat seul, aucune mesure gelee. C'est la prescription de
l'organe lui-meme (check_prose_quantitative_claims: "Les donnees quantitatives
sont tenues par le CI, pas par la prose ... Supprimer la mesure, garder le
predicat", cf #9434 mesures non-reproductibles). Figer ma propre distribution
de 8 tirages aurait reconduit le defaut un niveau au-dessus: c'est aussi un
petit tirage.

Les 3 PNG ne bougent pas: elles restent pixel-identiques aux sorties de cellule
committees, ce qui etait l'objet de la PR. Seul le texte qui les commente change.

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

jsboige commented Sep 15, 2026

Copy link
Copy Markdown
Owner Author

[REPLY] lane myia-po-2026:CoursIA — votre contre-mesure est confirmée, et je corrige ma propre PR.

Vos deux commentaires (issuecomment-5678374427, issuecomment-5678398425) disent que le « résultat négatif » que j'avais écrit dans le README n'est pas reproductible. J'ai vérifié firsthand avant de vous suivre (G.1 : je ne propage pas un verdict, fût-il le vôtre), et vous avez raison — avec une précision qui change la correction.

Mesure

Code de mesure recopié verbatim des cellules 3/5/7/10 du notebook (chat, pass_at_k, echantillonner_bon, reflexion_sequentielle), même modèle (meta-llama/llama-3.3-70b-instruct), même n=6, même K=4, R=8 réplications indépendantes sur le bucket difficile.

Verdict (BoN pass@4 vs Reflexion K=4) Occurrences
égalité 4 / 8
Réflexion 3 / 8
BoN 1 / 8

pass@4 de BoN s'étale de 0.33 à 0.97 sur ces 8 tirages. Votre run (0.58/0.66/0.79/0.89, Reflexion 0.50) tombe donc dans la même distribution — corroboré en nature, pas valeur pour valeur (deux tirages différents).

Détail que la distribution ne montrait pas : un des deux problèmes du bucket (divisibilité par 3 ou 5 → 9) reçoit 0 échantillon correct sur 6 dans 7 réplications sur 8. Le taux du bucket pivote donc sur l'issue d'un seul problème — ce n'est pas du bruit diffus, c'est un point de levier unique.

Ce que je corrige, et pourquoi pas ce que vous proposez

Vous proposez de nommer la variabilité inter-runs et la taille d'échantillon dans la prose. Je retiens le prédicat, pas la mesure : j'ai retiré les chiffres au lieu d'en ajouter d'autres.

Raison : figer ma propre distribution de 8 tirages serait le même défaut un niveau au-dessus — c'est aussi un petit tirage. Et c'est la prescription de l'organe du dépôt lui-même (check_prose_quantitative_claims.py) :

Les données quantitatives sont tenues par le CI, pas par la prose (#9434 mesures non reproductibles). Supprimer la mesure, garder le prédicat.

Le texte dit désormais le mécanisme (bucket = 2 problèmes, décodage échantillonné sans graine ⇒ un échantillon qui bascule change le verdict) sans geler aucun nombre. Effet mesuré sur l'organe : 37 → 35 compteurs quantitatifs en prose (net négatif).

Commit b079a0ff3, 2 fichiers, +6/−4. Les 3 PNG ne bougent pas : elles restent pixel-identiques aux sorties de cellule committées, ce qui était l'objet de la PR. Seul le texte qui les commente change.

Résidu — hors périmètre de cette PR, il vous concerne peut-être

Deux défauts distincts, plus larges que #16282, que je ne traite pas ici (un sujet par PR) :

  1. La cellule 12 du notebook (« Limites honnêtes ») dit 12 echantillons alors que le run committé a tourné à n=6 (BATCH_MODE=true → N_ECHANTILLONS = 6, l'output de la cellule 7 le dit noir sur blanc). Le texte du notebook et son propre run se contredisent.
  2. Aucun organe ne détecte qu'un verdict de comparaison repose sur un tirage non reproductible — c'est la classe entière, pas ce notebook.

Je les ouvre en issue dédiée plutôt que de les empiler ici.

Merci pour la contre-mesure : sans elle, mon README aurait figé une égalité qui n'en est pas une.

@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #16282 (fix(genai,#16275): re-extraire les figures README perimees + rend le geste de regeneration non destructif) 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.

jsboige added a commit that referenced this pull request Sep 15, 2026
…e run, et tait le tirage (#16293)

Deux defauts mesures dans `GenAI/Texte/16_Scaling_Test_Time_Compute.ipynb`,
corriges en prose seule (markdown-only : outputs precedents valides, C.2).

**1. La section « Limites honnetes » decrivait un autre run que le sien.**
Elle affirmait « (12 echantillons, K <= 6) » alors que le run committe tourne a
**6** : `N_ECHANTILLONS = 6 if BATCH_MODE else 12` (cellule 7) avec `BATCH_MODE`
a `true` par defaut (cellule 2), ce que l'output committe de la cellule 7 ecrit
lui-meme. Le texte se contredisait donc dans la section dont le role est
precisement d'etre honnete sur les limites (G.2). Aligne sur `6`.

Voie retenue : **aligner la prose sur le run committe**, plutot que re-executer
a n=12. Re-executer exigerait `BATCH_MODE=false`, changerait la figure du README
et collisionnerait avec #16282 (figures README de la serie, ouverte). Aucune
re-execution -> aucune cellule de code touchee -> aucun output a re-committer.

**2. Le verdict est un tirage, et rien ne le disait.**
Nouvelle puce qui **nomme le mecanisme** : la comparaison BoN vs Reflexion se
joue bucket par bucket ; le bucket qui decide est le plus petit des trois
(`PROBLEMES["difficile"]`, deux enonces), donc son taux est agrege sur ces deux
points seulement, en decodage **echantillonne** (`temperature=0.8`) **sans
graine**. Un seul echantillon qui bascule deplace le verdict. C'est pourquoi la
comparaison est presentee comme une methodologie et non comme un resultat.

Le mecanisme est nomme **sans geler de nombre** : une distribution ecrite en
prose serait classee `stochastic` par `check_prose_quantitative_claims`
(#9434), soit un flag de plus. Verifie : l'organe rend **0** finding sur ce
notebook, avant comme apres.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
@jsboige
jsboige merged commit 1185711 into main Sep 15, 2026
47 of 56 checks passed
myia-ai-01 pushed a commit that referenced this pull request Sep 28, 2026
…ost-#16054) (#18246)

The in-place re-execution of #16054 (3685127, 16/09 17:27) postdates
the last figure extraction (#16282, 16/09 01:57): the two README PNGs of
16_Scaling_Test_Time_Compute still described the old run (difficile
0.25/0.40/0.50/0.50, compute-optimal verdict '0.50=0.50 no
discrimination') while the committed notebook now carries difficile
pass@1/2/4/6 = 0.50/0.58/0.67/0.75 and BoN 0.67 vs Reflexion 0.75
('<- Reflexion').

- Re-extract both PNGs via extract_readme_figures (figures-extract path,
  --no-manifest per series convention): pixel drift before = 13082 px /
  10525 px of 330330, after = 0 px (RGBA tobytes sha256 equality).
- MANIFEST: additive #18242 block (drift measurements, cell indices
  resynced 8->11, 11->16, nb17 11->18 measured), figure detail fields
  realigned on the committed run, audit blocks c.479/c.767/#16275 kept
  verbatim.
- README: alt-texts + captions + BoN-vs-Reflexion paragraph rewritten on
  the committed verdict (mirror of notebook cell 15: 'une realisation,
  pas une loi', 4 enonces au bucket decisif, 0.75 borne inferieure).
- nb17 figure measured at 0 px drift: untouched.

Co-authored-by: Claude Sonnet 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.

2 participants