Skip to content

G-VAR : le vocabulaire du tag Grain: n'est valide sur aucun de ses 3 axes (genre, tier, prev) et echoue fail-OPEN #13475

Description

@myia-ai-01

Grain: LIGHT/docs -- lane myia-ai-01:CoursIA -- prev: MED/notebook-python #13466

Le defaut

canonicalize_genre() (scripts/variation_light_cap.py) rend le mot d'entree verbatim quand il n'est ni dans GENRES, ni dans _GENRE_ALIASES, ni un compose <famille>-<genre> dont la tete est aliasee. Ce mot inconnu :

  • compte dans le denominateur (lane_grains, donc dans light_budget(n) = max(1, n//3) — il augmente le budget) ;
  • echappe au numerateur (LIGHT_GENRES ne le contient pas, donc light_genre ne l'incremente pas).

C'est exactement a l'envers : un mot non reconnu relache le cap au lieu de le serrer. Et il ouvre le meme trou sur G-VAR-3 — un genre inconnu ne peut jamais egaler le precedent, donc l'adjacence est inatteignable par simple choix de mot. C'est le trou que #12158 avait deja bouche au cas par cas (scripts, infra, csp) sans fermer la classe.

Mesure — pas une hypothese

Sur la seule journee du 2026-08-29, lane myia-po-2023:CoursIA-2, 16 grains mergés :

PR genre declare canonicalise compte light ?
#13429 prose prose non
#12945 layout layout non
#13009 ict ict non
#12943, #13131 notebook notebook non

prose est le cas net : une PR de prose declaree LIGHT, qui ne consomme pas le budget LIGHT. Le compte rendu par l'organe etait light_genre: 6 (7 avec la candidate #13461) ; le compte vrai est au moins 7 (8 avec la candidate).

Verification directe :

$ python -c "import sys; sys.path.insert(0,'scripts'); from variation_light_cap import canonicalize_genre, LIGHT_GENRES
for g in ['prose','documentation','layout','ict','notebook']:
    c=canonicalize_genre(g); print('%-14s -> %-14s light=%s' % (g,c,c in LIGHT_GENRES))"
prose          -> prose          light=False
documentation  -> documentation  light=False
layout         -> layout         light=False
ict            -> ict            light=False
notebook       -> notebook       light=False

documentation est le plus parlant : le texte de variation-protocol.md §1 le nomme explicitement parmi les synonymes qui « se normalisent » (test-coverage -> test, documentation -> docs, data -> ledger, slidev -> slides). Trois des quatre sont dans la table ; celui-la n'y est pas. La regle et son organe divergent, et la divergence est silencieuse.

Ce qu'il faut, et ce qu'il ne faut pas

Pas une entree d'alias de plus par mot rencontre : c'est la boucle qui a produit le defaut (chaque incident ajoute son mot, le suivant passe). L'enumeration de variation-protocol.md §GENRE est CLOSE par intention — « La fermeture protege G-VAR-3, qu'un vocabulaire ouvert rendrait inatteignable par simple choix de mot ».

Deux pieces :

  1. Fermer la chute : un genre non resoluble ne doit pas etre traite comme « pas light ». Options a trancher dans la PR — (a) le classer light par defaut (fail-CLOSED : le cap se serre au lieu de se relacher) ; (b) le remonter en signal GENRE-UNKNOWN distinct, compte a part et visible dans le JSON, pour que « je n'ai pas su lire » ne se confonde jamais avec « ce n'est pas light ». Ma preference : (b) + (a) — signaler ET compter light, parce qu'un silence qui relache est pire qu'un faux positif qui se conteste.
  2. Aligner la table sur le texte de la regle : au minimum documentation -> docs, prose -> docs, notebook -> ? (ce dernier est ambigu — notebook-python / notebook-dotnet / notebook-lean existent ; notebook nu doit probablement etre refuse en GENRE-UNKNOWN plutot que devine).

Controle positif exige

Un test qui, avec le correctif retire, echoue — et pas seulement un test qui passe :

  • prose, documentation comptent light apres correctif, et le test les voit non-light avant ;
  • un mot invente (zzz-inexistant) leve GENRE-UNKNOWN ;
  • les genres canoniques (notebook-python, research-code) ne regressent pas en light (controle negatif — c'est ce que le guard verbatim protegeait au depart, cf le KeyError: 'notebook-python' du 2026-08-08 documente dans la docstring).

Sans ce controle par faux negatifs, le correctif est indistinguable d'un no-op.

Contexte

Mandat user du 2026-08-28 sur la monoculture : « c'est donc l'echec de ton organe qu'il faut completement repenser ». Ce ticket ne porte pas le picker (c'est #13466) mais le cap qui mesure la monoculture apres coup — un cap qui sous-compte donne un vert qui ne prouve rien, exactement le motif de [[handrolled-pattern-set-undercounts-silently]] : un jeu de motifs se valide par ses faux negatifs, jamais par ses hits.

Constat de terrain : merge de #13461 (2026-08-29T08:39Z).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions