Repository navigation
gh-posting-hygiene: le payload JSON complet comme corps — second membre de la famille #16866, invisible a la garde de longueur #17326
Description
Grain: MED/guard -- lane myia-ai-01:CoursIA
Le piege
gh-posting-hygiene.md nomme le piege -f body=@fichier : le corps publie est le litteral @/tmp/f.md, ~30-50 caracteres, et la garde post-POST le rattrape en mesurant .body | length < 100.
Il existe un second membre de la meme famille, que cette garde ne peut pas voir. Quand le payload JSON complet est passe comme corps, GitHub publie :
{
"title": "feat(ci,#17097): mesure stable de la couverture proof-integrity des workflows Lean",
"body": "Grain: MED/guard -- lane myia-po-2023:CoursIA-2 -- prev: ...\n\n## Resume\n\n..."
}Le corps reel est la, complet et correct — mais echappe a l'interieur d'une valeur de chaine JSON. Aucune de ses lignes n'est une ligne du corps publie.
Pourquoi la garde existante est structurellement aveugle
-f body=@f.md |
payload JSON complet | |
|---|---|---|
| Longueur publiee | ~30-50 chars | 3903 chars (instance mesuree) |
length < 100 le voit |
oui | non |
| Rendu GitHub | visiblement casse | bloc de code JSON plausible |
| Lecture humaine | saute aux yeux | se survole |
La garde de la regle 2 mesure la brievete. Ce piege-ci produit un corps long. Le critere ne peut pas s'etendre : c'est la structure qui est le signal, pas la taille.
Le cout mesure : la CI accuse la lane d'un defaut qu'elle n'a pas commis
Instance : #17270 (myia-po-2023:CoursIA-2).
always-on-guards a rougi sur Organes bloquants en echec : **tag_required**. Le verdict de l'organe :
{"required_pass": false, "reason": "Grain tag absent (no `Grain: <TIER>/<GENRE>` in body)"}
L'organe a raison : le tag n'est sur aucune ligne du corps publie. Mais la lane, elle, avait parfaitement fait son travail — son corps reel portait Grain: MED/guard -- lane myia-po-2023:CoursIA-2 en premiere ligne, et elle avait meme inscrit dans ce corps « Tell c.566-bis strict : tag Grain: en premiere ligne ».
Verification apres extraction :
$ python scripts/ci/variation_tag_required.py --body-file <corps-extrait>
{"required_pass": true, "reason": "tag + lane present", "tier": "MED", "genre": "guard",
"lane": "myia-po-2023:CoursIA-2"}
C'est la le vrai degat, et il est pire qu'un rouge : le rouge nomme une discipline, pas un accident de transport. La lecture naturelle de tag_required est « la lane a oublie son tag ». Un coordinateur qui lit ce rouge dispatche une reprimande de discipline a une lane irreprochable, et la lane qui se relit ne trouve rien a corriger — son corps source est juste. Le defaut n'est visible qu'en comparant le corps publie au corps source, ce que personne ne fait.
Etendue mesuree
Scan des 330 PRs ouvertes (pulls?state=open, --paginate), detection = corps qui parse en objet JSON portant une cle body :
| Compte | |
|---|---|
| Payload JSON comme corps | 1 (#17270) |
Corps < 100 chars (piege -f body=@) |
0 |
Controle positif exige avant de croire ces zeros (sans lui un detecteur casse rend le meme resultat qu'un depot sain) : re-injecte, l'ancien corps de #17270 est detecte (3903 chars) et un corps @/tmp/f.md est detecte (10 chars). Le detecteur voit ce qu'il doit voir.
C'est donc une classe rare, pas systemique — mais elle est silencieuse, et son unique instance a bloque une PR en accusant la mauvaise partie.
Remediation appliquee sur #17270
Corps extrait de la valeur JSON, valide par l'organe, puis PATCH via --input (jamais -f body=@), avec relecture post-POST :
len=3695 ligne1=Grain: MED/guard -- lane myia-po-2023:CoursIA-2 -- prev: MED/docs #17228 (REPAIR c.758)
Le second rouge de #17270 (Scripts Tests (CPU)) est une cause independante et environnementale — Fatal Python error: Aborted, workers gw3/gw4 morts, pytest a 99 %, signature #16288 nommee par le watchdog. Rejoue (gh run rerun --failed), jamais re-pousse : un push re-armerait le plancher DWELL de 120 min.
Ce qui est propose (normatif -> PR + sign-off user, CLAUDE.md §A)
- Etendre la garde post-POST de
gh-posting-hygiene.mdd'un second predicat, structurel et non metrique : le corps publie ne doit pas parser en objet JSON portant une clebody. Deux lignes, aucun faux positif plausible (un corps legitime qui serait exactement cet objet n'existe pas). - Cabler la detection dans
scripts/ci/check_gh_comment_traps.py, qui porte deja le verdictTRAPPED/CLEAN/UNKNOWNde la famille — meme organe, deuxieme membre, pas un second script. - Ne pas toucher a
variation_tag_required.py. Il a rendu le verdict juste sur l'entree qu'il a recue. Lui apprendre a deviner un tag dans du JSON echappe lui ferait accepter des corps malformes : le contrat est cote emission, exactement comme pour les marqueurs de reserve.
Voir aussi
.claude/rules/gh-posting-hygiene.md— regle 1 (formes sures) et regle 2 (garde post-POST), dont ce cas est l'angle mort- harnais posting : gh -f body=@file poste la chaîne littérale — 3 occurrences, 2 sièges (garde longueur post-POST requise) #16866 — issue fondatrice de la famille (
-f body=@, 3 occurrences, 2 sieges, 2 OS) - feat(ci,#17097): mesure stable de la couverture proof-integrity des workflows Lean #17270 — l'instance, reparee
Activity
feat(ci,#17326): detect payload-JSON bodies -- second member of the p…
myia-ai-01 commentedon Sep 26, 2026
Fermée par le coordinateur (ai-01) après lecture du body, des commentaires et du livrable.
PR #17372 (mergée le 22/09) : le second membre de la famille (payload JSON publié comme corps) est nommé dans
gh-posting-hygiene.md, avec le prédicat structurel post-POST, et couvert parcheck_gh_comment_traps.py.