# Plan 0.0.3 — écriture Git contrôlée et push gardé ## Statut et sources Plan historique de la stable `0.0.3`, ouverte depuis la stable Knowledge `v0.0.2` publiée et vérifiée. Sources autoritaires de reprise : ```text Knowledge tag stable v0.0.2 Knowledge commit stable 183d354a67bec6d2d512c4898f5189759a6120b0 Knowledge archive SHA-256 0e518c7eaad115811cccc8fb2b38a1e68150ec985c2ca72ec08a9ca5bbb202ce Knowledge publish report sasedev-knowledge-0.0.2-publish.001-report.md = PASS Knowledge start prompt prompts/003-V0_0_3_START_PROMPT.md ``` PGR `v0.1.3` reste une provenance historique de l'adoption fermée pendant `0.0.2`. Aucune version PGR plus récente n'est une source de cette release et aucune réévaluation PGR n'est engagée. `0.0.3-alpha.1` et `alpha.1.fix.1` sont conservées `PARTIAL` avec leurs preuves réelles. `alpha.1.fix.2` a complété la gate documentaire et technique en `PASS`. `alpha.2` a matérialisé le contrat d'écriture provider-neutral en `PASS`. `alpha.3` reste historisée `FAIL` pour son défaut de test `E0369`; `alpha.3.fix.1` a corrigé uniquement cette assertion en `PASS`. `alpha.4` a fermé le scope fonctionnel alpha en `PASS` avec push gardé, création de branche sous attente d'absence et conflit concurrent sans écrasement. `beta.1` a réconcilié l'état acquis, préparé le changelog candidat, rejoué la non-régression Rust/Web et effectué la revue d'horizon produit en `PASS`. `rc.1` a rejoué toutes les preuves produit/runtime mais reste historisée `FAIL` pour une assertion lexicale de statut ; `rc.1.fix.1` a corrigé uniquement cette preuve en `PASS`. `rel.1` est la tranche courante de promotion mécanique pré-tag vers la stable `0.0.3`. ## Mission `0.0.3` doit étendre le backend Git générique de Knowledge avec une capacité d'écriture contrôlée, indépendante d'une forge, capable de produire une révision candidate puis de mettre à jour une branche distante uniquement si son état précédent correspond encore à l'attente de l'appelant. Le chemin cible est : ```text source Git configurée -> base commit explicite -> worktree d'écriture isolé -> mutations de fichiers confinées -> commit avec identité explicite -> révision candidate -> push gardé vers refs/heads/... -> succès ou conflit explicite ``` La release fournit une primitive Git réutilisable aux futurs workflows de proposition/publication ; elle n'implémente pas encore ces workflows produit. ## État acquis et questions ouvertes Acquis par `0.0.2` : - Git reste la source autoritaire du contenu publié ; - `knowledge-git-api::GitRepository` possède le contrat provider-neutral de lecture ; - `knowledge-git-lib` possède la configuration physique, les mirrors, refresh, résolution et snapshots ; - les opérations Git sont lancées sans shell, avec prompts interactifs désactivés et erreurs publiques redacted ; - les snapshots de lecture sont adressés par révision et vérifiés avant réutilisation ; - `knowledge-app-lib` possède uniquement le cas d'usage de synchronisation `Changed` / `Unchanged` ; - Gitea, PostgreSQL, auth/admin et workflow complet de proposition restent différés. Décisions prises par l'étude `006` : - conserver le processus `git` contrôlé ; - utiliser un worktree d'écriture isolé plutôt qu'une nouvelle implémentation Git ou un moteur plumbing complet ; - introduire un contrat d'écriture distinct de `GitRepository` afin de préserver les consommateurs lecture seule ; - limiter `0.0.3` aux branches `refs/heads/...` ; - utiliser une attente explicite sur l'état distant pour empêcher l'écrasement concurrent ; - traiter une divergence comme conflit récupérable, sans rebase/merge automatique ; - ne créer aucune nouvelle crate tant qu'un owner distinct n'est pas démontré. Décisions d'implémentation désormais résolues dans les alphas : - mutations publiques provider-neutral matérialisées dans `knowledge-git-api` ; - worktree d'écriture backend déterministe sous `write-worktrees//candidate` ; - candidats retenus sous `refs/knowledge/candidates/` ; - conflits distants représentés par `GitPushOutcome::Conflict`, séparés des erreurs process ; - garde distante matérialisée par observation `ls-remote` puis `push --force-with-lease` exact ; - `remote.origin.mirror=true` neutralisé uniquement sur le push ciblé afin de ne jamais publier toutes les refs internes du mirror. ## Scope La release couvre : - contrat passif d'écriture Git dans `knowledge-git-api`, séparé du contrat de lecture ; - création/modification/suppression de fichiers par chemins relatifs validés ; - worktree d'écriture sous la racine d'état contrôlée, séparé des snapshots de lecture ; - commit à partir d'une base `GitRevision` explicite ; - identité auteur/committer et message fournis explicitement ; - neutralisation des hooks et de la configuration Git ambiante pertinente ; - résultat de révision candidate explicite ; - push vers une branche générique avec garde sur l'état distant attendu ; - conflit explicite et non destructif en cas de divergence ; - tests unitaires et d'intégration locaux couvrant sécurité de chemin, commit, push et concurrence ; - documentation durable des invariants réellement matérialisés. ## Hors scope `0.0.3` n'introduit pas : - API Gitea/GitHub/GitLab, webhook, pull/merge request ou release de forge ; - rebase/merge automatique ; - workflow complet de proposition/revue, commentaires ou audit applicatif ; - PostgreSQL, migrations ou persistance de dernière révision ; - auth/admin ou modèle rôles/capabilities ; - route HTTP d'écriture ou UI d'administration ; - modification du rendu public ou du package Web ; - signature de commits ; - Git LFS/submodules ; - partage concurrent de la racine d'état Git entre plusieurs processus ; - formats finaux HOWTO/snippet ; - scheduler/job de publication. ## Stratégie de validation Les alphas fonctionnelles privilégient les preuves Git locales et ciblées : ```text cargo fmt --all cargo fmt --all -- --check -> audits Rust structurels applicables -> cargo metadata / cargo check -> clippy strict -> tests ciblés knowledge-git-api / knowledge-git-lib -> tests d'intégration avec repositories temporaires locaux/bare -> tests workspace lorsque la frontière publique ou le workspace change ``` Les tests d'écriture ne nécessitent ni Internet ni forge. Ils créent leur propre repository source/remote temporaire et fournissent explicitement l'identité de commit. `Web/` reste hors scope alpha ; npm/Vite ne sont pas rejoués par défaut sans diff Web. La phase beta/RC pourra imposer la non-régression runtime globale conformément à l'owner de validation. La gate de `alpha.1` reste une gate de cadrage : elle valide baseline, documentation, version, audits et non-régression du workspace existant, sans prétendre tester une implémentation d'écriture encore absente. ## Trajectoire prévisionnelle ### alpha.1 — baseline, étude et cadrage - vérifier la stable `v0.0.2` et son rapport post-tag ; - confirmer l'autonomie normative Knowledge sans nouvelle consultation PGR ; - réconcilier les `DEFER` avec la prochaine mission ; - produire l'étude `006` ; - engager `0.0.3` et établir un premier horizon au-delà d'elle ; - mettre à jour les owners/architecture vivants nécessaires ; - établir le présent plan ; - créer exceptionnellement `prompts/003-V0_0_3_START_PROMPT.md` comme rattrapage, puisque `0.0.2` avait été fermée sans prochaine mission décidée ; - ne modifier aucun code sous `crates/` ni `Web/`. ### alpha.1.fix.1 — correction du cycle documentaire - conserver `alpha.1` comme `PARTIAL` sans réécrire ses preuves ; - retirer du changelog l'entrée candidate écrite prématurément ; - faire de la roadmap une vue de la release en cours plus un horizon prévisionnel borné ; - codifier que le changelog est rédigé vers la stabilisation à partir des changements réellement acquis ; - codifier que le prompt de `N+1` est normalement préparé pendant les dernières phases de `N`, après revue d'horizon ; - garder `prompts/003-V0_0_3_START_PROMPT.md` comme rattrapage historique valide ; - ne modifier aucun code sous `crates/` ni `Web/`. ### alpha.1.fix.2 — complétion de la preuve opérateur - conserver `alpha.1.fix.1` comme `PARTIAL` sans réécrire les preuves observées ; - ne modifier aucune décision fonctionnelle du cadrage ; - rejouer la gate utile et terminer explicitement les assertions documentaires, l'hygiène texte, l'invariance `crates/` / `Web/`, la politique `Cargo.lock` et le staging ; - ne modifier aucun code sous `crates/` ni `Web/` ; - autoriser `alpha.2` uniquement après un `PASS` complet. ### alpha.2 — contrat d'écriture provider-neutral - étendre `knowledge-git-api` avec un contrat distinct du `GitRepository` de lecture ; - matérialiser uniquement les types nécessaires aux mutations, identité de commit, branche cible, état attendu et résultat ; - valider strictement les chemins relatifs et les branches `refs/heads/...` ; - préserver les implémentations/fakes lecture seule sans leur imposer des méthodes d'écriture ; - ne pas effectuer encore de push distant réel si le découpage de la tranche devient disproportionné. ### alpha.3 — worktree d'écriture et commit candidat - partir de `alpha.2 = PASS` historisé et committé ; - matérialiser dans `knowledge-git-lib` un worktree d'écriture isolé dérivé d'une base résolue ; - appliquer create/update/delete sous confinement et refuser les traversées par symlink ; - neutraliser la configuration Git système/globale pertinente et les hooks ; - créer un commit avec identité auteur/committer explicite ; - vérifier que le candidat a exactement la base demandée comme parent ; - retenir le candidat sous une référence backend interne sans mettre à jour de branche distante ; - nettoyer l'état temporaire de manière déterministe sans supprimer silencieusement un worktree préexistant. ### alpha.3.fix.1 — correction de l'assertion du test candidat - conserver `alpha.3 = FAIL` avec la preuve exacte de compilation `E0369` ; - ne modifier aucun code produit de `knowledge-git-lib` ni aucun contrat public ; - remplacer uniquement l'assertion invalide sur `Result` par une vérification du cas `Ok("first\n")` qui n'exige pas `PartialEq` sur `std::io::Error` ; - rejouer Clippy, le test `git_write_candidate` et les tests workspace ; - autoriser `alpha.4` uniquement après `PASS` complet du fix. ### alpha.4 — push gardé et concurrence - partir de `alpha.3.fix.1 = PASS` historisé et committé ; - observer l'état de la branche distante via le remote générique `origin` ; - exiger que la révision candidate soit encore retenue par le backend ; - pousser la révision candidate uniquement si la cible correspond à l'attente explicite ; - utiliser `--force-with-lease` comme garde compare-and-exchange autoritaire ; - gérer création de branche lorsque l'absence est attendue ; - réobserver après rejet afin de produire un conflit récupérable en cas de divergence concurrente ; - implémenter `GitRepositoryWriter` sur `GitBackend` maintenant que create + push sont disponibles ; - prouver l'absence d'écrasement par tests d'intégration avec remote bare local ; - fermer le scope fonctionnel alpha sans ajouter workflow de proposition ou forge. ### beta.1 — réconciliation et revue d'horizon - partir de `alpha.4 = PASS` historisé et committé ; - réconcilier contrats, implémentation et documentation durable sans modifier `crates/` ni `Web/` ; - préparer `CHANGELOG.md` en état `0.0.3 (candidate)` à partir des capacités réellement acquises ; - vérifier les `DEFER` encore valides et reclasser la prochaine dépendance structurante ; - retenir `0.0.4` comme fondation PostgreSQL partagée, sans préchoisir driver/ORM avant son étude de démarrage ; - étendre l'horizon jusqu'aux phases de modèles/projections, templates publics, templates admin, intégration Actix/Maud et workflow de gestion/proposition/publication des trois sites ; - produire l'étude durable `007-V0_0_3_GIT_WRITE_RECONCILIATION.md` ; - préparer `prompts/004-V0_0_4_START_PROMPT.md` pendant cette stabilisation, sans inventer commit/tag/SHA postérieurs de `v0.0.3` ; - rejouer la non-régression Rust et Web utile à la stabilisation ; - n'introduire aucune fonctionnalité PostgreSQL, Web, auth, forge ou proposition dans `0.0.3`. ### rc.1 — candidate stable - geler le scope ; - rejouer la gate complète applicable à la release ; - vérifier reproductibilité des tests Git d'écriture locaux, intégrité des deltas/histories, Cargo/Clippy/tests et non-régression Web/runtime prévue par la phase ; - n'introduire aucune nouvelle fonctionnalité. ### rc.1.fix.1 — correction de la vérification des statuts historiques - conserver `rc.1 = FAIL` avec la preuve exacte de l'assertion lexicale trop stricte ; - ne réécrire aucun history antérieur, en particulier `alpha.1` dont le statut historique est écrit `` `PARTIAL` `` ; - normaliser uniquement la lecture du statut lors des gates afin d'accepter la présentation Markdown existante ; - ne modifier aucun fichier sous `crates/`, `Web/`, `CHANGELOG.md`, `ROADMAP.md`, `docs/architecture/`, `docs/studies/`, `docs/rules/` ou `prompts/` ; - rejouer les contrôles documentaires, Cargo/Clippy/tests et la cohérence RC nécessaires à ce fix ; - autoriser `rel.1` uniquement après `PASS` complet du fix. ### rel.1 — promotion stable pré-tag - promouvoir mécaniquement `VERSION` et le workspace vers `0.0.3` ; - finaliser le changelog à partir du scope réellement acquis ; - fermer roadmap/plan sans nouveau scope et vérifier que le handoff de la prochaine release décidée est déjà présent ; - rejouer la gate stable prévue ; - produire le history observé avant commit produit/tag ; - ne fabriquer aucun rapport post-tag avant publication réelle. ### rel.1.fix.1 — complétion de la preuve de clôture stable - conserver `rel.1 = PARTIAL` avec toutes les preuves produit/runtime réellement acquises ; - ne modifier aucun code produit, frontend, changelog, roadmap, architecture, étude, règle ou prompt ; - compléter explicitement l'audit de composition du workspace à partir du JSON `cargo metadata` déjà prévu par la gate ; - compléter explicitement l'audit d'hygiène texte sur les documents gouvernés ; - réutiliser les preuves Cargo/Clippy/tests, Web et smokes HTTP `PASS` de `rel.1` puisqu'aucun fichier concerné n'est modifié ; - autoriser le premier commit stable `0.0.3` uniquement après `PASS` complet de ce fix. ## Déclencheurs de REPLAN REPLAN avant de poursuivre si : - le contrat d'écriture exige de casser le contrat de lecture existant au lieu de rester séparé ; - le push gardé ne peut pas garantir l'absence d'écrasement avec une attente explicite ; - l'implémentation nécessite une forge spécifique ; - un besoin de rebase/merge automatique devient nécessaire pour fermer la mission ; - l'écriture révèle une responsabilité de persistance PostgreSQL indispensable à la correction du backend lui-même ; - le cycle de vie des worktrees exige un owner/processus distinct ; - le partage multi-processus de la racine d'état devient nécessaire ; - la stratégie process Git actuelle devient inadéquate pour une raison mesurée ; - une tranche atteint `.fix.3`, conformément à la gouvernance locale. La conclusion du REPLAN doit utiliser `CONTINUE`, `SPLIT`, `CONTINUE-NEXT-SESSION` ou `ABANDON`. ## Clôture et transition La release est fermable lorsque : - l'écriture produit une révision candidate à partir d'une base explicite ; - les mutations restent confinées au worktree contrôlé ; - le commit n'utilise ni hooks ni identité Git ambiante ; - la mise à jour distante est gardée contre une révision attendue ou une absence attendue ; - une divergence produit un conflit sans écrasement ; - les tests locaux réels couvrent les chemins critiques ; - les règles/architecture décrivent l'état effectivement obtenu ; - beta et RC ont fermé les non-régressions prévues. Le `PARTIAL` de `alpha.1` a autorisé `0.0.3-alpha.1.fix.1`. Le premier fix est resté `PARTIAL`, puis `alpha.1.fix.2` a fermé la preuve en `PASS`. `alpha.2` a matérialisé le contrat d'écriture provider-neutral en `PASS`. `alpha.3` est conservée `FAIL` à cause de l'assertion de test `E0369`; `alpha.3.fix.1` a corrigé uniquement le test en `PASS`. `alpha.4` a ensuite fermé le scope fonctionnel alpha en `PASS`. `beta.1` a stabilisé et réconcilié cet état en `PASS`, sans nouveau code produit. `rc.1` a confirmé toutes les preuves produit/runtime mais reste `FAIL` à cause d'une assertion lexicale trop stricte sur le statut historique `alpha.1`. `rc.1.fix.1` a corrigé uniquement cette preuve en `PASS`. `rel.1` a acquis toutes les preuves produit/runtime de la promotion stable mais reste `PARTIAL` parce que deux contrôles annoncés — composition exacte du workspace et hygiène texte — ne figurent pas dans le transcript. `rel.1.fix.1` ferme uniquement ces deux preuves avant le premier commit stable réellement `PASS`. ## Revue d'horizon La revue `0.0.3-beta.1` remplace l'horizon initial trop centré sur les seules briques backend. La prochaine mission engagée par la promotion stable est : ```text 0.0.4 fondation PostgreSQL partagée et migrations ``` L'horizon produit devient ensuite : ```text 0.0.5 modèles de contenu et projections PGR/HOWTO/snippet 0.0.6 templates publics des trois sites, pages de garde incluses 0.0.7 templates d'administration des trois sites 0.0.8 routes publiques Actix Web + adaptation Maud 0.0.9 auth/autorisation + routes admin Actix Web + adaptation Maud 0.0.10 gestion/proposition/revue/publication Git + PostgreSQL ``` Ces versions après `0.0.4` restent des horizons révisables. Elles rendent cependant explicite l'objectif produit : trois sites distincts PGR, HOWTOs et snippets, chacun avec lecture publique et gestion, partageant Git comme vérité éditoriale, PostgreSQL comme état/projection applicative et un pipeline de templates Web validés avant adaptation runtime en Maud. Recherche avancée, adapters de forge, webhooks forge-only, scheduler, administration transverse, opérations multi-domaines, Git LFS/submodules et partage multi-processus restent non numérotés tant qu'un besoin réel ne les engage pas. `prompts/004-V0_0_4_START_PROMPT.md` a été préparé pendant `beta.1` conformément au cycle normal de handoff. La stable `0.0.3` le conserve : au prochain démarrage il exigera l'archive taggée réelle `v0.0.3` et son rapport post-tag, sans avoir inventé à l'avance le commit stable ou le SHA-256.