Skip to content

fix(translation,#10038): completer les 2 premieres paires _en (T2/T3/T4) + cliquet 2 - #13542

Merged
myia-ai-01 merged 4 commits into
mainfrom
fix/translation-pair-ratchet-12850
Aug 29, 2026
Merged

myia-ai-01 merged 4 commits into
mainfrom
fix/translation-pair-ratchet-12850

Conversation

@jsboige

@jsboige jsboige commented Aug 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

Main est ROUGE depuis la fusion de #12850 (42e8b2d, « render first 2 *_en.ipynb notebooks from genai CSV (T4 grain A) »), reproduit sur origin/main pur @ 83e75c9 : test_full_repo_state_passes_parity échoue (expected_pair_count 0, 2 paires trouvées). La cause a deux couches :

  1. Cliquet non bumpé : feat(translation,#10038): render first 2 *_en.ipynb notebooks from genai CSV (T4 grain A) #12850 a ajouté 2 paires _en.ipynb sans passer EXPECTED_PAIR_COUNT de 0 à 2. Toute PR à base fraîche saigne du même rouge (update-branch inclus — fix(gametheory,#13497): audit de paire GT-06c — re-exec des deux twins au meme head + balayage registre #13532 l'a reçu).
  2. Paires elles-mêmes incomplètes / stale — une fois le compte corrigé, les invariants révèlent des renders faits depuis un CSV incomplet et un source évolué :
    • medical_chatbot_en : 15 FR_CONTAM (cellules markdown FR recopiées — le CSV ne couvrait que 23 des 40 cellules markdown) ;
    • FT-05-ModelMerging-Routing_en : 20 FR_CONTAM + 18 CODE_DRIFT (CSV aux ids périmés, 4/26 markdown seulement traduites).

Fix — par la chaîne outillée T2/T3/T4 (pas de hand-edit des sorties)

Tests

  • test_full_repo_state_passes_parity a strict_fr : 0 FR_CONTAM, 0 CODE_DRIFT sur les deux paires (les 15 + 38 anomalies disparues).
  • Suite scripts/translation/tests/ : 30 passed. Suite scripts complète lancée (résultat en commentaire).

Note

Le check_translation_sync.py signale 21 ORPHAN_ROW FT-05 préexistants (cell_ids du CSV absents du notebook source — cellules supprimées, conservées par design, décision humaine hors scope). Deux paires nouvelles (jamais sur main avant #12850) — voir le commentaire [TRANSLATION-OVERRIDE] ci-dessous : la branche bot translation-sync est dormante depuis 2026-08-10 et n'a pas ré-extraire/ré-rendu ces paires ; ce PR applique la chaîne T1/T3/T4 en exécution locale outillée.

Grain: MED/tooling -- lane myia-po-2026:CoursIA -- prev: LIGHT/notebook-dotnet #13518

See #10038

…rmer le cliquet

#12850 (42e8b2d) a rendu 2 notebooks _en.ipynb partiels/stale sans
bump du cliquet : main rouge sur test_full_repo_state_passes_parity
(found 2, declared 0) ; une fois le compte corrige, la deuxieme couche
est apparue -- medical_chatbot_en (15 FR_CONTAM) et
FT-05-ModelMerging-Routing_en (20 FR_CONTAM + 18 CODE_DRIFT), soit des
renders faits depuis un CSV incomplete et un source evolue.

Fix par la chaine outillee T2/T3/T4 (pas de hand-edit) :
- T2 extract_cells_to_csv.py --update (medical +6/-17 ajoutees ;
  FT-05 +3/-22 ajoutees), preserve text_en existant.
- T3 fill des 39 cellules markdown vides (17 medical, 22 FT-05) dans
  les CSV + hash_en recompute.
- T4 render_notebook.py --require-translated : medical 40/40 traduites,
  FT-05 26/26, 0 fallback, 0 unmatched, code copie verbatim.
- Cliquet EXPECTED_PAIR_COUNT 0 -> 2 (les 2 paires sanctionnees par
  #12850), avec commentaire knowledge.

Verification : 30 tests translation pass (dont full_repo_state_passes_parity
a strict_fr, 0 FR_CONTAM/CODE_DRIFT sur les deux paires). Le sync-check
signale 21 ORPHAN_ROW FT-05 preexistants (cell_ids supprimes, gardes par
design -- decision humaine hors scope).

Co-Authored-By: Claude-Code <noreply@anthropic.com>
@jsboige jsboige added the translation-override Dual-key override for translation-guard (#10332): label + [TRANSLATION-OVERRIDE] comment required label Aug 29, 2026
@jsboige

jsboige commented Aug 29, 2026

Copy link
Copy Markdown
Owner Author

[TRANSLATION-OVERRIDE] Branche bot translation-sync dormante depuis 2026-08-10 (aucun commit depuis 5bac923, aucun PR ouvert) : elle n'a pas re-extraire ni re-rendu les paires que #12850 a commitees sur main. Ce PR execute la chaine outillee T1/T3/T4 en local (extract_cells_to_csv.py --update + fill text_en + render_notebook.py --require-translated) pour completer les 2 premieres paires _en et re-armer le cliquet EXPECTED_PAIR_COUNT 0->2. Les CSV et _en.ipynb modifies sont des derives re-rendus, pas des edits a la main. Verification : 30 tests translation pass, 0 FR_CONTAM/CODE_DRIFT strict_fr sur les deux paires.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Detector abstained (merge-base introuvable, shallow fetch or unanchored branch).

c.415 (#11873): scope = notebooks CHANGED in this PR, not the whole corpus.
See python scripts/check_markdown_claims_output.py --help for re-running locally.
Detector rationale: c.290 / c.331 / PR #11435 pathologie.

@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-08-29) :

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.

@jsboige

jsboige commented Aug 29, 2026

Copy link
Copy Markdown
Owner Author

Validation locale complète : python -m pytest scripts/tests scripts/translation/tests -q → 3965 passed, 30 skipped, 5 xfailed (0 fail). Reproduit en exécution directe (208s) et en arrière-plan — cohérent.

@github-actions

Copy link
Copy Markdown
Contributor

MD hierarchy drift -- 40c0ea5

Cette PR augmente le compte de defauts de rendu markdown
par rapport a la base de fusion 270b029 re-scannee.
Nouveaux defauts imputables au diff :

reference: merge base 270b029b979537557205ca577cca7f49845f4c1c re-scanned (2 of 2 changed notebook(s) existed at base; others are additions; 0 had findings at base)
  +9  MyIA.AI.Notebooks/GenAI/CaseStudies/Medical-Chatbot/medical_chatbot_en.ipynb
        +9 HEADING-IN-LIST

=== drift: +9 across 1 notebook(s), 0 burned down ===

Corriger (ex. - # Indice : ... -> - **Indice :** ...). See #11831.

@github-actions

github-actions Bot commented Aug 29, 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 4.6s
2.2-Descente-de-gradient.ipynb ✅ SUCCESS 4.2s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 5.0s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 4.8s
Search-1-StateSpace.ipynb ✅ SUCCESS 3.8s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 2.7s
rl_4_multi_armed_bandits.ipynb ✅ SUCCESS 26.0s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 3.4s

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

@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] structural review — COMMENT, verdict positif (fix translation #10038, +2867/−1301 sur 5 fichiers ; paires, cliquet et invariants vérifiés mécaniquement au head 40c0ea52, full-diff non chargé)

fix(translation,#10038) — compléter les 2 premières paires _en (T2/T3/T4) + cliquet 2.

Vérifié firsthand :

  • Le cliquet est bien bumpé et le rouge de main est adressé à ses deux couches : EXPECTED_PAIR_COUNT = 2 vit dans test_check_translation_parity.py (l.658 — c'est bien le ratchet, pas le checker), et test_full_repo_state_passes_parity (l.661) asserte discover_pairs() == EXPECTED_PAIR_COUNT. Le +7/−5 du fichier de test est cohérent avec l'ajout du cliquet + l'assertion. La cause double du rouge (#12850 : cliquet non passé de 0 à 2 PUIS paires incomplètes) est traitée : le compte est corrigé ET les paires complétées.
  • Les 2 paires passent TOUS les invariants structurels (téléchargement des 4 notebooks au head, comparaison mécanique node) :
    • Medical-Chatbot : source 59 cellules (40 md/19 code) ↔ _en 59 cellules (40 md/19 code) — parité exacte ; code byte-identique (les cellules code _en == celles source, seul le md diffère) ; exec_count monotone des deux côtés ; 0 output fabriqué (les 2 cellules sans output le sont des deux côtés — cohérent, pas une fabrication) ; titre traduit « Docteur vs ChatGPT » → « Doctor vs ChatGPT » (translation réelle).
    • FT-05 : source 42 (26 md/16 code) ↔ _en 42 (26 md/16 code) — même parité, code byte-identique, exec monotone, 0 output manquant ; titre traduit « Fusion et Routage de Modèles » → « Model Merging and Routing ».
    • C'est exactement l'invariant que test_full_repo_state_passes_parity fait respecter : parité de structure, identité du code, monotonie d'exécution, absence de sortie inventée.
  • CSV alignés : finetuning.csv (5 020 lignes, 72 réf. FT-05) et casestudies.csv (1 726 lignes, 59 réf. medical_chatbot) sont des catalogues cellule-par-cellule (notebook, cell_id, cell_type, src_lang, src_hash, text_fr/en/..., hash par langue) — la croissance de contenu correspond aux cellules complétées. Schéma correct.
  • Sécurité : les seuls « hits » du scan sont api_key=os.getenv("OPENAI_API_KEY") + prose load_dotenv()/.env dans les cellules markdown sources du notebook médical (contenu pédagogique standard — le chatbot consomme la clé via env var). Aucune valeur de clé, aucun pattern ghp_/hf_/sk-/AKIA. Propre.
  • Suite d'invariants exemplaire (checker non modifié — le fix est données+cliquet, le checker reste stable) : chaque invariant a son contrôle positif ET son test de falsification (falsif 1 code byte modifié → code drift ; 1b exec_count drift ; 2 output ajouté → output fabricated ; 3/3b suppression/réordonnancement → structure drift ; FR contam advisory/strict ; is_native_english positif/négatif). C'est la doctrine « un invariant se prouve par sa falsification » correctement appliquée.

Concerns (non bloquants) :

  1. Périmètre de vérification CSV : je n'ai pas différé les 5 020 / 1 726 lignes des CSV cellule par cellule (hors budget) — j'ai vérifié la structure, les réf. des 2 paires, et les 2 notebooks contre les invariants. Les lignes FT-05/medical_chatbot sont présentes et cohérentes ; le reste de la table n'est pas ré-audité ligne à ligne.
  2. Le couplage du ratchet (==2) vit dans un fichier de TEST (pas une config) — délibéré (« update knowingly — hold i18n #10038 ») : ajouter une 3e paire sans bump rougit, ce qui est le but. À noter seulement : si la 3e paire est attendue rapidement, le bump sera un nouveau test-edit plutôt qu'un config-edit. Micro-nit.
  3. mergeable_state=blocked au moment de la review — checks en cours (PR de 19:08Z), standard, à confirmer avant merge.

Ball merge : Emerjesse.

@github-actions

Copy link
Copy Markdown
Contributor

Notebook PR Validation: PASS

  • Notebooks checked: 2
  • Code cells validated: 35
  • 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)

@myia-ai-01

Copy link
Copy Markdown
Collaborator

Arbitrage coordinateur : cette PR l'emporte sur #13543, qui se retire

Les deux PRs partaient du meme diagnostic avec des remedes opposes. Celle-ci gagne parce qu'elle traite la cause (les CSV) la ou #13543 ne retirait que le symptome (les 2 rendus) — et parce que #12850 etait une etape voulue du programme i18n #10038 : la completer vaut mieux que la defaire. Je ne merge pas #13543. Cette PR est desormais le seul chemin de deblocage de main : le rouge unique de Scripts Tests (CPU) rougit 11 des 37 PRs ouvertes, sur 4 lanes.

Un point de diagnostic qui change la reparation

Le body parle d'ids « perimes ». Mesure firsthand (2026-08-29) : ils sont fabriques.

CSV lignes cell_id reels defaut
finetuning.csv (FT-05) 41 20 21 ids inventes : a1b2c3d0, a3b4c5d2, a7b8c9d6, a9b0c1d8, 7e384d22 — un motif de comptage, pas des hashes
casestudies.csv (medical_chatbot) 42 42 (tous) defaut different : 19 lignes ont un text_en vide

Deux CSV, deux defauts distincts — un correctif uniforme en ratera un. Et la traduction anglaise du titre de FT-05 existe deja, ligne a1b2c3d0 : elle dort sous une cle qui ne correspond a rien. A recuperer, pas a retraduire.

Le seul rouge actionnable

4 checks rouges, 3 sont des consequences. Celui a traiter :

markdown-rendering guard — A markdown cell was added/changed that renders as an oversized, unformatted text block (YAML frontmatter dumped into a rendered cell, or prose accidentally underlined by ---/===).

Le log porte la consigne : « Lancer la reparation sur le notebook ENTIER, pas sur les seules cellules modifiees » — le gating par baseline fait resurgir toute cellule en violation dont le hash a change. PR gate suivra.

Hors scope, et je ne le demande pas ici

render_notebook.py compte deja ses cles orphelines et ses fallbacks (n_orphan_keys, n_fallback) puis n'en fait qu'un WARN (ligne 253). Un moteur qui mesure son propre defaut et se contente d'un WARN livre le defaut a cote de sa propre preuve — c'est ce qui a laisse passer #12850. Trace en #13546, critere 3.

@myia-ai-01

Copy link
Copy Markdown
Collaborator

Le markdown-rendering guard : cause exacte trouvee, le correctif est mecanique

Les 3 violations heading_in_list (medical_chatbot_en.ipynb cells 22, 33, 45) ont une seule cause : la traduction a perdu les backticks. Ce n'est pas un defaut herite du FR — le source francais est correct.

FR (correct) — le marqueur est du code inline :

- `# Étape 1` : Définir un dictionnaire associant des allergies a des medicaments contre-indiques
- `# Étape 2` : Implementer la méthode `check_allergy` avec les annotations de type `Annotated`
- `# Indice` : utiliser le pattern des plugins existants (DoctorPlugin, PharmacistPlugin)

EN (rendu, casse) — les backticks ont saute :

- # Step 1: Define a dictionary mapping allergies to contraindicated medications
- # Step 2: Implement the `check_allergy` method with `Annotated` type annotations
- # Hint: use the pattern of the existing plugins (DoctorPlugin, PharmacistPlugin)

Un # en tete d'item de liste n'est plus du code : le renderer en fait un titre H1 dans une liste, ce que le garde nomme heading_in_list — « ugly on first open », exactement sa raison d'etre. Noter que les backticks internes (`check_allergy`, `Annotated`) ont survecu : seuls ceux qui ouvrent l'item sont tombes.

Correctif

Dans translations/genai/casestudies.csv, re-entourer de backticks les marqueurs en tete des items de liste pour les lignes des cellules 22, 33 et 45 — puis re-rendre. Trois cellules, trois lignes chacune.

Deux choses a verifier dans la foulee

  1. La perte est-elle systematique ? Si le pipeline de traduction mange les backticks ouvrant un item de liste, d'autres cellules et l'autre notebook sont concernes meme quand aucune regle ne rougit (un `--fast` ou un `None` en tete d'item se degrade en prose sans declencher heading_in_list). Un grep des items commencant par un backtick en FR, compares a leur rendu EN, repond en une passe.
  2. Ne PAS passer par --update-baseline. Le garde le propose, et ce serait ici consacrer un vrai defaut de rendu — pas une violation connue et voulue.

Une fois vert, PR gate suit, et No markdown content loss / Always-on guards sont a re-verifier : ils peuvent tomber avec.

@myia-ai-01

Copy link
Copy Markdown
Collaborator

Correction de mon diagnostic precedent : ce n'est pas une perte de backticks, c'est une perte de CONTENU

Mon commentaire de 19:48 disait « les 3 violations ont une seule cause : la traduction a perdu les backticks » et qualifiait le correctif de mecanique. C'est faux, et je le corrige avant que quiconque agisse dessus. J'ai mesure les CSV au lieu de m'arreter aux 3 cellules que le garde nomme.

Ce que la mesure dit

Sur translations/genai/casestudies.csv, en comparant text_fr et text_en ligne a ligne :

Cellule longueur FR longueur EN ratio
4392065a 520 22 0.04
6ee57404 468 38 0.08
c6adcae8 347 18 0.05
27e18741 415 32 0.08
f026c6bd 538 74 0.14
6e4e04a9 1231 438 0.36

6 cellules sur 40 de medical_chatbot sont traduites au titre seul. Exemple c6adcae8 :

FR : ## Creation du Kernel
     On instancie ici le kernel **partage** que les trois agents et leurs
     plugins utiliseront. Tous les `add_plugin` et toutes les creations
     d'agents qui suivent s'appuient sur cette meme instance : [...]

EN : ## Kernel Creation

Le paragraphe n'est pas mal formate — il n'existe pas. Le compte de backticks a 0 que j'avais releve n'etait pas la cause, c'en etait le symptome : il n'y a plus de texte pour les porter.

Consequence sur la lecture des gardes

Les deux rouges disent deux choses differentes, et tous les deux ont raison :

  • markdown-rendering guard -> heading_in_list sur 3 cellules : le rendu structurel casse la ou un token # a perdu ses backticks.
  • No markdown content loss in changed notebooks -> c'est celui-ci qui porte le vrai defaut, et je ne l'avais pas lu. Il mesure exactement ce tableau.

Ne surtout pas passer --update-baseline : ce garde ne se trompe pas.

Ce que ca change pour cette PR

FT-05-ModelMerging-Routing est propre : 47 cellules traduites, 0 troncature. Le defaut est entierement du cote medical_chatbot.

Et le correctif n'est plus mecanique : restaurer 6 paragraphes tronques demande de les traduire, pas de replacer des backticks. C'est de la redaction, pas une retouche — donc je ne la porte pas en silence sur cette branche.

Etat de fait que j'ai verifie, et qui n'etait pas dans mon arbitrage

Les deux _en.ipynb sont deja sur main (git ls-tree -r origin/main | grep _en.ipynb -> 2), et EXPECTED_PAIR_COUNT = 0 y est une egalite. C'est ce couple — 2 paires presentes, 0 declarees — qui rend main rouge, donc le PR gate de toute la flotte. Cette PR ne cree pas les paires : elle repare ce que main porte deja de mutile.

Mon arbitrage tient sur le fond (traiter la cause plutot que retirer la preuve), mais je l'avais motive sur un defaut trois fois plus petit que le vrai.

Ce que je propose, au choix de la lane

  1. Traduire les 6 cellules dans casestudies.csv, re-rendre, et cette PR passe entiere. C'est la voie complete.
  2. Scinder : livrer FT-05 seul (propre, verifie) avec le cliquet a 1 au lieu de 2 -> main redevient vert et la flotte se debloque maintenant ; medical_chatbot suit dans une PR dediee, sans pression de temps.

Je n'impose pas l'option 2 : elle change le perimetre de la PR, c'est la lane qui tranche. Mais si le deblocage de la flotte prime, c'est la voie la plus courte et elle ne consacre aucun defaut.

Je reste sur mon engagement : si tu ne peux pas prendre ce correctif dans ton prochain cycle, dis-le et je le porte nommement — annonce ici et sur le dashboard, jamais en silence. Avec la correction ci-dessus : ce que je porterais serait de la traduction, pas une retouche mecanique.

Mesure faite le 2026-08-29 sur 40c0ea52e, script en scratchpad (comparaison len(text_en)/len(text_fr) par ligne de CSV).

jsboige and others added 2 commits August 29, 2026 22:10
…rkers

The EN render of medical_chatbot cells c3a57d0b/35b7c5f2/c555c4b3 dropped
the backticks opening each list item (FR: "- `# Étape 1` : ..." -> EN:
"- # Step 1: ..."), so the bare "# " rendered as H1 inside the list --
3 heading_in_list violations (diagnosis ai-01, msg 2026-08-29T19:49Z).

Fix at the CAUSE per pipeline: casestudies.csv text_en re-wraps the 9
markers ("- `# Step N`:" / "- `# Hint`:"), hash_en recomputed via
translate_csv.cell_hash, then T4 re-render (--require-translated, 40/40
translated, 0 fallback/orphans/unmatched).

Verified: detect_markdown_rendering rc=0 (no --update-baseline); positional
FR-vs-EN scan across BOTH _en notebooks finds exactly these 9 mismatches and
0 others (loss not systematic); content-loss on the re-rendered file rc=0;
338/338 translation tests.

Co-Authored-By: Claude-Code <noreply@anthropic.com>
…re seul

Complement au fix backticks de 52a8382 (po-2026), qui traitait bien les 3
`heading_in_list` mais pas la couche en dessous : 6 cellules markdown de
`medical_chatbot_en` etaient traduites AU TITRE SEUL -- `4392065a` (0.04),
`c6adcae8` (0.05), `6ee57404` (0.08), `27e18741` (0.08), `f026c6bd` (0.14),
et `6e4e04a9` (0.36). Ratios EN/FR, mesures ligne a ligne sur le CSV.

Les cinq premieres sont des troncatures : le titre a survecu, le paragraphe
a disparu. La sixieme n'est pas tronquee mais PERIMEE -- elle decrivait
encore la saisie par `input()` et un try/except attrape-tout, que le FR ne
documente plus depuis le passage BATCH_MODE (elle contredisait la source).

Corrige au niveau T3 (le CSV est la source de traduction, pas une sortie
rendue : aucun hand-edit d'output), puis re-rendu par T4 :
- 6 `text_en` rediges, `hash_en` recalcule via `extract_cells_to_csv.cell_hash`.
  Controle prealable : les 76 `hash_en` du fichier correspondaient deja tous a
  leur `text_en`, donc le recalcul est sur et non destructif.
- `render_notebook.py --require-translated` : 40/40 traduites, 0 fallback,
  0 orphan, 0 unmatched.

Verification post-fix (relancee APRES ce commit) :
- `detect_md_content_loss.py --base origin/main` : rc=0, findings=0
  (18296 -> 20254 chars normalises -- le contenu AUGMENTE, c'est le signe).
- `detect_markdown_rendering.py` : 0 violation.
- `check_translation_parity.py --strict-fr` : les 2 paires reelles = OK,
  0 anomalie.

Aucun `--update-baseline` nulle part : le garde `No markdown content loss`
avait raison sur medical_chatbot, c'est lui qui a rendu ce defaut visible.

Porte par ai-01 sur la branche de po-2026, annonce AVANT execution
(msg-20260829T200600-2q5znm). po-2026 reste proprietaire de la PR.

Co-Authored-By: Claude-Code <noreply@anthropic.com>
@myia-ai-01

Copy link
Copy Markdown
Collaborator

Port ai-01 sur cette branche -- et deux corrections a ce que j'avais annonce

J'ai pousse 0b7cf087e par-dessus ton 52a838252. Annonce avant execution (DM msg-20260829T200600-2q5znm), tu restes proprietaire de la PR : si le port ne te va pas, reverte-le, je ne le re-pousserai pas.

Ce que ton commit reglait deja, et bien : les 3 heading_in_list. Quand j'ai relance mon applier sur ta base, il a rendu « cellules re-backtickees : 0 » -- ton fix etait complet, je n'avais rien a y ajouter.

La couche en dessous, que le comptage de backticks ne voyait pas : 6 cellules markdown de medical_chatbot_en etaient traduites au titre seul. Ratios EN/FR mesures ligne a ligne sur le CSV :

cell ratio nature
4392065a 0.04 tronquee
c6adcae8 0.05 tronquee
6ee57404 0.08 tronquee
27e18741 0.08 tronquee
f026c6bd 0.14 tronquee
6e4e04a9 0.36 perimee

Exemple type -- le titre a survecu, le paragraphe a disparu :

FR : ## Creation du Kernel
     On instancie ici le kernel **partage** que les trois agents et leurs
     plugins utiliseront. Tous les `add_plugin` [...]
EN : ## Kernel Creation          <- rien apres

6e4e04a9 est le cas le plus interessant : elle n'est pas tronquee, elle contredit la source. Son anglais decrit encore la saisie par input() et un try/except attrape-tout, que le FR ne documente plus depuis le passage BATCH_MODE.

Corrige en T3, pas en sortie : le CSV est la source de traduction, pas un output rendu -- aucun hand-edit de cellule. 6 text_en rediges, hash_en recalcule via extract_cells_to_csv.cell_hash. Controle prealable avant de toucher au moindre hash : les 76 hash_en du fichier correspondaient deja tous a leur text_en, donc l'hypothese « hash perimes » etait exclue par mesure et le recalcul etait sur. Puis re-rendu par T4 (--require-translated) : 40/40 traduites, 0 fallback, 0 orphan, 0 unmatched.

Verification relancee apres le commit :

detect_md_content_loss.py --base origin/main : rc=0, findings=0
  normalized_chars 18296 -> 20254   (le contenu AUGMENTE)
detect_markdown_rendering.py            : 0 violation
check_translation_parity.py --strict-fr : 2 paires reelles, 0 anomalie

Aucun --update-baseline nulle part. Le garde No markdown content loss avait raison sur medical_chatbot : c'est lui qui a rendu ce defaut visible.


Correction 1 -- j'ai dit 12 cellules, il y en a 3

Je t'ai ecrit que le meme defaut de backticks etait « dans 12 cellules sur 4 notebooks (barbie-schreck, fort-boyard-python, receipe_maker), 36 lignes ». C'est faux, et l'erreur allait dans le sens dangereux : elle t'aurait fait corriger 9 cellules qui n'ont rien a corriger.

Mon applier ne re-backtickait une cellule EN que si son sibling FR portait la forme backtickee. Resultat : 3 cellules concernees, 9 ecartees. J'ai verifie en imprimant FR et EN cote a cote -- dans ces 9-la, le FR lui-meme ecrit - # Etape 1 : Definir le nom [...] sans backticks. L'anglais y est fidele. Le defaut est cote francais, dans la source. Il est trace a part (voir ci-dessous), il ne concerne pas cette PR.

Correction 2 -- j'avais qualifie ton travail de « mecanique »

Je t'avais decrit le probleme comme « 3 cellules, backticks perdus, mecanique ». La mesure dit autre chose : sur main, 17 des 40 cellules markdown de medical_chatbot_en sont identiques au francais, et 21 sur 26 pour FT-05_en. Sur cette branche : 0 et 0. main publie aujourd'hui deux notebooks majoritairement francais sous un nom anglais. Cette PR ne les ajoute pas, elle repare ce que main expose deja.


Ce qui reste rouge, et pourquoi ce n'est pas a toi de le porter

No markdown content loss echoue encore sur FT-05 avec 3 findings. Je les ai lus un par un en comparant le texte base-vs-tete : ce sont des faux positifs de traduction -- l'anglais est ~26 % plus court que le francais a contenu egal, et Objectif -> Objective se lit comme un motif perdu.

Le garde n'a ni conscience de la langue ni override -- j'ai greppe _en|lang|translat|TARGET_LANGS|suffix et override|label|bypass dans detect_md_content_loss.py : rien. Donc toute PR de traduction fidele le fera rougir.

Et l'exemption en bloc sur *_<lang>.ipynb serait le mauvais reflexe : le meme garde vient d'attraper la vraie troncature de medical_chatbot. Contre-exemple inscrit avant que quiconque propose le skip. Issue dediee ouverte, c'est un correctif de garde, pas un correctif de PR.

@myia-ai-01

Copy link
Copy Markdown
Collaborator

Correction de ma correction -- ma « Correction 1 » ci-dessus est fausse

Je viens de verifier ce que j'avais affirme il y a une heure, et c'etait faux. Aucune action n'a encore ete prise dessus, donc rien n'est casse -- mais la version publiee est a corriger avant qu'elle serve a quelqu'un.

Ce que j'ai ecrit : « dans ces 9-la, le FR lui-meme ecrit - # Etape 1 : ... sans backticks. L'anglais y est fidele. Le defaut est cote francais, dans la source. »

Ce que la mesure dit :

$ grep '^\s*-\s+#' barbie-schreck.ipynb  (via parse json, cellules markdown)
- `# Étape 1` : Définir le nom et la description de chaque nouvelle contrainte
- `# Étape 2` : Ajouter les tuples `(nom, description)` a la liste `CONTRAINTES`
- `# Indice` : respecter le format existant `("Nom", "Description de la règle")`

Le notebook francais porte deja la forme backtickee. Il a ete repare -- fix_hint_headings.py existe pour exactement ca. Ce qui porte la forme cassee, c'est la colonne text_fr du CSV, qui est un instantane perime du francais :

--- csv.text_fr        +++ notebook FR courant
-- # Étape 1 : Définir le nom et la description [...]
+- `# Étape 1` : Définir le nom et la description [...]

C'est la seule difference sur cette cellule. Et le hash_fr stocke correspond au texte perime (0a2e6e8ca6a4ff4d des deux cotes) : la ligne est donc parfaitement coherente avec elle-meme, ce qui explique qu'aucune verification interne au CSV ne la signale.

Consequence sur mon raisonnement : ma regle d'applier conditionnait le re-backtickage a « le sibling FR porte-t-il des backticks ? » -- une bonne question, ancree sur la mauvaise reference. Elle lisait text_fr (perime) au lieu du notebook (courant). Elle a donc sous-corrige, et j'ai ensuite explique cette sous-correction par un defaut francais qui n'existe pas.

Ce qui ne change pas : ces 9 cellules sont hors du perimetre de cette PR (barbie-schreck, fort-boyard-python, receipe_maker), donc aucun changement de code ici. Et le port lui-meme tient -- les 6 troncatures de medical_chatbot etaient bien des troncatures, mesurees sur les ratios, pas sur les backticks.

Ce que ca revele, et qui vaut mieux que mon issue initiale : l'organe canonique nomme deja ce defaut -- SRC_DRIFT dans check_translation_sync.py. Il tourne en CI (translation-drift.yml), non bloquant par conception. Mesure du jour sur translations/ :

SRC_DRIFT 2007   ORPHAN_ROW 2284   MISSING_LANG 206   TRAD_DRIFT 1

Les 2007 bruts ne sont pas tous actionnables -- une source qui derive sans traduction deposee n'a rien a retraduire. Le sous-ensemble qui mord est SRC_DRIFT + traduction deja deposee = 47 cellules sur 8 notebooks. La, l'anglais publie est fidele a un francais qui n'existe plus. Issue dediee ouverte ; @po-2026 rien a faire de ton cote, c'est un grain a part.

jsboige added a commit that referenced this pull request Aug 29, 2026
…R sibling (#13549)

Artefacts *_<lang>.ipynb dont le sibling FR existe a la meme revision :
comparaison head-vs-sibling-FR (pas head-vs-base-git qui mesure la
difference de langue) au seuil TRANSLATION_DROP_THRESHOLD=0.5 calibre
sur les mesures reelles #13542 (troncatures 0.04-0.36, fideles
0.734-0.92). Motifs structurants comptes bilingues (aliases EN :
Objectives, Prerequisites, Statement...). Artefact orphelin -> retombee
mono-langue. Le mode s'applique aussi aux artefacts NOUVEAUX : une
creation tronquee "au titre seul" (#12850) est detectee des la creation
au lieu d'etre exemptee new_file.

Closes #13548

Co-authored-by: Claude-Code <noreply@anthropic.com>
@myia-ai-01
myia-ai-01 merged commit 7cc2d35 into main Aug 29, 2026
62 checks passed
jsboige added a commit that referenced this pull request Aug 29, 2026
…e local

Extrait de #13543 sa moitie non destructive. #13543 melait la suppression de
deux notebooks _en (collision frontale avec #13542, qui les complete) et ce
correctif de perimetre ; seul le second est ici.

discover_pairs traversait les copies du depot : une machine portant des
worktrees rend un compte different de la CI, et EXPECTED_PAIR_COUNT — une
egalite — devient non maintenable.

La version de #13543 sautait une LISTE DE NOMS. Mesure du 30/08 : un worktree
nomme `.wt-parity-split` faisait toujours rendre 2 paires inexistantes hors de
la copie, filtre actif. Le commentaire promettait l independance a
l environnement, la condition ne filtrait que sept noms. Ce qui caracterise une
copie n est pas son nom mais la presence d un `.git`. La garde teste cela.

Controles : racine polluee -> 0 paire ; worktree reel -> 2 paires (pas de
sur-filtrage) ; 31 tests passent.

Ne touche PAS EXPECTED_PAIR_COUNT : c est le cliquet de #13542.

Co-Authored-By: Claude-Code <noreply@anthropic.com>
jsboige added a commit that referenced this pull request Aug 30, 2026
…strument en silence — il amputait la traine (#13574)

* fix(translation,#10038): le compte de paires ne depend plus de l arbre local

Extrait de #13543 sa moitie non destructive. #13543 melait la suppression de
deux notebooks _en (collision frontale avec #13542, qui les complete) et ce
correctif de perimetre ; seul le second est ici.

discover_pairs traversait les copies du depot : une machine portant des
worktrees rend un compte different de la CI, et EXPECTED_PAIR_COUNT — une
egalite — devient non maintenable.

La version de #13543 sautait une LISTE DE NOMS. Mesure du 30/08 : un worktree
nomme `.wt-parity-split` faisait toujours rendre 2 paires inexistantes hors de
la copie, filtre actif. Le commentaire promettait l independance a
l environnement, la condition ne filtrait que sept noms. Ce qui caracterise une
copie n est pas son nom mais la presence d un `.git`. La garde teste cela.

Controles : racine polluee -> 0 paire ; worktree reel -> 2 paires (pas de
sur-filtrage) ; 31 tests passent.

Ne touche PAS EXPECTED_PAIR_COUNT : c est le cliquet de #13542.

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

* fix(picker): le plafond de recuperation du pool inversait l'instrument en silence

`fetch_pool()` demandait `gh issue list --limit 300`. Mesure du 2026-08-30 :
213 issues ouvertes, marge de 87 -- et `gh issue list` rend par recence de
creation (verifie : les 12 premieres rendues etaient les 12 dernieres creees).

Une saturation du plafond n'ampute donc pas le pool au hasard : elle ampute
exactement la traine. Ce que le plafond de 300 aurait fait tomber en premier,
mesure : #1028 (mandat audiobook), #1203, #1206, #1210, #1453, #1454 -- six
EPICs de mai, tous vivants. C'est-a-dire precisement la population que la
ponderation age + delaissement existe pour atteindre. Le plafond n'aurait pas
borne l'instrument, il l'aurait retourne, sans rien dire.

Deux changements :

- `POOL_FETCH_LIMIT = 2000` (etait 300, en dur dans l'appel).
- Garde de saturation : `len(raw) >= POOL_FETCH_LIMIT` est la signature de la
  troncature (on a recu exactement ce qu'on a demande). Le tirage se poursuit
  -- bloquer la lane serait pire que la biaiser (R4) -- mais il le DIT, parce
  que le seul risque reel est de lire un tirage tronque comme une couverture
  du pool.

Aucun plafond ne se choisit une fois pour toutes ; c'est la garde qui est
durable, pas le 2000.

Controles (2026-08-30, pool reel de 213) :
  plafond 50   -> 50 rendues, garde declenchee    (controle positif)
  plafond 2000 -> 213 rendues, garde silencieuse  (controle negatif)

Couverture mesuree apres correctif : 213 issues, **zero a poids nul**, ratio
lourd/leger 22.7x. Les 6 vieux EPICs pesent 8.3 % pour les rangs 4-21 ; les 10
issues deposees ce jour pesent 1.6 % pour les rangs 118-178. Les neuves entrent
derriere les delaissees et remontent avec l'age -- deposer n'ecrase pas la
traine.

See #13420

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

---------

Co-authored-by: jsboige <jsboige@gmail.com>
Co-authored-by: Claude-Code <noreply@anthropic.com>
@jsboige
jsboige deleted the fix/translation-pair-ratchet-12850 branch September 2, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

translation-override Dual-key override for translation-guard (#10332): label + [TRANSLATION-OVERRIDE] comment required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants