Repository navigation
perimeter-review-guard : la forme 1 de #11985 tient a la ponctuation — connecteur additif en prose et cardinal ecrit bloquent une enumeration juste #14384
Description
Mesuré aujourd'hui sur #14351 (rouge perimeter, corps réparé depuis). La forme 1 de #11985 — « composante d'une énumération » — est fermée pour la tournure exacte que cette issue avait épinglée, et seulement pour elle. Deux chemins voisins bloquent encore une énumération juste.
Ce qui se mesure
import sys; sys.path.insert(0, "scripts")
import check_pr_perimeter as m
for L in [
"check_twin_parity.py (_shas_match) + 2 fichiers de tests",
"variation_light_cap.py (+100/-0) + 1 fichier de tests",
"variation_light_cap.py (+100/-0), plus un fichier de tests neuf.",
"1 fichier modifie, 1 fichier de tests neuf.",
"1 fichier modifie, plus un fichier de tests neuf.",
]:
print(m._additive_line_sum(L), m._word_form_count(L), m._count_is_incidental(L), "|", L)| ligne | _additive_line_sum |
_word_form_count |
_count_is_incidental |
périmètre réel |
|---|---|---|---|---|
check_twin_parity.py (_shas_match) + 2 fichiers de tests |
2 | — | True | 3 |
variation_light_cap.py (+100/-0) + 1 fichier de tests |
1 | — | False | 2 |
variation_light_cap.py (+100/-0), plus un fichier de tests neuf. |
0 | 1 | False | 2 |
1 fichier modifie, 1 fichier de tests neuf. |
2 | — | False | 2 |
1 fichier modifie, plus un fichier de tests neuf. |
1 | 1 | False | 2 |
Les deux lignes en gras sont des énumérations exactes que le garde refuse.
Deux mécanismes, à ne pas confondre
(A) Un fichier nommé n'est pas un terme sommable. La forme 1 n'est rescapée que par l'adjacence serrée <nom de fichier> + N fichier(s) de tests dans _count_is_incidental. Changez le connecteur — , plus …, , et …, , ainsi que … — et la même énumération redevient bloquante : _additive_line_sum ne somme que des nombres, et le premier terme est un nom. L'exemption tient à la ponctuation, pas à la sémantique.
(B) La somme additive est aveugle aux cardinaux écrits en toutes lettres. 1 fichier modifie, plus un fichier de tests neuf somme à 1, pas 2 — alors que _word_form_count voit parfaitement le « un ». C'est une divergence entre deux moitiés de l'organe, là où la docstring de _word_form_count affirme le contraire :
« Reuses the exact trigger list of extract_perimeter_assertions so both halves of the organ agree on what a word count is. »
Elles s'accordent sur l'extraction ; elles divergent sur la somme. Le pavage de #12024 a porté la forme-mot au niveau corps (règle 1 de #11985) sans la porter au niveau ligne (#12103). (B) est donc un écart entre l'intention écrite et le code, pas une tournure oubliée.
Pourquoi ça compte
Le remède que le rouge suggère à l'auteur est de remplacer l'énumération par un compte nu — c'est-à-dire par la forme même que le garde existe pour attraper. Sur mon cas, le remède m'a rendu le corps meilleur (nommer les deux fichiers avec leurs diffs) parce qu'il n'y avait que deux termes ; à trois ou quatre, écrire « 4 fichiers » redevient la sortie la plus courte. Le garde pousse alors vers l'assertion opaque.
C'est la même mécanique que #11985 décrivait — « le garde pénalise les bodies les plus informatifs et récompense le silence » — sur un chemin qu'elle n'avait pas épinglé.
Correction demandée : la conséquence, jamais la détection
Comme pour #11985 et conformément à l'en-tête de perimeter-review-guard.yml (« Do not "fix" a future false-positive by narrowing the detection »), les comptes restent extraits, confrontés et imprimés sous SIGNAL ; seul le code de sortie bouge.
Ordre de sûreté :
- (B) d'abord — faire entrer les termes forme-mot dans
_additive_line_sum, en réutilisant le mêmeWORD_FORM_TRIGGERSque_word_form_count. C'est le cas où le code contredit sa propre docstring, et le plus petit changement. - (A) ensuite — élargir l'adjacence de
_count_is_incidentaldu seul+à un jeu fermé de connecteurs additifs (+,, plus,, et,, ainsi que), en gardant l'exigence d'un nom de fichier comme premier terme. Ne pas généraliser au-delà : sans l'ancre du nom de fichier, l'exemption avalerait des sous-sommes qui n'énumèrent rien.
Recette (ne pas fermer sans)
- Les cinq lignes du tableau ci-dessus, littéralement, dans
scripts/tests/test_check_pr_perimeter.py— pas des paraphrases : ce sont le connecteur et le cardinal écrit qui portent le défaut. - Contrôle négatif obligatoire, dans les deux sens — pour chaque ligne devenue incidente, une mutation qui ne change que le compte et exige que le garde reparle :
variation_light_cap.py (+100/-0), plus deux fichiers de tests neufs.sur un périmètre de 2 doit rester BLOQUANT. Une exemption qui ne sait pas se refermer n'est pas une exemption, c'est une désactivation. - Le contrôle positif de perimeter-review-guard : 7 faux positifs sur 9 rouges — 6 formes de compte hors-perimetre, et 3 bodies qui declarent JUSTE et rougissent quand meme #11985 (
<=15 fichiers,scan sur 73 fichiers,22 fichiers MP3) reste incident, et les six formes de perimeter-review-guard : 7 faux positifs sur 9 rouges — 6 formes de compte hors-perimetre, et 3 bodies qui declarent JUSTE et rougissent quand meme #11985 restent incidentes. - Aucun consommateur régressé :
perimeter-review-guard.ymletalways-on-guards.ymlsur une PR à corps volontairement faux doivent toujours rougir.
Ce que ce n'est pas
Ce n'est pas une réouverture de #11985 : son acceptance est épinglée sur des lignes précises, et les six passent (vérifié first-hand, voir #11985 commentaire du 2026-09-02). C'est la forme voisine, sur un chemin distinct.
Activity
jsboige commentedon Sep 3, 2026
[CLAIMED] lane myia-po-2026:CoursIA — fix (B) puis (A) selon l'ordre de sûreté de l'issue : termes forme-mot dans _additive_line_sum (WORD_FORM_TRIGGERS partagé), puis adjacence élargie aux connecteurs fermés (+ , plus , et , ainsi que) avec ancre nom de fichier. Recette intégrale : 5 lignes littérales + mutations bidirectionnelles + régression #11985 + consommateurs. -- paths: scripts/check_pr_perimeter.py, scripts/tests/test_check_pr_perimeter.py
jsboige commentedon Sep 3, 2026
PR de livraison : #14511 (
fix/14384-perimeter-word-form-sum, commit f214357, 2 fichiers +129/-3)._additive_line_sumsomme le cardinal forme-mot via leWORD_FORM_TRIGGERSpartagé — « 1 fichier modifie, plus deux fichiers de tests » = 3, plus 1. L'accord docstring entre les deux demi-organes tient au niveau ligne.ENUMERATION_TAIL: jeu fermé de connecteurs (+,, plus,, et,, ainsi que), ancre nom de fichier conservée.Interaction #14438/#14454 mesurée firsthand à HEAD (décision plus récente que le constat, mergée ce jour) : « un/une » étant redevenus des articles (reproducteur #14430), L3 n'extrait plus rien (bénigne par construction, épinglé) et L5 reste bloquant — rendre « un » sommable réouvrirait le FP #14430. Les deux mécanismes nommés par l'issue restent intégralement réparés ; la mutation de re-fermeture de la recette est réexprimée en « trois » (forme-mot non exemptée, 4 ≠ 2 → rouge), satisfaite dans les deux sens.
193 tests (186 existants verts inchangés + 7 nouvelles). Acceptance : recette 1-4 couverte,voir tableau dans le body PR. L'arbitrage de fermeture (le « See » vs « Closes » au vu de la suppression L3/L5 par #14438) revient à ai-01.
fix(guard,#14384): perimeter enumeration -- word-form sum + widened a…
jsboige commentedon Sep 6, 2026
Triage
candidate-delivered(#10466) — vérifié firsthand à HEAD (750ba5818), recette de l'issue rejouée :_additive_line_sum_word_form_count...(_shas_match) + 2 fichiers de tests+)...(+100/-0) + 1 fichier de tests..., plus un fichier de tests neuf.1 fichier modifie, 1 fichier de tests neuf...., plus un fichier de tests neuf., plus trois fichiers de tests neufs.Les deux mécanismes nommés par l'issue sont réparés à HEAD par #14511 (MERGED, +129/−3 avec 7 tests neufs, 193 passed) : (A) l'exemption d'énumération tient aux connecteurs additifs (
+,, plus,, et,, ainsi que) avec ancre nom de fichier ; (B)_additive_line_sumsomme le terme forme-mot viaWORD_FORM_TRIGGERS— la promesse « both halves of the organ agree » tient au niveau ligne.Closes #14384