# Étude 0.0.3 — écriture Git contrôlée ## Objet Cette étude ouvre `0.0.3` depuis la stable autoritaire `v0.0.2` et détermine le prochain incrément utile après le chemin Git générique de lecture matérialisé en `0.0.2`. Elle s'appuie uniquement sur les règles, l'architecture, la roadmap, les décisions différées et les preuves locales Knowledge. PGR `v0.1.3` reste une provenance historique d'adoption et aucune version PGR plus récente n'est consultée ou adoptée pour cette décision. ## Baseline observée La stable de départ est : ```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 ``` `0.0.2` fournit déjà : ```text source locale/remote -> mirror contrôlé -> refresh avec pruning -> résolution vers commit -> snapshot/worktree de lecture -> synchronisation Changed / Unchanged ``` Le backend process Git contrôlé et les contrats provider-neutral sont donc acquis avant toute nouvelle capacité d'écriture. ## Revue des axes différés La revue d'horizon `0.0.2-beta.1` laisse notamment ouverts : - écriture Git contrôlée et publication ; - PostgreSQL et migrations ; - workflow complet de proposition/revue ; - parsing final HOWTO/snippet ; - recherche/indexation ; - adapter Gitea ; - auth/admin complète ; - scheduler concret ; - rétention de snapshots et partage multi-processus. Le prochain axe doit apporter une capacité réellement réutilisable sans forcer plusieurs de ces décisions à la fois. ## Choix de la prochaine mission La mission retenue est l'**écriture Git générique contrôlée avec mise à jour distante gardée**. Ce choix est retenu parce qu'il : - prolonge directement les responsabilités déjà matérialisées dans `knowledge-git-api` et `knowledge-git-lib` ; - reste testable avec des repositories locaux et remotes bare temporaires, sans service externe ; - conserve la forge optionnelle ; - fournit la primitive nécessaire aux futurs workflows de proposition/publication sans implémenter prématurément leur état PostgreSQL, leurs rôles ou leur UI ; - évite de sélectionner maintenant un driver/ORM PostgreSQL alors que l'écriture Git peut être fermée indépendamment ; - transforme un `DEFER` explicitement identifié en une mission bornée sans absorber rebase/merge automatique ni publication produit complète. `0.0.3` est donc le prochain incrément SemVer engagé. ## Stratégies d'écriture considérées ### A — worktree d'écriture isolé + commandes Git usuelles Séquence conceptuelle : ```text base commit explicite -> worktree d'écriture isolé sous la racine d'état -> mutations de fichiers validées -> git add -> commit avec identité explicite et hooks neutralisés -> révision candidate -> push gardé vers une branche autorisée -> suppression contrôlée du worktree temporaire ``` Avantages : - comportement proche de Git utilisé manuellement et facile à diagnostiquer ; - réutilise le backend process déjà choisi et validé ; - permet des tests locaux réalistes ; - rend les mutations de fichiers et leur diff inspectables ; - n'introduit pas de nouvelle bibliothèque Git. Risques : - cycle de vie d'un worktree temporaire à posséder explicitement ; - validation stricte des chemins de mutation nécessaire ; - nettoyage après erreur à traiter sans suppression destructive ambiguë. ### B — construction de commits par commandes Git plumbing Une implémentation fondée sur `hash-object`, index temporaire, `write-tree` et `commit-tree` éviterait un worktree d'écriture classique. Avantages : - état filesystem potentiellement plus réduit ; - contrôle fin de la construction du commit. Inconvénients : - complexité sensiblement supérieure pour les mutations multi-fichiers, suppressions et futurs cas de validation ; - risque d'introduire une mini-couche Git plumbing difficile à maintenir alors que le projet possède déjà un modèle worktree pour la lecture ; - bénéfice non démontré à ce stade. ### C — réouverture du choix `gix`/`git2` Changer de backend uniquement pour l'écriture n'est pas retenu. `0.0.2` a déjà validé le processus `git` contrôlé comme implémentation locale remplaçable derrière le contrat. Une seconde implémentation demanderait une preuve de besoin distincte. ## Décision technique `0.0.3` retient la stratégie A : **worktree d'écriture isolé piloté par le processus `git` existant**. La capacité d'écriture reste séparée de la lecture dans l'API publique : `GitRepository` n'est pas transformé en interface obligatoire d'écriture pour tous ses implémenteurs. `knowledge-git-api` introduira un contrat d'écriture distinct uniquement lorsque `alpha.2` matérialisera les types nécessaires. Aucune nouvelle crate n'est justifiée par le cadrage. L'implémentation appartient à `knowledge-git-lib` et l'orchestration métier future reste dans `knowledge-app-lib` lorsqu'un vrai cas d'usage de proposition/publication sera engagé. ## Invariants de sécurité et de cohérence L'implémentation doit respecter les invariants suivants : - aucune commande Git via shell ; - prompts interactifs désactivés ; - hooks neutralisés pour les opérations possédées par le backend ; - identité auteur/committer fournie explicitement, sans dépendre de la configuration Git globale de la machine ; - base d'écriture obligatoirement une `GitRevision` déjà résolue ; - chemins de mutation obligatoirement relatifs, normalisés et confinés au worktree ; - chemins absolus, composants `..`, accès `.git` et échappement par symlink refusés ; - aucune mutation du snapshot de lecture stable ; - aucune suppression/réinitialisation silencieuse d'un état inattendu ; - le résultat d'écriture est une nouvelle révision Git explicite avant toute mise à jour distante ; - la mise à jour distante porte uniquement sur une branche `refs/heads/...` dans `0.0.3` ; - la branche distante est mise à jour avec une attente explicite sur son état précédent ; une divergence devient un conflit récupérable ; - aucun `push --force` non gardé ; - aucun rebase ou merge automatique pour masquer une divergence ; - les erreurs publiques ne divulguent ni URL remote, ni credentials, ni arguments sensibles, ni stderr brut. ## Modèle de concurrence retenu Le push doit utiliser une sémantique de comparaison-et-échange : ```text expected remote revision + candidate revision + target branch -> refresh/observation -> push gardé -> succès seulement si la cible possède encore l'état attendu ``` Pour une nouvelle branche, l'état attendu est l'absence de branche. Pour une branche existante, l'état attendu est une révision explicite. Une divergence n'entraîne ni rebase ni écrasement automatique. Le futur workflow de proposition décidera comment présenter et résoudre ce conflit. ## Scope fonctionnel proposé pour 0.0.3 La release doit fournir : - un contrat d'écriture Git distinct et provider-neutral ; - des types de mutation de fichiers suffisamment bornés pour créer/modifier/supprimer un contenu ; - un worktree d'écriture isolé dérivé d'une révision de base ; - un commit avec message et identité explicites ; - une révision candidate vérifiée ; - un push vers une branche Git générique avec garde sur l'état distant attendu ; - un résultat de conflit explicite lorsque la branche distante a divergé ; - des tests d'intégration sur repositories locaux/bare temporaires couvrant succès, création de branche, modification, suppression, conflit et redaction. ## Hors scope confirmé Restent différés : - workflow complet de proposition/revue ; - publication directe déclenchée par une requête utilisateur ; - rebase/merge automatique ; - pull/merge request de forge ; - adapter Gitea ; - PostgreSQL, migrations et persistance des propositions ; - auth/admin complète ; - signature GPG/SSH des commits ; - Git LFS/submodules ; - partage concurrent d'une même racine d'état entre plusieurs processus ; - scheduler et jobs de publication ; - formats finaux HOWTO/snippet. ## Ownership ```text knowledge-git-api contrat passif d'écriture Git distinct du contrat de lecture knowledge-git-lib worktree d'écriture, mutations, commit, push gardé et erreurs redacted knowledge-app-lib inchangée tant qu'aucun cas d'usage produit de proposition/publication n'est matérialisé ``` Aucune `knowledge-forge-gitea-lib`, `knowledge-store-postgres-lib` ou autre crate candidate n'est créée par cette release uniquement pour préparer l'avenir. ## Validation attendue Les preuves fonctionnelles doivent utiliser des repositories Git temporaires locaux et un remote bare local. Elles ne doivent dépendre ni d'Internet, ni de Gitea, ni d'un compte utilisateur Git préconfiguré. La validation devra notamment démontrer : - qu'un commit candidat est descendant de la base attendue ; - qu'un fichier hors worktree ne peut pas être modifié ; - qu'une branche absente peut être créée seulement lorsque l'appelant attend explicitement son absence ; - qu'une branche existante peut avancer lorsque sa révision correspond à l'attente ; - qu'une divergence concurrente produit un conflit sans écrasement ; - que l'identité de commit ne provient pas de la configuration globale ; - que les hooks ne s'exécutent pas ; - que les erreurs restent expurgées. ## Conclusion `0.0.3` est engagée comme release d'écriture Git contrôlée et push gardé. Le cadrage ne justifie aucun changement de forge, de base de données, d'authentification ou de rendu Web.