Files
khadhroony-solana-project/docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md
2026-08-23 12:36:54 +02:00

32 KiB
Raw Blame History

Plan 0.2.8 — Helius LaserStream WebSocket

Statut : gate 0.2.8-pre.001 préparé, publication conditionnée aux graphes Cargo opérateur. L'audit normatif Helius du 23 août 2026, l'inventaire du runtime v0.2.7, le threat model provider et le sizing sont fermés. Aucun runtime Helius, aucun changement Config provider et aucune nouvelle dépendance ne sont introduits dans pre.001.

1. Objet et base vérifiée

0.2.8 étend le moteur WebSocket publié par 0.2.7 avec la surface Helius LaserStream WebSocket réellement documentée, sans créer un second client/session actor et sans confondre WebSocket avec LaserStream gRPC.

Base autoritaire auditée :

archive fournie : khadhroony-solana-project-v0.2.7-full-from-gitea.zip
workspace.package.version avant ouverture = 0.2.7
delta stable présent = deltas/0.2.7/rel.001.md
prompt actif présent = prompts/013-V0_2_8_START_PROMPT.md
Git metadata dans l'archive = absente ; le tag n'est donc pas revalidable localement avec git

La combinaison archive stable fournie + version Cargo stable + delta rel.001 + prompt actif satisfait la base documentaire exigée par le prompt. Les souvenirs, prereleases et anciennes copies ne sont pas utilisés comme autorité.

0.2.8-pre.001 ouvre techniquement :

workspace.package.version = 0.2.8-pre.1
livraison                 = 0.2.8-pre.001
commit attendu            = v0.2.8-pre.001
aucun tag prerelease

2. Sources internes relues et hiérarchie appliquée

Les sources internes obligatoires du prompt ont été relues depuis la base stable, notamment :

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

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
docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md

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/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md
docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md

deltas/0.2.7/rel.001.md
docs/IDEAS.md

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
.env.example

Décisions de workflow conservées :

  • pre.001 est audit + brainstorming + sizing ;
  • une prerelease non-fix synchronise toujours Cargo ;
  • une tranche vise nominalement environ 1520 minutes de travail effectif ;
  • le forecast est souple et doit être recalibré, jamais traité comme une deadline ;
  • ROADMAP.md reste global ; les détails des prereleases vivent dans le plan, la validation et les deltas ;
  • CHANGELOG.md reste réservé principalement à la publication stable.

3. Baseline de démarrage

3.1 Preuve opérateur fournie sur v0.2.7

Le log opérateur joint à la session enregistre, avant ouverture de 0.2.8 :

cargo fmt --all                               OK
python3 scripts/audit_rust_workspace_rules.py OK
  General Rust rule audit                     clean
  Rust export completeness audit              0 candidate(s)
  KSP workspace Rust rule audit               clean
cargo check --workspace                       OK
cargo clippy --workspace --all-targets        OK
cargo test --workspace                        OK

Les tests live/bench explicitement opt-in restent ignorés par défaut, conformément à leurs contrats.

3.2 Baseline du sandbox de préparation

Le sandbox de préparation ne fournit pas cargo. Avant modification :

python3 scripts/audit_rust_workspace_rules.py  OK
cargo fmt/check/clippy/tree                    IMPOSSIBLE : cargo absent

L'archive ne contient pas .git; git status/validation du tag n'est donc pas disponible dans ce sandbox.

Aucun cargo tree de v0.2.7 n'a été fourni dans le log opérateur de cette session. Les deux graphes imposés par le prompt restent donc un gate opérateur avant commit de pre.001 :

cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates

4. État réel hérité de v0.2.7

4.1 HTTP à ne pas régresser

Le contrat stable reste :

52/52 méthodes HTTP courantes typées
14/14 méthodes historiques Deprecated/Removed conservées
KSP-TRANSPORT-007 appliqué
write submissions sans resend après dispatch ambigu

4.2 WebSocket standard publié

Le runtime stable expose neuf familles :

Account
Block
Logs
Program
Root
Signature
Slot
SlotsUpdates
Vote

avec les paires exactes subscribe/unsubscribe et la partition :

stable   : Account, Logs, Program, Root, Signature, Slot
unstable : Block, SlotsUpdates, Vote

Le moteur possède déjà : actor unique propriétaire du socket, pending JSON-RPC borné, queues bornées, local IDs stables, remote IDs internes/remappables, reconnect fini, resubscribe déterministe, cleanup late ACK, backpressure isolée, continuity_gap_count, one-shot Signature et close().await borné.

4.3 Contrats publics utiles

WsProtocolKind est #[non_exhaustive] mais ne contient que :

SolanaStandard -> "solana_standard"

WsEndpointSettings possède déjà le conteneur commun nécessaire :

name
enabled
provider
cluster
protocol kind
WsEndpointUrl redacted
WsSessionSettings

WsSubscriptionKind est lui aussi non exhaustif et centralise pour les neuf familles les triplets :

subscribe method
unsubscribe method
notification method

WsSession::subscribe_typed est interne à la crate et constitue le point naturel de contrôle de capability avant émission JSON-RPC.

4.4 Config V2

Le document stable conserve :

format_version = 2
retry
ws_defaults
default_profile
profiles[].endpoints[]
profiles[].ws_endpoints[].kind

Le schema et l'adapter n'acceptent aujourd'hui que :

solana_standard

La structure a été volontairement rendue extensible en 0.2.7; il n'est pas nécessaire de créer un nouveau conteneur provider.

5. Audit Helius officiel du 2026-08-23

5.1 Sources primaires utilisées

Sources Helius relues :

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/rpc/websocket/token-account-filtering
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/api-reference/rpc/websocket/slotsupdatessubscribe
https://www.helius.dev/docs/faqs/websockets
https://www.helius.dev/docs/api-reference/rpc/websocket/llms.txt
https://www.helius.dev/docs/llms.txt

Les documents llms.txt servent d'index et de source secondaire de rapprochement. Lorsqu'ils divergent d'une page de référence dédiée ou de la page exhaustive des méthodes, la divergence est enregistrée au lieu d'être résolue silencieusement.

5.2 Terminologie et endpoints

Décisions normatives :

nom produit courant      = LaserStream WebSocket
ancien nom               = Enhanced WebSockets, désormais intégré à LaserStream WebSocket
mainnet                  = wss://mainnet.helius-rpc.com/?api-key=...
devnet                   = wss://devnet.helius-rpc.com/?api-key=...
credential               = api-key en query URL, Secret
Gatekeeper beta          = hors 0.2.8
LaserStream gRPC         = distinct, hors 0.2.8

La FAQ Helius confirme que les anciens chemins Enhanced WebSockets redirigent vers la famille LaserStream WebSocket et que les méthodes standard/Helius passent par les mêmes endpoints par réseau.

5.3 Inventaire provider retenu

La page exhaustive LaserStream WebSocket Methods distingue :

standard supporté : account, logs, program, root, signature, slot
Helius extension   : transactionSubscribe
non supporté       : block, slotsUpdates, vote

transactionUnsubscribe n'est pas listé comme entrée séparée dans l'index des méthodes, mais la référence transactionSubscribe le documente explicitement avec :

method = transactionUnsubscribe
params = [remoteSubscriptionId]
result = true

et précise que quelques notifications in-flight peuvent encore arriver après l'unsubscribe.

5.4 Divergence slotsUpdatesSubscribe

Les sources Helius se contredisent :

  • la page exhaustive websocket-methods classe explicitement slotsUpdatesSubscribe/slotsUpdatesUnsubscribe dans Unstable Methods (Not Supported) ;
  • la page individuelle dit que la méthode est unstable et « may not always be supported » ;
  • le fichier websocket/llms.txt la place paradoxalement dans une section « Stable, Helius-supported » avant d'introduire une section de méthodes unstable non supportées.

Décision KSP du gate :

HeliusLaserStream + SlotsUpdates -> capability Unsupported, rejet avant I/O

Raison : la page exhaustive courante énonce le support provider le plus explicitement. Un futur réaudit peut changer cette décision si Helius harmonise sa documentation ou si une preuve live sûre l'infirme.

5.5 transactionSubscribe

Filtre documenté courant :

vote             Option<bool>
failed           Option<bool>
signature        Option<string>
accountInclude   Option<string[]>  max 50_000
accountExclude   Option<string[]>  max 50_000
accountRequired  Option<string[]>  max 50_000
tokenAccounts    none | balanceChanged | all

tokenAccounts étend la correspondance owner/ATA pour les adresses d'accountInclude; none équivaut à l'absence. Une valeur invalide reçoit actuellement -32602 côté provider. KSP doit rendre les trois valeurs représentables par type et ne pas exposer une string arbitraire.

Options documentées :

commitment                       processed | confirmed | finalized
encoding                         base58 | base64 | jsonParsed
transactionDetails               full | signatures | accounts | none
showRewards                      bool
maxSupportedTransactionVersion   integer

La référence impose maxSupportedTransactionVersion lorsque transactionDetails vaut accounts ou full.

Notification :

method = transactionNotification

La forme full illustrée contient :

transaction.transaction
transaction.meta
signature
slot
transactionIndex

La documentation officielle ne détaille pas avec la même précision la forme de résultat de chacun des quatre modes transactionDetails. KSP ne doit pas inventer ces formes. Le plan retient un contrat typé capable de représenter les formes prouvées et un fallback Unknown borné pour les formes/futures variantes non suffisamment documentées, sur le modèle déjà utilisé pour les variantes standard évolutives.

5.6 accountSubscribe / programSubscribe et notifyOn

Les références courantes de accountSubscribe et programSubscribe documentent notifyOn mais le marquent :

deprecated
no-op depuis Agave 4.2
suppression future annoncée

Décision : ne pas ajouter notifyOn aux DTOs KSP.

La FAQ et les indexes continuent d'employer l'expression « enhanced/filtered accountSubscribe », mais la page API courante et le guide accountSubscribe ne publient pas de wire provider-specific supplémentaire précis au-delà du contrat standard et du champ notifyOn devenu no-op.

Décision :

Account/Program sur HeliusLaserStream -> wrappers standard KSP réutilisés tels quels
nouveau DTO provider account/program -> non
notifyOn                              -> non exposé
extension account provider non spécifiée exactement -> reportée explicitement

Le report n'est pas un oubli : une surface provider ne sera ajoutée que lorsqu'une référence courante fournit un contrat wire exact et testable.

6. Matrice normative Helius WebSocket

Famille Paire Classe Support Helius retenu Paramètres/options utiles Notification Idle/credential Stratégie KSP/test
account accountSubscribe / accountUnsubscribe Solana standard Oui contrat standard ; notifyOn deprecated/no-op donc omis accountNotification ping provider ; api-key query wrapper 0.2.7 inchangé + fixture capability
block blockSubscribe / blockUnsubscribe Solana unstable Non aucune émission provider blockNotification théorique api-key query rejet capability avant I/O
logs logsSubscribe / logsUnsubscribe Solana standard Oui contrat standard logsNotification ping provider ; api-key query wrapper 0.2.7 inchangé
program programSubscribe / programUnsubscribe Solana standard Oui contrat standard ; notifyOn deprecated/no-op donc omis programNotification ping provider ; api-key query wrapper 0.2.7 inchangé + filtres existants
root rootSubscribe / rootUnsubscribe Solana standard Oui aucun paramètre rootNotification ping provider ; api-key query wrapper 0.2.7 inchangé
signature signatureSubscribe / signatureUnsubscribe Solana standard Oui contrat standard ; one-shot conservé signatureNotification ping provider ; api-key query wrapper 0.2.7 + fermeture terminale inchangée
slot slotSubscribe / slotUnsubscribe Solana standard Oui aucun paramètre slotNotification ping provider ; api-key query wrapper 0.2.7 inchangé
slotsUpdates slotsUpdatesSubscribe / slotsUpdatesUnsubscribe Solana unstable Non par page exhaustive ; docs divergentes aucune émission provider slotsUpdatesNotification théorique api-key query rejet avant I/O + canari divergence
vote voteSubscribe / voteUnsubscribe Solana unstable Non aucune émission provider voteNotification théorique api-key query rejet capability avant I/O
heliusTransaction transactionSubscribe / transactionUnsubscribe Helius extension Oui filtres + tokenAccounts; options complètes ci-dessus transactionNotification ping provider ; api-key query ; extension Developer+ d'après index nouveaux DTOs typed + fixtures exactes + actor existant

Statut provider de la surface standard :

6 paires standard supportées
3 paires standard explicitement non supportées
1 paire Helius transaction ajoutée

La compliance standard globale KSP reste toutefois 18/18 : les 18 opérations continuent d'exister et de fonctionner pour WsProtocolKind::SolanaStandard; le protocol Helius applique une capability matrix différente.

7. Décisions d'architecture du gate

7.1 Nouveau protocol kind

Retenir :

WsProtocolKind::HeliusLaserStream
as_str() = "helius_laserstream"
provider metadata attendu = "helius"

Pourquoi ne pas utiliser SolanaStandard + provider=helius : les capabilities et le heartbeat provider changent le comportement de session et l'ensemble de méthodes admissibles. Le discriminateur de protocole est précisément le contrat extensible préparé par 0.2.7.

provider reste une metadata ouverte et sûre ; il ne devient pas un second discriminateur implicite.

7.2 Pas de nouveau moteur

Le chemin reste :

WsEndpointSettings
 -> WsSession::connect
 -> actor existant
 -> subscribe_typed / registry
 -> local WsSubscriptionId
 -> remote id interne/remappable

Aucun HeliusWsClient, aucun second actor et aucun SDK Helius ne sont prévus.

7.3 Extension du registry de subscription

Retenir une nouvelle famille logique provider :

WsSubscriptionKind::HeliusTransaction
subscribe     = transactionSubscribe
unsubscribe   = transactionUnsubscribe
notification  = transactionNotification

Le nom public exact pourra rester provider-explicite pour ne pas faire passer transactionSubscribe pour une méthode Solana standard.

7.4 Capability validation avant I/O

Ajouter une matrice déterministe protocol kind x subscription kind avant construction/envoi du RPC :

SolanaStandard:
  Account Block Logs Program Root Signature Slot SlotsUpdates Vote -> allowed
  HeliusTransaction                                           -> rejected

HeliusLaserStream:
  Account Logs Program Root Signature Slot HeliusTransaction -> allowed
  Block SlotsUpdates Vote                                     -> rejected

Le rejet doit produire un code d'erreur sûr et stable sans URL/api-key/payload. Une erreur RPC provider reste possible pour des paramètres/quotas/plan runtime non déterministes et ne doit pas tuer la session physique sans raison.

7.5 DTOs transaction provider-specific

Créer des types dédiés, sans polluer les DTOs standard :

HeliusTransactionSubscribeFilter
HeliusTokenAccountsMode
HeliusTransactionEncoding
HeliusTransactionSubscribeOptions
HeliusTransactionNotification / variantes prouvées

Réutilisations possibles après vérification d'égalité sémantique :

SolanaCommitment
SolanaTransactionDetails
SolanaEncodedTransaction / types transaction wire communs compatibles
SolanaWireField<T>

HeliusTransactionEncoding doit rester restreint aux valeurs documentées Helius (base58, base64, jsonParsed) plutôt que de réexporter automatiquement toutes les valeurs d'un enum HTTP plus large.

Validation locale prouvable :

accountInclude.len()  <= 50_000
accountExclude.len()  <= 50_000
accountRequired.len() <= 50_000
accounts/full -> maxSupportedTransactionVersion requis

Ne pas inventer de limite agrégée, de minimum ou d'interaction non documentée.

7.6 Heartbeat/idle ownership

Helius annonce un timeout d'inactivité de 10 minutes et recommande des pings périodiques, généralement toutes les 3060 secondes / chaque minute.

Décision : heartbeat provider-owned dans l'actor existant, activé automatiquement pour HeliusLaserStream, sans devenir un champ public générique de WsSessionSettings dans cette release.

Politique cible :

intervalle nominal = 60 s
frame = WebSocket Ping control frame
actif uniquement quand la session est Active
annulé pendant close / terminal failure
réarmé après reconnect réussi
échec d'écriture -> chemin disconnect/reconnect existant
aucune boucle de reconnect infinie : budget 0.2.7 conservé
aucun secret/payload dans logs

Raison du choix : ce heartbeat est une exigence opérationnelle provider, pas une politique générique démontrée pour tous les protocoles. Une cadence configurable ne sera ajoutée que si un besoin réel apparaît.

Les réponses automatiques aux Ping entrants déjà acquises en 0.2.7 restent distinctes de ce Ping sortant périodique.

7.7 Config V2

Évolution retenue :

profiles[].ws_endpoints[].kind:
  solana_standard
  helius_laserstream

Aucun nouveau conteneur Config et aucun champ heartbeat n'est requis au gate.

Les filtres/options de transactionSubscribe sont des paramètres de subscription runtime ; ils n'appartiennent pas au profil endpoint Config.

7.8 Credentials

L'api-key Helius reste uniquement contenue dans l'URL résolue :

wss://mainnet.helius-rpc.com/?api-key=${KSP_SECRET_HELIUS_API_KEY}

Le nom exact de secret sera matérialisé en pre.003, sous le namespace secret KSP et avec .env.example sans vraie valeur. Transport ne lit jamais std::env; il reçoit seulement WsEndpointUrl, déjà redacted dans Debug et erreurs.

Aucun champ api_key n'est ajouté à WsEndpointSettings.

8. Threat model provider

8.1 Secret dans query URL

Risque : URL complète copiée dans Debug, erreur de handshake, logs tungstenite ou contexte KspError.

Mesures : conserver WsEndpointUrl opaque/redacted, erreurs mappées vers metadata sûre, canaris avec valeur secret reconnaissable et interdiction de l'observer dans Debug/Display/log context.

8.2 Heartbeat concurrent avec reconnect/close

Risque : timer continue après close, écrit sur ancien socket, déclenche reconnect parasite ou bloque l'actor.

Mesures : timer détenu par l'actor, sélectionné dans la boucle Active, reset/cancel avec le lifecycle, test temps raccourci déterministe par hook interne/test-only.

8.3 Late notifications et IDs distants

Helius documente des messages in-flight après transactionUnsubscribe. Le contrat KSP 0.2.7 est compatible : local unsubscribe gagne, remote id devient non routable et une notification tardive ne réactive pas la subscription.

8.4 Payload transaction volumineux

transactionDetails=full, rewards et metadata transaction peuvent produire des notifications nettement plus grosses que les familles standard légères.

Mesures : conserver max_message_size_bytes/max_frame_size_bytes, reject/reconnect borné sur frame oversized, notification queue par subscription et overflow isolé. Aucun payload brut dans snapshots/logs.

8.5 Filtres 50k

Trois listes indépendantes peuvent contenir jusqu'à 50 000 adresses chacune. Risques : mémoire de construction, clone inutile, sérialisation lourde et logs accidentels.

Mesures : validation de cardinalité avant I/O, pas de Debug affichant les listes, éviter les copies superflues et ne jamais projeter les adresses comme metadata de session.

8.6 Capability mismatch

Risque : envoyer block/slotsUpdates/vote à Helius puis interpréter Method not found comme panne session.

Mesure : capability validation locale déterministe. Les erreurs provider dynamiques restent des erreurs de subscription/request, pas une faillite du socket par défaut.

8.7 Continuité

LaserStream WebSocket ne reçoit aucune promesse KSP de replay historique. Après reconnect :

resubscribe oui
continuity_gap_count oui
backfill non
historical replay non
lossless non

Les capacités de replay de LaserStream gRPC sont hors scope.

9. Audit dépendances

Dépendances directes déjà présentes et versions stables observées au 2026-08-23 :

futures-util       0.3.34
tokio              1.53.1
tokio-tungstenite  0.30.0
reqwest             0.13.4

Les contraintes workspace (^0.3, ^1.53, ^0.30, ^0.13) restent compatibles avec ces versions. Aucun changement de manifest n'est justifié dans pre.001.

Verdict : aucune nouvelle dépendance.

Le moteur actuel sait déjà : WebSocket TLS, control Ping/Pong, timers Tokio, futures sink/stream, JSON serde. Un SDK Helius dupliquerait le moteur, introduirait des choix de lifecycle non KSP et n'est pas requis pour modéliser le wire.

Le graphe résolu/doublons doit encore être observé par les commandes opérateur cargo tree avant commit de cette prerelease.

10. Stratégie de tests

10.1 Gate principal : déterministe local

Prévoir des fixtures/local peers couvrant :

protocol capability matrix
transactionSubscribe serialization exacte
transactionUnsubscribe exact
transactionNotification method exact
ack/error RPC
50k/50k/50k bounds
maxSupportedTransactionVersion requirement
tokenAccounts exact enum
late notifications après unsubscribe
remote id remapping reconnect/resubscribe
provider RPC error sans session failure
heartbeat timer + cancellation
shutdown pendant heartbeat/reconnect
oversized frame/message
queue overflow isolé
URL/api-key redaction
public API canaries
Config -> Transport mapping
standard WS 18/18 non régressé
HTTP 52 + 14 non régressé

10.2 Smoke live Helius

Le live est opt-in et ne constitue pas la preuve principale de wire.

Stratégie retenue : composition Config -> Transport avec secret résolu par Config. Transport ne doit jamais faire std::env pour récupérer l'api-key.

Le smoke ne sera matérialisé qu'après le contrat Config de pre.003. En absence de credential opérateur sûr, la release peut rester déterministiquement conforme et documenter le smoke opérateur plutôt que de violer les frontières.

11. Questions explicitement reportées

forme provider-specific exacte de « enhanced/filtered accountSubscribe » non publiée clairement
modes transactionNotification non suffisamment documentés pour inventer leurs DTOs
Gatekeeper beta
provider metering/billing
LaserStream gRPC / replay
Yellowstone gRPC
pool/scheduler automatique de sessions
configuration publique arbitraire du heartbeat

Le premier point doit être réaudité à la compliance finale. Si Helius publie un wire exact pendant 0.2.8, le forecast peut ajouter une tranche dédiée ; il ne doit pas être injecté silencieusement dans un DTO standard.

12. Sizing et forecast recalibré

L'audit réduit le scope par rapport au forecast initial : notifyOn ne doit pas être implémenté et aucune extension account/program exacte supplémentaire n'est actuellement spécifiable. La difficulté se concentre sur transactionSubscribe, capability validation et heartbeat provider.

Prévision souple recalibrée :

pre.001  audit actuel + matrice + architecture + threat model + dependencies + sizing
         preuves : ce plan + validation/011 + delta ; graphes Cargo opérateur requis ; aucun runtime Helius

pre.002  WsProtocolKind::HeliusLaserStream + WsSubscriptionKind::HeliusTransaction
         + capability matrix + erreurs/redaction/public canaries
         preuves : aucun second client ; 6 standard Helius admis, 3 standard Helius rejetés avant I/O

pre.003  Config V2 helius_laserstream + schema/fixtures + mapping Config -> Transport
         + stratégie de secret Helius
         preuves : V1/V2 backward, unknown kind rejeté, URL secret redacted, aucune dépendance inverse

pre.004  transactionSubscribe request typed + filters/options/tokenAccounts + transactionUnsubscribe
         preuves : wire exact, bounds 50k, max version conditionnel, ack/error fixtures, aucune string raw publique

pre.005  transactionNotification typed + actor integration + reconnect/resubscribe/unsubscribe races
         preuves : formes officielles prouvées, fallback borné, remote/local remap, late notification ignorée

pre.006  heartbeat Helius 60s + interaction control frames/reconnect/shutdown
         preuves : tests temporels locaux déterministes, cancellation bornée, échec Ping -> lifecycle existant

pre.007  provider adversarial lifecycle + payload/backpressure + security
         preuves : provider RPC error isolée, oversized, queue overflow, secret canaries, mismatch capability

pre.008  compliance Helius + non-régression standard 18/18 + HTTP 52/14 + Config/API canaries
         preuves : matrice rapprochée source par source, account/program standard inchangés, aucun scope silencieux

pre.009  smoke Helius opt-in si credential/config sûrs + README/USAGE + audit dependencies/duplicates
         preuves : smoke sans secret versionné si réalisable ; cargo tree direct + duplicates ; docs version-neutral

pre.010  validation workspace finale + fermeture plan/matrice/indexes + prompt 0.2.9
         preuves : workspace complet vert, docs cohérentes, dépendances finales auditées, prompt suivant autonome

rel.001  publication stable stricte

Budget nominal : chaque tranche vise environ 1520 minutes de travail effectif.

Critères de split/addition :

  • une tranche dépasse réellement ~20 minutes parce que notification decoding ou lifecycle cache plusieurs problèmes indépendants ;
  • Helius publie une nouvelle surface provider WebSocket normative avant le gate final ;
  • la forme exacte de plusieurs modes transactionDetails nécessite une investigation distincte ;
  • la stratégie live impose une surface d'intégration qui n'existe pas encore ;
  • un défaut du moteur standard doit être corrigé séparément plutôt que masqué dans une tranche provider.

pre.010 n'est pas une deadline. Des pre.011+ ou fixes seront ajoutés si nécessaire.

13. Verdict du gate pre.001

Décisions fermées

base stable autoritaire                     confirmé
surface officielle Helius actuelle          auditée
terminologie LaserStream WebSocket           clarifiée
protocol kind                               HeliusLaserStream / helius_laserstream
moteur                                      WsSession actor existant réutilisé
standard Helius                             6 paires supportées / 3 rejetées
transaction pair                            transactionSubscribe / transactionUnsubscribe
transaction notification                    transactionNotification
transaction filters/options                 inventoriés, tokenAccounts inclus
notifyOn                                    deprecated no-op, non exposé
account/program provider extras             report explicite faute de wire exact courant
capability validation                       avant I/O
heartbeat                                   actor provider-owned, 60s cible
Config                                      V2 kind addition, pas de nouveau conteneur
credential                                  URL Secret résolue par Config, jamais env direct Transport
new dependency                              aucune
historical/lossless replay                   aucune promesse
forecast                                    recalibré pre.001 -> pre.010

Point restant avant commit

Le gate n'est pas déclaré entièrement positif dans ce sandbox tant que les deux graphes Cargo obligatoires n'ont pas été exécutés par l'opérateur :

cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates

Aucun code provider ne doit commencer avant cette preuve. Si les graphes ne révèlent pas de dérive incompatible, pre.001 peut être validé/commité et pre.002 ouvrir le runtime provider.