Skip to content

fix(genai,#18574): muscle l'exemple guide 3 de Image/01-1 -- mesurer les pixels au lieu d'y croire, + 2 reparations d'automatisation - #19639

Merged
myia-ai-01 merged 2 commits into
mainfrom
fix/18574-muscle-image01
Oct 7, 2026
Merged

myia-ai-01 merged 2 commits into
mainfrom
fix/18574-muscle-image01

Conversation

@jsboige

@jsboige jsboige commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Grain: MED/notebook-python — lane myia-po-2024:CoursIA — prev: MED/notebook-python #19632

Objet

Seconde passe #18574 (item 6) sur GenAI/Image/01-Foundation/01-1-OpenAI-DALL-E-3.ipynb, exemple guidé 3 (contribution étudiante, PR #18561).

Verdict : À MUSCLER. L'exemple revendique trois axes visuels et n'en mesure aucun, alors que l'instrument correct est enseigné trois cellules plus bas dans le même carnet.

Ce que l'exemple revendique, et ce qui manquait

L'étudiante compare deux révisions de prompt et conclut sur trois axes : palette (« contraste bleu / orange chaud »), éclairage (« lumière naturelle directionnelle »), composition. La preuve fournie est une liste differences — une lecture à l'œil — et un comptage de mots du prompt, que la Lecture du même exemple déclare elle-même sans rapport avec l'image.

L'exercice 4, juste en dessous, enseigne pourtant l'instrument juste : secteurs de teinte, pixels peu saturés masqués. Trois pièges y sont nommés, et ils comptent : l'échelle de teinte de Pillow est 0-255 (pas 0-360°), la moyenne arithmétique de teinte n'a pas de sens (deux rouges à cheval sur le rebouclage rendent du cyan), et un gris à H=0 compterait comme « rouge » sans masque de saturation.

Le geste : purement additif

+39 / -0 sur la cellule 28, +9 / -0 sur la cellule 29. Le code de l'étudiante — prompts, liste differences, bloc de comparaison des longueurs — est conservé intégralement.

git show b8f6e37f1f5:<carnet> prouve que le bloc de comptage de mots n'existe pas dans le commit d'intégration : il vient de la contribution étudiante. L'effacer serait un effacement, pas une musculation.

Mesure ajoutée (profil_couleur) : luminosité moyenne, part de pixels chauds, part de pixels froids — secteurs 0-60 et 200-255 pour le chaud, 100-180 pour le froid, masque S >= 30.

La Lecture est réécrite sur la sortie réelle : la palette est confirmée, l'éclairage est l'axe que l'œil surévalue, et la composition n'est pas mesurée par cet instrument — le dire fait partie de la mesure.

Deux défauts d'automatisation exposés par la ré-exécution

Ils préexistent sur main ; c'est l'exécution honnête qui les rend visibles.

1. Import périmé (cellule 4). La cellule importe save_generated_image, qui n'existe pas dans shared/helpers/genai_helpers.py — son __all__ porte save_generation_result. Un except ImportError masquait l'import, et le nom n'apparaît qu'à cette ligne dans tout le dépôt : l'import ne pouvait donc jamais réussir, et le carnet tournait en « mode autonome » depuis toujours. Corrigé vers le nom réel (vérifié hors ligne : l'import réussit, l'ancien nom est bien absent).

2. Contrat d'automatisation non honoré (cellule 23). Le runner canonique scripts/notebook_tools/notebook_tools.py exporte BATCH_MODE dans l'environnement — son commentaire le dit explicitement, « notebooks read os.getenv("BATCH_MODE"), not Papermill -p params ». Le carnet ne le lisait pas : une exécution automatisée entrait donc dans le bloc interactif, imprimait une invitation à saisir un prompt, puis la rétractait par un message d'indisponibilité. Corrigé en lisant la variable, comme le font les carnets frères de la série.

Les deux sont des réparations, pas des contournements (règle F) : la cause est corrigée, et le carnet est ré-exécuté. Un utilisateur sous Jupyter n'a pas la variable BATCH_MODE : l'interactif reste ouvert pour lui.

Résidu mesuré sur le ratchet output-failure

La ré-exécution fait passer TOOL_FAILURE de 0 à 1 : la cellule 23 imprime encore sa branche de repli. Cette occurrence est un faux positif de l'organe, et il est mesuré, pas supposé :

  • scan(base) classe les cellules 4 et 23 en DECLARED_FALLBACK (l'organe reconnaît donc lui-même un repli déclaré) ;
  • scan(head, base_nb=base) les reclasse en TOOL_FAILURE, uniquement parce que la condition de base de l'exemption juge la cellule de base « substantielle » ;
  • or les sorties base et tête sont identiques terme à terme à ces deux cellules, à l'horodate près.

Ce que _substantial_output lit comme « sortie substantielle » dans la cellule de base, ce sont les impressions d'information voisines de la bannière (titre, date, mode) — pas un rendu que la bannière aurait remplacé. La cible de la condition de base (#3473 / #11685) est « un rendu remplacé par une bannière » ; ce n'est pas ce qui se passe ici.

Le défaut est d'organe, pas de carnet, et il est latent sur toute la série Image : quatre carnets basculent au rouge à la simple ré-exécution, sans changer une ligne — 01-2, 01-5b, 02-5, 03-3. Tracé dans #19638, avec la mesure reproductible.

Gates locales

Garde Résultat
check_output_failure_text.py origin/main 0 regressed, RC=0
check_c2_compliance.py --path <carnet> 1/1 notebooks compliant — All clear!
Exécution Papermill (kernel python3) 16/16 cellules, 0 erreur, sorties committées
Drift kernel language_info.version 3.13.3 → 3.13.7, même majeure.mineure, kernelspec python3 inchangé

Vérifié hors ligne avant le run payant : l'import du helper, et la discrimination de la mesure — une image chaude rend une part chaude élevée, une image froide l'inverse, et un gris neutre est bien neutralisé par le masque de saturation. Sans ce témoin, un chiffre qui ne sépare rien passerait pour une mesure.

See #18574 — l'item 6 de la seconde passe couvre plusieurs carnets ; celui-ci n'en est qu'un volet.

🤖 Generated with Claude Code

jsboige and others added 2 commits October 7, 2026 03:07
…rer au lieu de croire

L'exemple guide 3 concluait ses deux axes les plus visibles -- eclairage et
palette -- par une lecture A L'OEIL (la liste `differences` du groupe), et son
bloc `Comparaison des revisions` imprimait un COMPTAGE DE MOTS du prompt, que la
Lecture du meme exemple declare elle-meme ne rien mesurer. Or l'exercice 4, juste
en dessous, enseigne l'instrument correct (secteurs de teinte, saturation
masquee) : l'exemple demontrait donc le contraire de ce que l'exercice prescrit.

Ajout d'une mesure sur les pixels des deux axes revendiques. Le bloc de comptage
de l'etudiante est CONSERVE -- son commit 86d6f04 l'a introduit, le retirer
serait un effacement de contenu etudiant ; la mesure vient a cote, et la Lecture
la lit.

Resultat mesure (run reel, 37/37 cellules, 0 erreur) :
- palette   : pixels chauds 18,3% -> 48,6% (+30,3 pts) -- l'axe est CONFIRME et chiffre
- eclairage : luminosite 175,2 -> 180,0 (+4,8 sur 255) -- l'axe que l'oeil surestime,
              porte par la teinte et non par la luminosite
- composition : non mesuree par cet indicateur, et la Lecture le dit

La fonction de mesure est eprouvee HORS LIGNE avant tout appel API (image chaude /
froide / gris) : elle discrimine, et le masque de saturation neutralise bien le gris.

Diff purement additif : +39 lignes, 0 retiree.

See #18574

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…xels, et reparer deux defauts d'automatisation

L'exemple guide 3 (contribution etudiante, PR #18561) revendique trois axes
visuels -- palette, eclairage, composition -- et n'en mesure aucun : sa preuve
est une lecture a l'oeil et un comptage de mots du prompt, que la Lecture du
meme exemple declare elle-meme sans rapport avec l'image. L'exercice 4, trois
cellules plus bas, enseigne pourtant l'instrument correct (secteurs de teinte,
pixels peu satures masques).

Ajout purement additif a la cellule 28 (+39/-0) et a la Lecture (cellule 29).
Le code de l'etudiante -- prompts, liste `differences`, bloc de comparaison des
longueurs -- est conserve integralement : `git show b8f6e37` prouve que son
bloc de comptage de mots n'existe pas dans le commit d'integration, il vient de
la contribution. L'effacer serait un effacement.

La re-execution honnete a expose deux defauts d'automatisation pre-existants :

- cellule 4 : le carnet importe `save_generated_image`, qui n'existe pas dans
  `shared/helpers/genai_helpers.py` (le nom reel est `save_generation_result`).
  Le nom perime n'apparait qu'a cette ligne dans tout le depot, et un
  `except ImportError` masquait l'echec : l'import ne pouvait donc jamais
  reussir, et le carnet tournait en mode autonome depuis toujours.
- cellule 23 : le carnet ignorait le contrat `BATCH_MODE` que le runner
  canonique (`scripts/notebook_tools`) exporte dans l'environnement. Une
  execution automatisee entrait donc dans le bloc interactif -- qui n'a pas de
  stdin -- imprimait une invitation a saisir un prompt, puis la retractait par
  un message d'indisponibilite. Le carnet prend desormais sa branche batch,
  comme ses carnets freres de la serie. Un utilisateur sous Jupyter n'a pas
  cette variable : l'interactif reste ouvert pour lui.

Re-execution : 16/16 cellules, 0 erreur, outputs commites (C.2).
Ratchet output-failure : 0 regressed.
Verifie hors ligne avant le run payant : import du helper, et discrimination de
la mesure (une image chaude rend une part chaude elevee, et le masque de
saturation neutralise un gris).

See #18574

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

github-actions Bot commented Oct 7, 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 commented Oct 7, 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 7, 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 7, 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 consecutive-code-cells Modified notebook has >=2 consecutive code cells (#12797) label Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 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 7, 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 3.6s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 4.0s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 4.5s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 4.3s
Search-01-StateSpace.ipynb ✅ SUCCESS 3.2s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 2.1s
RL-04-Bandits-Manchots-Python.ipynb ✅ SUCCESS 18.1s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 7.6s
GameTheory-13d-Optimistic-CFR-Python.ipynb ✅ SUCCESS 10.4s

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

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

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

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359/#13615)

Cette PR #19639 (fix(genai,#18574): muscle l'exemple guide 3 de Image/01-1 -- mesurer les pixels au lieu d'y croire, + 2 reparations d'automatisation) 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 7, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 19639
head: 79d4932
complete: true
body: read
comments-reviewed: 8
reviews-reviewed: 0
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 6aed19b5865736f677cc8073b89cebdbad10d9a9521e768b8a32390048e94f25
diff-files: 1
diff-additions: 277
diff-deletions: 208
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
organ: check_adjoint_prevalidation.py
organ-command: python scripts/check_adjoint_prevalidation.py --derive-verdict 19639
organ-rc: 0
[/ADJOINT PREFLIGHT]

@myia-ai-01
myia-ai-01 merged commit 29da7da into main Oct 7, 2026
94 of 95 checks passed
@jsboige
jsboige deleted the fix/18574-muscle-image01 branch October 7, 2026 07:55
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)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants