# Delta 0.0.2-beta.1.fix.2 — correction finale de la gate beta ## Base requise État `0.0.2-beta.1.fix.1` committé et poussé après application du history : ```text history/0.0.2/beta.1.fix.1.md = FAIL ``` La version devient : ```text 0.0.2-beta.1.fix.2 ``` ## Cause `beta.1.fix.1` acquiert toutes les preuves runtime manquantes, y compris les trois smokes HTTP, mais sa gate contient deux défauts propres au livrable de validation : - l'audit Python de stabilisation utilise une chaîne délimitée par apostrophes contenant `n'est`, produisant `SyntaxError: unterminated string literal` ; - `docs/validation/001-VALIDATION_MATRIX.md` se termine par une ligne vide supplémentaire, ce que `git diff --check` puis `git diff --cached --check` rejettent comme `new blank line at EOF`. Le script d'hygiène texte de `fix.1` vérifie seulement `endswith(b'\n')` et ne détecte donc pas le suffixe invalide `b'\n\n'`. ## Objet du fix Le fix n'introduit aucune fonctionnalité et ne rejoue pas mécaniquement les preuves runtime déjà acquises sur un arbre produit inchangé. Il : - corrige le quoting de l'audit Python ; - normalise tous ses fichiers remplacés à exactement un LF terminal ; - rend durable la règle d'un unique LF terminal chez `400-VALIDATION` ; - étend l'audit d'hygiène pour rejeter `\n\n` à EOF ; - interdit dans les gates destinées au shell interactif les modifications persistantes `set -e`, `set -u` et `set -o pipefail` ; - conserve comme preuves cumulatives les résultats `PASS` de `beta.1.fix.1` pour Cargo/Clippy/tests, Web et smokes HTTP. ## Scope Fichiers remplacés : ```text VERSION Cargo.toml docs/rules/400-VALIDATION.md docs/plans/002-V0_0_2_GIT_SYNC_PLAN.md docs/validation/001-VALIDATION_MATRIX.md ``` Fichier ajouté : ```text deltas/0.0.2/beta.1.fix.2.md ``` Aucun fichier sous `crates/` ou `Web/` n'est remplacé. Aucun package, dépendance, contrat métier, comportement Git ou future release n'est ajouté. ## Gate opérateur Exécuter les commandes ci-dessous directement dans le shell interactif. La gate ne modifie volontairement pas les options globales du shell. ```bash test "$(cat VERSION)" = '0.0.2-beta.1.fix.2' grep -F 'version = "0.0.2-beta.1.fix.2"' Cargo.toml grep -A2 '^## Statut$' history/0.0.2/beta.1.fix.1.md | grep -Fx 'FAIL' git diff --check python3 -B scripts/audit_markdown_headers.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts deltas history python3 -B scripts/audit_markdown_links.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts deltas history python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts deltas history python3 - <<'PYGATE' from pathlib import Path import tomllib workspace = tomllib.loads(Path("Cargo.toml").read_text(encoding="utf-8")) assert len(workspace["workspace"]["members"]) == 9 study = Path("docs/studies/005-V0_0_2_GIT_SYNC_RECONCILIATION.md").read_text(encoding="utf-8") assert "Aucun prompt `0.0.3` n'est créé" in study roadmap = Path("ROADMAP.md").read_text(encoding="utf-8") assert "0.0.3" not in roadmap assert not Path("prompts/003-V0_0_3_START_PROMPT.md").exists() assert not Path("history/0.0.2/beta.1.fix.2.md").exists() previous = Path("history/0.0.2/beta.1.fix.1.md").read_text(encoding="utf-8") for phrase in ( "knowledge-pgr-server smoke PASS", "knowledge-howtos-server smoke PASS", "knowledge-snippets-server smoke PASS", "cargo check --workspace", "cargo test --workspace --all-targets --all-features", ): assert phrase in previous, phrase rule400 = Path("docs/rules/400-VALIDATION.md").read_text(encoding="utf-8") assert "exactement un unique LF" in rule400 assert "ne doit pas modifier durablement les options du shell" in rule400 print("Knowledge 0.0.2-beta.1.fix.2 stabilization audit: clean") PYGATE python3 - <<'PYTEXT' from pathlib import Path roots = [Path('README.md'), Path('RULES.md'), Path('ROADMAP.md'), Path('CHANGELOG.md'), Path('docs'), Path('prompts'), Path('deltas'), Path('history')] paths = [] for root in roots: if root.is_file(): paths.append(root) elif root.is_dir(): paths.extend(path for path in root.rglob('*') if path.is_file()) for path in paths: data = path.read_bytes() assert b'\r' not in data, path assert data.endswith(b'\n'), path assert not data.endswith(b'\n\n'), path text = data.decode('utf-8') for number, line in enumerate(text.splitlines(), start=1): assert line == line.rstrip(' \t'), (path, number) print(f'Knowledge beta.1.fix.2 text hygiene: clean ({len(paths)} file(s))') PYTEXT test -f Cargo.lock git check-ignore -q Cargo.lock if git ls-files --error-unmatch Cargo.lock >/dev/null 2>&1; then echo 'Cargo.lock must remain untracked for Knowledge' >&2 exit 1 fi test -z "$(git diff --name-only -- crates Web)" test ! -e crates/knowledge-forge-gitea-lib test ! -e crates/knowledge-store-postgres-lib git add -A git diff --cached --check git status --short ``` ## Résultat attendu Le `PASS` doit notamment afficher : ```text Knowledge 0.0.2-beta.1.fix.2 stabilization audit: clean Knowledge beta.1.fix.2 text hygiene: clean (... file(s)) ``` Aucune commande Cargo, npm ou smoke n'est répétée dans ce fix documentaire : leurs preuves `PASS` sont conservées dans le history `beta.1.fix.1`, et le contrôle de scope prouve l'absence de diff sous `crates/` et `Web/`. ## Transition `PASS` ferme la stabilisation beta et autorise uniquement : ```text 0.0.2-rc.1 ``` Le history `beta.1.fix.2` est produit seulement après réception de la gate opérateur complète.