# Delta 0.0.3-alpha.4 — push gardé et concurrence ## Baseline requise Partir de `0.0.3-alpha.3.fix.1` après application, commit et push de son history `PASS`. La version devient : ```text 0.0.3-alpha.4 ``` ## Objet Fermer le scope fonctionnel alpha de `0.0.3` en implémentant le push Git provider-neutral gardé par l'état distant attendu. La tranche : - conserve la création locale de candidat acquise en `alpha.3.fix.1` ; - exige que le candidat soit encore retenu sous `refs/knowledge/candidates/` ; - observe la branche distante par `git ls-remote --refs origin ` ; - compare l'état observé à `GitRemoteState::Absent` ou `GitRemoteState::Revision(...)` ; - utilise `--force-with-lease=:` comme compare-and-exchange autoritaire ; - neutralise `remote.origin.mirror=true` uniquement pour la commande de push explicite du mirror ; - crée une branche uniquement lorsque l'absence est explicitement attendue ; - réobserve l'état distant après un rejet de push afin de produire un conflit récupérable en cas de divergence ; - implémente `knowledge_git_api::GitRepositoryWriter` sur `GitBackend` ; - ajoute des tests d'intégration avec remote bare local pour mise à jour, création et conflit sans écrasement. Aucun rebase/merge automatique, aucun force-push non gardé, aucune API de forge, aucun PostgreSQL et aucune orchestration applicative de proposition ne sont introduits. ## Scope des fichiers REPLACE : ```text VERSION Cargo.toml README.md crates/knowledge-git-lib/src/error.rs crates/knowledge-git-lib/src/lib.rs crates/knowledge-git-lib/src/write.rs docs/architecture/002-KNOWLEDGE_ARCHITECTURE.md docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md docs/validation/001-VALIDATION_MATRIX.md ``` ADD : ```text crates/knowledge-git-lib/tests/git_write_push.rs deltas/0.0.3/alpha.4.md ``` DELETE : aucun. `knowledge-git-api`, `knowledge-app-lib`, `Web/`, `CHANGELOG.md` et `ROADMAP.md` ne sont pas modifiés. Aucun history `alpha.4` n'est inclus dans ce delta. ## Compare-and-exchange distant Le chemin d'écriture complet devient : ```text base explicite -> candidat local retenu -> observation distante -> comparaison à l'état attendu -> push --force-with-lease exact -> Updated(candidate) ou Conflict { actual } ``` Pour une branche existante : ```text --force-with-lease=refs/heads/main: ``` Pour une branche qui doit être absente : ```text --force-with-lease=refs/heads/proposal: ``` L'observation préalable fournit un conflit rapide, mais elle n'est pas la garde de concurrence définitive. La lease est évaluée par Git au moment du push et protège la course entre observation et mise à jour distante. Un mirror créé avec `git clone --mirror` possède `remote.origin.mirror=true`. Le push de `alpha.4` fournit donc explicitement : ```text -c remote.origin.mirror=false ``` pour cette commande uniquement, afin d'autoriser le refspec ciblé sans transformer le mirror ou pousser toutes ses références internes. ## 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.4' grep -F 'version = "0.0.3-alpha.4"' 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.4-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 -p knowledge-git-lib --test git_write_candidate cargo test -p knowledge-git-lib --test git_write_push cargo test --workspace --all-targets --all-features ``` Les contrôles spécifiques sont volontairement courts et indépendants afin d'éviter les problèmes de copier/coller de blocs heredoc : ```bash grep -F 'PASS' history/0.0.3/alpha.3.fix.1.md grep -F 'pub fn push_candidate(' crates/knowledge-git-lib/src/write.rs grep -F -- '--force-with-lease=' crates/knowledge-git-lib/src/write.rs grep -F 'remote.origin.mirror=false' crates/knowledge-git-lib/src/write.rs grep -F 'GitOperation::InspectRemote' crates/knowledge-git-lib/src/write.rs grep -F 'GitOperation::PushCandidate' crates/knowledge-git-lib/src/write.rs grep -F 'impl knowledge_git_api::GitRepositoryWriter for crate::GitBackend' crates/knowledge-git-lib/src/write.rs grep -F 'guarded_push_updates_expected_branch_and_creates_only_expected_absent_branch' crates/knowledge-git-lib/tests/git_write_push.rs grep -F 'guarded_push_returns_conflict_after_concurrent_remote_change_without_overwrite' crates/knowledge-git-lib/tests/git_write_push.rs ! grep -F '## 0.0.3' CHANGELOG.md test ! -e history/0.0.3/alpha.4.md test ! -e crates/knowledge-forge-gitea-lib test ! -e crates/knowledge-store-postgres-lib test ! -e migrations test -z "$(git diff --name-only -- crates/knowledge-git-api crates/knowledge-app-lib Web CHANGELOG.md ROADMAP.md)" ``` Hygiène texte : ```bash python3 -c '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=[p for r in roots for p in ([r] if r.is_file() else r.rglob("*")) if p.is_file()]; bad=[str(p) for p in paths if (lambda b: b"\r" in b or not b.endswith(b"\n") or b.endswith(b"\n\n") or any(line != line.rstrip(" \t") for line in b.decode("utf-8").splitlines()))(p.read_bytes())]; print(f"Knowledge 0.0.3-alpha.4 text hygiene: clean ({len(paths)} file(s))") if not bad else (_ for _ in ()).throw(AssertionError(bad))' ``` Politique des lockfiles et staging : ```bash 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 : aucun fichier `Web/`, launcher ou contrat runtime Web n'est modifié. ## Transition ### PASS Produire `history/0.0.3/alpha.4.md`, l'appliquer, commit/push `0.0.3-alpha.4`, puis préparer `0.0.3-beta.1` pour réconciliation, revue d'horizon étendue et stabilisation. La revue d'horizon beta doit notamment réintroduire explicitement la trajectoire produit complète des trois sites PGR / Snippets / Howtos : templates publics et admin, prototypes Web, Actix Web, adaptation Maud, PostgreSQL, consultation/gestion et workflow de proposition/publication. ### FAIL / PARTIAL / BLOCKED Conserver le résultat réel dans son history avant toute correction. Une correction bornée utilise `alpha.4.fix.N` ; une remise en cause de la garantie compare-and-exchange, de la frontière provider-neutral ou du modèle de remote exige un `REPLAN` explicite.