# Delta 0.0.3-alpha.1 — cadrage de l'écriture Git contrôlée ## Baseline requise Partir de la stable autoritaire : ```text tag Knowledge v0.0.2 commit Knowledge 183d354a67bec6d2d512c4898f5189759a6120b0 archive SHA-256 0e518c7eaad115811cccc8fb2b38a1e68150ec985c2ca72ec08a9ca5bbb202ce publish report sasedev-knowledge-0.0.2-publish.001-report.md = PASS ``` La stable `0.0.2` ne contenait volontairement aucun prompt `0.0.3`, car sa revue d'horizon n'avait engagé aucune prochaine mission. La présente session a ouvert explicitement une nouvelle mission depuis cette baseline ; le prompt versionné correspondant est donc matérialisé par cette tranche : ```text prompts/003-V0_0_3_START_PROMPT.md ``` PGR `v0.1.3` reste une provenance historique. Aucune version PGR ultérieure n'est consultée ou adoptée. La version devient : ```text 0.0.3-alpha.1 ``` ## Objet Fermer le cadrage de la prochaine release avant toute modification fonctionnelle : - vérifier la stable `v0.0.2`, ses règles/owners, architecture, deltas/histories et `DEFER` ; - sélectionner l'écriture Git générique contrôlée comme mission `0.0.3` ; - conserver le processus `git` contrôlé déjà validé en `0.0.2` ; - choisir un worktree d'écriture isolé pour créer une révision candidate ; - décider que le contrat d'écriture restera distinct du contrat `GitRepository` de lecture ; - borner la mise à jour distante aux branches `refs/heads/...` avec attente explicite sur leur état précédent ; - garder une divergence comme conflit récupérable sans rebase/merge automatique ; - établir l'étude, le plan, le prompt local et la gate de release. Aucun code produit, aucune crate, aucune dépendance Cargo/npm et aucun fichier Web ne sont ajoutés ou modifiés dans cette tranche. ## Décision d'horizon La prochaine release engagée est : ```text 0.0.3 — écriture Git contrôlée et push gardé ``` Les domaines PostgreSQL, proposition/revue, rendu/publication produit, recherche, Gitea, auth/admin et opérations restent non numérotés. `0.0.3` ne ferme pas le workflow de proposition complet. Elle fournit la primitive Git générique dont ce workflow aura besoin : base explicite, mutations confinées, commit candidat et mise à jour distante gardée. ## Contrats retenus L'étude : ```text docs/studies/006-V0_0_3_GIT_WRITE_STUDY.md ``` retient : - un worktree d'écriture isolé sous la racine d'état contrôlée ; - des mutations de fichiers par chemins relatifs validés ; - une identité auteur/committer explicite ; - hooks et prompts neutralisés ; - une nouvelle révision candidate avant tout push ; - un push de branche avec comparaison de l'état distant attendu ; - conflit explicite si la branche a divergé ; - aucun `push --force` non gardé ; - aucun rebase/merge automatique ; - aucune forge obligatoire. Le plan actif est : ```text docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md ``` avec trajectoire prévisionnelle `alpha.1` à `alpha.4`, puis `beta.1`, `rc.1` et `rel.1`. ## Scope des fichiers REPLACE : ```text VERSION Cargo.toml README.md RULES.md ROADMAP.md CHANGELOG.md docs/000-README.md docs/architecture/001-PROJECT_PROFILE.md docs/architecture/002-KNOWLEDGE_ARCHITECTURE.md docs/validation/001-VALIDATION_MATRIX.md ``` ADD : ```text docs/studies/006-V0_0_3_GIT_WRITE_STUDY.md docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md prompts/003-V0_0_3_START_PROMPT.md deltas/0.0.3/alpha.1.md ``` DELETE : aucun. Aucun fichier sous `crates/` ou `Web/` n'est modifié. Aucun history `0.0.3-alpha.1` n'est inclus : il doit refléter la gate opérateur réelle. ## Gate opérateur Exécuter depuis la racine du dépôt après application du delta : ```bash test "$(cat VERSION)" = '0.0.3-alpha.1' grep -F 'version = "0.0.3-alpha.1"' Cargo.toml 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 cargo fmt --all cargo fmt --all -- --check python3 -B scripts/audit_rust_test_layout.py crates python3 -B scripts/audit_rust_blank_lines.py crates python3 -B scripts/audit_rust_item_spacing.py crates python3 -B scripts/audit_rust_module_order.py crates python3 -B scripts/audit_rust_trait_import_blocks.py crates python3 -B scripts/audit_rust_reexport_blocks.py crates python3 -B scripts/audit_rust_crate_root_facades.py crates python3 -B scripts/audit_rust_export_completeness.py --root . --summary-only cargo metadata --format-version 1 --no-deps > /tmp/sasedev-knowledge-0.0.3-alpha.1-metadata.json cargo check --workspace cargo clippy --workspace --all-targets --all-features -- -D warnings cargo test -p knowledge-git-lib --test git_read_path cargo test --workspace --all-targets --all-features python3 - <<'PYGATE' import json from pathlib import Path assert Path('docs/studies/006-V0_0_3_GIT_WRITE_STUDY.md').is_file() assert Path('docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md').is_file() assert Path('prompts/003-V0_0_3_START_PROMPT.md').is_file() assert Path('deltas/0.0.3/alpha.1.md').is_file() assert not Path('history/0.0.3/alpha.1.md').exists() roadmap = Path('ROADMAP.md').read_text(encoding='utf-8') assert '- `( ) 0.0.3`' in roadmap assert '0.0.4' not in roadmap rules = Path('RULES.md').read_text(encoding='utf-8') for phrase in ( 'Écriture Git contrôlée', 'MUST viser une branche `refs/heads/...`', 'MUST NOT effectuer un `push --force` non gardé', ): assert phrase in rules, phrase study = Path('docs/studies/006-V0_0_3_GIT_WRITE_STUDY.md').read_text(encoding='utf-8') for phrase in ( 'worktree d\'écriture isolé', 'comparaison-et-échange', 'aucun rebase ou merge automatique', 'PGR `v0.1.3` reste une provenance historique', ): assert phrase in study, phrase plan = Path('docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md').read_text(encoding='utf-8') headings = ( '## Statut et sources', '## Mission', '## État acquis et questions ouvertes', '## Scope', '## Hors scope', '## Stratégie de validation', '## Trajectoire prévisionnelle', '## Déclencheurs de REPLAN', '## Clôture et transition', '## Revue d\'horizon', ) positions = [plan.index(value) for value in headings] assert positions == sorted(positions) for tranche in ('alpha.1', 'alpha.2', 'alpha.3', 'alpha.4', 'beta.1', 'rc.1', 'rel.1'): assert f'### {tranche} —' in plan, tranche prompt = Path('prompts/003-V0_0_3_START_PROMPT.md').read_text(encoding='utf-8') assert 'Ne pas rechercher, charger ni adopter automatiquement une nouvelle version de PGR.' in prompt assert '0e518c7eaad115811cccc8fb2b38a1e68150ec985c2ca72ec08a9ca5bbb202ce' in prompt metadata = json.loads(Path('/tmp/sasedev-knowledge-0.0.3-alpha.1-metadata.json').read_text(encoding='utf-8')) expected = { 'knowledge-app-lib', 'knowledge-domain-lib', 'knowledge-git-api', 'knowledge-git-lib', 'knowledge-sync-api', 'knowledge-web-lib', 'knowledge-pgr-server', 'knowledge-howtos-server', 'knowledge-snippets-server', } assert {package['name'] for package in metadata['packages']} == expected assert len(metadata['workspace_members']) == 9 assert not Path('crates/knowledge-forge-gitea-lib').exists() assert not Path('crates/knowledge-store-postgres-lib').exists() assert not Path('migrations').exists() print('Knowledge 0.0.3-alpha.1 framing 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 0.0.3-alpha.1 text hygiene: clean ({len(paths)} file(s))') PYTEXT test -z "$(git diff --name-only -- crates Web)" test ! -e history/0.0.3/alpha.1.md 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 -f Web/knowledge-template-lab/package-lock.json git add -A git diff --cached --check git status --short ``` La gate ne rejoue pas npm/Vite/HTTP dans `alpha.1` : aucun contrat Web ni fichier `Web/` n'est modifié, et la stable `0.0.2` a déjà acquis une gate Web/runtime complète. Cette omission est conforme à la validation proportionnée locale. ## Transition ### PASS Produire séparément : ```text history/0.0.3/alpha.1.md ``` avec les résultats réellement observés. Après application du history, commit/push `0.0.3-alpha.1`, puis seulement préparer `0.0.3-alpha.2`. ### FAIL / PARTIAL / BLOCKED Produire le history réel avec son statut, l'appliquer et le committer avant toute correction. Une correction bornée à ce cadrage utilise : ```text 0.0.3-alpha.1.fix.1 ``` Si le diagnostic invalide la mission, l'ownership ou la stratégie d'écriture, exécuter un REPLAN plutôt que d'absorber une nouvelle responsabilité dans un fix.