diff --git a/deltas/0.2.8/pre.001-fix.001.md b/deltas/0.2.8/pre.001-fix.001.md new file mode 100644 index 0000000..1950988 --- /dev/null +++ b/deltas/0.2.8/pre.001-fix.001.md @@ -0,0 +1,269 @@ + + + +# Delta `0.2.8-pre.001-fix.001` — séparation des façades WebSocket et forecast visible + +## 1. Base requise + +Ce correctif s'applique exclusivement après : + +```text +0.2.8-pre.001 +workspace.package.version = 0.2.8-pre.1 +``` + +Il corrige le **plan et la matrice de validation** de `pre.001` avant toute implémentation de `pre.002`. + +Le correctif est documentaire uniquement. Conformément à `VER-ID-008` : + +```text +livraison = 0.2.8-pre.001-fix.001 +workspace.package.version = 0.2.8-pre.1 # inchangé +commit attendu = v0.2.8-pre.001-fix.001 +``` + +## 2. Motif du fix + +Le plan initial faisait porter à un `WsSession` public commun toute la surface WebSocket, puis utilisait une capability matrix pour rejeter avant I/O les méthodes standard non supportées par Helius. + +Après revue du code réel `v0.2.7`, cette forme est jugée trop permissive au niveau API : les neuf wrappers standard sont directement implémentés sur `WsSession`. Un endpoint Helius aurait donc pu être représenté par un type exposant publiquement `block_subscribe`, `slots_updates_subscribe` et `vote_subscribe`, même si ces appels étaient ensuite rejetés. + +Décision corrigée : + +```text +séparer les façades publiques par protocole +partager intégralement le moteur physique/lifecycle +rendre les méthodes provider non supportées absentes de la façade Helius +conserver une validation interne defense-in-depth +``` + +## 3. Architecture corrigée + +Cible : + +```text + WsSession + moteur physique partagé + actor/socket/reconnect/queues + │ + ┌────────────┴────────────┐ + ▼ ▼ + SolanaStandardWsSession HeliusLaserStreamWsSession + 9 familles 6 standard communes + + transaction + + heartbeat policy +``` + +### Surface standard + +```text +Account +Block +Logs +Program +Root +Signature +Slot +SlotsUpdates +Vote +``` + +### Surface Helius + +```text +Account +Logs +Program +Root +Signature +Slot +HeliusTransaction +``` + +Absents de la façade Helius : + +```text +Block +SlotsUpdates +Vote +``` + +Les DTOs standard réellement identiques restent partagés. Les DTOs Helius sont créés uniquement pour les contrats provider-specific (`transactionSubscribe`, `tokenAccounts`, notification transaction, etc.). + +`WsSession` reste compatible avec la surface standard publiée en `0.2.7`. La façade Helius ne doit fournir aucun escape hatch public (`inner`/`into_inner`) qui permettrait de récupérer un handle générique et de contourner sa surface. + +## 4. Capability matrix — rôle corrigé + +La capability matrix n'est plus la première barrière publique. Elle devient une protection interne : + +```text +API/façade correcte + -> méthodes impossibles absentes + -> validation descriptor/constructor avant I/O + -> actor commun +``` + +Matrice interne conservée : + +```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 +``` + +## 5. Gate Cargo désormais fermé + +Les commandes manquantes de `pre.001` ont été fournies par l'opérateur : + +```bash +cargo tree -p ksp-onchain-transport-lib +cargo tree -p ksp-onchain-transport-lib --duplicates +``` + +Résolution observée : + +```text +futures-util 0.3.34 +tokio 1.53.1 +tokio-tungstenite 0.30.0 +reqwest 0.13.4 +new Helius SDK aucun +``` + +Doublons ciblés : + +```text +syn 2.0.119 / 3.0.3 +webpki-roots 0.26.11 / 1.0.9 +``` + +Ils sont transitifs dans le graphe actuel et ne bloquent pas le gate. + +**Verdict : gate `pre.001` positif après ce fix documentaire.** + +## 6. Forecast souple recalibré + +Le forecast revient à `pre.001 -> pre.011` parce que la séparation de façade mérite une tranche propre et que les six wrappers standard supportés par Helius doivent être validés séparément de la mécanique de connexion commune. + +```text +pre.001 audit/sizing/matrice/dependencies +pre.001-fix.001 architecture de façades + gate Cargo + forecast visible + +pre.002 socle protocolaire : protocol kind + façades + connexion physique partagée +pre.003 6 familles standard Helius + absence typée Block/SlotsUpdates/Vote +pre.004 Config V2 helius_laserstream + secret strategy +pre.005 transactionSubscribe/unsubscribe request/filter/options/tokenAccounts +pre.006 transactionNotification + reconnect/resubscribe/unsubscribe races +pre.007 heartbeat/idle lifecycle +pre.008 adversarial provider/security/backpressure +pre.009 compliance + standard WS 18/18 + HTTP 52/14 + Config/API canaries +pre.010 live smoke opt-in si sûr + README/USAGE + dependency audit +pre.011 workspace final + fermeture docs/matrix/indexes + prompt 0.2.9 +rel.001 stable +``` + +Chaque tranche vise nominalement 15–20 minutes. Le plan contient désormais un tableau immédiatement visible avec objectif, preuves, budget et critères de split pour chaque tranche. + +`pre.011` n'est pas une deadline ; `pre.012+` ou des fixes sont ajoutés si nécessaire. + +## 7. Fichiers ajoutés + +```text +deltas/0.2.8/pre.001-fix.001.md +``` + +## 8. Fichiers modifiés + +```text +docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md +docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md +``` + +## 9. Fichiers volontairement inchangés + +```text +Cargo.toml +ROADMAP.md +CHANGELOG.md +.env.example +config/** +crates/** +docs/000-README.md +docs/plans/000-README.md +docs/validation/000-README.md +docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md +deltas/0.2.8/pre.001.md +``` + +Le delta `pre.001` publié reste immutable ; ce fix ne le réécrit pas. + +## 10. Validations et preuves + +### Réellement fournies par l'opérateur avant ce fix + +```text +baseline v0.2.7 : fmt/audit/check/clippy/test workspace = OK +cargo tree transport = exécuté +cargo tree transport --duplicates = exécuté +``` + +### Réellement exécutées dans l'environnement de préparation du fix + +```text +inspection du code public WsSession/WsSubscriptionKind/WsSessionSnapshot = OK +lecture VERSION_WORKFLOW.md pour VER-ID-008 = OK +contrôle overlay documentaire = OK +``` + +L'audit Rust workspace est réexécuté sur le workspace reconstitué après application de l'overlay lorsque le script est disponible. + +### Non exécutées pour ce fix documentaire + +```text +cargo fmt --all +cargo check --workspace +cargo clippy --workspace --all-targets +cargo test --workspace +``` + +Motif : aucun code/build/runtime/config n'est modifié par ce correctif et l'environnement de préparation ne fournit pas Cargo. + +## 11. Décisions prises + +```text +façades publiques séparées par protocole +moteur WsSession actor unique partagé +SolanaStandardWsSession = 9 familles standard +HeliusLaserStreamWsSession = 6 familles standard + transaction +Block/SlotsUpdates/Vote absents de la façade Helius +capability matrix conservée defense-in-depth +DTOs communs réutilisés si wire identique +DTOs Helius dédiés seulement aux divergences +pas d'escape hatch Helius vers raw WsSession +forecast visible et recalibré jusqu'à pre.011 +Cargo pre.1 inchangé car fix documentaire +``` + +## 12. Questions ouvertes laissées à `pre.002+` + +```text +forme interne minimale pour partager la connexion physique sans dupliquer l'actor +forme exacte des constructeurs des deux façades +extension minimale de WsSubscriptionKind/snapshot pour HeliusTransaction +forme typed des différents transactionDetails insuffisamment documentés +wire éventuel futur de enhanced/filtered accountSubscribe +``` + +Ces questions ne remettent pas en cause la frontière décidée : **surface publique séparée, moteur physique partagé**. + +## 13. Prochaine tranche + +```text +0.2.8-pre.002 +``` + +Mission : matérialiser uniquement le socle protocolaire et les façades/constructeurs autour du moteur `WsSession` existant. Ne pas commencer `transactionSubscribe` ni Config Helius dans cette tranche. diff --git a/docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md b/docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md index 22ba697..2aab115 100644 --- a/docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md +++ b/docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md @@ -1,13 +1,13 @@ - + # 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`. +> **Statut : gate `0.2.8-pre.001` positif, architecture rectifiée par `0.2.8-pre.001-fix.001`.** Le moteur physique `WsSession` de `0.2.7` reste unique et partagé, mais les surfaces publiques de protocole sont désormais séparées : `SolanaStandardWsSession` expose la surface Solana standard, tandis que `HeliusLaserStreamWsSession` n'expose que les opérations réellement supportées par Helius et les extensions Helius retenues. Le fix est documentaire et conserve `workspace.package.version = 0.2.8-pre.1`. -## 1. Objet et base vérifiée +## 1. Objet, base et état du gate -`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. +`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 moteur/session actor et sans confondre WebSocket avec LaserStream gRPC. Base autoritaire auditée : @@ -19,18 +19,230 @@ 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 : +`0.2.8-pre.001` a ouvert techniquement : ```text workspace.package.version = 0.2.8-pre.1 livraison = 0.2.8-pre.001 -commit attendu = v0.2.8-pre.001 +``` + +Le correctif documentaire courant est : + +```text +livraison = 0.2.8-pre.001-fix.001 +workspace.package.version = 0.2.8-pre.1 # inchangé : documentation uniquement +commit attendu = v0.2.8-pre.001-fix.001 aucun tag prerelease ``` -## 2. Sources internes relues et hiérarchie appliquée +Les deux graphes Cargo manquants lors de la préparation initiale ont été fournis par l'opérateur le 2026-08-23 : + +```text +cargo tree -p ksp-onchain-transport-lib exécuté +cargo tree -p ksp-onchain-transport-lib --duplicates exécuté +``` + +Constat : aucune dépendance Helius/SDK ajoutée ; les doublons visibles sont transitifs (`syn` 2/3 et `webpki-roots` 0.26/1.0) et ne constituent pas une anomalie bloquante de `pre.001`. + +**Verdict courant : gate `pre.001` positif.** `pre.002` peut commencer après commit de ce fix. + +## 2. Décision structurante de `pre.001-fix.001` — séparer les surfaces, pas le moteur + +La première version du plan prévoyait un unique `WsSession` public exposant toutes les méthodes standard et une matrice de capabilities rejetant à l'exécution les méthodes incompatibles avec Helius. + +Cette approche est remplacée par une séparation plus forte : **les méthodes impossibles pour un protocole doivent être absentes de sa façade publique**. + +Architecture cible : + +```text + moteur physique commun + WsSession + actor/socket/reconnect/queues + pending/remapping/backpressure/close + │ + ┌───────────────┴────────────────┐ + │ │ + ▼ ▼ + SolanaStandardWsSession HeliusLaserStreamWsSession + façade protocole standard façade protocole Helius + │ │ + 9 familles standard 6 familles communes + + transaction + + policy heartbeat +``` + +Principe : + +```text +ce qui est dupliqué/séparé : + façade publique de protocole + méthodes disponibles + policy/capabilities du protocole + DTOs provider-specific lorsque le wire diverge + heartbeat/provider behavior + +ce qui reste partagé : + socket physique + actor unique + command queue / pending JSON-RPC + WsSubscription + local/remote IDs et remapping + reconnect/resubscribe machinery + backpressure + shutdown + snapshots/redaction + DTOs wire réellement identiques +``` + +Aucun `HeliusWsClient`, aucun second actor et aucune copie du lifecycle physique ne sont autorisés. + +### 2.1 Surface `SolanaStandardWsSession` + +La façade standard expose exactement les neuf familles acquises en `0.2.7` : + +```text +account +block +logs +program +root +signature +slot +slotsUpdates +vote +``` + +Les 18 opérations standard restent donc présentes et testées : 9 subscribe + 9 unsubscribe. + +### 2.2 Surface `HeliusLaserStreamWsSession` + +La façade Helius expose uniquement : + +```text +account +logs +program +root +signature +slot +transaction +``` + +Elle **n'expose pas** : + +```text +block +slotsUpdates +vote +``` + +L'objectif est qu'un appel du genre : + +```text +helius.block_subscribe(...) +``` + +soit absent de l'API Helius et donc impossible à écrire contre la façade Helius, plutôt que simplement rejeté après construction d'une requête. + +La validation runtime avant I/O reste conservée en défense en profondeur pour les constructeurs, descriptors internes et chemins de compatibilité. + +### 2.3 Compatibilité de `WsSession` publié en `0.2.7` + +`WsSession` est déjà public et ses wrappers standard sont déjà stabilisés. `0.2.8` ne les supprime pas et ne casse pas les consommateurs existants. + +Décision cible : + +```text +WsSession + reste le handle/moteur physique partagé + conserve la compatibilité publique standard publiée en 0.2.7 + ne devient pas l'entrée publique Helius générique + +SolanaStandardWsSession + nouvelle façade explicite/recommandée pour le protocole standard + délègue au même WsSession + +HeliusLaserStreamWsSession + nouvelle façade Helius + contient/délègue à un WsSession privé + n'expose aucun getter/into_inner permettant de contourner sa surface en 0.2.8 +``` + +Le chemin public historique `WsSession::connect` doit rester compatible avec `SolanaStandard`. Lors de l'introduction de `HeliusLaserStream`, il ne doit pas permettre d'obtenir un `WsSession` générique Helius puis d'appeler une méthode standard non supportée. Le socle de `pre.002` doit donc extraire/réutiliser un chemin de connexion physique interne partageable, tout en gardant un garde protocolaire sur les constructeurs publics. + +### 2.4 DTOs communs versus DTOs Helius + +Les six familles communes réutilisent les DTOs standard lorsque le wire et la sémantique sont réellement identiques : + +```text +account +logs +program +root +signature +slot +``` + +Ne pas créer artificiellement `HeliusAccountNotification`, `HeliusLogsNotification`, etc. si ces types seraient des copies strictes des types standard. + +Créer des types Helius distincts dès que le contrat diverge ou n'existe pas en standard : + +```text +HeliusTransactionSubscribeFilter +HeliusTokenAccountsMode +HeliusTransactionEncoding +HeliusTransactionSubscribeOptions +HeliusTransactionNotification / formes prouvées +``` + +Une option provider-specific ne doit jamais être injectée dans un DTO Solana standard pour éviter une duplication de façade. + +### 2.5 Kind de subscription et registry interne + +`WsSubscriptionKind` appartient au lifecycle/snapshot commun et non à la capacité d'invocation publique. Il peut être étendu de manière `#[non_exhaustive]` avec une variante provider-explicite pour `transaction` si cela minimise la rupture du snapshot existant. + +Le point obligatoire n'est pas de dupliquer cet enum à tout prix ; le point obligatoire est que : + +```text +la façade Helius ne puisse pas invoquer Block/SlotsUpdates/Vote +la façade standard ne puisse pas invoquer HeliusTransaction +le registry/actor interne reste unique et provider-neutral +``` + +Si `pre.002` montre qu'un descriptor interne distinct rend le snapshot plus propre sans rupture publique, cette forme peut être retenue. Aucun refactor ne doit toutefois remplacer une séparation de façade simple par une hiérarchie générique lourde. + +## 3. Prévision souple courante — vue immédiate + +Cette section est la **source visible du forecast courant**. Elle est mise à jour à chaque recalibrage important. Les détails de progression restent dans les deltas ; ce tableau n'est ni une deadline ni un changelog. + +| Livraison | Objectif principal | Preuves/gates attendus | Budget nominal | Split si… | +|-------------------|--------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|---------------:|--------------------------------------------------------------| +| `pre.001` | Audit Helius, matrice, threat model, dépendances, sizing | sources actuelles rapprochées ; baseline ; Cargo trees ; plan/validation | 15–20 min | audit normatif non fermable | +| `pre.001-fix.001` | Corriger l'architecture : façades séparées + forecast visible | plan/validation corrigés ; gate Cargo fermé ; aucun runtime | doc-only | — | +| `pre.002` | Socle protocolaire : `HeliusLaserStream`, façades standard/Helius, connexion physique partagée, guards | un seul actor ; constructeurs protocolaires ; compatibilité `WsSession` ; API canaries | 15–20 min | extraction du connect/lifecycle devient indépendante | +| `pre.003` | Surface Helius standard réellement supportée : 6 familles communes, absence des 3 unsupported | 6 wrappers Helius exacts ; `block/slotsUpdates/vote` absents de la façade ; standard 9/9 intact | 15–20 min | une famille commune diverge réellement du wire standard | +| `pre.004` | Config V2 `helius_laserstream` + schema/fixtures + secret mapping | V1/V2 backward ; Config -> façade correcte ; URL secret redacted ; aucune dépendance inverse | 15–20 min | stratégie secret/config exige un changement transversal | +| `pre.005` | `transactionSubscribe` request typed + filters/options/`tokenAccounts` + unsubscribe | wire exact ; limites 50k ; max version conditionnel ; ack/error ; API typed | 15–20 min | filtres/options cachent plusieurs contrats indépendants | +| `pre.006` | `transactionNotification` + actor integration + reconnect/resubscribe/unsubscribe races | formes prouvées ; remapping ; late notifications ; backpressure ciblée | 15–20 min | plusieurs modes de notification exigent un audit séparé | +| `pre.007` | Heartbeat Helius/idle + interaction reconnect/control frames/shutdown | timer déterministe ; cancellation ; échec Ping -> lifecycle existant ; budget reconnect fini | 15–20 min | timer/lifecycle révèle une modification générique du moteur | +| `pre.008` | Adversarial provider/security/backpressure | provider errors isolées ; oversized ; queue overflow ; secret/filter redaction | 15–20 min | un défaut générique `WsSession` mérite un fix/tranche propre | +| `pre.009` | Compliance Helius + non-régressions WS standard/HTTP/Config/API | matrice finale rapprochée ; standard 18/18 ; HTTP 52/14 ; firewall dépendances | 15–20 min | surface Helius change pendant la release | +| `pre.010` | Smoke Helius opt-in si sûr + README/USAGE + dependency audit | aucun secret versionné ; docs version-neutral ; `cargo tree` direct/duplicates | 15–20 min | surface d'intégration live sûre manque encore | +| `pre.011` | Validation workspace finale + fermeture docs/indexes + prompt `0.2.9` | workspace vert ; validation fermée ; prompt suivant autonome | 15–20 min | un gate reste rouge | +| `rel.001` | Publication stable stricte | tous critères de clôture verts | n/a | jamais forcé par le numéro | + +Règles de granularité : + +```text +chaque tranche vise environ 15–20 minutes de travail effectif +une tranche > 20 minutes est normalement scindée +une ambiguïté normative nouvelle peut créer une tranche supplémentaire +un fix peut être inséré après n'importe quelle prerelease +pre.011 n'est pas une deadline +la release continue en pre.012+ si un gate l'exige +``` + +## 4. Sources internes relues et hiérarchie appliquée Les sources internes obligatoires du prompt ont été relues depuis la base stable, notamment : @@ -80,25 +292,22 @@ config/schemas/std.transport.schema.json Décisions de workflow conservées : -- `pre.001` est audit + brainstorming + sizing ; +- `pre.001` reste audit + brainstorming + sizing ; +- ce fix corrige uniquement le design prévu par cette tranche ; - une prerelease non-fix synchronise toujours Cargo ; -- une tranche vise nominalement environ 15–20 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. +- un fix documentaire conserve la version Cargo de sa base ; +- `ROADMAP.md` reste global ; les détails vivent dans plan/validation/deltas ; +- `CHANGELOG.md` reste principalement réservé à la publication stable. -## 3. Baseline de démarrage +## 5. Baseline de démarrage et graphes Cargo -### 3.1 Preuve opérateur fournie sur `v0.2.7` +### 5.1 Baseline opérateur sur `v0.2.7` -Le log opérateur joint à la session enregistre, avant ouverture de `0.2.8` : +Le log opérateur fourni avant ouverture de `0.2.8` enregistre : ```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 +python3 scripts/audit_rust_workspace_rules.py OK / clean cargo check --workspace OK cargo clippy --workspace --all-targets OK cargo test --workspace OK @@ -106,29 +315,31 @@ 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 +### 5.2 Graphes fournis après application de `pre.001` -Le sandbox de préparation ne fournit pas `cargo`. Avant modification : +État observé : ```text -python3 scripts/audit_rust_workspace_rules.py OK -cargo fmt/check/clippy/tree IMPOSSIBLE : cargo absent +ksp-onchain-transport-lib = 0.2.8-pre.1 +futures-util = 0.3.34 +tokio = 1.53.1 +tokio-tungstenite = 0.30.0 +reqwest = 0.13.4 +new Helius dependency = aucune ``` -L'archive ne contient pas `.git`; `git status`/validation du tag n'est donc pas disponible dans ce sandbox. +`cargo tree --duplicates` ciblé montre uniquement des doublons transitifs attendus dans le graphe courant : -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 +```text +syn 2.0.119 / 3.0.3 +webpki-roots 0.26.11 / 1.0.9 ``` -## 4. État réel hérité de `v0.2.7` +Aucun doublon direct introduit par `0.2.8-pre.001`, aucun SDK Helius et aucune inversion de dépendance KSP ne sont observés. -### 4.1 HTTP à ne pas régresser +## 6. État réel hérité de `v0.2.7` -Le contrat stable reste : +### 6.1 HTTP à ne pas régresser ```text 52/52 méthodes HTTP courantes typées @@ -137,7 +348,7 @@ KSP-TRANSPORT-007 appliqué write submissions sans resend après dispatch ambigu ``` -### 4.2 WebSocket standard publié +### 6.2 WebSocket standard publié Le runtime stable expose neuf familles : @@ -153,7 +364,7 @@ SlotsUpdates Vote ``` -avec les paires exactes subscribe/unsubscribe et la partition : +Partition : ```text stable : Account, Logs, Program, Root, Signature, Slot @@ -162,15 +373,15 @@ 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 +### 6.3 Contrats publics utiles -`WsProtocolKind` est `#[non_exhaustive]` mais ne contient que : +`WsProtocolKind` est `#[non_exhaustive]` et ne contient en `v0.2.7` que : ```text SolanaStandard -> "solana_standard" ``` -`WsEndpointSettings` possède déjà le conteneur commun nécessaire : +`WsEndpointSettings` fournit déjà : ```text name @@ -182,19 +393,9 @@ WsEndpointUrl redacted WsSessionSettings ``` -`WsSubscriptionKind` est lui aussi non exhaustif et centralise pour les neuf familles les triplets : +`WsSession` est un handle `Clone` vers un actor unique et les wrappers standard sont implémentés directement sur ce type. Cette réalité explique la correction de `pre.001-fix.001` : la façade Helius ne doit pas être le même type public surchargé de méthodes incompatibles. -```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 : +### 6.4 Config V2 ```text format_version = 2 @@ -205,19 +406,15 @@ profiles[].endpoints[] profiles[].ws_endpoints[].kind ``` -Le schema et l'adapter n'acceptent aujourd'hui que : +Le schema et l'adapter n'acceptent actuellement 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. +## 7. Audit Helius officiel du 2026-08-23 -## 5. Audit Helius officiel du 2026-08-23 - -### 5.1 Sources primaires utilisées - -Sources Helius relues : +### 7.1 Sources primaires utilisées ```text https://www.helius.dev/docs/rpc/websocket @@ -234,15 +431,13 @@ 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. +Les documents `llms.txt` servent d'index et de source secondaire. 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. -### 5.2 Terminologie et endpoints - -Décisions normatives : +### 7.2 Terminologie et endpoints ```text nom produit courant = LaserStream WebSocket -ancien nom = Enhanced WebSockets, désormais intégré à LaserStream WebSocket +ancien nom = Enhanced WebSockets, 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 @@ -250,19 +445,15 @@ 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 : +### 7.3 Inventaire provider retenu ```text standard supporté : account, logs, program, root, signature, slot -Helius extension : transactionSubscribe +Helius extension : transactionSubscribe / transactionUnsubscribe 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 : +`transactionUnsubscribe` est documenté dans la référence `transactionSubscribe` avec : ```text method = transactionUnsubscribe @@ -270,27 +461,27 @@ params = [remoteSubscriptionId] result = true ``` -et précise que quelques notifications in-flight peuvent encore arriver après l'unsubscribe. +La référence précise que quelques notifications in-flight peuvent encore arriver après l'unsubscribe. -### 5.4 Divergence `slotsUpdatesSubscribe` +### 7.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. +- `websocket-methods` classe `slotsUpdatesSubscribe`/`slotsUpdatesUnsubscribe` parmi les méthodes unstable non supportées ; +- la page individuelle indique que la méthode est unstable et peut ne pas être supportée ; +- `websocket/llms.txt` la place aussi dans une section « Stable, Helius-supported ». -Décision KSP du gate : +Décision KSP : ```text -HeliusLaserStream + SlotsUpdates -> capability Unsupported, rejet avant I/O +HeliusLaserStreamWsSession n'expose pas SlotsUpdates ``` -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. +Une validation interne garde aussi un rejet avant I/O si un descriptor incompatible atteint le moteur par un chemin interne ou de compatibilité. -### 5.5 `transactionSubscribe` +### 7.5 `transactionSubscribe` -Filtre documenté courant : +Filtre courant : ```text vote Option @@ -302,9 +493,7 @@ accountRequired Option 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 : +Options : ```text commitment processed | confirmed | finalized @@ -314,7 +503,7 @@ showRewards bool maxSupportedTransactionVersion integer ``` -La référence impose `maxSupportedTransactionVersion` lorsque `transactionDetails` vaut `accounts` ou `full`. +`maxSupportedTransactionVersion` est requis lorsque `transactionDetails` vaut `accounts` ou `full`. Notification : @@ -322,21 +511,11 @@ Notification : method = transactionNotification ``` -La forme `full` illustrée contient : +La documentation ne détaille pas avec la même précision chacun des quatre modes de `transactionDetails`. KSP ne doit pas inventer ces formes : types précis pour les formes prouvées et fallback borné uniquement si nécessaire. -```text -transaction.transaction -transaction.meta -signature -slot -transactionIndex -``` +### 7.6 `accountSubscribe` / `programSubscribe` et `notifyOn` -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 : +`notifyOn` est documenté mais marqué : ```text deprecated @@ -344,49 +523,37 @@ no-op depuis Agave 4.2 suppression future annoncée ``` -Décision : **ne pas ajouter `notifyOn` aux DTOs KSP**. +Décision : ne pas l'ajouter 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. +Les pages continuent à employer « enhanced/filtered accountSubscribe » sans publier un wire provider-specific supplémentaire assez précis pour une API typed. Ce point reste reporté explicitement. -Décision : +## 8. Matrice normative Helius WebSocket + +| Famille | Paire | Classe | Support Helius retenu | Surface publique Helius | Paramètres/options utiles | Notification | Stratégie KSP/test | +|---------------------|-----------------------------------------------------|------------------|-----------------------|-------------------------|------------------------------------|---------------------------|----------------------------------------------------| +| `account` | `accountSubscribe` / `accountUnsubscribe` | Solana standard | Oui | présente | contrat standard ; `notifyOn` omis | `accountNotification` | DTO/wire standard partagé | +| `block` | `blockSubscribe` / `blockUnsubscribe` | Solana unstable | **Non** | **absente** | aucune émission provider | théorique | façade Helius sans méthode + guard interne | +| `logs` | `logsSubscribe` / `logsUnsubscribe` | Solana standard | Oui | présente | contrat standard | `logsNotification` | DTO/wire standard partagé | +| `program` | `programSubscribe` / `programUnsubscribe` | Solana standard | Oui | présente | contrat standard ; `notifyOn` omis | `programNotification` | DTO/wire standard partagé | +| `root` | `rootSubscribe` / `rootUnsubscribe` | Solana standard | Oui | présente | aucun paramètre | `rootNotification` | wrapper partagé | +| `signature` | `signatureSubscribe` / `signatureUnsubscribe` | Solana standard | Oui | présente | one-shot conservé | `signatureNotification` | wrapper partagé + terminal close | +| `slot` | `slotSubscribe` / `slotUnsubscribe` | Solana standard | Oui | présente | aucun paramètre | `slotNotification` | wrapper partagé | +| `slotsUpdates` | `slotsUpdatesSubscribe` / `slotsUpdatesUnsubscribe` | Solana unstable | **Non** | **absente** | aucune émission provider | théorique | façade Helius sans méthode + divergence documentée | +| `vote` | `voteSubscribe` / `voteUnsubscribe` | Solana unstable | **Non** | **absente** | aucune émission provider | théorique | façade Helius sans méthode + guard interne | +| `heliusTransaction` | `transactionSubscribe` / `transactionUnsubscribe` | Helius extension | Oui | présente | filtres/options/`tokenAccounts` | `transactionNotification` | DTOs Helius + actor partagé | + +Statut : ```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 +SolanaStandardWsSession : 9 familles / 18 opérations standard +HeliusLaserStreamWsSession : 6 familles standard supportées + 1 famille Helius ``` -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. +La compliance standard KSP reste **18/18** pour `SolanaStandard`. -## 6. Matrice normative Helius WebSocket +## 9. Décisions d'architecture détaillées -| 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 +### 9.1 Protocol kind Retenir : @@ -396,114 +563,65 @@ 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`. +Le discriminateur est nécessaire car la surface de méthodes et la policy heartbeat diffèrent du standard. -`provider` reste une metadata ouverte et sûre ; il ne devient pas un second discriminateur implicite. +### 9.2 Connexion et propriété du moteur -### 7.2 Pas de nouveau moteur - -Le chemin reste : +Cible de `pre.002` : ```text -WsEndpointSettings - -> WsSession::connect - -> actor existant - -> subscribe_typed / registry - -> local WsSubscriptionId - -> remote id interne/remappable +un seul code de création/spawn de l'actor physique +un seul type de socket physique +un seul registry pending/subscriptions +un seul lifecycle reconnect/backpressure/shutdown ``` -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 : +Les façades délèguent à ce moteur commun. Le mécanisme précis d'extraction du chemin physique est choisi en `pre.002` à partir du code réel, avec les invariants suivants : ```text -WsSubscriptionKind::HeliusTransaction -subscribe = transactionSubscribe -unsubscribe = transactionUnsubscribe -notification = transactionNotification +pas de clone du run_ws_session_actor +pas de second WsSessionCommand +pas de second snapshot model +pas de public escape hatch Helius -> raw standard WsSession ``` -Le nom public exact pourra rester provider-explicite pour ne pas faire passer `transactionSubscribe` pour une méthode Solana standard. +### 9.3 Capability validation defense-in-depth -### 7.4 Capability validation avant I/O - -Ajouter une matrice déterministe `protocol kind x subscription kind` avant construction/envoi du RPC : +La séparation de façade est la première barrière. Une matrice interne reste utile : ```text SolanaStandard: Account Block Logs Program Root Signature Slot SlotsUpdates Vote -> allowed - HeliusTransaction -> rejected + HeliusTransaction -> rejected HeliusLaserStream: Account Logs Program Root Signature Slot HeliusTransaction -> allowed - Block SlotsUpdates Vote -> rejected + 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. +Cette matrice sert aux guards de constructor/descriptor, aux canaries et à la protection interne ; elle ne remplace plus la séparation de l'API publique. -### 7.5 DTOs transaction provider-specific +### 9.4 Heartbeat/idle ownership -Créer des types dédiés, sans polluer les DTOs standard : +Helius annonce un timeout d'inactivité de 10 minutes et recommande des pings périodiques. -```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 -``` - -`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 30–60 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. +Décision : heartbeat provider-owned dans l'actor existant, activé pour `HeliusLaserStream`, sans champ public générique ajouté à `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 +frame = WebSocket Ping control frame +actif = session Active seulement +close/failure = timer annulé +reconnect réussi = timer réarmé +write failure = chemin disconnect/reconnect existant +budget reconnect = fini, inchangé ``` -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. +### 9.5 Config V2 -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 : +Évolution : ```text profiles[].ws_endpoints[].kind: @@ -511,75 +629,69 @@ profiles[].ws_endpoints[].kind: helius_laserstream ``` -Aucun nouveau conteneur Config et aucun champ heartbeat n'est requis au gate. +Les paramètres de `transactionSubscribe` restent runtime et n'appartiennent pas au profil endpoint Config. -Les filtres/options de `transactionSubscribe` sont des paramètres de subscription runtime ; ils n'appartiennent pas au profil endpoint Config. +### 9.6 Credentials -### 7.8 Credentials - -L'api-key Helius reste uniquement contenue dans l'URL résolue : +L'api-key reste uniquement 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. +Le nom final du secret est matérialisé avec Config. Transport ne lit jamais `std::env` et reçoit un `WsEndpointUrl` redacted. -Aucun champ `api_key` n'est ajouté à `WsEndpointSettings`. +## 10. Threat model provider -## 8. Threat model provider +### 10.1 Secret dans query URL -### 8.1 Secret dans query URL +Risque : fuite par `Debug`, handshake error, logs tungstenite ou contexte d'erreur. -Risque : URL complète copiée dans `Debug`, erreur de handshake, logs tungstenite ou contexte `KspError`. +Mesures : `WsEndpointUrl` opaque/redacted, mapping vers metadata sûre, canaris avec secret reconnaissable. -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. +### 10.2 Contournement de façade -### 8.2 Heartbeat concurrent avec reconnect/close +Risque nouveau identifié par le fix : obtenir un handle générique Helius puis appeler une méthode standard non supportée. -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 : +Mesures : ```text -resubscribe oui -continuity_gap_count oui -backfill non -historical replay non -lossless non +HeliusLaserStreamWsSession possède son inner privé +aucun inner()/into_inner() public en 0.2.8 +constructeur générique historique gardé standard-only +validation protocolaire interne avant I/O ``` -Les capacités de replay de LaserStream gRPC sont hors scope. +### 10.3 Heartbeat concurrent avec reconnect/close -## 9. Audit dépendances +Timer détenu par l'actor, actif seulement en `Active`, reset/cancel avec lifecycle, test déterministe par cadence raccourcie interne/test-only. -Dépendances directes déjà présentes et versions stables observées au 2026-08-23 : +### 10.4 Late notifications et IDs distants + +Après `transactionUnsubscribe`, les messages in-flight sont possibles. L'unsubscribe local gagne ; un remote ID tardif ne réactive pas la subscription. + +### 10.5 Payload transaction volumineux + +Conserver `max_message_size_bytes`, `max_frame_size_bytes`, queue bornée par subscription et absence de payload brut dans les logs/snapshots. + +### 10.6 Filtres 50k + +Valider chaque liste avant I/O, ne pas logguer les valeurs et éviter les clones inutiles. + +### 10.7 Continuité + +```text +reconnect oui +resubscribe oui +continuity_gap_count oui +backfill non +historical replay non +lossless WebSocket non +``` + +## 11. Audit dépendances + +Versions observées dans le graphe opérateur : ```text futures-util 0.3.34 @@ -588,22 +700,32 @@ 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 moteur courant sait déjà gérer TLS WebSocket, Ping/Pong, timers Tokio, futures sink/stream et JSON serde. Un SDK Helius dupliquerait des choix de lifecycle que KSP possède déjà. -Le graphe résolu/doublons doit encore être observé par les commandes opérateur `cargo tree` avant commit de cette prerelease. +## 12. Stratégie de tests -## 10. Stratégie de tests +### 12.1 Architecture/façades -### 10.1 Gate principal : déterministe local - -Prévoir des fixtures/local peers couvrant : +Prévoir : + +```text +public API canary SolanaStandardWsSession +public API canary HeliusLaserStreamWsSession +Helius facade sans block/slotsUpdates/vote +Solana facade sans transactionSubscribe +Helius facade sans escape hatch vers WsSession générique +WsSession historique standard toujours disponible +un seul actor/socket implementation path +constructeur protocolaire invalide rejeté avant I/O +``` + +L'absence d'une méthode peut être couverte par compile-fail doctest/canary sans ajouter de dépendance de test si cette forme reste compatible avec les règles Rust KSP. + +### 12.2 Helius transaction/lifecycle ```text -protocol capability matrix transactionSubscribe serialization exacte transactionUnsubscribe exact transactionNotification method exact @@ -619,121 +741,100 @@ 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 +### 12.3 Non-régressions ```text -forme provider-specific exacte de « enhanced/filtered accountSubscribe » non publiée clairement -modes transactionNotification non suffisamment documentés pour inventer leurs DTOs +standard WS 18/18 pour SolanaStandard +partition unstable 3/9 inchangée +signature one-shot inchangée +HTTP 52 current + 14 historical +KSP-TRANSPORT-007 +Config V1 HTTP-only backward readable +Config V2 solana_standard backward readable +no Transport -> Config/Wallet/Store/Program/tracing direct +``` + +## 13. Smoke live Helius + +Le live reste opt-in et secondaire par rapport aux fixtures déterministes. + +Stratégie : Config résout le secret et construit l'endpoint Helius ; Transport ne lit jamais l'environnement. Si aucune surface d'intégration sûre n'est disponible, le smoke opérateur peut rester documenté plutôt que d'introduire une dépendance inverse. + +## 14. Questions explicitement reportées + +```text +wire exact d'un éventuel enhanced/filtered accountSubscribe provider-specific +modes transactionNotification non suffisamment documentés Gatekeeper beta provider metering/billing LaserStream gRPC / replay Yellowstone gRPC pool/scheduler automatique de sessions configuration publique arbitraire du heartbeat +refonte générique WsSession

: non nécessaire en 0.2.8 ``` -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. +Une nouvelle preuve normative peut rouvrir un point et insérer une tranche ; aucun report ne doit disparaître silencieusement. -## 12. Sizing et forecast recalibré +## 15. Critères de split et de clôture -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. +Créer une tranche/fix supplémentaire si : -Prévision souple recalibrée : +- l'extraction du chemin physique de `WsSession` révèle un problème générique indépendant ; +- une des six familles Helius dites communes diverge réellement du standard ; +- plusieurs formes de notification transaction demandent des contrats séparés ; +- Helius modifie sa surface normative pendant la release ; +- le smoke live impose une intégration non disponible ; +- un gate final reste rouge après `pre.011`. + +La release ne passe stable que si : ```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 +surface Helius rapprochée source par source +façades protocolaires séparées +moteur WsSession/actor unique +unsupported Helius absent de la façade publique +transaction extension sans pollution des DTOs standard +standard WS 18/18 non régressé +HTTP 52/14 non régressé +Config -> Transport uniquement +credentials redacted +heartbeat borné/testé si implémenté +reconnect/resubscribe/backpressure/shutdown bornés +aucune promesse replay/lossless WebSocket +aucune nouvelle dépendance injustifiée +workspace complet vert +README/USAGE synchronisés +validation finale fermée +prompt 0.2.9 prêt ``` -Budget nominal : chaque tranche vise environ **15–20 minutes** de travail effectif. +## 16. Verdict après `pre.001-fix.001` -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 +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 +base stable autoritaire confirmé +surface Helius actuelle auditée +Cargo graph audité, non bloquant +protocol kind HeliusLaserStream / helius_laserstream +moteur physique WsSession actor unique, partagé +façade standard SolanaStandardWsSession +façade Helius HeliusLaserStreamWsSession +Helius standard exposé Account Logs Program Root Signature Slot +Helius standard absent Block SlotsUpdates Vote +Helius extension Transaction +DTOs communs réutilisés si wire identique +DTOs provider dédiés uniquement si divergence +capability guard defense-in-depth avant I/O +heartbeat actor provider-owned, 60s cible +Config V2 kind addition, même conteneur +credential URL Secret résolue par Config +new dependency aucune +historical/lossless replay aucune promesse +forecast visible et recalibré pre.001 -> pre.011 ``` -### 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. +**Gate `pre.001` positif. Prochaine tranche : `0.2.8-pre.002` — socle protocolaire et façades séparées.** diff --git a/docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md b/docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md index c46f0b0..eb11591 100644 --- a/docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md +++ b/docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md @@ -1,9 +1,9 @@ - + # 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. +> **Statut : gate `0.2.8-pre.001` positif ; architecture corrigée par `0.2.8-pre.001-fix.001`.** Les graphes Cargo opérateur sont reçus et non bloquants. La validation runtime à venir doit prouver deux façades protocolaires distinctes partageant un seul moteur `WsSession`, et non un `WsSession` Helius générique exposant des méthodes provider non supportées. ## 1. Références @@ -11,6 +11,8 @@ 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 +pre.001 deltas/0.2.8/pre.001.md +fix architecture deltas/0.2.8/pre.001-fix.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 @@ -18,31 +20,102 @@ KSP-TRANSPORT-007 docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AU Audit Helius initial : **2026-08-23**. -## 2. Matrice provider normative initiale +## 2. Gate `pre.001` et dependency graph -| 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 | +Baseline opérateur acquise : -## 3. Contrat `transactionSubscribe` à couvrir +```text +cargo fmt --all OK +python3 scripts/audit_rust_workspace_rules.py clean +cargo check --workspace OK +cargo clippy --workspace --all-targets OK +cargo test --workspace OK +``` -### Filter +Graphes requis reçus : + +```text +cargo tree -p ksp-onchain-transport-lib OK / inspecté +cargo tree -p ksp-onchain-transport-lib --duplicates OK / inspecté +``` + +Versions résolues observées : + +```text +futures-util 0.3.34 +tokio 1.53.1 +tokio-tungstenite 0.30.0 +reqwest 0.13.4 +``` + +Doublons ciblés visibles : + +```text +syn 2.0.119 / 3.0.3 +webpki-roots 0.26.11 / 1.0.9 +``` + +Verdict : doublons transitifs, aucune nouvelle dépendance Helius, aucune anomalie bloquante du gate. + +## 3. Matrice provider normative + +| Capability | Standard KSP | Helius doc actuelle | Décision `0.2.8` | Surface Helius attendue | Preuve finale attendue | +|------------------------------|----------------:|---------------------------------------------------|--------------------------|-------------------------|---------------------------------------| +| `accountSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression | +| `logsSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression | +| `programSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression | +| `rootSubscribe` pair | oui | supporté | réutiliser standard | présente | exact wire + no regression | +| `signatureSubscribe` pair | oui | supporté | réutiliser standard | présente | one-shot conservé | +| `slotSubscribe` pair | oui | supporté | réutiliser standard | présente | exact wire + no regression | +| `blockSubscribe` pair | oui, unstable | non supporté | ne pas exposer Helius | **absente** | API absence + guard interne avant I/O | +| `slotsUpdatesSubscribe` pair | oui, unstable | docs divergentes ; index exhaustif = non supporté | ne pas exposer Helius | **absente** | API absence + divergence documentée | +| `voteSubscribe` pair | oui, unstable | non supporté | ne pas exposer Helius | **absente** | API absence + guard interne avant I/O | +| `transactionSubscribe` | non standard | extension Helius | ajouter typed | présente | request/ack/notification fixtures | +| `transactionUnsubscribe` | non standard | documenté dans référence transaction | ajouter via handle | présente | exact method + late-message race | +| `tokenAccounts` | non standard | `none/balanceChanged/all` | ajouter typed | présente dans filter | enum + serialization | +| `notifyOn` account | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absente | absence DTO public | +| `notifyOn` program | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absente | absence DTO public | +| enhanced account extra | non standard | mentionné, wire exact non publié | report explicite | absente | réaudit final | +| proactive heartbeat | absent standard | 10 min idle, ping recommandé | Helius-only actor policy | interne | deterministic timer tests | +| replay historique | absent standard | pas de contrat WS KSP | interdit | absent | docs/canary no promise | + +## 4. Matrice des façades protocolaires + +### 4.1 Surface attendue + +| Famille | `SolanaStandardWsSession` | `HeliusLaserStreamWsSession` | DTO/wire | +|--------------------|:-------------------------:|:----------------------------:|--------------------| +| Account | oui | oui | partagé standard | +| Block | oui | **non** | standard seulement | +| Logs | oui | oui | partagé standard | +| Program | oui | oui | partagé standard | +| Root | oui | oui | partagé standard | +| Signature | oui | oui | partagé standard | +| Slot | oui | oui | partagé standard | +| SlotsUpdates | oui | **non** | standard seulement | +| Vote | oui | **non** | standard seulement | +| Helius Transaction | **non** | oui | provider-specific | + +### 4.2 Invariants architecture + +| Critère | Décision | Preuve cible | État | +|-------------------------------------|-----------------------------------------------|---------------------------------|--------| +| actor physique | un seul `WsSession` actor partagé | source/runtime canary | décidé | +| façade standard | `SolanaStandardWsSession` | public API canary | décidé | +| façade Helius | `HeliusLaserStreamWsSession` | public API canary | décidé | +| escape hatch Helius | aucun `inner()`/`into_inner()` public | API/source canary | décidé | +| generic Helius `WsSession::connect` | ne doit pas permettre de contourner la façade | invalid protocol pre-I/O canary | décidé | +| Helius unsupported | absent de la façade | compile-fail/API absence canary | décidé | +| standard Helius commun | délégation vers le même wire/actor | exact fixture | décidé | +| DTO duplication | seulement si wire/sémantique divergent | public/source audit | décidé | +| Config direction | Config -> Transport uniquement | ownership tests | décidé | +| heartbeat | Helius-only, actor commun | deterministic timers | décidé | +| secret | query URL derrière `WsEndpointUrl` | redaction canaries | décidé | +| new Rust dependency | aucune | manifest/tree audit | décidé | + +## 5. `transactionSubscribe` à couvrir + +### 5.1 Filter | Champ | Type | Limite/état | Statut | |-------------------|--------------------|-------------------------------------|-------------| @@ -54,7 +127,7 @@ Audit Helius initial : **2026-08-23**. | `accountRequired` | string[] | <= 50 000 | audit fermé | | `tokenAccounts` | enum string | `none`, `balanceChanged`, `all` | audit fermé | -### Options +### 5.2 Options | Champ | Valeurs | Règle | Statut | |----------------------------------|-------------------------------|-----------------------------------|-------------| @@ -64,38 +137,36 @@ Audit Helius initial : **2026-08-23**. | `showRewards` | bool | optionnel | audit fermé | | `maxSupportedTransactionVersion` | integer | requis pour accounts/full | audit fermé | -### Notification +### 5.3 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 +Validation finale : ```text +aucune forme inventée +types précis pour les formes prouvées +fallback borné si une forme officielle reste insuffisamment explicitée +aucun payload brut dans logs/snapshots +``` + +## 6. Validation lifecycle/provider à construire + +```text +[ ] un seul actor/socket implementation path +[ ] SolanaStandardWsSession public et constructible +[ ] HeliusLaserStreamWsSession public et constructible +[ ] WsSession historique standard reste compatible +[ ] Helius facade n'expose pas blockSubscribe +[ ] Helius facade n'expose pas slotsUpdatesSubscribe +[ ] Helius facade n'expose pas voteSubscribe +[ ] SolanaStandard facade n'expose pas transactionSubscribe +[ ] Helius facade n'expose aucun escape hatch vers le handle générique +[ ] protocol mismatch rejeté avant I/O +[ ] 6 familles standard Helius utilisent le wire standard exact [ ] transaction subscribe/ack exact [ ] transaction unsubscribe/result exact [ ] transaction notification dispatch exact @@ -114,7 +185,7 @@ Le wire exact de tous les modes n'est pas suffisamment détaillé par la source [ ] payload/filters/api-key absents de Debug/snapshots sûrs ``` -## 6. Non-régressions obligatoires +## 7. Non-régressions obligatoires ```text [ ] standard WebSocket 18/18 toujours comptabilisé pour SolanaStandard @@ -128,7 +199,7 @@ Le wire exact de tous les modes n'est pas suffisamment détaillé par la source [ ] no Transport -> Config/Wallet/Store/Program/tracing direct ``` -## 7. Security/redaction +## 8. Security/redaction ```text [ ] api-key absente de Debug WsEndpointUrl @@ -139,59 +210,38 @@ Le wire exact de tous les modes n'est pas suffisamment détaillé par la source [ ] 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 +[ ] façade Helius ne permet pas de contourner les capabilities par exposition du inner ``` ## 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. +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 lié au plan/credential provider doit rester distinguable d'une panne du moteur. ## 10. Forecast courant +Le forecast détaillé et normatif est visible dans la section 3 du plan. Résumé : + ```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 +pre.001 audit/sizing +pre.001-fix.001 façades séparées + gate Cargo fermé +pre.002 socle protocolaire/façades/connect partagé +pre.003 6 wrappers Helius communs + absence 3 unsupported +pre.004 Config V2 + secrets +pre.005 transaction request/unsubscribe +pre.006 transaction notification + lifecycle +pre.007 heartbeat +pre.008 adversarial/security/backpressure +pre.009 compliance/non-regression +pre.010 live smoke/docs/dependency graph +pre.011 final workspace/prompt 0.2.9 +rel.001 stable ``` -Le forecast est révisable ; seul le respect des gates autorise la publication. +Le forecast reste souple ; le numéro final n'est jamais un critère de clôture. -## 11. Gate initial +## 11. Gate initial après fix ```text [x] base stable inspectée @@ -203,14 +253,17 @@ Le forecast est révisable ; seul le respect des gates autorise la publication. [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] architecture corrigée : surfaces protocolaires séparées +[x] moteur WsSession/actor unique préservé +[x] stratégie de compatibilité WsSession 0.2.7 définie [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 +[x] forecast recalibré et rendu visible dans le plan +[x] cargo tree direct exécuté par opérateur +[x] cargo tree duplicates exécuté par opérateur +[x] doublons ciblés analysés comme transitifs/non bloquants ``` -Verdict : **gate normatif/architectural prêt ; gate `pre.001` entièrement positif après réception des deux graphes Cargo sans anomalie bloquante.** +Verdict : **gate `0.2.8-pre.001` positif. `pre.002` peut ouvrir le socle protocolaire/façades sans commencer prématurément `transactionSubscribe`.**