You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
guard(prev_guard): citer un tag prev: en prose CREE une declaration — 3 PRs gelees sur une phrase de documentation correcte #14550
find_prev_self_references() et find_prev_target_pr_numbers() l'itèrent tous deux sur text sans distinguer la ligne de tag (la déclaration) de la prose (une citation). Conséquence : écrire le tag d'une autre PR dans une phrase explicative crée une déclaration au sens du garde.
Le docstring de find_prev_target_pr_numbers montre que la distinction a bien été pensée — mais sur le mauvais axe :
« A #N that appears OUTSIDE a prev: clause (e.g. Refs #13439) is NOT a target here. »
Le garde sait donc écarter un #Nhors clause prev:. Il n'a aucun moyen d'écarter une clause prev:complète et bien formée qui se trouve être une citation.
prev-selfetprev-not-merged tombent nécessairement ensemble dans ce cas : une PR qui se cite elle-même n'est jamais mergée au moment de son évaluation. Cette conjonction est la signature du faux positif — un vrai prev-self (typo de tag, comme #14431 qui déclare authentiquement prev: MED/guard #14431) produit la même paire, mais sur la ligne 1.
Coût mesuré : #14522 gelée, et derrière elle #14538 puis #14543, dont les prev: pointent la chaîne — 3 PRs immobilisées sur une phrase de documentation correcte. Débloqué le 2026-09-04T00:4x par une édition de 8 caractères en prose (prev: → prev pointant), le tag n'ayant jamais eu besoin d'être touché.
Pourquoi ce n'est pas un cas marginal
Le garde punit la lane qui documente le mieux. Une PR qui explique quel successeur elle débloque, et cite son tag pour être vérifiable, se sabote ; une PR muette passe. L'incitation est exactement inversée par rapport à ce que le protocole de variation cherche à obtenir.
C'est la même classe de défaut que « citer un [CLAIMED] verbatim en pose un », déjà rencontrée sur le protocole de claim.
Remèdes candidats
#
Remède
Coût
Effet de bord
1
N'évaluer que la ligne de tag — celle que grain_tag.parse_grain_tag() identifie déjà
faible
perd la détection dans les messages de commit, que le garde évalue aussi (commits[i]) et qui est légitime
2
Ignorer toute occurrence dans un span code (backticks simples ou bloc clôturé)
faible
une citation hors backticks passe encore ; mais c'est la forme dominante en pratique
3
N'évaluer que la PREMIÈRE occurrence par emplacement
très faible
un tag réellement dupliqué et divergent ne serait plus vu
4
Exiger l'ancrage en début de ligne (^ + tolérance de puce/décoration)
faible
dépend de la stabilité de forme du tag, que le guard de tag garantit déjà par mot-clé
Recommandation : 1 + 2. Le (1) traite la cause — le tag est la déclaration, le reste est du texte ; le (2) couvre les messages de commit, où (1) ne s'applique pas et où la citation en backticks reste la forme usuelle.
Un contrôle positif dans le même test : le corps réel de chore(genai,#13581): T2 hub .NET — EFCore+CopilotSDK -> Integrations-DotNet/ #14431 (prev: MED/guard #14431 en ligne 1, auto-référence authentique) rend toujours guard_pass: false avec prev-self. Sans ce second cas, le correctif serait indiscernable d'une désactivation du garde.
Les cas existants de scripts/tests/test_variation_prev_guard.py restent verts, y compris ceux qui portent sur commits[i].
Le point (2) est le cœur : un prédicat qu'on assouplit se valide par ce qu'il attrape encore, jamais par ce qu'il cesse d'attraper.
Le défaut
scripts/ci/variation_prev_guard.pyapplique son prédicat au corps entier de la PR :find_prev_self_references()etfind_prev_target_pr_numbers()l'itèrent tous deux surtextsans distinguer la ligne de tag (la déclaration) de la prose (une citation). Conséquence : écrire le tag d'une autre PR dans une phrase explicative crée une déclaration au sens du garde.Le docstring de
find_prev_target_pr_numbersmontre que la distinction a bien été pensée — mais sur le mauvais axe :Le garde sait donc écarter un
#Nhors clauseprev:. Il n'a aucun moyen d'écarter une clauseprev:complète et bien formée qui se trouve être une citation.Cas mesuré — PR #14522 (2026-09-04)
La lane
myia-po-2023:CoursIA-2avait un tag correct dès le départ :#14459est mergée (2026-09-03T18:50:47Z). Le tag satisfait les trois invariants de #13475.Son dernier paragraphe documentait le successeur, ce qui est exactement la bonne pratique :
Le garde a compté cette citation comme une seconde déclaration et rendu deux invariants en échec sur la même occurrence :
prev-selfetprev-not-mergedtombent nécessairement ensemble dans ce cas : une PR qui se cite elle-même n'est jamais mergée au moment de son évaluation. Cette conjonction est la signature du faux positif — un vraiprev-self(typo de tag, comme #14431 qui déclare authentiquementprev: MED/guard #14431) produit la même paire, mais sur la ligne 1.Coût mesuré : #14522 gelée, et derrière elle #14538 puis #14543, dont les
prev:pointent la chaîne — 3 PRs immobilisées sur une phrase de documentation correcte. Débloqué le 2026-09-04T00:4x par une édition de 8 caractères en prose (prev:→prev pointant), le tag n'ayant jamais eu besoin d'être touché.Pourquoi ce n'est pas un cas marginal
Le garde punit la lane qui documente le mieux. Une PR qui explique quel successeur elle débloque, et cite son tag pour être vérifiable, se sabote ; une PR muette passe. L'incitation est exactement inversée par rapport à ce que le protocole de variation cherche à obtenir.
C'est la même classe de défaut que « citer un
[CLAIMED]verbatim en pose un », déjà rencontrée sur le protocole de claim.Remèdes candidats
grain_tag.parse_grain_tag()identifie déjàcommits[i]) et qui est légitimecode(backticks simples ou bloc clôturé)^+ tolérance de puce/décoration)Recommandation : 1 + 2. Le (1) traite la cause — le tag est la déclaration, le reste est du texte ; le (2) couvre les messages de commit, où (1) ne s'applique pas et où la citation en backticks reste la forme usuelle.
Acceptance
guard_pass: true.prev: MED/guard #14431en ligne 1, auto-référence authentique) rend toujoursguard_pass: falseavecprev-self. Sans ce second cas, le correctif serait indiscernable d'une désactivation du garde.scripts/tests/test_variation_prev_guard.pyrestent verts, y compris ceux qui portent surcommits[i].Le point (2) est le cœur : un prédicat qu'on assouplit se valide par ce qu'il attrape encore, jamais par ce qu'il cesse d'attraper.
See #13475