v0.3.2-pre.011
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 344
|
# version: 345
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["crates/ksp-app-config-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib"]
|
members = ["crates/ksp-app-config-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.3.2-pre.10"
|
version = "0.3.2-pre.11"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: crates/ksp-config-lib/README.md -->
|
<!-- file: crates/ksp-config-lib/README.md -->
|
||||||
<!-- version: 10 -->
|
<!-- version: 11 -->
|
||||||
|
|
||||||
# ksp-config-lib
|
# ksp-config-lib
|
||||||
|
|
||||||
@@ -25,6 +25,7 @@ La crate centralise les documents JSON, leurs schemas, les profils et compositio
|
|||||||
- l'adapter du document Logging effectif vers `ksp_logging_lib::LoggingSettings` ;
|
- l'adapter du document Logging effectif vers `ksp_logging_lib::LoggingSettings` ;
|
||||||
- l'adapter du document Transport V1/V2/V3 vers `HttpTransportSettings`, `WsTransportSettings` et, en V3, `YellowstoneGrpcTransportSettings`, y compris redaction/provenance des URLs `KSP_SECRET_*` ;
|
- l'adapter du document Transport V1/V2/V3 vers `HttpTransportSettings`, `WsTransportSettings` et, en V3, `YellowstoneGrpcTransportSettings`, y compris redaction/provenance des URLs `KSP_SECRET_*` ;
|
||||||
- l'adapter de `cfg.std.offchain_transport` vers `ksp_offchain_transport_lib::MarketPriceService`, avec contrôle de provenance des credentials/public fields et sans rendre les limites provider configurables ;
|
- l'adapter de `cfg.std.offchain_transport` vers `ksp_offchain_transport_lib::MarketPriceService`, avec contrôle de provenance des credentials/public fields et sans rendre les limites provider configurables ;
|
||||||
|
- l'adapter de `cfg.std.store` vers `ksp_store_lib::StoreSettings`, avec sélection d'un target nommé, réseau explicite et URI PostgreSQL à provenance `Secret` ;
|
||||||
- la surface de management pour inspecter et réparer les sources Config enregistrées, modifier `std.logging.json`, consulter les rapports d'environnement, révéler explicitement une valeur réelle et modifier `.env` ;
|
- la surface de management pour inspecter et réparer les sources Config enregistrées, modifier `std.logging.json`, consulter les rapports d'environnement, révéler explicitement une valeur réelle et modifier `.env` ;
|
||||||
- les écritures atomiques JSON/`.env` et la protection des permissions `.env` ;
|
- les écritures atomiques JSON/`.env` et la protection des permissions `.env` ;
|
||||||
- les audits workspace empêchant les bypass d'ownership Config et les oublis dans `.env.example`.
|
- les audits workspace empêchant les bypass d'ownership Config et les oublis dans `.env.example`.
|
||||||
@@ -34,14 +35,17 @@ La crate centralise les documents JSON, leurs schemas, les profils et compositio
|
|||||||
Le registre par défaut connaît :
|
Le registre par défaut connaît :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
cfg.composite.ksp-app-solprices-desk -> config/composite.ksp-app-solprices-desk.json
|
||||||
cfg.composite.ksp-app-wallet-desk -> config/composite.ksp-app-wallet-desk.json
|
cfg.composite.ksp-app-wallet-desk -> config/composite.ksp-app-wallet-desk.json
|
||||||
cfg.std.logging -> config/std.logging.json
|
cfg.std.logging -> config/std.logging.json
|
||||||
cfg.std.offchain_transport -> config/std.offchain_transport.json
|
cfg.std.offchain_transport -> config/std.offchain_transport.json
|
||||||
|
cfg.std.store -> config/std.store.json
|
||||||
cfg.std.transport -> config/std.transport.json
|
cfg.std.transport -> config/std.transport.json
|
||||||
cfg.std.wallet -> config/std.wallet.json
|
cfg.std.wallet -> config/std.wallet.json
|
||||||
schema.composite -> config/schemas/composite.schema.json
|
schema.composite -> config/schemas/composite.schema.json
|
||||||
schema.std.logging -> config/schemas/std.logging.schema.json
|
schema.std.logging -> config/schemas/std.logging.schema.json
|
||||||
schema.std.offchain_transport -> config/schemas/std.offchain_transport.schema.json
|
schema.std.offchain_transport -> config/schemas/std.offchain_transport.schema.json
|
||||||
|
schema.std.store -> config/schemas/std.store.schema.json
|
||||||
schema.std.transport -> config/schemas/std.transport.schema.json
|
schema.std.transport -> config/schemas/std.transport.schema.json
|
||||||
schema.std.wallet -> config/schemas/std.wallet.schema.json
|
schema.std.wallet -> config/schemas/std.wallet.schema.json
|
||||||
```
|
```
|
||||||
@@ -50,7 +54,7 @@ schema.std.wallet -> config/schemas/std.wallet.schema.json
|
|||||||
|
|
||||||
`ConfigManagement::read_source()` permet d'inspecter le texte brut d'un document Config enregistré même lorsque ce document est invalide. `save_source_candidate()` complète cette frontière : le candidat brut est parsé, validé contre son schema et les invariants sémantiques KSP, puis persisté atomiquement uniquement après validation complète. Le `file_id` doit appartenir au registre et désigner un document Config ; aucun path arbitraire n'est accepté.
|
`ConfigManagement::read_source()` permet d'inspecter le texte brut d'un document Config enregistré même lorsque ce document est invalide. `save_source_candidate()` complète cette frontière : le candidat brut est parsé, validé contre son schema et les invariants sémantiques KSP, puis persisté atomiquement uniquement après validation complète. Le `file_id` doit appartenir au registre et désigner un document Config ; aucun path arbitraire n'est accepté.
|
||||||
|
|
||||||
`config/examples/composite.example.json` conserve l’exemple générique. `config/composite.ksp-app-wallet-desk.json` est le premier composite runtime concret : il sélectionne Logging, Transport et Wallet par `file_id`, sans dépendre de leurs filenames physiques.
|
`config/examples/composite.example.json` conserve l’exemple générique. Les composites runtime committed restent possédés par Config : `config/composite.ksp-app-solprices-desk.json` sélectionne Logging + Off-chain Transport, tandis que `config/composite.ksp-app-wallet-desk.json` sélectionne Logging + Off-chain Transport + On-chain Transport + Wallet. Tous référencent leurs documents par `file_id`, sans dépendre de filenames physiques.
|
||||||
|
|
||||||
Le fichier local d'environnement est :
|
Le fichier local d'environnement est :
|
||||||
|
|
||||||
@@ -68,11 +72,11 @@ Les autres crates et applications KSP ne doivent pas :
|
|||||||
- parser ou écrire directement `.env` ;
|
- parser ou écrire directement `.env` ;
|
||||||
- ouvrir directement les documents Config connus par leur filename physique ;
|
- ouvrir directement les documents Config connus par leur filename physique ;
|
||||||
- réimplémenter la sélection de profils, les compositions ou les placeholders ;
|
- réimplémenter la sélection de profils, les compositions ou les placeholders ;
|
||||||
- reconstruire elles-mêmes la configuration Logging, On-chain Transport, Off-chain Transport ou Wallet depuis le JSON.
|
- reconstruire elles-mêmes la configuration Logging, On-chain Transport, Off-chain Transport, Store ou Wallet depuis le JSON.
|
||||||
|
|
||||||
`ksp-config-lib` dépend de `ksp-core-lib` pour `Error`/`Result`, de `ksp-logging-lib` pour les événements Config utiles et le contrat `LoggingSettings`, de `ksp-onchain-transport-lib` pour construire le contrat runtime On-chain Transport et de `ksp-offchain-transport-lib` pour construire le service market-price dans la direction Config -> Transport. Le document Wallet reste un contrat de chemins/profils Config et n’introduit aucune dépendance Config -> `ksp-wallet-lib`.
|
`ksp-config-lib` dépend de `ksp-core-lib` pour `Error`/`Result`, de `ksp-logging-lib` pour les événements Config utiles et le contrat `LoggingSettings`, de `ksp-onchain-transport-lib` pour construire le contrat runtime On-chain Transport et de `ksp-offchain-transport-lib` pour construire le service market-price dans la direction Config -> Transport et de `ksp-store-lib` avec `default-features = false` pour construire les settings Store dans la direction Config -> Store sans forcer un backend physique. Le document Wallet reste un contrat de chemins/profils Config et n’introduit aucune dépendance Config -> `ksp-wallet-lib`.
|
||||||
|
|
||||||
La dépendance inverse est interdite : `ksp-core-lib`, `ksp-logging-lib`, `ksp-onchain-transport-lib` et `ksp-offchain-transport-lib` ne dépendent pas de Config.
|
La dépendance inverse est interdite : `ksp-core-lib`, `ksp-logging-lib`, `ksp-onchain-transport-lib`, `ksp-offchain-transport-lib` et les crates Store ne dépendent pas de Config.
|
||||||
|
|
||||||
Config ne possède pas le `LoggingGuard`. L'application ou le service qui orchestre le runtime construit la configuration effective puis possède le lifecycle `ksp_logging_lib::initialize/reinitialize`.
|
Config ne possède pas le `LoggingGuard`. L'application ou le service qui orchestre le runtime construit la configuration effective puis possède le lifecycle `ksp_logging_lib::initialize/reinitialize`.
|
||||||
|
|
||||||
@@ -84,7 +88,7 @@ Un secret reste accessible au runtime ou au management lorsqu'un consumer autori
|
|||||||
|
|
||||||
Les méthodes `reveal_*` constituent un opt-in explicite au réel. L'authentification/autorisation de l'utilisateur humain appartient à l'application appelante et les valeurs retournées par ces méthodes ne doivent jamais être journalisées.
|
Les méthodes `reveal_*` constituent un opt-in explicite au réel. L'authentification/autorisation de l'utilisateur humain appartient à l'application appelante et les valeurs retournées par ces méthodes ne doivent jamais être journalisées.
|
||||||
|
|
||||||
Le document Logging refuse les valeurs de sensibilité `Secret` dans sa configuration effective. Le document Transport accepte les valeurs secrètes pour les URLs HTTP/WebSocket et, en V3, pour `grpc_endpoints[].secret_metadata[]` : la valeur réelle est transmise au runtime légitime, tandis que la projection sûre et les `Debug` restent redacted. Les metadata gRPC publiques et secrètes sont séparées et leur provenance Config est contrôlée avant mapping. `std.offchain_transport` exige une provenance `Secret` pour les API keys effectives et une provenance `Public` pour la paire DexScreener lorsqu'elle vient de l'environnement ; il ne permet ni URL provider arbitraire ni override de rate limit. `std.wallet` refuse également toute sensibilité `Secret` pour `wallets_directory`/`wallets_subdirectory`; les passwords Wallet restent un autre flux Config et ne sont jamais stockés dans ce JSON.
|
Le document Logging refuse les valeurs de sensibilité `Secret` dans sa configuration effective. Le document Transport accepte les valeurs secrètes pour les URLs HTTP/WebSocket et, en V3, pour `grpc_endpoints[].secret_metadata[]` : la valeur réelle est transmise au runtime légitime, tandis que la projection sûre et les `Debug` restent redacted. Les metadata gRPC publiques et secrètes sont séparées et leur provenance Config est contrôlée avant mapping. `std.offchain_transport` exige une provenance `Secret` pour les API keys effectives et une provenance `Public` pour la paire DexScreener lorsqu'elle vient de l'environnement ; il ne permet ni URL provider arbitraire ni override de rate limit. `std.store` exige une provenance `Secret` pour chaque URI PostgreSQL effective et conserve des targets réseau-spécifiques indépendants (`devnet`, `mainnet`, `testnet`) sans exposer l'URI dans les projections sûres. `std.wallet` refuse également toute sensibilité `Secret` pour `wallets_directory`/`wallets_subdirectory`; les passwords Wallet restent un autre flux Config et ne sont jamais stockés dans ce JSON.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
@@ -94,6 +98,8 @@ Le document Logging refuse les valeurs de sensibilité `Secret` dans sa configur
|
|||||||
- [`../../config/std.logging.json`](../../config/std.logging.json) — document standard Logging ;
|
- [`../../config/std.logging.json`](../../config/std.logging.json) — document standard Logging ;
|
||||||
- [`../../config/std.transport.json`](../../config/std.transport.json) — document standard Transport V3 HTTP + WebSocket + Yellowstone gRPC, avec lecture backward des V1/V2 ;
|
- [`../../config/std.transport.json`](../../config/std.transport.json) — document standard Transport V3 HTTP + WebSocket + Yellowstone gRPC, avec lecture backward des V1/V2 ;
|
||||||
- [`../../config/std.offchain_transport.json`](../../config/std.offchain_transport.json) — document standard Off-chain Transport V1, actuellement limité au domaine `market_price` SOL/USD ;
|
- [`../../config/std.offchain_transport.json`](../../config/std.offchain_transport.json) — document standard Off-chain Transport V1, actuellement limité au domaine `market_price` SOL/USD ;
|
||||||
|
- [`../../config/std.store.json`](../../config/std.store.json) — targets Store PostgreSQL Devnet/Mainnet/Testnet et settings runtime bornés ;
|
||||||
- [`../../config/std.wallet.json`](../../config/std.wallet.json) — racine Wallet globale et sous-répertoire optionnel par profil ;
|
- [`../../config/std.wallet.json`](../../config/std.wallet.json) — racine Wallet globale et sous-répertoire optionnel par profil ;
|
||||||
- [`../../config/composite.ksp-app-wallet-desk.json`](../../config/composite.ksp-app-wallet-desk.json) — composition Logging/Transport/Wallet de Wallet Desk ;
|
- [`../../config/composite.ksp-app-solprices-desk.json`](../../config/composite.ksp-app-solprices-desk.json) — composition Logging/Off-chain Transport de SOL Prices Desk ;
|
||||||
|
- [`../../config/composite.ksp-app-wallet-desk.json`](../../config/composite.ksp-app-wallet-desk.json) — composition Logging/Off-chain Transport/On-chain Transport/Wallet de Wallet Desk ;
|
||||||
- [`../../.env.example`](../../.env.example) — inventaire versionné des variables d'environnement runtime.
|
- [`../../.env.example`](../../.env.example) — inventaire versionné des variables d'environnement runtime.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: crates/ksp-config-lib/USAGE.md -->
|
<!-- file: crates/ksp-config-lib/USAGE.md -->
|
||||||
<!-- version: 13 -->
|
<!-- version: 14 -->
|
||||||
|
|
||||||
# Utilisation de ksp-config-lib
|
# Utilisation de ksp-config-lib
|
||||||
|
|
||||||
@@ -28,8 +28,11 @@ Les arguments compris par Config sont :
|
|||||||
```text
|
```text
|
||||||
--cfgpath=/path/to/config
|
--cfgpath=/path/to/config
|
||||||
--schemapath=/path/to/schemas
|
--schemapath=/path/to/schemas
|
||||||
|
--filemap=cfg.composite.ksp-app-solprices-desk=my-solprices-desk.json
|
||||||
--filemap=cfg.composite.ksp-app-wallet-desk=my-wallet-desk.json
|
--filemap=cfg.composite.ksp-app-wallet-desk=my-wallet-desk.json
|
||||||
--filemap=cfg.std.logging=my-logging.json
|
--filemap=cfg.std.logging=my-logging.json
|
||||||
|
--filemap=cfg.std.offchain_transport=my-offchain-transport.json
|
||||||
|
--filemap=cfg.std.store=my-store.json
|
||||||
--filemap=cfg.std.transport=my-transport.json
|
--filemap=cfg.std.transport=my-transport.json
|
||||||
--filemap=cfg.std.wallet=my-wallet.json
|
--filemap=cfg.std.wallet=my-wallet.json
|
||||||
```
|
```
|
||||||
@@ -212,7 +215,56 @@ Config ne permet pas de fournir `base_url`, `endpoint_url`, `rate_limit` ou `req
|
|||||||
ksp-config-lib -> ksp-offchain-transport-lib
|
ksp-config-lib -> ksp-offchain-transport-lib
|
||||||
```
|
```
|
||||||
|
|
||||||
Off-chain Transport ne lit ni `.env`, ni `KSP_*`, ni les documents Config. Une application telle que la future `ksp-app-solprices-desk` peut recevoir le service déjà composé puis utiliser uniquement `registry()`, `refresh`, `refresh_many` et `refresh_all`.
|
Off-chain Transport ne lit ni `.env`, ni `KSP_*`, ni les documents Config. `ksp-app-solprices-desk` reçoit le service déjà composé puis utilise uniquement la surface provider-neutral `registry()`, `refresh`, `refresh_many` et `refresh_all`.
|
||||||
|
|
||||||
|
### 4.4 Construire le Store depuis Config
|
||||||
|
|
||||||
|
`cfg.std.store` définit des targets nommés. Chaque target sélectionne exactement un réseau logique, un backend et une URI PostgreSQL distincte. Config résout les secrets puis construit le contrat backend-neutral `ksp_store_lib::StoreSettings` sans activer la feature PostgreSQL du consumer :
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let store_config = match engine.load_resolved_store_config(
|
||||||
|
std::option::Option::Some("devnet"),
|
||||||
|
&environment,
|
||||||
|
) {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||||
|
};
|
||||||
|
|
||||||
|
let target_id = store_config.target_id();
|
||||||
|
let network = store_config.settings().network();
|
||||||
|
let _ = (target_id, network);
|
||||||
|
|
||||||
|
let store_settings = store_config.into_settings();
|
||||||
|
let store = match ksp_store_lib::Store::open(store_settings).await {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||||
|
};
|
||||||
|
let _health = store.health().await;
|
||||||
|
let closed = store.close().await;
|
||||||
|
if let std::result::Result::Err(error) = closed {
|
||||||
|
return std::result::Result::Err(error);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Targets committed :
|
||||||
|
|
||||||
|
```text
|
||||||
|
devnet -> network devnet -> KSP_SECRET_STORE_DEVNET_POSTGRES_URI
|
||||||
|
mainnet -> network mainnet-beta -> KSP_SECRET_STORE_MAINNET_POSTGRES_URI
|
||||||
|
testnet -> network testnet -> KSP_SECRET_STORE_TESTNET_POSTGRES_URI
|
||||||
|
```
|
||||||
|
|
||||||
|
`default_profile = "devnet"` choisit un seul target. La sélection d'un autre target se fait par le `profile_id` explicite ; `ksp-store-lib` ne multiplexe pas plusieurs bases ou réseaux dans une même instance.
|
||||||
|
|
||||||
|
Chaque `connection_uri` doit provenir d'un placeholder `KSP_SECRET_*`/`KSPB_SECRET_*`. Une URI littérale ou issue d'une variable non secrète est rejetée par l'adapter effectif. La valeur réelle est transmise au runtime Store, mais `ResolvedStoreConfig`, `StoreSettings` et les projections sûres ne l'affichent pas.
|
||||||
|
|
||||||
|
La direction de dépendance reste :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ksp-config-lib -> ksp-store-lib (default-features = false)
|
||||||
|
ksp-store-lib -X-> ksp-config-lib
|
||||||
|
ksp-store-postgres-lib -X-> ksp-config-lib
|
||||||
|
```
|
||||||
|
|
||||||
## 5. Profils et composites
|
## 5. Profils et composites
|
||||||
|
|
||||||
@@ -237,7 +289,7 @@ let component = match composite.component("wallet") {
|
|||||||
let wallet = engine.resolve_wallet_config_profile(component.resolved(), &environment);
|
let wallet = engine.resolve_wallet_config_profile(component.resolved(), &environment);
|
||||||
```
|
```
|
||||||
|
|
||||||
La même forme existe pour Logging via `resolve_logging_config_profile`. Le composite concret `cfg.composite.ksp-app-wallet-desk` référence actuellement `logging`, `transport` et `wallet`; Wallet Desk valide ces trois frontières au bootstrap.
|
La même forme existe pour Logging via `resolve_logging_config_profile`. Le composite `cfg.composite.ksp-app-solprices-desk` référence `logging` et `offchain_transport`. Le composite `cfg.composite.ksp-app-wallet-desk` référence `logging`, `offchain_transport`, `transport` et `wallet`; chaque application valide ses frontières de composition au bootstrap.
|
||||||
|
|
||||||
## 6. Management de `std.logging.json`
|
## 6. Management de `std.logging.json`
|
||||||
|
|
||||||
|
|||||||
95
crates/ksp-store-lib/README.md
Normal file
95
crates/ksp-store-lib/README.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<!-- file: crates/ksp-store-lib/README.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# ksp-store-lib
|
||||||
|
|
||||||
|
`ksp-store-lib` est la façade runtime Store commune de KSP.
|
||||||
|
|
||||||
|
Elle expose aux consumers une surface backend-neutral, réexporte les contrats RAW de `ksp-store-api`, sélectionne uniquement les backends compilés et masque leurs objets physiques. Le backend PostgreSQL officiel est activé par défaut via la feature `postgres` et reste implémenté dans `ksp-store-postgres-lib`.
|
||||||
|
|
||||||
|
## Responsabilités
|
||||||
|
|
||||||
|
`ksp-store-lib` possède :
|
||||||
|
|
||||||
|
- `StoreSettings`, avec un réseau logique unique, un backend sélectionné et un timeout de fermeture borné ;
|
||||||
|
- les settings PostgreSQL publics KSP-owned : pool, TLS, bootstrap/migrations et URI sensible ;
|
||||||
|
- la feature `postgres` par défaut et le comportement explicite `backend_not_compiled` lorsque PostgreSQL est sélectionné sans cette feature ;
|
||||||
|
- `Store::open`, qui ne retourne une instance qu'après validation, ouverture physique du backend compilé et bootstrap/history réussis ;
|
||||||
|
- `Store::runtime_snapshot()` pour les compteurs runtime sûrs sans I/O ;
|
||||||
|
- `Store::health().await` pour la readiness portable et bornée ;
|
||||||
|
- `Store::close(self).await` pour la fermeture explicite bornée ;
|
||||||
|
- le mapping des erreurs backend vers des codes Store stables sans exposer les erreurs physiques ;
|
||||||
|
- les réexports crate-root de `ksp-store-api` nécessaires aux consumers ordinaires.
|
||||||
|
|
||||||
|
## Une instance = un réseau
|
||||||
|
|
||||||
|
Une instance `Store` représente exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
1 Store = 1 RawNetworkId + 1 backend physique sélectionné
|
||||||
|
```
|
||||||
|
|
||||||
|
Le runtime Store n'est pas un multiplexeur multi-database ou multi-réseau. La sélection d'un target nommé appartient à Config. Le document `std.store` peut donc définir plusieurs targets indépendants — par exemple Devnet, Mainnet et Testnet — mais un appel à `Store::open` reçoit les settings d'un seul target.
|
||||||
|
|
||||||
|
Cette séparation permet d'utiliser des bases PostgreSQL distinctes par réseau tout en conservant le réseau dans l'identité logique des données RAW.
|
||||||
|
|
||||||
|
## PostgreSQL
|
||||||
|
|
||||||
|
Avec la feature par défaut :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ksp-store-lib
|
||||||
|
-> ksp-store-api
|
||||||
|
-> ksp-logging-lib
|
||||||
|
-> ksp-store-postgres-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
`ksp-store-lib` ne réexporte aucun type `tokio-postgres`, Deadpool ou Rustls.
|
||||||
|
|
||||||
|
Les modes TLS publics sont volontairement limités à :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Disabled
|
||||||
|
VerifyFull
|
||||||
|
```
|
||||||
|
|
||||||
|
`VerifyFull` impose TLS avec vérification de la chaîne et de l'identité serveur. La policy typée Store prime sur les paramètres TLS présents dans l'URI.
|
||||||
|
|
||||||
|
## Config et secrets
|
||||||
|
|
||||||
|
Store ne lit ni `.env`, ni variables `KSP_*` / `KSPB_*`, ni variables/fichiers implicites libpq (`PG*`, `.pgpass`, fichiers TLS PostgreSQL).
|
||||||
|
|
||||||
|
`ksp-config-lib` possède `std.store`, la résolution des secrets et la sélection du target. Il construit ensuite un `StoreSettings` backend-neutral. L'URI PostgreSQL reste nécessaire au runtime mais n'a aucun getter public dans `ksp-store-lib` et son `Debug` est redacted.
|
||||||
|
|
||||||
|
Les targets committed sont actuellement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
devnet -> network devnet -> base indépendante
|
||||||
|
mainnet -> network mainnet-beta -> base indépendante
|
||||||
|
testnet -> network testnet -> base indépendante
|
||||||
|
```
|
||||||
|
|
||||||
|
Les credentials restent dans les variables `KSP_SECRET_STORE_*_POSTGRES_URI` ou le `.env` possédé par Config.
|
||||||
|
|
||||||
|
## Surface actuelle et hors périmètre
|
||||||
|
|
||||||
|
La fondation runtime ne fournit encore aucune implémentation PostgreSQL des capabilities métier RAW de `ksp-store-api`.
|
||||||
|
|
||||||
|
Sont volontairement hors de cette surface :
|
||||||
|
|
||||||
|
- persistence/query/rétention PostgreSQL de `RawTransaction` ;
|
||||||
|
- persistence/query/rétention PostgreSQL de `RawAccountState` ;
|
||||||
|
- batch-size, priorité, backlog ou policy de worker/job ;
|
||||||
|
- transport d'acquisition, Program decoding et materialization ;
|
||||||
|
- exposition publique de SQL, pool, client, row, statement ou transaction PostgreSQL.
|
||||||
|
|
||||||
|
Les premières vertical slices métier sont ajoutées séparément afin que la façade runtime reste stable et backend-neutral.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- [`USAGE.md`](USAGE.md) — construction des settings, ouverture, health et fermeture ;
|
||||||
|
- [`../ksp-store-postgres-lib/README.md`](../ksp-store-postgres-lib/README.md) — responsabilité du backend PostgreSQL physique ;
|
||||||
|
- [`../../config/std.store.json`](../../config/std.store.json) — targets Store committed ;
|
||||||
|
- [`../../docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md`](../../docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md) — architecture durable Store ;
|
||||||
|
- [`../../docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md`](../../docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md) — plan de fondation ;
|
||||||
|
- [`../../docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md`](../../docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md) — matrice de validation.
|
||||||
219
crates/ksp-store-lib/USAGE.md
Normal file
219
crates/ksp-store-lib/USAGE.md
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
<!-- file: crates/ksp-store-lib/USAGE.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Utilisation de ksp-store-lib
|
||||||
|
|
||||||
|
## 1. Dépendance et features
|
||||||
|
|
||||||
|
Le consumer runtime normal dépend uniquement de la façade :
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
ksp-store-lib = { path = "../ksp-store-lib" }
|
||||||
|
```
|
||||||
|
|
||||||
|
La feature par défaut est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Pour construire un binaire sans backend physique :
|
||||||
|
|
||||||
|
```toml
|
||||||
|
ksp-store-lib = { path = "../ksp-store-lib", default-features = false }
|
||||||
|
```
|
||||||
|
|
||||||
|
Dans ce mode, le type PostgreSQL reste connu par la surface de settings mais `Store::open` retourne `ERROR_CODE_BACKEND_NOT_COMPILED` avant toute I/O si PostgreSQL est sélectionné.
|
||||||
|
|
||||||
|
Un consumer ordinaire ne dépend pas directement de `ksp-store-postgres-lib`.
|
||||||
|
|
||||||
|
## 2. Construire des settings PostgreSQL programmatiquement
|
||||||
|
|
||||||
|
La construction directe est utile pour les tests, outils internes ou compositions qui n'utilisent pas `ksp-config-lib`.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn programmatic_store_settings(connection_uri: std::string::String) -> ksp_store_lib::Result<ksp_store_lib::StoreSettings> {
|
||||||
|
let network = ksp_store_lib::RawNetworkId::new("devnet");
|
||||||
|
let network = match network {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||||
|
};
|
||||||
|
|
||||||
|
let postgres = ksp_store_lib::PostgresStoreSettings::new(
|
||||||
|
connection_uri,
|
||||||
|
ksp_store_lib::PostgresPoolSettings::default(),
|
||||||
|
ksp_store_lib::PostgresTlsMode::VerifyFull,
|
||||||
|
ksp_store_lib::PostgresBootstrapSettings::default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let settings = ksp_store_lib::StoreSettings::with_default_shutdown(
|
||||||
|
network,
|
||||||
|
ksp_store_lib::StoreBackendSettings::Postgres(postgres),
|
||||||
|
);
|
||||||
|
|
||||||
|
let validation = settings.validate();
|
||||||
|
if let std::result::Result::Err(error) = validation {
|
||||||
|
return std::result::Result::Err(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::result::Result::Ok(settings);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`PostgresStoreSettings` ne fournit volontairement aucun getter public de l'URI. Son `Debug` remplace cette valeur par `<redacted>`.
|
||||||
|
|
||||||
|
## 3. Ouvrir et fermer un Store
|
||||||
|
|
||||||
|
`Store::open` est async et ne retourne un succès qu'après que le backend compilé a prouvé sa fondation runtime.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
async fn use_store(settings: ksp_store_lib::StoreSettings) -> ksp_store_lib::Result<()> {
|
||||||
|
let store = ksp_store_lib::Store::open(settings).await;
|
||||||
|
let store = match store {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||||
|
};
|
||||||
|
|
||||||
|
let runtime = store.runtime_snapshot();
|
||||||
|
let _network = runtime.network();
|
||||||
|
let _capacity = runtime.pool_capacity();
|
||||||
|
let _size = runtime.pool_size();
|
||||||
|
let _available = runtime.pool_available();
|
||||||
|
let _waiting = runtime.pool_waiting();
|
||||||
|
|
||||||
|
let health = store.health().await;
|
||||||
|
match health.state() {
|
||||||
|
ksp_store_lib::StoreHealthState::Ready => {}
|
||||||
|
ksp_store_lib::StoreHealthState::NotReady => {
|
||||||
|
let _safe_error_code = health.last_error_code();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return store.close().await;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`Store::close(self)` consomme l'instance afin qu'une fermeture explicite ne puisse pas être suivie d'une nouvelle opération via la même valeur.
|
||||||
|
|
||||||
|
## 4. Construire les settings depuis Config
|
||||||
|
|
||||||
|
Le chemin applicatif recommandé utilise `ksp-config-lib`, propriétaire du document `std.store`, de `.env` et des secrets.
|
||||||
|
|
||||||
|
Après construction du `ConfigDocumentEngine` :
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn resolve_store_settings(
|
||||||
|
engine: &ksp_config_lib::ConfigDocumentEngine,
|
||||||
|
environment: &ksp_config_lib::ConfigEnvironment,
|
||||||
|
target: std::option::Option<&str>,
|
||||||
|
) -> ksp_core_lib::Result<ksp_store_lib::StoreSettings> {
|
||||||
|
let resolved = engine.load_resolved_store_config(target, environment);
|
||||||
|
let resolved = match resolved {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||||
|
};
|
||||||
|
|
||||||
|
return std::result::Result::Ok(resolved.into_settings());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Targets committed :
|
||||||
|
|
||||||
|
```text
|
||||||
|
devnet -> RawNetworkId("devnet")
|
||||||
|
mainnet -> RawNetworkId("mainnet-beta")
|
||||||
|
testnet -> RawNetworkId("testnet")
|
||||||
|
```
|
||||||
|
|
||||||
|
Chaque target peut utiliser une URI PostgreSQL distincte. `default_profile` sélectionne un seul target ; `Store` ne route pas automatiquement entre plusieurs targets.
|
||||||
|
|
||||||
|
## 5. Settings disponibles
|
||||||
|
|
||||||
|
### `PostgresPoolSettings`
|
||||||
|
|
||||||
|
Valeurs par défaut :
|
||||||
|
|
||||||
|
```text
|
||||||
|
max_connections 8
|
||||||
|
connect_timeout 10 s
|
||||||
|
wait_timeout 5 s
|
||||||
|
create_timeout 10 s
|
||||||
|
recycle_timeout 5 s
|
||||||
|
```
|
||||||
|
|
||||||
|
Les getters sont :
|
||||||
|
|
||||||
|
```text
|
||||||
|
max_connections()
|
||||||
|
connect_timeout()
|
||||||
|
wait_timeout()
|
||||||
|
create_timeout()
|
||||||
|
recycle_timeout()
|
||||||
|
```
|
||||||
|
|
||||||
|
`validate()` vérifie les bornes sans I/O.
|
||||||
|
|
||||||
|
### `PostgresBootstrapSettings`
|
||||||
|
|
||||||
|
Valeurs par défaut :
|
||||||
|
|
||||||
|
```text
|
||||||
|
auto_migrate true
|
||||||
|
migration_timeout 30 s
|
||||||
|
migration_lock_timeout 10 s
|
||||||
|
```
|
||||||
|
|
||||||
|
Getters :
|
||||||
|
|
||||||
|
```text
|
||||||
|
auto_migrate()
|
||||||
|
migration_timeout()
|
||||||
|
migration_lock_timeout()
|
||||||
|
```
|
||||||
|
|
||||||
|
### `StoreSettings`
|
||||||
|
|
||||||
|
La surface expose :
|
||||||
|
|
||||||
|
```text
|
||||||
|
backend()
|
||||||
|
backend_kind()
|
||||||
|
network()
|
||||||
|
shutdown_timeout()
|
||||||
|
validate()
|
||||||
|
```
|
||||||
|
|
||||||
|
`StoreSettings::new` permet de choisir explicitement le timeout de shutdown. `StoreSettings::with_default_shutdown` utilise la borne commune par défaut de 5 secondes.
|
||||||
|
|
||||||
|
## 6. Health et diagnostics
|
||||||
|
|
||||||
|
`StoreRuntimeSnapshot` est synchrone et ne déclenche aucune I/O. Il expose uniquement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
backend_kind
|
||||||
|
network
|
||||||
|
pool_capacity
|
||||||
|
pool_size
|
||||||
|
pool_available
|
||||||
|
pool_waiting
|
||||||
|
```
|
||||||
|
|
||||||
|
`StoreHealthSnapshot` ajoute une probe async bornée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
state = Ready | NotReady
|
||||||
|
migration_version
|
||||||
|
pending_migration_count
|
||||||
|
last_error_code
|
||||||
|
runtime snapshot
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun snapshot n'expose URI, host, user, database, SQL, handle backend ou texte d'erreur PostgreSQL.
|
||||||
|
|
||||||
|
## 7. Limite fonctionnelle actuelle
|
||||||
|
|
||||||
|
`ksp-store-lib` réexporte les modèles et traits RAW de `ksp-store-api`, mais le backend PostgreSQL de la fondation n'implémente encore aucune capability `RawTransaction*` ou `RawAccount*`.
|
||||||
|
|
||||||
|
Les consumers ne doivent donc pas interpréter la disponibilité du runtime PostgreSQL comme une persistence métier déjà présente.
|
||||||
124
crates/ksp-store-postgres-lib/README.md
Normal file
124
crates/ksp-store-postgres-lib/README.md
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<!-- file: crates/ksp-store-postgres-lib/README.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# ksp-store-postgres-lib
|
||||||
|
|
||||||
|
`ksp-store-postgres-lib` est le backend PostgreSQL physique officiel du Store KSP.
|
||||||
|
|
||||||
|
La crate implémente la fondation connexion/pool/TLS/migrations/health derrière `ksp-store-lib`. Elle dépend directement de `ksp-store-api` mais ne dépend jamais de la façade `ksp-store-lib`.
|
||||||
|
|
||||||
|
## Responsabilités
|
||||||
|
|
||||||
|
La crate possède seule pour PostgreSQL :
|
||||||
|
|
||||||
|
- le parsing et la normalisation de la configuration physique `tokio-postgres` ;
|
||||||
|
- le pool borné `deadpool-postgres` ;
|
||||||
|
- la policy TLS physique avec Rustls ;
|
||||||
|
- les roots système et le provider cryptographique AWS-LC ;
|
||||||
|
- le bootstrap/moteur de migrations privé KSP ;
|
||||||
|
- la table metadata `ksp_store_schema_migrations` ;
|
||||||
|
- le sentinel `V000__bootstrap.sql` et son checksum SHA-256 ;
|
||||||
|
- l'advisory transaction lock borné des migrations ;
|
||||||
|
- les snapshots runtime/health sûrs destinés au bridge de façade ;
|
||||||
|
- la fermeture explicite du pool et son fallback `Drop` best-effort ;
|
||||||
|
- la classification d'erreurs backend sans conserver le texte d'erreur PostgreSQL.
|
||||||
|
|
||||||
|
## Frontière d'utilisation
|
||||||
|
|
||||||
|
Les applications, jobs et workers KSP ne dépendent normalement pas de cette crate :
|
||||||
|
|
||||||
|
```text
|
||||||
|
consumer -> ksp-store-lib -> [feature postgres] ksp-store-postgres-lib
|
||||||
|
```
|
||||||
|
|
||||||
|
La surface publique de cette crate existe pour le bridge inter-crates et les tests d'intégration backend. Elle ne constitue pas une seconde façade Store.
|
||||||
|
|
||||||
|
`ksp-store-postgres-lib` ne réexporte pas `tokio-postgres`, Deadpool ou Rustls.
|
||||||
|
|
||||||
|
## Connexion et pool
|
||||||
|
|
||||||
|
`PostgresBackend::open` :
|
||||||
|
|
||||||
|
1. valide et normalise l'URI fournie explicitement ;
|
||||||
|
2. impose la policy TLS typée ;
|
||||||
|
3. construit un pool borné ;
|
||||||
|
4. prouve une connexion physique ;
|
||||||
|
5. vérifie/applique le bootstrap selon les settings ;
|
||||||
|
6. ne retourne qu'après succès de cette fondation.
|
||||||
|
|
||||||
|
Le backend ne lit aucun environnement, `.env`, `PG*`, `.pgpass` ou fichier TLS implicite libpq.
|
||||||
|
|
||||||
|
## TLS
|
||||||
|
|
||||||
|
Les modes sont exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Disabled
|
||||||
|
VerifyFull
|
||||||
|
```
|
||||||
|
|
||||||
|
`VerifyFull` exige :
|
||||||
|
|
||||||
|
- TLS ;
|
||||||
|
- roots système ;
|
||||||
|
- certificat valide ;
|
||||||
|
- vérification de l'identité serveur ;
|
||||||
|
- aucune dégradation automatique en plaintext.
|
||||||
|
|
||||||
|
Les configurations ne permettant pas de vérifier une identité serveur, comme `hostaddr` seul, sont rejetées.
|
||||||
|
|
||||||
|
## Migrations
|
||||||
|
|
||||||
|
La fondation embarque uniquement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
migrations/V000__bootstrap.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Elle crée la metadata privée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ksp_store_schema_migrations
|
||||||
|
```
|
||||||
|
|
||||||
|
Le moteur vérifie version, nom et checksum SHA-256, sérialise les runners par advisory transaction lock et refuse une history divergente ou plus récente que le runtime.
|
||||||
|
|
||||||
|
Aucune migration métier RAW n'appartient à cette fondation.
|
||||||
|
|
||||||
|
## Health et erreurs
|
||||||
|
|
||||||
|
`PostgresBackendRuntimeSnapshot` et `PostgresBackendHealthSnapshot` ne contiennent que des compteurs et états sûrs destinés à la façade.
|
||||||
|
|
||||||
|
`PostgresBackendError` ne conserve que :
|
||||||
|
|
||||||
|
```text
|
||||||
|
PostgresBackendErrorKind
|
||||||
|
phase statique
|
||||||
|
```
|
||||||
|
|
||||||
|
Le texte d'erreur PostgreSQL, l'URI, SQL et les valeurs bind ne traversent pas cette frontière.
|
||||||
|
|
||||||
|
## Support PostgreSQL
|
||||||
|
|
||||||
|
La politique de support de `0.3.2` fixe PostgreSQL 15 comme major minimal. Le test live de fondation refuse explicitement un serveur plus ancien ; le backend ne fixe aucun plafond arbitraire de major PostgreSQL. La compatibilité de migration reste basée sur le schéma KSP.
|
||||||
|
|
||||||
|
La preuve opérateur réelle et le major effectivement exercé sont conservés dans la matrice de validation, pas dans cette documentation durable.
|
||||||
|
|
||||||
|
## Hors périmètre actuel
|
||||||
|
|
||||||
|
La crate ne contient encore :
|
||||||
|
|
||||||
|
- aucune implémentation PostgreSQL des capabilities `RawTransaction*` ;
|
||||||
|
- aucune implémentation PostgreSQL des capabilities `RawAccount*` ;
|
||||||
|
- aucun repository métier RAW ;
|
||||||
|
- aucune table/index métier ;
|
||||||
|
- aucune orchestration worker/job ;
|
||||||
|
- aucun transport d'acquisition ou decoder Program.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- [`USAGE.md`](USAGE.md) — bridge physique et lifecycle ;
|
||||||
|
- [`../ksp-store-lib/README.md`](../ksp-store-lib/README.md) — façade runtime destinée aux consumers ;
|
||||||
|
- [`../../docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md`](../../docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md) — architecture Store ;
|
||||||
|
- [`../../docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md`](../../docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md) — décisions pool/TLS/migrations ;
|
||||||
|
- [`../../docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md`](../../docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md) — preuves déterministes et PostgreSQL réel.
|
||||||
155
crates/ksp-store-postgres-lib/USAGE.md
Normal file
155
crates/ksp-store-postgres-lib/USAGE.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<!-- file: crates/ksp-store-postgres-lib/USAGE.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Utilisation de ksp-store-postgres-lib
|
||||||
|
|
||||||
|
## 1. Quand utiliser cette crate directement
|
||||||
|
|
||||||
|
Le consumer applicatif normal utilise `ksp-store-lib`.
|
||||||
|
|
||||||
|
Une dépendance directe à `ksp-store-postgres-lib` est réservée aux composants qui implémentent ou testent le bridge physique PostgreSQL. La crate backend ne doit pas devenir une façade parallèle.
|
||||||
|
|
||||||
|
Un tel composant doit déclarer explicitement le backend et `ksp-store-api`, car `PostgresBackendSettings::new` reçoit le `RawNetworkId` backend-neutral sans le réexporter :
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
ksp-store-api = { path = "../ksp-store-api" }
|
||||||
|
ksp-store-postgres-lib = { path = "../ksp-store-postgres-lib" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Construire le bridge physique
|
||||||
|
|
||||||
|
`PostgresBackendSettings` reçoit des valeurs déjà possédées et validées par la couche appelante. L'URI est sensible et son `Debug` est redacted.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn backend_settings(
|
||||||
|
network: ksp_store_api::RawNetworkId,
|
||||||
|
connection_uri: std::string::String,
|
||||||
|
) -> ksp_store_postgres_lib::PostgresBackendSettings {
|
||||||
|
return ksp_store_postgres_lib::PostgresBackendSettings::new(
|
||||||
|
network,
|
||||||
|
connection_uri,
|
||||||
|
8,
|
||||||
|
std::time::Duration::from_secs(10),
|
||||||
|
std::time::Duration::from_secs(5),
|
||||||
|
std::time::Duration::from_secs(10),
|
||||||
|
std::time::Duration::from_secs(5),
|
||||||
|
ksp_store_postgres_lib::PostgresBackendTlsMode::VerifyFull,
|
||||||
|
true,
|
||||||
|
std::time::Duration::from_secs(30),
|
||||||
|
std::time::Duration::from_secs(10),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Le backend reçoit un seul `RawNetworkId`. Une instance physique n'est pas un routeur multi-réseau.
|
||||||
|
|
||||||
|
## 3. Ouvrir, sonder et fermer
|
||||||
|
|
||||||
|
```rust
|
||||||
|
async fn use_backend(
|
||||||
|
settings: ksp_store_postgres_lib::PostgresBackendSettings,
|
||||||
|
) -> std::result::Result<(), ksp_store_postgres_lib::PostgresBackendError> {
|
||||||
|
let backend = ksp_store_postgres_lib::PostgresBackend::open(settings).await;
|
||||||
|
let backend = match backend {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||||
|
};
|
||||||
|
|
||||||
|
let runtime = backend.runtime_snapshot();
|
||||||
|
let _capacity = runtime.pool_capacity();
|
||||||
|
let _size = runtime.pool_size();
|
||||||
|
let _available = runtime.pool_available();
|
||||||
|
let _waiting = runtime.pool_waiting();
|
||||||
|
|
||||||
|
let health = backend.health().await;
|
||||||
|
let _ready = health.ready();
|
||||||
|
let _migration_version = health.migration_version();
|
||||||
|
let _pending = health.pending_migration_count();
|
||||||
|
let _safe_error_kind = health.last_error_kind();
|
||||||
|
|
||||||
|
return backend.close(std::time::Duration::from_secs(5)).await;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`open` prouve la connexion et le bootstrap avant de retourner. `close` ferme le pool puis attend son drain dans la deadline fournie.
|
||||||
|
|
||||||
|
## 4. Choisir le mode TLS
|
||||||
|
|
||||||
|
### `VerifyFull`
|
||||||
|
|
||||||
|
À utiliser pour les connexions PostgreSQL protégées :
|
||||||
|
|
||||||
|
```rust
|
||||||
|
ksp_store_postgres_lib::PostgresBackendTlsMode::VerifyFull
|
||||||
|
```
|
||||||
|
|
||||||
|
Le backend charge les roots système et vérifie certificat + identité serveur. Il rejette une configuration ne fournissant pas d'identité vérifiable.
|
||||||
|
|
||||||
|
### `Disabled`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
ksp_store_postgres_lib::PostgresBackendTlsMode::Disabled
|
||||||
|
```
|
||||||
|
|
||||||
|
Ce mode désactive explicitement TLS. Il ne doit être utilisé que lorsque la topologie de déploiement justifie clairement une connexion non chiffrée.
|
||||||
|
|
||||||
|
La valeur typée choisie par KSP prime sur les paramètres SSL de l'URI.
|
||||||
|
|
||||||
|
## 5. Bootstrap et migrations
|
||||||
|
|
||||||
|
Le backend embarque son propre moteur de migrations. Le seul artefact initial est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
migrations/V000__bootstrap.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Le bootstrap maintient :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ksp_store_schema_migrations
|
||||||
|
version
|
||||||
|
name
|
||||||
|
checksum SHA-256
|
||||||
|
```
|
||||||
|
|
||||||
|
Le runner est transactionnel et sérialisé par advisory transaction lock. Une divergence de checksum/nom/version ou une history plus récente est terminale ; aucun down migration automatique n'est exécuté.
|
||||||
|
|
||||||
|
`auto_migrate = false` permet de vérifier l'état sans appliquer de migration pending.
|
||||||
|
|
||||||
|
## 6. Classifier les erreurs sans fuite
|
||||||
|
|
||||||
|
```rust
|
||||||
|
match error.kind() {
|
||||||
|
ksp_store_postgres_lib::PostgresBackendErrorKind::ConfigInvalid => {}
|
||||||
|
ksp_store_postgres_lib::PostgresBackendErrorKind::ConnectFailed => {}
|
||||||
|
ksp_store_postgres_lib::PostgresBackendErrorKind::PoolTimeout => {}
|
||||||
|
ksp_store_postgres_lib::PostgresBackendErrorKind::HealthFailed => {}
|
||||||
|
ksp_store_postgres_lib::PostgresBackendErrorKind::MigrationFailed => {}
|
||||||
|
ksp_store_postgres_lib::PostgresBackendErrorKind::MigrationMismatch => {}
|
||||||
|
ksp_store_postgres_lib::PostgresBackendErrorKind::SchemaNewer => {}
|
||||||
|
ksp_store_postgres_lib::PostgresBackendErrorKind::ShutdownTimeout => {}
|
||||||
|
ksp_store_postgres_lib::PostgresBackendErrorKind::TlsFailed => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _safe_phase = error.phase();
|
||||||
|
```
|
||||||
|
|
||||||
|
Ne pas reconstruire un diagnostic utilisateur à partir de l'erreur brute PostgreSQL : cette erreur n'est volontairement pas conservée par le bridge.
|
||||||
|
|
||||||
|
## 7. Ce que cette crate ne permet pas encore
|
||||||
|
|
||||||
|
La fondation physique n'implémente pas les traits `RawTransaction*` ou `RawAccount*` de `ksp-store-api`.
|
||||||
|
|
||||||
|
Un backend ouvert et healthy prouve uniquement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
connexion/pool
|
||||||
|
TLS selon policy
|
||||||
|
bootstrap/history
|
||||||
|
health/readiness
|
||||||
|
close borné
|
||||||
|
```
|
||||||
|
|
||||||
|
Il ne prouve aucune persistence métier RAW.
|
||||||
268
deltas/0.3.2/pre.011.md
Normal file
268
deltas/0.3.2/pre.011.md
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
<!-- file: deltas/0.3.2/pre.011.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta `0.3.2-pre.011` — réconciliation documentaire finale Store/PostgreSQL
|
||||||
|
|
||||||
|
## 1. Base requise
|
||||||
|
|
||||||
|
Base directe attendue :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.3.2-pre.010
|
||||||
|
```
|
||||||
|
|
||||||
|
Commit attendu :
|
||||||
|
|
||||||
|
```text
|
||||||
|
v0.3.2-pre.011
|
||||||
|
```
|
||||||
|
|
||||||
|
Archive overlay attendue :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ksp-general-0.3.2-pre.011.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette tranche suit le gate technique final `pre.010` et n'ajoute aucun comportement runtime.
|
||||||
|
|
||||||
|
## 2. Résultat du gate technique `pre.010`
|
||||||
|
|
||||||
|
Le gate opérateur `0.3.2-pre.010` a été rejoué après `cargo clean` et fournit les preuves suivantes :
|
||||||
|
|
||||||
|
```text
|
||||||
|
audits Rust PASS
|
||||||
|
cargo check --workspace PASS
|
||||||
|
cargo clippy --workspace --all-targets PASS
|
||||||
|
tests ciblés de toutes les crates PASS
|
||||||
|
ksp-store-lib default + --no-default-features PASS
|
||||||
|
cargo test --workspace PASS
|
||||||
|
graphes Cargo normal/features/duplicates exécutés
|
||||||
|
3 builds Tauri Linux PASS
|
||||||
|
PostgreSQL live foundation PASS — major 17
|
||||||
|
```
|
||||||
|
|
||||||
|
La ligne d'audit Markdown du journal opérateur `pre.010` a utilisé par erreur `deltas/0.3.1` au lieu de `deltas/0.3.2`. L'overlay `pre.010` avait été audité dans l'environnement de génération avec le chemin correct ; `pre.011` rejoue explicitement le scope complet `deltas/0.3.2`. Cette erreur de scope de commande ne constitue pas un défaut runtime et n'ouvre pas un `pre.010-fix`.
|
||||||
|
|
||||||
|
## 3. Objectif
|
||||||
|
|
||||||
|
Appliquer `VER-LIFECYCLE-006` et figer les documents durables de la fondation Store/PostgreSQL avant la préparation de publication minimale :
|
||||||
|
|
||||||
|
```text
|
||||||
|
README/USAGE ksp-store-lib
|
||||||
|
README/USAGE ksp-store-postgres-lib
|
||||||
|
README/USAGE ksp-config-lib pour std.store
|
||||||
|
index docs global
|
||||||
|
index plans
|
||||||
|
index validations
|
||||||
|
plan 023
|
||||||
|
validation 019
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette tranche ne finalise pas `CHANGELOG.md`, `ROADMAP.md` ni le prompt `0.3.3`.
|
||||||
|
|
||||||
|
## 4. Documentation de `ksp-store-lib`
|
||||||
|
|
||||||
|
Le nouveau README fixe durablement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
façade runtime backend-neutral
|
||||||
|
feature postgres par défaut
|
||||||
|
1 Store = 1 RawNetworkId + 1 backend physique
|
||||||
|
aucun multiplexage automatique de bases/réseaux
|
||||||
|
Config propriétaire des targets et secrets
|
||||||
|
aucun type PostgreSQL physique réexporté
|
||||||
|
aucune capability RAW PostgreSQL encore implémentée
|
||||||
|
```
|
||||||
|
|
||||||
|
Le nouveau USAGE documente :
|
||||||
|
|
||||||
|
```text
|
||||||
|
dépendance consumer normale uniquement vers ksp-store-lib
|
||||||
|
construction programmatique de StoreSettings
|
||||||
|
Store::open / runtime_snapshot / health / close
|
||||||
|
résolution recommandée via ksp-config-lib
|
||||||
|
settings pool/bootstrap/TLS
|
||||||
|
surface health sûre
|
||||||
|
limite fonctionnelle de la fondation
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Documentation de `ksp-store-postgres-lib`
|
||||||
|
|
||||||
|
Le README et le USAGE fixent la crate comme backend physique, non comme seconde façade :
|
||||||
|
|
||||||
|
```text
|
||||||
|
consumer ordinaire -X-> ksp-store-postgres-lib
|
||||||
|
bridge façade/tests seulement
|
||||||
|
pool Deadpool borné
|
||||||
|
TLS Disabled / VerifyFull via Rustls
|
||||||
|
roots système + AWS-LC
|
||||||
|
moteur de migrations KSP privé
|
||||||
|
V000 bootstrap + ksp_store_schema_migrations
|
||||||
|
history version/name/SHA-256 + advisory transaction lock
|
||||||
|
health/runtime snapshots sûrs
|
||||||
|
PostgresBackendError = kind + phase statique
|
||||||
|
aucune table/repository/capability RAW métier
|
||||||
|
```
|
||||||
|
|
||||||
|
La politique durable reste PostgreSQL >= 15 pour la validation de fondation ; le major effectivement exercé reste enregistré dans la matrice et non figé comme dépendance runtime maximale.
|
||||||
|
|
||||||
|
## 6. Réconciliation Config
|
||||||
|
|
||||||
|
`ksp-config-lib/README.md` et `USAGE.md` documentent désormais :
|
||||||
|
|
||||||
|
```text
|
||||||
|
cfg.std.store / schema.std.store
|
||||||
|
Config -> Store avec default-features = false
|
||||||
|
sélection de target nommée
|
||||||
|
RawNetworkId explicite
|
||||||
|
provenance Secret obligatoire de l'URI PostgreSQL
|
||||||
|
variables KSP_SECRET_STORE_DEVNET_POSTGRES_URI
|
||||||
|
KSP_SECRET_STORE_MAINNET_POSTGRES_URI
|
||||||
|
KSP_SECRET_STORE_TESTNET_POSTGRES_URI
|
||||||
|
targets committed devnet/mainnet/testnet
|
||||||
|
bases PostgreSQL indépendantes par target
|
||||||
|
absence de routage multi-target dans Store
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucune lecture d'environnement n'est déplacée vers Store/backend.
|
||||||
|
|
||||||
|
## 7. Indexes et documents de release
|
||||||
|
|
||||||
|
Les indexes durables référencent maintenant le plan `023` et la validation `019` ainsi que la documentation des deux crates runtime.
|
||||||
|
|
||||||
|
Le plan `023` enregistre le résultat réel de `pre.010`, la correction de scope Markdown à rejouer et la matérialisation documentaire de `pre.011`.
|
||||||
|
|
||||||
|
La matrice `019` est réconciliée avec les preuves réelles de `pre.002` à `pre.010`, y compris :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ksp-store-api non régressé
|
||||||
|
pool/TLS/bootstrap/health/close
|
||||||
|
hardening/security
|
||||||
|
feature mismatch
|
||||||
|
no-env
|
||||||
|
PostgreSQL live major 17 en pre.008 et pre.010
|
||||||
|
3 builds Tauri au gate final
|
||||||
|
aucun TODO technique applicable à 0.3.2
|
||||||
|
```
|
||||||
|
|
||||||
|
Le seul statut restant avant fermeture de `pre.011` est son propre gate documentaire opérateur.
|
||||||
|
|
||||||
|
## 8. Documents relus et volontairement inchangés
|
||||||
|
|
||||||
|
Les architectures suivantes ont été relues sur la surface finale `pre.010` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/architecture/003-COMPONENT_CONTRACTS.md
|
||||||
|
docs/architecture/004-COMPONENT_INVENTORY.md
|
||||||
|
docs/architecture/005-DEPENDENCY_GRAPH.md
|
||||||
|
docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Elles sont déjà cohérentes avec le split façade/backend et ne sont pas modifiées artificiellement.
|
||||||
|
|
||||||
|
Le choix documentaire de `0.3.1-pre.009` de ne pas créer un README/USAGE propre à `ksp-store-api` n'est pas rouvert par cette release runtime/backend.
|
||||||
|
|
||||||
|
## 9. Hors scope préservé
|
||||||
|
|
||||||
|
Aucun élément suivant n'est introduit :
|
||||||
|
|
||||||
|
```text
|
||||||
|
RawTransaction PostgreSQL persistence/query/retention
|
||||||
|
RawAccountState PostgreSQL persistence/query/retention
|
||||||
|
SQL métier RAW
|
||||||
|
repository métier
|
||||||
|
batch/backlog/priority worker/job
|
||||||
|
Store Desk
|
||||||
|
nouvelle migration
|
||||||
|
nouvelle dépendance
|
||||||
|
nouveau test fonctionnel
|
||||||
|
modification src/**
|
||||||
|
```
|
||||||
|
|
||||||
|
## 10. Fichiers ajoutés
|
||||||
|
|
||||||
|
```text
|
||||||
|
crates/ksp-store-lib/README.md
|
||||||
|
crates/ksp-store-lib/USAGE.md
|
||||||
|
crates/ksp-store-postgres-lib/README.md
|
||||||
|
crates/ksp-store-postgres-lib/USAGE.md
|
||||||
|
deltas/0.3.2/pre.011.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 11. Fichiers modifiés
|
||||||
|
|
||||||
|
```text
|
||||||
|
Cargo.toml
|
||||||
|
crates/ksp-config-lib/README.md
|
||||||
|
crates/ksp-config-lib/USAGE.md
|
||||||
|
docs/000-README.md
|
||||||
|
docs/plans/000-README.md
|
||||||
|
docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md
|
||||||
|
docs/validation/000-README.md
|
||||||
|
docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 12. Fichiers supprimés
|
||||||
|
|
||||||
|
```text
|
||||||
|
aucun
|
||||||
|
```
|
||||||
|
|
||||||
|
## 13. Version Cargo
|
||||||
|
|
||||||
|
La prerelease non-fix synchronise :
|
||||||
|
|
||||||
|
```text
|
||||||
|
workspace.package.version = 0.3.2-pre.11
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucune dépendance, feature ou configuration Cargo n'est modifiée en dehors de cette version.
|
||||||
|
|
||||||
|
## 14. Validation de génération
|
||||||
|
|
||||||
|
L'environnement de génération ne fournit pas `cargo`/`rustc`; aucun résultat Cargo local n'est donc déclaré PASS par ce delta.
|
||||||
|
|
||||||
|
Les audits Python applicables ont été rejoués après matérialisation de l'overlay, avec le chemin Markdown exact `deltas/0.3.2` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
General Rust rule audit: clean
|
||||||
|
Rust export completeness audit: 0 candidate(s)
|
||||||
|
KSP workspace Rust rule audit: clean
|
||||||
|
Markdown table audit: clean (186 table(s), 142 file(s))
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette preuve corrige explicitement le défaut de scope de la commande Markdown observé dans le journal opérateur `pre.010`.
|
||||||
|
|
||||||
|
## 15. Gate opérateur après application
|
||||||
|
|
||||||
|
```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
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
Le smoke PostgreSQL réel, les graphes Cargo complets, `cargo test --workspace` et les trois builds Tauri ne sont pas rejoués par nécessité dans cette tranche documentaire : ils sont déjà le gate technique vert de `pre.010` et `pre.011` ne modifie aucun code, dépendance, config runtime, resource Tauri ou migration.
|
||||||
|
|
||||||
|
## 16. Suite
|
||||||
|
|
||||||
|
Si le gate documentaire `pre.011` est vert, la seule prerelease restante est `pre.012`, strictement limitée à la préparation de publication :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Cargo.toml
|
||||||
|
CHANGELOG.md
|
||||||
|
ROADMAP.md
|
||||||
|
prompts/022-V0_3_3_START_PROMPT.md
|
||||||
|
deltas/0.3.2/pre.012.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun README, USAGE, plan, validation, architecture, code, test, schema ou config ne devra être rouvert dans `pre.012`.
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/plans/000-README.md -->
|
<!-- file: docs/plans/000-README.md -->
|
||||||
<!-- version: 68 -->
|
<!-- version: 69 -->
|
||||||
|
|
||||||
# Plans KSP
|
# Plans KSP
|
||||||
|
|
||||||
@@ -31,6 +31,7 @@ Un plan décrit le périmètre, les décisions déjà acquises, les questions ou
|
|||||||
- [`020-V0_2_13_INTERFACE_PLAN.md`](020-V0_2_13_INTERFACE_PLAN.md) — plan historique clôturé de la release stable `0.2.13 — Interface / wire foundation`; il fixe la surface finale `ProgramAccountMeta` + `ProgramInstruction`, les bornes `255` / `10_240`, le firewall Interface -> Core, les canaris de complétude/consumer externe et la frontière avec Program API/RAW/CORE.
|
- [`020-V0_2_13_INTERFACE_PLAN.md`](020-V0_2_13_INTERFACE_PLAN.md) — plan historique clôturé de la release stable `0.2.13 — Interface / wire foundation`; il fixe la surface finale `ProgramAccountMeta` + `ProgramInstruction`, les bornes `255` / `10_240`, le firewall Interface -> Core, les canaris de complétude/consumer externe et la frontière avec Program API/RAW/CORE.
|
||||||
- [`021-V0_2_14_PROGRAM_API_PLAN.md`](021-V0_2_14_PROGRAM_API_PLAN.md) — plan historique clôturé de la release stable `0.2.14 — Program API foundation`; il fixe la façade instruction-only ouverte, les enums Recognition/Outcome, `ProgramInstructionDecoder`, l'output associé possédé par l'implémentation, le canari externe avec Program Pubkey non enregistré, le firewall Core/Interface et le report du payload canonique D3, du registry runtime et de `ProgramExecutionPreparer`.
|
- [`021-V0_2_14_PROGRAM_API_PLAN.md`](021-V0_2_14_PROGRAM_API_PLAN.md) — plan historique clôturé de la release stable `0.2.14 — Program API foundation`; il fixe la façade instruction-only ouverte, les enums Recognition/Outcome, `ProgramInstructionDecoder`, l'output associé possédé par l'implémentation, le canari externe avec Program Pubkey non enregistré, le firewall Core/Interface et le report du payload canonique D3, du registry runtime et de `ProgramExecutionPreparer`.
|
||||||
- [`022-V0_3_1_STORE_RAW_PLAN.md`](022-V0_3_1_STORE_RAW_PLAN.md) — plan candidat réconcilié de `0.3.1 — Store API RAW foundation`; il fixe `ksp-store-api` seul, les modèles transaction/account + observations, queries/outcomes/capabilities, rétention/tombstone, la frontière event-only/Interface et le report de `ksp-store-lib` + PostgreSQL à `0.3.2`.
|
- [`022-V0_3_1_STORE_RAW_PLAN.md`](022-V0_3_1_STORE_RAW_PLAN.md) — plan candidat réconcilié de `0.3.1 — Store API RAW foundation`; il fixe `ksp-store-api` seul, les modèles transaction/account + observations, queries/outcomes/capabilities, rétention/tombstone, la frontière event-only/Interface et le report de `ksp-store-lib` + PostgreSQL à `0.3.2`.
|
||||||
|
- [`023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md`](023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md) — plan candidat réconcilié de `0.3.2 — Store/PostgreSQL runtime foundation`; il fixe le split façade/backend, `std.store` multi-target réseau-spécifique, tokio-postgres/Deadpool/Rustls, migrations metadata-only, health/readiness, live PostgreSQL et les reports des vertical slices RAW vers `0.3.3`/`0.3.4`.
|
||||||
|
|
||||||
Le `pre.001` de chaque release fonctionnelle peut introduire son propre plan détaillé lorsque la release s'ouvre.
|
Le `pre.001` de chaque release fonctionnelle peut introduire son propre plan détaillé lorsque la release s'ouvre.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md -->
|
<!-- file: docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md -->
|
||||||
<!-- version: 12 -->
|
<!-- version: 13 -->
|
||||||
|
|
||||||
# Plan `0.3.2` — Store/PostgreSQL runtime foundation
|
# Plan `0.3.2` — Store/PostgreSQL runtime foundation
|
||||||
|
|
||||||
@@ -1117,11 +1117,26 @@ cargo tree --duplicates
|
|||||||
|
|
||||||
### `pre.010` — Gate technique final
|
### `pre.010` — Gate technique final
|
||||||
|
|
||||||
Base requise : `0.3.2-pre.009` avec hardening/completeness entièrement vert. Le gate opérateur `pre.009` du 29 août 2026 confirme les audits Rust/Markdown, workspace check/Clippy, Store API, backend PostgreSQL, façade avec et sans feature, Config, graphes Cargo et `cargo test --workspace`.
|
Statut : matérialisé et gate technique opérateur exécuté le 29 août 2026.
|
||||||
|
|
||||||
Cette tranche ne modifie aucun code de production, test fonctionnel, migration, Config ou dépendance runtime. Elle synchronise uniquement la version de prerelease et prépare le gate technique final.
|
Le gate part de `0.3.2-pre.009` avec hardening/completeness entièrement vert. Il a été rejoué après `cargo clean` sur `0.3.2-pre.10` et confirme :
|
||||||
|
|
||||||
Gate final attendu :
|
```text
|
||||||
|
audits Rust clean
|
||||||
|
workspace check + Clippy PASS
|
||||||
|
toutes les crates ciblées PASS
|
||||||
|
ksp-store-lib default + no-default-features PASS
|
||||||
|
cargo test --workspace PASS
|
||||||
|
graphes normal/features/duplicates exécutés
|
||||||
|
3 builds Tauri Linux PASS
|
||||||
|
PostgreSQL live foundation PASS sur major 17
|
||||||
|
```
|
||||||
|
|
||||||
|
La commande opérateur d'audit Markdown a ciblé par erreur `deltas/0.3.1` au lieu de `deltas/0.3.2`. L'overlay `pre.010` avait été audité avec le bon chemin dans l'environnement de génération ; `pre.011` rejoue obligatoirement l'audit Markdown complet avec `deltas/0.3.2` avant de figer la documentation. Ce défaut de scope de commande ne révèle aucun échec runtime et n'ouvre pas de `pre.010-fix`.
|
||||||
|
|
||||||
|
Cette tranche ne modifie aucun code de production, test fonctionnel, migration, Config ou dépendance runtime. Elle synchronise uniquement la version de prerelease et porte le gate technique final.
|
||||||
|
|
||||||
|
Gate final exécuté :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo fmt --all
|
cargo fmt --all
|
||||||
@@ -1162,7 +1177,24 @@ Aucun développement fonctionnel nouveau n'est autorisé dans `pre.010`. Tout d
|
|||||||
|
|
||||||
### `pre.011` — Réconciliation documentaire finale
|
### `pre.011` — Réconciliation documentaire finale
|
||||||
|
|
||||||
README/USAGE des deux crates, plan/validation/indexes/architecture réellement impactés. Pas de CHANGELOG/ROADMAP/prompt suivant.
|
Statut : matérialisé par `0.3.2-pre.011`; gate documentaire opérateur requis après application.
|
||||||
|
|
||||||
|
La tranche fige les références durables réellement concernées :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ksp-store-lib/README.md + USAGE.md
|
||||||
|
ksp-store-postgres-lib/README.md + USAGE.md
|
||||||
|
ksp-config-lib README/USAGE complétés pour std.store
|
||||||
|
docs/000-README.md
|
||||||
|
docs/plans/000-README.md
|
||||||
|
docs/validation/000-README.md
|
||||||
|
plan 023
|
||||||
|
validation 019
|
||||||
|
```
|
||||||
|
|
||||||
|
Les architectures `003/004/005/008` ont été relues sur la base `pre.010` et restent cohérentes avec la surface réellement livrée ; elles ne sont pas modifiées artificiellement. Le choix historique de `0.3.1-pre.009` de ne pas créer un README/USAGE `ksp-store-api` n'est pas rouvert dans cette release backend/runtime.
|
||||||
|
|
||||||
|
`CHANGELOG.md`, `ROADMAP.md` et le prompt `0.3.3` restent strictement réservés à `pre.012`.
|
||||||
|
|
||||||
### `pre.012` — Préparation de publication minimale
|
### `pre.012` — Préparation de publication minimale
|
||||||
|
|
||||||
@@ -1221,9 +1253,9 @@ Store Desk
|
|||||||
|
|
||||||
## 21. Questions restantes
|
## 21. Questions restantes
|
||||||
|
|
||||||
Aucune question architecturale ne bloque `pre.002`.
|
Aucune question architecturale ou technique ne bloque la préparation de publication de `0.3.2`.
|
||||||
|
|
||||||
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.
|
La fondation runtime/backend est fermée fonctionnellement. Les seules surfaces volontairement reportées sont les vertical slices métier déjà réservées à `0.3.3+` : persistence/query/rétention `RawTransaction`, puis `RawAccountState` et conformance RAW.
|
||||||
|
|
||||||
Toute découverte qui exigerait :
|
Toute découverte qui exigerait :
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/validation/000-README.md -->
|
<!-- file: docs/validation/000-README.md -->
|
||||||
<!-- version: 32 -->
|
<!-- version: 33 -->
|
||||||
|
|
||||||
# Validations KSP
|
# Validations KSP
|
||||||
|
|
||||||
@@ -27,3 +27,4 @@ Documents :
|
|||||||
- [`016-V0_2_13_INTERFACE.md`](016-V0_2_13_INTERFACE.md) — matrice historique clôturée de la release stable `0.2.13` : ownership Interface/Core/Transport/Program, surface passive, bornes/adversarial, façade publique exacte, consumer externe, release completeness et dependency firewall.
|
- [`016-V0_2_13_INTERFACE.md`](016-V0_2_13_INTERFACE.md) — matrice historique clôturée de la release stable `0.2.13` : ownership Interface/Core/Transport/Program, surface passive, bornes/adversarial, façade publique exacte, consumer externe, release completeness et dependency firewall.
|
||||||
- [`017-V0_2_14_PROGRAM_API.md`](017-V0_2_14_PROGRAM_API.md) — matrice historique clôturée de la release stable `0.2.14 — Program API foundation` : façade instruction-only ouverte, Recognition/Outcome, trait externe, Program Pubkey non enregistré, hardening adversarial, release completeness et firewall Core/Interface.
|
- [`017-V0_2_14_PROGRAM_API.md`](017-V0_2_14_PROGRAM_API.md) — matrice historique clôturée de la release stable `0.2.14 — Program API foundation` : façade instruction-only ouverte, Recognition/Outcome, trait externe, Program Pubkey non enregistré, hardening adversarial, release completeness et firewall Core/Interface.
|
||||||
- [`018-V0_3_1_STORE_RAW.md`](018-V0_3_1_STORE_RAW.md) — matrice candidate finale de `0.3.1 — Store API RAW foundation` : modèles transaction/account, observations, capabilities backend, pagination sans policy executor, outcomes, rétention/tombstone, hardening, gate complet `pre.008` et reports explicites vers `0.3.2+`.
|
- [`018-V0_3_1_STORE_RAW.md`](018-V0_3_1_STORE_RAW.md) — matrice candidate finale de `0.3.1 — Store API RAW foundation` : modèles transaction/account, observations, capabilities backend, pagination sans policy executor, outcomes, rétention/tombstone, hardening, gate complet `pre.008` et reports explicites vers `0.3.2+`.
|
||||||
|
- [`019-V0_3_2_STORE_POSTGRES_FOUNDATION.md`](019-V0_3_2_STORE_POSTGRES_FOUNDATION.md) — matrice candidate finale de `0.3.2 — Store/PostgreSQL runtime foundation` : feature graph, settings/Config, pool/TLS, migrations metadata-only, health, hardening, graphes, builds Tauri et preuve PostgreSQL réelle major 17.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md -->
|
<!-- file: docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md -->
|
||||||
<!-- version: 12 -->
|
<!-- version: 13 -->
|
||||||
|
|
||||||
# Validation `0.3.2` — Store/PostgreSQL runtime foundation
|
# Validation `0.3.2` — Store/PostgreSQL runtime foundation
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ exports/capabilities existants conservés
|
|||||||
aucun type backend ajouté pour PostgreSQL
|
aucun type backend ajouté pour PostgreSQL
|
||||||
```
|
```
|
||||||
|
|
||||||
Statut : `PASS pre.009 opérateur / TODO revalidation pre.010` — le canari backend externe de `ksp-store-api` est rejoué sans modification de la crate.
|
Statut : `PASS pre.009 opérateur / PASS pre.010 opérateur` — le canari backend externe de `ksp-store-api` est rejoué sans modification de la crate.
|
||||||
|
|
||||||
## 4. Public API et settings
|
## 4. Public API et settings
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ 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`.
|
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.
|
Statut : `PASS pre.004-fix.001 opérateur` pour la sélection target/réseau / `N/A 0.3.2` pour le mismatch d'opérations RAW, dont l'enforcement appartient aux vertical slices `0.3.3`-`0.3.4`.
|
||||||
|
|
||||||
### V32-CONFIG-003 — No-env Store/backend
|
### V32-CONFIG-003 — No-env Store/backend
|
||||||
|
|
||||||
@@ -458,7 +458,7 @@ Critères :
|
|||||||
0 repository RAW métier
|
0 repository RAW métier
|
||||||
```
|
```
|
||||||
|
|
||||||
Statut : `PASS pre.009 opérateur / TODO revalidation pre.010`.
|
Statut : `PASS pre.009 opérateur / PASS pre.010 opérateur`.
|
||||||
|
|
||||||
## 9. Health/readiness
|
## 9. Health/readiness
|
||||||
|
|
||||||
@@ -536,7 +536,7 @@ cleanup metadata
|
|||||||
|
|
||||||
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.
|
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 : `PASS live pre.008 PostgreSQL 17 / TODO revalidation pre.010`.
|
Statut : `PASS live pre.008 PostgreSQL 17 / PASS live pre.010 PostgreSQL 17`.
|
||||||
|
|
||||||
### V32-LIVE-004 — PostgreSQL support
|
### V32-LIVE-004 — PostgreSQL support
|
||||||
|
|
||||||
@@ -544,7 +544,7 @@ Critère : test refuse major < 15 et enregistre seulement le major safe réellem
|
|||||||
|
|
||||||
Cible release : PostgreSQL 18.6. `pre.008` interroge uniquement `SHOW server_version_num`, dérive le major et n'imprime aucune identité de serveur. Le gate opérateur réel a été exécuté avec succès sur PostgreSQL 17.
|
Cible release : PostgreSQL 18.6. `pre.008` interroge uniquement `SHOW server_version_num`, dérive le major et n'imprime aucune identité de serveur. Le gate opérateur réel a été exécuté avec succès sur PostgreSQL 17.
|
||||||
|
|
||||||
Statut : `PASS live pre.008 PostgreSQL 17 / TODO revalidation pre.010`.
|
Statut : `PASS live pre.008 PostgreSQL 17 / PASS live pre.010 PostgreSQL 17`.
|
||||||
|
|
||||||
## 11. Security/adversarial
|
## 11. Security/adversarial
|
||||||
|
|
||||||
@@ -636,7 +636,9 @@ PostgreSQL live foundation
|
|||||||
3 builds Tauri avec resources std.store packagées
|
3 builds Tauri avec resources std.store packagées
|
||||||
```
|
```
|
||||||
|
|
||||||
Statut global `pre.010` : `MATÉRIALISÉ / TODO gate opérateur`.
|
Statut global `pre.010` : `PASS technique opérateur`.
|
||||||
|
|
||||||
|
Le gate a été rejoué après `cargo clean` sur `0.3.2-pre.10` : audits Rust, workspace check/Clippy, tests ciblés, `cargo test --workspace`, graphes Cargo, trois builds Tauri et PostgreSQL live major 17 sont verts. La ligne d'audit Markdown opérateur a utilisé `deltas/0.3.1` par erreur ; l'overlay `pre.010` avait été audité avec `deltas/0.3.2` dans l'environnement de génération et `pre.011` rejoue le scope Markdown exact avant clôture documentaire.
|
||||||
|
|
||||||
## 14. Gates Rust/workspace
|
## 14. Gates Rust/workspace
|
||||||
|
|
||||||
@@ -686,9 +688,27 @@ cargo test --workspace
|
|||||||
|
|
||||||
Les trois builds Tauri sont requis au gate final parce que `pre.004` a réellement ajouté les resources `std.store` au packaging desktop.
|
Les trois builds Tauri sont requis au gate final parce que `pre.004` a réellement ajouté les resources `std.store` au packaging desktop.
|
||||||
|
|
||||||
Statut global : `TODO gate opérateur pre.010`.
|
Statut global technique : `PASS pre.010 opérateur`; audit Markdown `deltas/0.3.2` à rejouer dans le gate documentaire `pre.011`.
|
||||||
|
|
||||||
## 15. Critères de fermeture
|
## 15. Réconciliation documentaire `pre.011`
|
||||||
|
|
||||||
|
Critères :
|
||||||
|
|
||||||
|
```text
|
||||||
|
README/USAGE ksp-store-lib présents et alignés sur la façade publique
|
||||||
|
README/USAGE ksp-store-postgres-lib présents et explicitement backend-only
|
||||||
|
ksp-config-lib README/USAGE documentent cfg.std.store et les targets réseau
|
||||||
|
indexes docs/plans/validation référencent 0.3.2
|
||||||
|
plan 023 reflète le gate technique réel
|
||||||
|
matrice 019 ne conserve aucun TODO applicable à 0.3.2
|
||||||
|
CHANGELOG/ROADMAP/prompt suivant inchangés
|
||||||
|
```
|
||||||
|
|
||||||
|
Les architectures générales Store ont été relues et restent cohérentes ; aucune modification artificielle n'est nécessaire.
|
||||||
|
|
||||||
|
Statut : `MATÉRIALISÉ pre.011 / TODO gate documentaire opérateur`.
|
||||||
|
|
||||||
|
## 16. Critères de fermeture
|
||||||
|
|
||||||
La matrice ne peut passer en finale que si tous les critères applicables sont `PASS` et que :
|
La matrice ne peut passer en finale que si tous les critères applicables sont `PASS` et que :
|
||||||
|
|
||||||
@@ -703,4 +723,4 @@ PostgreSQL live vert
|
|||||||
workspace/clippy/tests verts
|
workspace/clippy/tests verts
|
||||||
```
|
```
|
||||||
|
|
||||||
La réconciliation finale de cette matrice appartient à la prerelease documentaire précédant la lane de publication.
|
La réconciliation finale de cette matrice est matérialisée par `pre.011`. Après son gate documentaire vert, la seule étape restante est la préparation de publication minimale `pre.012`.
|
||||||
|
|||||||
Reference in New Issue
Block a user