Skip to content

fix(tooling,#13140): encoding=utf-8 on subprocess text=True — tranche 1 CI guards (15 sites) - #13167

Merged
myia-ai-01 merged 2 commits into
mainfrom
fix/13140-encoding-tranche1-ci
Aug 28, 2026
Merged

myia-ai-01 merged 2 commits into
mainfrom
fix/13140-encoding-tranche1-ci

Conversation

@jsboige

@jsboige jsboige commented Aug 26, 2026 •

Copy link
Copy Markdown
Owner

Summary

Tranche 1/4 du sweep #13140 : 15 sites subprocess avec text=True sans encoding= corrigés sur les 8 scripts de garde CI — exactement la classe de défaut qui a tué le garde lane-claim en production (UnicodeDecodeError cp1252 sur symboles UTF-8, #12811→#12813). Même pattern que #12813 : encoding="utf-8", errors="replace".

Fichier Sites
scripts/ci/fast_lane.py 4
scripts/check_hooks_parity.py 3
scripts/pr_gate.py 2
scripts/ci/translation_override_required.py 2
scripts/ci/pr_close_keyword_guard.py 1
scripts/ci/lane_claim_required.py 1
scripts/ci/fetch_merged_prs_since.py 1
scripts/check_pr_perimeter.py 1

Validation

  • Re-scan firsthand (parsing par appel, parenthèses équilibrées — même méthode que l'issue) sur origin/main avant fix : 15 sites détectés dans ces fichiers (l'issue annonçait ~13 pour sa tranche 1 ; l'écart = les 3 sites check_hooks_parity.py, inclus ici car même rôle garde + CI) → 0 restant après fix (re-scan post-fix par le même parseur)
  • py_compile 8/8 OK
  • Suites de tests des gardes touchés : 340/340 passed (test_fast_lane, test_translation_override_required, test_pr_close_keyword_guard, test_lane_claim_required, test_fetch_merged_prs_since, test_pr_gate + missing + rerun_noop + sweep_select, test_check_hooks_parity, test_check_pr_perimeter, test_derive_pr_gate_rerun_workflows)

Découpage

Tranche 1 (gardes CI) dans cette PR. Tranches suivantes — (2) scripts/audit/* + review_coverage.py + setup_hooks.py + scan_student_forks.py ~28 sites, (3) notebook_tools/* ~20 sites, (4) reste ~37 sites — livrées séparément (une PR = un sujet ; §A >15 fichiers = split). Garde anti-régression optionnelle de l'issue (check CI interdisant text=True sans encoding=) : grain séparé à venir.

Grain

Grain: LIGHT/tooling -- lane myia-po-2026:CoursIA — prev: MED/notebook-python #13165

See #13140 (tranche 1/4, contribution partielle)

🤖 Generated with Claude Code


[ai-01] Genre re-qualifie guard -> tooling (merge-gate variation-protocol.md §3, ligne "tag mal derive"). Les trois tranches du sweep #13140 font un travail byte-identique (text=True -> + encoding="utf-8", errors="replace"). #13168 et #13169 le declarent tooling ; #13169 est deja mergee sous ce genre. Cette tranche l'avait declare guard parce que ses fichiers sont des guards CI — c'est le genre pris sur la famille, pas sur le type de travail, et le litmus du protocole le tranche : si le prochain grain de ce rollout tombait dans une autre famille, changerais-je le GENRE ? Les tranches soeurs repondent oui. Le discriminant guard vs tooling est "est-ce que ca peut rougir" : ajouter un encoding= a un subprocess.run ne cree ni ne modifie aucun statut d'echec.

Le TIER reste LIGHT — un sweep mecanique sur N sites d'appel passe le litmus "generable-en-serie". Je ne le monte pas a MED : ce serait de l'inflation, celle-la meme que l'organe signale (TIER-INFLATION: true) sur les tranches soeurs.

Re-qualifie dans le body et non en commentaire : le cap G-VAR-2 compte le genre depuis le body, une requalification postee a cote laisserait la mesure fausse.

Mesure fraiche de l'organe (variation_light_cap.py --genre-signals, arguments de la CI, set des 110 PR mergees du 2026-08-28) : cap=3, light_genre=3, CAP-EXCEEDED-BY-GENRE: false. Les labels variation-light-cap-reached / variation-genre-cap-exceeded portes par cette PR datent de 08:18Z et mesuraient cap=2 — le denominateur a bouge depuis (la lane est a 11 grains mergees aujourd'hui). Un label est une mesure datee, pas un etat.

@jsboige jsboige left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

[Hermes] — review #13167 (head 7e1289b8, encoding sweep tranche 1)

Verdict : LGTM (contrainte token : self-review → COMMENT only)

Tranche 1 : 15 sites / 8 CI guards (ci/fast_lane.py, lane_claim_required.py, pr_gate.py, etc.) — exactement 15 ajouts encoding="utf-8", errors="replace" pour 15 suppressions de text=True sans encoding. Security scan : 0 match. Le guard lane_claim_required.py (la classe qui a tué #12811) est bien traité.

Cohérent avec #13168/#13169 — le sweep #13140 est homogène sur les trois tranches.

@github-actions

Copy link
Copy Markdown
Contributor

<mot-clé fermant> #N où N est une PR -- bloquant (#10101).

closing-keyword + PR-number reference(s) that would auto-close a PR on squash: ['fixed #12813 (commit[0], resolves to a PR)']. Remove the closing keyword, or write the number WITHOUT the leading # (a bare number is not an auto-close). See #10101.

GitHub interprète close/closes/closed/fix/fixes/fixed/resolve/resolves/resolved #N comme un ordre de fermeture automatique dès que le texte atterrit dans le message de squash -- et fermer une PR par mot-clé n'est jamais intentionnel (une PR se merge ou se ferme explicitement, elle ne se « résout » pas). C'est exactement l'incident mesuré dans #10101 : un commit affirmant avoir fermé une PR « sans la merger ».

Le discriminateur est la nature du numéro, pas le contexte du mot-clé : Closes #<issue> est intentionnel (catalog-pr-hygiene HARD 4) et passe silencieusement ; seul un #N qui résout en PR déclenche ce gate.

Pour passer ce gate :

  • retirez le mot-clé fermant devant le numéro, ou
  • écrivez le numéro SANS le # (un nombre nu n'est pas un auto-close).

…e 1 CI guards

15 sites across 8 guard scripts (scripts/ci/fast_lane.py, pr_gate.py,
check_pr_perimeter.py, check_hooks_parity.py, translation_override_required.py,
pr_close_keyword_guard.py, lane_claim_required.py, fetch_merged_prs_since.py):
text=True alone decodes with the Windows locale (cp1252), raising
UnicodeDecodeError on UTF-8 bytes undefined in cp1252 -- the exact class
that killed the lane-claim guard in production (#12811, issue #12813, corrigée par PR).
Same pattern as #12813: encoding="utf-8", errors="replace".

Firsthand re-scan (balanced-paren per-call parse) on origin/main:
15 sites in these files, 0 remaining after fix; py_compile 8/8;
guard test suites 340/340 passed.

Tranche 1/4 per issue decomposition; tranches 2-4 follow separately.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jsboige
jsboige force-pushed the fix/13140-encoding-tranche1-ci branch from 7e1289b to 362461a Compare August 27, 2026 07:26
jsboige added a commit that referenced this pull request Aug 27, 2026
… 3a scripts/tests + root residuel

32 sites / 15 fichiers, TOUS disjoints des 9 PRs encoding en queue
(#13167/#13168/#13169/#13172/#13177/#13183/#13184/#13191/#13206,
disjonction verifiee fichier par fichier) : 14 suites scripts/tests
+ audit_workflow_paths_filters.py (racine).

Base frais origin/main @ 62d47eb (convention re-mesure de l'issue).

Validation : py_compile 15/15, AST scan 0 site restant, pytest 380
passed / 5 skipped sur les 14 suites (chemins subprocess executes a
travers les sites fixes), audit_workflow_paths_filters --json exit 0.
EOL preserve (test_gitleaks_allowlist.py i/crlf traite via edits
byte-preserving, pas de rewrite fichier-entier).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
myia-ai-01 pushed a commit that referenced this pull request Aug 27, 2026
… residuel (32 sites / 15 fichiers) (#13207)

* fix(tooling,#13176): encoding=utf-8 on subprocess text=True — tranche 2b residuel

3 sites / 2 scripts notebook_tools (re-mesure origin/main @ 62d47eb) :
- scan_md_hierarchy.py _repo_root() git rev-parse
- validate_pr_notebooks.py merge-base + diff --name-only (2 appels)

scan_d1_d3_d4_d5.py verifie DEJA propre sur main (encoding present) —
non touche.

Validation : py_compile 2/2, AST scan 0 site restant (text sans encoding),
invocations reelles : validate_pr_notebooks origin/main exit 0 (chemins
merge-base + diff executes), scan_md_hierarchy _repo_root() resolu,
pytest test_scan_d1_stream_text 4/4.

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

* fix(tooling,#13176): encoding=utf-8 on subprocess text=True — tranche 3a scripts/tests + root residuel

32 sites / 15 fichiers, TOUS disjoints des 9 PRs encoding en queue
(#13167/#13168/#13169/#13172/#13177/#13183/#13184/#13191/#13206,
disjonction verifiee fichier par fichier) : 14 suites scripts/tests
+ audit_workflow_paths_filters.py (racine).

Base frais origin/main @ 62d47eb (convention re-mesure de l'issue).

Validation : py_compile 15/15, AST scan 0 site restant, pytest 380
passed / 5 skipped sur les 14 suites (chemins subprocess executes a
travers les sites fixes), audit_workflow_paths_filters --json exit 0.
EOL preserve (test_gitleaks_allowlist.py i/crlf traite via edits
byte-preserving, pas de rewrite fichier-entier).

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

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions github-actions Bot added variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory) variation-genre-run >= 2 grains consecutifs du meme genre LIGHT pour la lane (#10020, advisory) variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) labels Aug 28, 2026
@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-28) :

  • TIER-INFLATION : declared LIGHT << effective LIGHT-genre (tally : declared=1 genre=3 cap=2)
  • GENRE-RUN : run consecutif d'un genre LIGHT (voir signals.runs dans le log du job)
  • CAP-EXCEEDED-BY-GENRE : light_genre > cap partage G-VAR-2 (tally : declared=1 genre=3 cap=2)

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 github-actions Bot added the variation-light-cap-reached Lane ayant deja merge une LIGHT aujourd'hui (cap G-VAR-2 atteint) label Aug 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

G-VAR-2 light cap reached (advisory, non bloquant).
La lane myia-po-2026:CoursIA a deja consomme son budget LIGHT du jour (#? (merge a ?)).
G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour,
toutes categories LIGHT confondues
(guard, doc, refs, ... partagent un seul budget) :
c'est un RATIO, pas un plafond plat. La decision de merge reste au coordinateur.

myia-ai-01 added a commit that referenced this pull request Aug 28, 2026
… 4 SymbolicAI hors Lean (15 sites) (#13183)

* fix(tooling,#13140): encoding=utf-8 on subprocess text=True — tranche 4/4 finale (34 sites)

Derniere tranche du sweep repo-wide du defaut de #12811/#12813: sur un hote
cp1252, `subprocess.run(..., text=True)` sans `encoding=` leve
UnicodeDecodeError sur payload UTF-8 (0x81/0x8D/0x8F/0x90/0x9D). Pattern
`encoding="utf-8", errors="replace"` (variante single-quote impossible ici,
aucun site en f-string dans cette tranche).

34 sites sur 14 fichiers : genai-stack (audio_apis 5, gpu 3, diagnose_comfyui_auth
4), translation/demo_t3_t4 (3), datasets (kaggle 3, qc_data 2), regen_quarto_render
2, check_quantconnect_notebook_freshness 2, lean/setup_shared_mathlib_scan 1,
execute_sudoku_python 1, docker/funasr-api 2, GameTheory/validate_lean_setup 3,
forge_helper 2, slide_tools 1.

Ecart de mesure vs table de l'issue (37 attendus) : fix_sc9_foundry.py,
setup_lean4_all.py et GradeBookApp/gradebook.py ont 3 sites *apparents* mais 0
site reel (les `text=True` y vivent dans des docstrings/strings de code genere
ou sont des `wrap_text` faux-positifs) — aucun appel subprocess runtime, non
modifie.

Validation: re-scan firsthand 34->0 (meme parseur que l'issue et la garde),
py_compile 14/14, tests dedies 167/167 (freshness, execute_sudoku, audio_apis,
gpu, regen_quarto_render).

Avec la garde (PR #13169) et les tranches 1-3 (#13167/#13168/#13169), le sweep
decoupe par l'issue est termine sur les 39 fichiers listes.

See #13140 (fin du sweep liste, contribution partielle sur l'epic)

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

* fix(tooling,#13176): encoding=utf-8 on subprocess text=True — tranche 1 chaîne Lean (23 sites)

Sweep 2e génération du défaut #12811/#12813, point d'entrée le plus exposé :
la chaîne d'exécution Lean. Ces scripts décodent des sorties Lean/WSL
contenant de l'UTF-8 (identifiants Unicode, prose française des erreurs) —
exactement la classe qui a tué la garde #12811 sur hôte cp1252.

23 sites sur 8 fichiers : lean_runner.py (7 — le runner des notebooks Lean),
scripts/verify_lean.py (5), agent_tests/lean_server.py (3),
scripts/validate_lean_setup.py (3), scripts/tests/test_verify_lean.py (2),
scripts/tests/test_leandojo_basic.py (1), test_leandojo_repos.py (1),
scripts/lean4-kernel-wrapper.py (1 — le wrapper kernel lui-même).

Pattern #12813 : encoding="utf-8", errors="replace". Aucun site en
f-string (les f-strings du runner sont des arguments d'appel, pas des
délimiteurs — vérifié ligne par ligne).

Validation:
- re-scan firsthand 23->0 (parseur de la garde #13140), py_compile 8/8
- test_verify_lean : 59/59 passed (les tests L538/L554 invoquent réellement
  verify_lean.py --help/--quick via les sites fixés)
- leandojo suites : 3 passed + 2 ERRORS fixture 'repo' not found --
  préexistantes sur main non-fixé (stash-verify), unrelated
- BOOT-TEST kernel (règle F, wrapper touché) : kernelspec lean4-wsl
  propagé (backup .bak-encoding) puis notebook 3 cellules via nbclient —
  #eval (1+1), #eval "café" ++ utf-8 (payload cp1252-hostile), theorem rfl
  — 3/3 exec, 0 erreur

Note drift (hors scope, à tracker) : le wrapper déployé WSL
(~/.lean4-kernel-wrapper.py, v6 c.126 UNLOCK) est EN AVANCE sur le fichier
repo (fixes AppDataLocal + lake-cwd absents du repo) — 168 lignes de diff
préexistantes. Le fix encoding a été propagé aux DEUX (repo + déployé) sans
écraser le drift.

See #13176 (tranche 1/5, 2e génération)

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

* fix(lean,#13180): wrapper drift guard — deployed WSL copy vs repo canonical

Le kernelspec lean4-wsl execute ~/.lean4-kernel-wrapper.py (copie WSL
deployee) qu'AUCUN script du depot n'ecrit ni ne verifie — les deux copies
ont diverge silencieusement (mesure 2026-08-26 : deploye c.126 stale, sans
la detection lakefile.toml, vs repo c.127 canonique ; divergence
token-skeleton 55 lignes). Constat fait pendant le sweep encoding #13176
(la correction live de la copie deployee a expose le drift).

- Sync live (ops, hors repo) : copie deployee remplacee par la version repo
  (c.127 + fix encoding #13177), backup .bak-c126-enc, md5 deploye = repo
  (3e408241...), boot-test 3/3 cellules kernel lean4-wsl PASS (regle F).
- Garde de derive : inspect_wrapper_content_drift() dans lean_kernel_check.py
  — compare octet-a-octet le deploye (traduction \wsl$\$<distro>, distro
  extraite de l'argv kernel.json) contre la copie repo de reference.
  Statut warning advisory, JAMAIS error (posture #12740 signaler-sans-bloquer
  : un hotfix machine-local sur le deploye reste legal). Le CLI affiche la
  ligne drift quand l'identite du wrapper est ok ; l'exit code reste porte
  par le check d'identite #1618.
- Doc : section wrapper-sync dans wsl-kernels-detail.md (procedure de
  re-sync + verif + boot-test).

Tests : 10/10 (4 preexistants #1618 + 6 nouveaux : traduction UNC, drift ok,
drift warning avec message DRIFT/#13180, deploye illisible, reference repo
absente, never-returns-error).

Closes #13180

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

* fix(tooling,#13176): encoding=utf-8 on subprocess text=True — tranche 4 SymbolicAI hors Lean (15 sites)

Sweep 2e génération #13176, famille SymbolicAI hors chaîne Lean (tranche 1
= PR #13177) : les scripts d'environnement et tests de solveurs des familles
notebooks. Pattern #12813 : encoding="utf-8", errors="replace". Aucun site
en f-string.

15 sites / 7 fichiers : SmartContracts/setup_env.py (6 — vérifs WSL/foundry),
Tweety/scripts/verify_all_tweety.py (3), Argument_Analysis/install_jdk_portable.py
(2), ext_tools/test_marco.py + test_maxsat_solver.py + test_sat_solver.py (1
chacun), SMT/Z3-Linq2Z3/download_meal_data.py (1).

Exclu par sémantique vendor : SymbolicLearning/vendor/difflogic/setup.py
(1 site — code tiers vendu, hors périmètre comme .lake/_peters).

Validation: re-scan firsthand 15->0, py_compile 7/7, tests solveurs
ext_tools 27/27 (les tests invoquent réellement les solveurs via les sites
fixés), verify_all_tweety --help OK.

See #13176 (tranche 4/5)

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

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: myia-ai-01 <myia.ai.01.myia@gmail.com>
@myia-ai-01
myia-ai-01 merged commit ba1cbc0 into main Aug 28, 2026
43 checks passed
@github-actions github-actions Bot removed variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory) variation-genre-run >= 2 grains consecutifs du meme genre LIGHT pour la lane (#10020, advisory) variation-genre-cap-exceeded light_genre > cap partage G-VAR-2 (#10020, advisory) variation-light-cap-reached Lane ayant deja merge une LIGHT aujourd'hui (cap G-VAR-2 atteint) labels Aug 28, 2026
@jsboige
jsboige deleted the fix/13140-encoding-tranche1-ci branch September 2, 2026 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants