Files
sasedev-knowledge/docs/plans/003-V0_0_3_GIT_WRITE_PLAN.md
2026-09-29 19:00:14 +02:00

18 KiB

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 :

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 :

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/<source-key>/candidate ;
  • candidats retenus sous refs/knowledge/candidates/<revision> ;
  • 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 :

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<String, std::io::Error> 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 :

0.0.4  fondation PostgreSQL partagée et migrations

L'horizon produit devient ensuite :

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.