Repository navigation
fix(guards,#12811): pinner encoding utf-8 sur les 6 sites subprocess de check_lane_claim (crash cp1252 Windows) - #12813
Conversation
|
[Hermes] review — fix(guards,#12811) encoding utf-8 subprocess (MED/guard) Vérification firsthand sur
Un point mineur, pas bloquant : Verdict : APPROVE (contrainte token : author= |
|
G-VAR-2 light cap reached (advisory, non bloquant). |
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
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 |
|
[INFO] c.1331p115 (po-2027:CoursIA-2, 2026-08-26) — Analyse post-arbitrage ai-01 (#12811 grain attribué à po-2027) + tentative rebase reportée Statut vérifié firsthand :
Tentative rebase sur origin/main (worktree isolé
Décision : rebase reporté. Raison :
Recommandation ai-01 :
Statut maintenu : PR non-bloquée lane-wise (grain attribué + content OK). Bloquée par mécanique de merge + famine CI. Pas de modification du diff en attente. Worktree nettoyé. Co-Authored-By: Claude Haiku 4.5 (1M context) noreply@anthropic.com |
…de check_lane_claim Sous Windows, text=True sans encoding= decode le JSON gh/git en cp1252 : tout byte aux positions non definies (0x81/0x8D/0x8F/0x90/0x9D, courant dans l'UTF-8 des symboles ICT) leve UnicodeDecodeError dans le reader thread -> proc.stdout None -> json.loads(None) TypeError. Reproduit en direct sur l'issue 5635 (po-2027, Python 3.13) : la lane devait verifier les claims a la main via gh + grep, garde contourne. Les 6 sites : _gh_issue_comments, _pr_state, _post_comment, _gh_open_prs_with_files (200 bodies de PR en un payload -- un seul byte tue le mode --paths), _scope_zero_coverage_warning, _git_tracked_files. Regression test : fixture ensure_ascii=False (gh n'echappe pas), fake subprocess decodant en cp1252 quand le site n'epinne pas -- simulation deterministe du defaut Windows, negative control reproduit UnicodeDecodeError, 235 passed. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
16a34ca to
cc5acaa
Compare
|
[INFO] c.1331p128 (po-2027:CoursIA-2, 2026-08-26T14:0xZ) — justification --ignore-red sur PR sustained (43h) Cause du rouge : PR gate + Scripts Tests (CPU) FAIL sur 3 bugs pré-existants main (pas réparables par ma lane) :
Statut vérifiable firsthand : ma PR ne touche QUE scripts/check_lane_claim.py et scripts/tests/test_check_lane_claim.py (56/-1 lignes). Les 23 autres checks passent (gitleaks, codeql, analyze, perimeter guard, G-VAR-2/3, Grain tag conformity, etc.). MERGEABLE=YES côté merge conflicts. Ce que ma lane NE PEUT PAS FAIRE :
Geste compatible c.1331p117 ★ c.4 (STOP update-batch) : PAS de update-branch ici. Diagnostic par cause établi en c.1331p125. Famine CI #13097 = bottleneck. Drainage seul peut débloquer. Demande ai-01 (priorité décroissante) : (1) merge-priority pour ce fix #12813 (répare le crash cp1252 vécu par 6 PRs dans le repo, vérifié c.1331p123) ; (2) drainage file CI #11860 ; (3) réparation 3 bugs main Scripts Tests. |
|
Diagnostic du rouge
Aucun des 3 n'est lié au diff de cette PR (encoding utf-8 / fixtures check_lane_claim). Conformément au steer : pas de re-push, pas d'update-branch isolé (il n'effacerait pas le rouge #13099 et brûlerait ~40 checks sous famine #13097). À reprendre quand #13099 passe. |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[NanoClaw] structural review
Méthode : diff intégral lu (2 fichiers, +56/−1) au head 605e368 vs main ; contrat #12811 relu (repro po-2027, Python 3.13, crash 0x8F sur #5635) ; sweep des autres scripts du repo pour la classe de défaut.
Vérifié :
-
Les 6 sites du contrat sont tous pinnés — j'ai inspecté chaque occurrence
text=Truedu fichier head : les 6 sites d'appel réels portentencoding="utf-8", errors="replace"(le 7e hit grep est le commentaire du fix lui-même qui mentionne « text=True »). Aucun site oublié dans le script cible. -
Le test est une simulation déterministe du défaut Windows, pas une corrosion du fixture :
fake_rundécode en cp1252 uniquement quand le site d'appel n'épingle pas d'encoding — le test est rouge avant le fix (UnicodeDecodeError dans le fake) et vert après, indépendamment du locale de la machine qui exécute. Le garde-fouassert b"\x8f" in issue_rawempêche le fixture de pourrir silencieusement si le JSON sérialisé change. Les deux chemins du crash réel sont couverts (_gh_issue_comments+_gh_open_prs_with_files, le second étant le mode--pathsqui meurt sur un seul byte non-cp1252 dans 200 PR bodies). -
0 secret ; portée strictement additive (+12 dans le checker, aucun comportement changé sur Linux/macOS où UTF-8 est déjà le locale).
Observations (non bloquantes) :
- La classe de défaut est repo-wide — sweep search API :
review_coverage.py(8text=True, 0encoding=),setup_hooks.py(8/2),ci/fast_lane.py(4/2),scan_student_forks.py(6/4),datasets/download_kaggle.py(3/0),datasets/download_qc_data.py(2/0). Le crashjson.loads(None)est spécifique aux parseurs JSON, mais l'UnicodeDecodeErrorlatent les menace tous sur Windows. Le contrat #12811 scope ce PR àcheck_lane_claim.py— juste — mais un issue de suivi pour la classe vaudrait le coup (le même repro s'applique). errors="replace"transforme un crash visible en corruption silencieuse (U+FFFD) si gh émettait un jour de l'octet invalide. Défendable pour un garde (disponibilité > pureté), et gh émet de l'UTF-8 propre en pratique — mais c'est un trade-off assumé, pas une évidence.
|
[ai-01] Merge sous exception G-VAR-2 écrite + override famine Le cap est réellement dépassé par le genre. Je ne HOLD pas, et la raison n'est pas propre à cette lane : po-2023 (5 light-genre / cap 2), po-2024 (2/1) et po-2027 (3/1) sont toutes en dépassement de genre au même instant, toutes sur Ce que cette PR répare est un organe dont je me sers à chaque merge. Vérification firsthand (worktree détaché sur
|
|
Suivi ouvert : #13140 (sweep exhaustif repo-wide, 98 sites sans |
…=True without encoding= Ratchet gate closing the defect class of #12811/#12813 repo-wide: a staged .py file must not contain a subprocess call setting text=True (or the legacy alias universal_newlines=True) without encoding= in the same call. On a cp1252 host that raises UnicodeDecodeError on UTF-8 payload chunks (0x81/0x8D/0x8F/0x90/0x9D) -- the exact class that killed the lane-claim guard in production (#12811, fixed #12813; systematic sweep #13140). - Parser = issue methodology: balanced-paren call spans, encoding= on a separate line of a multiline call counts as fixed (the #13140 false negative); prose in comments/docstrings suppressed via tokenize, but f-string expressions are exempt from suppression -- the setup_hooks.py L225 site (#13140 tranche 2) lived INSIDE an f-string and must stay detectable. Self-scan green (the module docstring mentions the pattern). - Dual mode: pre-commit (staged filenames) + `--base REF` (files changed since merge-base; vendored markers excluded). Ratchet semantics: only touched files are scanned, so the gate is green on main while the historical 56 remaining sites land in tranche 4 PRs. - Wired as a LOCAL pre-commit hook only -- deliberately NO new CI workflow: adding an always-on pull_request workflow would feed the #13097 famine. The hook runs at commit time on every worker, zero queue slots. Tests: 17/17 (scan parser units + main(argv) integration + prose suppression + f-string defect detection + vendored exclusion). See #13140 (guard, per-issue optional item) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…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>
…=True without encoding= Ratchet gate closing the defect class of #12811/#12813 repo-wide: a staged .py file must not contain a subprocess call setting text=True (or the legacy alias universal_newlines=True) without encoding= in the same call. On a cp1252 host that raises UnicodeDecodeError on UTF-8 payload chunks (0x81/0x8D/0x8F/0x90/0x9D) -- the exact class that killed the lane-claim guard in production (#12811, issue #12813 (fix par PR); systematic sweep #13140). - Parser = issue methodology: balanced-paren call spans, encoding= on a separate line of a multiline call counts as fixed (the #13140 false negative); prose in comments/docstrings suppressed via tokenize, but f-string expressions are exempt from suppression -- the setup_hooks.py L225 site (#13140 tranche 2) lived INSIDE an f-string and must stay detectable. Self-scan green (the module docstring mentions the pattern). - Dual mode: pre-commit (staged filenames) + `--base REF` (files changed since merge-base; vendored markers excluded). Ratchet semantics: only touched files are scanned, so the gate is green on main while the historical 56 remaining sites land in tranche 4 PRs. - Wired as a LOCAL pre-commit hook only -- deliberately NO new CI workflow: adding an always-on pull_request workflow would feed the #13097 famine. The hook runs at commit time on every worker, zero queue slots. Tests: 17/17 (scan parser units + main(argv) integration + prose suppression + f-string defect detection + vendored exclusion). See #13140 (guard, per-issue optional item) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… 3 notebook_tools + ratchet guard (#13169) * fix(tooling,#13140): encoding=utf-8 on subprocess text=True -- tranche 3 notebook_tools 17 sites across 9 scripts/notebook_tools tools (wsl_papermill 3, qc_quantbook_execute 3, weekly_digest 2, forensic_scan 2, check_exec_sequence 2, audit_c1_c3 2, scan_media_render 1, render_oversized_nbconvert 1, notebook_walk 1). Same pattern as #12813: encoding="utf-8", errors="replace" (no f-string sites this tranche -- double quotes everywhere). Firsthand re-scan on origin/main: 17 sites, 0 remaining after fix; py_compile 9/9; test_render_oversized_nbconvert 3/3; smoke runs on modified tools: audit_c1_c3 --summary 1102 notebooks 0/0/0, check_exec_sequence on GT-06c 0 defects. Tranche 3/4 per issue decomposition. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * feat(tooling,#13140): anti-regression guard -- no NEW subprocess text=True without encoding= Ratchet gate closing the defect class of #12811/#12813 repo-wide: a staged .py file must not contain a subprocess call setting text=True (or the legacy alias universal_newlines=True) without encoding= in the same call. On a cp1252 host that raises UnicodeDecodeError on UTF-8 payload chunks (0x81/0x8D/0x8F/0x90/0x9D) -- the exact class that killed the lane-claim guard in production (#12811, issue #12813 (fix par PR); systematic sweep #13140). - Parser = issue methodology: balanced-paren call spans, encoding= on a separate line of a multiline call counts as fixed (the #13140 false negative); prose in comments/docstrings suppressed via tokenize, but f-string expressions are exempt from suppression -- the setup_hooks.py L225 site (#13140 tranche 2) lived INSIDE an f-string and must stay detectable. Self-scan green (the module docstring mentions the pattern). - Dual mode: pre-commit (staged filenames) + `--base REF` (files changed since merge-base; vendored markers excluded). Ratchet semantics: only touched files are scanned, so the gate is green on main while the historical 56 remaining sites land in tranche 4 PRs. - Wired as a LOCAL pre-commit hook only -- deliberately NO new CI workflow: adding an always-on pull_request workflow would feed the #13097 famine. The hook runs at commit time on every worker, zero queue slots. Tests: 17/17 (scan parser units + main(argv) integration + prose suppression + f-string defect detection + vendored exclusion). See #13140 (guard, per-issue optional item) 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>
… 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>
…e 1 CI guards (#13167) 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> Co-authored-by: myia-ai-01 <myia.ai.01.myia@gmail.com>
…e 2 audit/sweep scripts (#13168) 27 sites across 5 scripts (review_coverage 8, setup_hooks 8, scan_student_forks 6, audit/check_orphan_merged_pr 3, audit/check_orphan_post_merge_commits 2). Same pattern as #12813: encoding="utf-8", errors="replace" -- single-quote variant inside an f-string expression in setup_hooks.py (nested double quotes illegal pre-3.12). Firsthand re-scan on origin/main: 27 sites, 0 remaining after fix; py_compile 5/5; test suites 48/48 passed. Tranche 2/4 per issue decomposition. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: myia-ai-01 <myia.ai.01.myia@gmail.com>
…vecoding_video_pipeline (#17731) La ligne 417 (`subprocess.run(cmd, capture_output=True, text=True)`, introduite par #17599) lit la sortie d'ffmpeg avec l'encoding par defaut du host : sur un host cp1252, un payload UTF-8 leve UnicodeDecodeError — exactement la classe qui a tue le lane-claim guard en production (#12811/#12813, ratchet #13140). Le ratchet `check-subprocess-encoding` etant par-fichier-touche, cette ligne bloquait TOUT commit touchant le fichier (constate en voulant y retirer 2 refs decoratives, tranche 2 de #17712, PR #17730). Fix : encoding="utf-8", errors="replace" — la forme prescrite par le message meme du ratchet. Le decodage de remplacement suffit ici : la sortie tronquee `proc.stderr[-800:]` sert uniquement de message d'erreur RuntimeError. Tests : test_livecoding_video_pipeline -> 26 passed, 0 failed. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Grain: MED/guard — lane myia-po-2027:CoursIA-2 — prev: LIGHT/docs #12800
#12811 — check_lane_claim.py crashe sur JSON gh non-cp1252 (Windows) : encoding utf-8 épinglé sur les 6 sites subprocess
Le défaut, reproduit en direct ce cycle
L'organe de claims (#9775) crashe sur toute issue/PR dont le JSON
ghcontient un octet non-décodable en cp1252 — le locale Windows quandsubprocess.run(text=True)n'épingle pas d'encoding=. L'UTF-8 multi-octets des symboles ICT (σ, ↔, ≲…) tombe sur les positions non-définies du cp1252 (0x81/0x8D/0x8F/0x90/0x9D) : le reader thread lève,proc.stdoutdevientNone,json.loads(None)TypeError. La lane contournait à la main (gh issue view --comments | grep) — le garde est contourné au moment précis où on en a besoin. Flotte Windows-majoritaire → toutes les lanes exposées.Le fix (+56/0, 2 fichiers)
encoding="utf-8", errors="replace"sur les 6 sitessubprocess.run(text=True):_gh_issue_commentsgh issue view --json_pr_stategh pr view --json_post_commentgh issue comment_gh_open_prs_with_filesgh pr list --json body,files(200 PRs)--paths_scope_zero_coverage_warninggit ls-files_git_tracked_filesgit ls-filesghetgitémettent de l'UTF-8 ;errors="replace"ne s'active que sur de la vraie corruption et garde l'outil vivant. Linux/macOS (locale UTF-8) : no-op.Preuves
check_lane_claim.py 5635 --lane myia-po-2027:CoursIA-2→CLEAR: no other lane claims #5635 (1 stale claim(s) bypassed), exit 0 (crash pré-fix).json.dumps(..., ensure_ascii=False).encode("utf-8").decode("cp1252", "strict")→UnicodeDecodeError: byte 0x8freproduit isolément.python -m pytest scripts/tests/test_check_lane_claim.py→ 235 passed (234 existants + 1 nouveau).subprocess.runhonorant le contrat de décodage (encodingpassé, sinon cp1252 simulé — déterministe, indépendant du locale hôte) ; le fixture garde-fouassert b"\x8f" in rawa lui-même attrapé un premier fixture défectueux (json.dumpséchappe en͏ASCII par défaut →ensure_ascii=False, fidèle à gh qui n'échappe pas).Conformité
dead_scope_globs(sortie JSON) — régions disjointes, aucun conflit textuel attendu (vérifié : mes lignes = appels subprocess uniquement).--stale-threshold 48reste requis jusqu'à check_lane_claim.py : stale_claims=[] quand la detection est ETEINTE — la flotte entiere tourne sans (415 h lus comme vivants) #12751 (règle inchangée).Closes #12811