Skip to content

G-VAR-3 : une simple MENTION du marqueur revoque l'override valide qui la precede (parse_override sort de la boucle au premier marqueur malforme) #13261

Description

@myia-ai-01

Symptome

Sur #13234, le gate G-VAR-3 est passe au rouge 62 s apres un commentaire de review qui ne faisait que citer le marqueur d'override, entre backticks, pour expliquer un faux positif de check_unaddressed_nits. L'override reel, bien forme, avait ete poste 3 h 49 plus tot et etait accepte jusque-la.

Run : 33111721678, verdict {"overridden": false, "override_rejected": {"author": "myia-ai-01", "reason": "next: manquant"}}.

Cause, mesuree

parse_override (scripts/ci/variation_adjacency_guard.py:135) parcourt le fil du plus recent au plus ancien et retourne au premier commentaire d'un login coordinateur contenant le marqueur :

for c in reversed(comments):
    ...
    m = _OVERRIDE_RE.search(body)
    if m:  return {...}                     # bien forme
    if _MARKER_RE.search(body):
        ...
        return {"author": login, "lane": None, "malformed": reason}   # <-- sort de la boucle
return None

Le return de la branche « malforme » abandonne la recherche. Une simple mention posterieure ne s'ajoute donc pas au bruit : elle masque l'override valide qui la precede.

Controle execute sur la fonction elle-meme (4 cas, dont un positif et un negatif) :

Cas Fil Verdict
A override seul ACCEPTE next=notebook-python
B override, puis review d'un tiers ACCEPTE next=notebook-python
C override, puis mention en prose du meme auteur REJETE — next: manquant
D mention en prose seule REJETE — next: manquant

A et B sont les controles positifs (le mecanisme marche), D le controle negatif (une prose seule ne doit rien accorder — correct). C est le defaut : l'override valide est revoque par une phrase qui parle de lui.

Et C rend exactement le meme verdict que D : depuis la sortie, on ne peut pas distinguer « un override valide est masque » de « il n'y a pas d'override ». C'est le contrat trois-etats de #12096 (« rien trouve » != « pas regarde ») qui se referme d'un cran trop tot.

Deux consequences

  1. On ne peut pas parler du marqueur sur une PR sans l'armer. La garde d'entree du job est contains(github.event.comment.body, '[G-VAR-3 OVERRIDE]') (perf(ci,#11718): filtrer les runs issue_comment sur la presence du marqueur — une edition coute 11 runs, mesure #11782) : elle est plus large que ce que le parseur accepte. Toute prose citant le marqueur passe l'entree et echoue au parse — le chemin le plus court pour transformer un commentaire de review en gate rouge.
  2. Le retrait de la citation ne repare pas. Reformuler la mention en description skippe le job (la garde d'entree ne matche plus), donc aucun check-run n'est reposte et le rouge perime reste en place. Verifie sur fix(ci,#13232): retirer le paths-filter des 2 gardes metadonnee-dependants (tranche 1c) #13234 : 3 runs skipped a 20:11, check-run rouge de 20:07 intact. Le seul remede est de republier un marqueur bien forme.

Correctif propose

(a) Ne pas abandonner sur un marqueur malforme. Memoriser le premier rejet comme repli, continuer la boucle, et ne rendre le verdict « malforme » que si aucun marqueur bien forme n'existe dans le fil. Le contrat #12096 est preserve (« lu mais malforme » reste distinct de « absent ») ; l'override devient durable face a la prose posterieure.

(b) Neutraliser les spans de code avant le match. Retirer les `...` inline et les blocs clotures avant d'appliquer _MARKER_RE/_OVERRIDE_RE, cote parseur. Cela rend la discussion du mecanisme sure, ce qui est aujourd'hui impossible.

(a) suffit a fermer le symptome ; (b) ferme la classe.

Acceptance

  • Test : override valide suivi d'une mention en prose du meme auteur -> parse_override rend toujours le dict bien forme. C'est le cas C ci-dessus, en rouge aujourd'hui.
  • Controles positif et negatif dans la meme invocation : A/B doivent rester acceptes, D rester rejete. Un correctif qui ferait passer D serait pire que le defaut (auto-exemption par simple prose).
  • Si (b) est retenu : un marqueur dans un bloc de code ne doit rien accorder ni rien rejeter.

Portee

Ne concerne pas [CLAIMED] / [OVERRIDE] de check_lane_claim.py, dont le reducteur ordonne par createdAt a une semantique differente (evenements open/close) — non verifie ici, a ne pas supposer identique.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions