0.0.4-alpha.2

This commit is contained in:
2026-10-01 11:00:00 +02:00
parent b55eb23dc0
commit 095ac37d08
19 changed files with 863 additions and 47 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/002-KNOWLEDGE_ARCHITECTURE.md -->
<!-- version: 19 -->
<!-- version: 20 -->
# Architecture de fondation Knowledge
@@ -36,7 +36,7 @@ knowledge-app-lib cas d'usage partagé de synchronisation Changed/Unchanged
Les deux crates `-api` sont justifiées par des implémentations réellement remplaçables ou multiples. Elles restent sans runtime, sans logging propre et sans dépendance à Actix, Gitea ou PostgreSQL.
`0.0.4-alpha.1` retient `knowledge-store-postgres-lib` comme prochain owner concret du pool, des migrations et de l'état PostgreSQL partagé. Cette crate n'est pas encore créée dans la tranche de cadrage et aucun `knowledge-store-api` symétrique n'est introduit sans besoin de substitution démontré.
`0.0.4-alpha.2` matérialise `knowledge-store-postgres-lib` comme owner concret du pool, des migrations et de l'état PostgreSQL partagé. La crate masque `tokio-postgres`, Deadpool et Refinery derrière sa façade publique et aucun `knowledge-store-api` symétrique n'est introduit sans besoin de substitution démontré.
Les tests unitaires Rust sont désormais placés hors de `src/` sous `unit_tests/`, conformément à la convention locale Knowledge sélectionnée sur l'option permise par PGR.
@@ -151,7 +151,7 @@ Les données générées résident hors du dépôt applicatif et hors des dépô
Le backend reçoit explicitement `<git-state-root>` ; il n'utilise aucun défaut implicite sous le workspace. Une variable de déploiement telle que `KNOWLEDGE_GIT_STATE_ROOT` pourra alimenter la composition, mais la librairie reçoit un chemin et ne lit pas elle-même l'environnement.
`source-key` est une clé sûre dérivée par l'implémentation. En `alpha.2`, elle encode de manière déterministe les octets UTF-8 du `SourceId` sous une forme hexadécimale préfixée ; un `SourceId` ou une URL remote ne sont jamais interpolés directement comme chemin de filesystem.
`source-key` est une clé sûre dérivée par l'implémentation Git. Depuis `0.0.2-alpha.2`, elle encode de manière déterministe les octets UTF-8 du `SourceId` sous une forme hexadécimale préfixée ; un `SourceId` ou une URL remote ne sont jamais interpolés directement comme chemin de filesystem.
Pendant `0.0.2`, une racine d'état appartient exclusivement à une instance backend/processus. Le partage simultané d'une même racine entre plusieurs processus reste `DEFER` jusqu'à matérialisation d'un verrouillage inter-processus.
@@ -250,7 +250,7 @@ Un webhook peut être perdu ou dupliqué. Le commit Git résolu reste l'identit
La synchronisation partagée est une responsabilité de couche application, distincte du backend Git et des producteurs de signaux. `0.0.2-alpha.5` confirme cette responsabilité et matérialise `knowledge-app-lib` comme owner du cas d'usage provider-neutral ; les launchers n'ont pas à dupliquer cette orchestration.
Sans PostgreSQL dans cette release, la dernière révision connue n'est pas stockée dans un fichier ad hoc caché. Le cas d'usage reçoit `previous_revision` de l'appelant et retourne explicitement la révision observée ainsi qu'un résultat `Changed` ou `Unchanged`. La future persistance pourra remplacer cet état appelant sans modifier la frontière Git.
Le cas d'usage de synchronisation existant continue de recevoir `previous_revision` de l'appelant et retourne explicitement la révision observée ainsi qu'un résultat `Changed` ou `Unchanged`. `0.0.4-alpha.2` matérialise seulement le store et le schéma ; le raccord de cette persistance au cas d'usage reste réservé à `alpha.4`, sans modifier la frontière Git.
La cause `Periodic` reste supportée par `knowledge-sync-api`, mais `0.0.2-alpha.1` ne désigne pas encore de scheduler concret. Un scheduler n'est matérialisé que si son lifecycle/runtime est démontré ; lorsqu'il existe, il appelle exactement le même cas d'usage que la voie explicite.
@@ -302,28 +302,28 @@ La baseline retient **une base PostgreSQL logique partagée** par les trois appl
Ce choix est justifié par l'état transversal : identités, sessions, propositions, synchronisation, relations entre familles, index et recherche. Il évite trois bases divergentes pour des concepts qui appartiennent à la même plateforme.
### Fondation sélectionnée pour `0.0.4`
### Fondation matérialisée pour `0.0.4`
`0.0.4-alpha.1` sélectionne `tokio-postgres` comme driver PostgreSQL async natif, `deadpool-postgres` comme pool et Refinery comme mécanisme de migrations. La future crate `knowledge-store-postgres-lib` possédera la composition de ces trois responsabilités, la conversion de leurs erreurs en erreurs publiques récupérables et les opérations PostgreSQL concrètes. Knowledge ne sélectionne pas d'ORM, ne recherche pas d'abstraction multi-SGBD et n'introduit pas de `knowledge-store-api` tant qu'une seconde implémentation de stockage ou une frontière passive réellement indépendante n'est pas démontrée.
`0.0.4-alpha.1` sélectionne le toolkit ; `0.0.4-alpha.2` matérialise `knowledge-store-postgres-lib` avec `tokio-postgres 0.7.18`, `deadpool-postgres 0.14.2` et Refinery `0.9.2`. La façade publique reste limitée à `PostgresStoreConfig`, `PostgresStore` et `PostgresStoreError`. Les types du driver, du pool et du migrator ne remontent ni dans le domaine ni dans les contrats applicatifs, et aucun `knowledge-store-api` symétrique n'est introduit sans seconde implémentation démontrée.
La configuration est injectée par la composition : la crate de stockage reçoit une URL/options de connexion et des paramètres de pool. Elle ne lit pas directement les variables d'environnement du processus et ne journalise jamais l'URL ou les credentials. Une connexion ou migration impossible retourne une erreur ; aucun fallback fichier/mémoire ne masque l'indisponibilité PostgreSQL.
La configuration est injectée par la composition : la crate reçoit une URL PostgreSQL et une taille maximale de pool. Elle ne lit pas directement les variables d'environnement du processus, n'expose pas l'URL par son API publique et ne journalise jamais l'URL ou les credentials. Une configuration invalide, une acquisition de pool ou une migration impossible produit une erreur récupérable ; aucun fallback fichier/mémoire ne masque l'indisponibilité PostgreSQL. La première implémentation utilise `tokio_postgres::NoTls`; un backend TLS ne sera ajouté que lorsqu'une cible de déploiement le justifiera.
Le premier schéma utile est volontairement borné :
```text
knowledge_sources
source_id TEXT PRIMARY KEY
family TEXT NOT NULL
git_reference TEXT NOT NULL
family TEXT NOT NULL CHECK (pgr/howto/snippet/project_local)
git_reference TEXT NOT NULL
knowledge_source_sync_state
source_id TEXT PRIMARY KEY REFERENCES knowledge_sources(source_id)
source_id TEXT PRIMARY KEY REFERENCES knowledge_sources(source_id) ON DELETE CASCADE
last_synchronized_revision TEXT NOT NULL
```
`family` reste aligné sur `ContentFamily` et sera contraint aux valeurs supportées par le domaine. `git_reference` est la référence Git logique à suivre ; la localisation physique locale/remote et les credentials restent hors de cette table et sous les frontières de configuration appropriées. La dernière révision synchronisée est un état applicatif, pas une nouvelle autorité de contenu : elle peut être reconstruite/réconciliée à partir de Git et une valeur obsolète provoque au pire une resynchronisation.
`git_reference` est la référence Git logique à suivre ; la localisation physique locale/remote et les credentials restent hors de cette table et sous les frontières de configuration appropriées. La dernière révision synchronisée est un état applicatif, pas une nouvelle autorité de contenu : elle peut être reconstruite/réconciliée à partir de Git et une valeur obsolète provoque au pire une resynchronisation.
Les migrations sont des fichiers SQL versionnés placés sous l'owner de stockage et appliqués explicitement par Refinery. La stratégie de test utilise une URL PostgreSQL de test fournie explicitement et un schéma unique éphémère par exécution ; la gate doit être `BLOCKED` si le service PostgreSQL requis n'est pas disponible, jamais convertir cette absence en test artificiellement passé. Le même mécanisme peut cibler un PostgreSQL local ou un service PostgreSQL éphémère de CI sans rendre Docker obligatoire pour la bibliothèque.
La migration `V1__initial_sources.sql` est embarquée au build et appliquée uniquement via `PostgresStore::apply_migrations`; Refinery conserve son historique dans PostgreSQL. Le test d'intégration réel reste `#[ignore]` pour ne pas transformer tout `cargo test` en dépendance externe implicite. La gate PostgreSQL vérifie explicitement `KNOWLEDGE_POSTGRES_TEST_URL`, crée un schéma unique, borne le `search_path` de la connexion du store, exécute la migration, vérifie `knowledge_sources`, `knowledge_source_sync_state` et `refinery_schema_history`, puis supprime le schéma. L'absence du service requis rend la gate `BLOCKED`.
PostgreSQL MAY contenir ultérieurement des documents/index/métadonnées dérivés et assurer une première capacité de recherche. Le corps publié et ses métadonnées éditoriales autoritaires restent dans Git. `0.0.4` ne matérialise pas encore le parsing/projection final prévu par l'horizon `0.0.5`.