Files
khadhroony-solana-project/docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md
2026-08-29 19:33:43 +02:00

19 KiB

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 :

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 :

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 :

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é

Le gate opérateur après application de pre.001, fourni le 29 août 2026, est vert : audits Rust/Markdown, cargo check --workspace et cargo clippy --workspace --all-targets passent sur 0.3.2-pre.1.

Le gate opérateur de pre.002, fourni le 29 août 2026, confirme également les tests ciblés, --no-default-features et les cargo tree. cargo check/Clippy terminent avec succès mais signalent deux warnings par nouvelle crate (TRACING_TARGET importé mais inutilisé et constant dead_code) ; pre.002-fix.001 traite cet écart par un canari compile-time privé, tout en conservant les invariants KSP-TRACE-102/103 et sans ajouter de logging runtime.

Le gate opérateur de pre.002-fix.001, fourni le 29 août 2026, est entièrement vert et sans warning : audits Rust/Markdown, workspace check/Clippy, tests des deux crates et compilation ksp-store-lib --no-default-features passent. Cette base est l'entrée effective de pre.003.

Le gate opérateur de pre.003-fix.001, fourni le 29 août 2026, est entièrement vert : audits Rust/Markdown, workspace check/Clippy, tests ksp-store-lib avec et sans feature par défaut, tests backend et compilation --no-default-features passent. Cette base est l'entrée effective de pre.004.

Le gate opérateur de pre.004-fix.001, après correction manuelle des commentaires .env.example, est entièrement vert : audits Rust/Markdown, workspace check/Clippy, 126 tests ksp-config-lib, ownership, ksp-store-lib avec et sans feature PostgreSQL, compilation --no-default-features et 63 tests Config Desk passent. Cette base est l'entrée effective de pre.005.

3. Frontières Cargo

V32-DEP-001 — Façade -> API

ksp-store-lib -> ksp-store-api

Matérialisé par 0.3.2-pre.002 dans le manifest de ksp-store-lib.

Statut : PASS pre.002 opérateur — test ciblé et cargo tree fournis.

V32-DEP-002 — Backend -> API

ksp-store-postgres-lib -> ksp-store-api

Matérialisé par 0.3.2-pre.002 dans le manifest de ksp-store-postgres-lib.

Statut : PASS pre.002 opérateur — test ciblé et cargo tree fournis.

V32-DEP-003 — Pas de cycle backend

ksp-store-postgres-lib -X-> ksp-store-lib

Preuves : manifest scanner + cargo tree.

Le canari source de pre.002 interdit explicitement la dépendance inverse ; le cargo tree opérateur confirme l'absence de cycle. La frontière sera durcie à nouveau en pre.009.

Statut : PASS pre.002 opérateur / TODO pre.009 final.

V32-DEP-004 — Feature PostgreSQL

Critères :

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

Le manifest de ksp-store-lib matérialise default = ["postgres"] et l'optional dependency ksp-store-postgres-lib. La compilation sans default feature est une preuve opérateur obligatoire.

Statut : PASS pre.002 opérateur — default feature, optional backend edge et compilation --no-default-features confirmés.

V32-DEP-005 — Firewall domaines

Interdictions :

Store/backend -> Config
Store/backend -> Transport
Store/backend -> Program
Store/backend -> Materializer
consumer ordinaire -> ksp-store-postgres-lib

Matérialisé par pre.005 : les types physiques nécessaires sont publics uniquement dans la crate backend pour la frontière inter-crates et ne sont jamais réexportés par ksp-store-lib; Pool/Client/Row/Statement restent absents de sa crate-root.

Statut : TODO gate opérateur pre.005 / TODO pre.009.

V32-DEP-006 — ksp-store-api non régressé

Critères :

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.

Matérialisé par pre.003 : StoreSettings, StoreBackendSettings, PostgresStoreSettings, pool/bootstrap/TLS typés, sans dépendance Config/serde/env.

Statut : PASS pre.003-fix.001 opérateur.

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.

Matérialisé par pre.003 : le test feature_mismatch appelle réellement Store::open sous --no-default-features et exige store.backend_not_compiled.

Statut : PASS pre.003-fix.001 opérateur / TODO pre.009 final.

V32-API-003 — Aucun type backend physique public

Interdits dans crate-root ksp-store-lib :

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.

pre.003 réexporte explicitement les 60 symboles crate-root acquis de ksp-store-api depuis ksp-store-lib, sans glob et sans réexport backend.

Statut : PASS pre.003-fix.001 opérateur / TODO pre.009 exact exports.

V32-API-005 — Lifecycle

Critères :

Store::open async
Store::close(self) async
pas de pool/client échappé
close borné
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 / TODO gate opérateur pre.005 pour l'ouverture et le shutdown physiques / TODO pre.007 pour la composition health.

5. Config ownership

V32-CONFIG-001 — Document/schema/example

Critères :

std.store enregistré
schema V1 valide
example valide
profiles/targets nommés typés
un réseau explicite par target
backend postgres explicite

Matérialisé par pre.004 puis corrigé par pre.004-fix.001 avec cfg.std.store / schema.std.store, trois targets committed devnet/mainnet/testnet, default_profile = devnet, un network explicite par target et des URI PostgreSQL séparées.

Statut : PASS pre.004-fix.001 opérateur.

V32-CONFIG-002 — Secrets/provenance

Critères :

KSP_SECRET_STORE_{DEVNET,MAINNET,TESTNET}_POSTGRES_URI classés Secret
safe projection redacted
provenance sans valeur
dotenv inventory à jour

Matérialisé par pre.004-fix.001 : les trois URI réseau-spécifiques sont inventoriées, chaque fallback reste Secret, la safe projection est redacted et la provenance n'embarque aucune valeur.

Statut : PASS pre.004-fix.001 opérateur.

V32-CONFIG-002B — Target/réseau sans multiplexage

Critères :

profile_id std.store = identifiant de target Store
default_profile choisit exactement un target
StoreSettings porte exactement un RawNetworkId
résolution explicite mainnet/devnet/testnet retourne URI + network du target choisi
ksp-store-lib ne possède aucun routeur multi-target/multi-réseau
future RAW mismatch Store.network != entity/query.network rejeté avant I/O

Matérialisé contractuellement par pre.004-fix.001; l'enforcement sur opérations RAW sera exercé dans 0.3.3/0.3.4.

Statut : PASS pre.004-fix.001 opérateur pour la sélection target/réseau / TODO 0.3.3-0.3.4 pour le mismatch RAW.

V32-CONFIG-003 — No-env Store/backend

Critère : production sources ksp-store-lib et ksp-store-postgres-lib ne lisent aucun :

std::env
dotenv
KSP_*
KSPB_*
PG*
.pgpass

pre.004 renforce aussi le canari d'ownership avec les nouveaux filenames Store ; pre.004-fix.001 conserve cette frontière tout en ajoutant le réseau au contrat StoreSettings. Store/backend restent sans dépendance Config et sans lecture KSP/KSPB.

Statut : PASS pre.004-fix.001 opérateur / TODO pre.009.

V32-CONFIG-004 — Adapter Config -> Store

Critère : ksp-config-lib seul transforme un profil/target résolu en StoreSettings réseau-spécifique et ne transmet aucun secret dans diagnostics.

Matérialisé par pre.004 puis pre.004-fix.001 : seul ksp-config-lib dépend de ksp-store-lib avec default-features = false; il mappe le profile_id sélectionné vers un target, construit son RawNetworkId et ses settings backend sans forcer la feature backend.

Statut : PASS pre.004-fix.001 opérateur.

6. Pool et lifecycle PostgreSQL

V32-POOL-001 — Pool borné

Critères :

max_connections 1..64
wait/create/recycle timeouts bornés
aucune taille zéro
aucune valeur pathologique

Matérialisé par pre.005 : deadpool-postgres possède un pool max_size explicite et applique les deadlines wait/create/recycle; tokio-postgres::Config reçoit aussi le connect_timeout typé après parsing de l'URI.

Statut : TODO gate opérateur 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.

pre.005 délègue la création/recycle des connexions au Manager Deadpool retenu ; aucun tokio::spawn KSP n'est introduit dans Store. La preuve de non-régression détaillée reste au hardening.

Statut : TODO gate opérateur pre.005 / TODO 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.

Matérialisé par pre.005 : parsing/connexion/pool/TLS sont ramenés à une classification backend locale sans conserver le texte des erreurs externes ni l'URI. La façade mappe vers des codes store.postgres_* stables avec contexte statique sûr.

Statut : TODO gate opérateur pre.005.

V32-POOL-004 — Close

Critères :

pool fermé
nouvelles acquisitions refusées
shutdown respecte timeout
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 : TODO gate opérateur pre.005 / TODO pre.007/pre.008.

7. TLS

V32-TLS-001 — Modes exacts

Surface initiale :

Disabled
VerifyFull

Matérialisé par pre.005 : la surface physique accepte exactement Disabled et VerifyFull; l'URI parsée est ensuite normalisée vers SslMode::Disable ou SslMode::Require, donc elle ne peut pas modifier la policy typée.

Statut : TODO gate opérateur pre.005.

V32-TLS-002 — VerifyFull

Critères :

TLS requis
root store système
authenticité du certificat vérifiée
nom serveur vérifié
aucun fallback plaintext

Matérialisé par pre.005 : VerifyFull construit un rustls::RootCertStore à partir des roots système, utilise explicitement le provider AWS-LC, requiert un host TCP pour l'identité serveur, rejette hostaddr seul et les sockets Unix, et ne permet aucun fallback plaintext. Les erreurs de roots/certificats sont réduites à des compteurs sûrs.

Statut : TODO gate opérateur 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 :

ksp_store_schema_migrations

et aucune table métier RAW/CORE/DECODE/SPECIALIZED.

Statut : TODO pre.006.

V32-MIG-002 — Version/checksum

Critères :

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 :

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 :

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 :

#[ignore]
URI lue depuis stdin
aucun env requis
URI jamais imprimée

Statut : TODO pre.008.

V32-LIVE-002 — Non destructif

Critères :

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 :

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 :

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.

Les bornes backend-neutral décidées en pre.001 sont matérialisées et couvertes par tests unitaires en pre.003. Le parsing PostgreSQL et les timeouts physiques restent à pre.005.

Statut : PASS pre.003-fix.001 opérateur pour les bornes backend-neutral / TODO pre.005 / TODO pre.009 pour les timeouts physiques.

V32-SEC-004 — Feature mismatch avant I/O

pre.003 matérialise un canari d'intégration compilé avec et sans postgres. Sans feature, Store::open retourne le code stable store.backend_not_compiled avant tout chemin backend physique.

Statut : PASS pre.003-fix.001 opérateur / TODO 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 :

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 :

cargo test -p ksp-store-api
cargo test -p ksp-store-lib
cargo test -p ksp-store-lib --no-default-features
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 :

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 :

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.