# Delta 0.1.4-alpha.2.fix.1 — hygiène EOF et prévention automatique ## Diagnostic La gate opérateur de `0.1.4-alpha.2` a validé les `48/48` tests Python, les trois audits Markdown et le contrôle normatif Tauri, puis a échoué sur les deux contrôles Git d'hygiène : ```text docs/studies/002-TAURI_SKELETON_DECISION.md:299: new blank line at EOF. ``` Le même défaut a été signalé par : ```text git diff --check git diff --cached --check ``` `history/0.1.4/alpha.2.md` enregistre donc `FAIL`. Le contenu normatif Tauri de `alpha.2` reste conservé ; le présent fix corrige uniquement l'hygiène mécanique et la lacune de prévention qui a permis la réapparition d'un défaut déjà rencontré historiquement. Version après application : ```text 0.1.4-alpha.2.fix.1 ``` ## Objet Corriger la ligne vide surnuméraire à EOF de l'étude Tauri et faire de cette classe de défaut une propriété automatiquement contrôlée avant les futures livraisons PGR. Le correctif introduit un audit monotâche read-only au lieu d'ajouter une vérification ad hoc dans chaque delta. ## Scope REPLACE : ```text VERSION docs/rules/210-WORKFLOW.md docs/studies/002-TAURI_SKELETON_DECISION.md docs/validation/001-VALIDATION_MATRIX.md ``` ADD : ```text deltas/0.1.4/alpha.2.fix.1.md scripts/audit_text_hygiene.py tests/test_text_hygiene.py ``` Les autres décisions de `alpha.2`, notamment `docs/rules/710-TAURI.md`, le plan `010` et `docs/000-README.md`, MUST rester inchangées. ## Correction EOF `docs/studies/002-TAURI_SKELETON_DECISION.md` conserve son contenu et sa révision interne `3`. La seule modification de ce fichier est mécanique : sa terminaison passe de deux caractères LF successifs à exactement un LF final. Aucune décision Tauri n'est modifiée par cette correction. ## Audit `text_hygiene` `scripts/audit_text_hygiene.py` possède quatre propriétés mécaniques sur les fichiers texte sélectionnés : ```text LF uniquement aucun whitespace terminal newline finale obligatoire exactement une newline finale, donc aucune ligne vide supplémentaire à EOF ``` L'audit reste read-only, accepte des fichiers ou répertoires explicites et ignore les répertoires générés usuels. Il ne remplace pas un formatter, un parser Markdown ou `git diff --check`. `tests/test_text_hygiene.py` couvre au minimum : - fichier propre avec exactement un LF final ; - ligne vide supplémentaire à EOF ; - newline finale absente ; - CRLF ; - espace ou tabulation terminale ; - exclusion d'un répertoire généré ; - sélection invalide. ## Contrat de workflow `docs/rules/210-WORKFLOW.md` passe de la révision `7` à `8` et rend explicite que le générateur doit contrôler l'hygiène mécanique avant livraison, plutôt que déléguer sa découverte à la gate opérateur. `docs/validation/001-VALIDATION_MATRIX.md` passe de la révision `14` à `15` et ajoute `PGR-TEXT-HYGIENE-001` comme audit faible coût déclenché lorsqu'un fichier texte gouverné est modifié. Le contrôle Git reste conservé comme filet indépendant. ## Gate opérateur Après application puis commit/push du history `FAIL` de `alpha.2`, appliquer ce delta et exécuter : ```bash cat VERSION test -f history/0.1.4/alpha.2.md grep -A2 '^## Statut$' history/0.1.4/alpha.2.md | grep -Fx 'FAIL' test -f deltas/0.1.4/alpha.2.fix.1.md test ! -e history/0.1.4/alpha.2.fix.1.md test -f scripts/audit_text_hygiene.py test -f tests/test_text_hygiene.py python3 -B -m unittest discover -s tests -v python3 -B scripts/audit_text_hygiene.py \ VERSION README.md RULES.md ROADMAP.md CHANGELOG.md \ docs deltas history prompts scripts tests templates .gitignore .settings python3 -B scripts/audit_markdown_headers.py \ README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts python3 -B scripts/audit_markdown_tables.py \ README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts python3 -B scripts/audit_markdown_links.py \ README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts python3 -B - <<'PY' from pathlib import Path import re assert Path('VERSION').read_text(encoding='utf-8').strip() == '0.1.4-alpha.2.fix.1' history = Path('history/0.1.4/alpha.2.md').read_text(encoding='utf-8') assert re.search(r'## Statut\s+FAIL', history) study_path = Path('docs/studies/002-TAURI_SKELETON_DECISION.md') study = study_path.read_bytes() assert study.endswith(b'\n') assert not study.endswith(b'\n\n') assert study_path.read_text(encoding='utf-8').startswith( '\n' '' ) workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8') assert workflow.startswith( '\n' '' ) for phrase in ( '## Hygiène mécanique des artefacts texte', 'exactement une seule newline finale', 'scripts/audit_text_hygiene.py', 'Un générateur MUST corriger un défaut mécanique détectable avant livraison', ): assert phrase in workflow, phrase matrix = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8') assert matrix.startswith( '\n' '' ) assert '`PGR-TEXT-HYGIENE-001`' in matrix assert 'exactement une seule newline finale' in matrix assert Path('scripts/audit_text_hygiene.py').exists() assert Path('tests/test_text_hygiene.py').exists() for path, version in ( ('docs/rules/710-TAURI.md', '7'), ('docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md', '2'), ('docs/000-README.md', '42'), ): lines = Path(path).read_text(encoding='utf-8').splitlines() assert lines[1] == f'', (path, lines[1]) assert not Path('docs/skeletons/004-TAURI.md').exists() assert not Path('history/0.1.4/alpha.2.fix.1.md').exists() print( '0.1.4 alpha.2.fix.1 hygiene audit: clean ' '(EOF corrected, reusable text hygiene audit active, Tauri decisions preserved)' ) PY git diff --check git add -A git diff --cached --check git status --short ``` Le scope indexé attendu est : ```text M VERSION A deltas/0.1.4/alpha.2.fix.1.md M docs/rules/210-WORKFLOW.md M docs/studies/002-TAURI_SKELETON_DECISION.md M docs/validation/001-VALIDATION_MATRIX.md A scripts/audit_text_hygiene.py A tests/test_text_hygiene.py ``` L'ordre d'affichage peut varier ; l'ensemble des chemins doit être identique. ## Transition ### PASS Produire `history/0.1.4/alpha.2.fix.1.md`, commit/push sous l'identité `0.1.4-alpha.2.fix.1`, puis poursuivre avec `alpha.3` sur cette baseline propre. Les gates suivantes de `0.1.4` doivent sélectionner `PGR-TEXT-HYGIENE-001` pour les fichiers texte modifiés. ### FAIL Enregistrer le résultat réel dans `history/0.1.4/alpha.2.fix.1.md` et poursuivre sous `alpha.2.fix.N`. Ne pas commencer `alpha.3` tant que l'hygiène texte et le scope du correctif ne sont pas `PASS`.