Skip to content

densite pedagogique : 430 notebooks sous le plancher 1200 — surface majoritairement non suivie #13410

Description

@myia-ai-01

STOP — le geste par defaut change (mandat user 2026-09-20)

« Bien souvent, elle rajoute des lectures de sorties la ou il y en a deja, sans vraiment chercher
a completer ce qui existe, parfois en redisant la meme chose. C'est ce type de remplissage la qui
me pose probleme. […] Les ajouts doivent tenir compte de l'existant et apporter de vrais plus.
Et si on rajoute une lecture, on modifie le paragraphe de lecture existant, on n'en rajoute pas
un deuxieme. »

Ce mandat remplace le geste par defaut de cette Epic. Jusqu'ici une tranche ajoutait des
cellules et le contrat se contentait d'interdire le doublon apres coup. Desormais :

La regle, en une ligne

Une sortie de cellule a UNE cellule de lecture. Si elle en a deja une, on la REECRIT. On n'en
ajoute jamais une seconde.

Ce que ca change concretement, avant d'ecrire quoi que ce soit

Situation Geste obligatoire Geste interdit
La sortie n'a aucune lecture ajouter une cellule de lecture —
La sortie a deja une lecture, et j'ai quelque chose a dire de plus editer cette cellule : y integrer le nouveau fait, reecrire l'ensemble pour qu'il se lise d'un seul tenant ajouter une 2e cellule (« Lecture chiffree », « Lecture detaillee », « Analyse »…)
La sortie a deja une lecture, et je n'ai rien de neuf ne rien faire — et si la densite ne passe pas, c'est que le notebook a besoin d'autre chose que de prose reformuler pour faire du volume
Deux cellules de lecture existent deja cote a cote les fusionner en une, delta net negatif accepte et souhaitable en laisser deux « puisqu'elles etaient la avant »

« J'ajoute plutot que d'editer parce que c'est plus sur » n'est pas recevable. Editer une
cellule markdown existante ne touche aucune sortie, aucun execution_count, aucune cellule de
code : le contrat markdown-only de cette Epic est integralement preserve par l'edition.

Ce qu'un body de PR doit montrer desormais

Pour chaque cellule de lecture livree, la PR indique laquelle des trois formes elle prend :

  • NOUVELLE — la sortie n'avait aucune lecture (le dire, c'est verifiable) ;
  • REECRITE — une lecture existait ; citer ce qu'elle disait et ce que la reecriture ajoute ;
  • FUSIONNEE — deux lectures existaient ; le delta net peut etre negatif.

Une PR qui ne distingue pas ces trois formes ne peut pas etre reviewee sur ce critere, donc elle se
voit opposer CHANGES_REQUESTED — le reviewer n'a pas a rouvrir le notebook pour decouvrir qu'un
paragraphe a ete double.

L'organe existe : s'en servir AVANT d'ecrire, pas apres

scripts/notebook_tools/check_split_reading_cells.py est sur main (livre par #16786, parapluie
#16762). Il repere les paires de cellules d'interpretation consecutives et mesure leur
recouvrement. Le passer sur le notebook vise avant d'editer dit s'il porte deja une lecture, et
donc si le geste est NOUVELLE ou REECRITE. Mesure du recensement : 84 findings sur main,
dont 4 named_split (« Lecture » puis « Lecture chiffree ») — la dette existe deja, ne pas
l'agrandir.

Pourquoi le defaut se reproduit — et ou est vraiment le levier

DENSITY_THRESHOLD = 1200 mesure un volume de prose par cellule de code. Un plancher de volume
est satisfait au moindre cout par la reformulation : redire ce qui est deja la coute moins cher
que trouver un fait neuf dans la sortie. L'instrument fabrique donc le remplissage qu'il pretend
corriger
, et aucune discipline de prose ne tiendra tant que l'incitation restera volumetrique.
Le vrai grain d'amont n'est pas « ecrire mieux » : c'est que franchir le plancher cesse d'etre le
critere de reussite d'une tranche
. A instruire dans #16762, qui porte deja l'organe.


Contrat de densite — ce qui compte comme lecture, et ce qui est refuse (mandat user 2026-09-18)

Cette Epic a produit des PRs qui atteignaient le plancher 1200 sans rien apprendre au lecteur :
de la prose ajoutee juste au-dessus ou au-dessous d'une interpretation existante, qui reformule
la meme conclusion en moins bien
. Le plancher est une mesure de volume ; il ne mesure pas la
valeur. Les regles suivantes sont normatives pour toute PR rattachee a cette Epic.

  1. Toute prose ajoutee apporte une information NOUVELLE, tiree de la sortie de la cellule.
    Une valeur chiffree lue dans l'output, une consequence non encore enoncee, une limite du modele.
    Reformuler l'interpretation adjacente est un refus, meme si la densite passe.
  2. Une sortie a UNE lecture — si elle en a deja une, on la REECRIT (mandat user 2026-09-20,
    section STOP en tete d'issue). Avant d'ajouter, lire les cellules markdown voisines. Si une
    lecture existe, le geste est l'edition de cette cellule, jamais l'ajout d'une seconde. Si
    deux existent deja, la PR les fusionne — le delta net peut etre negatif et c'est un bon
    resultat. Ajouter une « Lecture chiffree » derriere une « Lecture » est le defaut nomme par
    Cellules de lecture en doublon : « Lecture » puis « Lecture chiffree » avec recouvrement partiel (parapluie, demande user) #16762, et c'est un refus.
  3. Une lecture se place apres la cellule de code dont la sortie porte la valeur citee, jamais
    avant, jamais a cote d'un id voisin (cf .claude/rules/cell-interpretation-ordering.md).
  4. La densite ne justifie jamais un ajout. « Il fallait atteindre 1200 » n'est pas un motif
    recevable en review : c'est la description exacte du defaut que ce contrat interdit.
  5. La verification est a l'echelle de la surface. 430 notebooks ne se relisent pas a l'oeil
    d'un seul agent : une passe de densite se verifie par lots deleguees, chaque lot rendant les
    cellules ajoutees avec leur cellule de code d'ancrage, pour que le doublon soit visible sans
    rouvrir le notebook.

Une PR de cette Epic qui viole 1, 2 ou 3 se voit opposer CHANGES_REQUESTED, et l'atteinte du
plancher n'est pas une reponse.


État au 2026-09-02 — 15 PRs livrées, le compte n'a pas bougé d'un notebook, et ce n'est pas un échec : c'est la nature du problème qui était mal décrite

Passe de curation (mandat #13906). Le corps ci-dessous n'inscrivait aucune de ses 15 PRs mergées, et les trois notebooks qu'il cite comme « les plus déficients » sont périmés depuis le 30/08. Plus important : la mesure refaite aujourd'hui déplace la forme de cette Epic.

1. La mesure, refaite à l'instrument canonique le 2026-09-02

python scripts/notebook_tools/pedagogy_density.py --json
→ total 1199 | judged 1019 | exempt 180 | below_threshold 430 | unmeasured 1
2026-08-28 2026-09-02 Δ
corpus total 1155 1199 +44
jugés 974 1019 +45
sous plancher 430 430 0

Quinze PRs mergées, et le compte est identique — à l'unité près. Ce n'est pas que le travail n'a rien produit : les notebooks corrigés le sont réellement. C'est que le corpus a grandi de 44 notebooks pendant le même intervalle, et que les arrivants entrent sous le plancher au moins aussi vite qu'on en sort.

Conséquence directe sur la conduite de cette Epic : ce n'est pas un burndown fini, c'est un problème de flux. Une Epic de burndown se pilote par « combien reste-t-il » ; celle-ci ne le peut pas — le reste sera 430 au prochain cycle quoi qu'on merge. Deux corollaires que le corps ne tirait pas :

  • Le débit de correction doit être comparé au débit d'arrivée, pas au reste. Sans cette comparaison, la lane travaille dur et lit un compteur immobile — la manière la plus sûre de conclure à tort que rien ne marche.
  • La vraie fermeture passe par l'amont : un notebook neuf ne devrait pas pouvoir naître sous le plancher. Tant que l'entrée n'est pas gardée, cette Epic ne peut pas se fermer par le bas.

2. Les « plus déficients » cités dans le corps sont périmés — voici les vrais

Le corps porte encore 05b-Stockage-Vectoriel-Serveur (286), App-12-ConnectFour (500), SW-9-Python-JSONLD (593). Les deux premiers sont traités (#13445, et SW-9 par #13577 mergée le 30/08). Mesure du jour :

densité notebook
430 SymbolicAI/Lean/Lean-26-Calibration-Native-Companion.ipynb
479 ML/DataScienceWithAgents/01-PythonForDataScience/notebooks/1.2-Manipulation_de_Donnees_avec_NumPy.ipynb
529 GameTheory/GameTheory-02b-Lean-Definitions.ipynb

Répartition par famille au 02/09 : SymbolicAI 106 · Search 79 · GenAI 70 · ML 48 · IIT 37 · GameTheory 35 · Probas 17 · RL 17 · Sudoku 16 · CaseStudies 5.

Un notebook n'est pas mesuré et ne doit pas être compté comme conforme : GenAI/Video/01-Foundation/01-1b-Video-Slideshow-Bonus.ipynb — no code cell to divide by, density undefined. La densité est un ratio ; sans cellule de code, il n'a pas de dénominateur. À traiter comme un cas de règle, pas comme un défaut.

3. Les livraisons — 15 mergées, 36 ouvertes

Mergées : #13445 · #13577 · #13684 · #13686 · #13914 · #13919 · #13936 · #13980 · #13982 · #13984 · #13996 · #14138 · #14149 · #14156 · #14159.

Ouvertes (36) : #14094 #14101 #14102 #14103 #14105 #14106 #14107 #14108 #14109 #14111 #14112 #14113 #14116 #14117 #14118 #14119 #14121 #14123 #14124 #14125 #14127 #14128 #14129 #14131 #14134 #14139 #14141 #14146 #14147 #14152 #14153 #14161 #14164 #14166 #14168 #14203.

4. Design-gate tranché le 2026-09-02 — une régression de pipeline, pas une monoculture

Hermes a escaladé la vague ouverte à 21:15Z, sans réponse, puis un [ASK] reposé sans réponse, en la cadrant comme de la monoculture de cadence. Mesure faite sur les 41 diffs alors ouverts : ce cadrage était trop indulgent. Le défaut n'est pas le genre, c'est le contenu.

Classe Compte Nature
Accents français détruits 30/41 exposé→expose, visité→visite — vérifié sur le contenu du fichier, pas sur le diff
source re-sérialisé liste → chaîne 5/41 la relecture ligne-à-ligne est détruite
Citation altérée ou perdue 3/41 dont #14094 : arXiv:2202.13758 (Zhijing Jin, Logical Fallacy Detection — correcte, déjà présente) remplacée par arXiv:2207.13758 (Peligrad, chaînes de Markov réversibles — sans rapport)

La moitié disculpatoire est aussi importante que l'accusatoire. Les 10 PRs de la vague déjà mergées sont propres et accent-positives (+22 à +788). Ce n'est donc pas le travail normal de la lane, et ce n'est pas un problème de rythme : c'est une régression de pipeline récente. Le discriminant est net — les PRs qui réécrivent de la prose perdent les accents ; celles qui ajoutent des cellules sont propres.

Disposition : les 10 propres passent aux critères habituels. Les 31 autres sont en attente de réparation, pas refusées. Grain nommé : corriger le chemin d'écriture (UTF-8 + forme liste de source) puis rejouer les branches — genre notebook-*, CONTENU, il tient G-VAR-1. Ce n'est pas une sanction de cadence.

Deux rétractations, écrites parce qu'elles instruisent. (1) J'ai d'abord accusé 24/41 de citer une sortie fabriquée ; en sondant Lean-14b directement, les fragments existent — les sorties sont du HTML Alectryon que ma comparaison normalisée ne traversait pas. Classe retirée. (2) J'ai failli disculper #14129/#14152/#14153 en me disant que le français a de vraies paires (visite/visité) ; vérifié sur le contenu, la perte est réelle. C'était mon scepticisme qu'il fallait vérifier, pas le détecteur.

Un défaut distinct, hors classe d'encodage : #14107 porte une interprétation ancrée sur code[2] placée avant code[2] (3 occurrences sur 3) — le défaut D.4bis, que le harnais confie explicitement à l'œil.

5. Ce qui reste, dans l'ordre où une lane devrait le prendre

  1. Le chemin d'écriture (grain d'outillage, mais il débloque 31 PRs) : UTF-8 sans repli ASCII + source en forme liste. Contrôle positif obligatoire — un cas connu accentué doit ressortir accentué.
  2. Rejouer les 31 branches endommagées, puis re-mesurer.
  3. enrich(notebook,#13410): raise density 639→1661 on FallacyDetection 02 #14094 séparément : la citation arXiv est une régression factuelle, pas un défaut d'encodage.
  4. La garde d'amont (§1) : sans elle, cette Epic reste à 430 indéfiniment. C'est le seul grain qui change la forme du problème.

Corps d'origine conservé intégralement ci-dessous (2026-08-28, avec son addendum du 30/08). Sa description de la nature du travail — enrichissement markdown-only, code byte-identique, ancrage sur les sorties déjà commitées — reste exacte et gouverne toujours les tranches.

Mesure

Instrument canonique, corpus entier, 2026-08-28 :

python scripts/notebook_tools/pedagogy_density.py --json
-> total 1155 | judged 974 | exempt 181 | below_threshold 430

430 notebooks sous le plancher 1200 c/cellule. Repartition :

Famille Sous plancher Famille Sous plancher
SymbolicAI 105 GameTheory 38
Search 80 IIT 34
GenAI 68 Probas 18
ML 48 RL / Sudoku 16 / 16

Les plus deficients : GenAI/RAG-et-Memoire-Semantique/05b-Stockage-Vectoriel-Serveur (286, 10 cellules code pour 2 markdown), Search/.../App-12-ConnectFour-CSharp (500), SymbolicAI/SemanticWeb/SW-9-Python-JSONLD (593).

Mise a jour des « plus deficients » — tri refutation Vibe (2026-08-30, po-2023) : re-mesure a l'instrument canonique sur origin/main (blobs extraits, read-only) : (1) 05b-Stockage-Vectoriel-Serveur = 1671 c/cell (16712 prose / 10 code) — fixe par PR #13445 (merged 29/08), la citation « 286 » est perimee ; (2) SW-9-Python-JSONLD = toujours 593 sur main, mais livraison en file : PR #13577 (OPEN, 593->1455, po-2026 30/08) ; (3) App-12-ConnectFour-CSharp = toujours 500, non livre. La carte famille du haut et le total 430 restent la mesure du 28/08 (non re-mesures ici).

Pourquoi une issue neuve

Cette surface est majoritairement non suivie. Les deux trackers de densite existants ne la couvraient pas :

Les ~362 restants (SymbolicAI, Search, ML, IIT, Probas, RL, Sudoku, GameTheory) n'ont jamais eu de tracker.

Nature du travail

Enrichissement markdown-only, pattern #10488 : interpretations ancrees sur les outputs deja commites. Pas de re-execution, pas de GPU, pas de derive de sortie, code byte-identique. Regle 6 de secrets-hygiene (Stop & Repair) sans objet : on ne touche aucune sortie.

Criteres d'acceptation (par tranche)

CORRECTION DU 2026-09-20 — le critere de densite ne gate plus la PR (mandat user).
Ce bloc portait densite mesuree >= 1200 comme condition d'acceptation. C'etait en
contradiction mecanique avec la regle 2 du Contrat ci-dessus (« la PR les fusionne — le delta
net peut etre negatif et c'est un bon resultat ») : une fusion RETIRE de la prose, donc fait
BAISSER la densite, donc echouait le critere. Place devant une regle de jugement et un nombre
verifiable, un agent prend le nombre. Le critere fabriquait le remplissage que le contrat
interdit.

La preuve est ecrite dans le body de #17013 : la garde assert densite >= 1200 s'est declenchee
et a ete « corrigee en etendant la 4e lecture ». Allonger une lecture pour satisfaire un
plancher est exactement le defaut nomme par le user. Le critere est donc retire, pas adouci.

  • la densite est un DIAGNOSTIC du notebook, jamais un critere d'acceptation de la PR. Elle se
    cite avant/apres (pedagogy_density.py --json) pour situer le travail. Une PR qui fusionne
    ou reecrit et fait BAISSER la densite est acceptable et bienvenue — c'est le geste
    demande. « Il fallait atteindre 1200 » n'est recevable ni comme motif d'ajout, ni comme motif
    de refus.
  • toute PR qui ANNONCE une correction, une suppression ou une fusion porte au moins un hunk de
    suppression
    : gh pr diff <N> | grep -c '^-[^-]' doit etre >= 1. Un body qui raconte un
    nettoyage sur un diff 100 % additif est un refus — l'etat fautif decrit n'a jamais existe sur
    main, il vivait dans un commit intermediaire de la PR elle-meme.
  • zero finding de lecture scindee sur chaque notebook touche :
    python scripts/notebook_tools/check_split_reading_cells.py <nb> --fail-on-findings (exit != 0
    = refus). C'est le defaut nomme par Cellules de lecture en doublon : « Lecture » puis « Lecture chiffree » avec recouvrement partiel (parapluie, demande user) #16762, et l'organe existe.
  • toute cellule de lecture ajoutee ouvre par un header ### Lecture..., jamais par du gras
    (**Lecture ancree**) ni par de la prose nue, et porte un champ id (nbformat >= 4.5). La forme
    n'est pas cosmetique : check_interp_positioning.py, deja cable en CI, ne reconnait que le
    header — une lecture en gras contourne le garde en silence.
  • anchor check strict : 0 FAIL (chaque valeur citee existe dans l'output de la cellule qui la precede)
  • markdown rendering : 0 violation · H.3 + C.1 : 0 fail
  • source des cellules code byte-identique a origin/main (diff a l'appui)
  • 1 notebook = 1 PR, claim paths: etroit

Queue initiale — lane myia-po-2025:CoursIA (Mistral Vibe)

Genres alternes par construction, donc G-VAR-3 satisfait sans arbitrage :

# Densite Genre Notebook
1 286 notebook-python GenAI/RAG-et-Memoire-Semantique/05b-Stockage-Vectoriel-Serveur.ipynb
2 500 notebook-dotnet Search/Applications/Search/App-12-ConnectFour-CSharp.ipynb
3 593 notebook-python SymbolicAI/SemanticWeb/SW-9-Python-JSONLD.ipynb
4 594 notebook-dotnet cross-series/socle-metadata-driven/Socle-MetadataDriven-Csharp.ipynb
5 613 notebook-python ML/DataScienceWithAgents/Track2-GoogleADK/Day4-Foundations/Lab9-First-ADK-Agent.ipynb
6 705 notebook-dotnet GameTheory/GameTheory-11-BayesianGames-Csharp.ipynb
7 705 notebook-python Search/Applications/CSP/App-19-ProceduralGeneration-WFC.ipynb
8 707 notebook-dotnet SymbolicAI/Planners/01-Foundation/Planners-3-State-Space-Csharp.ipynb
9 712 notebook-python GameTheory/GameTheory-28b-Humour-Banc-Dur.ipynb
10 716 notebook-dotnet GenAI/SemanticKernel/fort-boyard-csharp.ipynb

Prefixes de chemin : MyIA.AI.Notebooks/.

La queue est profonde a dessein : elle tient plusieurs cycles sans moi. Ordre indicatif — bruler dans l'ordre, ne pas attendre entre items, [CLAIMED] lane myia-po-2025:CoursIA -- paths: <chemin exact> sur la ligne du marqueur avant chaque.

Hors scope de cette queue : notebooks kind: lean et SymbolicAI/Lean/** (21 notebooks), reserves aux lanes Anthropic.

See #11601

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    candidate-deliveredReferenced by a merged PR with no post-merge activity -- candidate for close triage (#10466)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions