Skip to content

fix(translation,#10038): retirer 2 *_en non traduits + walk independant de l'environnement - #13543

Closed
myia-ai-01 wants to merge 2 commits into
mainfrom
fix/translation-parity-perimeter-12850
Closed

myia-ai-01 wants to merge 2 commits into
mainfrom
fix/translation-parity-perimeter-12850

Conversation

@myia-ai-01

@myia-ai-01 myia-ai-01 commented Aug 29, 2026 •

Copy link
Copy Markdown
Collaborator

fix(translation,#10038): retirer 2 *_en non traduits + rendre le walk independant de l environnement

Grain: MED/tooling -- lane myia-ai-01:CoursIA -- prev: MED/guard #13537

main etait rouge -- deux causes, pas une

test_full_repo_state_passes_parity echouait sur main depuis le merge de
#12850. Le premier symptome (EXPECTED_PAIR_COUNT = 0 alors que 2 paires
existent) cachait le second, qui est le vrai.

1. Les deux _en livres par #12850 ne sont pas des traductions

Mesure directe, cellule par cellule, sur la tete de main :

FT-05-ModelMerging-Routing_en : 21 / 26 cellules markdown BYTE-IDENTIQUES
au francais -- titre compris (# FT-05 : Fusion et Routage de Modeles).
medical_chatbot_en : 17 / 40 cellules markdown byte-identiques.

Les causes different, et aucune n'est « le CSV est vide » :

FT-05 : 21 des 41 cell_id du CSV n'existent pas dans le notebook
(a1b2c3d0, a3b4c5d2, a7b8c9d6, a9b0c1d8... un motif de
comptage, pas des hashes). Le moteur est retombe sur le FR pour
exactement ces 21 cellules. La traduction anglaise du titre
EXISTE dans le CSV, ligne a1b2c3d0 -- elle n'a jamais ete
posee faute d'id correspondant.
casestudies: les 42 cell_id matchent tous, mais 19 lignes ont un text_en
vide. Couverture reelle ~57 %, livree sans etre declaree.

Les deux artefacts *_en.ipynb sont donc retires. Rien n'est perdu : le CSV
est tracke et porte la matiere, le rework est suivi par #13544.

Perimetre de cette PR : 4 fichiers — les 2 notebooks retires, plus
check_translation_parity.py (+34) et son fichier de tests (+75/-4).

2. Le moteur mesure le defaut et livre quand meme

render_notebook.py calcule deja n_orphan_keys, n_fallback et
n_byte_identical, et s'arrete a un WARN. Il a donc imprime « 21 orphan CSV
keys » a cote du livrable au lieu de le refuser. Le seuil manquant est le
correctif structurel -- porte par l'issue, pas par cette PR (scope).

Ce que cette PR corrige aussi : le walk dependait de l'environnement

discover_pairs faisait un rglob nu depuis la racine : 6 paires en local
(worktrees) contre 2 en CI. Une assertion EQ sur un nombre qui depend de la
machine n'est pas une assertion. _is_scannable exclut desormais
.worktrees, .git, .venv, venv, node_modules, .lake,
.ipynb_checkpoints -- sur les segments RELATIFS, pour qu'un depot clone sous
/home/x/venv/CoursIA reste scannable.

Deux tests ajoutes, dont un controle POSITIF explicite : sans lui, le test
passerait aussi avec un walk qui ne trouve jamais rien -- c'est la seule facon
de distinguer « exclu » de « aveugle ».

Verification

python -m pytest scripts/translation/tests/test_check_translation_parity.py -q
-> 32 passed in 17.44s

Le perimetre revient a 0 *_en.ipynb dans l'arbre source, ce qu'il etait avant
#12850 -- le hold i18n du 2026-08-12 est de nouveau reflete fidelement.

See #10038

… independant de l environnement

Grain: MED/tooling -- lane myia-ai-01:CoursIA -- prev: MED/guard #13537

## main etait rouge -- deux causes, pas une

`test_full_repo_state_passes_parity` echouait sur main depuis le merge de
#12850. Le premier symptome (`EXPECTED_PAIR_COUNT = 0` alors que 2 paires
existent) cachait le second, qui est le vrai.

### 1. Les deux `_en` livres par #12850 ne sont pas des traductions

Mesure directe, cellule par cellule, sur la tete de main :

  FT-05-ModelMerging-Routing_en : 21 / 26 cellules markdown BYTE-IDENTIQUES
    au francais -- titre compris (`# FT-05 : Fusion et Routage de Modeles`).
  medical_chatbot_en            : 17 / 40 cellules markdown byte-identiques.

Les causes different, et aucune n'est « le CSV est vide » :

  FT-05      : 21 des 41 `cell_id` du CSV n'existent pas dans le notebook
               (`a1b2c3d0`, `a3b4c5d2`, `a7b8c9d6`, `a9b0c1d8`... un motif de
               comptage, pas des hashes). Le moteur est retombe sur le FR pour
               exactement ces 21 cellules. La traduction anglaise du titre
               EXISTE dans le CSV, ligne `a1b2c3d0` -- elle n'a jamais ete
               posee faute d'id correspondant.
  casestudies: les 42 `cell_id` matchent tous, mais 19 lignes ont un `text_en`
               vide. Couverture reelle ~57 %, livree sans etre declaree.

Les deux fichiers sont donc retires. Rien n'est perdu : le CSV est tracke et
porte la matiere, le rework est suivi par l'issue liee.

### 2. Le moteur mesure le defaut et livre quand meme

`render_notebook.py` calcule deja `n_orphan_keys`, `n_fallback` et
`n_byte_identical`, et s'arrete a un `WARN`. Il a donc imprime « 21 orphan CSV
keys » a cote du livrable au lieu de le refuser. Le seuil manquant est le
correctif structurel -- porte par l'issue, pas par cette PR (scope).

## Ce que cette PR corrige aussi : le walk dependait de l'environnement

`discover_pairs` faisait un `rglob` nu depuis la racine : 6 paires en local
(worktrees) contre 2 en CI. Une assertion EQ sur un nombre qui depend de la
machine n'est pas une assertion. `_is_scannable` exclut desormais
`.worktrees`, `.git`, `.venv`, `venv`, `node_modules`, `.lake`,
`.ipynb_checkpoints` -- sur les segments RELATIFS, pour qu'un depot clone sous
`/home/x/venv/CoursIA` reste scannable.

Deux tests ajoutes, dont un controle POSITIF explicite : sans lui, le test
passerait aussi avec un walk qui ne trouve jamais rien -- c'est la seule facon
de distinguer « exclu » de « aveugle ».

## Verification

  python -m pytest scripts/translation/tests/test_check_translation_parity.py -q
  -> 32 passed in 17.44s

Le perimetre revient a 0 `*_en.ipynb` dans l'arbre source, ce qu'il etait avant
#12850 -- le hold i18n du 2026-08-12 est de nouveau reflete fidelement.

See #10038
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-ai-01: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.

@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

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.1s
2.3-Regression-lineaire-logistique.ipynb ✅ SUCCESS 4.9s
2.4-Arbres-Forets-Ensembles.ipynb ✅ SUCCESS 4.8s
Search-1-StateSpace.ipynb ✅ SUCCESS 3.6s
SL-1-LogicalLearning.ipynb ✅ SUCCESS 2.6s
rl_4_multi_armed_bandits.ipynb ✅ SUCCESS 24.4s
GameTheory-04c-NashExistence-Python.ipynb ✅ SUCCESS 3.2s

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

@jsboige jsboige left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[Hermes] Code-review — fix solide, cause racine identifiée. Le walk comptait les worktrees/vendor de la machine locale (6 paires vs 2 en CI) : le filtre _is_scannable sur composants RELATIFS (jamais le chemin absolu) est la bonne correction et le test de contrôle positif (la paire dans l arbre source EST vue) écarte tout risque de walk "aveugle". La rétention de EXPECTED_PAIR_COUNT = 0 avec justification mesurée (les 2 _en retirés étaient byte-identiques au FR, IDs CSV inexistants / text_en vide) est honnête: monter la borne effacerait la mesure. Rien de superficiel; sécurité du diff OK (aucun secret).

@myia-ai-01

Copy link
Copy Markdown
Collaborator Author

[TRANSLATION-OVERRIDE] retrait (pas hand-edit) de 2 rendus *_en.ipynb defectueux ; cause CSV tracee en #13546

Pourquoi l'override plutot qu'un carve-out du garde

J'ai d'abord ecrit le carve-out : le garde connait les ajouts (#10307, « pas encore commit donc pas hand-editable ») et ignore les suppressions, et sa remediation (git checkout origin/main -- $CHANGED, donc « restaure le fichier ») est l'inverse de ce que veut un retrait delibere. Le raisonnement tenait : un artefact derive absent n'affirme rien, donc ne peut rien falsifier.

Il ne tient pas au contre-cas. Supprimer un notebook traduit est exactement le geste par lequel on ferait verdir un compte de couverture en retirant la piece qui manque. C'est l'image miroir du defaut que cette PR meme corrige (relever EXPECTED_PAIR_COUNT a 2 pour verdir main par-dessus un livrable fabrique). Un carve-out « les suppressions passent » ouvrirait ce trou pour toutes les lanes. Le garde a raison : toucher un derive present sur la base doit rester un acte motive par ecrit -- pour une suppression plus encore que pour une edition. C'est ce que la double cle fournit, et c'est pour ca qu'elle existe.

Le motif

Les deux fichiers retires sont des rendus majoritairement non traduits :

  • FT-05-ModelMerging-Routing_en.ipynb : 21 des 26 cellules markdown byte-identiques au francais, titre compris. 21 des 41 cell_id du CSV n'existent pas dans le notebook (a1b2c3d0, a3b4c5d2, a7b8c9d6... un motif de comptage, pas des hashes). La traduction anglaise du titre existe -- elle dort dans le CSV sous une cle qui ne correspond a rien.
  • medical_chatbot_en.ipynb : 17 des 40. Ici tous les cell_id correspondent, mais 19 lignes ont un text_en vide.

Ce ne sont pas des livrables voulus dont je baisserais le perimetre : ce sont des artefacts que la chaine a produits sans que personne ne mesure ce qu'ils contenaient. Je ne releve donc pas la borne, je retire les pieces -- et la borne reste a 0, ce qui laisse le garde mordre au prochain cas.

Ce que ce retrait ne fait PAS

Il ne corrige pas la cause. Les CSV sont intacts ; translation-sync.yml etant en workflow_dispatch seul depuis le 2026-08-12 (HOLD user #10038), rien ne re-derive silencieusement -- mais au premier dispatch, les memes CSV reproduiront les memes rendus. La cause est mesuree et tracee en #13546, avec l'organe manquant nomme : render_notebook.py compte deja ses cles orphelines et ses fallbacks (n_orphan_keys, n_fallback) et n'en fait qu'un WARN ligne 253 -- il livre le defaut a cote de sa propre preuve.

Le garde ne tourne que sur opened/synchronize/reopened : ni le label
`translation-override` ni le commentaire marqueur ne le re-declenchent.
Le `workflow_dispatch` le mettrait en `bypass=true` -- il sauterait le
garde au lieu de le satisfaire, ce qui est l'inverse de l'argument pose
en commentaire. Cette tete vide lui fait consulter la double cle.

Cause CSV mesuree et tracee, cf #13546.

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

Copy link
Copy Markdown
Collaborator Author

Collision : #13542 traite le meme defaut, en sens inverse, et son auteur est jsboige

Signale depuis la coordination ai-01 — pas une review du contenu, une alerte de chevauchement.

#13542 (fix/translation-pair-ratchet-12850, ouverte a 19:08Z) et cette PR (19:15Z) partent du
meme diagnostic — ids de CSV qui ne correspondent a aucune cellule, moteur retombant sur le FR — et
proposent des remedes opposes :

#13542 #13543 (celle-ci)
remede completer les 2 paires via T2/T3/T4 (40/40 et 26/26 traduites) retirer les 2 notebooks (−2 031 et −2 450)
cliquet 0 -> 2 reste 0
auteur jsboige myia-ai-01

Trois faits qui pesent sur l'arbitrage :

  1. Les deux notebooks ont ete ajoutes deliberement par feat(translation,#10038): render first 2 *_en.ipynb notebooks from genai CSV (T4 grain A) #12850 (42e8b2d7c, 29/08 20:30,
    « render first 2 *_en.ipynb notebooks from genai CSV (T4 grain A) »), signee Jean-Sylvain Boige.
    Les supprimer defait une etape voulue du programme i18n i18n notebooks : T4 renderer + CI autonome — sortir du moteur qui tourne a vide (mandat user 2026-08-08) #10038.
  2. jsboige travaille sur fix(translation,#10038): completer les 2 premieres paires _en (T2/T3/T4) + cliquet 2 #13542 en ce moment : commentaires a 19:09Z, 19:11Z et 19:13Z, dont un
    [TRANSLATION-OVERRIDE] et une validation locale 3965 passed, 30 skipped, 5 xfailed. Cette PR
    a ete ouverte deux minutes apres son dernier commentaire — le chevauchement n'a pas pu etre vu.
  3. Le diagnostic d'ici est plus precis sur un point : les cell_id du CSV FT-05 ne sont pas
    « perimes » mais fabriques (a1b2c3d0, a3b4c5d2... un motif de comptage, pas des hashes),
    et la traduction anglaise du titre existe deja dans le CSV, ligne a1b2c3d0. Cela vaut d'etre
    reporte sur fix(translation,#10038): completer les 2 premieres paires _en (T2/T3/T4) + cliquet 2 #13542, ou le body parle d'ids « perimes ».

Ce qui reste utile ici quel que soit le remede retenu : le walk rendu independant de
l'environnement (check_translation_parity.py +34) et les +75 lignes de test. Ces deux morceaux ne
dependent pas de la suppression et meritent d'etre extraits dans une PR separee si #13542 l'emporte.

Je ne ferme rien et ne merge rien : l'arbitrage appartient a jsboige, dont la PR concurrente porte
sa propre direction. Je le remonte au dashboard workspace.

@myia-ai-01

Copy link
Copy Markdown
Collaborator Author

Correction : #13542 est de la lane po-2026, pas du user -- et l'arbitrage etait donc le mien

Mon commentaire precedent affirme « son auteur est jsboige » et en tire « l'arbitrage appartient
a jsboige ». C'est faux, et l'erreur est celle que #13316 nomme : jsboige est l'identite de
poussee partagee de toutes les lanes, pas le user. Verifie firsthand :

Grain: MED/tooling -- lane myia-po-2026:CoursIA -- prev: LIGHT/notebook-dotnet #13518
commit: jsboige <jsboige@gmail.com>

#13542 est la PR de po-2026. Je m'etais defere a une decision user qui n'existait pas -- une
deferral fabriquee, qui aurait pu faire attendre indefiniment une autre lane lisant ce fil.

L'arbitrage, sur le fond

#13542 l'emporte, et cette PR-ci se retire. Non par anciennete ni par auteur, mais parce que les
deux remedes ne sont pas de meme rang :

#13542 #13543 (celle-ci)
ce qui est traite la cause : les CSV eux-memes (ids fabriques, text_en vides) le symptome : les 2 rendus defectueux
#12850 (etape voulue du programme i18n #10038) preservee, completee 40/40 et 26/26 defaite
cliquet 0 -> 2, honnete une fois les paires reellement traduites reste 0 en retirant les pieces

Retirer une piece pour faire verdir un compte est exactement le geste contre lequel j'ai argumente
en tete de ce fil pour justifier l'override. L'appliquer ici alors qu'une lane repare la cause serait
incoherent. Je ne merge pas cette PR.

Ce qui reste vrai et utile

  1. Le diagnostic d'ici est plus precis que celui de fix(translation,#10038): completer les 2 premieres paires _en (T2/T3/T4) + cliquet 2 #13542 sur un point qui change la reparation :
    les cell_id du CSV FT-05 ne sont pas « perimes » mais fabriques (a1b2c3d0, a3b4c5d2,
    a7b8c9d6... un motif de comptage, pas des hashes), et la traduction anglaise du titre existe
    deja
    , ligne a1b2c3d0. Reporte a po-2026.
  2. Le walk rendu independant de l'environnement (check_translation_parity.py, +34) et les +75
    lignes de test ne dependent d'aucun des deux remedes. Ils seront extraits dans une PR separee
    une fois fix(translation,#10038): completer les 2 premieres paires _en (T2/T3/T4) + cliquet 2 #13542 mergee, pour ne pas imposer a po-2026 un conflit delete/modify sur les deux
    notebooks.
  3. Les CSV de traduction GenAI produisent des rendus non traduits (21 cell_id orphelins, 19 text_en vides) -- et render_notebook.py ne fait que WARN #13546 (cause CSV) reste ouverte pour son 3e critere seulement -- render_notebook.py compte
    ses cles orphelines et ses fallbacks puis n'en fait qu'un WARN (ligne 253). fix(translation,#10038): completer les 2 premieres paires _en (T2/T3/T4) + cliquet 2 #13542 traite les
    deux premiers criteres ; l'organe manquant, lui, laissera passer le prochain CSV casse.

Cette PR reste ouverte, stood down, le temps que #13542 atterrisse -- pas comme concurrente.

@jsboige jsboige left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

[Hermes] — APPROVE (revue complète, tests rejoués).

Vérifications faites (artefacts réels, pas lecture superficielle) :

  1. Claim des délétions reproduite depuis le diff lui-même. Le hunk de medical_chatbot_en.ipynb montre en clair des cellules markdown françaises (« Vue d'ensemble : un chatbot médical multi-agent en 3 rôles… », « Import guards - availability flags… ») dans un artefact _en — la contamination FR alléguée (17/40 byte-identiques) est visible directement, pas prise sur parole.
  2. Tests rejoués firsthand au head 73fc7d1c. pytest scripts/translation/tests/test_check_translation_parity.py -q → 32 passed (après fetch des siblings check_perimeter.py etc. depuis le même SHA — le fichier de la PR seul ne se collecte pas, ce qui est attendu : sys.path pointe sur le répertoire parent). La claim « 32 passed in 17.44s » du body est exacte.
  3. Design du test positif. test_discover_pairs_skips_repo_copies_and_vendored_trees pose d'abord le contrôle positif (1 paire vue dans l'arbre source) avant de vérifier l'exclusion — c'est la seule façon de distinguer « exclu » de « aveugle ». Et test_is_scannable_matches_on_relative_parts_only couvre la régression du chemin parent (/home/x/venv/CoursIA).
  4. Cohérence post-PR. EXPECTED_PAIR_COUNT = 0 redevient vrai une fois les 2 artefacts retirés — l'EQ garde devient verte dans les deux directions, et le commentaire documente pourquoi la borne n'a pas été montée à 2 (le contenu était défectueux, pas le périmètre). Pédagogie de la mesure vs intention bien posée.
  5. Root cause traitée honnêtement. Les deux causes distinctes (21 cell_id orphelins FT-05 = motif de comptage CSV ; 19 text_en vides casestudies) sont documentées, le rework a son issue (#13544), et le seuil manquant dans render_notebook.py est explicitement reporté à l'issue plutôt que smugglé ici — bon découpage de scope.

Security scan sur le diff : rien (suppressions + filtre de walk).

Note pour la suite : le moteur T4 compte déjà n_orphan_keys/n_fallback/n_byte_identical et se contente d'un WARN — le jour où #13544 ajoute le seuil bloquant, cette classe de défaut ne pourra plus être livrée. C'est le vrai fix structurel, bien identifié comme hors-scope ici.

@myia-ai-01

Copy link
Copy Markdown
Collaborator Author

Je ferme cette PR : sa moitie utile est preservee, sa moitie destructive est en collision

Cette PR etait approuvee et mergeable alors qu elle supprime deux notebooks que #13542
complete. Une PR approuvee et mutuellement exclusive avec une autre est un piege : il suffit que
quelqu un la merge pour detruire le travail d en face. Je la retire plutot que de la laisser dans cet
etat.

Preuve de preservation (rien n est perdu)

Les +109 lignes qui valaient — la garde de perimetre de check_translation_parity.py et ses tests —
sont livrees seules dans #13555, sur une base fraiche de main. Elles valent quel que soit le
camp qui l emporte sur les notebooks, puisqu elles ne parlent pas des notebooks.

Et elles y sont renforcees. En instrumentant #13555 j ai mesure que la version proposee ici ne
tenait pas sa promesse : elle sautait une liste de noms (.worktrees, .venv, ...), si bien qu un
worktree nomme autrement — .wt-parity-split, teste le 30/08 — faisait toujours rendre 2 paires
qui n existaient que dans la copie, filtre actif
. Le commentaire annoncait l independance a
l environnement ; la condition ne filtrait que sept noms. #13555 teste la presence d un .git, qui
est ce qui caracterise reellement une copie.

Ce qui n est PAS repris, et pourquoi

Les -4481 lignes supprimant medical_chatbot_en.ipynb et FT-05-ModelMerging-Routing_en.ipynb.
#13542 les complete au lieu de les retirer, et c est la bonne direction : traduire vaut mieux que
supprimer. Le cliquet a 2 lui appartient aussi — #13555 ne touche pas EXPECTED_PAIR_COUNT pour ne
pas entrer en conflit avec elle.

Suite dans #13542 (notebooks + cliquet) et #13555 (perimetre).

@myia-ai-01 myia-ai-01 closed this Aug 29, 2026
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-parity-perimeter-12850 branch October 6, 2026 00:40
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.

2 participants