v0.3.2-pre.001

This commit is contained in:
2026-08-29 16:45:14 +02:00
parent 6cc94ebb46
commit 8d4b3b67fb
7 changed files with 1938 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# Data, Materialization et Store
@@ -291,26 +291,39 @@ La première implementation `0.3.1` est volontairement **RAW-only** : elle ne cr
Les surfaces CORE/DECODE/SPECIALIZED sont ajoutées quand leurs couches sont réellement ouvertes.
## `ksp-store-lib`
## `ksp-store-lib` et backends physiques
`ksp-store-lib` fournit PostgreSQL comme backend officiel de référence derrière `ksp-store-api`.
`ksp-store-lib` est la façade/runtime Store commune derrière `ksp-store-api`. Il sélectionne uniquement les backends compilés par ses features, convertit ses settings KSP-owned vers le backend retenu, expose le lifecycle commun et masque les objets physiques du moteur.
Il possède :
Il possède notamment :
- migrations ;
- SQL ;
- transactions ;
- mapping backend ;
- pagination ;
- claim/lease lorsque nécessaire ;
- notifications backend si retenues.
- identité et sélection de backend côté façade ;
- settings Store publics KSP-owned indépendants de Config ;
- lifecycle commun `open` / `close` ;
- dispatch vers le backend compilé ;
- mapping des diagnostics/health backend vers une projection portable lorsque cette surface est justifiée ;
- réexport de la surface `ksp-store-api` utile aux consumers.
Il ne possède pas :
Le backend PostgreSQL officiel appartient à `ksp-store-postgres-lib`. Cette crate dépend de `ksp-store-api`, ne dépend jamais de `ksp-store-lib` et possède seule :
- transport réseau ;
- `tokio-postgres` et le pool PostgreSQL ;
- le connecteur TLS PostgreSQL ;
- SQL et statements physiques ;
- transactions PostgreSQL ;
- migrations/bootstrap et metadata de schéma ;
- mapping rows/backend ;
- détails de cursorisation physique ;
- diagnostics PostgreSQL internes.
`ksp-store-lib` et les crates backend ne possèdent pas :
- transport réseau dacquisition ;
- decoder Program ;
- materializer ;
- orchestration de worker/job.
- orchestration de worker/job ;
- politique de batch, backlog, priorité ou retry de processing.
La pagination/cursorisation reste un contrat de navigation Store. Une limite demandée par lappelant peut être validée pour sa forme/sécurité, mais aucun plafond métier global arbitraire ni batch-size de worker nest introduit par le runtime Store.
## `ksp-materializer-api` et `ksp-materializer-lib`

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/RULES_DEPENDENCIES.md -->
<!-- version: 16 -->
<!-- version: 17 -->
# Règles des dépendances KSP
@@ -79,13 +79,15 @@ Elles complètent les règles Rust générales et le graphe de `docs/architectur
- **DEP-MAT-002** — `ksp-materializer-api` et `ksp-materializer-lib` ne dépendent pas de `ksp-store-api` ou `ksp-store-lib`.
- **DEP-MAT-003** — Une matérialisation générique doit pouvoir produire un output compatible avec le journal D3 sans imposer une table PostgreSQL spécialisée par materializer.
- **DEP-STORE-001** — `ksp-store-api` ne dépend pas de Program, Materializer ou Transport.
- **DEP-STORE-002** — `ksp-store-lib` dépend de `ksp-store-api` et contient l'implémentation PostgreSQL de référence ; il ne dépend pas des implémentations Program/Materializer/Transport.
- **DEP-STORE-002** — `ksp-store-lib` dépend de `ksp-store-api`, porte la façade/runtime Store commune et peut dépendre optionnellement de crates backend compilées par feature ; il ne dépend pas des implémentations Program/Materializer/Transport.
- **DEP-STORE-003** — Les workers/jobs spécialisés sont propriétaires des conversions entre modèles runtime et DTO persistants.
- **DEP-STORE-004** — Les niveaux durables sont D1 Raw, D2 Core canonique, D3 journal de matérialisation générique et D4 projections spécialisées.
- **DEP-STORE-005** — Les replays D1 -> D2, D2 -> D3 et D3 -> D4 doivent pouvoir être exécutés indépendamment.
- **DEP-STORE-006** — Une notification de donnée persistée ne constitue jamais la source de vérité du backlog ; les queries Store et marqueurs durables d'idempotence/version de processor font autorité.
- **DEP-STORE-007** — Une notification de donnée est publiée seulement après persistence/commit réussis.
- **DEP-STORE-008** — D4 est organisé par faits canoniques quand les invariants le permettent, et non par familles de tables propres aux protocoles.
- **DEP-STORE-009** — `ksp-store-postgres-lib` dépend de `ksp-store-api`, possède seul le driver, le pool, TLS, SQL et les migrations PostgreSQL physiques, et ne dépend jamais de `ksp-store-lib`.
- **DEP-STORE-010** — Les consumers runtime ordinaires — workers, jobs, services et apps — dépendent de `ksp-store-lib` et non directement dune crate backend ; Config/composition traduit la configuration effective vers les settings publics Store sans créer de dépendance Store -> Config.
## Transport

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/RULES_KSP.md -->
<!-- version: 38 -->
<!-- version: 39 -->
# Règles spécifiques à KSP
@@ -23,7 +23,7 @@
- **KSP-API-003** — KSP ne crée pas de `ksp-api-lib` monolithique regroupant les contrats de domaines indépendants.
- **KSP-API-004** — Un contrat public extensible doit pouvoir être implémenté depuis une crate séparée du workspace principal lorsque cela est techniquement pertinent.
- **KSP-API-005** — Les signatures des contrats publics utilisent en priorité des types publics KSP et les primitives externes explicitement admises ; elles ne doivent pas imposer des détails internes instables.
- **KSP-API-006** — `ksp-store-lib` contient PostgreSQL comme implémentation officielle de référence derrière `ksp-store-api`.
- **KSP-API-006** — `ksp-store-lib` est la façade/runtime Store commune derrière `ksp-store-api` et sélectionne uniquement des backends compilés via ses features ; limplémentation PostgreSQL officielle appartient à `ksp-store-postgres-lib`, qui dépend de `ksp-store-api` et ne dépend jamais de `ksp-store-lib`.
- **KSP-API-007** — Une crate `*-api` n'est créée que lorsqu'un vrai besoin d'extension, backend ou lifecycle le justifie ; la symétrie de nommage n'est jamais une justification suffisante.
## Configuration et environnement

View File

@@ -0,0 +1,539 @@
<!-- file: docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md -->
<!-- version: 1 -->
# Validation `0.3.2` — Store/PostgreSQL runtime foundation
## 1. Objet
Cette matrice est ouverte par `0.3.2-pre.001`. Elle fixe les critères de preuve de la fondation Store/PostgreSQL sans préjuger des résultats non encore exécutés.
Statuts :
```text
TODO preuve requise non encore exécutée
PASS preuve réellement exécutée et verte
FAIL preuve exécutée et en échec
N/A non applicable avec justification
```
Aucun `TODO` n'est présenté comme validé.
## 2. Base et audit `pre.001`
### V32-BASE-001 — Base stable
Critère :
```text
workspace.package.version = 0.3.1 sur l'archive source
deltas/0.3.1/rel.001.md présent
prompt 021 présent
ksp-store-api présent
ksp-store-lib absent
ksp-store-postgres-lib absent
```
Statut : `PASS` au gate documentaire `pre.001`.
Note : metadata Git absente de l'archive ; le tag `v0.3.1` n'est pas interrogé localement.
### V32-AUDIT-001 — Sources internes
Critère : règles, architecture, plan/validation `0.3.1`, source/tests `ksp-store-api`, CHANGELOG et ROADMAP relus avant design.
Statut : `PASS` au gate documentaire `pre.001`.
### V32-AUDIT-002 — Archive kbot3
Critère : ancien Store/config/PostgreSQL/migrations/health/pool/erreurs relus et classés reprendre/redessiner/reporter/rejeter.
Statut : `PASS` au gate documentaire `pre.001`.
### V32-AUDIT-003 — Audit externe actuel
Critère : PostgreSQL, tokio-postgres, pool, TLS et helper migrations réaudités avec sources actuelles.
Statut : `PASS` au gate documentaire `pre.001`.
Référence du gate :
```text
PostgreSQL 18.6
tokio-postgres 0.7.18
deadpool-postgres 0.14.1
tokio-postgres-rustls 0.14.0
sha2 0.11.0
refinery 0.9.2 audité/rejeté
```
## 3. Frontières Cargo
### V32-DEP-001 — Façade -> API
```text
ksp-store-lib -> ksp-store-api
```
Statut : `TODO pre.002`.
### V32-DEP-002 — Backend -> API
```text
ksp-store-postgres-lib -> ksp-store-api
```
Statut : `TODO pre.002`.
### V32-DEP-003 — Pas de cycle backend
```text
ksp-store-postgres-lib -X-> ksp-store-lib
```
Preuves : manifest scanner + cargo tree.
Statut : `TODO pre.002/pre.009`.
### V32-DEP-004 — Feature PostgreSQL
Critères :
```text
postgres est default feature de ksp-store-lib
ksp-store-postgres-lib est optional dependency
cargo check -p ksp-store-lib --no-default-features passe
```
Statut : `TODO pre.002`.
### V32-DEP-005 — Firewall domaines
Interdictions :
```text
Store/backend -> Config
Store/backend -> Transport
Store/backend -> Program
Store/backend -> Materializer
consumer ordinaire -> ksp-store-postgres-lib
```
Statut : `TODO pre.009`.
### V32-DEP-006 — `ksp-store-api` non régressé
Critères :
```text
dépendance runtime exacte ksp-core-lib seulement
exports/capabilities existants conservés
aucun type backend ajouté pour PostgreSQL
```
Statut : `TODO gate final`, baseline `v0.3.1` déjà verte.
## 4. Public API et settings
### V32-API-001 — Settings Config-independent
Critère : `StoreSettings` est constructible sans `ksp-config-lib`, sans env et sans serde requis par la façade.
Statut : `TODO pre.003`.
### V32-API-002 — Backend connu non compilé
Critère : `Postgres` reste un backend connu sans feature et `Store::open` échoue avant I/O avec un code stable.
Statut : `TODO pre.003`.
### V32-API-003 — Aucun type backend physique public
Interdits dans crate-root `ksp-store-lib` :
```text
tokio_postgres::*
deadpool_postgres::*
rustls::*
PostgresBackend / Pool / Client / Row / Statement
```
Statut : `TODO pre.009`.
### V32-API-004 — Réexports Store API
Critère : un consumer de `ksp-store-lib` accède aux contrats Store API utiles sans dépendre directement de la crate backend.
Statut : `TODO pre.003`.
### V32-API-005 — Lifecycle
Critères :
```text
Store::open async
Store::close(self) async
pas de pool/client échappé
close borné
Drop best-effort seulement
```
Statut : `TODO pre.003/pre.007`.
## 5. Config ownership
### V32-CONFIG-001 — Document/schema/example
Critères :
```text
std.store enregistré
schema V1 valide
example valide
profiles typés
backend postgres explicite
```
Statut : `TODO pre.004`.
### V32-CONFIG-002 — Secrets/provenance
Critères :
```text
KSP_SECRET_STORE_POSTGRES_URI classé Secret
safe projection redacted
provenance sans valeur
dotenv inventory à jour
```
Statut : `TODO pre.004`.
### V32-CONFIG-003 — No-env Store/backend
Critère : production sources `ksp-store-lib` et `ksp-store-postgres-lib` ne lisent aucun :
```text
std::env
dotenv
KSP_*
KSPB_*
PG*
.pgpass
```
Statut : `TODO pre.004/pre.009`.
### V32-CONFIG-004 — Adapter Config -> Store
Critère : `ksp-config-lib` seul transforme un profil résolu en `StoreSettings` et ne transmet aucun secret dans diagnostics.
Statut : `TODO pre.004`.
## 6. Pool et lifecycle PostgreSQL
### V32-POOL-001 — Pool borné
Critères :
```text
max_connections 1..64
wait/create/recycle timeouts bornés
aucune taille zéro
aucune valeur pathologique
```
Statut : `TODO pre.005`.
### V32-POOL-002 — Connection task ownership
Critère : chaque connection future tokio-postgres est pilotée par le manager retenu et son task handle reste possédé jusqu'au drop/close.
Statut : `TODO pre.005/pre.009`.
### V32-POOL-003 — Open failure safe
Critère : DNS/connect/auth/server errors ne copient ni URI ni texte remote arbitraire dans Display/Debug public.
Statut : `TODO pre.005`.
### V32-POOL-004 — Close
Critères :
```text
pool fermé
nouvelles acquisitions refusées
shutdown respecte timeout
aucune tâche volontairement laissée orpheline
```
Statut : `TODO pre.007/pre.008`.
## 7. TLS
### V32-TLS-001 — Modes exacts
Surface initiale :
```text
Disabled
VerifyFull
```
Statut : `TODO pre.005`.
### V32-TLS-002 — VerifyFull
Critères :
```text
TLS requis
root store système
authenticité du certificat vérifiée
nom serveur vérifié
aucun fallback plaintext
```
Statut : `TODO pre.005`.
### V32-TLS-003 — Pas de fichier TLS implicite
Critère : backend ne lit pas `sslrootcert`, `sslcert`, `sslkey`, `.postgresql/*` ou autre fichier implicite hors settings KSP.
Statut : `TODO pre.009`.
## 8. Migration/bootstrap
### V32-MIG-001 — Metadata privée uniquement
Critère : `0.3.2` crée au plus la relation d'infrastructure :
```text
ksp_store_schema_migrations
```
et aucune table métier RAW/CORE/DECODE/SPECIALIZED.
Statut : `TODO pre.006`.
### V32-MIG-002 — Version/checksum
Critères :
```text
version entière monotone
nom immuable
SHA-256 du SQL exact
sentinel bootstrap version 0
mismatch historique terminal
```
Statut : `TODO pre.006`.
### V32-MIG-003 — Concurrence
Critère : deux runners concurrents sont sérialisés par advisory transaction lock avec attente bornée.
Statut : `TODO pre.006/pre.008`.
### V32-MIG-004 — Atomicité/recovery
Critère : échec d'une migration du run courant rollback DDL + history de ce run ; un rerun depuis état précédent reste sûr.
Statut : `TODO pre.006/pre.008`.
### V32-MIG-005 — Newer runtime guard
Critère : migration appliquée inconnue/supérieure à la liste embarquée produit `STORE_POSTGRES_SCHEMA_NEWER`, sans down migration.
Statut : `TODO pre.006`.
### V32-MIG-006 — SQL injection
Critères :
```text
SQL de migration statique embarqué
values paramétrées
aucun identifier physique user-configurable en 0.3.2
```
Statut : `TODO pre.006/pre.009`.
### V32-MIG-007 — No business capability
Critères :
```text
0 impl PostgreSQL de capability RawTransaction
0 impl PostgreSQL de capability RawAccountState
0 repository RAW métier
```
Statut : `TODO pre.009/gate final`.
## 9. Health/readiness
### V32-HEALTH-001 — Projection portable
Critère : façade expose uniquement état/backend/counts/migration safe, jamais URI/SQL/pool/client.
Statut : `TODO pre.007`.
### V32-HEALTH-002 — Readiness réelle
Critère : `Store::open` ne retourne Ready qu'après connect + bootstrap/verify selon settings.
Statut : `TODO pre.007/pre.008`.
### V32-HEALTH-003 — Error redaction
Critère : un health failure n'expose pas server error string, query text ou credential.
Statut : `TODO pre.007/pre.009`.
## 10. PostgreSQL integration réelle
### V32-LIVE-001 — Input opérateur explicite
Critères :
```text
#[ignore]
URI lue depuis stdin
aucun env requis
URI jamais imprimée
```
Statut : `TODO pre.008`.
### V32-LIVE-002 — Non destructif
Critères :
```text
refus si metadata table préexiste
aucune base/schema drop
aucune table métier créée
cleanup seulement de metadata créée par le test
```
Statut : `TODO pre.008`.
### V32-LIVE-003 — Scénario foundation
Preuves :
```text
connect
bootstrap initial
bootstrap idempotent
bootstrap concurrent
checksum mismatch
failure rollback
health ready
close borné
```
Statut : `TODO pre.008/pre.010`.
### V32-LIVE-004 — PostgreSQL support
Critère : test refuse major < 15 et enregistre seulement le major safe réellement testé.
Cible release : PostgreSQL 18.6.
Statut : `TODO pre.008/pre.010`.
## 11. Security/adversarial
### V32-SEC-001 — URI hostile
Cas : vide, surdimensionnée, malformed, paramètres conflictuels, password contenant contrôles/URL-like.
Attendu : rejet borné sans echo.
Statut : `TODO pre.009`.
### V32-SEC-002 — Secret canary
Injecter un canary dans URI/password et prouver son absence de :
```text
Debug
Display
ErrorContext
tracing snapshots
health snapshots
```
Statut : `TODO pre.009`.
### V32-SEC-003 — Timeouts hostiles
Cas : zéro, inversion, dépassement bornes pour pool/connect/migration/close.
Statut : `TODO pre.003/pre.005/pre.009`.
### V32-SEC-004 — Feature mismatch avant I/O
Statut : `TODO pre.003/pre.009`.
### V32-SEC-005 — Server error sanitization
Un serveur/test double qui renvoie un message contenant un canary ne doit pas le faire traverser l'erreur publique.
Statut : `TODO pre.005/pre.009`.
## 12. Gates Rust/workspace
À chaque tranche applicable :
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.2
cargo check --workspace
cargo clippy --workspace --all-targets
```
Après création des crates :
```bash
cargo test -p ksp-store-api
cargo test -p ksp-store-lib
cargo test -p ksp-store-postgres-lib
cargo test -p ksp-config-lib
cargo check -p ksp-store-lib --no-default-features
cargo tree -p ksp-store-lib --edges normal
cargo tree -p ksp-store-lib -e features
cargo tree -p ksp-store-postgres-lib --edges normal
cargo tree --duplicates
```
Gate technique final :
```bash
cargo test --workspace
```
Les builds Tauri ne sont requis que si `pre.004` modifie réellement les resources/packaging desktop de manière justifiant cette preuve, puis au gate final si la matrice de packaging l'exige.
Statut global : `TODO` jusqu'aux preuves de chaque tranche.
## 13. Critères de fermeture
La matrice ne peut passer en finale que si tous les critères applicables sont `PASS` et que :
```text
aucun RawTransaction PostgreSQL
aucun RawAccountState PostgreSQL
aucun SQL métier RAW
aucune policy worker/job dans Store
aucune fuite backend dans façade
aucune lecture env par Store/backend
PostgreSQL live vert
workspace/clippy/tests verts
```
La réconciliation finale de cette matrice appartient à la prerelease documentaire précédant la lane de publication.