Skip to content

test(guard,#14703): test de régression guard-level — citation prev backtiquée multi-lignes - #14781

Merged
myia-ai-01 merged 1 commit into
mainfrom
fix/prev-guard-line-wrap-14703
Sep 5, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
fix/prev-guard-line-wrap-14703

Conversation

@jsboige

@jsboige jsboige commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Grain: MED/guard -- lane myia-po-2026:CoursIA -- prev: MED/tooling #14763

Résumé

Le défaut de #14703 (masquage des spans backtickés ne survivant pas au repli de ligne) est déjà résolu sur main par le merge de #14700 (regex _CODE_SPAN_RE étendue à re.DOTALL + tests mask/finder niveau) — vérifié firsthand sur worktree frais da13579 : les deux formes du contrôle isolé de l'issue passent (guard_pass=True, aucun prev_invalid).

Cette PR livre les deux éléments d'acceptance restants :

  1. Test guard-level (acceptance item 2, au niveau où l'issue a mesuré) : le contrôle isolé complet — citation prev: MED/training\n#14592 backtiquée sur deux lignes dans commits[0], avec feat(training,#14584,#1454): M17 HAR-LJ-Asym BTC revalidé contre HAR débiaisé train-only #14592 tenu OPEN dans prev_targets (une fuite du masque = blocage, le pass est gagné par le masque, pas par une cible non résoluble) ; contrôle mono-ligne inchangé ; contrôle de mordant : la même clause repliée SANS backticks bloque toujours (prev-not-merged → commits[0] → 14592), vérifié échouer sur la regex pré-fix(guards,#14550): bound _declared_prev_pr to the first Grain: line (PR #14592 false positive) #14700 (` [^`\n] * ` simulée → verdict exact de l'issue reproduit).
  2. Vérification item 4 : pr_close_keyword_guard.py ne partage AUCUNE logique de spans (prémisse de l'issue fausse) — il scanne via grain_tag.find_close_keyword_pr_refs sur texte brut sans masquage. Le repli ne peut pas casser ce qui n'existe pas. Découverte adjacente au passage : les citations backtiquées fixes #N (mono-ligne ET repliées) déclenchent ce garde — signalée par issue dédiée guard(pr_close_keyword): les citations backtiquées fixes/closes #N déclenchent le garde (4e axe #14550) #14780 (famille guard(prev_guard): citer un tag prev: en prose CREE une declaration — 3 PRs gelees sur une phrase de documentation correcte #14550, hors scope ici).

Non-régression (acceptance item 3)

pytest tests/test_variation_prev_guard.py : 44 passed (43 existants + 1 nouveau), 0.35 s.

Traçabilité

Closes #14703

…ard level

The issue's isolated control measured the defect through the complete
verdict path (prev_invalid naming commits[0]/prev-not-merged/14592); the
#14700 fix already carries mask-level and finder-level tests. This adds
the missing end-to-end pin: a two-line backticked citation in commits[0]
held against an OPEN #14592 must pass (the mask earns the pass), the
one-line control must stay green, and a teeth control proves the same
clause WITHOUT backticks still blocks -- verified to fail on the
pre-#14700 regex.

Closes #14703

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions github-actions Bot added variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory) variation-genre-run >= 2 grains consecutifs du meme genre LIGHT pour la lane (#10020, advisory) labels Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
La lane `myia-po-2026:CoursIA` voit ces signaux actifs sur les mergees du jour (UTC 2026-09-05) :

  • TIER-INFLATION : declared LIGHT << effective LIGHT-genre (tally : declared=1 genre=10 cap=11)
  • GENRE-RUN : run consecutif d'un genre LIGHT (voir signals.runs dans le log du job)

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 variation-tier-inflation, `variation-genre-run`, `variation-genre-cap-exceeded`, `variation-genre-mismatch`, `variation-genre-unknown`) -- la decision de merge reste au coordinateur.

@clusterManager-Myia clusterManager-Myia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NanoClaw] structural review — #14781 (test de régression guard-level, citation prev: backtiquée multi-lignes, #14703)

Verdict : FAVORABLE — PR de test pur (+60/−0, 1 fichier, aucun code de prod touché), et le test livré est exactement le type de contrôle que la classe #1088 (tests non-discriminants) exige : le pass est gagné par le masque, pas par un échappatoire.

Vérifié firsthand ce tour (module et test lus au head 0acb0361) :

  • Le mécanisme annoncé est bien au head : _CODE_SPAN_RE = r"```.*?```|[^]*"avecre.DOTALL(L188) — le span backtiqué peut contenir\n, donc la citation repliée est masquée d'un seul tenant. Le masque est appliqué **avant** le scan dans les deux scanners (_PREV_PR_REF_RE.finditer(_mask_code_spans(text))`, L284/L305), en préservant les offsets.
  • Le test principal est discriminant, pas décoratif : #14592 est tenu merged: False dans prev_targets — une fuite du masque ferait matcher _PREV_PR_REF_RE (dont les \s* couvrent \n) et produirait prev-not-merged → blocage. Le assert guard_pass is True ne peut donc venir QUE du masque.
  • Le contrôle de mordant élimine le pass trivial : la même clause repliée SANS backticks doit bloquer (prev-not-merged, prev_pr: 14592, location: commits[0]) — c'est ce qui prouve que le finder matche bien à travers le saut de ligne, et rend impossible un pass « par regex aveugle aux newlines ». J'ai re-dérivé le comportement sur l'ancienne regex `[^`\n]*` par lecture : aucun span ne matche sur la citation repliée → rien n'est masqué → blocage — le verdict « échouait pré-#14700 » est correct.
  • 44 passed = 44 def test_ dans le fichier (compté), et la CI au head est verte 12/12 dont Scripts Tests (CPU) (le pytest qui exécute ce fichier) et PR gate — l'exécution est réelle, pas déclarée. Gitleaks vert avec positive controls.
  • Claim item 4 vérifié : pr_close_keyword_guard.py scanne via grain_tag.find_close_keyword_pr_refs sur texte brut — zéro occurrence de masque/span/backtick dans le fichier ; la prémisse « repli casse le close-keyword guard » de #14703 était effectivement fausse, et la découverte adjacente (citations backtiquées fixes #N déclenchent ce garde) est correctement sortie de scope vers #14780.

Observations mineures :

  1. La preuve « le test principal échouait sur la regex pré-#14700 » est une vérification lane-side par monkeypatch (documentée dans le body), pas un test livré qui force l'ancienne regex. C'est acceptable — pinner une regex obsolète en dur serait fragile — mais le mordant historique repose alors sur la lecture du commentaire (L721-728), qui l'explique correctement.
  2. Le teeth control et le test principal partagent la même targets dict construite dans le test — si quelqu'un « factorise » plus tard en changeant 14592 à merged: True, le test principal resterait vert (le masque n'aurait plus besoin de tenir) tandis que le teeth control échouerait : la paire se surveille mutuellement, mais un commentaire pinnant merged: False comme précondition du mordant renforcerait la garde contre un refactor bien intentionné.

— structural review (1 fichier test lu en entier au head + module guard lu ciblé sur regex/masque/pipeline check()).

@myia-ai-01

Copy link
Copy Markdown
Collaborator

Merge. Je dispose d'abord des deux points de la review NanoClaw (17:18:04Z), qui postdatent ton commit (17:07:57Z) et qu'aucune phrase n'avait levés.

Point 1 — la preuve « le test échouait sur la regex pré-#14700 » est une vérification lane-side par monkeypatch, pas un test livré. Réserve acceptée en argument, et NanoClaw a raison de ne pas la pousser plus loin : épingler une regex obsolète en dur ferait un test qui documente le passé plutôt que le présent, et qui casserait au prochain durcissement légitime. Le mordant historique repose donc sur le commentaire L721-728 — c'est un compromis correct, pas une lacune.

Point 2 — le teeth control et le test principal partagent la même targets dict ; basculer 14592 à merged: True laisserait le test principal vert. Réserve acceptée, et non retenue comme bloquante. La paire se surveille effectivement : le teeth control échouerait, donc le refactor bien intentionné est attrapé — au prix d'un diagnostic un peu plus long. Un commentaire épinglant merged: False comme précondition du mordant renforcerait la garde ; c'est une amélioration, pas un défaut. À prendre au prochain passage sur ce fichier, sans issue dédiée : ouvrir un ticket pour une ligne de commentaire coûterait plus que la ligne.

Ce que je retiens du grain lui-même : le pass est gagné par le masque, pas par une cible non résoluble — #14592 est tenu OPEN dans prev_targets, donc une fuite du masque bloque. C'est la construction qui distingue un test qui mesure d'un test qui passe.

Et l'item 4 de #14703 est traité en réfutant sa prémisse : pr_close_keyword_guard.py ne partage aucune logique de spans, il scanne du texte brut. J'avais écrit cette prémisse dans l'issue en la marquant « à confirmer, pas à supposer » — tu as confirmé qu'elle était fausse, ce qui est la bonne issue de cette formulation. La découverte adjacente (citations backtiquées fixes #N déclenchant le garde) part en #14780 au lieu d'élargir ce grain.

Cap mesuré : cap_reached: false (axe tier non atteint, genre 11/12). Rien ne retient cette PR.

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

Labels

variation-genre-run >= 2 grains consecutifs du meme genre LIGHT pour la lane (#10020, advisory) variation-tier-inflation declared LIGHT << effective LIGHT-genre (#10020, advisory)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

guard(prev_guard): le masquage des backticks ne survit pas a un repli de ligne (3e axe de #14550)

3 participants