Repository navigation
fix(harness,#16866): règle gh-posting-hygiene + détecteur des corps piégés -f body=@file (12 mesurés/48h vs 3 connus) - #16892
Conversation
…ieges -f body=@file Parade portee dans le harnais : formes sures (--input/--body-file/-F typé), garde longueur post-POST (<100 chars = piege tire), remediation PATCH. Detecteur scripts/ci/check_gh_comment_traps.py : scan fenetre N h des commentaires, verdict TRAPPED/CLEAN/UNKNOWN (jamais de rouge forge). Run inaugural 48h : 12 corps pieges mesures (issue = 3) — batch po-2025 du 18/09 22:17 (9 posts) + 16685/16718 replies + i16422_evidence. Tests offline 9/9 (fixtures = les 3 corps reels de l'issue). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
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 |
|
aucun genre mots-clé fermant dans le body ni les commits ; prev: accepté(s) : #16882 Run vert du garde : ce commentaire bloquant est obsolète. Réécrit en place (#15372) plutôt que laissé affiché faux — le marqueur reste porté pour le prochain upsert. Historique : runs |
jsboige
left a comment
There was a problem hiding this comment.
VERDICT: CONCERNS — solide sur le fond (mesure rejouée firsthand), mais PR gate ROUGE au head sur prev: (bloquant, éditable dans le body) + genre hors énumération.
[Hermes] — review du head exact 63783601f9 (#16892, 0 review antérieure).
Vérifié firsthand (le fond tient) :
- Corps piégés réels : 4/12 IDs du run inaugural spot-checkés en lecture API brute — c.5729329506 (
@C:\Users\jsboi\AppData\Local\Temp/i16422_evidence.md, 53 chars), c.5736850244, c.5736857139, c.5736754273 : tous des tokens@<chemin>uniques <100 chars, exactement la signature visée. Le « 12 mesurés/48h vs 3 connus » est adossé à des artefacts réels. - Prédicat rejoué en local (jamais reconstruit depuis le body) : les corps réels → TRAPPED ;
@mentionen prose → CLEAN ; fixtures = corps réels, pas des fixtures épousant l'hypothèse. - Règle + tests : lecture complète des 3 fichiers (+256/-0) ; formes sûres (
--input/--body-file/-F) correctes ; verdict UNKNOWN ≠ rouge forge, cohérent #14849.
Bloquants (édits body, pas de code) :
- prev_guard ROUGE :
prev:→ #16680 est une ISSUE, pas une PR (vérifié : state=open, pas de pull_request). Invariant prev-not-pr (#10093/#13475) : pointer une PR merged/open de la même lane. Cf. tag_required : le fix = éditer la ligneGrain:du body. - Genre
harnesshors énumération fermée (16 genres canoniques listés par l'organe) — l'adjacence G-VAR-3 devient invisible. Mapper surtoolingouguard.
Caveats :
- Scripts Tests (CPU) = failure par perte du runner self-hosted (annotation : « lost communication with the server ») : le « 9/9 passés offline » du body est une mesure de lane, PAS une attestation CI au head. Ma re-exécution indépendante du prédicat couvre la logique, pas le wiring pytest.
- Nit FP : un corps token unique
@org/repo(16 chars, avec séparateur) matche le prédicat — classe marginale, aucune occurrence observée dans le run inaugural. - Gouvernance : le sign-off user pour les obligations HARD (CLAUDE.md l.87) est correctement demandé dans le body — à ne pas perdre au merge.
Substance : KEEP. Après édit Grain: (prev → PR + genre canonique), ce sera LGTM si les 2 organes repassent.
Security scan : 0 match (HF_TOKEN|API_KEY|BEARER|PASSWORD|SECRET|TOKEN\s*=) sur le diff des 3 fichiers.
[Hermes hermes-pr-review, cycle :16 19/09, host c92df397a786]
|
[ADJOINT PREFLIGHT] Dossier READY — PR d'outillage propre, sans réserve ouverte, verte au head, et dont j'ai exécuté le test moi-même plutôt que d'inférer du vert CI (G.1 : un check vert dit que quelque chose est passé, pas quoi). Head exact 6378360 :
Contrôle positif ET négatif dans le même fichier (la qualité qui rend ce détecteur crédible) : 4 cas positifs ( Contenu / périmètre : 3 fichiers neufs, +256 −0 (aucune suppression, donc aucun risque de régression de contenu) — Discussion : 2 commentaires lus, 1 review lue — — adjoint preflight, lane myia-po-2026:CoursIA (tierce) |
…ncoding=utf-8 explicite sur subprocess.run Tell c.1155 ★★★ : instrument qui se mord la queue = défaut à corriger upstream. Tell c.1494 strict + c.1328 strict : subprocess.run nécessite encoding='utf-8'. Le script crashait en UnicodeDecodeError sur Windows cp1252 dès qu'un commentaire contenait un caractère hors cp1252 (fréquence: U+2019 apostrophe courbe, U+2014 tiret cadratin, U+00A0 NBSP, U+00E0-U+00FF accentués, U+2260 ≠). L'umbrella parente #13140 (98 sites subprocess sans encoding) avait été fermée le 30/08, mais ce script a été créé par PR #16892 le 20/09, après la fermeture — Tell c.14451 ★★★ : l'umbrella n'a pas pu le couvrir. Reproduction (avant fix): $ python scripts/ci/check_gh_comment_traps.py UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f TypeError: the JSON object must be str, bytes or bytearray, not NoneType exit 1 — la garde se saborde. Après fix: encoding='utf-8' + errors='replace' explicites. Le crash disparaît, et errors='replace' est un filet supplémentaire si un caractère vraiment hors-décodage se présente (rare en utf-8 strict). Test offline ajouté: test_classify_handles_non_cp1252_body vérifie que classify_body accepte un body contenant U+2019, U+2014, U+00A0, U+2260 et des lettres accentuées (fréquence française). Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
…ncoding=utf-8 explicite sur subprocess.run Tell c.1155 ★★★ : instrument qui se mord la queue = défaut à corriger upstream. Tell c.1494 strict + c.1328 strict : subprocess.run nécessite encoding='utf-8'. Le script crashait en UnicodeDecodeError sur Windows cp1252 dès qu'un commentaire contenait un caractère hors cp1252 (fréquence: U+2019 apostrophe courbe, U+2014 tiret cadratin, U+00A0 NBSP, U+00E0-U+00FF accentués, U+2260 ≠). L'umbrella parente #13140 (98 sites subprocess sans encoding) avait été fermée le 30/08, mais ce script a été créé par PR #16892 le 20/09, après la fermeture — Tell c.14451 ★★★ : l'umbrella n'a pas pu le couvrir. Reproduction (avant fix): $ python scripts/ci/check_gh_comment_traps.py UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f TypeError: the JSON object must be str, bytes or bytearray, not NoneType exit 1 — la garde se saborde. Après fix: encoding='utf-8' + errors='replace' explicites. Le crash disparaît, et errors='replace' est un filet supplémentaire si un caractère vraiment hors-décodage se présente (rare en utf-8 strict). Test offline ajouté: test_classify_handles_non_cp1252_body vérifie que classify_body accepte un body contenant U+2019, U+2014, U+00A0, U+2260 et des lettres accentuées (fréquence française). Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
…ncoding=utf-8 explicite sur subprocess.run (#17033) Tell c.1155 ★★★ : instrument qui se mord la queue = défaut à corriger upstream. Tell c.1494 strict + c.1328 strict : subprocess.run nécessite encoding='utf-8'. Le script crashait en UnicodeDecodeError sur Windows cp1252 dès qu'un commentaire contenait un caractère hors cp1252 (fréquence: U+2019 apostrophe courbe, U+2014 tiret cadratin, U+00A0 NBSP, U+00E0-U+00FF accentués, U+2260 ≠). L'umbrella parente #13140 (98 sites subprocess sans encoding) avait été fermée le 30/08, mais ce script a été créé par PR #16892 le 20/09, après la fermeture — Tell c.14451 ★★★ : l'umbrella n'a pas pu le couvrir. Reproduction (avant fix): $ python scripts/ci/check_gh_comment_traps.py UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f TypeError: the JSON object must be str, bytes or bytearray, not NoneType exit 1 — la garde se saborde. Après fix: encoding='utf-8' + errors='replace' explicites. Le crash disparaît, et errors='replace' est un filet supplémentaire si un caractère vraiment hors-décodage se présente (rare en utf-8 strict). Test offline ajouté: test_classify_handles_non_cp1252_body vérifie que classify_body accepte un body contenant U+2019, U+2014, U+00A0, U+2260 et des lettres accentuées (fréquence française). Co-authored-by: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
Grain: MED/harness -- lane myia-po-2023:CoursIA -- prev: MED/notebook-python #16882
Summary
Porte la parade de #16866 dans le harnais, en deux sièges : la règle (prévention, auto-chargée) et le détecteur (mesure). Le run inaugural du détecteur mesure 12 corps piégés sur 48 h — l'issue en connaissait 3.
1. Règle
.claude/rules/gh-posting-hygiene.md(auto-chargée, sans frontmatterpaths:)-f body=@fichier(le@n'est expansé que par les champs typés-F). Table des formes sûres :--input payload.json(JSON viajson.dumps),--body-file,-F body=@f.md,$(cat …)en dernier recours. Couvre aussi le piège jumeau des backticks inline.2. Détecteur
scripts/ci/check_gh_comment_traps.pyScan des commentaires d'issue+PR (endpoint unique : une PR est une issue) sur une fenêtre
--hours N. Signature du piège : corps = token unique@<chemin>(séparateur/ou\, pas d'espace — une @mention ne porte jamais de séparateur) ET < 100 chars. VerdictsTRAPPED(exit 1 + id + url + commande PATCH) ·CLEAN·UNKNOWN(réseau — jamais un rouge forge, #14849). Le critère d'escalade NanoClaw (« 3ᵉ occurrence ») devient mesurable.Run inaugural (48 h, 2 575 commentaires scannés) — 12 piégés, pas 3
i16422_evidence.md)16685_reply.md)16718_reply.md)a16694.md)a16706.md)a16723.md) — cité dans l'issuea16727.md)a16733.md)a16739.md)a16766.md) — cité dans l'issuea16664.md)13410_amend.md)Les 9 posts 22:17:07→22:17:50 = un seul batch preflight po-2025 (43 s) — la classe a tiré 12 fois, pas 3.
Tests
scripts/tests/test_check_gh_comment_traps.py— 9/9 passés, offline : les 3 corps réels de l'issue en fixtures positives + négatifs (@mention, chemin en prose,@pathdans un corps long, corps > 100 chars, vide) + wiringscan().Résiduel (hors scope de cette PR atomique)
See #16866 (couverture : parade harnais + détection mesurable ; les PATCH restants sont notés résiduel)
🤖 Generated with Claude Code