File size: 3,739 Bytes
2b116bb
 
 
 
 
 
 
 
 
 
afc88ab
 
 
 
 
 
 
 
 
 
 
 
2b116bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
afc88ab
 
 
 
 
 
 
2b116bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
afc88ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""Garde-fou anti-régression — pas de narration sprint *nettoyable*.

Audit prod Chantier 2 : la narration de chantier (« Sprint X — »,
« Phase B2.7 — », « Audit prod P1 — ») a été retirée du code
courant de ``picarones/`` (catégorie A = supprimée, B = préfixe
retiré, WHY conservé).  Reste un résidu R (≈480) : commentaires où
le tag est *fusionné* à une phrase porteuse d'invariant ou en
docstring multi-ligne — retrait mécanique = mutilation, donc
laissés à une revue humaine ultérieure (hors périmètre auto).

Ce test verrouille **deux** invariants :

1. **A == 0 et B == 0** via le classifieur de triage : toute
   narration sprint *proprement dé-tagable* (préfixe propre / tag
   seul) qui réapparaîtrait → échec CI.  L'auteur doit commenter
   par intention, pas par sprint.
2. **Compteur TOTAL ≤ baseline** (ratchet-down absolu) : ferme le
   *seul* trou réel du test #1 — une narration sous forme R
   (tag fusionné mid-phrase, ``# pattern Sprint 78``) passerait #1
   silencieusement.  Le total ne peut désormais que DÉCROÎTRE ;
   tout ajout de narration (même R-style) échoue, et toute
   résorption oblige à resserrer le baseline (pattern doc_paths).
"""

from __future__ import annotations

import importlib.util
from pathlib import Path

_SCRIPT = (
    Path(__file__).resolve().parents[2]
    / "scripts" / "triage_sprint_comments.py"
)


def _load_triage():
    spec = importlib.util.spec_from_file_location("_triage", _SCRIPT)
    assert spec and spec.loader
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod


#: Compteur total de narrations sprint dans ``picarones/`` à la
#: clôture du Chantier 2 (A=0, B=0, R=483).  Ratchet-down absolu :
#: si on descend en dessous (revue humaine de R, reformulation),
#: BAISSER cette valeur dans le même commit.  Ne JAMAIS augmenter.
BASELINE = 483


def test_no_auto_cleanable_sprint_narrative() -> None:
    triage = _load_triage()
    rows = triage.scan()
    offenders = [
        f"{r['cat']} {r['file']}:{r['line']}  «{r['text'][:80]}»"
        for r in rows
        if r["cat"] in ("A", "B")
    ]
    assert not offenders, (
        "Narration sprint *nettoyable* réapparue (catégorie A/B). "
        "Nommer/commenter par INTENTION, pas par sprint — "
        "l'historique vit dans git/CHANGELOG. Lancer "
        "`python scripts/triage_sprint_comments.py --check` :\n  "
        + "\n  ".join(offenders)
    )


def test_total_sprint_narrative_at_or_below_baseline() -> None:
    """Ratchet-down absolu : toute narration sprint ajoutée (même
    forme R fusionnée) fait dépasser le baseline → échec.  Ferme le
    *seul* trou réel du test #1."""
    triage = _load_triage()
    total = len(triage.scan())
    assert total <= BASELINE, (
        f"Narration sprint en hausse : {total} > baseline {BASELINE}. "
        "Le ratchet est strictement décroissant — toute nouvelle "
        "mention Sprint/Phase/Audit dans picarones/ doit être "
        "reformulée par intention (l'historique vit dans CHANGELOG). "
        "Lancer ``python scripts/triage_sprint_comments.py --check``."
    )


def test_baseline_must_be_tightened_when_progress_made() -> None:
    """Pattern miroir (cf. ``test_doc_paths``) : si le total est
    descendu sous le baseline, c'est qu'une revue R a porté ses
    fruits — BAISSER :data:`BASELINE` dans le même commit pour
    verrouiller le gain."""
    triage = _load_triage()
    total = len(triage.scan())
    assert total >= BASELINE, (
        f"Excellent : {total} narrations < baseline {BASELINE}. "
        f"Resserrer ``BASELINE = {total}`` dans ce fichier pour "
        "verrouiller le progrès."
    )