v0.5.3-pre.002

This commit is contained in:
2026-08-11 22:22:40 +02:00
parent 01d78b5845
commit 8448ad1079
134 changed files with 4518 additions and 3595 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/DEVNET_EXECUTION_GUIDE.md -->
<!-- version: 27 -->
<!-- version: 28 -->
# Guide dexécution Devnet
@@ -30,7 +30,7 @@ Les commandes réutilisables sont centralisées en section 4. Chaque scénario r
- le wallet temporaire persistant nest jamais copié dans les logs ou les preuves ;
- le financement est réalisé par un faucet Web Devnet, pas par `solana airdrop`.
Lorsque `database.postgres.auto_initialize_schema` vaut `true`, louverture dune fenêtre Devnet crée les tables manquantes. Lorsquil vaut `false`, le schéma doit être préparé avant louverture.
Depuis `0.5.3-pre.002`, le desktop ne lit plus une section PostgreSQL concrète. Le profil sélectionne `database.backend` et transporte ses paramètres dans `database.backend_options`, interprétés uniquement par `ks-store`. Lorsque loption backend `auto_initialize_schema` vaut `true`, louverture persistante du `Store` peut initialiser le schéma du backend actif. Lorsquelle vaut `false`, le modèle de stockage doit déjà être disponible.
## 3. Organisation des terminaux
@@ -81,7 +81,7 @@ Attendre avant tout scénario :
- le démarrage de Vite ;
- le lancement du binaire `kb-app-demo-desktop` ;
- louverture de la fenêtre ;
- le message PostgreSQL indiquant que les 13 tables sont prêtes ;
- le résumé store indiquant que le backend actif est joignable et que les modèles logiques attendus sont prêts ;
- la résolution correcte du profil `local_devnet`.
Ne pas exécuter les commandes `C06` ou `C07` dans ce terminal.
@@ -330,7 +330,7 @@ Un scénario nest validé que si le replay ne produit ni échec fonctionnel n
1. Dans le terminal B, exécuter `C01`, `C02`, `C03` et `C04`.
2. Dans le terminal B, exécuter `C05` pour repartir dune base propre.
3. Dans le terminal A, exécuter `T01`.
4. Attendre la création des 13 tables et la disponibilité de la fenêtre.
4. Attendre que le résumé store confirme la disponibilité des modèles logiques attendus, puis la disponibilité de la fenêtre.
5. Dans la fenêtre Configuration, vérifier que `local_devnet` utilise la base Devnet.
6. Dans le terminal B, exécuter le contrôle de tables de `C05`.
7. Financer la pubkey par un faucet Web Devnet si le solde est insuffisant.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/STORAGE_ARCHITECTURE.md -->
<!-- version: 5 -->
<!-- version: 7 -->
# Architecture du stockage
@@ -7,30 +7,38 @@
`ks-store` réunit :
- la façade publique backend-agnostique `Store` et ses options d'ouverture ;
- les contrats store-neutral ;
- les DTO et entités persistées ;
- la pagination et les rapports de santé ;
- la pagination, le replay et les rapports de santé ;
- les traits de repositories ;
- limplémentation PostgreSQL ;
- les migrations, requêtes et mécanismes de replay associés.
- les résumés runtime/init sanitisés ;
- limplémentation PostgreSQL privée ;
- les migrations et requêtes appartenant au backend actif.
La consolidation remplace lancien découpage entre plusieurs crates de stockage sans supprimer la séparation interne entre contrats et adaptateur PostgreSQL.
Depuis `0.5.3-pre.002`, les consommateurs ne construisent plus un backend concret. `ks-store` possède la connexion et le dispatch interne ; `PostgresStore`, `PgPool` et SQLx ne traversent plus sa frontière publique.
## 2. Frontières
### 2.1 Contrats store-neutral
Les contrats ne doivent pas dépendre des détails SQL lorsquune abstraction stable est suffisante. Ils décrivent les entrées, sorties, identifiants, pages et erreurs nécessaires aux consommateurs.
Les contrats ne dépendent pas des détails SQL lorsquune abstraction stable est suffisante. Ils décrivent les entrées, sorties, identifiants, pages, diagnostics et erreurs nécessaires aux consommateurs. `StoreOpenOptions` transporte un code backend et un objet d'options opaque ; seul `ks-store` interprète le moteur sélectionné.
Le résumé runtime expose des modèles logiques et des compteurs d'objets par catégorie sans publier les noms physiques. PostgreSQL peut ainsi exposer des compteurs `table`/`index`, tandis qu'un futur backend peut utiliser d'autres catégories sans modifier le desktop.
### 2.2 Adaptateur PostgreSQL
Le module PostgreSQL possède :
- la validation de ses options ;
- la connexion et linitialisation ;
- lapplication idempotente des migrations ;
- les requêtes typées ;
- les diagnostics ;
- les opérations de replay et de sélection de candidats.
- les diagnostics physiques ;
- les opérations de replay et de sélection de candidats ;
- le target de tracing canonique `ks-store`, enrichi des champs `backend="postgres"`, `domain="ks-store.pg"` et `action` pour les opérations PostgreSQL.
Les détails physiques restent privés. Les erreurs et résumés traversant la façade ne doivent pas divulguer de DSN, password ou option sensible.
### 2.3 Modèles partagés
@@ -38,14 +46,14 @@ Les modèles métier communs restent dans `ks-lib` lorsquils dépassent la se
## 3. Catégories de données
Le stockage couvre plusieurs niveaux :
Le stockage distingue quatre niveaux durables :
- données brutes acquises ;
- transactions et instructions canoniques ;
- événements de décodage et diagnostics ;
- matérialisations ;
- états de campagne et candidats de replay ;
- informations opérationnelles et de santé.
- **N1** — acquisition et raw canonique ;
- **N2** — Core Solana canonique ;
- **N3** — decode/materialization générique et journaux versionnés ;
- **N4** — projections spécialisées/queryables additives.
N1/N2/N3 constituent la fondation fortement gelée après `0.5.3`, sous réserve d'une urgence ou d'une omission structurelle majeure. N4 reste plus évolutif. Les replays N1 -> N2, N2 -> N3 et N3 -> N4 doivent pouvoir être exécutés indépendamment et de manière idempotente.
Les noms de tables, contrats de replay et APIs publiques sont documentés dans `ks-store/USAGE.md` à partir des exports et migrations actuels.

View File

@@ -1,32 +1,37 @@
<!-- file: docs/guides/POSTGRES_STORAGE.md -->
<!-- version: 3 -->
<!-- version: 5 -->
# Guide PostgreSQL et contrats de stockage
## Objectif
`ks-store` consolide les contrats de stockage Core, raw, decode et PostgreSQL de bot2 dans une crate unique.
`ks-store` porte la frontière de stockage généraliste. PostgreSQL reste le backend opérationnel actif, mais il est encapsulé derrière la façade publique backend-agnostique `Store`.
## Connexion
Les consommateurs ne construisent plus `PostgresStore`, `PostgresStoreOptions` ni un pool SQLx. Ils transmettent le backend sélectionné et ses options résolues à `StoreOpenOptions`; `ks-store` valide et interprète ensuite les paramètres PostgreSQL.
```rust
let options = match ks_store::PostgresStoreOptions::new(
database_url,
10,
10_000,
let options = match ks_store::StoreOpenOptions::new(
true,
"postgres",
serde_json::json!({
"url": database_url,
"max_connections": 10,
"connect_timeout_ms": 10_000,
"auto_initialize_schema": true
}),
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let store = match ks_store::PostgresStore::connect(options).await {
let store = match ks_store::Store::open(options).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
```
Toujours utiliser `masked_dsn()` dans les diagnostics.
Le descripteur public éventuellement affiché provient du résumé runtime et est déjà masqué par `ks-store`. Le DSN brut et les options backend ne doivent jamais être propagés dans les DTO, erreurs applicatives ou logs normaux.
## Domaines
@@ -37,7 +42,9 @@ Toujours utiliser `masked_dsn()` dans les diagnostics.
## Migrations
Les migrations sont idempotentes et ordonnées. Une nouvelle migration ne doit pas modifier rétroactivement une migration déjà publiée.
`0.5.3-pre.002` conserve temporairement le schéma PostgreSQL historique `kb_sol_*` et son mécanisme d'initialisation afin de réaliser d'abord la rupture d'API backend. `pre.003` reconstruit le baseline sous `k_sol_*`, range les ressources sous `ks-store/migrations/postgres/` et impose une instruction SQL par fichier exécutée par les fonctions privées du backend.
Les bases Devnet/Mainnet/test `0.5.2` sont reconstructibles : aucune compatibilité in-place n'est requise pour ce changement de baseline.
## Compatibilité des identités de processeurs
@@ -47,15 +54,20 @@ Aucune migration SQL automatique de ces valeurs n'est ajoutée en `0.5.1` : avan
## Repositories
Les traits publics séparent le contrat de limplémentation PostgreSQL. Les opérations de lecture utilisent des filtres et paginations bornés.
Les traits publics et la façade `Store` décrivent des opérations fonctionnelles indépendantes du moteur. PostgreSQL implémente ces contrats à lintérieur de `ks-store`; aucune crate consommatrice ne reçoit `PgPool`, un type SQLx ou une requête concrète. Les opérations de lecture utilisent des filtres et paginations bornés.
## Diagnostics
La surface publique expose :
- health snapshot ;
- migration snapshot ;
- backend diagnostics ;
- diagnostics des tables raw, Core et decode ;
- validation des noms de tables.
- backend descriptor masqué ;
- résumé de configuration sanitisé ;
- résumé d'initialisation/vérification par modèle logique ;
- diagnostics de ressources raw/Core/decode/materialization sans nom physique d'objet.
Les noms de tables, index, contraintes et le SQL restent des détails backend-internes. Les traces PostgreSQL utilisent lunique `target: crate::TRACING_TARGET` (`ks-store`) avec les champs structurés `backend="postgres"`, `domain="ks-store.pg"` et un `action` précis (`connection`, `migration`, `query`, `health`, `replay`, etc.).
## Invariants
@@ -63,7 +75,7 @@ Les traits publics séparent le contrat de limplémentation PostgreSQL. Les o
- les écritures rejouables doivent être idempotentes ;
- la progression de campagne doit rester cohérente avec les lignes effectivement traitées ;
- les requêtes dynamiques nacceptent que des identifiants validés ;
- les erreurs PostgreSQL restent distinctes des erreurs de contrat.
- les détails PostgreSQL utiles au diagnostic restent backend-internes ; les erreurs traversant la façade publique ne doivent jamais divulguer DSN, password ou options sensibles.
## Références

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/V0_5_3_KS_STORE_NORMALIZATION_PLAN.md -->
<!-- version: 5 -->
<!-- version: 7 -->
# Plan `0.5.3` — audit et normalisation de `ks-store`
@@ -55,7 +55,7 @@ Les décisions suivantes sont retenues pour les tranches suivantes :
14. **`ks-store` ne dépend pas de `ks-config`** : la frontière applicative transporte une configuration résolue, mais l'interprétation du backend et la création de la connexion sont internes à `ks-store` ;
15. **le bloc de configuration backend devient sélectionné et opaque jusqu'à `ks-store`**, afin que `ks-config` n'impose plus simultanément les paramètres de backends non sélectionnés ;
16. **`ks-store` expose un résumé runtime sans secrets** destiné notamment à `kb-app-demo-desktop` : backend actif, état de connexion, options publiques retenues, auto-initialisation, version/état du schéma et tables créées/vérifiées au démarrage ;
17. **les surfaces `demo_sql` du desktop seront adaptées** à cette façade et à ces diagnostics génériques lorsque l'API change ; aucune logique SQL/PostgreSQL ne doit revenir dans l'application ;
17. **les surfaces historiques `demo_sql_*` du desktop sont renommées structurellement en `demo_store_*` dès `pre.002`** ; la refonte fonctionnelle finale des tableaux/compteurs reste planifiée plus tard et aucune logique SQL/PostgreSQL ne doit revenir dans l'application ;
18. **toutes les opérations PostgreSQL portent un target de logging sous `ks-store.pg`** ; le SQL brut peut être journalisé au niveau `trace`, sans valeurs bindées ni secrets, tandis que les niveaux normaux journalisent l'identité d'opération, la durée et le résultat ;
19. **le contrat de page publique abandonne les gros offsets comme mécanisme durable** au profit d'une pagination stable/cursorisée pour les lectures qui en ont besoin ; aucune requête UI ne doit pouvoir demander 100 000 lignes en un appel ;
20. **les index non uniques sont des objets physiques évolutifs**, exclus du gel logique des tables ; les PK, FK, uniques, checks, types, nullabilités et sémantiques de colonnes sont gelés ;
@@ -67,7 +67,7 @@ Les décisions suivantes sont retenues pour les tranches suivantes :
26. **les replays inter-niveaux sont des contrats de premier rang** : N1 -> N2, N2 -> N3 et N3 -> N4 doivent pouvoir être rejoués indépendamment, de façon idempotente, versionnée et avec invalidation descendante contrôlée ;
27. **`k_sol_mat_outputs` est conservée impérativement comme journal N3 générique** même lorsque des projections N4 existent ; une projection spécialisée n'est jamais un remplacement de la sortie matérialisée canonique/versionnée ;
28. **les metadata auront à terme deux projections N4 conceptuelles distinctes** : une projection canonique d'asset/token alimentable par Metaplex Token Metadata et Token-2022, et une projection de metadata de programme pour Solana Program Metadata (SPM) ; elles ne sont pas créées en `0.5.3`, mais leur séparation conceptuelle est retenue ;
29. **le desktop ne doit plus exposer le backend concret** : les surfaces `demo_sql` seront refondues vers des résultats tabulaires génériques (avec préférence pour une nomenclature `demo_store_*`), `demo_config` consommera un résumé store sanitisé sans champs PostgreSQL/SQLite concrets, et le splash vérifiera des modèles logiques avec compteurs d'objets sans afficher les noms physiques des tables/index ;
29. **le desktop ne doit plus exposer le backend concret** : les surfaces portent la nomenclature `demo_store_*` dès `pre.002` et seront refondues fonctionnellement vers des résultats tabulaires génériques, `demo_config` consommera un résumé store sanitisé sans champs PostgreSQL/SQLite concrets, et le splash vérifiera des modèles logiques avec compteurs d'objets sans afficher les noms physiques des tables/index ;
30. **la façade `Store` ouverte au démarrage est destinée à être conservée dans l'état applicatif** plutôt que recréée par chaque commande desktop ; `ks-store` possède ainsi la connexion, l'initialisation et les diagnostics runtime, tandis que l'application ne conserve qu'une capacité backend-agnostique ;
31. **le gel N1-N3 est conditionné par un canari de compatibilité avec les futurs mécanismes de décodage**, Anchor/IDL étant le premier cas concret : l'ajout d'un décodeur futur doit pouvoir se faire sans modification structurelle normale de N1/N2/N3. `0.5.3` n'implémente pas Anchor, mais doit vérifier que les niveaux gelés conservent les bytes d'instruction, comptes ordonnés et leurs attributs, hiérarchie CPI, logs, return data lorsqu'elle existe, temporalité, provenance et observations/états de comptes nécessaires à un redécodage ultérieur ; toute omission générique découverte par cet audit doit être corrigée avant gel ;
32. **les 13 tables existantes constituent la baseline auditée, pas un quota de tables finales** : leur séparation top-level/CPI est conservée, mais le nombre final peut augmenter en `0.5.3` si le canari de readiness démontre qu'un fait Solana générique indispensable manque dans N1/N2/N3. Aucune nouvelle table ne doit être ajoutée pour Anchor en tant que technologie ; seules des structures canoniques Solana indépendantes du mécanisme de décodage sont admissibles.
@@ -824,31 +824,17 @@ Le contrat visé couvre au minimum :
- compteurs d'objets attendus, présents, créés et vérifiés, notamment tables et index lorsque le backend possède ces notions ;
- éventuelles actions de migration/init exécutées, identifiées sans SQL sensible ni paramètres secrets.
Le résumé public **n'expose pas les noms physiques des tables, index ou contraintes**. Ces détails restent backend-internes et peuvent être tracés dans `ks-store.pg.migration`. Un backend non relationnel peut produire le même résumé logique avec ses propres objets physiques.
Le résumé public **n'expose pas les noms physiques des tables, index ou contraintes**. Ces détails restent backend-internes et peuvent être tracés sous le target canonique `ks-store` avec les champs structurés `backend="postgres"`, `domain="ks-store.pg"` et `action="migration"`. Un backend non relationnel peut produire le même résumé logique avec ses propres objets physiques.
Les noms exacts (`StoreRuntimeSummary`, `StoreInitializationSummary`, `StoreModelVerificationSummary`, etc.) seront figés lors de `pre.002`. Le desktop consomme uniquement ces DTO génériques. Les panneaux `demo_sql` seront refondus vers des résultats tabulaires génériques et pourront être renommés `demo_store_*`; `demo_config` ne doit plus lire directement la configuration PostgreSQL/SQLite. Le même résumé logique alimente les informations store du splash.
Les noms exacts (`StoreRuntimeSummary`, `StoreInitializationSummary`, `StoreModelVerificationSummary`, etc.) seront figés lors de `pre.002`. Le desktop consomme uniquement ces DTO génériques. Les panneaux portent la nomenclature `demo_store_*` dès `pre.002`; leur présentation tabulaire finale sera refondue en `pre.005`. `demo_config` ne doit plus lire directement la configuration PostgreSQL/SQLite. Le même résumé logique alimente les informations store du splash.
### 18.5 Logging PostgreSQL
Le domaine racine retenu est :
```text
ks-store.pg
```
avec des sous-targets possibles et cohérents :
```text
ks-store.pg.connection
ks-store.pg.migration
ks-store.pg.query
ks-store.pg.health
ks-store.pg.replay
```
Le target Rust reste lunique `crate::TRACING_TARGET` de la crate, soit `ks-store`, conformément aux règles du workspace. Le backend PostgreSQL est distingué par des champs structurés stables : `backend = "postgres"`, `domain = "ks-store.pg"` et `action = ...`.
Règles :
- toute exécution SQL PostgreSQL est traçable par un target `ks-store.pg.*` ;
- toute exécution SQL PostgreSQL est traçable sous `target: crate::TRACING_TARGET` avec `backend = "postgres"` et `domain = "ks-store.pg"` ;
- `info`/`debug` journalisent l'identité d'opération, le temps d'exécution, le nombre de lignes et l'issue ;
- le texte SQL brut peut être journalisé à `trace` pour le diagnostic ;
- les valeurs bindées ne sont pas journalisées par défaut ;
@@ -1235,7 +1221,7 @@ Le découpage suivant est une **trajectoire fonctionnelle**. Il ne force pas la
- supprimer les quatre traits/DTO historiques non implémentés ;
- remodeler le bloc store config en backend + options sélectionnées/opaques ;
- déplacer toute validation/interprétation PostgreSQL dans `ks-store` ;
- introduire les targets `ks-store.pg.*` et les canaris backend/secret ;
- introduire linstrumentation PostgreSQL sous le `TRACING_TARGET` canonique avec `backend="postgres"`, `domain="ks-store.pg"` et les canaris backend/secret ;
- migrer les helpers de connexion sans changer encore les tables ;
- préparer une façade `Store` persistante dans létat applicatif afin que les commandes desktop ne recréent pas de connexion backend.
@@ -1263,12 +1249,12 @@ Le découpage suivant est une **trajectoire fonctionnelle**. Il ne force pas la
- ajouter les index justifiés ;
- couvrir les bornes BIGINT ;
- vérifier atomicité et reprise après erreur ;
- instrumenter les requêtes PostgreSQL sous `ks-store.pg.query`.
- instrumenter les requêtes PostgreSQL sous `target: crate::TRACING_TARGET`, `backend="postgres"`, `domain="ks-store.pg"` et `action` explicite.
### `0.5.3-pre.005` — consommateurs, `demo_sql` et validation PostgreSQL réelle
### `0.5.3-pre.005` — finalisation `demo_store`, consommateurs et validation PostgreSQL réelle
- supprimer les derniers `Postgres*` de `ks-pipeline-demo-scenarios` ;
- refaire les surfaces `demo_sql` concernées de `kb-app-demo-desktop` autour de résultats tabulaires génériques indépendants du backend, avec migration de nomenclature vers `demo_store_*` si elle reste cohérente avec la surface UI ;
- finaliser les surfaces `demo_store_*` de `kb-app-demo-desktop` autour de résultats tabulaires génériques indépendants du backend ; la nomenclature technique a déjà été migrée en `pre.002` ;
- refaire `demo_config` afin qu'elle n'expose/interprète plus les champs PostgreSQL/SQLite et consomme uniquement le résumé store sanitisé ;
- refaire les informations store du splash autour d'une vérification par modèle logique et de compteurs (tables/index attendus, présents, créés), sans afficher les noms physiques ;
- confirmer que `ks-pipeline` reste inchangé dans son rôle d'orchestration ;
@@ -1346,7 +1332,7 @@ La version ne peut être clôturée que si :
- les index ajoutés correspondent à des requêtes réelles ;
- aucune API publique de `ks-store` n'expose PostgreSQL ou SQLx ;
- aucune crate externe n'interprète les paramètres PostgreSQL ;
- PostgreSQL reste entièrement fonctionnel comme backend actif, avec ses SQL ressources sous `migrations/postgres/` et ses logs sous `ks-store.pg.*` ;
- PostgreSQL reste entièrement fonctionnel comme backend actif, avec ses SQL ressources sous `migrations/postgres/` et ses logs sous le target canonique `ks-store` avec domaine structuré `ks-store.pg` ;
- aucun secret n'apparaît dans diagnostics/erreurs/résumés runtime/logs ;
- les tables futures sont guidées par des faits canoniques, pas par des Program IDs ;
- aucune table DEX spéculative n'a été gelée sans matérialiseur réel ;
@@ -1368,18 +1354,102 @@ Les retours de revue de `pre.001` fixent désormais les points suivants :
8. SQL PostgreSQL sous `ks-store/migrations/postgres/`, une instruction par fichier, fonctions privées `include_str!`, tables/keys/index/drop/truncate séparés et orchestrateur d'init ;
9. façade publique `Store` backend-agnostique et PostgreSQL entièrement privé ;
10. configuration backend opaque jusqu'à `ks-store`, sans dépendance `ks-store -> ks-config` ;
11. résumé runtime/init sans secrets exposé à `kb-app-demo-desktop` et réconciliation future de `demo_sql` ;
12. logging PostgreSQL sous `ks-store.pg.*`, sans secrets ni valeurs bindées par défaut ;
11. résumé runtime/init sans secrets exposé à `kb-app-demo-desktop` et renommage structurel immédiat des surfaces `demo_sql_*` vers `demo_store_*` ;
12. logging PostgreSQL sous le target canonique `ks-store` avec `backend="postgres"` et `domain="ks-store.pg"`, sans secrets ni valeurs bindées par défaut ;
13. pagination cursorisée/bornée et distinction gel logique/index physiques ;
14. architecture future préservée et précisée : N1 Worker 1/raw, N2 Worker 2/Core, N3 decode/materialization générique avec `k_sol_mat_outputs`, N4 projections spécialisées/queryables ;
15. les contrats N1/N2/N3 sont fortement gelés après `0.5.3` sauf urgence ou omission structurelle majeure ; les tables/modèles N4 restent plus souples et évolutifs ;
16. replays explicites et indépendants N1 -> N2, N2 -> N3 et N3 -> N4, avec idempotence, version de processor/projector et invalidation descendante ;
17. aucune troisième table `outer` : les instructions historiquement dites outer sont les top-level ; les nouveaux contrats utilisent `top-level` et la table CPI conserve `stack_height` ainsi que le parent CPI immédiat reconstructible ;
18. metadata N4 prévue en deux projections : asset/token metadata commune Metaplex + Token-2022 et program metadata distincte pour SPM, toutes deux reconstructibles depuis N3 ;
19. `demo_sql` évolue vers des résultats tabulaires backend-agnostiques, `demo_config` cesse d'exposer PostgreSQL/SQLite, et le splash vérifie des modèles logiques avec compteurs sans noms de tables/index ;
19. `demo_store_*` devient la nomenclature technique dès `pre.002`; sa présentation finale évolue vers des résultats tabulaires backend-agnostiques, `demo_config` cesse d'exposer PostgreSQL/SQLite, et le splash vérifie des modèles logiques avec compteurs sans noms de tables/index ;
20. la façade `Store` est destinée à être ouverte une fois et conservée dans `AppState`, les commandes desktop réutilisant cette capacité générique ;
21. `pre.007` est un premier candidat de clôture, jamais une obligation : la clôture est décalée si des manques apparaissent ;
22. Anchor reste hors périmètre fonctionnel de `0.5.3`, mais devient un canari explicite du gel : N1/N2/N3 doivent conserver sans perte les informations génériques nécessaires aux futurs decoders (instructions/CPI, comptes ordonnés et flags, logs, `returnData` réelle, observations/états de comptes, temporalité/provenance) et N3 doit pouvoir tracer le decoder + schéma/IDL/version/hash utilisés ;
23. les 13 tables sont la baseline existante, pas un quota final : si ce canari révèle une omission Solana générique, `0.5.3` peut ajouter avant gel un contrat N1/N2/N3 canonique non nommé d'après Anchor.
Ces décisions remplacent les propositions initiales de fusion des instructions et de conservation immuable des migrations `0001` à `0004`. `pre.002` peut démarrer sur cette base ; aucune migration SQL massive n'est encore incluse dans `pre.001`.
## 32. État réalisé de `0.5.3-pre.002`
La tranche `0.5.3-pre.002` réalise la première rupture effective de dépendance au backend concret, sans modifier le schéma SQL historique qui reste volontairement réservé à `pre.003`.
### 32.1 Façade et possession de la connexion
- `ks-store` expose désormais `Store` et `StoreOpenOptions` comme frontière publique douverture et dutilisation du stockage ;
- `PostgresStore`, `PostgresStoreOptions`, le pool SQLx et les helpers PostgreSQL restent internes à `ks-store` ;
- `Store` implémente les contrats fonctionnels déjà consommés par les pipelines et délègue au backend actif sans faire remonter le dispatch dans les crates consommatrices ;
- le desktop conserve un `Store` ouvert une seule fois dans `AppState` via `tokio::sync::OnceCell`, puis les commandes réutilisent cette capacité ;
- `ks-pipeline-demo-scenarios` utilise également la façade générique et ne construit plus le backend PostgreSQL.
### 32.2 Configuration backend opaque
Le contrat runtime de `ks-config` conserve désormais uniquement :
```text
enabled
backend
backend_options
```
`backend_options` reste un objet JSON opaque pour `ks-config`. La sélection, la validation des paramètres PostgreSQL, la création de la connexion et lauto-initialisation sont interprétées par `ks-store`. `ks-store` ne dépend pas de `ks-config`.
PostgreSQL est le seul backend opérationnel de cette tranche. Un backend inconnu ou incomplet est refusé par une erreur structurée qui ne recopie pas ses options sensibles.
### 32.3 Diagnostics et résumé runtime génériques
La surface publique fournit des DTO backend-agnostiques pour :
- configuration sanitisée ;
- backend descriptor masqué ;
- health ;
- état de migration ;
- ressources logiques et statistiques ;
- vérification par modèle logique ;
- résumé dinitialisation ;
- résumé runtime complet.
Le résumé dinitialisation regroupe actuellement les ressources du schéma historique sous les modèles logiques `raw`, `core`, `processing`, `decode` et `materialization`. Il expose des compteurs de ressources attendues/disponibles/créées sans exposer les noms physiques. Une liste générique de catégories dobjets backend expose en plus les compteurs physiques sans noms : PostgreSQL fournit déjà la catégorie `table`; `pre.003` ajoutera la catégorie `index` lors de la reconstruction/introspection du nouveau baseline. Un futur backend pourra fournir dautres catégories sans modifier le contrat du desktop.
La constante `STORE_SCHEMA_CONTRACT_VERSION` identifie explicitement cette étape comme un schéma legacy transitoire ; elle ne constitue pas le snapshot frozen final.
### 32.4 Replay et API publique
Les DTO publics de diagnostic et de replay ne portent plus le préfixe `Postgres`. Le vocabulaire nouveau utilise `top-level` au lieu de `outer`. Les quatre anciens traits publics sans implémentation PostgreSQL réelle et leurs DTO historiques sont supprimés au lieu dêtre figés.
La structure SQL et les requêtes restent encore basées sur les tables `kb_sol_*` de `0.5.2` : leur reconstruction sous `k_sol_*`, lalignement top-level/CPI et le nouveau baseline appartiennent toujours à `pre.003`.
### 32.5 Desktop
Les commandes et payloads nécessaires au desktop ne construisent plus un backend concret. `demo_config` reçoit un résumé store sanitisé ; les diagnostics SQL utilisent désormais des ressources logiques génériques et un descriptor de connexion masqué. Le splash utilise le résumé dinitialisation par modèle et des compteurs, sans afficher de noms physiques de tables/index.
Les noms historiques de fenêtres/commandes `demo_sql_*` sont supprimés dès `pre.002` et remplacés par `demo_store_*`. `pre.005` conserve uniquement la refonte fonctionnelle finale de lexpérience tabulaire, de `demo_config` et du splash autour du nouveau baseline.
### 32.6 Logging et sécurité
Le backend PostgreSQL utilise lunique target canonique de la crate :
```text
target: crate::TRACING_TARGET // "ks-store"
backend = "postgres"
domain = "ks-store.pg"
action = "connection | migration | query | health | replay | ..."
```
Un canari workspace interdit désormais les types/symboles PostgreSQL/SQLx dans les crates consommatrices et vérifie que limplémentation PostgreSQL utilise `target: crate::TRACING_TARGET` avec les champs structurés `backend="postgres"` et `domain="ks-store.pg"`. Des tests sentinelles vérifient également quun backend inconnu, un descriptor masqué et les résumés publics ne recopient pas des options contenant un secret.
Le nettoyage fin de linstrumentation des requêtes (durées, nombres de lignes et suppression systématique de toute valeur bindée des traces normales) reste couplé à la réécriture des repositories de `pre.004`, conformément au plan.
### 32.7 Limites volontaires de la tranche
`pre.002` ne :
- renomme aucune table `kb_sol_*` ;
- ne crée aucun contrat N1/N2/N3 supplémentaire ;
- ne restructure pas encore `migrations/postgres/` ;
- ne change pas `block_time`, `stack_height`, la hiérarchie CPI ou `k_sol_mat_outputs` ;
- ne crée aucune projection N4 metadata/trading ;
- nimplémente pas Anchor.
Ces travaux restent affectés aux tranches `pre.003+` prévues par le présent plan.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/RULES_RUST.md -->
<!-- version: 8 -->
<!-- version: 9 -->
# Règles Rust générales
@@ -101,6 +101,7 @@ implicit_saturating_sub = "allow"
## Visibilité et API de crate
- Aucun `pub mod` n'est autorisé. Les modules restent privés et l'API est constituée exclusivement par des réexports explicites depuis le point dentrée de la crate.
- Aucun `pub(in ...)` ni `pub(super)` n'est autorisé : un élément partagé au-delà de son module est `pub(crate)`, réexporté au crate-root, puis consommé via `crate::Item`; sinon il reste strictement privé.
- Un élément `pub` inaccessible depuis le point d'entrée de sa crate est une erreur de conception, pas un simple avertissement.
- Un élément `pub(crate)` utilisé hors de son module est réexporté au niveau du point d'entrée de la crate.
- Les chemins internes de modules ne font pas partie de l'API stable.