v0.2.9-pre.001-fix.001

This commit is contained in:
2026-08-24 09:17:30 +02:00
parent bdcab1e1a7
commit 3081bd1085
5 changed files with 560 additions and 370 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 86 -->
<!-- version: 87 -->
# Séquence des releases fonctionnelles KSP
@@ -363,11 +363,14 @@ Par défaut :
0.2.6 Wallet Desk
0.2.7 standard Solana WebSocket
0.2.8 Helius LaserStream WebSocket
0.2.9 Yellowstone gRPC standard foundation
0.2.10 off-chain price transport
0.2.11 price visualization desk + intégration prix dans Wallet Desk
0.2.12 interface/wire foundation
0.2.13 program-api foundation
0.2.9 Yellowstone gRPC engine + Solana standard + PublicNode
0.2.10 OrbitFlare Yellowstone gRPC
0.2.11 Helius LaserStream gRPC
0.2.12 eRPC Yellowstone gRPC (conditionnel après réaudit accès/capabilities)
0.2.13 off-chain price transport
0.2.14 price visualization desk + intégration prix dans Wallet Desk
0.2.15 interface/wire foundation
0.2.16 program-api foundation
```
`0.2.1-pre.001` a appliqué le gate de sizing et refusé le scope HTTP monolithique initial : l'inventaire du 2026-08-17 contient 52 méthodes courantes et 14 méthodes Deprecated historiques. Ce premier delta avait réparti la couverture typée sur `0.2.1``0.2.6`. `0.2.1-pre.001-fix.001` recalibre ensuite les 48 méthodes restantes sur trois releases complémentaires `0.2.2``0.2.4`, soit trois sessions nominales au maximum si chaque release utilise sa session complète. Si une release se clôt plus vite que prévu, la même session peut enchaîner la suivante après clôture complète de la précédente et nouveau gate de sizing positif. Un Wallet Desk utile doit pouvoir lire le solde du wallet : `getBalance` fait donc partie des quatre canaris de la foundation `0.2.1`, avant Wallet. Les transports live arrivent ensuite ; Interface/Program restent préparés avant les couches de données décodées.
@@ -471,31 +474,39 @@ Le réaudit final Helius du 23 août 2026 retient `helius_laserstream` comme pro
`pre.010` ferme README/USAGE, la stratégie smoke live architecture-safe et les graphes Cargo finaux ; `pre.011` ferme la candidate documentaire et prépare [`../../prompts/014-V0_2_9_START_PROMPT.md`](../../prompts/014-V0_2_9_START_PROMPT.md). `0.2.8-rel.001` publie ensuite cette surface stable sans nouvelle capacité runtime. Aucun SDK Helius, aucune dépendance gRPC et aucun replay historique WebSocket ne sont introduits.
### `0.2.9` — Yellowstone gRPC standard
### `0.2.9` — Yellowstone gRPC engine + standard Solana + PublicNode
Mission active : introduire un backend Yellowstone standard/provider-neutral dans `ksp-onchain-transport-lib`, distinct de HTTP et WebSocket. Le gate `pre.001` est conservé dans [`016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md`](016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md) et sa matrice dans [`../validation/012-V0_2_9_YELLOWSTONE_GRPC.md`](../validation/012-V0_2_9_YELLOWSTONE_GRPC.md).
Mission : construire un moteur client Yellowstone gRPC partagé dans `ksp-onchain-transport-lib`, exposer la façade Solana Yellowstone standard puis valider une première intégration concrète PublicNode Mainnet/Testnet sans recopier le moteur.
Le réaudit du 23 août 2026 corrige le snapshot du prompt : la release GitHub courante observée est `v15.1.2+solana.4.2.0`, tandis que les crates publiées restent `yellowstone-grpc-client 13.3.0` et `yellowstone-grpc-proto 12.6.0`. `0.2.9` retient la stratégie `yellowstone-grpc-proto` Apache-2.0 + client/lifecycle KSP autour de Tonic, et couvre `Subscribe`, les sept RPC unary standard retenus, les filtres Cuckoo/token actuels et les neuf variantes `SubscribeUpdate`. `SubscribeDeshred` reste hors scope comme extension Triton/pré-exécution.
Le `pre.001` est un gate de sizing : chaque prerelease vise 1520 minutes de travail effectif et la release complète doit rester clôturable dans une seule session. Si cette clôture devient incertaine, `0.2.9` est scindée avant implémentation lourde supplémentaire.
La Config cible une V3 séparant `grpc_endpoints` de HTTP/WS tout en conservant V1/V2 backward-readable. PublicNode/Allnodes-backed entre dans la release comme premier environnement live standard gratuit Mainnet/Testnet ; OrbitFlare suit comme smoke Devnet gratuit authentifié. Aucun adapter public provider-specific n'est créé pour eux. Tatum reste un fallback opérateur Mainnet à quota lifetime ; les offres gRPC payantes Helius/Shyft/Alchemy/NodeFlare ne deviennent pas des dépendances de validation.
La séparation cible reprend le modèle WebSocket : moteur physique partagé -> protocole standard -> adaptations provider. PublicNode est la première intégration provider ; une façade spécialisée n'est créée que si une différence réelle de capabilities/wire/lifecycle le justifie.
Forecast recalibré : `pre.002` deps/settings, `pre.003` TLS/metadata+unary, `pre.004` Subscribe commun, `pre.005` accounts/slots, `pre.006` transactions, `pre.007` blocks/meta/entry, `pre.008` lifecycle/backpressure, `pre.009` reconnect/replay, `pre.010` Config V3, `pre.011` live/compliance, `pre.012` clôture candidate/prompt suivant. Chaque tranche reste nominalement 1520 minutes et peut être scindée si le wire transaction/block, le replay ou le graphe de dépendances l'exige.
### `0.2.10``0.2.12` — providers Yellowstone
### `0.2.10` / `0.2.11` — Off-chain price + app
```text
0.2.10 OrbitFlare Yellowstone gRPC
0.2.11 Helius LaserStream gRPC
0.2.12 eRPC Yellowstone gRPC, conditionné à un accès exploitable et à un delta provider réel
```
`0.2.10` introduit `ksp-offchain-transport-lib` avec au minimum SOL/USD et SOL/EUR via une abstraction indépendante du premier provider.
Chaque release réutilise le moteur et le standard de `0.2.9`. Un provider qui ne diffère finalement que par son URL/configuration ne justifie ni second actor ni façade vide ; son gate peut réduire/fusionner le scope avant implémentation.
`0.2.11` ajoute une petite application desk de visualisation/validation. Après stabilisation de cette application spécialisée, la même release doit intégrer la capacité de prix offchain dans `ksp-app-wallet-desk` sans dupliquer la récupération/normalisation appartenant au composant spécialisé.
### `0.2.13` / `0.2.14` — Off-chain price + app
`0.2.13` introduit `ksp-offchain-transport-lib` avec au minimum SOL/USD et SOL/EUR via une abstraction indépendante du premier provider.
`0.2.14` ajoute une petite application desk de visualisation/validation. Après stabilisation de cette application spécialisée, la même release doit intégrer la capacité de prix offchain dans `ksp-app-wallet-desk` sans dupliquer la récupération/normalisation appartenant au composant spécialisé.
Metadata HTTP/IPFS/Arweave viendra au premier besoin Metadata réel.
### `0.2.12` — Interface foundation
### `0.2.15` — Interface foundation
`ksp-interface-lib` devient la façade wire officielle et expose une API publique wire utilisable par les implementations officielles et externes.
Aucune `ksp-interface-api` séparée n'est retenue pour l'instant.
### `0.2.13` — Program API foundation
### `0.2.16` — Program API foundation
Introduire `ksp-program-api`, sans suffixe `-lib`, comme contrat d'extension Program.

View File

@@ -1,9 +1,9 @@
<!-- file: docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md -->
<!-- version: 1 -->
<!-- version: 3 -->
# Plan `0.2.9` — Yellowstone gRPC standard/provider-neutral
# Plan `0.2.9` — moteur Yellowstone gRPC + standard Solana + PublicNode
> **Statut : `0.2.9-pre.001` — gate audit/sizing positif. Aucune implémentation gRPC lourde ni dépendance Yellowstone/Tonic n'est introduite dans cette tranche. La stratégie cible est `yellowstone-grpc-proto` publié + client/lifecycle KSP autour de Tonic, avec PublicNode comme premier smoke live Mainnet/Testnet et OrbitFlare comme second smoke Devnet authentifié.**
> **Statut : `0.2.9-pre.001-fix.001` — gate audit/sizing corrigé. `0.2.9` est bornée à un moteur client Yellowstone partagé, une façade Solana Yellowstone standard et une première intégration concrète PublicNode. Les autres providers Yellowstone sont sortis de la release et planifiés séparément. Chaque prerelease vise 1520 minutes de travail effectif et la release complète doit rester clôturable dans une seule session de chat.**
## 1. Objet, base et état d'ouverture
@@ -45,30 +45,32 @@ Transport -> Config interdit
Le gate est **positif avec scope borné**.
`0.2.9` peut raisonnablement porter :
`0.2.9` peut raisonnablement porter **trois niveaux distincts dans la même crate Transport** :
```text
backend Yellowstone gRPC paré
settings/runtime bounds gRPC
TLS + metadata générique et redacted
7 RPC unary du service Geyser courant hors SubscribeDeshred
Subscribe bidirectionnel standard
7 familles de filtres top-level
9 variantes SubscribeUpdate
DTOs KSP provider-neutral
backpressure/half-close/shutdown bornés
reconnect/resubscribe KSP-owned
from_slot + SubscribeReplayInfo avec observabilité gap/duplicate/equivocation
Config V3 dédiée gRPC, tout en lisant V1/V2
smokes live opt-in PublicNode puis OrbitFlare
compliance HTTP/WS/Helius non régressée
N1 moteur client Yellowstone gRPC partagé
channel/TLS/metadata, stream bidi, bounds, backpressure, shutdown, reconnect/replay observables
N2 façade protocolaire Solana Yellowstone standard
7 unary retenus + Subscribe standard + filters/updates typed provider-neutral
N3 première intégration provider : PublicNode / Allnodes-backed
Mainnet + Testnet, capabilities/profile/config + smokes live opt-in
sans duplication du moteur ni du wire standard
```
Sont explicitement exclus :
Le moteur est **Yellowstone-specific**, pas une abstraction gRPC universelle. Le serveur/plugin Geyser reste hors de KSP ; KSP implémente le client du protocole Yellowstone exposé par les providers.
La première intégration PublicNode peut rester volontairement mince si le provider n'ajoute aucun wire ou lifecycle propriétaire : l'objectif est de matérialiser la frontière provider, les capabilities et la validation live, pas de créer artificiellement un second actor/session. Un type/facade provider-specific public n'est justifié que si PublicNode impose une différence réelle de contrat.
Sont explicitement exclus de `0.2.9` :
```text
SubscribeDeshred et pré-exécution/deshred
adapters publics PublicNode/Allnodes/OrbitFlare/Tatum/Helius/Triton/etc.
OrbitFlare provider integration
Helius LaserStream gRPC provider integration
eRPC provider integration
Tatum/Triton/Chainstack/Shyft/autres providers
client autoreconnect upstream comme contrat public KSP
pool/scheduler automatique complexe de sessions gRPC
exactly-once / lossless / ordre global garanti
@@ -76,7 +78,7 @@ serveur Geyser/plugin validator
Store/workers/backfill historique
```
La présence de PublicNode et OrbitFlare **ne nécessite donc pas une couche provider-specific publique**. Ils entrent dans la release comme environnements d'interopérabilité et profils Config derrière le même backend Yellowstone standard.
Les providers suivants sont **des releases ultérieures**, comme Helius LaserStream WebSocket l'a été après le moteur WebSocket standard. Ils réutiliseront N1/N2 et n'ajouteront une façade spécialisée que lorsqu'une différence d'authentification, de capabilities, de wire, de keepalive, de replay ou de lifecycle le nécessite.
## 3. Sources internes relues
@@ -282,36 +284,35 @@ https://github.com/rpcpool/yellowstone-grpc/blob/master/LICENSING.md
https://docs.rs/crate/yellowstone-grpc-proto/latest
```
### 5.4 MSRV / build
### 5.4 Compatibilité toolchain / build
Observations pertinentes :
KSP suit la **Rust stable courante de l'opérateur** et ne documente pas de numéro Rust upstream comme objectif de projet. Le seul gate utile est opérationnel : les dépendances finalement retenues doivent compiler avec la stable courante utilisée par le workspace.
Éléments build à vérifier en `pre.002` :
```text
plugin release 15.1.2 Rust 1.96.1
tonic 0.14.6 rust-version 1.88
prost 0.14.x MSRV publié actuellement 1.85
proto crate 12.6.0 génération incluse dans la crate publiée
proto crate crate publiée/pré-générée ; pas de vendoring de .proto KSP
client KSP autour de Tonic features client/TLS minimales
protoc/build.rs aucun outil système ajouté sauf besoin démontré
```
Le build de `yellowstone-grpc-proto` utilise une chaîne de génération avec `protoc` vendored côté crate publiée ; KSP n'a donc pas à ajouter son propre `build.rs` ni à exiger un `protoc` système pour la stratégie B.
Le MSRV du **plugin Geyser** n'est pas le MSRV automatique du client KSP. Le gate technique final reste la toolchain réellement utilisée par le workspace et la compilation des dépendances choisies en `pre.002`.
Un minimum Rust déclaré par une dépendance n'est enregistré que s'il devient un **blocage réel** lors de la compilation ; il n'est pas suivi comme métrique de release.
## 6. Matrice du service `Geyser` courant
Le proto publié `yellowstone-grpc-proto 12.6.0` et le proto master exposent le même inventaire de service observé pendant le gate :
| RPC | Forme | Statut | Cible `0.2.9` | Décision |
| --- | --- | --- | --- | --- |
| `Subscribe` | bidi stream | standard Yellowstone | **oui** | fondation principale |
| `SubscribeDeshred` | bidi stream | présent dans proto, trajectoire Triton extension/pré-exécution | **non** | report explicite |
| `SubscribeReplayInfo` | unary | standard | **oui** | information de replay, pas garantie lossless |
| `Ping` | unary | standard | **oui** | canari/liveness unary |
| `GetLatestBlockhash` | unary | standard | **oui** | canari typed |
| `GetBlockHeight` | unary | standard | **oui** | canari typed |
| `GetSlot` | unary | standard | **oui** | canari typed |
| `IsBlockhashValid` | unary | standard | **oui** | canari typed |
| `GetVersion` | unary | standard | **oui** | canari typed |
| RPC | Forme | Statut | Cible `0.2.9` | Décision |
|-----------------------|-------------|----------------------------------------------------------------|---------------|----------------------------------------------|
| `Subscribe` | bidi stream | standard Yellowstone | **oui** | fondation principale |
| `SubscribeDeshred` | bidi stream | présent dans proto, trajectoire Triton extension/pré-exécution | **non** | report explicite |
| `SubscribeReplayInfo` | unary | standard | **oui** | information de replay, pas garantie lossless |
| `Ping` | unary | standard | **oui** | canari/liveness unary |
| `GetLatestBlockhash` | unary | standard | **oui** | canari typed |
| `GetBlockHeight` | unary | standard | **oui** | canari typed |
| `GetSlot` | unary | standard | **oui** | canari typed |
| `IsBlockhashValid` | unary | standard | **oui** | canari typed |
| `GetVersion` | unary | standard | **oui** | canari typed |
`SubscribeDeshred` est techniquement publié dans le proto, mais le changelog upstream le rattache explicitement aux **Triton Extension Patches** et décrit la réception de transactions avant exécution. Il reste donc hors fondation provider-neutral `0.2.9`.
@@ -319,19 +320,19 @@ Le proto publié `yellowstone-grpc-proto 12.6.0` et le proto master exposent le
Surface standard retenue intégralement :
| Champ | Type / sémantique | `0.2.9` |
| --- | --- | --- |
| `accounts` | map nom -> `SubscribeRequestFilterAccounts` | oui |
| `slots` | map nom -> `SubscribeRequestFilterSlots` | oui |
| `transactions` | map nom -> `SubscribeRequestFilterTransactions` | oui |
| `transactions_status` | même famille de filtre transaction | oui |
| `blocks` | map nom -> `SubscribeRequestFilterBlocks` | oui |
| `blocks_meta` | map nom -> filtre vide | oui |
| `entry` | map nom -> filtre vide | oui |
| `commitment` | optional Processed/Confirmed/Finalized | oui |
| `accounts_data_slice` | repeated offset/length | oui |
| `ping` | optional request ping/id | oui |
| `from_slot` | optional u64 | oui, sémantique prudente |
| Champ | Type / sémantique | `0.2.9` |
|-----------------------|-------------------------------------------------|--------------------------|
| `accounts` | map nom -> `SubscribeRequestFilterAccounts` | oui |
| `slots` | map nom -> `SubscribeRequestFilterSlots` | oui |
| `transactions` | map nom -> `SubscribeRequestFilterTransactions` | oui |
| `transactions_status` | même famille de filtre transaction | oui |
| `blocks` | map nom -> `SubscribeRequestFilterBlocks` | oui |
| `blocks_meta` | map nom -> filtre vide | oui |
| `entry` | map nom -> filtre vide | oui |
| `commitment` | optional Processed/Confirmed/Finalized | oui |
| `accounts_data_slice` | repeated offset/length | oui |
| `ping` | optional request ping/id | oui |
| `from_slot` | optional u64 | oui, sémantique prudente |
### 7.1 Accounts
@@ -417,17 +418,17 @@ KSP appliquera des bornes déterministes avant I/O sur les noms, cardinalités,
Le `oneof update_oneof` standard contient exactement neuf variantes observées :
| Variante | Champs structurants à préserver |
| --- | --- |
| `account` | account info + slot + `is_startup` |
| `slot` | slot + optional parent + status + optional dead_error |
| `transaction` | signature/is_vote/transaction/meta/index + slot |
| `transaction_status` | slot/signature/is_vote/index/error |
| `block` | slot/hash/rewards/time/height/parent/counts + transactions/accounts/entries |
| `ping` | marker server ping |
| `pong` | id |
| `block_meta` | block metadata/counts sans tableaux complets |
| `entry` | slot/index/num_hashes/hash/transaction counts/index |
| Variante | Champs structurants à préserver |
|----------------------|-----------------------------------------------------------------------------|
| `account` | account info + slot + `is_startup` |
| `slot` | slot + optional parent + status + optional dead_error |
| `transaction` | signature/is_vote/transaction/meta/index + slot |
| `transaction_status` | slot/signature/is_vote/index/error |
| `block` | slot/hash/rewards/time/height/parent/counts + transactions/accounts/entries |
| `ping` | marker server ping |
| `pong` | id |
| `block_meta` | block metadata/counts sans tableaux complets |
| `entry` | slot/index/num_hashes/hash/transaction counts/index |
Le top-level contient aussi :
@@ -440,15 +441,15 @@ Les types imbriqués `solana-storage.proto` nécessaires aux transactions/blocs
## 9. RPCs unary retenus
| RPC | Request | Response | Notes |
| --- | --- | --- | --- |
| `SubscribeReplayInfo` | vide | `first_available?` | information de disponibilité seulement |
| `Ping` | `count` | `count` | exact echo attendu |
| `GetLatestBlockhash` | `commitment?` | slot, blockhash, last_valid_block_height | typed |
| `GetBlockHeight` | `commitment?` | block_height | typed |
| `GetSlot` | `commitment?` | slot | typed |
| `IsBlockhashValid` | blockhash + `commitment?` | slot + valid | typed |
| `GetVersion` | vide | version | opaque string bornée |
| RPC | Request | Response | Notes |
|-----------------------|---------------------------|------------------------------------------|----------------------------------------|
| `SubscribeReplayInfo` | vide | `first_available?` | information de disponibilité seulement |
| `Ping` | `count` | `count` | exact echo attendu |
| `GetLatestBlockhash` | `commitment?` | slot, blockhash, last_valid_block_height | typed |
| `GetBlockHeight` | `commitment?` | block_height | typed |
| `GetSlot` | `commitment?` | slot | typed |
| `IsBlockhashValid` | blockhash + `commitment?` | slot + valid | typed |
| `GetVersion` | vide | version | opaque string bornée |
Les unary ne remplacent pas les méthodes HTTP équivalentes : ce sont des capacités du backend Yellowstone et restent séparées des wrappers JSON-RPC HTTP existants.
@@ -539,14 +540,22 @@ Inconvénients : copie/licence/synchronisation du proto, `build.rs`, protoc et d
## 12. Architecture publique cible
### 12.1 Séparation des backends
### 12.1 Séparation des backends et des niveaux Yellowstone
```text
HTTP TransportSettings / EndpointClient / pool HTTP existants
WebSocket Ws* existants
Yellowstone gRPC nouveaux Grpc*/Yellowstone* dédiés
HTTP TransportSettings / EndpointClient / pool HTTP existants
WebSocket engine WsSession actor partagé
Solana standard WS SolanaStandardWsSession
Helius LaserStream WS HeliusLaserStreamWsSession
Yellowstone gRPC engine nouveau runtime/session physique partagé
Solana Yellowstone standard façade typed standard sur ce moteur
PublicNode Yellowstone première intégration provider sur standard
future providers adapters/facades séparés seulement si différence réelle
```
Cette structure reprend le principe validé par `0.2.7`/`0.2.8` : **le moteur physique n'est jamais recopié par provider**.
Interdictions :
```text
@@ -554,6 +563,8 @@ pas de WsProtocolKind pour gRPC
pas de WsEndpointSettings réutilisé
pas de WsSession déguisée
pas de client Tonic brut réexporté
pas de second actor Yellowstone par provider
pas de façade provider vide uniquement pour renommer le même protocole
```
### 12.2 Noms et ownership
@@ -561,17 +572,26 @@ pas de client Tonic brut réexporté
Noms cibles, affinables sans casser le principe :
```text
# N1 — moteur Yellowstone
YellowstoneGrpcEndpointUrl
YellowstoneGrpcEndpointSettings
YellowstoneGrpcSessionSettings
YellowstoneGrpcTransportSettings
YellowstoneGrpcSession
YellowstoneSubscriptionHandle<T>
# N2 — standard Solana Yellowstone
SolanaYellowstoneGrpcSession # façade candidate, si le gate API confirme ce nom
YellowstoneSubscribeRequest / filters KSP
YellowstoneUpdate / typed update projections
# N3 — provider
provider descriptor/capabilities ouverts
PublicNode integration/profile/canaries
PublicNode-specific facade seulement si une différence réelle le justifie
```
Le backend wire Tonic/Prost reste privé. Tous les types publics nécessaires sont réexportés au crate root conformément aux règles KSP.
Le backend wire Tonic/Prost reste privé. Tous les types publics nécessaires sont réexportés au crate root conformément aux règles KSP. Le provider et le protocole restent deux axes distincts : `PublicNode` décrit **où/comment** on exécute Yellowstone standard, pas un nouveau protocole.
### 12.3 Metadata/auth provider-neutral
@@ -669,10 +689,13 @@ PublicNode est un service soutenu/opéré par Allnodes dans l'écosystème actue
Décision `0.2.9` :
```text
pas de PublicNodeGrpcSession publique
pas de AllnodesGrpcSession publique
PublicNode Mainnet = premier smoke live opt-in sans secret
PublicNode Testnet = second cluster du même smoke/provider si endpoint exact confirmé live
PublicNode = première intégration provider concrète du moteur Yellowstone
PublicNode Mainnet = premier environnement live opt-in sans secret
PublicNode Testnet = second cluster du même provider si endpoint exact confirmé live
provider/capabilities/profile explicitement représentés
aucun second moteur/actor/session physique
façade PublicNode spécialisée seulement si une différence réelle est démontrée
Allnodes n'est pas modélisé comme un protocole distinct
```
La page officielle confirme l'existence de Testnet GRPC, mais le hostname exact n'est pas figé dans ce gate tant qu'il n'a pas été confirmé depuis la surface officielle/live. Il sera vérifié avant ajout d'un profil committé.
@@ -766,7 +789,9 @@ Hiérarchie cible :
```text
1. Transport pur programmatic -> PublicNode Mainnet, sans secret
2. Transport pur programmatic -> PublicNode Testnet, si endpoint exact confirmé
3. composition Config V3 -> Transport -> OrbitFlare Devnet, secret résolu par Config
3. Config V3 -> Transport -> PublicNode profile, si Config est matérialisée dans 0.2.9
OrbitFlare et les providers authentifiés sont validés dans leurs releases dédiées.
4. Tatum Mainnet authentifié, opérateur-only si utile
```
@@ -845,69 +870,77 @@ TLS/certificate failure
unary timeout
```
## 17. Forecast souple recalibré
## 17. Forecast souple recalibré — **1520 min max par prerelease ; 1 release <= 1 session**
Règles de dimensionnement **obligatoires** :
```text
chaque prerelease = tranche nominale de 1520 minutes de travail effectif maximum
si une tranche paraît dépasser 20 minutes -> la scinder avant implémentation
0.2.9 complète = doit rester ouvrable et clôturable dans une seule session de chat
si la clôture dans la session devient incertaine -> scinder la release avant dette lourde
le numéro final des prereleases n'est jamais une deadline
```
Prévision courante :
```text
pre.001 DONE — audit upstream/service/proto + providers gratuits + licences/deps + architecture + threat model + sizing
preuve : plan + matrice + stratégie B + Config V3 décidée + forecast recalibré
budget : 1520 min nominal ; preuve : plan + matrice + stratégie B + forecast recalibré
pre.002 proto/dependencies matérialisés + settings/errors/façade gRPC minimale provider-neutral
preuve : features justifiées + compile/tests + redaction + cargo tree direct/duplicates
pre.002 moteur Yellowstone : proto/dependencies + settings/errors + channel minimal
budget : 1520 min ; preuve : features minimales + compile/tests + redaction + cargo tree
pre.003 channel/TLS/metadata générique + fixture serveur local + 7 unary RPCs
preuve : connect/TLS/timeouts/Status safe + wire unary exact
pre.003 moteur Yellowstone : TLS/metadata générique + fixture locale + 7 unary RPCs
budget : 1520 min ; preuve : connect/TLS/timeouts/Status safe + wire unary exact
pre.004 Subscribe foundation : maps, commitment, ping, from_slot, data slices, Cuckoo/token controls, validations/bounds
preuve : omitted/empty/oneof exact + rejects avant I/O
pre.004 standard Solana : Subscribe foundation + maps/commitment/ping/from_slot/data slices/bounds
budget : 1520 min ; preuve : omitted/empty/oneof exact + rejets avant I/O
pre.005 Accounts + Slots : filters + typed updates
preuve : fixtures exactes + enum/optional/malformed/adversarial
pre.005 standard Solana : Accounts + Slots filters/updates
budget : 1520 min ; preuve : fixtures exactes + enum/optional/malformed/adversarial
pre.006 Transactions + transaction_status + solana-storage wire utile
preuve : include/exclude/required/Cuckoo/token expansion + tx/meta sans perte arbitraire
pre.006 standard Solana : Transactions + transaction_status
budget : 1520 min ; preuve : include/exclude/required/Cuckoo/token expansion + tx/meta
pre.007 Blocks + block_meta + entry + rewards/storage nested types
preuve : counts/arrays/optional/oneof/payload bounds exacts
pre.007 standard Solana : Blocks + block_meta + entry
budget : 1520 min ; preuve : counts/arrays/optional/oneof/payload bounds
pre.008 stream bidirectionnel : mutations, Ping/Pong, half-close, backpressure, shutdown
preuve : actor/session local + bounded queues + cleanup déterministe
pre.008 moteur partagé : bidi mutation + Ping/Pong + half-close + backpressure + shutdown
budget : 1520 min ; preuve : actor/session local + bounded queues + cleanup déterministe
pre.009 reconnect/resubscribe + from_slot/ReplayInfo + gaps/duplicates/equivocation observability
preuve : reconnect local déterministe + aucune promesse lossless implicite
pre.009 moteur partagé : reconnect/resubscribe + from_slot/ReplayInfo + gaps/duplicates
budget : 1520 min ; preuve : reconnect local déterministe + aucune promesse lossless
pre.010 Config Transport V3 : grpc_defaults/grpc_endpoints + public/secret metadata + backward V1/V2
preuve : schema/fixtures/mapping/redaction + Config -> Transport uniquement
pre.010 Config V3 + séparation protocol/provider + profils PublicNode Mainnet/Testnet
budget : 1520 min ; preuve : V1/V2 backward + schema/mapping/redaction + Config -> Transport
pre.011 interop live + compliance : PublicNode Mainnet puis Testnet, OrbitFlare Devnet secondaire, Tatum optionnel
preuve : smokes opt-in architecture-safe + HTTP 52/14 + WS 18/18 + Helius + API/firewall + cargo graph final
pre.012 README/USAGE + matrice finale + workspace final + indexes + prompt 0.2.10
preuve : workspace final vert + documentation version-neutral + prompt autonome
pre.011 intégration PublicNode + smokes live + compliance + docs finales + prompt 0.2.10 OrbitFlare
budget : 1520 min ; preuve : Mainnet/Testnet opt-in + HTTP 52/14 + WS 18/18 + Helius + cargo graphs + workspace final
rel.001 publication stable stricte
```
Chaque tranche vise nominalement **1520 minutes** de travail effectif. Le forecast n'est pas une deadline.
Prévision : **11 prereleases**, soit environ **165220 minutes de travail effectif nominal hors temps d'attente des commandes**, compatible avec une session complète. Si une tranche réelle excède son budget ou si `pre.011` ne peut pas raisonnablement fermer la release dans la session, on scinde avant de poursuivre au lieu de prolonger artificiellement `0.2.9`.
### Critères de split
Scinder avant dette silencieuse si l'un de ces cas apparaît :
1. `yellowstone-grpc-proto + tonic` impose un conflit MSRV ou un doublon majeur de stack réseau impossible à justifier ;
1. `yellowstone-grpc-proto + tonic` impose une incompatibilité avec la Rust stable courante ou un doublon majeur de stack réseau impossible à justifier ;
2. les DTOs transactions/blocs exigent une réexposition massive des types upstream ou une réimplémentation disproportionnée ;
3. l'upstream modifie encore matériellement le proto pendant la release ;
4. le replay/reconnect devient un sous-système plus grand que la foundation ;
5. les smokes provider nécessitent des comportements non standard qui contamineraient l'API publique.
5. PublicNode exige finalement un comportement provider-specific assez large pour dépasser la session ;
6. toute prerelease dépasse le budget nominal de 20 minutes sans frontière claire de split.
En cas de split, le noyau prioritaire à conserver dans `0.2.9` est :
```text
connexion/TLS/metadata + unary + Subscribe standard canonique + lifecycle borné
moteur Yellowstone + façade Solana standard + première intégration PublicNode minimale
```
et le reste est replanifié explicitement dans la séquence ; aucune capacité n'est abandonnée silencieusement.
et le reste est replanifié explicitement ; aucune capacité n'est abandonnée silencieusement.
## 18. Fichiers attendus par tranche
@@ -991,18 +1024,33 @@ metadata/secrets redacted
resource bounds et backpressure testés
reconnect/from_slot/replay documentés sans promesse lossless
Config V3 backward V1/V2 si Config intégrée
PublicNode intégration provider matérialisée sans duplication du moteur
PublicNode interop Mainnet validée opt-in ou impossibilité externe documentée
OrbitFlare Devnet validé si credential opérateur disponible, sinon procédure documentée
PublicNode Testnet validé si endpoint live confirmé, sinon raison documentée
OrbitFlare/Helius/eRPC absents du runtime 0.2.9 hors documentation de séquence
HTTP 52+14 non régressé
standard WS 18/18 non régressé
Helius WS non régressé
cargo graphs inspectés
README/USAGE synchronisés
matrice `012` fermée
prompt 0.2.10 prêt
prompt 0.2.10 OrbitFlare prêt
workspace final vert
```
## 21. Release suivante
## 21. Releases suivantes recalibrées
`0.2.10` reste dédiée à `ksp-offchain-transport-lib` et aux prix, sans être anticipée dans la stack Yellowstone.
Le gate `pre.001-fix.001` reprend la logique WebSocket : moteur/standard d'abord, providers ensuite, un provider par release lorsque son intégration apporte un delta réel.
```text
0.2.9 moteur Yellowstone + Solana standard + PublicNode
0.2.10 OrbitFlare Yellowstone gRPC
0.2.11 Helius LaserStream gRPC
0.2.12 eRPC Yellowstone gRPC, conditionné à un accès exploitable et à un delta provider réel
0.2.13 off-chain price transport
0.2.14 Price Desk + intégration prix Wallet Desk
0.2.15 interface/wire foundation
0.2.16 program-api foundation
```
La numérotation `0.2.10+` reste réauditable au gate de chaque release : un provider qui n'ajoute finalement qu'une URL interchangeable sans contrat propre ne doit pas provoquer une façade vide ni une release artificielle.