# Delta `0.2.8-pre.002` — Socle protocolaire et façades WebSocket ## 1. Objet Cette tranche matérialise le socle protocolaire décidé par `pre.001-fix.001`/`fix.002` sans commencer Config Helius, `transactionSubscribe` ni le heartbeat provider. Version workspace : ```text 0.2.8-pre.2 ``` Livraison : ```text 0.2.8-pre.002 ``` Commit attendu : ```text v0.2.8-pre.002 ``` Aucun tag prerelease. ## 2. Protocol kind WebSocket `WsProtocolKind` contient désormais : ```text SolanaStandard -> solana_standard HeliusLaserStream -> helius_laserstream ``` Le nom `HeliusLaserStream` appartient explicitement au namespace WebSocket. Cette tranche n'ajoute aucun type, discriminateur ou backend LaserStream gRPC. ## 3. Deux façades, un seul moteur physique Nouvelles façades publiques : ```text SolanaStandardWsSession HeliusLaserStreamWsSession ``` Elles contiennent un `WsSession` privé et délèguent toutes les opérations physiques au moteur acquis en `0.2.7`. Le chemin partagé est : ```text facade::connect -> WsSession::connect_for_protocol # crate-internal guard -> WsSession::connect_physical # unique physical constructor -> tokio::spawn(run_ws_session_actor) ``` Aucun second : ```text socket type actor WsSessionCommand pending registry subscription registry reconnect loop backpressure path shutdown path snapshot model ``` n'est créé. ## 4. Compatibilité `WsSession` historique `WsSession::connect` reste public pour les consommateurs `0.2.7`, mais devient explicitement : ```text standard-only ``` Un endpoint `WsProtocolKind::HeliusLaserStream` présenté à ce constructeur est rejeté avant toute I/O avec : ```text ERROR_CODE_INVALID_SETTINGS field = ws_endpoints.protocol expected_protocol = solana_standard actual_protocol = helius_laserstream ``` Ces contextes sont des descriptors sûrs ; aucune URL ou credential n'est copiée. La façade Helius n'expose ni `inner()` ni `into_inner()` et ne permet donc pas de récupérer un `WsSession` générique afin de contourner sa surface provider-specific. ## 5. Surface standard dans la nouvelle façade `SolanaStandardWsSession` délègue immédiatement les neuf wrappers standard acquis, sans dupliquer leur wire ou leurs decoders : ```text account_subscribe block_subscribe logs_subscribe program_subscribe root_subscribe signature_subscribe slot_subscribe slots_updates_subscribe vote_subscribe ``` Les méthodes historiques correspondantes restent aussi disponibles sur `WsSession` pour compatibilité. ## 6. Surface Helius volontairement minimale dans `pre.002` `HeliusLaserStreamWsSession` expose uniquement : ```text connect id snapshot state close ``` Elle n'expose encore aucune subscription. Cela garde la tranche sur le socle et réserve à `pre.003` l'ajout contrôlé des six familles Helius documentées comme compatibles avec le wire standard : ```text account logs program root signature slot ``` `block`, `slotsUpdates` et `vote` restent absents. Des rustdocs `compile_fail` verrouillent dès cette tranche l'absence de `block_subscribe` et de `into_inner`. ## 7. Tests et canaries ajoutés Unitaires Transport : ```text WsProtocolKind expose deux descriptors distincts les deux façades ouvrent et ferment un WebSocket contre un peer local snapshot de chaque façade conserve le protocol kind attendu WsSession::connect rejette Helius avant I/O chaque façade rejette le mauvais protocol kind avant I/O Debug Helius ne projette pas une api-key canary présente dans l'URL module de façade sans second tokio::spawn / tokio_tungstenite / WsSessionCommand module de façade sans getter inner/into_inner public ``` Public API : ```text WsProtocolKind::HeliusLaserStream visible au crate-root SolanaStandardWsSession visible au crate-root HeliusLaserStreamWsSession visible au crate-root 9 wrappers standard accessibles via SolanaStandardWsSession release-completeness conserve les 9 kinds standard et les deux descripteurs protocolaires WsSession historique toujours visible ``` Les tests `compile_fail` de la rustdoc couvrent : ```text HeliusLaserStreamWsSession::block_subscribe absent HeliusLaserStreamWsSession::into_inner absent ``` ## 8. Hors périmètre préservé Cette tranche ne modifie pas : ```text ksp-config-lib config/std.transport.json config/schemas/std.transport.schema.json .env.example WsSubscriptionKind transactionSubscribe / transactionUnsubscribe notification transaction Helius heartbeat/idle timer HTTP 52/14 Store / Program / Wallet ``` Aucune dépendance Rust n'est ajoutée. ## 9. Fichiers de la livraison Nouveaux : ```text crates/ksp-onchain-transport-lib/src/ws_protocol_session.rs crates/ksp-onchain-transport-lib/unit_tests/ws_protocol_session.rs deltas/0.2.8/pre.002.md ``` Modifiés : ```text Cargo.toml crates/ksp-onchain-transport-lib/src/lib.rs crates/ksp-onchain-transport-lib/src/ws_session.rs crates/ksp-onchain-transport-lib/src/ws_settings.rs crates/ksp-onchain-transport-lib/unit_tests/ws_settings.rs crates/ksp-onchain-transport-lib/tests/public_api.rs crates/ksp-onchain-transport-lib/tests/release_completeness.rs docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md ``` ## 10. Validation exécutée dans le sandbox de préparation Exécuté après modification : ```text python3 scripts/audit_rust_workspace_rules.py General Rust rule audit: clean Rust export completeness audit: 0 candidate(s) KSP workspace Rust rule audit: clean ``` Le sandbox de préparation ne fournit pas `cargo`/`rustfmt`. Les commandes compilées ne sont donc pas déclarées réussies ici. ## 11. Gates opérateur avant commit Après application de l'overlay : ```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 ``` Puis, si le ciblé est vert : ```bash cargo test --workspace ``` Points à surveiller spécifiquement dans la sortie : ```text les deux doctests compile_fail doivent réussir aucun warning missing_docs/unreachable_pub aucune régression des 309+ tests Transport hérités aucune régression Config causée par l'ajout de la variante non_exhaustive ``` ## 12. Suite `0.2.8-pre.003` doit ajouter uniquement sur `HeliusLaserStreamWsSession` : ```text account_subscribe logs_subscribe program_subscribe root_subscribe signature_subscribe slot_subscribe ``` avec réutilisation exacte des DTOs/wire standard, puis prouver durablement que : ```text block_subscribe absent slots_updates_subscribe absent vote_subscribe absent ``` La tranche `pre.003` ne doit toujours pas commencer Config Helius ni `transactionSubscribe`.