v0.3.2-pre.008
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md -->
|
||||
<!-- version: 9 -->
|
||||
<!-- version: 10 -->
|
||||
|
||||
# Plan `0.3.2` — Store/PostgreSQL runtime foundation
|
||||
|
||||
@@ -863,7 +863,7 @@ Mesures : conversion immédiate vers code KSP + contexte allowlisté ; source er
|
||||
|
||||
## 16. PostgreSQL integration test réel
|
||||
|
||||
Le test opt-in sera dans `ksp-store-postgres-lib/tests/` et ignoré par défaut.
|
||||
Le test opt-in est matérialisé par `ksp-store-postgres-lib/tests/postgres_foundation_live.rs` et reste ignoré par défaut.
|
||||
|
||||
Entrée :
|
||||
|
||||
@@ -891,13 +891,15 @@ second bootstrap idempotent
|
||||
deux bootstrap concurrents après reset contrôlé
|
||||
corruption test-only du checksum sentinel -> mismatch explicite
|
||||
restore/reset contrôlé
|
||||
migration failure injectée sous cfg(test) -> rollback/history inchangée
|
||||
échec SQL contrôlé dans une transaction de test exécutant le V000 exact -> drop implicite de `tokio-postgres::Transaction` -> rollback DDL/history prouvé
|
||||
health ready
|
||||
close explicite borné
|
||||
cleanup metadata
|
||||
```
|
||||
|
||||
Le gate de référence visera PostgreSQL 18.6. Le test peut accepter un serveur >= 15, mais le rapport opérateur doit enregistrer le major réellement utilisé sans imprimer d'identité sensible.
|
||||
Le gate de référence visera PostgreSQL 18.6. Le test accepte un serveur >= 15, n'imprime que le major et refuse tout serveur plus ancien. La connexion d'administration du test et le backend live utilisent `Disabled` afin que ce gate porte sur la fondation PostgreSQL/migrations ; la policy TLS `VerifyFull` reste prouvée séparément par les canaris déterministes de `pre.005`. Le test ne lit aucune variable d'environnement.
|
||||
|
||||
La preuve de rollback n'ajoute aucun hook public ou feature de test à la crate de production : le test réutilise par `include_str!` le V000 committed exact, ouvre une transaction PostgreSQL, exécute le DDL et un sentinel transitoire, injecte ensuite une erreur SQL contrôlée puis droppe la transaction. `tokio-postgres 0.7.18` garantit le rollback implicite d'une `Transaction` droppée ; le test vérifie ensuite physiquement l'absence de la table metadata avant de relancer le bootstrap KSP normal.
|
||||
|
||||
## 17. Validation de dépendances et API
|
||||
|
||||
@@ -1018,7 +1020,7 @@ Avec les quatre codes PostgreSQL ajoutés en `pre.005` puis les trois codes migr
|
||||
|
||||
### `pre.007` — Composition end-to-end + health
|
||||
|
||||
Statut : matérialisé par `0.3.2-pre.007`, gate Cargo opérateur requis.
|
||||
Statut : matérialisé par `0.3.2-pre.007`, gate Cargo opérateur `PASS` le 2026-08-29.
|
||||
|
||||
La façade ferme la projection runtime/health sans exposer de type physique :
|
||||
|
||||
@@ -1036,7 +1038,28 @@ Avec `StoreHealthState`, `StoreRuntimeSnapshot`, `StoreHealthSnapshot` et `ERROR
|
||||
|
||||
### `pre.008` — PostgreSQL integration réelle
|
||||
|
||||
Ajouter/exécuter le smoke opt-in non destructif : initial/idempotent/concurrent/mismatch/failure/close sur serveur réel.
|
||||
Statut : test opt-in matérialisé par `0.3.2-pre.008`; compilation/gates déterministes puis exécution PostgreSQL réelle opérateur requises.
|
||||
|
||||
Le scénario `postgres_foundation_live` :
|
||||
|
||||
```text
|
||||
lit une URI dédiée uniquement depuis stdin
|
||||
refuse si ksp_store_schema_migrations existe avant le test
|
||||
refuse PostgreSQL < 15 et n'imprime que le major
|
||||
bootstrap initial + health Ready + close borné
|
||||
réouverture idempotente + health Ready
|
||||
reset contrôlé de la metadata possédée par le test
|
||||
deux bootstrap concurrents sérialisés par advisory lock
|
||||
corruption checksum sentinel -> MigrationMismatch
|
||||
restauration checksum -> recovery Ready
|
||||
reset contrôlé
|
||||
transaction test avec V000 exact + sentinel transitoire + erreur injectée
|
||||
Drop Transaction -> rollback implicite -> metadata absente
|
||||
re-bootstrap normal + health Ready + close borné
|
||||
cleanup uniquement de la metadata prouvée créée par le test
|
||||
```
|
||||
|
||||
Aucun hook test-only n'est ajouté au runtime de production et aucune table RAW métier n'est créée.
|
||||
|
||||
### `pre.009` — Hardening/completeness/dependency matrix
|
||||
|
||||
@@ -1109,12 +1132,7 @@ Store Desk
|
||||
|
||||
Aucune question architecturale ne bloque `pre.002`.
|
||||
|
||||
Les détails suivants sont réservés à leur tranche sans rouvrir les décisions du gate :
|
||||
|
||||
```text
|
||||
DDL précis de ksp_store_schema_migrations en pre.006
|
||||
forme finale des snapshots health en pre.007
|
||||
```
|
||||
Les décisions foundation encore ouvertes après `pre.008` sont uniquement des preuves de hardening/completeness et de clôture ; le DDL metadata, le health/readiness et la stratégie du test PostgreSQL réel sont désormais matérialisés.
|
||||
|
||||
Toute découverte qui exigerait :
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md -->
|
||||
<!-- version: 9 -->
|
||||
<!-- version: 10 -->
|
||||
|
||||
# Validation `0.3.2` — Store/PostgreSQL runtime foundation
|
||||
|
||||
@@ -207,7 +207,7 @@ Drop best-effort seulement
|
||||
|
||||
`pre.003` fixe les signatures `Store::open(settings).await` et `Store::close(self).await`. `pre.005` remplace le stop de staging PostgreSQL par l'ouverture physique : un succès exige `pool.get().await` après construction du pool, puis `close(self)` ferme et draine ce pool sous la deadline configurée. Aucun pool/client n'est exposé par la façade.
|
||||
|
||||
Statut : `PASS pre.003-fix.001 opérateur` pour les signatures / `PASS pre.005-fix.001 opérateur` pour l'ouverture et le shutdown physiques / `TODO gate opérateur pre.007` pour la composition health.
|
||||
Statut : `PASS pre.003-fix.001 opérateur` pour les signatures / `PASS pre.005-fix.001 opérateur` pour l'ouverture et le shutdown physiques / `PASS pre.007 opérateur` pour la composition health.
|
||||
|
||||
## 5. Config ownership
|
||||
|
||||
@@ -331,7 +331,7 @@ aucune tâche volontairement laissée orpheline
|
||||
|
||||
`pre.005` matérialise déjà `Pool::close()` et un drain borné par `shutdown_timeout`; `Drop` ne fait qu'un `close()` best-effort. La preuve end-to-end avec backend réel reste réservée à `pre.007/pre.008`.
|
||||
|
||||
Statut : `PASS pre.005-fix.001 opérateur / TODO gate pre.007 / TODO pre.008 live`.
|
||||
Statut : `PASS pre.005-fix.001 opérateur / PASS pre.007 opérateur / TODO exécution live pre.008`.
|
||||
|
||||
## 7. TLS
|
||||
|
||||
@@ -384,7 +384,7 @@ et aucune table métier RAW/CORE/DECODE/SPECIALIZED.
|
||||
|
||||
`pre.006` embarque exactement `migrations/V000__bootstrap.sql`, dont le seul DDL de production crée `ksp_store_schema_migrations`. Le canari source interdit les identifiants métier RAW/CORE/DECODE/SPECIALIZED dans le moteur et la ressource SQL.
|
||||
|
||||
Statut : `PASS pre.006 opérateur / TODO pre.008 live`.
|
||||
Statut : `PASS pre.006 opérateur / MATÉRIALISÉ pre.008 / TODO exécution live opérateur`.
|
||||
|
||||
### V32-MIG-002 — Version/checksum
|
||||
|
||||
@@ -400,7 +400,7 @@ mismatch historique terminal
|
||||
|
||||
`pre.006` calcule explicitement SHA-256 sur les octets exacts du SQL embarqué puis encode les 32 octets en 64 caractères hex minuscules. Le sentinel `(0, bootstrap, checksum)` est inséré dans la même transaction que la création metadata. Les tests unitaires figent le checksum du SQL committed et couvrent sentinel valide, missing, nom/checksum divergents et historique plus récent.
|
||||
|
||||
Statut : `PASS pre.006 opérateur / TODO pre.008 live`.
|
||||
Statut : `PASS pre.006 opérateur / MATÉRIALISÉ pre.008 / TODO exécution live opérateur`.
|
||||
|
||||
### V32-MIG-003 — Concurrence
|
||||
|
||||
@@ -408,7 +408,7 @@ Critère : deux runners concurrents sont sérialisés par advisory transaction l
|
||||
|
||||
`pre.006` utilise une clé KSP fixe et `pg_try_advisory_xact_lock($1)` dans une boucle bornée par `migration_lock_timeout`, avec polling de 25 ms maximum. Aucun lock bloquant illimité n'est utilisé.
|
||||
|
||||
Statut : `PASS pre.006 opérateur / TODO pre.008 concurrence réelle`.
|
||||
Statut : `PASS pre.006 opérateur / MATÉRIALISÉ pre.008 / TODO concurrence live opérateur`.
|
||||
|
||||
### V32-MIG-004 — Atomicité/recovery
|
||||
|
||||
@@ -416,7 +416,7 @@ Critère : échec d'une migration du run courant rollback DDL + history de ce ru
|
||||
|
||||
`pre.006` place lock, metadata DDL, sentinel et validation dans une transaction unique ; toute sortie d'erreur avant `commit()` droppe la transaction et PostgreSQL rollback le run courant. Un timeout externe borne également l'ensemble du bootstrap. L'injection d'échec et la preuve physique du rollback restent au smoke réel.
|
||||
|
||||
Statut : `PASS pre.006 opérateur / TODO pre.008 rollback réel`.
|
||||
Statut : `PASS pre.006 opérateur / MATÉRIALISÉ pre.008 / TODO rollback live opérateur`.
|
||||
|
||||
### V32-MIG-005 — Newer runtime guard
|
||||
|
||||
@@ -460,7 +460,7 @@ Critère : façade expose uniquement état/backend/network/counts/migration safe
|
||||
|
||||
`pre.007` matérialise `StoreRuntimeSnapshot`, `StoreHealthState::{Ready, NotReady}` et `StoreHealthSnapshot`. Les compteurs pool sont bornés en `u32`; la version migration est optionnelle si le probe ne peut pas la lire.
|
||||
|
||||
Statut : `TODO gate opérateur pre.007`.
|
||||
Statut : `PASS pre.007 opérateur`.
|
||||
|
||||
### V32-HEALTH-002 — Readiness réelle
|
||||
|
||||
@@ -468,7 +468,7 @@ Critère : `Store::open` ne retourne Ready qu'après connect + bootstrap/verify
|
||||
|
||||
`pre.007` conserve l'ouverture stricte acquise en `pre.006` et ajoute un probe borné par le `wait_timeout` du pool : acquisition, `SELECT 1`, lecture de version migration. Le smoke réel reste nécessaire pour prouver ce chemin contre PostgreSQL.
|
||||
|
||||
Statut : `TODO gate opérateur pre.007 / TODO pre.008 live`.
|
||||
Statut : `PASS pre.007 opérateur / TODO exécution live pre.008`.
|
||||
|
||||
### V32-HEALTH-003 — Error redaction
|
||||
|
||||
@@ -476,7 +476,7 @@ Critère : un health failure n'expose pas server error string, query text ou cre
|
||||
|
||||
Le backend ne conserve que `PostgresBackendErrorKind`; la façade mappe vers un `ErrorCode` KSP optionnel. Le snapshot public ne contient aucune string serveur, URI, SQL, host, user, database ou handle.
|
||||
|
||||
Statut : `TODO gate opérateur pre.007 / TODO pre.009 hardening`.
|
||||
Statut : `PASS pre.007 opérateur / TODO pre.009 hardening`.
|
||||
|
||||
## 10. PostgreSQL integration réelle
|
||||
|
||||
@@ -488,10 +488,12 @@ Critères :
|
||||
#[ignore]
|
||||
URI lue depuis stdin
|
||||
aucun env requis
|
||||
URI jamais imprimée
|
||||
URI jamais imprimée par le test
|
||||
```
|
||||
|
||||
Statut : `TODO pre.008`.
|
||||
`pre.008` ajoute `tests/postgres_foundation_live.rs`. Le test borne l'entrée à 4096 octets, ne conserve dans ses erreurs que des phases statiques et ne rend jamais l'erreur PostgreSQL brute. L'opérateur peut masquer la saisie côté shell puis piper une seule ligne sur stdin ; aucune variable d'environnement n'est lue par le test.
|
||||
|
||||
Statut : `MATÉRIALISÉ pre.008 / TODO exécution live opérateur`.
|
||||
|
||||
### V32-LIVE-002 — Non destructif
|
||||
|
||||
@@ -504,7 +506,9 @@ aucune table métier créée
|
||||
cleanup seulement de metadata créée par le test
|
||||
```
|
||||
|
||||
Statut : `TODO pre.008`.
|
||||
Le test interroge `information_schema.tables` avant toute mutation. Il ne prend ownership du cleanup qu'après avoir prouvé que le bootstrap initial a créé la metadata alors que la précondition était absente. Les seuls `DROP` exécutés ciblent `ksp_store_schema_migrations` pendant les resets contrôlés et le cleanup final.
|
||||
|
||||
Statut : `MATÉRIALISÉ pre.008 / TODO exécution live opérateur`.
|
||||
|
||||
### V32-LIVE-003 — Scénario foundation
|
||||
|
||||
@@ -515,21 +519,24 @@ connect
|
||||
bootstrap initial
|
||||
bootstrap idempotent
|
||||
bootstrap concurrent
|
||||
checksum mismatch
|
||||
failure rollback
|
||||
checksum mismatch + restore/recovery
|
||||
failure rollback du V000 exact
|
||||
health ready
|
||||
close borné
|
||||
cleanup metadata
|
||||
```
|
||||
|
||||
Statut : `TODO pre.008/pre.010`.
|
||||
La preuve rollback évite tout hook public de test : une transaction `tokio-postgres` de test exécute le V000 exact par `include_str!`, insère un sentinel transitoire, provoque ensuite une erreur SQL puis est droppée. Le test vérifie que la metadata n'existe pas après le rollback implicite et que le bootstrap KSP normal peut repartir proprement.
|
||||
|
||||
Statut : `MATÉRIALISÉ pre.008 / TODO exécution live opérateur puis revalidation 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.
|
||||
Cible release : PostgreSQL 18.6. `pre.008` interroge uniquement `SHOW server_version_num`, dérive le major et n'imprime aucune identité de serveur.
|
||||
|
||||
Statut : `TODO pre.008/pre.010`.
|
||||
Statut : `MATÉRIALISÉ pre.008 / TODO exécution live opérateur puis revalidation pre.010`.
|
||||
|
||||
## 11. Security/adversarial
|
||||
|
||||
@@ -561,7 +568,7 @@ Cas : zéro, inversion, dépassement bornes pour pool/connect/migration/close.
|
||||
|
||||
Les bornes backend-neutral décidées en `pre.001` sont matérialisées et couvertes par tests unitaires en `pre.003`. `pre.005` applique physiquement `connect/wait/create/recycle/shutdown`; `pre.006` applique physiquement `migration_timeout` et `migration_lock_timeout`.
|
||||
|
||||
Statut : `PASS pre.003-fix.001 opérateur` pour les bornes backend-neutral / `PASS pre.005-fix.001 opérateur` pour pool/connect/shutdown / `TODO gate opérateur pre.006` pour migration / `TODO pre.009` hardening.
|
||||
Statut : `PASS pre.003-fix.001 opérateur` pour les bornes backend-neutral / `PASS pre.005-fix.001 opérateur` pour pool/connect/shutdown / `PASS pre.006 opérateur` pour migration / `TODO pre.009` hardening.
|
||||
|
||||
### V32-SEC-004 — Feature mismatch avant I/O
|
||||
|
||||
@@ -602,6 +609,16 @@ cargo tree -p ksp-store-postgres-lib --edges normal
|
||||
cargo tree --duplicates
|
||||
```
|
||||
|
||||
Gate PostgreSQL réel `pre.008` après les gates déterministes :
|
||||
|
||||
```bash
|
||||
read -rsp "Dedicated PostgreSQL URI: " KSP_PG_TEST_URI; echo
|
||||
printf '%s\n' "$KSP_PG_TEST_URI" | cargo test -p ksp-store-postgres-lib --test postgres_foundation_live -- --ignored --nocapture --test-threads=1
|
||||
unset KSP_PG_TEST_URI
|
||||
```
|
||||
|
||||
`KSP_PG_TEST_URI` est ici une variable shell non exportée servant uniquement à masquer la saisie ; le test lit exclusivement stdin et ne lit aucun environnement.
|
||||
|
||||
Gate technique final :
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user