v0.2.7-pre.014

This commit is contained in:
2026-08-23 11:15:57 +02:00
parent 3c5786f273
commit 5aa7b45840
23 changed files with 1605 additions and 103 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml # file: Cargo.toml
# version: 214 # version: 215
[workspace] [workspace]
resolver = "3" resolver = "3"
members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"] members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"]
[workspace.package] [workspace.package]
version = "0.2.7-pre.13" version = "0.2.7-pre.14"
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"

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md --> <!-- file: ROADMAP.md -->
<!-- version: 80 --> <!-- version: 81 -->
# Roadmap KSP # Roadmap KSP
@@ -51,7 +51,7 @@ Le roadmap décrit les objectifs à atteindre et les grandes étapes prévues. U
- [X] `0.2.4` — HTTP Blocks + Economics stable : 15/15 wrappers `V0_2_4` publiés, surface typed complète à 52/52 méthodes courantes, 14/14 historiques conservées, réaudit SIMD/inventaire final et `KSP-TRANSPORT-007` global validés ; deux smokes Devnet passés avant publication. - [X] `0.2.4` — HTTP Blocks + Economics stable : 15/15 wrappers `V0_2_4` publiés, surface typed complète à 52/52 méthodes courantes, 14/14 historiques conservées, réaudit SIMD/inventaire final et `KSP-TRANSPORT-007` global validés ; deux smokes Devnet passés avant publication.
- [X] `0.2.5` — Wallet foundation stable : `.kspwallet` V1, VIEW/OWNER indépendants, Argon2id/XChaCha20-Poly1305, autorité Ed25519 OWNER, persistence no-clobber, signature, administration/rotations/révocation VIEW forte, import/export Solana CLI JSON + Base58, canaris adversariaux, interop externe et documentation durable publiés. La clôture `pre.010-fix.001``fix.003` ajoute `ed25519-dalek 3.0.0` direct, normalise le Rust workspace et installe laudit structurel Python complémentaire à rustfmt/Clippy. `Pubkey` reste via `ksp-core-lib`, la keypair reste encapsulée dans Wallet et Config/Transport/ExecutionPolicy/Store/Tauri restent hors Wallet. - [X] `0.2.5` — Wallet foundation stable : `.kspwallet` V1, VIEW/OWNER indépendants, Argon2id/XChaCha20-Poly1305, autorité Ed25519 OWNER, persistence no-clobber, signature, administration/rotations/révocation VIEW forte, import/export Solana CLI JSON + Base58, canaris adversariaux, interop externe et documentation durable publiés. La clôture `pre.010-fix.001``fix.003` ajoute `ed25519-dalek 3.0.0` direct, normalise le Rust workspace et installe laudit structurel Python complémentaire à rustfmt/Clippy. `Pubkey` reste via `ksp-core-lib`, la keypair reste encapsulée dans Wallet et Config/Transport/ExecutionPolicy/Store/Tauri restent hors Wallet.
- [X] `0.2.6``ksp-app-wallet-desk` + `.kspwallet` V2 stables : composition Config/Wallet/HTTP/Logging, lifecycle VIEW/OWNER, balance, administration/import/export, wire binaire V2, APIs multi-version, migration V1 -> V2 explicite et runtime Tauri packagé user-writable validés ; bundles Linux `.deb`/`.rpm`/`.AppImage` produits avant publication. Plan clôturé : `docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md`. - [X] `0.2.6``ksp-app-wallet-desk` + `.kspwallet` V2 stables : composition Config/Wallet/HTTP/Logging, lifecycle VIEW/OWNER, balance, administration/import/export, wire binaire V2, APIs multi-version, migration V1 -> V2 explicite et runtime Tauri packagé user-writable validés ; bundles Linux `.deb`/`.rpm`/`.AppImage` produits avant publication. Plan clôturé : `docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md`.
- [ ] `0.2.7`Étendre `ksp-onchain-transport-lib` au WebSocket Solana standard complet ; permettre plusieurs sessions sur une même URL sans imposer encore un pool automatique complexe. - [/] `0.2.7`WebSocket Solana standard complet en candidate : 9 familles subscribe/unsubscribe typées, sessions physiques multiples explicites, lifecycle/reconnect/resubscribe/backpressure bornés, Config V2, compliance 18/18 et smoke Devnet live validés ; publication stable encore réservée à `rel.001`.
- [ ] `0.2.8` — Ajouter Helius LaserStream WebSocket comme extension du moteur WebSocket standard, sans duplication de client. - [ ] `0.2.8` — Ajouter Helius LaserStream WebSocket comme extension du moteur WebSocket standard, sans duplication de client.
- [ ] `0.2.9` — Ajouter une première fondation Yellowstone gRPC standard/provider-neutral ; dimensionner la surface exacte à `pre.001` selon la documentation normative actuelle. - [ ] `0.2.9` — Ajouter une première fondation Yellowstone gRPC standard/provider-neutral ; dimensionner la surface exacte à `pre.001` selon la documentation normative actuelle.
- [ ] `0.2.10` — Introduire `ksp-offchain-transport-lib` avec un premier lecteur de prix, au minimum SOL/USD et SOL/EUR. - [ ] `0.2.10` — Introduire `ksp-offchain-transport-lib` avec un premier lecteur de prix, au minimum SOL/USD et SOL/EUR.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-app-config-desk/README.md --> <!-- file: crates/ksp-app-config-desk/README.md -->
<!-- version: 27 --> <!-- version: 28 -->
# `ksp-app-config-desk` # `ksp-app-config-desk`
@@ -78,7 +78,7 @@ Les DTO Rust applicatifs restent la source de vérité et les bindings généré
## Robustesse desktop et extensibilité ## Robustesse desktop et extensibilité
`pre.018` rend le fallback de bootstrap Logging testable avant installation du subscriber : la résolution produit d'abord un plan `managed` ou `fallback`, puis seulement l'initialisation runtime est tentée. Une source Logging invalide peut ainsi être couverte par test sans installer un subscriber global dans le processus de tests. Le fallback reste transitoire, console-only, niveau `Info`, sans file sink. Le fallback de bootstrap Logging est testable avant installation du subscriber : la résolution produit d'abord un plan `managed` ou `fallback`, puis seulement l'initialisation runtime est tentée. Une source Logging invalide peut ainsi être couverte par test sans installer un subscriber global dans le processus de tests. Le fallback reste transitoire, console-only, niveau `Info`, sans file sink.
Le frontend possède désormais `shell_registry.ts`. Le registre décrit les vues du shell et les adapters d'éditeurs spécialisés par `file_id`. Le panneau Documents reste générique ; lorsqu'un document possède un adapter enregistré, **Ouvrir l'éditeur spécialisé** déclenche la navigation par événement de registre. `cfg.std.logging -> Logging` est le premier adapter. Ajouter un futur éditeur ne demande donc pas de réécrire le moteur Documents ni la logique générale d'activation des panneaux. Le frontend possède désormais `shell_registry.ts`. Le registre décrit les vues du shell et les adapters d'éditeurs spécialisés par `file_id`. Le panneau Documents reste générique ; lorsqu'un document possède un adapter enregistré, **Ouvrir l'éditeur spécialisé** déclenche la navigation par événement de registre. `cfg.std.logging -> Logging` est le premier adapter. Ajouter un futur éditeur ne demande donc pas de réécrire le moteur Documents ni la logique générale d'activation des panneaux.
@@ -123,11 +123,11 @@ main -> ksp-app-config-desk.frontend.main
splash -> ksp-app-config-desk.frontend.splash splash -> ksp-app-config-desk.frontend.splash
``` ```
Rust valide le niveau et le `targetId`, choisit un callsite statique puis émet exclusivement via les macros de `ksp-logging-lib`. Le package applicatif n'importe pas directement `tracing`. Le pont actuel garantit donc le trajet WebView -> Rust tout en conservant l'affichage local des appels `console.*` dans la console WebKit. Le retour général Rust -> console WebKit est volontairement hors périmètre de `0.1.4` : une future intégration devra passer par une couche possédée par `ksp-logging-lib`, sans second subscriber, double émission ni boucle avec le bridge KSP. Le panneau **Test Logging** complète désormais ce bridge : il peut émettre des événements backend via `ksp-logging-lib` avec target KSP statique et domain contrôlé, ou réutiliser le bridge frontend existant avec son target/domain fixes. Rust valide le niveau et le `targetId`, choisit un callsite statique puis émet exclusivement via les macros de `ksp-logging-lib`. Le package applicatif n'importe pas directement `tracing`. Le pont actuel garantit donc le trajet WebView -> Rust tout en conservant l'affichage local des appels `console.*` dans la console WebKit. Le retour général Rust -> console WebKit reste volontairement hors de la surface actuelle : une future intégration devra passer par une couche possédée par `ksp-logging-lib`, sans second subscriber, double émission ni boucle avec le bridge KSP. Le panneau **Test Logging** complète désormais ce bridge : il peut émettre des événements backend via `ksp-logging-lib` avec target KSP statique et domain contrôlé, ou réutiliser le bridge frontend existant avec son target/domain fixes.
## Panneau Test Logging ## Panneau Test Logging
`pre.017` ajoute une surface de validation volontairement explicite. Le champ **Message** est le contenu qui sera réellement journalisé ; il ne doit donc jamais recevoir de Secret. **Log backend** appelle `emit_logging_test`, qui valide le niveau (`trace/debug/info/warn/error/tous`), choisit un target statique (`ksp-app-config-desk` ou `ksp-app-config-desk.logging-test`) et applique un domain absent, connu ou personnalisé borné avant d'émettre exclusivement avec les macros `ksp-logging-lib`. Le résultat retourne uniquement des métadonnées sûres : nombre d'événements, niveau demandé, target/domain effectifs et génération runtime. Le panneau fournit une surface de validation volontairement explicite. Le champ **Message** est le contenu qui sera réellement journalisé ; il ne doit donc jamais recevoir de Secret. **Log backend** appelle `emit_logging_test`, qui valide le niveau (`trace/debug/info/warn/error/tous`), choisit un target statique (`ksp-app-config-desk` ou `ksp-app-config-desk.logging-test`) et applique un domain absent, connu ou personnalisé borné avant d'émettre exclusivement avec les macros `ksp-logging-lib`. Le résultat retourne uniquement des métadonnées sûres : nombre d'événements, niveau demandé, target/domain effectifs et génération runtime.
**Log via bridge frontend** réutilise le bridge déjà installé. Son contrat reste volontairement fixe : `target=ksp-app-config-desk.frontend.main`, `domain=frontend`. Cela permet de comparer dans le même panneau le routing backend et le chemin WebView -> Rust -> `ksp-logging-lib`, avant et après modification/hot reload des filtres. **Log via bridge frontend** réutilise le bridge déjà installé. Son contrat reste volontairement fixe : `target=ksp-app-config-desk.frontend.main`, `domain=frontend`. Cela permet de comparer dans le même panneau le routing backend et le chemin WebView -> Rust -> `ksp-logging-lib`, avant et après modification/hot reload des filtres.
@@ -171,13 +171,13 @@ La vue **Logging** charge le document standard exclusivement avec `ConfigManagem
Le panneau expose `format_version`, `logs_directory`, `default_profile`, tous les profils, la console, les fichiers persistants, les filtres locaux, les target overrides et les listes de targets/domains. Le frontend maintient un brouillon typé : create/clone/rename/delete de profils, 0/1/N file sinks et target filters restent locaux jusqu'à **Sauvegarder et appliquer**. Le backend reconstruit les types publics Config et appelle `ConfigManagement::save_logging_document()`, qui valide la totalité du candidat avant remplacement atomique. Après persistence, Config Desk recharge un `ConfigEnvironment` frais, résout le `default_profile`, puis appelle `ksp_logging_lib::reinitialize()` sur le `LoggingGuard` actif. Le hot reload est immédiat et `logging_generation` avance uniquement après succès. Si l'application runtime échoue, l'ancien runtime reste actif et la source précédente est restaurée. **Recharger le document** ne modifie que le brouillon/source persistée. Le panneau expose `format_version`, `logs_directory`, `default_profile`, tous les profils, la console, les fichiers persistants, les filtres locaux, les target overrides et les listes de targets/domains. Le frontend maintient un brouillon typé : create/clone/rename/delete de profils, 0/1/N file sinks et target filters restent locaux jusqu'à **Sauvegarder et appliquer**. Le backend reconstruit les types publics Config et appelle `ConfigManagement::save_logging_document()`, qui valide la totalité du candidat avant remplacement atomique. Après persistence, Config Desk recharge un `ConfigEnvironment` frais, résout le `default_profile`, puis appelle `ksp_logging_lib::reinitialize()` sur le `LoggingGuard` actif. Le hot reload est immédiat et `logging_generation` avance uniquement après succès. Si l'application runtime échoue, l'ancien runtime reste actif et la source précédente est restaurée. **Recharger le document** ne modifie que le brouillon/source persistée.
`pre.016` distingue en plus le **profil default persistant** du **profil runtime actif**. La section **Runtime actif** expose le profil actuellement appliqué, `selection_source` (`default_profile`, `explicit` ou `fallback`), la génération, l'état console, les compteurs de lignes abandonnées et les file sinks réellement actifs. Un profil déjà persisté peut être appliqué explicitement sans modifier `default_profile` ni écrire le document ; cette action est désactivée tant que le brouillon contient des changements non sauvegardés. Le panneau distingue le **profil default persistant** du **profil runtime actif**. La section **Runtime actif** expose le profil actuellement appliqué, `selection_source` (`default_profile`, `explicit` ou `fallback`), la génération, l'état console, les compteurs de lignes abandonnées et les file sinks réellement actifs. Un profil déjà persisté peut être appliqué explicitement sans modifier `default_profile` ni écrire le document ; cette action est désactivée tant que le brouillon contient des changements non sauvegardés.
Chaque lancement de Config Desk crée aussi une `LoggingRuntimeIdentity` stable : `application_id` + timestamp UTC de démarrage + PID. `ksp-logging-lib` utilise cette identité pour préfixer les noms des fichiers actifs et la conserve pendant tous les hot reloads du même processus. Deux lancements distincts ne partagent donc plus le même fichier persistant, même avec une rotation `daily`. Avec la configuration de release `info/ksp-info.log`, un prefix effectif peut être `ksp-app-config-desk.20260816-182519.123Z-p4242.ksp-info.log`. Le path Config reste inchangé ; l'identité appartient au runtime, pas au document source. Chaque lancement de Config Desk crée aussi une `LoggingRuntimeIdentity` stable : `application_id` + timestamp UTC de démarrage + PID. `ksp-logging-lib` utilise cette identité pour préfixer les noms des fichiers actifs et la conserve pendant tous les hot reloads du même processus. Deux lancements distincts ne partagent donc plus le même fichier persistant, même avec une rotation `daily`. Avec la configuration de release `info/ksp-info.log`, un prefix effectif peut être `ksp-app-config-desk.20260816-182519.123Z-p4242.ksp-info.log`. Le path Config reste inchangé ; l'identité appartient au runtime, pas au document source.
## Baseline Logging de release ## Baseline Logging de release
La configuration canonique livrée avec `0.1.4` revient à une baseline opératoire `info` conformément à KSP-APP-031 : console `info`, sink général `info/ksp-info.log` au niveau `info`, et overrides `ksp-config-lib`, `ksp-logging-lib`, `ksp-app-config-desk` à `info`. Le `default_filter` reste `warn` pour les autres targets KSP. Les niveaux `debug`/`trace` restent disponibles et peuvent être remontés temporairement depuis Config Desk lors dun développement ou diagnostic, puis redescendus avant la release suivante. La configuration canonique de release utilise une baseline opératoire `info` conformément à KSP-APP-031 : console `info`, sink général `info/ksp-info.log` au niveau `info`, et overrides `ksp-config-lib`, `ksp-logging-lib`, `ksp-app-config-desk` à `info`. Le `default_filter` reste `warn` pour les autres targets KSP. Les niveaux `debug`/`trace` restent disponibles et peuvent être remontés temporairement depuis Config Desk lors dun développement ou diagnostic, puis redescendus avant la release suivante.
## Traçabilité frontend ## Traçabilité frontend

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-app-config-desk/USAGE.md --> <!-- file: crates/ksp-app-config-desk/USAGE.md -->
<!-- version: 27 --> <!-- version: 28 -->
# Utilisation de `ksp-app-config-desk` # Utilisation de `ksp-app-config-desk`
@@ -85,7 +85,7 @@ splash
Ils sont convertis côté Rust vers des targets KSP statiques `ksp-app-config-desk.frontend*` et émis uniquement via `ksp-logging-lib`. Un niveau différent de `trace`, `debug`, `info`, `warn` ou `error`, ou un `targetId` non whitelisté, est rejeté avec un `CommandErrorDto` sûr. Ils sont convertis côté Rust vers des targets KSP statiques `ksp-app-config-desk.frontend*` et émis uniquement via `ksp-logging-lib`. Un niveau différent de `trace`, `debug`, `info`, `warn` ou `error`, ou un `targetId` non whitelisté, est rejeté avec un `CommandErrorDto` sûr.
`main.ts` et `splash.ts` installent aussi le bridge `console.*`; l'échec éventuel d'un `invoke` est écrit uniquement sur la console WebView originale afin d'éviter une boucle de logging. Ce bridge conserve les messages JavaScript dans la console WebKit et les transmet vers Rust. Le retour général Rust -> console WebKit est reporté hors `0.1.4`; il devra être ajouté ultérieurement sous ownership de `ksp-logging-lib`, sans installer de subscriber Tauri parallèle ni créer de boucle avec ce bridge. `main.ts` et `splash.ts` installent aussi le bridge `console.*`; l'échec éventuel d'un `invoke` est écrit uniquement sur la console WebView originale afin d'éviter une boucle de logging. Ce bridge conserve les messages JavaScript dans la console WebKit et les transmet vers Rust. Le retour général Rust -> console WebKit reste hors de la surface actuelle ; il devra être ajouté ultérieurement sous ownership de `ksp-logging-lib`, sans installer de subscriber Tauri parallèle ni créer de boucle avec ce bridge.
## Bindings TS-RS ## Bindings TS-RS
@@ -287,7 +287,7 @@ Si la résolution ou la préparation du profil explicite échoue, `ksp_logging_l
## Baseline Logging de release ## Baseline Logging de release
Après les tests `debug`/`trace`, la configuration canonique `0.1.4` revient à : Après les tests `debug`/`trace`, la configuration canonique revient à :
```text ```text
default_filter = warn default_filter = warn

View File

@@ -1,9 +1,9 @@
<!-- file: crates/ksp-app-wallet-desk/README.md --> <!-- file: crates/ksp-app-wallet-desk/README.md -->
<!-- version: 2 --> <!-- version: 3 -->
# `ksp-app-wallet-desk` # `ksp-app-wallet-desk`
`ksp-app-wallet-desk` est l'application desktop spécialisée stable d'administration et de validation des wallets KSP depuis KSP `0.2.6`. `ksp-app-wallet-desk` est l'application desktop spécialisée stable d'administration et de validation des wallets KSP.
La crate est un package Tauri mixte : La crate est un package Tauri mixte :
@@ -29,7 +29,7 @@ Le frontend ne reçoit jamais les keypairs, ciphertexts, passwords Config, paths
## `.kspwallet` V1/V2 ## `.kspwallet` V1/V2
La release `0.2.6` conserve V1 et ajoute V2 : La surface courante conserve V1 et utilise V2 comme format natif par défaut :
```text ```text
V1 : JSON UTF-8 historique, lecture explicite toujours supportée V1 : JSON UTF-8 historique, lecture explicite toujours supportée
@@ -45,9 +45,9 @@ Wallet Desk consomme uniquement les APIs non versionnées de `ksp-wallet-lib` :
`ksp-wallet-lib` conserve parallèlement les APIs explicites `_v1` / `_v2` pour les consumers qui doivent imposer un format. `DEFAULT_WALLET_FORMAT` et `LATEST_SUPPORTED_WALLET_FORMAT` sont des politiques distinctes ; l'apparition future d'un V3 n'impose donc pas de modifier automatiquement le format créé par les APIs génériques. `ksp-wallet-lib` conserve parallèlement les APIs explicites `_v1` / `_v2` pour les consumers qui doivent imposer un format. `DEFAULT_WALLET_FORMAT` et `LATEST_SUPPORTED_WALLET_FORMAT` sont des politiques distinctes ; l'apparition future d'un V3 n'impose donc pas de modifier automatiquement le format créé par les APIs génériques.
La migration V1 -> V2 est une opération explicite OWNER-authentifiée possédée par `ksp-wallet-lib`. Wallet Desk `0.2.6` ne migre jamais silencieusement un wallet lors de sa sélection, inspection ou ouverture. La migration V1 -> V2 est une opération explicite OWNER-authentifiée possédée par `ksp-wallet-lib`. Wallet Desk ne migre jamais silencieusement un wallet lors de sa sélection, inspection ou ouverture.
## Capacités fonctionnelles `0.2.6` ## Capacités fonctionnelles
La surface validée comprend : La surface validée comprend :

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-config-lib/README.md --> <!-- file: crates/ksp-config-lib/README.md -->
<!-- version: 7 --> <!-- version: 8 -->
# ksp-config-lib # ksp-config-lib
@@ -86,7 +86,7 @@ Le document Logging refuse les valeurs de sensibilité `Secret` dans sa configur
## Documentation ## Documentation
- [`USAGE.md`](USAGE.md) — construction du moteur, résolution runtime et management ; - [`USAGE.md`](USAGE.md) — construction du moteur, résolution runtime et management ;
- [`TODO.md`](TODO.md) — points explicitement différés après `0.1.3` ; - [`TODO.md`](TODO.md) — points explicitement différés ;
- [`../../docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md`](../../docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md) — plan historique détaillé de la fondation Config ; - [`../../docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md`](../../docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md) — plan historique détaillé de la fondation Config ;
- [`../../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 V2 HTTP + WebSocket, avec lecture backward du V1 HTTP-only ; - [`../../config/std.transport.json`](../../config/std.transport.json) — document standard Transport V2 HTTP + WebSocket, avec lecture backward du V1 HTTP-only ;

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-config-lib/USAGE.md --> <!-- file: crates/ksp-config-lib/USAGE.md -->
<!-- version: 7 --> <!-- version: 8 -->
# Utilisation de ksp-config-lib # Utilisation de ksp-config-lib
@@ -140,7 +140,7 @@ let ws_settings = transport.ws_settings();
let _ = (http_settings, ws_settings); let _ = (http_settings, ws_settings);
``` ```
`std.transport` V2 conserve `retry` et `profiles[].endpoints[]` pour HTTP, ajoute `ws_defaults` et `profiles[].ws_endpoints[]`, puis exige `kind = "solana_standard"` en `0.2.7`. Un `ws_endpoints[].session` optionnel surcharge seulement les paramètres génériques de `WsSessionSettings`. `std.transport` V2 conserve `retry` et `profiles[].endpoints[]` pour HTTP, ajoute `ws_defaults` et `profiles[].ws_endpoints[]`, puis exige actuellement `kind = "solana_standard"`. Un `ws_endpoints[].session` optionnel surcharge seulement les paramètres génériques de `WsSessionSettings`.
Le même schema enregistré conserve la lecture stricte du V1 historique : dans ce cas `http_settings()` reste disponible et `ws_settings()` retourne `None`. Aucun `WsTransportSettings` vide n'est inventé pour simuler l'absence de WebSocket. Le même schema enregistré conserve la lecture stricte du V1 historique : dans ce cas `http_settings()` reste disponible et `ws_settings()` retourne `None`. Aucun `WsTransportSettings` vide n'est inventé pour simuler l'absence de WebSocket.

View File

@@ -0,0 +1,135 @@
<!-- file: crates/ksp-core-lib/README.md -->
<!-- version: 1 -->
# `ksp-core-lib`
`ksp-core-lib` porte les contrats fondamentaux partagés par les couches KSP sans dépendre des domaines de plus haut niveau.
La crate possède actuellement trois responsabilités :
- le type d'erreur commun KSP ;
- le type Solana `Pubkey` réexporté comme primitive d'adresse canonique ;
- le registre KSP des Program IDs Solana fondamentaux et leur taxonomie.
## Frontière architecturale
Core reste une couche basse. Elle ne possède ni configuration, ni logging runtime, ni transport réseau, ni wallet, ni stockage, ni logique de décodage/exécution.
Les crates de niveau supérieur peuvent dépendre de Core et réutiliser ses contrats ; Core ne doit pas introduire de dépendance inverse vers ces couches.
La seule dépendance runtime externe directe actuelle est `solana-pubkey`, utilisée pour la primitive `Pubkey`.
## Erreur commune KSP
Le contrat d'erreur public repose sur :
```text
ErrorCode
ErrorContext
Error
Result<T>
```
`ErrorCode` sépare un `domain` stable d'un `code` stable. `Error` ajoute :
- un message humain ;
- des champs de contexte ordonnés ;
- une source d'erreur standard optionnelle compatible `Send + Sync`.
L'affichage d'une erreur reste compact :
```text
<domain>.<code>: <message>
```
Les consommateurs ajoutent uniquement des contextes sûrs. Les secrets, credentials, key material, URLs sensibles ou payloads massifs ne doivent pas être copiés dans le message ou le contexte d'une erreur.
## `Pubkey`
La crate réexporte :
```rust
ksp_core_lib::Pubkey
```
Les autres crates KSP utilisent cette primitive lorsqu'un contrat public a besoin d'une adresse Solana générique. Elles évitent ainsi de multiplier les propriétaires de type pour la même notion.
## Program IDs fondamentaux
Core possède 18 Program IDs Solana fondamentaux sous deux formes cohérentes :
```text
PRGID_* -> Base58 &str
PRGIDPK_* -> Pubkey typé
```
Les deux formes sont déclarées depuis une même valeur grâce à `declare_program_id!`.
Le registre couvre notamment :
- System, Vote, Stake, Config et Feature ;
- Address Lookup Table et Compute Budget ;
- les loaders natif, BPF v1, BPF v2, BPF upgradeable et Loader v4 ;
- les precompiles Ed25519, Secp256k1 et Secp256r1 ;
- Slashing ;
- ZK ElGamal Proof et ZK Token Proof.
Le registre n'est pas un catalogue général de tous les programmes Solana. Les protocoles, applications et Program IDs de domaines futurs sont ajoutés dans les couches propriétaires appropriées lorsqu'un besoin réel existe.
## Registre et taxonomie
Chaque entrée est exposée sous `ProgramIdEntry` avec :
```text
code
name
program_id
pubkey
domain
family
protocol
subfamily
program_version
kind
```
`ProgramIdKind` distingue actuellement :
```text
Program
Loader
Precompile
EnshrinedProgram
```
La lecture du registre s'effectue par :
```text
entries()
native_program_ids()
program_ids(filter)
program_ids_by_domain(...)
program_ids_by_family(...)
program_ids_by_protocol(...)
find_program_id(...)
find_program_pubkey(...)
```
`ProgramIdFilter` permet de combiner les axes `domain`, `family`, `protocol`, `subfamily`, `program_version` et `kind`.
## Garanties validées
Les tests publics et unitaires verrouillent notamment :
- la correspondance Base58 / `Pubkey` des constantes ;
- l'unicité des codes, Program IDs et pubkeys du registre ;
- les 18 entrées fondamentales ;
- les recherches textuelles et typées ;
- les vues et filtres taxonomiques ;
- l'absence des comptes well-known qui ne sont pas des programmes ;
- le contrat `Error`, son ordre de contexte et sa chaîne `source()` ;
- `Error: Send + Sync`.
## Documentation
- [`USAGE.md`](USAGE.md) — exemples d'utilisation de l'erreur commune, de `Pubkey`, des Program IDs et du registre.

View File

@@ -0,0 +1,265 @@
<!-- file: crates/ksp-core-lib/USAGE.md -->
<!-- version: 1 -->
# Utilisation de `ksp-core-lib`
## Utiliser le type d'erreur commun
Une crate KSP définit des codes stables puis retourne `ksp_core_lib::Result<T>` :
```rust
const ERROR_CODE_LOAD_FAILED: ksp_core_lib::ErrorCode =
ksp_core_lib::ErrorCode::new("store", "load_failed");
fn load_value() -> ksp_core_lib::Result<u64> {
let error = ksp_core_lib::Error::new(
ERROR_CODE_LOAD_FAILED,
"unable to load value",
)
.with_context("operation", "load_value");
return std::result::Result::Err(error);
}
```
Le domaine et le code sont accessibles séparément :
```rust
let code = ERROR_CODE_LOAD_FAILED;
assert_eq!(code.domain(), "store");
assert_eq!(code.code(), "load_failed");
```
Le message et les champs de contexte restent accessibles sans parser `Display` :
```rust
let error = ksp_core_lib::Error::new(
ERROR_CODE_LOAD_FAILED,
"unable to load value",
)
.with_context("component", "postgres")
.with_context("operation", "load_value");
assert_eq!(error.code(), ERROR_CODE_LOAD_FAILED);
assert_eq!(error.message(), "unable to load value");
assert_eq!(error.context()[0].key(), "component");
assert_eq!(error.context()[0].value(), "postgres");
```
Un `ErrorContext` peut aussi être construit indépendamment lorsquun caller prépare explicitement son contexte :
```rust
let context = ksp_core_lib::ErrorContext::new(
"operation",
"load_value",
);
assert_eq!(context.key(), "operation");
assert_eq!(context.value(), "load_value");
```
Les valeurs de contexte doivent être sûres à exposer. Ne pas y placer de secret, credential, seed, key material, URL contenant une clé API ou payload brut volumineux.
## Conserver une erreur source
Une erreur externe compatible `Send + Sync + 'static` peut rester dans la chaîne standard :
```rust
#[derive(Debug)]
struct SourceError;
impl std::fmt::Display for SourceError {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return formatter.write_str("source failure");
}
}
impl std::error::Error for SourceError {}
let error = ksp_core_lib::Error::new(
ERROR_CODE_LOAD_FAILED,
"unable to load value",
)
.with_source(SourceError);
let source = std::error::Error::source(&error);
assert!(source.is_some());
```
La source sert au chaînage d'erreurs ; son contenu ne doit pas être recopié sans contrôle dans un contexte ou un log public.
## Utiliser `Pubkey`
Core réexporte la primitive Solana utilisée par les contrats KSP :
```rust
let system = ksp_core_lib::Pubkey::from_str_const(
ksp_core_lib::PRGID_SOLANA_SYSTEM,
);
assert_eq!(system, ksp_core_lib::PRGIDPK_SOLANA_SYSTEM);
```
Une crate consommatrice peut donc utiliser `ksp_core_lib::Pubkey` dans sa propre API sans dépendre directement de `solana-pubkey` lorsque Core est déjà le propriétaire architectural de cette primitive.
## Utiliser les constantes Program ID
Chaque Program ID Core possède une forme texte et une forme typée :
```rust
let system_text: &str = ksp_core_lib::PRGID_SOLANA_SYSTEM;
let system_pubkey: ksp_core_lib::Pubkey =
ksp_core_lib::PRGIDPK_SOLANA_SYSTEM;
assert_eq!(
system_pubkey,
ksp_core_lib::Pubkey::from_str_const(system_text),
);
```
Les constantes `PRGID_*` sont utiles pour les wires, diagnostics sûrs ou comparaisons texte. Les constantes `PRGIDPK_*` sont préférées dès qu'un contrat manipule une adresse Solana typée.
## Déclarer une paire texte / `Pubkey`
`declare_program_id!` permet à une couche KSP propriétaire d'un Program ID de déclarer les deux représentations depuis une seule valeur Base58 :
```rust
ksp_core_lib::declare_program_id!(
PRGID_EXAMPLE,
PRGIDPK_EXAMPLE,
"11111111111111111111111111111111"
);
assert_eq!(PRGID_EXAMPLE, ksp_core_lib::PRGID_SOLANA_SYSTEM);
assert_eq!(PRGIDPK_EXAMPLE, ksp_core_lib::PRGIDPK_SOLANA_SYSTEM);
```
La macro ne signifie pas que toute nouvelle constante doit être ajoutée au registre Core. La couche propriétaire du domaine décide où vit le nouveau Program ID.
## Parcourir le registre canonique
`entries()` retourne le registre complet en ordre déterministe :
```rust
for entry in ksp_core_lib::entries() {
let code = entry.code();
let name = entry.name();
let text = entry.program_id();
let pubkey = entry.pubkey();
let domain = entry.domain();
let family = entry.family();
let protocol = entry.protocol();
let subfamily = entry.subfamily();
let program_version = entry.program_version();
let kind = entry.kind();
let _ = (
code,
name,
text,
pubkey,
domain,
family,
protocol,
subfamily,
program_version,
kind,
);
}
```
`native_program_ids()` fournit la vue des Program IDs Solana fondamentaux actuellement enregistrés :
```rust
let count = ksp_core_lib::native_program_ids().count();
assert_eq!(count, 18);
```
## Rechercher une entrée
Recherche par représentation Base58 :
```rust
let entry = ksp_core_lib::find_program_id(
ksp_core_lib::PRGID_SOLANA_SYSTEM,
);
let entry = match entry {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert_eq!(entry.code(), "solana.system");
```
Recherche par `Pubkey` :
```rust
let entry = ksp_core_lib::find_program_pubkey(
&ksp_core_lib::PRGIDPK_SOLANA_VOTE,
);
assert!(entry.is_some());
```
Une recherche inconnue retourne `None`; le registre n'invente pas une entrée générique.
## Filtrer par axe simple
Les helpers spécialisés conviennent aux filtres simples :
```rust
let loaders = ksp_core_lib::program_ids_by_family("loader");
for loader in loaders {
assert_eq!(loader.family(), "loader");
}
```
Les vues disponibles peuvent être consommées directement :
```rust
let solana_entries = ksp_core_lib::program_ids_by_domain("solana").count();
let loaders = ksp_core_lib::program_ids_by_family("loader").count();
let solana_protocol = ksp_core_lib::program_ids_by_protocol("solana").count();
assert_eq!(solana_entries, 18);
assert_eq!(loaders, 5);
assert_eq!(solana_protocol, 18);
```
## Combiner plusieurs axes
`ProgramIdFilter` compose les contraintes sans allocation de collection intermédiaire :
```rust
let filter = ksp_core_lib::ProgramIdFilter::new()
.with_domain("solana")
.with_family("loader")
.with_protocol("solana")
.with_subfamily("bpf")
.with_program_version("v2")
.with_kind(ksp_core_lib::ProgramIdKind::Loader);
for entry in ksp_core_lib::program_ids(filter) {
assert_eq!(entry.domain(), "solana");
assert_eq!(entry.family(), "loader");
assert_eq!(entry.protocol(), "solana");
assert_eq!(entry.subfamily(), std::option::Option::Some("bpf"));
assert_eq!(entry.program_version(), std::option::Option::Some("v2"));
assert_eq!(entry.kind(), ksp_core_lib::ProgramIdKind::Loader);
}
```
Un `ProgramIdFilter::new()` vide correspond à toutes les entrées du registre.
## Choisir entre texte, `Pubkey` et descriptor
Utiliser :
```text
PRGID_* / &str pour une représentation Base58 canonique
PRGIDPK_* / Pubkey pour un contrat Solana typé
ProgramIdEntry lorsqu'il faut aussi la taxonomie KSP
```
Ne pas reparcourir les constantes ou reconstruire une taxonomie parallèle dans une crate consommatrice lorsque le registre Core fournit déjà l'information requise.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-logging-lib/USAGE.md --> <!-- file: crates/ksp-logging-lib/USAGE.md -->
<!-- version: 7 --> <!-- version: 8 -->
# Utilisation de ksp-logging-lib # Utilisation de ksp-logging-lib
@@ -48,7 +48,7 @@ Les fichiers persistants interdisent `ansi = true`.
## Runtime multi-output et routing `domain` ## Runtime multi-output et routing `domain`
`0.1.3-pre.005` active le multi-sink, les formats et le routing niveau/target ; `0.1.3-pre.006` complète le routing structuré `domain`. Le runtime supporte donc réellement : Le runtime supporte le multi-sink, les formats, le routing niveau/target et le routing structuré `domain` :
- plusieurs fichiers simultanés ; - plusieurs fichiers simultanés ;
- les formats `Human`, `Compact`, `Pretty` et `Json` ; - les formats `Human`, `Compact`, `Pretty` et `Json` ;

View File

@@ -1,9 +1,9 @@
<!-- file: crates/ksp-onchain-transport-lib/README.md --> <!-- file: crates/ksp-onchain-transport-lib/README.md -->
<!-- version: 18 --> <!-- version: 19 -->
# `ksp-onchain-transport-lib` # `ksp-onchain-transport-lib`
`ksp-onchain-transport-lib` est la bibliothèque KSP propriétaire du transport on-chain Solana. Sa première surface est le transport HTTP JSON-RPC ; les extensions WebSocket et gRPC sont introduites séparément lorsque leur release les cible. `ksp-onchain-transport-lib` est la bibliothèque KSP propriétaire du transport on-chain Solana. Elle fournit le transport HTTP JSON-RPC complet et le moteur WebSocket Solana standard ; les extensions provider-specific et gRPC sont ajoutées séparément lorsquune release les cible.
## Responsabilités ## Responsabilités
@@ -19,7 +19,8 @@ La crate possède :
- les enveloppes JSON-RPC 2.0 et leur validation ; - les enveloppes JSON-RPC 2.0 et leur validation ;
- le registre audité des méthodes Solana HTTP ; - le registre audité des méthodes Solana HTTP ;
- l'exécution générique des méthodes standard supportées ; - l'exécution générique des méthodes standard supportées ;
- les wrappers typés explicitement livrés par KSP ; - les wrappers typés HTTP et WebSocket explicitement livrés par KSP ;
- les sessions physiques WebSocket, subscriptions logiques, reconnect/resubscribe et backpressure bornés ;
- les snapshots runtime sûrs ; - les snapshots runtime sûrs ;
- l'observabilité Transport via `ksp-logging-lib`. - l'observabilité Transport via `ksp-logging-lib`.
@@ -70,23 +71,23 @@ Le registre porte notamment :
- remplacement historique éventuel ; - remplacement historique éventuel ;
- release de couverture typée KSP. - release de couverture typée KSP.
La release stable `0.2.4` complète la surface typée des **52 méthodes courantes** : La surface HTTP typée couvre les **52 méthodes courantes** :
```text ```text
0.2.1 foundation : 4 foundation : 4
0.2.2 Accounts/Tokens/Cluster : 22 Accounts/Tokens/Cluster : 22
0.2.3 Transactions : 11 Transactions : 11
0.2.4 Blocks/Economics : 15 Blocks/Economics : 15
total : 52 total : 52
``` ```
`0.2.4` ajoute les dix wrappers Blocks et les cinq wrappers Economics. Les points sensibles restent notamment `getBlock` moderne + bare encoding legacy deprecated, les quatre `transactionDetails`, les versions transaction numériques génériques, `numRewardPartitions`, `commissionBps`, les overloads de `getBlocks`, les ranges de production, les valeurs d'inflation/minimum de délégation fournies par le runtime et les `null` positionnels de `getInflationReward`. Les dix wrappers Blocks et les cinq wrappers Economics couvrent notamment `getBlock` moderne + bare encoding legacy deprecated, les quatre `transactionDetails`, les versions transaction numériques génériques, `numRewardPartitions`, `commissionBps`, les overloads de `getBlocks`, les ranges de production, les valeurs d'inflation/minimum de délégation fournies par le runtime et les `null` positionnels de `getInflationReward`.
`KSP-TRANSPORT-007` impose qu'un wrapper typé couvre toutes les possibilités RPC supportées retenues par l'audit : paramètres/options, overloads et formes legacy encore supportées, contraintes déterministes utiles et variantes de réponse pertinentes sans perte. Le réaudit final `0.2.4` agrège le réaudit 37/37 de `0.2.3` avec les 15 nouveaux wrappers et porte la preuve stable à **52/52**. `KSP-TRANSPORT-007` impose qu'un wrapper typé couvre toutes les possibilités RPC supportées retenues par l'audit : paramètres/options, overloads et formes legacy encore supportées, contraintes déterministes utiles et variantes de réponse pertinentes sans perte. Les canaris de release portent la preuve globale à **52/52** méthodes courantes typées.
Les 14 méthodes historiques restent découvrables pour la compliance mais sont `Removed` et ne sont pas simulées comme appelables. Les 14 méthodes historiques restent découvrables pour la compliance mais sont `Removed` et ne sont pas simulées comme appelables.
## Foundation WebSocket `0.2.7-pre.004` ## Moteur WebSocket standard
La première session physique WebSocket est matérialisée sans introduire de pool/scheduler automatique ni de registry de subscriptions anticipé. La première session physique WebSocket est matérialisée sans introduire de pool/scheduler automatique ni de registry de subscriptions anticipé.
@@ -99,25 +100,25 @@ La première session physique WebSocket est matérialisée sans introduire de po
- publie `WsSessionSnapshot` via un état compact `watch` ; - publie `WsSessionSnapshot` via un état compact `watch` ;
- applique aux sockets les plafonds KSP de message, frame et write buffer ; - applique aux sockets les plafonds KSP de message, frame et write buffer ;
- ne projette jamais l'URL dans `Debug`, snapshot, erreurs KSP ou logs ; - ne projette jamais l'URL dans `Debug`, snapshot, erreurs KSP ou logs ;
- répond aux `Ping` reçus et tolère les `Pong`; le lifecycle complet `Close`/shutdown a été durci ensuite en `pre.005`. - répond aux `Ping` reçus et tolère les `Pong`; le lifecycle `Close`/shutdown est borné et explicite.
Le chemin JSON-RPC générique reste `pub(crate)`. Il sert de primitive au moteur typed de subscriptions et **ne constitue pas une API publique raw provider-extension**. Le registry subscriptions et le mapping remote/local sont matérialisés en `pre.006`, reconnect/resubscribe est actif depuis `pre.007` et le backpressure borné par subscription est effectif depuis `pre.008`. Le chemin JSON-RPC générique reste `pub(crate)`. Il sert de primitive au moteur typed de subscriptions et **ne constitue pas une API publique raw provider-extension**. Le registry de subscriptions et le mapping remote/local, le reconnect/resubscribe et le backpressure borné par subscription font partie du moteur standard.
Les tests déterministes utilisent un serveur WebSocket local et prouvent le handshake, le round-trip JSON-RPC, le dispatch de réponses hors ordre, l'isolation des erreurs RPC applicatives, deux sessions physiques distinctes sur la même URL et la redaction des erreurs de connexion. Les tests déterministes utilisent un serveur WebSocket local et prouvent le handshake, le round-trip JSON-RPC, le dispatch de réponses hors ordre, l'isolation des erreurs RPC applicatives, deux sessions physiques distinctes sur la même URL et la redaction des erreurs de connexion.
### Durcissement `0.2.7-pre.005` ### Limites, control frames et shutdown
La session physique dispose désormais de `WsSession::close().await`. Le signal de shutdown est distinct de la command queue, passe l'état en `Closing`, annule les requests JSON-RPC en attente, envoie un Close WebSocket best-effort sous `close_timeout`, puis publie `Closed`. Un peer qui ne répond pas au Close ne peut donc pas bloquer indéfiniment le shutdown. La session physique dispose désormais de `WsSession::close().await`. Le signal de shutdown est distinct de la command queue, passe l'état en `Closing`, annule les requests JSON-RPC en attente, envoie un Close WebSocket best-effort sous `close_timeout`, puis publie `Closed`. Un peer qui ne répond pas au Close ne peut donc pas bloquer indéfiniment le shutdown.
Les limites `max_message_size`, `max_frame_size`, `max_write_buffer_size` et `max_pending_requests` sont couvertes par des fixtures adversariales locales. Les requests outbound qui dépassent les bornes message/frame sont rejetées avant écriture ; les frames/messages inbound surdimensionnés sont rejetés par Tungstenite avant parse JSON. Les timeouts pending libèrent leur capacité sans faire tomber une session encore saine. Les limites `max_message_size`, `max_frame_size`, `max_write_buffer_size` et `max_pending_requests` sont couvertes par des fixtures adversariales locales. Les requests outbound qui dépassent les bornes message/frame sont rejetées avant écriture ; les frames/messages inbound surdimensionnés sont rejetés par Tungstenite avant parse JSON. Les timeouts pending libèrent leur capacité sans faire tomber une session encore saine.
Ping/Pong/Close sont traités comme control frames : le Pong automatique Tungstenite est flushé et aucun heartbeat applicatif périodique n'est ajouté. Depuis `pre.007`, un Close distant inattendu, EOF, erreur I/O/TLS/WebSocket ou violation protocolaire structurelle entre dans le reconnect borné ; `Closed` reste réservé au shutdown local explicite ou à la disparition des handles. Ping/Pong/Close sont traités comme control frames : le Pong automatique Tungstenite est flushé et aucun heartbeat applicatif périodique n'est ajouté. Un Close distant inattendu, EOF, erreur I/O/TLS/WebSocket ou violation protocolaire structurelle entre dans le reconnect borné ; `Closed` reste réservé au shutdown local explicite ou à la disparition des handles.
### Registry de subscriptions `0.2.7-pre.006` ### Registry de subscriptions
Le même actor possède maintenant le registre des subscriptions logiques, sans exposer les IDs numériques distants. Chaque subscription reçoit un `WsSubscriptionId` local stable, et le mapping `remote_subscription_id -> WsSubscriptionId` reste strictement runtime/interne. Le même actor possède maintenant le registre des subscriptions logiques, sans exposer les IDs numériques distants. Chaque subscription reçoit un `WsSubscriptionId` local stable, et le mapping `remote_subscription_id -> WsSubscriptionId` reste strictement runtime/interne.
La création générique typed reste `pub(crate)` et n'est jamais exposée comme API raw provider-extension. À partir de `pre.009`, les wrappers standard publics l'utilisent derrière leurs DTOs et paramètres typés. Le handle public `WsSubscription<T>` expose uniquement : La création générique typed reste `pub(crate)` et n'est jamais exposée comme API raw provider-extension. Les wrappers standard publics lutilisent derrière leurs DTOs et paramètres typés. Le handle public `WsSubscription<T>` expose uniquement :
- `id()` et `kind()` ; - `id()` et `kind()` ;
- `state()` ; - `state()` ;
@@ -126,7 +127,7 @@ La création générique typed reste `pub(crate)` et n'est jamais exposée comme
L'ACK de subscribe est traité atomiquement dans l'actor : le remote ID est lié au local ID avant que la notification suivante puisse être dispatchée. Les notifications inconnues/stale sont ignorées avec un diagnostic sûr. Un mismatch de méthode de notification ou un échec de décodage typed termine uniquement la subscription concernée ; la session physique reste `Active`. L'ACK de subscribe est traité atomiquement dans l'actor : le remote ID est lié au local ID avant que la notification suivante puisse être dispatchée. Les notifications inconnues/stale sont ignorées avec un diagnostic sûr. Un mismatch de méthode de notification ou un échec de décodage typed termine uniquement la subscription concernée ; la session physique reste `Active`.
### Reconnect et resubscribe `0.2.7-pre.007` ### Reconnect et resubscribe
Une perte de connexion physique invalide immédiatement les remote subscription IDs et incrémente `continuity_gap_count`. Le runtime utilise `WsReconnectSettings` pour appliquer un nombre fini de tentatives avec backoff exponentiel borné et sans jitter. Le shutdown surveille les phases de backoff et de handshake et interrompt la reprise sans reconnecter uniquement pour nettoyer des subscriptions. Une perte de connexion physique invalide immédiatement les remote subscription IDs et incrémente `continuity_gap_count`. Le runtime utilise `WsReconnectSettings` pour appliquer un nombre fini de tentatives avec backoff exponentiel borné et sans jitter. Le shutdown surveille les phases de backoff et de handshake et interrompt la reprise sans reconnecter uniquement pour nettoyer des subscriptions.
@@ -136,7 +137,7 @@ Avec `WsResubscribePolicy::Never`, la session physique peut se reconnecter mais
Le compteur de continuity gaps est un signal d'observabilité, pas une garantie de livraison. Transport n'ajoute aucun backfill HTTP et ne promet aucune continuité lossless pendant l'intervalle de déconnexion. Le compteur de continuity gaps est un signal d'observabilité, pas une garantie de livraison. Transport n'ajoute aucun backfill HTTP et ne promet aucune continuité lossless pendant l'intervalle de déconnexion.
### Backpressure et libération de capacité `0.2.7-pre.008` ### Backpressure et libération de capacité
Chaque subscription dispose de sa propre queue typed bornée par `notification_queue_capacity`. Le runtime ne droppe jamais silencieusement une notification lorsque cette queue est pleine : il incrémente `WsSessionSnapshot::overflow_count()`, fait passer uniquement le handle lent à `Failed`, publie `ERROR_CODE_WS_BACKPRESSURE_OVERFLOW` via `WsSubscription::terminal_error_code()` et programme un `*Unsubscribe` distant best-effort. Les autres subscriptions et la session physique restent utilisables. Chaque subscription dispose de sa propre queue typed bornée par `notification_queue_capacity`. Le runtime ne droppe jamais silencieusement une notification lorsque cette queue est pleine : il incrémente `WsSessionSnapshot::overflow_count()`, fait passer uniquement le handle lent à `Failed`, publie `ERROR_CODE_WS_BACKPRESSURE_OVERFLOW` via `WsSubscription::terminal_error_code()` et programme un `*Unsubscribe` distant best-effort. Les autres subscriptions et la session physique restent utilisables.
@@ -146,7 +147,7 @@ Les autres terminaisons en échec publient également un code KSP sûr sur le ha
Les fixtures adversariales prouvent l'isolation d'un consumer lent, la survie d'une subscription saine, le cleanup distant best-effort, la réutilisation de capacité après unsubscribe ou abandon du receiver et la conservation du compteur d'overflow à travers les snapshots. Aucune promesse de livraison lossless n'est ajoutée. Les fixtures adversariales prouvent l'isolation d'un consumer lent, la survie d'une subscription saine, le cleanup distant best-effort, la réutilisation de capacité après unsubscribe ou abandon du receiver et la conservation du compteur d'overflow à travers les snapshots. Aucune promesse de livraison lossless n'est ajoutée.
### Wrappers stables lot A `0.2.7-pre.009` ### Wrappers stables : account, program et logs
Les trois premiers wrappers WebSocket standards sont publics sur `WsSession` : Les trois premiers wrappers WebSocket standards sont publics sur `WsSession` :
@@ -162,9 +163,9 @@ logs_subscribe -> WsSubscription<SolanaRpcResponse<SolanaLogsNotification>>
`SolanaLogsSubscribeFilter` rend les trois filtres upstream explicites : `All`, `AllWithVotes` et `Mentions(Pubkey)`. La variante `Mentions` encode par construction exactement une adresse. `SolanaLogsNotification` conserve la signature opaque, le `err` nullable et l'ordre des messages `logs`, enveloppés dans `SolanaRpcResponse`. `SolanaLogsSubscribeFilter` rend les trois filtres upstream explicites : `All`, `AllWithVotes` et `Mentions(Pubkey)`. La variante `Mentions` encode par construction exactement une adresse. `SolanaLogsNotification` conserve la signature opaque, le `err` nullable et l'ordre des messages `logs`, enveloppés dans `SolanaRpcResponse`.
L'unsubscribe de ces trois familles passe toujours par `WsSubscription::unsubscribe()`: le caller ne voit ni ne fournit l'ID serveur. Les paramètres initiaux restent conservés par l'actor pour le resubscribe déterministe acquis en `pre.007`, et toutes les règles de backpressure/terminal error acquises en `pre.008` s'appliquent sans branche spéciale aux nouveaux DTOs publics. L'unsubscribe de ces trois familles passe toujours par `WsSubscription::unsubscribe()`: le caller ne voit ni ne fournit l'ID serveur. Les paramètres initiaux restent conservés par lactor pour le resubscribe déterministe, et toutes les règles de backpressure/terminal error sappliquent sans branche spéciale aux DTOs publics.
### Wrappers stables lot B `0.2.7-pre.010` ### Wrappers stables : signature, slot et root
Le second lot stable complète les subscriptions standard non instables : Le second lot stable complète les subscriptions standard non instables :
@@ -178,9 +179,9 @@ root_subscribe -> WsSubscription<u64>
Une cancellation effectuée avant cette terminaison continue d'utiliser `WsSubscription::unsubscribe()` et émet `signatureUnsubscribe` avec le remote ID détenu uniquement par l'actor. Après la notification terminale, `unsubscribe()` devient local-only et retourne `false`, puisque la subscription est déjà fermée côté serveur et côté KSP. Une cancellation effectuée avant cette terminaison continue d'utiliser `WsSubscription::unsubscribe()` et émet `signatureUnsubscribe` avec le remote ID détenu uniquement par l'actor. Après la notification terminale, `unsubscribe()` devient local-only et retourne `false`, puisque la subscription est déjà fermée côté serveur et côté KSP.
`slot_subscribe()` et `root_subscribe()` n'acceptent aucun paramètre. `SolanaSlotNotification` conserve exactement `slot`, `parent` et `root`; `root_subscribe()` délivre directement le root `u64`. Ces deux subscriptions restent continues et utilisent donc le reconnect/resubscribe standard de `pre.007`. `slot_subscribe()` et `root_subscribe()` n'acceptent aucun paramètre. `SolanaSlotNotification` conserve exactement `slot`, `parent` et `root`; `root_subscribe()` délivre directement le root `u64`. Ces deux subscriptions restent continues et utilisent donc le reconnect/resubscribe standard.
### Wrappers unstable `0.2.7-pre.011` ### Wrappers unstable : block, slotsUpdates et vote
Les trois familles standard restantes complètent désormais l'inventaire **9/9 subscribe + 9/9 unsubscribe via handles** : Les trois familles standard restantes complètent désormais l'inventaire **9/9 subscribe + 9/9 unsubscribe via handles** :
@@ -264,9 +265,9 @@ Les trois tests sont `ignored` par défaut. Les deux smokes Transport appartienn
- [`USAGE.md`](USAGE.md) — consommation directe, Config -> Transport, API typed/raw, smokes et inspection runtime ; - [`USAGE.md`](USAGE.md) — consommation directe, Config -> Transport, API typed/raw, smokes et inspection runtime ;
- [`../../docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](../../docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md) — foundation HTTP stable ; - [`../../docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](../../docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md) — foundation HTTP stable ;
- [`../../docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](../../docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) — extension typed Accounts/Tokens/Cluster ; - [`../../docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](../../docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) — extension typed Accounts/Tokens/Cluster ;
- [`../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) — matrice finale validée `0.2.2` ; - [`../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) — matrice finale validée Accounts/Tokens/Cluster ;
- [`../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) — plan historique clôturé de `0.2.3` ; - [`../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) — plan historique clôturé Transactions ;
- [`../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md) — matrice finale validée `0.2.3` ; - [`../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md) — matrice finale validée Transactions ;
- [`../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan Blocks/Economics et compliance HTTP finale ; - [`../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan Blocks/Economics et compliance HTTP finale ;
- [`../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée `52/52 + 14/14` et audit `KSP-TRANSPORT-007` global ; - [`../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée `52/52 + 14/14` et audit `KSP-TRANSPORT-007` global ;
- [`../../config/std.transport.json`](../../config/std.transport.json) — configuration standard HTTP + WebSocket V2, avec lecture backward V1 HTTP-only. - [`../../config/std.transport.json`](../../config/std.transport.json) — configuration standard HTTP + WebSocket V2, avec lecture backward V1 HTTP-only.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-onchain-transport-lib/USAGE.md --> <!-- file: crates/ksp-onchain-transport-lib/USAGE.md -->
<!-- version: 18 --> <!-- version: 19 -->
# Utilisation de `ksp-onchain-transport-lib` # Utilisation de `ksp-onchain-transport-lib`
@@ -67,7 +67,7 @@ Le document standard peut contenir une URL provenant d'un `KSP_SECRET_*`. La val
## 3. Session physique WebSocket ## 3. Session physique WebSocket
À partir de `0.2.7-pre.004`, un consumer peut créer explicitement une session physique : Un consumer peut créer explicitement une session physique WebSocket :
```rust ```rust
let ws_url = match ksp_onchain_transport_lib::WsEndpointUrl::parse("wss://api.devnet.solana.com") { let ws_url = match ksp_onchain_transport_lib::WsEndpointUrl::parse("wss://api.devnet.solana.com") {
@@ -92,7 +92,7 @@ let snapshot = session.snapshot();
Deux appels `WsSession::connect` avec le même endpoint créent volontairement deux connexions physiques distinctes. Il n'existe encore aucun pool de sessions automatique. Deux appels `WsSession::connect` avec le même endpoint créent volontairement deux connexions physiques distinctes. Il n'existe encore aucun pool de sessions automatique.
Le socket brut et la primitive JSON-RPC générique ne sont pas publics. Le moteur générique de subscription typed existe depuis `pre.006` mais sa création reste `pub(crate)` même après l'ouverture des premiers wrappers standards en `pre.009`; il ne constitue donc pas une escape hatch provider-specific. Le socket brut et la primitive JSON-RPC générique ne sont pas publics. Le moteur générique de subscription typed reste `pub(crate)` ; il ne constitue donc pas une escape hatch provider-specific.
`WsSubscription<T>` est le handle public commun retourné par les wrappers standards. Il porte un `WsSubscriptionId` local stable, jamais le remote ID numérique du serveur. Les notifications arrivent via un receiver typed borné et `unsubscribe().await` exécute le `*Unsubscribe` correspondant en préservant son résultat booléen. `WsSubscription<T>` est le handle public commun retourné par les wrappers standards. Il porte un `WsSubscriptionId` local stable, jamais le remote ID numérique du serveur. Les notifications arrivent via un receiver typed borné et `unsubscribe().await` exécute le `*Unsubscribe` correspondant en préservant son résultat booléen.
@@ -100,7 +100,7 @@ Le snapshot de session expose les subscriptions actuellement enregistrées via `
### Premiers wrappers standards publics ### Premiers wrappers standards publics
Depuis `0.2.7-pre.009`, trois familles stables peuvent être créées directement sur la session : Trois familles stables peuvent être créées directement sur la session :
```rust ```rust
let account = match "11111111111111111111111111111111".parse::<ksp_core_lib::Pubkey>() { let account = match "11111111111111111111111111111111".parse::<ksp_core_lib::Pubkey>() {
@@ -128,7 +128,7 @@ Les trois wrappers retournent le même handle `WsSubscription<T>` : reconnect, r
### Lot stable B : signature, slot et root ### Lot stable B : signature, slot et root
Depuis `0.2.7-pre.010`, la session expose également : La session expose également les familles stables suivantes :
```rust ```rust
let signature_config = ksp_onchain_transport_lib::SolanaSignatureSubscribeConfig::new( let signature_config = ksp_onchain_transport_lib::SolanaSignatureSubscribeConfig::new(
@@ -156,7 +156,7 @@ Avec `enableReceivedNotification = true`, `ReceivedSignature` peut arriver avant
### Familles unstable : block, slotsUpdates et vote ### Familles unstable : block, slotsUpdates et vote
Depuis `0.2.7-pre.011`, les trois familles unstable standard sont également typées. Leur utilisation déclenche un warning KSP centralisé : Les trois familles unstable standard sont également typées. Leur utilisation déclenche un warning KSP centralisé :
```rust ```rust
let block_config = ksp_onchain_transport_lib::SolanaBlockSubscribeConfig::new( let block_config = ksp_onchain_transport_lib::SolanaBlockSubscribeConfig::new(
@@ -185,7 +185,7 @@ Les trois familles utilisent le même `WsSubscription::unsubscribe().await`; auc
### Reconnect automatique borné ### Reconnect automatique borné
Depuis `0.2.7-pre.007`, les settings de session contrôlent réellement le reconnect physique. Une perte de socket publie `Reconnecting { attempt }`, invalide les remote IDs et incrémente `continuity_gap_count`. Avec la policy par défaut `ActiveSubscriptions`, les handles logiques gardent leur `WsSubscriptionId` et passent temporairement en `Resubscribing`; l'actor recrée leurs subscriptions dans l'ordre local avant de republier `Active`. Les settings de session contrôlent le reconnect physique. Une perte de socket publie `Reconnecting { attempt }`, invalide les remote IDs et incrémente `continuity_gap_count`. Avec la policy par défaut `ActiveSubscriptions`, les handles logiques gardent leur `WsSubscriptionId` et passent temporairement en `Resubscribing`; l'actor recrée leurs subscriptions dans l'ordre local avant de republier `Active`.
`WsResubscribePolicy::Never` reconnecte uniquement la session physique : les subscriptions existantes deviennent terminales et doivent être recréées explicitement par le consumer. Dans les deux modes, les requests applicatives qui étaient en vol lors de la coupure échouent et ne sont pas rejouées implicitement. `WsResubscribePolicy::Never` reconnecte uniquement la session physique : les subscriptions existantes deviennent terminales et doivent être recréées explicitement par le consumer. Dans les deux modes, les requests applicatives qui étaient en vol lors de la coupure échouent et ne sont pas rejouées implicitement.
@@ -193,7 +193,7 @@ Depuis `0.2.7-pre.007`, les settings de session contrôlent réellement le recon
### Backpressure par subscription ### Backpressure par subscription
Depuis `0.2.7-pre.008`, `WsSessionSettings::notification_queue_capacity()` borne réellement la queue de chaque `WsSubscription<T>`. Le consumer doit donc drainer `recv()` selon son débit métier. Une queue pleine ne bloque pas l'actor et n'affecte pas les autres subscriptions : la subscription lente devient terminale avec `state() == Failed` et `terminal_error_code() == Some(ERROR_CODE_WS_BACKPRESSURE_OVERFLOW)`, tandis que `WsSessionSnapshot::overflow_count()` est incrémenté. `WsSessionSettings::notification_queue_capacity()` borne la queue de chaque `WsSubscription<T>`. Le consumer doit donc drainer `recv()` selon son débit métier. Une queue pleine ne bloque pas l'actor et n'affecte pas les autres subscriptions : la subscription lente devient terminale avec `state() == Failed` et `terminal_error_code() == Some(ERROR_CODE_WS_BACKPRESSURE_OVERFLOW)`, tandis que `WsSessionSnapshot::overflow_count()` est incrémenté.
Un échec terminal non lié à l'overflow expose lui aussi un `ErrorCode` KSP sûr via `terminal_error_code()`. Une fermeture normale conserve `None`. Cette projection ne contient ni payload de notification, ni remote subscription ID, ni URL d'endpoint. Un échec terminal non lié à l'overflow expose lui aussi un `ErrorCode` KSP sûr via `terminal_error_code()`. Une fermeture normale conserve `None`. Cette projection ne contient ni payload de notification, ni remote subscription ID, ni URL d'endpoint.
@@ -203,7 +203,7 @@ Le consumer doit traiter `overflow_count` et `continuity_gap_count` comme deux s
### Fermeture explicite ### Fermeture explicite
À partir de `0.2.7-pre.005`, fermer explicitement la session est la voie normale de shutdown : Fermer explicitement la session est la voie normale de shutdown :
```rust ```rust
let session = ksp_onchain_transport_lib::WsSession::connect(endpoint).await?; let session = ksp_onchain_transport_lib::WsSession::connect(endpoint).await?;
@@ -238,7 +238,7 @@ let balance = pool
.await; .await;
``` ```
Les quatre canaris `0.2.1` restent disponibles. `0.2.2` ajoute les wrappers typés Accounts, Tokens et Cluster. Exemples représentatifs : Les wrappers foundation, Accounts, Tokens et Cluster sont disponibles directement sur le pool. Exemples représentatifs :
```rust ```rust
let account = pool let account = pool
@@ -248,7 +248,7 @@ let epoch = pool.get_epoch_info(&role, None).await;
let vote_accounts = pool.get_vote_accounts(&role, None).await; let vote_accounts = pool.get_vote_accounts(&role, None).await;
``` ```
La release stable `0.2.4` contient les **52 wrappers typés courants** : 4 foundation + 22 Accounts/Tokens/Cluster + 11 Transactions + 10 Blocks + 5 Economics. Les DTOs Transport conservent les `null`, options, overloads et formes wire sans décodage Program/SPL métier. La surface HTTP contient **52 wrappers typés courants** : 4 foundation + 22 Accounts/Tokens/Cluster + 11 Transactions + 10 Blocks + 5 Economics. Les DTOs Transport conservent les `null`, options, overloads et formes wire sans décodage Program/SPL métier.
Exemples Transaction représentatifs : Exemples Transaction représentatifs :
@@ -334,7 +334,7 @@ La configuration standard route les événements `info` de Transport vers un fic
## 10. Smokes Devnet opt-in ## 10. Smokes Devnet opt-in
Le smoke **Transport HTTP pur** construit ses settings programmatiquement et exerce un sous-ensemble représentatif d'Accounts/Tokens/Cluster, trois reads Transactions, puis des reads Blocks/Economics de la release stable `0.2.4` : Le smoke **Transport HTTP pur** construit ses settings programmatiquement et exerce un sous-ensemble représentatif d'Accounts/Tokens/Cluster, trois reads Transactions, puis des reads Blocks/Economics :
```bash ```bash
cargo test -p ksp-onchain-transport-lib --test transport_devnet_smoke -- --ignored --nocapture cargo test -p ksp-onchain-transport-lib --test transport_devnet_smoke -- --ignored --nocapture
@@ -350,7 +350,7 @@ cargo test -p ksp-onchain-transport-lib --test websocket_devnet_smoke -- --ignor
Il n'utilise ni `blockSubscribe`, ni `slotsUpdatesSubscribe`, ni `voteSubscribe` : ces familles restent unstable et leur disponibilité dépend des capabilities du validator. Le smoke live n'est donc pas un gate de disponibilité de ces extensions. Il n'utilise ni `blockSubscribe`, ni `slotsUpdatesSubscribe`, ni `voteSubscribe` : ces familles restent unstable et leur disponibilité dépend des capabilities du validator. Le smoke live n'est donc pas un gate de disponibilité de ces extensions.
Le smoke historique de **composition Config -> Transport** reste également disponible : Le smoke de **composition Config -> Transport** reste également disponible :
```bash ```bash
cargo test -p ksp-config-lib --test transport_devnet_smoke -- --ignored --nocapture cargo test -p ksp-config-lib --test transport_devnet_smoke -- --ignored --nocapture
@@ -360,7 +360,7 @@ Il valide le profil committé `devnet_public` et les quatre canaris foundation.
Les endpoints publics Solana sont rate-limités et non destinés à la production. Un échec réseau externe n'est pas assimilé automatiquement à une régression locale ; les fixtures HTTP et WebSocket locales restent les gates reproductibles. Les endpoints publics Solana sont rate-limités et non destinés à la production. Un échec réseau externe n'est pas assimilé automatiquement à une régression locale ; les fixtures HTTP et WebSocket locales restent les gates reproductibles.
Pour l'audit final de dépendances de `0.2.7`, inspecter également le graphe effectif après résolution Cargo : Pour auditer les dépendances, inspecter également le graphe effectif après résolution Cargo :
```bash ```bash
cargo tree -p ksp-onchain-transport-lib cargo tree -p ksp-onchain-transport-lib

View File

@@ -1,11 +1,11 @@
<!-- file: crates/ksp-wallet-lib/README.md --> <!-- file: crates/ksp-wallet-lib/README.md -->
<!-- version: 5 --> <!-- version: 6 -->
# `ksp-wallet-lib` # `ksp-wallet-lib`
Statut : **stable depuis KSP `0.2.5` ; surface V2/multi-version stable depuis `0.2.6`**. Statut : **stable ; surface V1/V2 et façade multi-version validées**.
`ksp-wallet-lib` est la bibliothèque KSP propriétaire du Wallet Solana natif. Elle possède le format autonome `.kspwallet` V1 et le format binaire V2 canonique, les capacités indépendantes VIEW/OWNER, la protection du secret Solana, la signature, l'administration des metadata, les rotations de credentials, la persistence native et les adapters d'import/export explicitement supportés. Depuis KSP `0.2.6`, les APIs non versionnées créent/importent en V2 par default explicite et lisent V1/V2 par détection bornée. La migration V1 -> V2 est explicite et OWNER-authentifiée, sans migration à l'ouverture. `ksp-wallet-lib` est la bibliothèque KSP propriétaire du Wallet Solana natif. Elle possède le format autonome `.kspwallet` V1 et le format binaire V2 canonique, les capacités indépendantes VIEW/OWNER, la protection du secret Solana, la signature, l'administration des metadata, les rotations de credentials, la persistence native et les adapters d'import/export explicitement supportés. Les APIs non versionnées créent/importent en V2 par default explicite et lisent V1/V2 par détection bornée. La migration V1 -> V2 est explicite et OWNER-authentifiée, sans migration à l'ouverture.
La crate est volontairement indépendante de Config, du réseau et de Tauri. Un consumer fournit les chemins, passwords et metadata ; Wallet ouvre, protège, signe et persiste sans décider d'une policy de dépense ni contacter un RPC. La crate est volontairement indépendante de Config, du réseau et de Tauri. Un consumer fournit les chemins, passwords et metadata ; Wallet ouvre, protège, signe et persiste sans décider d'une policy de dépense ni contacter un RPC.
@@ -191,13 +191,13 @@ Elles couvrent le wire, Argon2id/XChaCha20-Poly1305, l'ouverture VIEW/OWNER, la
- [`USAGE.md`](USAGE.md) — exemples des principales surfaces publiques ; - [`USAGE.md`](USAGE.md) — exemples des principales surfaces publiques ;
- [`../../docs/formats/KSPWALLET_V1.md`](../../docs/formats/KSPWALLET_V1.md) — spécification normative indépendante de Rust ; - [`../../docs/formats/KSPWALLET_V1.md`](../../docs/formats/KSPWALLET_V1.md) — spécification normative indépendante de Rust ;
- [`../../docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](../../docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md) — plan historique et threat model de `0.2.5` ; - [`../../docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](../../docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md) — plan historique et threat model de la fondation Wallet ;
- [`../../docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](../../docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) — matrice de sécurité/interoperabilité/compliance ; - [`../../docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](../../docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) — matrice de sécurité/interoperabilité/compliance ;
- [`../../prompts/011-V0_2_6_START_PROMPT.md`](../../prompts/011-V0_2_6_START_PROMPT.md) — reprise vers Wallet Desk après publication stable de `0.2.5`. - [`../../prompts/011-V0_2_6_START_PROMPT.md`](../../prompts/011-V0_2_6_START_PROMPT.md) — prompt historique de reprise vers Wallet Desk.
## V2 stable depuis `0.2.6` ## Wire/runtime V2 et façade multi-version
`pre.015` a figé le wire structurel V2, son codec et ses transcripts/AAD. `pre.016` matérialise le runtime V2 complet et la façade multi-version : Le wire structurel V2, son codec et ses transcripts/AAD sont figés ; le runtime V2 complet et la façade multi-version exposent :
```text ```text
DEFAULT_WALLET_FORMAT = V2 DEFAULT_WALLET_FORMAT = V2
@@ -211,7 +211,7 @@ open/inspect génériques -> détection V1/V2
open/inspect _v1/_v2 -> format forcé strict open/inspect _v1/_v2 -> format forcé strict
``` ```
`WalletOwner` et `WalletView` conservent le format natif qu'ils ont ouvert : metadata, rotations OWNER/VIEW, disable/recreate VIEW, self-rotation VIEW, signature et export ne transcodent jamais implicitement le fichier. Le default est une décision explicite et ne suit pas automatiquement une future V3. `pre.017` matérialise la migration authentifiée V1 -> V2 comme opération séparée ; aucune lecture ou mutation ordinaire ne migre implicitement. `WalletOwner` et `WalletView` conservent le format natif qu'ils ont ouvert : metadata, rotations OWNER/VIEW, disable/recreate VIEW, self-rotation VIEW, signature et export ne transcodent jamais implicitement le fichier. Le default est une décision explicite et ne suit pas automatiquement une future V3. La migration authentifiée V1 -> V2 est une opération séparée ; aucune lecture ou mutation ordinaire ne migre implicitement.
### Migration explicite V1 -> V2 ### Migration explicite V1 -> V2
```text ```text

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-wallet-lib/USAGE.md --> <!-- file: crates/ksp-wallet-lib/USAGE.md -->
<!-- version: 5 --> <!-- version: 6 -->
# Utilisation de `ksp-wallet-lib` # Utilisation de `ksp-wallet-lib`
@@ -278,9 +278,9 @@ ksp-onchain-transport-lib
-> utilise cette Pubkey pour getBalance et autres lectures réseau -> utilise cette Pubkey pour getBalance et autres lectures réseau
``` ```
Cette composition est le rôle de `0.2.6 — ksp-app-wallet-desk`, pas de `ksp-wallet-lib`. Cette composition appartient à `ksp-app-wallet-desk`, pas à `ksp-wallet-lib`.
## Wire/runtime V2 stable (`0.2.6`) ## Wire/runtime V2
Le codec structurel V2 reste disponible directement pour les outils qui travaillent explicitement au niveau wire : Le codec structurel V2 reste disponible directement pour les outils qui travaillent explicitement au niveau wire :

131
deltas/0.2.7/pre.014.md Normal file
View File

@@ -0,0 +1,131 @@
<!-- file: deltas/0.2.7/pre.014.md -->
<!-- version: 1 -->
# Delta `0.2.7-pre.014` — clôture candidate, audit documentaire et prompt `0.2.8`
## Base
Base autoritaire fournie par lopérateur : copie complète `0.2.7-pre.013`, déjà validée par `fmt`, audit structurel KSP, `check`, `clippy`, tests Transport/workspace, audit `cargo tree` et smoke WebSocket Devnet opt-in.
La livraison non-fix synchronise `workspace.package.version` vers `0.2.7-pre.14` conformément à `VER-ID-009`.
## Preuve opérateur héritée de `pre.013`
```text
cargo fmt --all OK
python3 scripts/audit_rust_workspace_rules.py OK
cargo check --workspace OK
cargo clippy --workspace --all-targets OK
cargo test -p ksp-onchain-transport-lib OK — 309 unit / 36 public API / 24 release completeness
cargo test --workspace OK
Config unit tests OK — 109
Core workspace dependency tests OK — 3
WebSocket Devnet smoke opt-in OK
```
Le smoke live valide `slotSubscribe -> slotNotification -> unsubscribe -> close` contre `wss://api.devnet.solana.com`.
Le graphe Transport résout notamment `reqwest 0.13.4`, `tokio 1.53.1`, `tokio-tungstenite 0.30.0` et `futures-util 0.3.34`. Les doublons locaux `syn` 2/3 et `webpki-roots` 0.26/1.0 sont transitifs/upstream et sont conservés ; aucune unification artificielle nest introduite.
## Audit documentaire
Audit effectué sur la copie complète du workspace, pas sur un overlay partiel.
Constats structurels :
- 83 documents Markdown durables contrôlés après correction ;
- aucun lien relatif Markdown réellement cassé dans la documentation durable auditée ;
- headers `file`/`version` cohérents sur les documents durables contrôlés ;
- séquence `0.2.7 -> 0.2.8 -> 0.2.9` cohérente entre ROADMAP, plan fonctionnel et architecture ;
- `CHANGELOG.md` reste réservé à la publication stable et nest pas modifié ici ;
- le statut stable de `0.2.7` reste réservé à `rel.001`.
Corrections/synchronisations :
- `ROADMAP.md` passe `0.2.7` en candidate/en cours `[/]`, sans le déclarer stable ;
- plan et matrice `0.2.7` enregistrent les preuves opérateur `pre.013`, le smoke live et lanalyse des doublons Cargo ;
- les index `docs/`, `plans/`, `validation/` et `prompts/` sont synchronisés ;
- la séquence fonctionnelle `0.2.7 -> 0.2.8 -> 0.2.9` est réalignée sur le statut candidate et la preuve de clôture ;
- `ksp-core-lib`, bibliothèque déjà complétée mais dépourvue de documentation locale, reçoit les `README.md` et `USAGE.md` durables exigés par `FILE_CONTRACTS.md`, fondés sur son API publique réelle ;
- `ksp-onchain-transport-lib/README.md` décrit la surface HTTP + WebSocket réellement acquise sans organiser le contrat WebSocket par numéros de prerelease ;
- `ksp-onchain-transport-lib/USAGE.md` devient un guide durable sans notes de version, conformément à `FILE_CONTRACTS.md` ;
- les narrations de prerelease/version présentes dans les README/USAGE historiques de Config Desk, Wallet Desk, Config, Logging et Wallet sont réécrites en contrats présents sans déplacer lhistorique hors des plans/deltas ;
- le scan final des `crates/*/README.md` et `crates/*/USAGE.md` ne contient plus de `pre.NNN`, `rel.NNN` ni de version KSP littérale utilisée comme note de release ;
- aucun refactoring documentaire historique non nécessaire nest entrepris hors de ces écarts.
## Prompt `0.2.8`
Ajout de `prompts/013-V0_2_8_START_PROMPT.md`, rédigé selon `docs/rules/PROMPT_STRUCTURE.md`.
Le prompt :
- exige la base stable exacte `v0.2.7` ;
- impose lordre de lecture des sources internes ;
- impose un réaudit Helius officiel actuel avant implémentation et référence les points dentrée documentaires actuels `/docs/rpc/websocket`, `/docs/api-reference/rpc/websocket*`, `/docs/faqs/websockets` et `docs/llms.txt` ;
- conserve les frontières HTTP/WebSocket/session/reconnect/backpressure/secrets acquises ;
- interdit de dupliquer le client WebSocket standard ;
- distingue LaserStream WebSocket de LaserStream gRPC et Yellowstone gRPC ;
- laisse ouvertes les décisions `transactionSubscribe/unsubscribe`, `notifyOn`, `tokenAccounts`, capability mapping, heartbeat/idle et shape Config jusquau gate ;
- rend `0.2.8-pre.001` strictement audit/brainstorming/sizing ;
- fournit une prévision souple visible et des critères de clôture ;
- prépare `0.2.9 — Yellowstone gRPC standard/provider-neutral` sans lanticiper.
## Runtime / API
Aucun fichier `src/` nest modifié. Aucun contrat HTTP/WebSocket, DTO, lifecycle, reconnect, backpressure, Config runtime ou dépendance directe Transport nest changé.
## Fichiers
```text
Cargo.toml
ROADMAP.md
docs/000-README.md
docs/plans/000-README.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md
docs/validation/000-README.md
docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
prompts/000-README.md
prompts/013-V0_2_8_START_PROMPT.md
crates/ksp-app-config-desk/README.md
crates/ksp-app-config-desk/USAGE.md
crates/ksp-app-wallet-desk/README.md
crates/ksp-config-lib/README.md
crates/ksp-config-lib/USAGE.md
crates/ksp-core-lib/README.md
crates/ksp-core-lib/USAGE.md
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
crates/ksp-logging-lib/USAGE.md
crates/ksp-wallet-lib/README.md
crates/ksp-wallet-lib/USAGE.md
deltas/0.2.7/pre.014.md
```
## Validation opérateur requise
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
cargo test --workspace
```
Les graphes Cargo et le smoke live nont pas besoin dêtre rejoués sur cette tranche documentaire si la base appliquée est exactement `pre.013`; ils redeviennent obligatoires si le graphe ou le chemin WebSocket est modifié.
Comptages attendus inchangés :
```text
Transport unit tests = 309
Transport public API tests = 36
Transport release completeness = 24
Transport WebSocket live smoke = 1 ignored par défaut
Config unit tests = 109
Core workspace dependency tests = 3
```
## Suite
Si `pre.014` est vert, la suite est `0.2.7-rel.001` : publication stable, Cargo `0.2.7`, `ROADMAP.md` `[X]`, synthèse `CHANGELOG.md`, statut final plan/matrice, delta `rel.001`, commit `v0.2.7-rel.001` et tag stable `v0.2.7`.

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/000-README.md --> <!-- file: docs/plans/000-README.md -->
<!-- version: 54 --> <!-- version: 55 -->
# Plans KSP # Plans KSP
@@ -22,7 +22,7 @@ Un plan décrit le périmètre, les décisions déjà acquises, les questions ou
- [`011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan historique clôturé de la release stable `0.2.4`, ouvert par `pre.001`, exécuté jusquà `pre.009`, complété par le fix documentaire Wallet `pre.009-fix.001` puis publié par `rel.001`; il couvre les 10 Blocks + 5 Economics et la compliance finale `52/52 + 14/14` sous `KSP-TRANSPORT-007`. - [`011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan historique clôturé de la release stable `0.2.4`, ouvert par `pre.001`, exécuté jusquà `pre.009`, complété par le fix documentaire Wallet `pre.009-fix.001` puis publié par `rel.001`; il couvre les 10 Blocks + 5 Economics et la compliance finale `52/52 + 14/14` sous `KSP-TRANSPORT-007`.
- [`012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](012-V0_2_5_WALLET_FOUNDATION_PLAN.md) — plan historique clôturé de la release stable `0.2.5 — Wallet foundation`, ouvert par `pre.001`, livré jusquà `pre.010`, renforcé par `pre.010-fix.001``fix.003` pour Dalek 3 et la normalisation Rust/audit structurel, puis publié par `rel.001`; il couvre `.kspwallet` V1, VIEW/OWNER, crypto, persistence, administration, transfer et compliance. - [`012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](012-V0_2_5_WALLET_FOUNDATION_PLAN.md) — plan historique clôturé de la release stable `0.2.5 — Wallet foundation`, ouvert par `pre.001`, livré jusquà `pre.010`, renforcé par `pre.010-fix.001``fix.003` pour Dalek 3 et la normalisation Rust/audit structurel, puis publié par `rel.001`; il couvre `.kspwallet` V1, VIEW/OWNER, crypto, persistence, administration, transfer et compliance.
- [`013-V0_2_6_WALLET_DESK_PLAN.md`](013-V0_2_6_WALLET_DESK_PLAN.md) — plan historique clôturé de la release stable `0.2.6 — Wallet Desk`, ouvert par `pre.001`, étendu en `pre.015``pre.017` au wire binaire `.kspwallet` V2, aux APIs multi-version et à la migration V1 -> V2, puis fermé par `pre.018`/`fix.001` avec le runtime Tauri packagé et le build final vert avant publication `rel.001`. - [`013-V0_2_6_WALLET_DESK_PLAN.md`](013-V0_2_6_WALLET_DESK_PLAN.md) — plan historique clôturé de la release stable `0.2.6 — Wallet Desk`, ouvert par `pre.001`, étendu en `pre.015``pre.017` au wire binaire `.kspwallet` V2, aux APIs multi-version et à la migration V1 -> V2, puis fermé par `pre.018`/`fix.001` avec le runtime Tauri packagé et le build final vert avant publication `rel.001`.
- [`014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md`](014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md) — plan actif de `0.2.7 — WebSocket Solana standard`, ouvert par `pre.001`; il conserve l'inventaire officiel 18 méthodes, le modèle session/subscription, le threat model, le choix de dependencies et le forecast recalibré. - [`014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md`](014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md) — plan candidate de `0.2.7 — WebSocket Solana standard`, ouvert par `pre.001` et exécuté jusquà `pre.014`; il conserve linventaire officiel 18 méthodes, le modèle session/subscription, le threat model, les preuves de compliance/smoke/dépendances et la préparation de `0.2.8`, avant publication stable `rel.001`.
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.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md --> <!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 80 --> <!-- version: 81 -->
# Séquence des releases fonctionnelles KSP # Séquence des releases fonctionnelles KSP
@@ -455,13 +455,13 @@ La tranche historique `pre.014` a traité les défauts visuels/templating observ
### `0.2.7` — WebSocket Solana standard ### `0.2.7` — WebSocket Solana standard
Mission : couvrir exhaustivement la surface WebSocket Solana standard officielle ciblée, avec sessions physiques explicites, subscriptions typées, lifecycle borné, reconnexion/resubscribe déterministes et observabilité sûre. Le plan actif est [`014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md`](014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md) et la matrice de compliance initiale est [`../validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md`](../validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md). Mission : couvrir exhaustivement la surface WebSocket Solana standard officielle ciblée, avec sessions physiques explicites, subscriptions typées, lifecycle borné, reconnexion/resubscribe déterministes et observabilité sûre. Le plan candidate est [`014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md`](014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md) et la matrice de compliance candidate est [`../validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md`](../validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md).
Le gate `0.2.7-pre.001`, audité le 22 août 2026, inventorie exactement 18 opérations WebSocket documentées : 9 subscribe + 9 unsubscribe. `blockSubscribe`, `slotsUpdatesSubscribe` et `voteSubscribe` sont actuellement marquées unstable ; aucune méthode de l'index officiel courant n'est marquée Deprecated. Le gate `0.2.7-pre.001`, audité le 22 août 2026, inventorie exactement 18 opérations WebSocket documentées : 9 subscribe + 9 unsubscribe. `blockSubscribe`, `slotsUpdatesSubscribe` et `voteSubscribe` sont actuellement marquées unstable ; aucune méthode de l'index officiel courant n'est marquée Deprecated.
Une URL peut avoir plusieurs sessions physiques explicites ; une session peut avoir plusieurs subscriptions. Un pool/scheduler automatique de sessions reste reporté jusqu'à besoin concret. Les IDs de session/subscription KSP sont locaux et stables ; les IDs serveur restent internes et peuvent être remappés après reconnexion. Une URL peut avoir plusieurs sessions physiques explicites ; une session peut avoir plusieurs subscriptions. Un pool/scheduler automatique de sessions reste reporté jusqu'à besoin concret. Les IDs de session/subscription KSP sont locaux et stables ; les IDs serveur restent internes et peuvent être remappés après reconnexion.
Le forecast initial allant jusqu'à `pre.008` est décompressé par `pre.001` jusqu'à environ `pre.014` afin de conserver des tranches intermédiaires nominales de 1520 minutes ; ce numéro reste un forecast et non une contrainte de clôture. La candidate atteint `pre.014` après matérialisation des 9 familles standard, compliance 18/18, composition Config V2, reconnect/resubscribe/backpressure bornés, smoke WebSocket Devnet et audit du graphe Cargo. La publication stable reste réservée à `rel.001`; le prompt `0.2.8` est préparé séparément dans `prompts/013-V0_2_8_START_PROMPT.md`.
### `0.2.8` — Helius LaserStream WebSocket ### `0.2.8` — Helius LaserStream WebSocket

View File

@@ -1,9 +1,9 @@
<!-- file: docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md --> <!-- file: docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md -->
<!-- version: 15 --> <!-- version: 16 -->
# Plan `0.2.7` — WebSocket Solana standard # Plan `0.2.7` — WebSocket Solana standard
> **Statut : actif, `0.2.7-pre.007`.** `pre.006-fix.001` est validé opérateur. `pre.007` active le reconnect borné, le resubscribe déterministe, le compteur de continuity gaps et les races unsubscribe/reconnect. Les wrappers typed publics restent différés. > **Statut : candidate, `0.2.7-pre.014`.** La surface WebSocket standard 18/18, la composition Config V2, les non-régressions HTTP, le lifecycle borné, le smoke WebSocket Devnet et laudit de dépendances sont validés. `pre.014` ferme la documentation/compliance et prépare le prompt `0.2.8`; seul `rel.001` peut publier `v0.2.7` stable.
## 1. Objet et base vérifiée ## 1. Objet et base vérifiée
@@ -975,6 +975,22 @@ Le canari source interdit qu'une dépendance nouvelle se glisse silencieusement
README/USAGE documentent désormais les smokes HTTP/WS séparés, les limites du smoke live et les commandes d'audit du graphe Cargo. README/USAGE documentent désormais les smokes HTTP/WS séparés, les limites du smoke live et les commandes d'audit du graphe Cargo.
Preuve opérateur `pre.013` enregistrée avant `pre.014` :
```text
cargo fmt --all OK
python3 scripts/audit_rust_workspace_rules.py OK
cargo check --workspace OK
cargo clippy --workspace --all-targets OK
cargo test -p ksp-onchain-transport-lib OK — 309 unit / 36 public API / 24 release completeness
cargo test --workspace OK
WebSocket Devnet smoke opt-in OK — slotSubscribe -> notification -> unsubscribe -> close
Core workspace dependency tests OK — 3
Config unit tests OK — 109
```
Le `cargo tree -p ksp-onchain-transport-lib --duplicates` ne montre que deux familles transitives dupliquées pertinentes : `syn` 2/3 et `webpki-roots` 0.26/1.0. Elles proviennent des dépendances upstream et ne justifient ni pin artificiel ni downgrade. Le graphe workspace plus large contient les duplications attendues des branches Tauri/GTK et Wallet/crypto ; aucune nouvelle dépendance directe anormale n'est introduite dans Transport.
## 22. Forecast recalibré ## 22. Forecast recalibré
L'inventaire officiel n'impose que 9 familles de subscriptions, mais le lifecycle concurrent est plus coûteux que le forecast initial. Le gate reste **positif sans split de release**, à condition de granulariser les tranches au lieu de compresser le moteur et les wrappers. L'inventaire officiel n'impose que 9 familles de subscriptions, mais le lifecycle concurrent est plus coûteux que le forecast initial. Le gate reste **positif sans split de release**, à condition de granulariser les tranches au lieu de compresser le moteur et les wrappers.
@@ -993,7 +1009,7 @@ pre.010 DONE — wrappers stable lot B : signature + slot + root, terminaison s
pre.011 DONE — unstable : block + slotsUpdates + vote, warnings + fallbacks wire/KSP-TRANSPORT-007 pre.011 DONE — unstable : block + slotsUpdates + vote, warnings + fallbacks wire/KSP-TRANSPORT-007
pre.012 DONE — compliance 18/18 + canaries public API + composition Config + régressions HTTP pre.012 DONE — compliance 18/18 + canaries public API + composition Config + régressions HTTP
pre.013 DONE — smoke live opt-in + README/USAGE + source dependency canary + cargo tree/duplicates opérateur pre.013 DONE — smoke live opt-in + README/USAGE + source dependency canary + cargo tree/duplicates opérateur
pre.014 validation workspace finale + docs/compliance + prompt 0.2.8 pre.014 DONE — validation finale enregistrée + audit documentaire + docs/compliance + prompt 0.2.8
rel.001 publication stable stricte rel.001 publication stable stricte
``` ```
@@ -1018,9 +1034,9 @@ La release ne peut passer stable que si :
- smoke live retenu reste opt-in ; - smoke live retenu reste opt-in ;
- README/USAGE, matrice finale, graphes Cargo et prompt `0.2.8` sont synchronisés. - README/USAGE, matrice finale, graphes Cargo et prompt `0.2.8` sont synchronisés.
## 24. Validation opérateur requise pour `pre.001` ## 24. Validation opérateur requise pour `pre.014`
Après application de ce gate documentaire/versionné : Après application de cette dernière prerelease documentaire/versionnée :
```bash ```bash
cargo fmt --all cargo fmt --all
@@ -1029,4 +1045,4 @@ cargo check --workspace
cargo clippy --workspace --all-targets cargo clippy --workspace --all-targets
``` ```
`cargo test --workspace` n'est pas imposé par cette tranche documentaire d'ouverture tant qu'aucun Rust runtime n'est ajouté, mais reste autorisé comme checkpoint opérateur. `cargo test -p ksp-onchain-transport-lib` puis `cargo test --workspace` font partie du gate final de `pre.014` même si la tranche ne modifie pas le runtime. Les graphes Cargo et le smoke live nont pas besoin dêtre rejoués si la base appliquée est exactement celle déjà validée en `pre.013`; toute modification ultérieure de dépendances ou du chemin WebSocket les rend de nouveau obligatoires.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/000-README.md --> <!-- file: docs/validation/000-README.md -->
<!-- version: 18 --> <!-- version: 19 -->
# Validations KSP # Validations KSP
@@ -18,4 +18,4 @@ Documents :
- [`007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée de `0.2.4`, inventaire exact 52 current + 14 Deprecated, preuve typed 52/52, audit SIMD final, `KSP-TRANSPORT-007`, workspace complet et deux smokes Devnet passés avant publication stable. - [`007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée de `0.2.4`, inventaire exact 52 current + 14 Deprecated, preuve typed 52/52, audit SIMD final, `KSP-TRANSPORT-007`, workspace complet et deux smokes Devnet passés avant publication stable.
- [`008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) — matrice finale validée de la release stable `0.2.5`, threat model V1, canaris adversariaux, reproduction externe des vecteurs, audit de frontières, normalisation Rust/audit structurel, graphes Cargo et checkpoint final `pre.010-fix.003` vert. - [`008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) — matrice finale validée de la release stable `0.2.5`, threat model V1, canaris adversariaux, reproduction externe des vecteurs, audit de frontières, normalisation Rust/audit structurel, graphes Cargo et checkpoint final `pre.010-fix.003` vert.
- [`009-V0_2_6_WALLET_DESK_COMPLIANCE.md`](009-V0_2_6_WALLET_DESK_COMPLIANCE.md) — matrice finale validée de la release stable `0.2.6`, couvrant Wallet Desk, les wires V1/V2, la migration explicite, le runtime Tauri packagé, les frontières sécurité/ownership et le gate opérateur `pre.018-fix.001` avec build final Linux vert. - [`009-V0_2_6_WALLET_DESK_COMPLIANCE.md`](009-V0_2_6_WALLET_DESK_COMPLIANCE.md) — matrice finale validée de la release stable `0.2.6`, couvrant Wallet Desk, les wires V1/V2, la migration explicite, le runtime Tauri packagé, les frontières sécurité/ownership et le gate opérateur `pre.018-fix.001` avec build final Linux vert.
- [`010-V0_2_7_ONCHAIN_WEBSOCKET.md`](010-V0_2_7_ONCHAIN_WEBSOCKET.md) — matrice active de `0.2.7`, ouverte par `pre.001` avec l'inventaire normatif 9 subscribe + 9 unsubscribe, les statuts unstable, le lifecycle, les risques et les preuves à fermer. - [`010-V0_2_7_ONCHAIN_WEBSOCKET.md`](010-V0_2_7_ONCHAIN_WEBSOCKET.md) — matrice candidate de `0.2.7`, ouverte par `pre.001` puis fermée techniquement par `pre.014` : inventaire 9 subscribe + 9 unsubscribe, lifecycle, statuts unstable, compliance 18/18, non-régression HTTP, composition Config, smoke WebSocket Devnet et audit de dépendances sont enregistrés avant `rel.001`.

View File

@@ -1,9 +1,9 @@
<!-- file: docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md --> <!-- file: docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md -->
<!-- version: 15 --> <!-- version: 16 -->
# Validation `0.2.7` — WebSocket Solana standard # Validation `0.2.7` — WebSocket Solana standard
> **Statut : matrice active, `0.2.7-pre.013`.** La compliance 18/18 est acquise. `pre.013` ajoute le smoke WebSocket Devnet opt-in, synchronise README/USAGE et renforce le gate de dépendances avant la validation workspace finale. > **Statut : matrice candidate, `0.2.7-pre.014`.** La compliance 18/18, le lifecycle borné, la composition Config V2, la non-régression HTTP, le smoke WebSocket Devnet et laudit de dépendances sont validés. `pre.014` enregistre les preuves finales et la documentation ; la publication stable reste `rel.001`.
## 1. Baseline normative ## 1. Baseline normative
@@ -47,7 +47,7 @@ Pour une paire unstable, l'unsubscribe associé est classé `Unstable pair` dans
| 10 | `rootUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | root pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/rootunsubscribe` | Done `pre.010` | | 10 | `rootUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | root pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/rootunsubscribe` | Done `pre.010` |
| 11 | `signatureSubscribe` | subscribe | Stable/documented | first transaction signature ; commitment ; `enableReceivedNotification` | `signatureNotification` early string or terminal error object | early + terminal + auto-close/no-resubscribe | `https://solana.com/docs/rpc/websocket/signaturesubscribe` | Done `pre.010` | | 11 | `signatureSubscribe` | subscribe | Stable/documented | first transaction signature ; commitment ; `enableReceivedNotification` | `signatureNotification` early string or terminal error object | early + terminal + auto-close/no-resubscribe | `https://solana.com/docs/rpc/websocket/signaturesubscribe` | Done `pre.010` |
| 12 | `signatureUnsubscribe` | unsubscribe | Stable/documented | remote id before terminal fire ; boolean/error | signature pair | cancel before terminal + stale after terminal | `https://solana.com/docs/rpc/websocket/signatureunsubscribe` | Done `pre.010` | | 12 | `signatureUnsubscribe` | unsubscribe | Stable/documented | remote id before terminal fire ; boolean/error | signature pair | cancel before terminal + stale after terminal | `https://solana.com/docs/rpc/websocket/signatureunsubscribe` | Done `pre.010` |
| 13 | `slotSubscribe` | subscribe | Stable/documented | no params ; numeric id | `slotNotification` `{slot,parent,root}` | exact fixture + live smoke candidate | `https://solana.com/docs/rpc/websocket/slotsubscribe` | Done `pre.010` | | 13 | `slotSubscribe` | subscribe | Stable/documented | no params ; numeric id | `slotNotification` `{slot,parent,root}` | exact fixture + live smoke Devnet passé | `https://solana.com/docs/rpc/websocket/slotsubscribe` | Done `pre.010` |
| 14 | `slotUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | slot pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/slotunsubscribe` | Done `pre.010` | | 14 | `slotUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | slot pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/slotunsubscribe` | Done `pre.010` |
| 15 | `slotsUpdatesSubscribe` | subscribe | **Unstable** | no params ; numeric id | tagged `slotsUpdatesNotification` | each known variant + unknown fallback | `https://solana.com/docs/rpc/websocket/slotsupdatessubscribe` | Done `pre.011` | | 15 | `slotsUpdatesSubscribe` | subscribe | **Unstable** | no params ; numeric id | tagged `slotsUpdatesNotification` | each known variant + unknown fallback | `https://solana.com/docs/rpc/websocket/slotsupdatessubscribe` | Done `pre.011` |
| 16 | `slotsUpdatesUnsubscribe` | unsubscribe | **Unstable pair** | remote id ; boolean/error | slotsUpdates pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/slotsupdatesunsubscribe` | Done `pre.011` | | 16 | `slotsUpdatesUnsubscribe` | unsubscribe | **Unstable pair** | remote id ; boolean/error | slotsUpdates pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/slotsupdatesunsubscribe` | Done `pre.011` |
@@ -220,7 +220,7 @@ Les votes observés sont gossip/pre-consensus ; aucune garantie d'entrée dans l
| unsubscribe pendant reconnect ne resubscribe pas | race fixture | Done `pre.007` | | unsubscribe pendant reconnect ne resubscribe pas | race fixture | Done `pre.007` |
| signature terminale ne resubscribe pas | terminal fixture | **Done `pre.010`** | | signature terminale ne resubscribe pas | terminal fixture | **Done `pre.010`** |
| shutdown ne bloque pas | peer hostile/no close ack fixture | **Done `pre.005`** | | shutdown ne bloque pas | peer hostile/no close ack fixture | **Done `pre.005`** |
| no Store/Program/Wallet/Config dep dans Transport | cargo tree + source canary | **Source gate `pre.013`, cargo tree opérateur requis** | | no Store/Program/Wallet/Config dep dans Transport | cargo tree + source canary | **Done `pre.013`, source + cargo tree opérateur** |
| no direct `tracing` dans Transport | workspace audit + source audit | **Done `pre.002`** | | no direct `tracing` dans Transport | workspace audit + source audit | **Done `pre.002`** |
## 8. Dependency compliance initiale ## 8. Dependency compliance initiale
@@ -688,6 +688,8 @@ Config unit tests = 109
Core workspace dependency tests = 3 Core workspace dependency tests = 3
``` ```
Preuve opérateur `pre.013` : tous les contrôles déterministes ci-dessus sont verts, `cargo test --workspace` est vert et le smoke WebSocket ignoré a été exécuté explicitement avec succès sur Devnet. L'audit du graphe Transport résout notamment `reqwest 0.13.4`, `tokio 1.53.1`, `tokio-tungstenite 0.30.0` et `futures-util 0.3.34` sur ce checkout sans lockfile versionné. Les doublons `syn` 2/3 et `webpki-roots` 0.26/1.0 sont transitifs/upstream et acceptés ; aucune unification artificielle n'est requise.
## 10. Validation du gate `pre.001` ## 10. Validation du gate `pre.001`
Exécuté dans le sandbox : Exécuté dans le sandbox :
@@ -734,10 +736,10 @@ N subscriptions same session prouvé
reconnect/resubscribe/backpressure/shutdown gates verts reconnect/resubscribe/backpressure/shutdown gates verts
unstable warnings centralisés unstable warnings centralisés
HTTP 52+14 non régressé (**Done `pre.012`**) HTTP 52+14 non régressé (**Done `pre.012`**)
Config V1 backward + V2 WS validés (**Done `pre.003`**, compilation opérateur requise) Config V1 backward + V2 WS validés (**Done `pre.003`, revalidé opérateur `pre.013`**)
smoke live opt-in documenté (**Done `pre.013`**) smoke live opt-in documenté (**Done `pre.013`**)
cargo tree inspecté (**preuve opérateur `pre.013` requise**) cargo tree inspecté (**Done opérateur `pre.013`**)
cargo test --workspace vert cargo test --workspace vert (**Done opérateur `pre.013`**)
README/USAGE synchronisés (**Done `pre.013`**) README/USAGE synchronisés et réaudités durables (**Done `pre.014`**)
prompt 0.2.8 préparé prompt 0.2.8 préparé (**Done `pre.014`**)
``` ```

View File

@@ -1,5 +1,5 @@
<!-- file: prompts/000-README.md --> <!-- file: prompts/000-README.md -->
<!-- version: 21 --> <!-- version: 22 -->
# Prompts KSP # Prompts KSP
@@ -32,4 +32,5 @@ Le prompt générique `0.1.x` a été affiné pendant `0.0.3` puis remplacé par
- [`009-V0_2_4_START_PROMPT.md`](009-V0_2_4_START_PROMPT.md) — prompt préparé par `0.2.3-pre.009`, destiné à ouvrir `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale` après publication stable de `0.2.3`; il cible les 15 wrappers restants et impose `KSP-TRANSPORT-007` ainsi qu'un nouvel audit/sizing à `pre.001`. - [`009-V0_2_4_START_PROMPT.md`](009-V0_2_4_START_PROMPT.md) — prompt préparé par `0.2.3-pre.009`, destiné à ouvrir `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale` après publication stable de `0.2.3`; il cible les 15 wrappers restants et impose `KSP-TRANSPORT-007` ainsi qu'un nouvel audit/sizing à `pre.001`.
- [`010-V0_2_5_START_PROMPT.md`](010-V0_2_5_START_PROMPT.md) — prompt préparé par `0.2.4-pre.009` puis finalisé en version 2 par `pre.009-fix.001`, destiné à ouvrir `0.2.5 — Wallet foundation` sur la base stable `v0.2.4`; il impose audit/threat-model/sizing avant choix cryptographiques et cadre `.kspwallet` interopérable, capacités indépendantes VIEW/OWNER, metadata protégées, key slots/rotations, signature, persistence atomique et import/export extensible sans `WalletPolicy`. - [`010-V0_2_5_START_PROMPT.md`](010-V0_2_5_START_PROMPT.md) — prompt préparé par `0.2.4-pre.009` puis finalisé en version 2 par `pre.009-fix.001`, destiné à ouvrir `0.2.5 — Wallet foundation` sur la base stable `v0.2.4`; il impose audit/threat-model/sizing avant choix cryptographiques et cadre `.kspwallet` interopérable, capacités indépendantes VIEW/OWNER, metadata protégées, key slots/rotations, signature, persistence atomique et import/export extensible sans `WalletPolicy`.
- [`011-V0_2_6_START_PROMPT.md`](011-V0_2_6_START_PROMPT.md) — prompt préparé par `0.2.5-pre.010` puis renforcé pendant `pre.010-fix.001``fix.003`, prompt historique consommé pour ouvrir `0.2.6 — Wallet Desk` après le tag stable `v0.2.5`; il impose une première tranche audit/sizing, rappelle les règles Rust/audit structurel, cadre Config composite + Wallet + HTTP `getBalance`, lifecycle VIEW/OWNER, sécurité password/export, validation frontend/Tauri et conserve le TODO `0.2.11` dintégration des prix offchain dans Wallet Desk après validation de la Price Desk spécialisée. - [`011-V0_2_6_START_PROMPT.md`](011-V0_2_6_START_PROMPT.md) — prompt préparé par `0.2.5-pre.010` puis renforcé pendant `pre.010-fix.001``fix.003`, prompt historique consommé pour ouvrir `0.2.6 — Wallet Desk` après le tag stable `v0.2.5`; il impose une première tranche audit/sizing, rappelle les règles Rust/audit structurel, cadre Config composite + Wallet + HTTP `getBalance`, lifecycle VIEW/OWNER, sécurité password/export, validation frontend/Tauri et conserve le TODO `0.2.11` dintégration des prix offchain dans Wallet Desk après validation de la Price Desk spécialisée.
- [`012-V0_2_7_START_PROMPT.md`](012-V0_2_7_START_PROMPT.md) — prompt réaligné par `0.2.6-pre.015` puis renforcé en contrat de reprise autonome par `0.2.6-pre.018-fix.002`; il est le prochain prompt actif et ouvre `0.2.7 — WebSocket Solana standard` depuis `v0.2.6`, impose les lectures/règles ordonnées, laudit officiel et historique, le threat-model session/subscription/reconnect/backpressure, la matrice de compliance, un gate `pre.001` strict et une prévision souple de prereleases avant toute implémentation lourde. - [`012-V0_2_7_START_PROMPT.md`](012-V0_2_7_START_PROMPT.md) — prompt réaligné par `0.2.6-pre.015` puis renforcé en contrat de reprise autonome par `0.2.6-pre.018-fix.002`; prompt historique consommé pour ouvrir `0.2.7 — WebSocket Solana standard` depuis `v0.2.6`, avec lectures/règles ordonnées, audit officiel et historique, threat-model session/subscription/reconnect/backpressure, matrice de compliance, gate `pre.001` strict et prévision souple de prereleases avant toute implémentation lourde.
- [`013-V0_2_8_START_PROMPT.md`](013-V0_2_8_START_PROMPT.md) — prochain prompt actif, préparé par `0.2.7-pre.014` et utilisable uniquement après publication stable de `v0.2.7` pour ouvrir `0.2.8 — Helius LaserStream WebSocket`; il impose la relecture des règles et de la surface WebSocket finale, un réaudit Helius actuel, un gate `pre.001` strict audit/brainstorming/sizing, la réutilisation du moteur actor standard sans second client, des frontières provider/Config/secrets explicites et une prévision souple avant toute implémentation lourde.

View File

@@ -0,0 +1,951 @@
<!-- file: prompts/013-V0_2_8_START_PROMPT.md -->
<!-- version: 1 -->
# Prompt de démarrage `0.2.8` — Helius LaserStream WebSocket
## 1. Identité de la release et base exacte requise
La release à ouvrir est :
```text
0.2.8 — Helius LaserStream WebSocket
```
Elle doit démarrer **uniquement après publication stable de `0.2.7`**.
Base Git attendue :
```text
v0.2.7
```
La base stable doit contenir au minimum :
```text
deltas/0.2.7/rel.001.md
prompts/013-V0_2_8_START_PROMPT.md
```
Si une archive complète du workspace `v0.2.7` est fournie au démarrage de session, **cette archive est autoritaire** par rapport aux souvenirs, snippets, copies de prereleases ou artefacts antérieurs. Vérifier l'état réel avant toute modification.
Signal Cargo initial attendu :
```text
workspace.package.version = "0.2.7"
```
La première livraison de la release sera :
```text
0.2.8-pre.001
Cargo = 0.2.8-pre.1
```
Aucun code fonctionnel lourd ne doit être commencé avant la sortie positive du gate `pre.001` décrit plus bas.
---
## 2. Mission et résultat attendu
`0.2.8` doit étendre le moteur WebSocket déjà stabilisé dans `ksp-onchain-transport-lib` avec la **surface Helius LaserStream WebSocket réellement documentée et supportée au moment de l'audit**, sans dupliquer le client/session actor standard et sans transformer Transport en SDK Helius généraliste.
Le résultat attendu est une extension provider-specific qui :
```text
réutilise le moteur physique WsSession acquis en 0.2.7
préserve les wrappers Solana standard existants
ajoute uniquement les capacités Helius WebSocket réellement auditées
conserve les paramètres/filtres/options Helius utiles sans perte
modélise explicitement les méthodes standard non supportées par Helius
respecte les limites/reconnect/backpressure/shutdown KSP existants
ne fuite jamais api-key, URL complète, query credentials ou payload massif
reste compatible avec Config -> Transport sans dépendance inverse
ne crée aucune dépendance Store/Program/Wallet dans Transport
ne confond jamais LaserStream WebSocket et LaserStream gRPC
```
Le nom produit Helius a évolué : les anciennes « Enhanced WebSockets » sont désormais présentées dans la documentation Helius comme faisant partie de **LaserStream WebSocket**. La session doit donc réauditer la terminologie actuelle au lieu de reprendre mécaniquement les anciens noms.
---
## 3. Sources de vérité internes obligatoires — ordre de lecture
### 3.1 Entrées et règles globales
Lire d'abord, dans cet ordre :
```text
RULES.md
docs/000-README.md
docs/rules/RULES_GENERAL.md
docs/rules/RULES_KSP.md
docs/rules/RULES_RUST.md
docs/rules/RULES_DEPENDENCIES.md
docs/rules/RULES_DOCUMENTATION.md
docs/rules/FILE_CONTRACTS.md
docs/rules/VERSION_WORKFLOW.md
docs/rules/PROMPT_STRUCTURE.md
```
Ne pas reconstituer ces règles depuis la mémoire de conversation. Le contenu présent dans la base stable est normatif.
### 3.2 Architecture à préserver
Lire ensuite :
```text
docs/architecture/000-README.md
docs/architecture/002-LAYERS_AND_DEPENDENCIES.md
docs/architecture/003-COMPONENT_CONTRACTS.md
docs/architecture/004-COMPONENT_INVENTORY.md
docs/architecture/005-DEPENDENCY_GRAPH.md
docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md
```
Points d'attention :
```text
Transport possède le réseau et ses settings runtime
Config adapte vers Transport, jamais l'inverse
Store/RAW persistence n'appartient pas à Transport
Program decode/materialization n'appartient pas à Transport
un provider WebSocket ne doit pas créer un second moteur session/subscription
```
### 3.3 Séquence fonctionnelle et héritage Transport
Lire :
```text
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md
docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md
docs/validation/003-V0_2_1_ONCHAIN_HTTP.md
docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
```
`docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md` porte la numérotation courante. Les anciens plans restent historiques et ne doivent pas réintroduire une numérotation dépassée.
### 3.4 Contrats publics réels à réauditer
Inspecter directement :
```text
crates/ksp-onchain-transport-lib/Cargo.toml
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
crates/ksp-onchain-transport-lib/src/
crates/ksp-onchain-transport-lib/tests/
crates/ksp-config-lib/Cargo.toml
crates/ksp-config-lib/src/transport.rs
crates/ksp-config-lib/unit_tests/transport.rs
config/std.transport.json
config/schemas/std.transport.schema.json
```
En particulier, vérifier les contrats réels de :
```text
WsProtocolKind
WsEndpointSettings
WsTransportSettings
WsSessionSettings
WsSession
WsSubscription<T>
WsSubscriptionKind
WsSessionSnapshot / WsSubscriptionSnapshot
```
Ne jamais supposer qu'une API imaginée pendant `0.2.7-pre.001` est celle finalement publiée : **le code stable `v0.2.7` prime**.
### 3.5 Clôture `0.2.7`
Lire obligatoirement :
```text
deltas/0.2.7/rel.001.md
docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md
docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
```
Le but est de reprendre exactement le moteur final, les limitations documentées et les preuves de clôture, pas de rouvrir les décisions standard déjà validées.
---
## 4. Sources externes normatives à réauditer en `pre.001`
La documentation Helius est une surface vivante. **Toutes les informations de cette section sont des pointeurs d'audit, pas des versions figées.** Les pages officielles courantes doivent être relues au début de `pre.001`.
Auditer au minimum les sources Helius officielles suivantes ou leurs remplaçantes actuelles :
```text
https://www.helius.dev/docs/rpc/websocket
https://www.helius.dev/docs/api-reference/rpc/websocket-methods
https://www.helius.dev/docs/api-reference/rpc/websocket/transactionsubscribe
https://www.helius.dev/docs/rpc/websocket/transaction-subscribe
https://www.helius.dev/docs/api-reference/rpc/websocket/accountsubscribe
https://www.helius.dev/docs/rpc/websocket/account-subscribe
https://www.helius.dev/docs/api-reference/rpc/websocket/programsubscribe
https://www.helius.dev/docs/faqs/websockets
https://www.helius.dev/docs/llms.txt
```
Utiliser l'index `llms.txt` et la navigation officielle pour retrouver les pages unsubscribe et toute extension/filter provider-specific encore documenté (`notifyOn`, `tokenAccounts` ou remplaçant actuel). Une URL déplacée n'annule pas le gate : retrouver la page officielle remplaçante et enregistrer la source effective dans le plan/matrice `0.2.8`.
Snapshot documentaire connu lors de la préparation de ce prompt, **à réauditer** :
```text
les endpoints WebSocket standard et Helius extensions sont unifiés par réseau
le produit anciennement appelé Enhanced WebSockets est désormais présenté dans la famille LaserStream WebSocket
transactionSubscribe est une extension Helius avec filtres riches
la référence transactionSubscribe documente transactionUnsubscribe, tandis que l'index méthodes ne l'énumère pas séparément
les méthodes standard block/slotsUpdates/vote sont actuellement annoncées non supportées par Helius
la FAQ annonce un idle timeout de 10 minutes et recommande des pings périodiques
les documents d'indexing distinguent WebSocket sans garantie de replay historique du produit LaserStream gRPC
notifyOn et tokenAccounts ont été observés dans des références Helius pendant la préparation ; leur présence, leur portée et leur forme exactes doivent être reconfirmées au gate
```
Le gate doit relever la **surface exacte du jour** : méthodes, unsubscribe associés, paramètres, limites, notifications, statuts et divergences entre index, guides et références.
Si deux pages Helius se contredisent, ne pas choisir arbitrairement : documenter la divergence, rechercher une source Helius plus primaire/récente, puis tester localement ou contre Helius uniquement si cela peut être fait sans violer les règles de secrets/configuration.
Réauditer aussi les versions courantes des dépendances externes concernées. La résolution observée à la fin de `0.2.7-pre.013` était notamment :
```text
futures-util 0.3.34
tokio 1.53.1
tokio-tungstenite 0.30.0
reqwest 0.13.4
```
Ces versions sont un **snapshot sans lockfile versionné**, pas une contrainte à recopier si Cargo résout plus récent au démarrage de `0.2.8`.
---
## 5. État validé à préserver depuis `v0.2.7`
### 5.1 HTTP
La surface HTTP reste un contrat stable :
```text
52/52 méthodes HTTP courantes typées
14/14 méthodes historiques Deprecated/Removed conservées
KSP-TRANSPORT-007 appliqué à toute la surface typed
retry/no-resend write submissions déjà centralisé
```
`0.2.8` ne doit pas régresser cette surface.
### 5.2 WebSocket Solana standard
La release `0.2.7` publie exactement neuf familles standard :
```text
account
block
logs
program
root
signature
slot
slotsUpdates
vote
```
soit :
```text
9 subscribe + 9 unsubscribe = 18 opérations standard
```
Partition stable/unstable héritée :
```text
stable : account, logs, program, root, signature, slot
unstable : block, slotsUpdates, vote
```
Les trois familles unstable ont un warning KSP centralisé dans le moteur standard.
### 5.3 Session, subscriptions et cardinalité
Contrat acquis :
```text
1 WsEndpointSettings
-> 0..N sessions physiques explicitement créées
-> 0..N logical subscriptions
```
Identités :
```text
WsSessionId = local et stable
WsSubscriptionId = local et stable pendant reconnect/resubscribe
remote subscription id = interne, transitoire, remappable
```
Aucun pool/scheduler automatique de sessions n'est imposé.
### 5.4 Lifecycle/reconnect/backpressure
Préserver les invariants suivants :
```text
actor unique propriétaire du socket
command queue bornée
pending JSON-RPC borné + timeout
notification queue bornée par subscription
max active subscriptions borné
reconnect fini + backoff exponentiel borné
budget reconnect reset après retour complet à Active
resubscribe ActiveSubscriptions déterministe par local id
remote IDs invalidés après reconnect
continuity_gap_count observable
unsubscribe local gagne les races reconnect/late ack
overflow d'une subscription ne tue pas les autres
shutdown explicite borné via WsSession::close().await
Drop best-effort seulement
```
`signatureSubscribe` reste one-shot après notification terminale et ne doit pas être resubscribed après fermeture normale.
### 5.5 Sécurité/observabilité
Safe metadata autorisée :
```text
endpoint logical name
provider
cluster
protocol kind
local session/subscription ids
subscription kind
states
counts
reconnect attempt
continuity gaps
overflow count
safe error codes
```
Interdit dans logs/Debug/Display/snapshots :
```text
URL complète
query api-key
authorization secret
headers sensibles
remote subscription id
raw notification arbitraire
payload massif
```
### 5.6 Config V2
Contrat stable :
```text
format_version = 2
retry
ws_defaults
default_profile
profiles[]
endpoints[]
ws_endpoints[]
kind
```
À la fin de `0.2.7`, la seule valeur WebSocket Config supportée est :
```text
solana_standard
```
Le type Transport correspondant est `WsProtocolKind`, `#[non_exhaustive]`, précisément pour permettre une extension future sans remplacer le conteneur commun.
---
## 6. Frontières architecturales et règles de dépendances
Direction autorisée :
```text
ksp-config-lib -> ksp-onchain-transport-lib
```
Interdictions durables :
```text
ksp-onchain-transport-lib -X-> ksp-config-lib
ksp-onchain-transport-lib -X-> ksp-wallet-lib
ksp-onchain-transport-lib -X-> ksp-store-api
ksp-onchain-transport-lib -X-> ksp-store-lib
ksp-onchain-transport-lib -X-> ksp-program-api
ksp-onchain-transport-lib -X-> ksp-program-lib
ksp-onchain-transport-lib -X-> tracing direct
```
Transport peut dépendre seulement des crates KSP basses autorisées et des crates réseau/serde/async strictement nécessaires.
Toutes les dépendances tierces restent déclarées dans le `[workspace.dependencies]` racine et consommées par les members avec `.workspace = true`.
Aucun client Helius SDK n'est ajouté par défaut. Une nouvelle dépendance doit démontrer un besoin que le moteur `tokio-tungstenite` existant ne satisfait pas.
---
## 7. Décisions acquises et questions réellement ouvertes
### 7.1 Décisions déjà acquises — ne pas les redébattre sans contradiction réelle
```text
Helius WebSocket réutilise le moteur/session actor de 0.2.7
pas de second client WebSocket provider-specific
les wrappers Solana standard restent valides pour la surface standard
aucune API raw provider-extension publique par défaut
pas de LaserStream gRPC dans 0.2.8
pas de Yellowstone gRPC dans 0.2.8
pas de Store/RAW persistence dans 0.2.8
pas de Program decode/materialization dans 0.2.8
pas de metering/billing provider dans 0.2.8
pas de promesse lossless/historical replay pour WebSocket
credentials Helius = Secret Config, jamais loggés
fixtures déterministes = gate principal ; réseau réel = opt-in uniquement
```
La piste de metering/observabilité réseau est suivie séparément dans `docs/IDEAS.md`; elle ne doit pas être introduite opportunistement dans cette release.
### 7.2 Questions ouvertes à trancher pendant `pre.001`
Le gate doit décider, avec preuves :
```text
nom/public descriptor exact du nouveau WsProtocolKind éventuel
Helius endpoint = SolanaStandard + provider helius, HeliusLaserStream, ou combinaison explicitement justifiée
surface Helius exacte du jour
transactionSubscribe + transactionUnsubscribe : existence, noms et wire exacts
notification transaction exacte et réutilisation possible des DTOs HTTP/WS existants
filtres transaction exacts et limites courantes
extension tokenAccounts : valeurs, cardinalité, interactions
notifyOn account/program : valeurs et comportement serveur
autres extensions Helius actuellement documentées éventuelles
méthodes Solana standard supportées/non supportées sur Helius
comportement KSP pour block/slotsUpdates/vote sur endpoint Helius
capability validation avant I/O vs erreur RPC provider
heartbeat/ping provider : nécessaire, cadence, ownership et interaction avec control frames existants
idle timeout Helius et stratégie de reconnect
interaction entre heartbeat et shutdown/reconnect/backpressure
Config : discriminateur, provider metadata, endpoint/auth shape
faut-il de nouveaux settings provider-specific distincts de WsSessionSettings commun
comment éviter d'injecter notifyOn/tokenAccounts dans les DTOs Solana standard
warning/info provider-specific éventuel et metadata sûre
stratégie de smoke Helius nécessitant une api-key sans lecture directe d'environnement par Transport
besoin réel ou non d'une nouvelle dépendance Rust
```
Une décision peut être de **ne pas exposer** une capacité Helius insuffisamment documentée. Elle doit alors être explicitement reportée, pas silencieusement oubliée.
---
## 8. Objectifs et livrables de `0.2.8`
Le plan créé par `pre.001` doit au minimum prévoir :
1. une matrice normative Helius WebSocket actuelle et sourcée ;
2. un inventaire explicite standard supporté / standard non supporté / extension Helius ;
3. le choix d'extension de `WsProtocolKind` et du Config V2 ;
4. la réutilisation du `WsSession` actor existant ;
5. `transactionSubscribe`/unsubscribe si toujours supportés et documentés ;
6. les filtres/options Helius réellement utiles et documentés ;
7. les extensions Helius de `accountSubscribe`/`programSubscribe` si toujours présentes ;
8. une politique provider capability sans contamination de la surface standard ;
9. heartbeat/idle handling si réellement requis ;
10. fixtures locales déterministes de toutes les extensions ;
11. tests de reconnect/resubscribe/unsubscribe/backpressure sur les nouvelles familles ;
12. redaction credentials Helius et erreurs sûres ;
13. adaptation Config -> Transport correspondante ;
14. canaries de non-régression 18/18 standard + 52/14 HTTP ;
15. documentation README/USAGE durable et version-neutral ;
16. stratégie de smoke live opt-in compatible avec les règles Config/secret ;
17. audit final des dépendances et prompt `0.2.9`.
Créer normalement :
```text
docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md
docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md
```
Si ces numéros sont déjà occupés dans la base réellement fournie, prendre les prochains numéros disponibles et mettre à jour les index correspondants.
---
## 9. Hors périmètre explicite
```text
LaserStream gRPC / helius-laserstream SDK -> hors 0.2.8
Yellowstone gRPC standard -> 0.2.9
providers Yellowstone commerciaux spécifiques -> après foundation 0.2.9 selon sizing
Gatekeeper beta -> hors scope sauf décision explicite après audit
Shred Delivery / shreds UDP -> plus tard
preconfirmations / Sender -> autres surfaces futures
HTTP Helius provider extensions non WebSocket -> hors 0.2.8
ksp-offchain-transport-lib / prix -> 0.2.10
Price Desk / Wallet Desk price integration -> 0.2.11
Store / RAW persistence -> série 0.3.x
Program decode / materialization -> plus tard
metering / coût / billing provider -> IDEAS/future crate dédiée
pool/scheduler automatique complexe de WsSession -> différé sans besoin démontré
historical replay WebSocket inventé -> interdit
```
Ne pas importer dans `0.2.8` les capacités gRPC de LaserStream sous prétexte qu'elles portent le même nom produit.
---
## 10. Contraintes sécurité, provider et API
### 10.1 Credentials Helius
Une api-key Helius est un Secret.
Elle ne doit jamais apparaître dans :
```text
Debug
Display
KspError context arbitraire
logs
panic output volontaire
snapshots runtime
nom d'endpoint
fixtures versionnées
commandes documentées avec vraie valeur
```
Les URLs contenant `?api-key=...` doivent rester derrière `WsEndpointUrl` et ses garanties de redaction.
### 10.2 Provider-specific sans pollution standard
Une option Helius ne doit pas être ajoutée à un DTO standard Solana simplement parce qu'elle réutilise le même nom JSON-RPC.
Le design doit distinguer explicitement :
```text
contrat Solana standard
extension Helius du même method name
nouvelle méthode Helius
```
Les wrappers standards de `0.2.7` ne doivent pas changer de wire lorsqu'ils sont utilisés avec `WsProtocolKind::SolanaStandard`.
### 10.3 Heartbeat
`0.2.7` n'impose aucun heartbeat applicatif périodique : il répond correctement aux control frames WebSocket reçues.
Si Helius exige/recommande un ping périodique pour éviter son inactivity timeout, `pre.001` doit décider si cela devient :
```text
une capability provider-specific
un setting explicite
un comportement automatique borné
ou une responsabilité caller
```
Toute solution automatique doit :
```text
être annulable au shutdown
ne pas masquer un socket réellement mort
ne pas créer une boucle de reconnexion infinie
ne pas bloquer l'actor
ne pas logguer de secret
être couverte par test temporel déterministe local
```
### 10.4 Continuité
Même si Helius annonce une infrastructure de failover, WebSocket ne doit pas être documenté comme lossless.
Le contrat KSP reste :
```text
reconnect possible
resubscribe possible
continuity_gap_count observable
aucun backfill automatique dans Transport
aucune garantie de replay historique WebSocket
```
---
## 11. Première mission `0.2.8-pre.001` — gate obligatoire
La première tranche est **audit + brainstorming + sizing**, pas une tranche d'implémentation lourde.
Elle doit exécuter dans l'ordre :
### 11.1 Reprise de la base
```text
vérifier base/tag v0.2.7 ou archive stable autoritaire
lire les règles obligatoires
lire plan + validation + rel.001 de 0.2.7
inventorier le code WsSession/WsSubscription/Config réellement publié
vérifier l'état Cargo et le graphe actuel
```
### 11.2 Audit Helius officiel actuel
Construire une matrice contenant au minimum :
```text
method
subscribe/unsubscribe pair
standard ou Helius extension
support Helius actuel
params obligatoires
options
filters
limits/cardinality
notification method
notification wire
nullable/optional states
idle/heartbeat requirement
credential requirement
source officielle
strategy de test
```
Le gate doit spécialement résoudre :
```text
transactionUnsubscribe exact
notifyOn exact
programSubscribe + notifyOn exact
tokenAccounts exact
autres filtres transaction actuels
liste des méthodes unstable explicitement non supportées
endpoints mainnet/devnet réellement courants
ancien atlas-* vs endpoints unifiés actuels
nom actuel Enhanced WebSockets vs LaserStream WebSocket
```
### 11.3 Audit architecture KSP
Comparer la matrice Helius avec :
```text
WsProtocolKind
WsEndpointSettings
WsSessionSettings
WsSubscriptionKind
subscribe_typed interne
registry/remapping remote/local
reconnect/resubscribe
Config V2 kind
```
Décider quelles parties sont :
```text
réutilisées telles quelles
étendues provider-specific
interdites avant I/O
laissées à l'erreur provider
reportées
```
### 11.4 Audit dépendances
Exécuter au minimum :
```bash
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
```
Vérifier les versions stables courantes des crates réseau utilisées. Ne pas ajouter un SDK Helius sans justification mesurable.
### 11.5 Threat model provider
Brainstormer au minimum :
```text
api-key dans query URL
endpoint redaction
provider idle timeout
heartbeat concurrent avec reconnect/close
rate/capability errors
subscription ids et late notifications
in-flight notifications après unsubscribe
provider-specific unknown fields
payload volumineux transactionSubscribe
50k-address style filters et coût mémoire/serialization
data gaps après reconnect
mismatch standard method support
```
### 11.6 Sizing
Produire :
```text
liste exacte des capacités à implémenter
questions reportées
nombre estimé de prereleases
budget de chaque tranche <= environ 1520 minutes de travail effectif
ordre des tranches
validations associées
risques de split
```
Si la surface Helius actuelle est plus large que prévu et menace la règle « une release concrète clôturable dans une session », **scinder avant implémentation lourde**.
### 11.7 Documents de sortie du gate
`pre.001` doit créer/mettre à jour au minimum :
```text
docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md
docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md
deltas/0.2.8/pre.001.md
```
ainsi que les index documentaires concernés.
### Critères de sortie de `pre.001`
Le gate est positif seulement si :
```text
base stable confirmée
sources Helius actuelles réauditées
surface exacte inventoriée
terminologie provider clarifiée
frontières standard/provider décidées
heartbeat/idle ownership décidé ou explicitement reporté
Config shape décidée
strategy de credentials sûre
strategy de tests/smoke décidée
aucune nouvelle dépendance non justifiée
release dimensionnée et forecast recalibré
```
---
## 12. Prévision souple initiale des prereleases
Prévision de départ, à recalibrer après `pre.001` :
```text
pre.001 audit Helius actuel + matrice + architecture + threat model + sizing
pre.002 protocol/provider settings + Config V2 extension + capability model
pre.003 transactionSubscribe/unsubscribe + DTOs/filters/options + fixtures
pre.004 extensions account/program et autres filtres Helius retenus + fixtures
pre.005 heartbeat/idle/reconnect/capability failures + adversarial lifecycle tests
pre.006 compliance provider + non-régressions standard/HTTP + smoke strategy + dependency audit + docs
pre.007 validation workspace finale + documentation/indexes + prompt 0.2.9
rel.001 publication stable stricte
```
Cette prévision est **souple**. Des tranches ou fixes peuvent être insérés si l'audit réel le justifie. La fermeture ne doit jamais être forcée pour respecter `pre.007`.
---
## 13. Versionnement, deltas, commits et tags
Convention de livraison :
```text
0.2.8-pre.001 -> Cargo 0.2.8-pre.1
0.2.8-pre.002 -> Cargo 0.2.8-pre.2
0.2.8-pre.NNN-fix.MMM -> Cargo 0.2.8-pre.N.fix.M seulement si code/build/runtime/config/migration change
0.2.8-rel.001 -> Cargo 0.2.8
```
Une prerelease non-fix synchronise toujours `workspace.package.version`, même si son contenu final est principalement documentaire. Un fix purement documentaire/de référence non consommée par le runtime conserve la version Cargo de sa base directe, conformément à `VERSION_WORKFLOW.md`.
Deltas :
```text
deltas/0.2.8/pre.001.md
deltas/0.2.8/pre.002.md
...
deltas/0.2.8/pre.NNN-fix.MMM.md
deltas/0.2.8/rel.001.md
```
Commits :
```text
v0.2.8-pre.001
v0.2.8-pre.001-fix.001
...
v0.2.8-rel.001
```
Aucun tag Git pour les prereleases.
Après validation de `rel.001` :
```text
tag stable = v0.2.8
```
Une livraison publiée est immutable. Une correction produit un nouveau `fix`; elle ne remplace jamais l'archive précédente.
Pendant les prereleases :
```text
ROADMAP.md = statut global seulement
CHANGELOG.md = principalement clôture stable
progression détaillée = plan + validation + deltas
pas de Cargo.lock / package-lock.json versionné
```
Tout fichier modifié incrémente son header `version:` selon les règles KSP.
---
## 14. Application et validation opérateur
L'assistant prépare normalement un overlay minimal ne contenant que les fichiers ajoutés/modifiés de la livraison.
Après application d'une prerelease Rust :
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
```
Puis tests ciblés pertinents, par exemple :
```bash
cargo test -p ksp-onchain-transport-lib
cargo test -p ksp-config-lib
```
À la fermeture d'une tranche technique importante et de la release :
```bash
cargo test --workspace
```
Lorsque le graphe de dépendances change ou constitue un gate :
```bash
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
cargo tree --duplicates
```
Ne jamais déclarer une commande réussie si elle n'a pas été exécutée. L'environnement de préparation peut ne pas disposer de Cargo/rustfmt ; dans ce cas, le delta doit le dire explicitement et l'opérateur exécute les gates.
### Tests provider attendus
Les preuves déterministes doivent couvrir au minimum, selon la surface retenue :
```text
subscribe/unsubscribe exacts
notification method exact
transaction filters/options complets
cardinalités/limites avant I/O lorsqu'elles sont déterministes
notifyOn/tokenAccounts ou extensions retenues
standard vs provider capability mismatch
provider RPC errors sans session failure injustifiée
late notification après unsubscribe
reconnect/resubscribe
heartbeat timer borné si ajouté
shutdown pendant heartbeat/reconnect
message/frame oversized
queue overflow d'une subscription
secret URL redaction
public API canaries
Config -> Transport mapping
HTTP 52+14 non régressé
Solana standard 18/18 non régressé
```
### Smoke live Helius
Un smoke live Helius ne doit **jamais** justifier :
```text
std::env direct dans Transport
api-key hardcodée
secret dans fixture
secret dans commande/delta/log
nouvelle dépendance Transport -> Config
```
`pre.001` doit décider une stratégie compatible avec l'architecture. Si aucune surface d'intégration sûre n'existe encore, il est acceptable de garder la compliance provider principalement déterministe et de documenter un smoke opérateur séparé au lieu de violer les frontières KSP.
---
## 15. Critères de clôture de `0.2.8`
La release ne peut passer stable que si :
```text
surface Helius WebSocket actuelle auditée et rapprochée
chaque capacité ciblée a un statut explicite
aucune méthode/options Helius retenue n'est perdue
standard Solana 18/18 non régressé
HTTP 52 current + 14 historical non régressé
moteur WsSession unique réutilisé
aucun second client WebSocket provider-specific
Config -> Transport reste la seule direction d'adaptation
credentials Helius redacted partout
heartbeat/idle behavior audité et testé si implémenté
reconnect/resubscribe/backpressure/shutdown restent bornés
aucune fausse promesse lossless/replay WebSocket
aucune dépendance Store/Program/Wallet/Config/tracing direct dans Transport
dépendances directes et doublons transitifs inspectés
fixtures déterministes vertes
workspace complet vert
README/USAGE synchronisés et version-neutral
matrice finale de validation fermée
prompt 0.2.9 préparé
```
`CHANGELOG.md` et le statut stable du ROADMAP ne sont finalisés qu'à la publication `rel.001`.
---
## 16. Release/session suivante envisagée
La release suivante prévue est :
```text
0.2.9 — Yellowstone gRPC standard/provider-neutral
```
Elle doit partir du moteur Transport stabilisé mais **ne doit pas être anticipée dans `0.2.8`** par l'ajout de dépendances gRPC, de protobufs Yellowstone ou du SDK LaserStream gRPC.
Le prompt `0.2.9` devra imposer un nouvel audit normatif de la surface Yellowstone actuelle et un sizing complet avant implémentation.
---
## 17. Instruction d'ouverture
Au début de la nouvelle session `0.2.8` :
1. vérifier que la base est réellement `v0.2.7` ou l'archive stable autoritaire fournie ;
2. lire les sources internes obligatoires dans l'ordre indiqué ;
3. relire `deltas/0.2.7/rel.001.md`, le plan et la matrice finale WebSocket standard ;
4. inspecter le code public/réel de `WsSession`, `WsSubscription`, `WsProtocolKind` et Config V2 ;
5. réauditer immédiatement la documentation officielle Helius LaserStream WebSocket du jour ;
6. produire la matrice standard/supporté/extension/non-supporté ;
7. brainstormer provider credentials, heartbeat, capabilities, reconnect et tests ;
8. dimensionner/recalibrer la release et écrire `pre.001` ;
9. exécuter les validations de gate disponibles ;
10. **ne pas commencer `transactionSubscribe`, modifier Config ou ajouter une dépendance avant que ce gate soit cohérent**.
La première réponse de travail doit donc être un **audit/sizing `0.2.8-pre.001`**, pas une implémentation prématurée.