v0.2.8-pre.001

This commit is contained in:
2026-08-23 12:36:54 +02:00
parent 4d77b607ea
commit f0865d5137
8 changed files with 1241 additions and 10 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 216
# version: 217
[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"
version = "0.2.8-pre.1"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

268
deltas/0.2.8/pre.001.md Normal file
View File

@@ -0,0 +1,268 @@
<!-- file: deltas/0.2.8/pre.001.md -->
<!-- version: 1 -->
# Delta `0.2.8-pre.001` — audit/sizing Helius LaserStream WebSocket
## 1. Base requise et vérifiée
Archive autoritaire fournie :
```text
khadhroony-solana-project-v0.2.7-full-from-gitea.zip
```
État vérifié :
```text
workspace.package.version = 0.2.7
deltas/0.2.7/rel.001.md présent
prompts/013-V0_2_8_START_PROMPT.md présent
metadata .git absente de l'archive
```
Cette livraison ouvre :
```text
workspace.package.version = 0.2.8-pre.1
commit attendu = v0.2.8-pre.001
aucun tag prerelease
```
## 2. Objet
`pre.001` est strictement le gate **audit + brainstorming + sizing** de `0.2.8 — Helius LaserStream WebSocket`.
Il ne modifie :
```text
aucun fichier Rust
aucun schema/config runtime
aucune dependency
aucun README/USAGE Transport
aucun secret/environment runtime
```
Il crée le plan durable, ouvre la matrice de validation, synchronise les index et recalcule la prévision souple.
## 3. Baseline acquise
Preuve opérateur jointe avant ouverture :
```text
cargo fmt --all OK
python3 scripts/audit_rust_workspace_rules.py OK / clean
cargo check --workspace OK
cargo clippy --workspace --all-targets OK
cargo test --workspace OK
```
Le sandbox de préparation a aussi exécuté :
```text
python3 scripts/audit_rust_workspace_rules.py OK
```
mais ne contient pas `cargo`; il ne déclare donc aucun gate Cargo local réussi.
Les graphes requis n'étaient pas présents dans le log opérateur et restent à exécuter avant commit :
```bash
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
```
## 4. Résultat de l'audit Helius du 2026-08-23
Terminologie/endpoints :
```text
produit courant = LaserStream WebSocket
Enhanced WebSockets = ancien nom intégré au produit courant
mainnet = wss://mainnet.helius-rpc.com/?api-key=...
devnet = wss://devnet.helius-rpc.com/?api-key=...
api-key = Secret query credential
LaserStream gRPC / Gatekeeper beta = hors scope
```
Surface retenue :
```text
Helius supporte les paires standard :
account, logs, program, root, signature, slot
Helius ne supporte pas d'après l'index exhaustif :
block, slotsUpdates, vote
Helius extension :
transactionSubscribe
transactionUnsubscribe
notification = transactionNotification
```
La documentation Helius diverge sur `slotsUpdates`; l'index exhaustif `LaserStream WebSocket Methods` le classe explicitement parmi les méthodes unstable non supportées, tandis que `websocket/llms.txt` le place aussi dans une section « stable ». Le gate retient **non supporté** et exige un rejet KSP avant I/O pour `HeliusLaserStream`.
`transactionSubscribe` expose actuellement :
```text
vote
failed
signature
accountInclude <= 50_000
accountExclude <= 50_000
accountRequired <= 50_000
tokenAccounts = none | balanceChanged | all
commitment
encoding = base58 | base64 | jsonParsed
transactionDetails = full | signatures | accounts | none
showRewards
maxSupportedTransactionVersion
```
`maxSupportedTransactionVersion` est requis par la référence lorsque `transactionDetails` vaut `accounts` ou `full`.
`notifyOn` est toujours visible dans les références account/program mais est désormais **deprecated et no-op depuis Agave 4.2**. Il ne sera pas ajouté à KSP.
La documentation continue de parler d'« enhanced/filtered accountSubscribe » sans publier, dans les références courantes auditées, un wire provider supplémentaire assez exact pour une API typed. Cette capacité est reportée explicitement au lieu d'être inventée.
## 5. Décisions du gate
```text
WsProtocolKind cible = HeliusLaserStream
wire/config string = helius_laserstream
provider metadata = helius
session actor = WsSession existant, aucun second client
new subscription kind = HeliusTransaction
provider capability = validation déterministe avant I/O
Helius standard support = Account Logs Program Root Signature Slot
Helius standard reject = Block SlotsUpdates Vote
notifyOn = non exposé
tokenAccounts = enum provider typed
heartbeat = actor Helius-only, cible 60 s
Config = ajout kind V2, même ws_endpoints[]
credential = URL résolue par Config derrière WsEndpointUrl
new dependency = aucune
WebSocket historical replay= aucune promesse
```
## 6. Threat model retenu
Points couverts par le plan :
```text
api-key dans query URL et erreurs handshake
heartbeat concurrent avec reconnect/close
late messages après transactionUnsubscribe
remote ids transitoires
provider capability mismatch
provider RPC errors sans session death automatique
transaction payload volumineux
3 listes de filtres jusqu'à 50k chacune
queue/frame/message bounds
unknown provider fields/modes de notification
continuity gaps après reconnect
```
## 7. Forecast recalibré
Le forecast initial `pre.001 -> pre.011` est resserré car `notifyOn` n'est pas une capacité utile et aucun wire account/program provider additionnel précis n'est actuellement publiable.
Forecast courant :
```text
pre.001 audit/sizing/matrice
pre.002 protocol descriptor + subscription kind + capability/redaction
pre.003 Config V2 helius_laserstream + secret strategy
pre.004 transactionSubscribe/unsubscribe request/filter/options
pre.005 transactionNotification + reconnect/resubscribe/unsubscribe races
pre.006 heartbeat/idle lifecycle
pre.007 adversarial provider/security/backpressure
pre.008 compliance + WS 18/18 + HTTP 52/14 + Config canaries
pre.009 live smoke opt-in si sûr + README/USAGE + cargo graphs
pre.010 workspace final + docs/matrix + prompt 0.2.9
rel.001 stable
```
Chaque tranche vise ~1520 minutes. Le forecast peut être scindé/étendu si une ambiguïté normative ou une difficulté de lifecycle le justifie. `pre.010` n'est pas une deadline.
## 8. Fichiers ajoutés
```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
```
## 9. Fichiers modifiés
```text
Cargo.toml
docs/000-README.md
docs/plans/000-README.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/validation/000-README.md
```
## 10. Fichiers volontairement inchangés
```text
ROADMAP.md
CHANGELOG.md
.env.example
config/**
crates/**
docs/architecture/**
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
```
`ROADMAP.md` possède déjà l'entrée globale `0.2.8`. Les documents/runtime Config/Transport ne changent pas avant le gate positif.
## 11. Validations réellement exécutées dans le sandbox de préparation
Avant modification :
```text
inspection archive/version/rel/prompt OK
lecture règles/architecture/plans/validation/code OK
réaudit officiel Helius actuel OK
inspection versions publiques dépendances OK
python3 scripts/audit_rust_workspace_rules.py OK
```
Après génération de l'overlay, l'audit Python a été réexécuté :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
```
## 12. Validations impossibles dans le sandbox
```text
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test --workspace
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
```
Cause : binaire `cargo` absent.
## 13. Validation opérateur requise avant commit
Appliquer l'overlay puis exécuter :
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
```
`cargo test --workspace` a déjà été fourni vert sur la base `v0.2.7`; `pre.001` ne change aucun code/runtime, mais il peut être rejoué si l'opérateur souhaite un checkpoint complet de la nouvelle version Cargo.
Le gate `pre.001` ne devient entièrement positif qu'après revue des deux graphes Cargo. Aucun `pre.002` runtime ne doit commencer avant cela.

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/000-README.md -->
<!-- version: 56 -->
<!-- version: 57 -->
# Plans KSP
@@ -23,6 +23,7 @@ Un plan décrit le périmètre, les décisions déjà acquises, les questions ou
- [`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 historique clôturé de la release stable `0.2.7 — WebSocket Solana standard`, ouvert par `pre.001`, exécuté jusquà `pre.014`, corrigé documentairement par `pre.014-fix.001` puis publié par `rel.001`; il conserve linventaire officiel 18 méthodes, le modèle session/subscription, le threat model, les preuves de compliance/smoke/dépendances et la préparation de `0.2.8`.
- [`015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md`](015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md) — plan actif de `0.2.8 — Helius LaserStream WebSocket`, ouvert par `pre.001`; il conserve laudit Helius du 23 août 2026, la matrice provider, le choix `HeliusLaserStream`, la stratégie transaction/heartbeat/Config/secrets et le forecast souple recalibré.
Le `pre.001` de chaque release fonctionnelle peut introduire son propre plan détaillé lorsque la release s'ouvre.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 82 -->
<!-- version: 83 -->
# Séquence des releases fonctionnelles KSP
@@ -465,7 +465,11 @@ La candidate atteint `pre.014` après matérialisation des 9 familles standard,
### `0.2.8` — Helius LaserStream WebSocket
Mission : étendre le moteur WebSocket standard avec les opérations/filtres/capabilities Helius ciblés sans copier le client.
Mission active : étendre le moteur WebSocket standard avec la surface Helius LaserStream WebSocket actuelle sans copier le client/session actor. Le gate `pre.001` est conservé dans [`015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md`](015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md) et la matrice active dans [`../validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md`](../validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md).
L'audit Helius du 23 août 2026 retient `helius_laserstream` comme nouveau protocol kind : les six familles standard `account/logs/program/root/signature/slot` réutilisent les wrappers publiés, tandis que `block/slotsUpdates/vote` sont rejetées avant I/O sur Helius selon l'index provider exhaustif. `transactionSubscribe`/`transactionUnsubscribe` et `tokenAccounts` constituent la nouvelle surface typed principale. `notifyOn`, désormais deprecated et no-op depuis Agave 4.2, n'est pas exposé. Un heartbeat Helius-only est planifié dans l'actor existant pour le timeout d'inactivité provider.
Le forecast souple est recalibré jusqu'à `pre.010` avant `rel.001`; le numéro final reste non contractuel. Aucun SDK Helius, aucune dépendance gRPC et aucun replay historique WebSocket ne sont introduits.
### `0.2.9` — Yellowstone gRPC standard

View File

@@ -0,0 +1,739 @@
<!-- file: docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md -->
<!-- version: 2 -->
# 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 :
```text
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 :
```text
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 :
```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
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` :
```text
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 :
```text
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` :
```bash
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 :
```text
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 :
```text
Account
Block
Logs
Program
Root
Signature
Slot
SlotsUpdates
Vote
```
avec les paires exactes subscribe/unsubscribe et la partition :
```text
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 :
```text
SolanaStandard -> "solana_standard"
```
`WsEndpointSettings` possède déjà le conteneur commun nécessaire :
```text
name
enabled
provider
cluster
protocol kind
WsEndpointUrl redacted
WsSessionSettings
```
`WsSubscriptionKind` est lui aussi non exhaustif et centralise pour les neuf familles les triplets :
```text
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 :
```text
format_version = 2
retry
ws_defaults
default_profile
profiles[].endpoints[]
profiles[].ws_endpoints[].kind
```
Le schema et l'adapter n'acceptent aujourd'hui que :
```text
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 :
```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/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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
method = transactionNotification
```
La forme `full` illustrée contient :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
HeliusTransactionSubscribeFilter
HeliusTokenAccountsMode
HeliusTransactionEncoding
HeliusTransactionSubscribeOptions
HeliusTransactionNotification / variantes prouvées
```
Réutilisations possibles après vérification d'égalité sémantique :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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 :
```text
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
```text
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 :
```text
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
```text
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 :
```bash
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.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/000-README.md -->
<!-- version: 20 -->
<!-- version: 21 -->
# Validations KSP
@@ -19,3 +19,4 @@ Documents :
- [`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 finale validée de la release stable `0.2.7`, ouverte par `pre.001`, fermée techniquement par `pre.014` puis publiée par `rel.001` : inventaire 9 subscribe + 9 unsubscribe, lifecycle borné, statuts unstable, compliance 18/18, non-régression HTTP 52+14, composition Config V2, smoke WebSocket Devnet et audit de dépendances.
- [`011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md`](011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md) — matrice active de `0.2.8`, ouverte par `pre.001` : support Helius par famille, `transactionSubscribe`/`transactionUnsubscribe`, `tokenAccounts`, `notifyOn` deprecated/no-op, capability validation, heartbeat provider, secrets et non-régressions Transport/Config.

View File

@@ -0,0 +1,216 @@
<!-- file: docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md -->
<!-- version: 2 -->
# Validation `0.2.8` — Helius LaserStream WebSocket
> **Statut : matrice ouverte par `0.2.8-pre.001`.** Les lignes normatives/sizing sont fermées ; les preuves runtime restent à matérialiser dans les prereleases suivantes. Le gate initial reste conditionné aux graphes Cargo opérateur absents du sandbox de préparation.
## 1. Références
```text
prompt prompts/013-V0_2_8_START_PROMPT.md
plan docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md
base stable v0.2.7 / deltas/0.2.7/rel.001.md
validation standard WS docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
HTTP compliance docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
KSP-TRANSPORT-007 docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md
```
Audit Helius initial : **2026-08-23**.
## 2. Matrice provider normative initiale
| Capability | Standard KSP | Helius doc actuelle | Décision `0.2.8` | Preuve finale attendue |
|-------------------------------------|----------------:|-------------------------------------------------------|-----------------------------|-------------------------------------------|
| `accountSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `logsSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `programSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `rootSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `signatureSubscribe` pair | oui | supporté | réutiliser standard | one-shot conservé |
| `slotSubscribe` pair | oui | supporté | réutiliser standard | exact wire + no regression |
| `blockSubscribe` pair | oui, unstable | non supporté Helius | rejet avant I/O | capability canary |
| `slotsUpdatesSubscribe` pair | oui, unstable | **docs divergentes ; index exhaustif = non supporté** | rejet avant I/O | canary + divergence documentée |
| `voteSubscribe` pair | oui, unstable | non supporté Helius | rejet avant I/O | capability canary |
| `transactionSubscribe` | non standard | extension Helius | ajouter typed | request/ack/notification fixtures |
| `transactionUnsubscribe` | non standard | explicitement documenté dans référence transaction | ajouter via handle | exact method + late message race |
| `tokenAccounts` | non standard | `none/balanceChanged/all` | ajouter typed | enum + serialization + invalid impossible |
| `notifyOn` account | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absence public DTO |
| `notifyOn` program | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absence public DTO |
| « enhanced accountSubscribe » extra | non standard | mentionné mais wire exact actuel non publié | report explicite | réaudit final |
| proactive heartbeat | absent standard | 10 min idle, ping recommandé | Helius-only actor heartbeat | deterministic timer tests |
| replay historique | absent standard | WebSocket sans contrat KSP de replay | interdit | docs/canary no promise |
## 3. Contrat `transactionSubscribe` à couvrir
### Filter
| Champ | Type | Limite/état | Statut |
|-------------------|--------------------|-------------------------------------|-------------|
| `vote` | bool optionnel | pas de limite locale supplémentaire | audit fermé |
| `failed` | bool optionnel | pas de limite locale supplémentaire | audit fermé |
| `signature` | string optionnelle | provider valide la signature | audit fermé |
| `accountInclude` | string[] | <= 50 000 | audit fermé |
| `accountExclude` | string[] | <= 50 000 | audit fermé |
| `accountRequired` | string[] | <= 50 000 | audit fermé |
| `tokenAccounts` | enum string | `none`, `balanceChanged`, `all` | audit fermé |
### Options
| Champ | Valeurs | Règle | Statut |
|----------------------------------|-------------------------------|-----------------------------------|-------------|
| `commitment` | processed/confirmed/finalized | réutilisation possible à vérifier | audit fermé |
| `encoding` | base58/base64/jsonParsed | enum Helius restreint | audit fermé |
| `transactionDetails` | full/signatures/accounts/none | complet | audit fermé |
| `showRewards` | bool | optionnel | audit fermé |
| `maxSupportedTransactionVersion` | integer | requis pour accounts/full | audit fermé |
### Notification
```text
method = transactionNotification
full documented result = transaction + signature + slot + transactionIndex
```
Le wire exact de tous les modes n'est pas suffisamment détaillé par la source officielle initiale. La validation finale exige :
- aucune forme inventée ;
- types précis pour les formes prouvées ;
- fallback borné/opaque pour une forme officielle non encore explicitée si nécessaire ;
- aucune projection brute dans logs/snapshots.
## 4. Matrice architecture
| Critère | Décision pre.001 | Preuve cible | État |
|-------------------------|--------------------------------------------|-------------------------------------------|----------------------|
| actor unique | réutiliser `WsSession` | aucun second client dans sources/manifest | décidé |
| protocol descriptor | `HeliusLaserStream` / `helius_laserstream` | public API + Config canary | décidé |
| provider metadata | `helius` reste metadata | snapshot sûr | décidé |
| Helius transaction kind | nouvelle variante provider explicite | registry triplet exact | décidé |
| capability before I/O | oui | local peer reçoit 0 request interdite | décidé |
| standard DTO pollution | interdite | public API/source canary | décidé |
| Config direction | Config -> Transport uniquement | ownership tests | décidé |
| heartbeat | actor Helius-only, 60s cible | deterministic timers | décidé |
| secret | URL query derrière `WsEndpointUrl` | redaction canaries | décidé |
| new Rust dependency | aucune | manifest/tree audit | décidé, tree pending |
## 5. Validation lifecycle/provider à construire
```text
[ ] transaction subscribe/ack exact
[ ] transaction unsubscribe/result exact
[ ] transaction notification dispatch exact
[ ] notification decode failure isole la logical subscription
[ ] provider RPC application error ne tue pas la session
[ ] late notification après unsubscribe ne réactive rien
[ ] reconnect invalide/remappe remote ids
[ ] resubscribe garde local id
[ ] unsubscribe pendant reconnect gagne
[ ] heartbeat n'écrit qu'en Active
[ ] heartbeat est annulé au close
[ ] heartbeat write failure suit reconnect borné
[ ] shutdown interrompt heartbeat/backoff
[ ] oversized inbound frame reste borné
[ ] queue overflow d'une transaction subscription n'affecte pas les autres
[ ] payload/filters/api-key absents de Debug/snapshots sûrs
```
## 6. Non-régressions obligatoires
```text
[ ] standard WebSocket 18/18 toujours comptabilisé pour SolanaStandard
[ ] partition standard unstable 3/9 inchangée
[ ] signature one-shot inchangée
[ ] HTTP current 52/52 inchangé
[ ] HTTP historical 14/14 inchangé
[ ] KSP-TRANSPORT-007 inchangé
[ ] Config V1 HTTP-only backward readable
[ ] Config V2 solana_standard backward readable
[ ] no Transport -> Config/Wallet/Store/Program/tracing direct
```
## 7. Security/redaction
```text
[ ] api-key absente de Debug WsEndpointUrl
[ ] api-key absente de Debug settings/session/subscription
[ ] api-key absente des KspError safe contexts
[ ] URL complète absente des snapshots
[ ] remote subscription id absent des snapshots publics
[ ] raw transaction payload absent des logs/snapshots
[ ] large filter addresses non loggées
[ ] provider error payload arbitraire non copié dans context
```
## 8. Dependencies
Audit web du 2026-08-23 :
```text
futures-util 0.3.34
tokio 1.53.1
tokio-tungstenite 0.30.0
reqwest 0.13.4
new dependency aucune prévue
```
Preuve locale `pre.001` :
```text
python3 scripts/audit_rust_workspace_rules.py = clean
cargo tree = impossible dans sandbox, cargo absent
```
Gate opérateur requis :
```bash
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
```
## 9. Smoke live
Statut initial : **non exécuté**.
Contrat cible : opt-in, Config résout l'api-key, Transport ne lit pas l'environnement. Aucun secret n'est versionné ou affiché. Un échec dû au plan/credential provider doit rester distinguable d'une panne du moteur.
## 10. Forecast courant
```text
pre.001 audit/sizing
pre.002 protocol + capability model
pre.003 Config V2 + secrets
pre.004 transaction request/unsubscribe
pre.005 transaction notification + lifecycle
pre.006 heartbeat
pre.007 adversarial/security/backpressure
pre.008 compliance/non-regression
pre.009 live smoke/docs/dependency graph
pre.010 final workspace/prompt 0.2.9
rel.001 stable
```
Le forecast est révisable ; seul le respect des gates autorise la publication.
## 11. Gate initial
```text
[x] base stable inspectée
[x] baseline opérateur disponible
[x] sources Helius courantes relues
[x] terminologie/endpoints/auth clarifiés
[x] surface standard supportée/non supportée inventoriée
[x] transactionSubscribe/unsubscribe inventoriés
[x] tokenAccounts inventorié
[x] notifyOn classé deprecated/no-op
[x] divergence slotsUpdates enregistrée et arbitrée explicitement
[x] protocol/capability architecture décidée
[x] heartbeat ownership décidé
[x] Config shape décidée
[x] credential strategy décidée
[x] aucune nouvelle dépendance justifiée
[x] forecast recalibré
[ ] cargo tree direct exécuté par opérateur
[ ] cargo tree duplicates exécuté par opérateur
```
Verdict : **gate normatif/architectural prêt ; gate `pre.001` entièrement positif après réception des deux graphes Cargo sans anomalie bloquante.**