From 5aa7b4584010f05d5de98d061a86240a5831b8b3 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Sun, 23 Aug 2026 11:15:57 +0200 Subject: [PATCH] v0.2.7-pre.014 --- Cargo.toml | 4 +- ROADMAP.md | 4 +- crates/ksp-app-config-desk/README.md | 12 +- crates/ksp-app-config-desk/USAGE.md | 6 +- crates/ksp-app-wallet-desk/README.md | 10 +- crates/ksp-config-lib/README.md | 4 +- crates/ksp-config-lib/USAGE.md | 4 +- crates/ksp-core-lib/README.md | 135 +++ crates/ksp-core-lib/USAGE.md | 265 +++++ crates/ksp-logging-lib/USAGE.md | 4 +- crates/ksp-onchain-transport-lib/README.md | 57 +- crates/ksp-onchain-transport-lib/USAGE.md | 28 +- crates/ksp-wallet-lib/README.md | 16 +- crates/ksp-wallet-lib/USAGE.md | 6 +- deltas/0.2.7/pre.014.md | 131 +++ docs/000-README.md | 4 +- docs/plans/000-README.md | 4 +- docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md | 6 +- .../014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md | 28 +- docs/validation/000-README.md | 4 +- .../010-V0_2_7_ONCHAIN_WEBSOCKET.md | 20 +- prompts/000-README.md | 5 +- prompts/013-V0_2_8_START_PROMPT.md | 951 ++++++++++++++++++ 23 files changed, 1605 insertions(+), 103 deletions(-) create mode 100644 crates/ksp-core-lib/README.md create mode 100644 crates/ksp-core-lib/USAGE.md create mode 100644 deltas/0.2.7/pre.014.md create mode 100644 prompts/013-V0_2_8_START_PROMPT.md diff --git a/Cargo.toml b/Cargo.toml index 498d083..d7d5eaf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 214 +# version: 215 [workspace] 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"] [workspace.package] -version = "0.2.7-pre.13" +version = "0.2.7-pre.14" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/ROADMAP.md b/ROADMAP.md index a902e2e..41eb5fc 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,5 @@ - + # 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.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 l’audit 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`. -- [ ] `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.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. diff --git a/crates/ksp-app-config-desk/README.md b/crates/ksp-app-config-desk/README.md index 430abc6..b0d2841 100644 --- a/crates/ksp-app-config-desk/README.md +++ b/crates/ksp-app-config-desk/README.md @@ -1,5 +1,5 @@ - + # `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é -`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. @@ -123,11 +123,11 @@ main -> ksp-app-config-desk.frontend.main 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 -`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. @@ -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. -`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. ## 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 d’un 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 d’un développement ou diagnostic, puis redescendus avant la release suivante. ## Traçabilité frontend diff --git a/crates/ksp-app-config-desk/USAGE.md b/crates/ksp-app-config-desk/USAGE.md index 80cfb6b..0c483c0 100644 --- a/crates/ksp-app-config-desk/USAGE.md +++ b/crates/ksp-app-config-desk/USAGE.md @@ -1,5 +1,5 @@ - + # 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. -`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 @@ -287,7 +287,7 @@ Si la résolution ou la préparation du profil explicite échoue, `ksp_logging_l ## 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 default_filter = warn diff --git a/crates/ksp-app-wallet-desk/README.md b/crates/ksp-app-wallet-desk/README.md index a2f36f4..7753257 100644 --- a/crates/ksp-app-wallet-desk/README.md +++ b/crates/ksp-app-wallet-desk/README.md @@ -1,9 +1,9 @@ - + # `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 : @@ -29,7 +29,7 @@ Le frontend ne reçoit jamais les keypairs, ciphertexts, passwords Config, paths ## `.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 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. -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 : diff --git a/crates/ksp-config-lib/README.md b/crates/ksp-config-lib/README.md index ef2471d..ec4ed48 100644 --- a/crates/ksp-config-lib/README.md +++ b/crates/ksp-config-lib/README.md @@ -1,5 +1,5 @@ - + # ksp-config-lib @@ -86,7 +86,7 @@ Le document Logging refuse les valeurs de sensibilité `Secret` dans sa configur ## Documentation - [`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 ; - [`../../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 ; diff --git a/crates/ksp-config-lib/USAGE.md b/crates/ksp-config-lib/USAGE.md index d7ccfcf..4ce2c7c 100644 --- a/crates/ksp-config-lib/USAGE.md +++ b/crates/ksp-config-lib/USAGE.md @@ -1,5 +1,5 @@ - + # Utilisation de ksp-config-lib @@ -140,7 +140,7 @@ let ws_settings = transport.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. diff --git a/crates/ksp-core-lib/README.md b/crates/ksp-core-lib/README.md new file mode 100644 index 0000000..983dc6a --- /dev/null +++ b/crates/ksp-core-lib/README.md @@ -0,0 +1,135 @@ + + + +# `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 +``` + +`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 +.: +``` + +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. diff --git a/crates/ksp-core-lib/USAGE.md b/crates/ksp-core-lib/USAGE.md new file mode 100644 index 0000000..d75892f --- /dev/null +++ b/crates/ksp-core-lib/USAGE.md @@ -0,0 +1,265 @@ + + + +# 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` : + +```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 { + 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 lorsqu’un 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. diff --git a/crates/ksp-logging-lib/USAGE.md b/crates/ksp-logging-lib/USAGE.md index bce54e2..1c49f8d 100644 --- a/crates/ksp-logging-lib/USAGE.md +++ b/crates/ksp-logging-lib/USAGE.md @@ -1,5 +1,5 @@ - + # Utilisation de ksp-logging-lib @@ -48,7 +48,7 @@ Les fichiers persistants interdisent `ansi = true`. ## 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 ; - les formats `Human`, `Compact`, `Pretty` et `Json` ; diff --git a/crates/ksp-onchain-transport-lib/README.md b/crates/ksp-onchain-transport-lib/README.md index c3e1dab..4306b98 100644 --- a/crates/ksp-onchain-transport-lib/README.md +++ b/crates/ksp-onchain-transport-lib/README.md @@ -1,9 +1,9 @@ - + # `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 lorsqu’une release les cible. ## Responsabilités @@ -19,7 +19,8 @@ La crate possède : - les enveloppes JSON-RPC 2.0 et leur validation ; - le registre audité des méthodes Solana HTTP ; - 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 ; - l'observabilité Transport via `ksp-logging-lib`. @@ -70,23 +71,23 @@ Le registre porte notamment : - remplacement historique éventuel ; - 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 -0.2.1 foundation : 4 -0.2.2 Accounts/Tokens/Cluster : 22 -0.2.3 Transactions : 11 -0.2.4 Blocks/Economics : 15 -total : 52 +foundation : 4 +Accounts/Tokens/Cluster : 22 +Transactions : 11 +Blocks/Economics : 15 +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. -## 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é. @@ -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` ; - applique aux sockets les plafonds KSP de message, frame et write buffer ; - 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. -### 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. 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. -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` 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 l’utilisent derrière leurs DTOs et paramètres typés. Le handle public `WsSubscription` expose uniquement : - `id()` et `kind()` ; - `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`. -### 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. @@ -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. -### 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. @@ -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. -### 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` : @@ -162,9 +163,9 @@ logs_subscribe -> WsSubscription> `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 l’actor pour le resubscribe déterministe, et toutes les règles de backpressure/terminal error s’appliquent 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 : @@ -178,9 +179,9 @@ root_subscribe -> WsSubscription 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** : @@ -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 ; - [`../../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/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/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/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/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é Transactions ; +- [`../../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/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. diff --git a/crates/ksp-onchain-transport-lib/USAGE.md b/crates/ksp-onchain-transport-lib/USAGE.md index b338672..3b11395 100644 --- a/crates/ksp-onchain-transport-lib/USAGE.md +++ b/crates/ksp-onchain-transport-lib/USAGE.md @@ -1,5 +1,5 @@ - + # 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 -À 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 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. -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` 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 -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 let account = match "11111111111111111111111111111111".parse::() { @@ -128,7 +128,7 @@ Les trois wrappers retournent le même handle `WsSubscription` : reconnect, r ### 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 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 -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 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é -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. @@ -193,7 +193,7 @@ Depuis `0.2.7-pre.007`, les settings de session contrôlent réellement le recon ### Backpressure par subscription -Depuis `0.2.7-pre.008`, `WsSessionSettings::notification_queue_capacity()` borne réellement la queue de chaque `WsSubscription`. 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`. 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. @@ -203,7 +203,7 @@ Le consumer doit traiter `overflow_count` et `continuity_gap_count` comme deux s ### 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 let session = ksp_onchain_transport_lib::WsSession::connect(endpoint).await?; @@ -238,7 +238,7 @@ let balance = pool .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 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; ``` -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 : @@ -334,7 +334,7 @@ La configuration standard route les événements `info` de Transport vers un fic ## 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 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. -Le smoke historique de **composition Config -> Transport** reste également disponible : +Le smoke de **composition Config -> Transport** reste également disponible : ```bash 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. -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 cargo tree -p ksp-onchain-transport-lib diff --git a/crates/ksp-wallet-lib/README.md b/crates/ksp-wallet-lib/README.md index e4482a3..fb77d2b 100644 --- a/crates/ksp-wallet-lib/README.md +++ b/crates/ksp-wallet-lib/README.md @@ -1,11 +1,11 @@ - + # `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. @@ -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 ; - [`../../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 ; -- [`../../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 DEFAULT_WALLET_FORMAT = V2 @@ -211,7 +211,7 @@ open/inspect génériques -> détection V1/V2 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 ```text diff --git a/crates/ksp-wallet-lib/USAGE.md b/crates/ksp-wallet-lib/USAGE.md index 7d49dd5..060a450 100644 --- a/crates/ksp-wallet-lib/USAGE.md +++ b/crates/ksp-wallet-lib/USAGE.md @@ -1,5 +1,5 @@ - + # Utilisation de `ksp-wallet-lib` @@ -278,9 +278,9 @@ ksp-onchain-transport-lib -> 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 : diff --git a/deltas/0.2.7/pre.014.md b/deltas/0.2.7/pre.014.md new file mode 100644 index 0000000..d68d09f --- /dev/null +++ b/deltas/0.2.7/pre.014.md @@ -0,0 +1,131 @@ + + + +# Delta `0.2.7-pre.014` — clôture candidate, audit documentaire et prompt `0.2.8` + +## Base + +Base autoritaire fournie par l’opé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 n’est 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 n’est 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 l’analyse 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 l’historique 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 n’est 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 l’ordre de lecture des sources internes ; +- impose un réaudit Helius officiel actuel avant implémentation et référence les points d’entré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 jusqu’au 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 l’anticiper. + +## Runtime / API + +Aucun fichier `src/` n’est modifié. Aucun contrat HTTP/WebSocket, DTO, lifecycle, reconnect, backpressure, Config runtime ou dépendance directe Transport n’est 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 n’ont 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`. diff --git a/docs/000-README.md b/docs/000-README.md index 0685e0d..34da31b 100644 --- a/docs/000-README.md +++ b/docs/000-README.md @@ -1,5 +1,5 @@ - + # Documentation KSP @@ -79,7 +79,7 @@ D'autres sous-répertoires seront ajoutés uniquement lorsque leur rôle aura é ## Documents de planification -Le plan historique de la phase fondatrice clôturée est conservé dans [`plans/001-V0_0_3_PLAN.md`](plans/001-V0_0_3_PLAN.md). La séquence active des premières releases fonctionnelles est définie dans [`plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md`](plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md). Le plan détaillé de la release stable `0.1.1` est conservé comme historique clôturé dans [`plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md`](plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.2` est conservé comme historique clôturé dans [`plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md`](plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.3 — Configuration foundation` est conservé comme historique clôturé dans [`plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md`](plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.4 — ksp-app-config-desk` est conservé comme historique clôturé dans [`plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md`](plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md), avec sa matrice finale [`validation/001-V0_1_4_CONFIG_DESKTOP.md`](validation/001-V0_1_4_CONFIG_DESKTOP.md). Son prompt d'ouverture historique reste [`../prompts/004-V0_1_4_START_PROMPT.md`](../prompts/004-V0_1_4_START_PROMPT.md). La release stable `0.2.0` clôt l'audit de bot3 et le découpage de la série. Son plan directeur est conservé comme historique clôturé dans [`plans/007-V0_2_0_SERIES_PLANNING.md`](plans/007-V0_2_0_SERIES_PLANNING.md), avec sa matrice finale [`validation/002-V0_2_0_SERIES_PLANNING.md`](validation/002-V0_2_0_SERIES_PLANNING.md). La release stable `0.2.1 — HTTP Solana foundation` a été ouverte par [`../prompts/006-V0_2_1_START_PROMPT.md`](../prompts/006-V0_2_1_START_PROMPT.md). Son gate de sizing et sa matrice exhaustive sont conservés dans [`plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md), avec la validation finale [`validation/003-V0_2_1_ONCHAIN_HTTP.md`](validation/003-V0_2_1_ONCHAIN_HTTP.md), README/USAGE Transport et le smoke Devnet opt-in de composition Config -> Transport. Le prompt [`../prompts/007-V0_2_2_START_PROMPT.md`](../prompts/007-V0_2_2_START_PROMPT.md) a ouvert la release stable `0.2.2 — HTTP Accounts + Tokens + Cluster`. Son plan clôturé [`plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) conserve l'audit et l'implémentation des 22 wrappers typés, tandis que [`validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) enregistre les validations déterministes, les graphes Cargo et les deux smokes Devnet passés avant publication. Le prompt [`../prompts/008-V0_2_3_START_PROMPT.md`](../prompts/008-V0_2_3_START_PROMPT.md) a ouvert la release stable `0.2.3 — HTTP Transactions`. Son plan clôturé [`plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) conserve l'audit et l'implémentation des 11 wrappers ; le réaudit [`validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`](validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md) confirme la complétude des 37 wrappers HTTP typés et [`validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](validation/006-V0_2_3_HTTP_TRANSACTIONS.md) enregistre les validations finales, graphes Cargo et deux smokes Devnet passés avant publication. Le prompt [`../prompts/009-V0_2_4_START_PROMPT.md`](../prompts/009-V0_2_4_START_PROMPT.md) a ouvert la release stable `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale`. Son plan clôturé [`plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) conserve l’implémentation des 15 wrappers et la compliance `52/52 + 14/14`; la matrice finale [`validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) enregistre le réaudit SIMD/inventaire, les canaries globales et les preuves opérateur avant publication. Le prompt [`../prompts/010-V0_2_5_START_PROMPT.md`](../prompts/010-V0_2_5_START_PROMPT.md), finalisé par `0.2.4-pre.009-fix.001`, ouvre `0.2.5 — Wallet foundation` sur la base stable `v0.2.4`. Son plan historique clôturé [`plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md) part du gate `pre.001` (héritage, threat model offline, VIEW/OWNER indépendants et niveau B read-only), puis matérialise la crate en `pre.002`, le wire/transcript en `pre.003`, les primitives Argon2id/XChaCha20-Poly1305 en `pre.004`, les payloads/create/open en `pre.005`, la persistence en `pre.006`, l'administration/signature en `pre.007` et les adapters transfer en `pre.008`. `pre.009` ferme l'audit adversarial/interoperability/compliance dans [`validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) avant la documentation finale `pre.010` ; `pre.010` finalise [`../crates/ksp-wallet-lib/README.md`](../crates/ksp-wallet-lib/README.md), [`../crates/ksp-wallet-lib/USAGE.md`](../crates/ksp-wallet-lib/USAGE.md), la spec, les graphes et la matrice ; `pre.010-fix.001`–`fix.003` ferment ensuite la mise à niveau Dalek et la normalisation Rust/audit structurel. `0.2.5-rel.001` publie la release stable et [`../prompts/011-V0_2_6_START_PROMPT.md`](../prompts/011-V0_2_6_START_PROMPT.md) ouvre `0.2.6 — Wallet Desk`. Le gate `0.2.6-pre.001` est conservé dans [`plans/013-V0_2_6_WALLET_DESK_PLAN.md`](plans/013-V0_2_6_WALLET_DESK_PLAN.md) : il réaudite Config Desk et les APIs finales, retient le gabarit desktop, fixe `std.wallet`, la composition Config/Wallet/HTTP/Logging, les secrets `KSP_SECRET_WALLET_PASS_*`, les frontières VIEW/OWNER et la trajectoire de validation. `pre.002`–`pre.014` matérialisent ensuite le shell Tauri, Config Wallet/composite, inventory, create/open, balance HTTP, import/export, metadata, rotations, révocation VIEW forte, compliance et polish desktop. `pre.015` fige le wire binaire `.kspwallet` V2, `pre.016` matérialise les APIs génériques/versionnées et le runtime V2, puis `pre.017` ajoute la migration explicite OWNER-authentifiée V1 -> V2. `pre.018` ferme le runtime Tauri packagé Config/resources et la documentation candidate ; `pre.018-fix.001` corrige le canari d'ownership Config, après quoi le gate workspace et le build final Linux sont verts. `pre.018-fix.002` renforce uniquement le contrat de reprise `0.2.7`. `0.2.6-rel.001` publie cette surface stable et [`../prompts/012-V0_2_7_START_PROMPT.md`](../prompts/012-V0_2_7_START_PROMPT.md) devient le prochain point d'entrée. Le gate `0.2.7-pre.001` ouvre désormais la release WebSocket standard dans [`plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md`](plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md) ; la matrice normative initiale est conservée dans [`validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md`](validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md). +Le plan historique de la phase fondatrice clôturée est conservé dans [`plans/001-V0_0_3_PLAN.md`](plans/001-V0_0_3_PLAN.md). La séquence active des premières releases fonctionnelles est définie dans [`plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md`](plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md). Le plan détaillé de la release stable `0.1.1` est conservé comme historique clôturé dans [`plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md`](plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.2` est conservé comme historique clôturé dans [`plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md`](plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.3 — Configuration foundation` est conservé comme historique clôturé dans [`plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md`](plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.4 — ksp-app-config-desk` est conservé comme historique clôturé dans [`plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md`](plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md), avec sa matrice finale [`validation/001-V0_1_4_CONFIG_DESKTOP.md`](validation/001-V0_1_4_CONFIG_DESKTOP.md). Son prompt d'ouverture historique reste [`../prompts/004-V0_1_4_START_PROMPT.md`](../prompts/004-V0_1_4_START_PROMPT.md). La release stable `0.2.0` clôt l'audit de bot3 et le découpage de la série. Son plan directeur est conservé comme historique clôturé dans [`plans/007-V0_2_0_SERIES_PLANNING.md`](plans/007-V0_2_0_SERIES_PLANNING.md), avec sa matrice finale [`validation/002-V0_2_0_SERIES_PLANNING.md`](validation/002-V0_2_0_SERIES_PLANNING.md). La release stable `0.2.1 — HTTP Solana foundation` a été ouverte par [`../prompts/006-V0_2_1_START_PROMPT.md`](../prompts/006-V0_2_1_START_PROMPT.md). Son gate de sizing et sa matrice exhaustive sont conservés dans [`plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md), avec la validation finale [`validation/003-V0_2_1_ONCHAIN_HTTP.md`](validation/003-V0_2_1_ONCHAIN_HTTP.md), README/USAGE Transport et le smoke Devnet opt-in de composition Config -> Transport. Le prompt [`../prompts/007-V0_2_2_START_PROMPT.md`](../prompts/007-V0_2_2_START_PROMPT.md) a ouvert la release stable `0.2.2 — HTTP Accounts + Tokens + Cluster`. Son plan clôturé [`plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) conserve l'audit et l'implémentation des 22 wrappers typés, tandis que [`validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) enregistre les validations déterministes, les graphes Cargo et les deux smokes Devnet passés avant publication. Le prompt [`../prompts/008-V0_2_3_START_PROMPT.md`](../prompts/008-V0_2_3_START_PROMPT.md) a ouvert la release stable `0.2.3 — HTTP Transactions`. Son plan clôturé [`plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) conserve l'audit et l'implémentation des 11 wrappers ; le réaudit [`validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`](validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md) confirme la complétude des 37 wrappers HTTP typés et [`validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](validation/006-V0_2_3_HTTP_TRANSACTIONS.md) enregistre les validations finales, graphes Cargo et deux smokes Devnet passés avant publication. Le prompt [`../prompts/009-V0_2_4_START_PROMPT.md`](../prompts/009-V0_2_4_START_PROMPT.md) a ouvert la release stable `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale`. Son plan clôturé [`plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) conserve l’implémentation des 15 wrappers et la compliance `52/52 + 14/14`; la matrice finale [`validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) enregistre le réaudit SIMD/inventaire, les canaries globales et les preuves opérateur avant publication. Le prompt [`../prompts/010-V0_2_5_START_PROMPT.md`](../prompts/010-V0_2_5_START_PROMPT.md), finalisé par `0.2.4-pre.009-fix.001`, ouvre `0.2.5 — Wallet foundation` sur la base stable `v0.2.4`. Son plan historique clôturé [`plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md) part du gate `pre.001` (héritage, threat model offline, VIEW/OWNER indépendants et niveau B read-only), puis matérialise la crate en `pre.002`, le wire/transcript en `pre.003`, les primitives Argon2id/XChaCha20-Poly1305 en `pre.004`, les payloads/create/open en `pre.005`, la persistence en `pre.006`, l'administration/signature en `pre.007` et les adapters transfer en `pre.008`. `pre.009` ferme l'audit adversarial/interoperability/compliance dans [`validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) avant la documentation finale `pre.010` ; `pre.010` finalise [`../crates/ksp-wallet-lib/README.md`](../crates/ksp-wallet-lib/README.md), [`../crates/ksp-wallet-lib/USAGE.md`](../crates/ksp-wallet-lib/USAGE.md), la spec, les graphes et la matrice ; `pre.010-fix.001`–`fix.003` ferment ensuite la mise à niveau Dalek et la normalisation Rust/audit structurel. `0.2.5-rel.001` publie la release stable et [`../prompts/011-V0_2_6_START_PROMPT.md`](../prompts/011-V0_2_6_START_PROMPT.md) ouvre `0.2.6 — Wallet Desk`. Le gate `0.2.6-pre.001` est conservé dans [`plans/013-V0_2_6_WALLET_DESK_PLAN.md`](plans/013-V0_2_6_WALLET_DESK_PLAN.md) : il réaudite Config Desk et les APIs finales, retient le gabarit desktop, fixe `std.wallet`, la composition Config/Wallet/HTTP/Logging, les secrets `KSP_SECRET_WALLET_PASS_*`, les frontières VIEW/OWNER et la trajectoire de validation. `pre.002`–`pre.014` matérialisent ensuite le shell Tauri, Config Wallet/composite, inventory, create/open, balance HTTP, import/export, metadata, rotations, révocation VIEW forte, compliance et polish desktop. `pre.015` fige le wire binaire `.kspwallet` V2, `pre.016` matérialise les APIs génériques/versionnées et le runtime V2, puis `pre.017` ajoute la migration explicite OWNER-authentifiée V1 -> V2. `pre.018` ferme le runtime Tauri packagé Config/resources et la documentation candidate ; `pre.018-fix.001` corrige le canari d'ownership Config, après quoi le gate workspace et le build final Linux sont verts. `pre.018-fix.002` renforce uniquement le contrat de reprise `0.2.7`. `0.2.6-rel.001` publie cette surface stable et [`../prompts/012-V0_2_7_START_PROMPT.md`](../prompts/012-V0_2_7_START_PROMPT.md) devient le prochain point d'entrée. Le gate `0.2.7-pre.001` ouvre la release WebSocket standard dans [`plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md`](plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md) ; la matrice normative et les preuves de clôture candidate sont conservées dans [`validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md`](validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md). `0.2.7-pre.014` ferme la prerelease technique/documentaire après validation 18/18, smoke WebSocket Devnet et audit du graphe Cargo ; le prompt [`../prompts/013-V0_2_8_START_PROMPT.md`](../prompts/013-V0_2_8_START_PROMPT.md) prépare `0.2.8 — Helius LaserStream WebSocket`, tandis que le statut stable reste réservé à `0.2.7-rel.001`. ## Spécifications de formats diff --git a/docs/plans/000-README.md b/docs/plans/000-README.md index 7e8374c..9b9a1d5 100644 --- a/docs/plans/000-README.md +++ b/docs/plans/000-README.md @@ -1,5 +1,5 @@ - + # 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`. - [`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`. -- [`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 l’inventaire 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. diff --git a/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md b/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md index 57abad2..e565342 100644 --- a/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md +++ b/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md @@ -1,5 +1,5 @@ - + # 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 -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. 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 15–20 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 diff --git a/docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md b/docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md index a7eed26..d5ebd36 100644 --- a/docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md +++ b/docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md @@ -1,9 +1,9 @@ - + # 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 l’audit 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 @@ -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. +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é 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.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.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 ``` @@ -1018,9 +1034,9 @@ La release ne peut passer stable que si : - smoke live retenu reste opt-in ; - 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 cargo fmt --all @@ -1029,4 +1045,4 @@ cargo check --workspace 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 n’ont 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. diff --git a/docs/validation/000-README.md b/docs/validation/000-README.md index ca2359b..df75473 100644 --- a/docs/validation/000-README.md +++ b/docs/validation/000-README.md @@ -1,5 +1,5 @@ - + # 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. - [`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. -- [`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`. diff --git a/docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md b/docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md index 1e23d76..f5f2bdd 100644 --- a/docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md +++ b/docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md @@ -1,9 +1,9 @@ - + # 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 l’audit de dépendances sont validés. `pre.014` enregistre les preuves finales et la documentation ; la publication stable reste `rel.001`. ## 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` | | 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` | -| 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` | | 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` | @@ -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` | | signature terminale ne resubscribe pas | terminal fixture | **Done `pre.010`** | | 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`** | ## 8. Dependency compliance initiale @@ -688,6 +688,8 @@ Config unit tests = 109 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` Exécuté dans le sandbox : @@ -734,10 +736,10 @@ N subscriptions same session prouvé reconnect/resubscribe/backpressure/shutdown gates verts unstable warnings centralisés 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`**) -cargo tree inspecté (**preuve opérateur `pre.013` requise**) -cargo test --workspace vert -README/USAGE synchronisés (**Done `pre.013`**) -prompt 0.2.8 préparé +cargo tree inspecté (**Done opérateur `pre.013`**) +cargo test --workspace vert (**Done opérateur `pre.013`**) +README/USAGE synchronisés et réaudités durables (**Done `pre.014`**) +prompt 0.2.8 préparé (**Done `pre.014`**) ``` diff --git a/prompts/000-README.md b/prompts/000-README.md index 743bbe9..96e4724 100644 --- a/prompts/000-README.md +++ b/prompts/000-README.md @@ -1,5 +1,5 @@ - + # 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`. - [`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` d’inté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, l’audit 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. diff --git a/prompts/013-V0_2_8_START_PROMPT.md b/prompts/013-V0_2_8_START_PROMPT.md new file mode 100644 index 0000000..2df5bc8 --- /dev/null +++ b/prompts/013-V0_2_8_START_PROMPT.md @@ -0,0 +1,951 @@ + + + +# 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 +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 15–20 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.