# Delta `0.2.7-pre.011` — familles WebSocket unstable : block + slotsUpdates + vote ## Base Base requise : ```text 0.2.7-pre.010-fix.001 workspace.package.version = 0.2.7-pre.10.fix.1 ``` Le checkpoint opérateur reçu sur cette base est vert et permet de poursuivre la série. Le correctif `pre.010-fix.001` a supprimé le helper typed devenu mort sans modifier le lifecycle WebSocket. ## Signal technique ```text livraison = 0.2.7-pre.011 workspace.package.version = 0.2.7-pre.11 commit = v0.2.7-pre.011 tag = aucun ``` ## Objectif Compléter les neuf familles standard Solana avec les trois paires officiellement instables : ```text blockSubscribe / blockUnsubscribe slotsUpdatesSubscribe / slotsUpdatesUnsubscribe voteSubscribe / voteUnsubscribe ``` La surface promise par `0.2.7` atteint ainsi : ```text 9/9 subscribe wrappers publics typed 9/9 unsubscribe via WsSubscription::unsubscribe() 18/18 opérations standard représentées ``` La compliance finale et les canaris transverses 18/18 restent le scope de `pre.012`. ## `blockSubscribe` Nouveaux contrats publics : ```text SolanaBlockSubscribeFilter All MentionsAccountOrProgram(Pubkey) SolanaBlockSubscribeConfig commitment encoding transaction_details max_supported_transaction_version show_rewards SolanaBlockNotification slot block : Option err : Option ``` Le config sérialise les noms wire exacts : `commitment`, `encoding`, `transactionDetails`, `maxSupportedTransactionVersion`, `showRewards`. Un commitment `processed` explicitement fourni est rejeté avant I/O. `confirmed` et `finalized` sont acceptés. Les cinq encodings documentés et les quatre niveaux de transaction details réutilisent les enums HTTP déjà acquis. `maxSupportedTransactionVersion` reste un `u8` numérique générique : KSP ne durcit pas la valeur à `0` et reste compatible avec de futures versions numériques supportées par le runtime ciblé. La notification réutilise `SolanaConfirmedBlock::decode_wire`, ce qui conserve les formes `full`, `accounts`, `signatures`, `none`, les encodings modern/legacy déjà acquis, les rewards et les extensions SIMD déjà couvertes côté HTTP. `block` et `err` restent indépendamment nullables. Un fixture couvre un payload de notification supérieur à 1232 octets tout en restant sous la limite WebSocket KSP, conformément à la décision de ne jamais dériver la taille maximale WS de l'ancienne limite transaction legacy. Une erreur RPC applicative simulant un validator sans capability block est renvoyée au caller sans teardown ni reconnect de la session physique. ## `slotsUpdatesSubscribe` Nouveaux contrats publics : ```text SolanaSlotUpdateStats SolanaSlotUpdate FirstShredReceived Completed CreatedBank Frozen Dead OptimisticConfirmation Root Unknown ``` Les sept variantes courantes conservent leurs champs spécifiques. `createdBank` exige `parent`, `frozen` exige `stats`, `dead` exige `err`. Une nouvelle valeur upstream du champ `type` devient : ```text Unknown { update_type, raw } ``` au lieu de faire échouer la subscription. Le `raw` est déjà borné par `WsSessionSettings.max_message_size_bytes` avant le parse JSON. Le fallback ne masque pas les violations d'une variante déjà connue : une forme connue mais structurellement invalide reste `invalid_response` pour la subscription concernée. ## `voteSubscribe` Nouveau DTO public : ```text SolanaVoteNotification vote_pubkey : Pubkey slots : Vec hash : String timestamp : Option signature : String ``` `timestamp` conserve de manière tolérante les trois formes wire retenues par l'audit : omitted, null et valeur `i64`. Omission et null deviennent `None`; une valeur devient `Some(i64)`. Les votes restent des observations gossip pre-consensus. Transport ne leur attribue aucune sémantique de confirmation ledger. ## Warning unstable centralisé `WsSubscriptionKind` connaît désormais exactement la partition unstable : ```text Block SlotsUpdates Vote ``` Le point commun `WsSession::subscribe_typed_with_completion` appelle `WsSubscriptionKind::warn_if_unstable()` avant la création logique. Le warning passe exclusivement par `ksp-logging-lib` et contient seulement : ```text rpc_method subscription_kind documentation_status = unstable ``` Il n'inclut jamais filtre, pubkey, signature, payload, remote subscription ID, URL ou credential. Le warning n'est pas répété à chaque notification. ## Tests Neuf tests unitaires supplémentaires couvrent : ```text block config complet + processed rejeté block notification null/block + shared SolanaConfirmedBlock block payload > 1232 octets sous borne WS block request exact + notification + blockUnsubscribe block RPC capability error sans échec session 7 variantes slotsUpdates + Unknown raw champs obligatoires createdBank/frozen/dead vote timestamp omitted/null/value slotsUpdates + vote end-to-end + unsubscribe partition unstable exacte ``` Le nombre de fonctions `#[test]` supplémentaires est neuf parce que le test block notification agrège aussi la preuve de payload >1232 et le test lifecycle agrège la partition warning. Un canari d'API publique supplémentaire vérifie les nouveaux wrappers et DTOs depuis la racine de crate. Comptages attendus après compilation : ```text Transport unit tests = 309 Transport public API tests = 35 release completeness = 22 ``` ## Fichiers ajoutés ```text crates/ksp-onchain-transport-lib/src/ws_blocks.rs crates/ksp-onchain-transport-lib/unit_tests/ws_blocks.rs deltas/0.2.7/pre.011.md ``` ## Fichiers modifiés ```text Cargo.toml crates/ksp-onchain-transport-lib/README.md crates/ksp-onchain-transport-lib/USAGE.md crates/ksp-onchain-transport-lib/src/lib.rs crates/ksp-onchain-transport-lib/src/ws_cluster.rs crates/ksp-onchain-transport-lib/src/ws_lifecycle.rs crates/ksp-onchain-transport-lib/src/ws_session.rs crates/ksp-onchain-transport-lib/tests/public_api.rs crates/ksp-onchain-transport-lib/unit_tests/ws_cluster.rs crates/ksp-onchain-transport-lib/unit_tests/ws_lifecycle.rs docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md ``` `ROADMAP.md` et `CHANGELOG.md` restent inchangés. ## Validation de préparation Le sandbox de préparation ne dispose pas de Cargo/rustc. Les contrôles statiques KSP sont exécutés avant packaging ; les gates compilées restent opérateur. ## 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 ``` Si ce checkpoint est vert, `pre.012` réalise la compliance WebSocket **18/18**, les canaris de composition Config et les régressions HTTP finales prévues par le plan.