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/001-PROJECT_PROFILE.md -->
<!-- version: 19 -->
<!-- version: 20 -->
# Profil du projet Knowledge
@@ -131,15 +131,12 @@ knowledge-web-lib composition Actix/Maud/Vite partagée
knowledge-pgr-server launcher PGR mince
knowledge-howtos-server launcher HOWTOs mince
knowledge-snippets-server launcher snippets mince
knowledge-store-postgres-lib pool, migrations et état applicatif PostgreSQL partagé
```
`knowledge-git-lib` devient réelle en `0.0.2-alpha.2` puis implémente le chemin de lecture Git dans `alpha.3`. `knowledge-app-lib` devient réelle en `0.0.2-alpha.5` : l'orchestration refresh / résolution / comparaison / snapshot confirme une responsabilité application partagée distincte du backend Git et des launchers.
`0.0.4-alpha.1` retient comme prochaine responsabilité réelle, sans encore la matérialiser dans cette tranche :
```text
knowledge-store-postgres-lib pool, migrations et état applicatif PostgreSQL partagé
```
`0.0.4-alpha.2` matérialise `knowledge-store-postgres-lib` comme responsabilité réelle : configuration explicite, pool `deadpool-postgres`, migrations Refinery et premier schéma partagé. Aucun `knowledge-store-api` symétrique n'est introduit.
Les responsabilités suivantes restent candidates et non matérialisées :
@@ -192,17 +189,17 @@ Après publication vérifiée de `v0.0.3`, `0.0.4-alpha.1` consomme les `DEFER`
La décision locale est :
```text
owner prévu knowledge-store-postgres-lib
driver tokio-postgres 0.7
owner knowledge-store-postgres-lib
driver tokio-postgres 0.7.18
modèle SQL explicite, sans ORM
pool deadpool-postgres 0.14
migrations SQL versionné + Refinery 0.9
pool deadpool-postgres 0.14.2
migrations SQL versionné + Refinery 0.9.2
premier état source logique + dernière révision synchronisée
autorité contenu Git
```
Aucune crate n'est créée pendant `alpha.1`. La tranche établit seulement l'étude et le plan qui autoriseront `alpha.2` après gate opérateur `PASS`.
`alpha.2` matérialise cette décision avec une façade crate-root limitée à `PostgresStoreConfig`, `PostgresStore` et `PostgresStoreError`, plus `V1__initial_sources.sql`. La configuration est injectée ; la crate ne lit pas `KNOWLEDGE_POSTGRES_TEST_URL` ni une autre variable d'environnement. La première connexion utilise `NoTls` et un backend TLS reste différé tant qu'un déploiement n'en démontre pas le besoin.
La configuration physique Git reste possédée par `knowledge-git-lib`. Le premier schéma PostgreSQL ne stocke pas de credentials Git et ne transforme pas les URLs/paths physiques en vérité métier. La configuration de connexion PostgreSQL est injectée par la composition, non lue implicitement par la future crate de stockage.
La configuration physique Git reste possédée par `knowledge-git-lib`. Le premier schéma PostgreSQL ne stocke pas de credentials Git et ne transforme pas les URLs/paths physiques en vérité métier.
Les `DEFER` Gitea/forge, scheduler, recherche avancée, auth/capabilities, formats finaux de contenu, quatrième application admin, partage multi-processus de racine Git, LFS/submodules et rétention avancée restent inchangés. L'horizon `0.0.5` à `0.0.10` reste cohérent et n'est pas replanifié par cette étude.

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`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/004-V0_0_4_POSTGRES_FOUNDATION_PLAN.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Plan 0.0.4 — fondation PostgreSQL partagée
@@ -43,12 +43,20 @@ Décisions de `alpha.1` :
- test PostgreSQL via URL explicitement fournie et schéma éphémère isolé ;
- aucune lecture implicite de secrets par la crate et aucun fallback de stockage.
Questions laissées aux tranches d'implémentation :
Décisions matérialisées par `alpha.2` :
- façade publique minimale `PostgresStoreConfig` / `PostgresStore` / `PostgresStoreError` ;
- pool borné par `max_pool_size` sans exposition de types Deadpool ;
- versions revalidées `tokio-postgres 0.7.18`, `deadpool-postgres 0.14.2`, Refinery `0.9.2` et Tokio test `1.53.1`, avec features minimales `runtime`, `rt_tokio_1` et `tokio-postgres` respectivement ;
- migration `V1__initial_sources.sql` embarquée et appliquée explicitement ;
- premier backend sans TLS via `NoTls`, sans dépendance TLS prématurée ;
- test réel de migration isolé par schéma et déclenché explicitement par la gate.
Questions laissées aux tranches suivantes :
- surface publique minimale exacte de `PostgresStore` et de sa configuration ;
- paramètres de pool utiles au produit sans exposer les types Deadpool ;
- besoin réel d'un contrat passif de persistance dans `knowledge-app-lib` pour le raccord `alpha.4` ;
- backend TLS à sélectionner uniquement si le déploiement visé l'exige.
- backend TLS à sélectionner uniquement si le déploiement visé l'exige ;
- paramètres supplémentaires de pool uniquement sur besoin runtime observé.
## Scope

View File

@@ -1,5 +1,5 @@
<!-- file: docs/studies/008-V0_0_4_POSTGRES_FOUNDATION_STUDY.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Étude 0.0.4 — fondation PostgreSQL partagée
@@ -78,7 +78,7 @@ La sélection privilégie des responsabilités explicitement bornées plutôt qu
La première implémentation utilisera `tokio-postgres` comme driver PostgreSQL asynchrone natif, `deadpool-postgres` comme pool et `refinery` comme owner technique des migrations SQL. Aucun ORM n'est sélectionné et aucune abstraction multi-SGBD n'est recherchée.
Les versions observées pendant l'étude sont `tokio-postgres 0.7.18`, `deadpool-postgres 0.14.2` et `refinery 0.9.2`. `tokio-postgres` et `deadpool-postgres` déclarent actuellement Rust 2024 avec un MSRV `1.85`; Refinery vise les Rust stable récents. `alpha.2` doit néanmoins revalider les versions stables compatibles au moment exact de leur ajout au manifest, conformément à la politique locale de dépendances, sans downgrade silencieux.
Les versions observées pendant l'étude sont `tokio-postgres 0.7.18`, `deadpool-postgres 0.14.2` et `refinery 0.9.2`. `tokio-postgres` et `deadpool-postgres` déclarent actuellement Rust 2024 avec un MSRV `1.85`; Refinery vise les Rust stable récents. `alpha.2` a revalidé ces versions le `2026-09-30` avant leur ajout au manifest et retient les features minimales `runtime` pour `tokio-postgres`, `rt_tokio_1` pour `deadpool-postgres` et `tokio-postgres` pour Refinery. Tokio `1.53.1` est ajouté uniquement comme runtime de test d'intégration.
La séparation est volontaire :
@@ -90,7 +90,7 @@ refinery découverte, historique et application des migrations SQL
La façade publique de `knowledge-store-postgres-lib` masque ces dépendances et normalise leurs erreurs dans le type d'erreur de la crate. Les types `tokio-postgres`, Deadpool ou Refinery ne doivent pas remonter dans `knowledge-domain-lib` ni dans les contrats applicatifs.
Un backend TLS n'est pas figé par `alpha.1`. Si la cible de déploiement PostgreSQL exige TLS, la tranche qui matérialise la connexion doit sélectionner explicitement l'intégration TLS minimale compatible avec `tokio-postgres` au lieu d'hériter d'un défaut implicite.
`alpha.2` matérialise la première connexion avec `tokio_postgres::NoTls` et n'ajoute aucune dépendance TLS prématurée. Si une cible de déploiement PostgreSQL exige TLS, une tranche ultérieure devra sélectionner explicitement l'intégration TLS minimale compatible avec `tokio-postgres` au lieu d'hériter d'un défaut implicite.
## Ownership
@@ -100,7 +100,7 @@ La responsabilité est suffisamment concrète pour justifier :
knowledge-store-postgres-lib
```
Cette crate possédera :
À partir d'`alpha.2`, cette crate possède :
- construction et lifecycle du pool `deadpool-postgres` ;
- migrations SQL de Knowledge ;
@@ -252,4 +252,4 @@ L'horizon reste donc :
`0.0.4` peut progresser sans REPLAN : l'owner PostgreSQL est démontré, `tokio-postgres`, `deadpool-postgres` et `refinery` couvrent respectivement le driver, le pool et les migrations nécessaires, le premier schéma est borné et reconstructible par rapport à Git, et une stratégie de test PostgreSQL réelle est définie sans imposer un outil de provisioning unique.
`alpha.1` ne crée encore aucune crate, dépendance ou migration. Après son `PASS` opérateur, `alpha.2` peut matérialiser `knowledge-store-postgres-lib`, le trio `tokio-postgres` / `deadpool-postgres` / `refinery` et la première migration.
`alpha.1` a fermé le cadrage en `PASS`. `alpha.2` matérialise maintenant `knowledge-store-postgres-lib`, le trio `tokio-postgres` / `deadpool-postgres` / `refinery`, une configuration/pool sans fuite de secret, la migration initiale des sources et un test PostgreSQL réel isolé par schéma. Les opérations de persistance source/state restent réservées à `alpha.3`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/001-VALIDATION_MATRIX.md -->
<!-- version: 42 -->
<!-- version: 43 -->
# Matrice de validation Knowledge
@@ -1041,3 +1041,32 @@ La première tranche de `0.0.4` est une gate de cadrage sans code produit, dépe
Clippy, tests workspace, npm/Vite et smokes HTTP ne sont pas requis par cette tranche : elle ne modifie ni source Rust, ni dépendance, ni frontend, ni runtime. La gate vérifie néanmoins `cargo check --workspace` après la promotion de version du manifest.
Un `PASS` autorise uniquement `0.0.4-alpha.2`. Un autre statut est historisé puis conduit à un fix borné ou à un REPLAN.
## Gate de `0.0.4-alpha.2`
La deuxième tranche matérialise le premier owner PostgreSQL réel. Elle doit prouver :
- `VERSION = 0.0.4-alpha.2` et `[workspace.package].version` identique ;
- `history/0.0.4/alpha.1.md` présent avec statut `PASS` et committé avant application ;
- workspace composé exactement de dix packages, avec `knowledge-store-postgres-lib` comme seul nouveau membre ;
- `tokio-postgres 0.7.18` avec `runtime`, `deadpool-postgres 0.14.2` avec `rt_tokio_1`, Refinery `0.9.2` avec `tokio-postgres` et Tokio test `1.53.1` ajouté uniquement à la crate PostgreSQL ;
- façade crate-root limitée à `PostgresStoreConfig`, `PostgresStore` et `PostgresStoreError` ;
- configuration injectée, sans lecture d'environnement ni getter public de l'URL PostgreSQL ;
- pool `deadpool-postgres` borné par `max_pool_size`, driver `tokio-postgres` et première connexion `NoTls` ;
- migration `V1__initial_sources.sql` embarquée via Refinery et appliquée seulement par `PostgresStore::apply_migrations` ;
- tables `knowledge_sources` et `knowledge_source_sync_state` avec contrainte des familles et cascade de suppression de l'état de synchronisation ;
- aucun corps de contenu, credential Git, compte, proposition, job ou projection finale ajouté au schéma ;
- test unitaire de configuration sans PostgreSQL ;
- test d'intégration PostgreSQL réel isolé dans un schéma unique et exécuté explicitement avec `KNOWLEDGE_POSTGRES_TEST_URL` ;
- absence de PostgreSQL réel pendant cette gate classée `BLOCKED`, jamais masquée par un skip ;
- aucun diff sous `Web/`, les trois launchers, `knowledge-app-lib`, `knowledge-git-api`, `knowledge-git-lib`, `knowledge-sync-api` ou `knowledge-domain-lib` ;
- audits Markdown et hygiène texte propres ;
- `cargo fmt --all` puis `cargo fmt --all -- --check` exécutés avant les audits Rust ;
- audits Rust locaux propres sur les dix crates ;
- `cargo metadata`, `cargo check`, Clippy strict, tests ciblés store et tests workspace propres ;
- `Cargo.lock` local ignoré/non suivi et `package-lock.json` Web inchangé/versionné ;
- `git diff --cached --check` propre avant commit.
La gate ne rejoue pas npm/Vite/HTTP : aucun fichier Web, launcher ou contrat runtime Web n'est modifié. Le test PostgreSQL marqué `#[ignore]` reste exclu des tests workspace ordinaires et est rejoué explicitement avec `--ignored` dans la gate afin que la dépendance externe soit volontaire et visible.
Un `PASS` autorise uniquement `0.0.4-alpha.3`. Un `FAIL` de code ou migration produit un fix borné ; une incompatibilité de toolchain/dépendances, une impossibilité d'isoler correctement le test PostgreSQL ou un besoin de modifier l'ownership déclenche un REPLAN.