32 KiB
Plan 0.2.9 — moteur Yellowstone gRPC + standard Solana + PublicNode
Statut courant : le couloir technique 0.2.9-pre.013 est fermé par pre.013-fix.004 : gates déterministes et workspace verts, graphes Cargo finaux inspectés, et smoke Yellowstone PublicNode authentifié exécuté avec succès sur Mainnet et Testnet (2/2 PASS). pre.014 est la réconciliation documentaire finale ; seule pre.015 restera ensuite pour le prompt 0.2.10, CHANGELOG.md et ROADMAP.md, avant rel.001.
1. Objet et autorité de la release
Base stable d'ouverture :
v0.2.8
Release :
0.2.9 — Yellowstone gRPC standard/provider-neutral
Le gate pre.001, ses fixes, les deltas techniques suivants et le code réel ont affiné le prompt de démarrage. L'ordre d'autorité utilisé pendant la release est :
règles normatives KSP
code et fichiers réellement livrés
nouveaux deltas immuables de 0.2.9
décisions courantes consolidées dans ce plan et la validation 012
prompt de démarrage pour les contraintes qui n'ont pas été explicitement supersédées
Les deltas historiques ne sont jamais réécrits pour refléter une décision ultérieure.
2. Résultat final attendu
0.2.9 doit fermer une première fondation Yellowstone gRPC exploitable sans devenir un SDK fournisseur :
backend gRPC distinct de HTTP et WebSocket
moteur Tonic/Protobuf privé dans ksp-onchain-transport-lib
façade Yellowstone standard provider-neutral
7 unary standard retenus
Subscribe standard avec les familles/accounts/slots/transactions/blocks retenues
9 variantes SubscribeUpdate courantes
stream bidirectionnel borné
backpressure, half-close et shutdown déterministes
reconnect KSP-owned et replay/from_slot prudent
aucune promesse exactly-once/lossless non prouvée
Config Transport V3 backward-readable V1/V2
provider et protocol distincts dans Config
première intégration PublicNode strictement standard
smoke live opt-in avec credential secret non versionné
non-régressions HTTP, WebSocket standard et Helius WebSocket
3. Scope fermé par pre.001
3.1 Inclus
N1 — moteur Yellowstone gRPC
N2 — standard Solana Yellowstone
N3 — première intégration PublicNode quand elle réutilise le standard sans divergence wire
TLS et metadata provider-neutral
7 unary standards retenus
Subscribe standard retenu
reconnect/replay observables mais non lossless
Config V3 si le mapping reste Config -> Transport
smokes PublicNode architecture-safe
3.2 Hors scope 0.2.9
SubscribeDeshred / pré-exécution
extensions Triton spécifiques
adapter Helius LaserStream gRPC spécifique
adapter OrbitFlare spécifique
pool/scheduler automatique complexe de sessions gRPC
serveur Geyser/plugin validator
Store/persistence/backfill historique
workers/jobs d'acquisition
replay lossless garanti
refonte HTTP ou WebSocket
Les intégrations provider futures ne dupliquent jamais le moteur N1. Une façade provider n'existe que si elle porte une divergence réelle : auth, capabilities, restriction, extension wire ou policy lifecycle.
4. Audit upstream et dépendances retenues
4.1 Snapshot normatif et réaudit final
Le gate d'ouverture puis le réaudit final du 2026-08-24 confirment que les numéros du plugin, du client, du proto et des releases GitHub évoluent indépendamment. Il ne faut donc pas transformer un numéro de master en numéro de release publié.
État observé au réaudit final :
latest release GitHub indexée v14.2.2+solana.4.1.0 — 2026-07-27
master yellowstone-grpc-geyser 15.1.2
master yellowstone-grpc-client 13.3.0
master yellowstone-grpc-proto 12.6.0
master Agave Geyser / storage 4.2.0
master prost / prost-types / tonic 0.14.x
KSP yellowstone-grpc-proto direct ^12.6
Le service Geyser, la shape de SubscribeRequest et les neuf variantes SubscribeUpdate retenues par KSP n'ont pas changé matériellement par rapport au gate pre.001. SubscribeDeshred reste explicitement hors scope 0.2.9.
Les sources primaires restent :
https://github.com/rpcpool/yellowstone-grpc/releases
https://github.com/rpcpool/yellowstone-grpc/blob/master/CHANGELOG.md
https://github.com/rpcpool/yellowstone-grpc/blob/master/yellowstone-grpc-proto/proto/geyser.proto
https://github.com/rpcpool/yellowstone-grpc/blob/master/yellowstone-grpc-proto/proto/solana-storage.proto
https://github.com/rpcpool/yellowstone-grpc/blob/master/LICENSING.md
https://docs.rs/crate/yellowstone-grpc-proto/latest
https://docs.rs/crate/yellowstone-grpc-client/latest
Le réaudit final a été exécuté en pre.012; aucun changement upstream matériel n’a remis en cause la surface retenue.
4.2 Licence
Le repository upstream est globalement AGPL-3.0-only, mais LICENSING.md affecte explicitement Apache-2.0 à :
examples/
yellowstone-grpc-client/
yellowstone-grpc-client-nodejs/
yellowstone-grpc-proto/
Décision :
dépendance publiée yellowstone-grpc-proto = acceptée
.proto vendored dans KSP = non
source provenant des zones AGPL = non copiée
future copie upstream = nouveau gate provenance/licence obligatoire
4.3 Stratégie client
| Stratégie | Décision | Raison principale |
|---|---|---|
yellowstone-grpc-client + yellowstone-grpc-proto |
non retenue | importerait trop de lifecycle/reconnect upstream et de surface client |
yellowstone-grpc-proto + client KSP autour de tonic |
retenue | wire officiel, moteur/lifecycle/redaction KSP-owned |
| proto/génération KSP vendored | fallback seulement | dette licence/synchronisation/build plus forte |
Matérialisation courante :
yellowstone-grpc-proto ^12.6 runtime sans feature tonic
yellowstone-grpc-proto dev/test avec feature tonic pour GeyserServer fixture
tonic ^0.14 channel + TLS runtime ; codegen/server dev/test
tonic-prost ^0.14 ProstCodec bas niveau
http ^1.5 PathAndQuery interne
yellowstone-grpc-client absent
prost/prost-types aucune dépendance KSP directe
proto vendored absent
Les graphes Cargo inspectés pendant pre.002/pre.003 n'ont pas révélé de seconde génération incompatible à corriger. Le graph final est réinspecté en pre.012.
5. Matrice protocolaire fermée
5.1 Service Geyser
| RPC | Forme | Classification | Cible 0.2.9 |
État |
|---|---|---|---|---|
Subscribe |
bidi stream | standard Yellowstone | oui | DONE pre.009/pre.010 |
SubscribeDeshred |
bidi stream | extension/pré-exécution Triton publiée dans le proto | non | OUT |
SubscribeReplayInfo |
unary | standard | oui | DONE |
Ping |
unary | standard | oui | DONE |
GetLatestBlockhash |
unary | standard | oui | DONE |
GetBlockHeight |
unary | standard | oui | DONE |
GetSlot |
unary | standard | oui | DONE |
IsBlockhashValid |
unary | standard | oui | DONE |
GetVersion |
unary | standard | oui | DONE |
SubscribeDeshred reste explicitement exclu même s'il existe dans le proto publié : sa présence wire n'en fait pas une capacité provider-neutral de la fondation KSP.
5.2 SubscribeRequest
| Champ | Sémantique | État |
|---|---|---|
accounts |
map nom -> filtre accounts | DONE |
slots |
map nom -> filtre slots | DONE |
transactions |
map nom -> filtre transactions | DONE |
transactions_status |
même famille de filtre transaction | DONE |
blocks |
map nom -> filtre blocks | DONE |
blocks_meta |
map nom -> filtre marqueur vide | DONE |
entry |
map nom -> filtre marqueur vide | DONE |
commitment |
optional Processed/Confirmed/Finalized | DONE |
accounts_data_slice |
repeated offset/length | DONE |
ping |
optional request ping/id | DONE |
from_slot |
optional u64 | DONE, sémantique prudente |
Accounts :
account[]
owner[]
filters[]
nonempty_txn_signature?
cuckoo_accounts_filter?
memcmp { offset, oneof bytes | base58 | base64 }
datasize
token_account_state
lamports { oneof eq | ne | lt | gt }
Slots :
filter_by_commitment?
interslot_updates?
statuses = processed | confirmed | finalized | first_shred_received | completed | created_bank | dead
Transactions et transaction_status :
vote?
failed?
signature?
account_include[]
account_exclude[]
account_required[]
cuckoo_account_include?
token_accounts? = ALL | BALANCE_CHANGED
Blocks :
account_include[]
include_transactions?
include_accounts?
include_entries?
cuckoo_account_include?
blocks_meta et entry conservent la distinction absence / map vide / filtre nommé vide.
Bornes KSP communes matérialisées :
filter groups nommés total <= 1024
filter name 1..128 octets, trim exact, sans contrôle
filter names uniques globalement entre les sept maps
accounts_data_slice count <= 128
accounts_data_slice length <= 64 MiB
offset + length sans overflow u64
Les bounds spécifiques Accounts/Transactions/Blocks sont ceux désormais testés dans leurs tranches respectives ; ils ne sont pas dupliqués comme knobs Config.
5.3 SubscribeUpdate
| Variante | Champs structurants conservés | État |
|---|---|---|
account |
account info + slot + is_startup |
DONE |
slot |
slot + parent? + status + dead_error? | DONE |
transaction |
signature/is_vote/transaction/meta/index + slot | DONE |
transaction_status |
slot/signature/is_vote/index/error | DONE |
block |
slot/hash/rewards/time/height/parent/counts + transactions/accounts/entries | DONE |
ping |
marker server ping | DONE |
pong |
id | DONE |
block_meta |
block metadata/counts sans tableaux complets | DONE |
entry |
slot/index/num_hashes/hash/transaction counts/index | DONE |
Le top-level conserve également filters[] et created_at. Les types Prost/Yellowstone générés restent privés.
5.4 Unary standards
| RPC | Request | Response KSP utile | État |
|---|---|---|---|
SubscribeReplayInfo |
vide | first_available? |
DONE |
Ping |
count |
count |
DONE |
GetLatestBlockhash |
commitment? |
slot, blockhash, last_valid_block_height | DONE |
GetBlockHeight |
commitment? |
block_height | DONE |
GetSlot |
commitment? |
slot | DONE |
IsBlockhashValid |
blockhash + commitment? |
slot + valid | DONE |
GetVersion |
vide | version bornée | DONE |
Ces capacités ne remplacent pas les wrappers Solana JSON-RPC HTTP.
6. Architecture runtime actuelle
6.1 Séparation des backends
HTTP HttpTransportSettings / pool HTTP
WebSocket engine WsSession actor partagé
Solana standard WS SolanaStandardWsSession
Helius LaserStream WS HeliusLaserStreamWsSession
Yellowstone gRPC engine YellowstoneGrpcChannel + moteur bidi KSP
Solana Yellowstone standard contrats typed KSP
provider descripteur d'exécution/capability, pas nouveau protocole
Interdictions :
pas de WsProtocolKind pour gRPC
pas de WsEndpointSettings pour gRPC
pas de client Tonic brut réexporté
pas de second moteur physique par provider
pas de façade provider vide qui ne ferait que renommer le standard
6.2 Contrats publics principaux matérialisés
YellowstoneGrpcEndpointUrl
YellowstoneGrpcProviderName
YellowstoneGrpcClusterName
YellowstoneGrpcMetadataEntry
YellowstoneGrpcReconnectSettings
YellowstoneGrpcSessionSettings
YellowstoneGrpcEndpointSettings
YellowstoneGrpcTransportSettings
YellowstoneGrpcChannel
YellowstoneSubscribeRequest + filtres typed
YellowstoneSubscribeUpdate + variantes typed
SolanaYellowstoneGrpcSubscribeSession
YellowstoneGrpcSubscribeSnapshot
7 unary typed
Le wire Tonic/Prost reste privé et n'est pas une escape hatch publique.
6.3 Credentials et diagnostics
Transport reçoit des valeurs déjà résolues par son consumer. Il ne connaît :
aucun KSP_SECRET_*
aucun KSP_PUBLIC_*
aucun std::env
aucun header commercial hardcodé dans le standard
Les URLs, metadata sensibles, messages/details de tonic::Status et payloads arbitraires ne sont pas recopiés dans Debug, Display, snapshots ou contexts KSP.
7. Lifecycle, backpressure et continuité
7.1 Stream bidi
Acquis depuis pre.009 :
une request mpsc bornée consommée par Tonic
une update queue bornée côté KSP
mutation du SubscribeRequest sur le même stream
Ping serveur -> réponse automatique appropriée
Pong décodé
server half-close observable
client explicit close borné
Drop best-effort sans panic
oversized inbound/outbound borné
slow receiver overflow terminal et observable
shutdown déterministe
Aucune queue non bornée et aucun drop silencieux n'est présenté comme lossless.
7.2 Reconnect/replay
Acquis depuis pre.010 :
reconnect automatique oui, borné et KSP-owned
resubscribe dernier SubscribeRequest complet accepté
from_slot de reprise max(from_slot explicite, dernier slot observé) quand applicable
SubscribeReplayInfo informatif
first_available clamp/prouve un gap seulement s'il dépasse le slot demandé
exactly-once non garanti
lossless non garanti
ordre global sans gap non garanti
duplicate possible, compté, non supprimé silencieusement
gap compté seulement lorsqu'une preuve est disponible
shutdown during backoff interrompt la reconnexion
budget reconnect épuisé état terminal safe
Snapshot public safe :
reconnect_count
replay_attempt_count
continuity_gap_count
duplicate_update_count
last_requested_from_slot
last_observed_slot
terminal state/error code safe
La présence de from_slot ou SubscribeReplayInfo n'autorise aucune promesse de replay historique complet.
8. Config Transport V3 — tranche pre.011
8.1 Compatibilité documentaire
Décision fermée :
V1 = HTTP-only, backward-readable
V2 = HTTP + WebSocket, backward-readable
V3 = HTTP + WebSocket + Yellowstone gRPC optionnel par profil
Le schema V3 conserve des branches strictes V1/V2 au lieu de relâcher leurs additionalProperties.
Shape V3 :
format_version = 3
retry
ws_defaults
grpc_defaults
default_profile
profiles[] {
profile_id
endpoints[]
ws_endpoints[]
grpc_endpoints[]? # optionnel par profil
}
L'absence de grpc_endpoints dans un profil V3 signifie None, pas un YellowstoneGrpcTransportSettings vide inventé.
8.2 grpc_defaults
Les defaults Config correspondent uniquement à de vrais settings runtime Transport :
connect_timeout_ms
unary_timeout_ms
close_timeout_ms
reconnect.max_retries
reconnect.initial_backoff_ms
reconnect.max_backoff_ms
request_channel_capacity
update_channel_capacity
max_inbound_message_size_bytes
max_outbound_message_size_bytes
Les bounds de filtres Subscribe restent un contrat Transport fixe et ne deviennent pas des options Config sans besoin démontré.
8.3 Endpoint gRPC
Chaque grpc_endpoints[] porte :
name
enabled
provider
cluster
protocol = solana_yellowstone
url
metadata[]? # classe publique
secret_metadata[]? # classe secrète
session? # overrides bornés
Axes distincts :
protocol = contrat wire standard, actuellement solana_yellowstone
provider = environnement d'exécution descriptif, par exemple publicnode
provider = publicnode ne crée donc pas un PublicNodeGrpcProtocol ni une façade provider sans divergence réelle.
8.4 Provenance des metadata
Config est propriétaire de la résolution :
metadata -> interdit toute provenance KSP_SECRET_*/KSPB_SECRET_*
secret_metadata -> exige au moins une provenance secret et interdit une variable non-secret
littéraux autour d'un placeholder secret -> autorisés ; safe_value masque seulement le segment secret
Transport reçoit ensuite YellowstoneGrpcMetadataEntry public/secret et ne connaît jamais le nom de variable d'environnement.
8.5 API Config sans rupture V2
L'API existante reste :
http_settings()
ws_settings()
into_transport_settings() -> (HTTP, Option<WS>)
pre.011 ajoute :
grpc_settings()
into_all_transport_settings() -> (HTTP, Option<WS>, Option<Yellowstone gRPC>)
Le tuple historique n'est pas modifié silencieusement.
9. PublicNode dans 0.2.9
9.1 Mainnet
Endpoint retenu et validé en live :
https://solana-yellowstone-grpc.publicnode.com:443
Le profil committé est :
profile_id = publicnode_mainnet
provider = publicnode
cluster = mainnet-beta
protocol = solana_yellowstone
metadata = x-token secret via KSP_SECRET_PUBLICNODE_MAINNET_GRPC_X_TOKEN
Les tentatives sans metadata ont atteint le service mais ont reçu PERMISSION_DENIED. Le profil final fournit donc le personal token PublicNode comme metadata gRPC secrète x-token; Transport ne connaît ni le nom de variable KSP ni sa provenance.
9.2 Testnet
L'endpoint exact confirmé par l'opérateur et validé en live est :
https://solana-testnet-yellowstone-grpc.publicnode.com:443
Le profil committé est :
profile_id = publicnode_testnet
provider = publicnode
cluster = testnet
protocol = solana_yellowstone
metadata = x-token secret via KSP_SECRET_PUBLICNODE_TESTNET_GRPC_X_TOKEN
Le smoke final prouve qu'un même personal token opérateur peut fonctionner sur Mainnet et Testnet. KSP conserve néanmoins deux variables de configuration distinctes afin de ne pas imposer une hypothèse de portée provider à long terme ; elles peuvent recevoir la même valeur. Cette séparation est une liberté de configuration KSP, pas une assertion que PublicNode délivre des tokens network-scoped.
10. Threat model et bornes
Menaces couvertes :
credential dans URI/metadata
Status/message/details provider arbitraires
Debug dérivé de filtres/payloads
TLS/connect error qui réémet l'URI
message inbound/outbound hostile
stream flood / slow consumer
filter explosion / collision de noms
unknown enum/oneof
server/client half-close
reconnect loop
node divergent après reconnect
duplicate/gap après replay
mutation tardive du stream
Réponses :
wrappers redacted
allowlist de contexts KSP
validation/bounds avant I/O
queues bornées
états terminaux observables
reconnect budget borné
aucune promesse de continuité non prouvée
Config sensitivity gate avant construction de metadata secret
11. Smoke ownership
Ordre de preuve :
Transport programmatic -> PublicNode Mainnet Yellowstone + secret x-token fourni au harness
Transport programmatic -> PublicNode Testnet Yellowstone + secret x-token fourni au harness
Config V3 -> Transport -> PublicNode via secret_metadata, jamais un smoke réseau placé dans Config par facilité
Un smoke Transport pur peut vivre dans ksp-onchain-transport-lib/tests puisqu'il construit ses settings programmatiquement.
Un smoke cross-crates Config -> Transport ne doit pas devenir une responsabilité durable de ksp-config-lib. S’il n’existe pas encore de surface d’intégration appropriée, la preuve live reste un smoke Transport programmatique avec secret fourni uniquement au harness opérateur.
Aucun secret provider n'est versionné.
12. État des tranches et historique compact
Les preuves détaillées restent dans les fichiers deltas/0.2.9/*.md. Le plan ne duplique plus leurs journaux complets.
| Tranche | Objet | État consolidé |
|---|---|---|
pre.001 + fixes |
audit upstream, licence, providers, architecture, sizing | CLOSED |
pre.002 + fixes |
dépendances, settings/errors, channel minimal | CLOSED |
pre.003 + fix |
TLS, metadata, fixture locale, 7 unary | CLOSED |
pre.004 + fix |
Subscribe foundation/common | CLOSED |
pre.005 + fix |
Accounts + Slots | CLOSED |
pre.006 |
namespace privé HTTP explicite | CLOSED |
pre.007 |
Transactions + transaction_status | CLOSED |
pre.008 + fix |
Blocks + block_meta + entry | CLOSED |
pre.009 + fix |
bidi, Ping/Pong, backpressure, half-close, shutdown | CLOSED |
pre.010 + fix |
reconnect, from_slot, ReplayInfo, gaps/duplicates | CLOSED |
pre.011 |
Config V3 + protocol/provider + PublicNode Mainnet | CLOSED |
pre.012 |
réaudit + smoke ajouté + docs préparatoires | LOCAL GATE PASS |
pre.012-fix.001 |
règles de séparation de fermeture + recalibrage | CLOSED |
pre.013 + fixes |
gate technique/live PublicNode + graphes finaux | CLOSED |
pre.014 |
réconciliation documentaire finale | ACTIVE CANDIDATE |
pre.015 |
prompt + CHANGELOG + ROADMAP | PLANNED |
Gate opérateur déterministe de pre.012 reçu le 2026-08-24 :
fmt/audit Rust PASS sans warning
Markdown tables PASS, 87 tableaux / 252 fichiers
cargo check PASS
cargo clippy PASS sans warning
Config unit 113/113
Config public API 15/15
Config ownership 5/5
Transport unit 383/383
Transport public API 49/49
Transport completeness 43/43
Transport doctests 4/4
workspace dependencies 3/3
cargo test --workspace PASS
PublicNode live smoke NOT RUN, test ignored
cargo tree final NOT PROVIDED / NOT RUN in supplied log
pre.012 reste historiquement une tranche mixte créée avant l'adoption de la nouvelle règle. Son fix ne réécrit pas cette histoire : le prompt 0.2.10 déjà présent est désormais considéré comme un brouillon à finaliser seulement en pre.015, et les README/USAGE préparés sont réconciliés par la présente pre.014.
Gate technique final pre.013-fix.004 reçu le 2026-08-24 :
fmt/audit Rust PASS sans warning
Markdown tables PASS, 87 tableaux / 258 fichiers
cargo check PASS
cargo clippy --all-targets PASS sans warning
Transport unit 383/383
Transport public API 49/49
Transport completeness 43/43
Transport doctests 4/4
cargo test --workspace PASS
cargo graphs finaux inspectés, stack Yellowstone unique tonic/prost 0.14
PublicNode Mainnet Subscribe + slot PASS
PublicNode Testnet Subscribe + slot PASS
live smoke total 2/2 PASS
Les graphes inspectés avant fix.004 restent valides : ce fix n'a modifié ni dépendance ni feature Cargo. La stack Yellowstone résolue est yellowstone-grpc-proto 12.6.0, tonic/tonic-prost 0.14.6, prost/prost-types 0.14.4, sans yellowstone-grpc-client runtime.
13. Forecast restant recalibré
pre.013 — gate technique/live final — CLOSED
Le couloir technique a finalement nécessité quatre fixes : découverte de l'auth PublicNode, ajout Testnet, adaptation de la fermeture live, puis conformité Clippy du harness. Le résultat consolidé est :
workspace.package.version final du couloir = 0.2.9-pre.13.fix.4
PublicNode Mainnet Subscribe + slot PASS
PublicNode Testnet Subscribe + slot PASS
secret wire metadata x-token
secret versionné non
harness deux lignes stdin, valeurs identiques autorisées
close provider succès ou timeout KSP borné après slot reçu
graphes Cargo inspectés
clippy --all-targets PASS sans warning
workspace PASS
Les essais intermédiaires PERMISSION_DENIED sans credential sont conservés dans les deltas pre.013-fix.001 à fix.003; ils ne sont pas réinterprétés comme une régression du moteur standard.
pre.014 — réconciliation documentaire finale — ACTIVE CANDIDATE
Payload :
workspace.package.version = 0.2.9-pre.14
plan 016 réconcilié avec le gate technique/live réel
validation 012 fermée avec uniquement des preuves exécutées
README/USAGE Transport relus et corrigés
références durables liées à 0.2.9 réconciliées si nécessaire
audit Markdown final des documents touchés
aucune modification fonctionnelle/runtime
aucune finalisation CHANGELOG/ROADMAP/prompt suivant
Si une correction de code ou de smoke apparaît ici, pre.014 ne l'absorbe pas : une nouvelle tranche technique est ouverte, puis la réconciliation documentaire est rejouée.
pre.015 — préparation de publication minimale
Payload fonctionnel strict :
workspace.package.version = 0.2.9-pre.15
prompt 0.2.10 OrbitFlare finalisé
CHANGELOG.md synchronisé pour 0.2.9
ROADMAP.md état global 0.2.9 / suite synchronisé
delta pre.015
Aucun README, USAGE, plan, validation, règle, code, test, schema ou config n'est modifié dans cette tranche. Si l'un de ces fichiers nécessite encore une correction, la tranche de publication est décalée après une nouvelle prerelease dédiée.
rel.001 — publication stable
rel.001 ne sert qu'à la mécanique de publication stable : version Cargo finale 0.2.9, delta de release, commit final et tag v0.2.9 après gate. Aucun rattrapage technique ou documentaire n'y est mélangé.
14. Critères de split
Scinder avant dette silencieuse si :
- une évolution upstream matérielle invalide le wire retenu ;
- PublicNode exige une divergence provider-specific significative ;
- le replay nécessite un sous-système de fork/equivocation plus large que la foundation ;
- une tranche dépasse nettement le budget nominal sans frontière claire ;
- le gate technique/live montre une dette dépendance/licence ou une non-régression qui ne peut pas être corrigée proprement dans son couloir ;
- une correction appartenant à un couloir déjà franchi est découverte pendant un couloir ultérieur.
Le noyau à préserver reste :
moteur Yellowstone + façade Solana standard + Config provider-neutral + première intégration PublicNode minimale
15. Gates opérateur restants
Le gate pre.013 est fermé. Gate pre.014 :
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.9
cargo test --workspace
Gate pre.015 : audit documentaire ciblé sur prompts/, CHANGELOG.md et ROADMAP.md, plus les validations minimales imposées par le changement de version Cargo. Aucun smoke n'est rejoué dans cette tranche en l'absence de changement technique.
16. Conditions de clôture 0.2.9
service/proto courant réconcilié
SubscribeDeshred explicitement OUT
7 unary verts
Subscribe standard et 9 updates verts
backend gRPC distinct de HTTP/WS
raw Tonic/Prost privé
secrets/metadata redacted
bounds/backpressure/shutdown verts
reconnect/replay documentés sans lossless implicite
Config V3 backward V1/V2
provider/protocol distincts
PublicNode Mainnet live Subscribe + slot PASS
PublicNode Testnet live Subscribe + slot PASS
auth PublicNode x-token secret documentée sans secret versionné
HTTP 52+14 non régressé
Standard WS 18/18 non régressé
Helius WS non régressé
cargo graphs finaux inspectés
README/USAGE finaux réconciliés en pre.014
validation 012 fermée en pre.014
prompt/CHANGELOG/ROADMAP seuls finalisés en pre.015
workspace final vert
17. Séquence après 0.2.9
La séquence active a été recalibrée par les fixes de pre.001; cette décision est conservée pendant le nettoyage documentaire :
0.2.9 moteur Yellowstone + Solana standard + PublicNode
0.2.10 OrbitFlare Yellowstone gRPC
0.2.11 Helius LaserStream gRPC
0.2.12 off-chain price transport
0.2.13 Price Desk + intégration prix Wallet Desk
0.2.14 interface/wire foundation
0.2.15 program-api foundation
Les intégrations suivantes restent dans le backlog non numéroté tant qu'aucune décision d'implémentation ne les fait entrer dans la séquence active :
TODO eRPC
TODO Triton
TODO Alchemy
TODO QuickNode
TODO Chainstack
IDEAS Tatum
IDEAS Shyft
IDEAS Solinfra
IDEAS NodeFlare
OrbitFlare reste le provider dédié 0.2.10 et Helius LaserStream gRPC 0.2.11 selon la séquence recalibrée par les fixes de pre.001. Chaque release doit réauditer auth, capabilities, restrictions, extensions wire, replay/from_slot et lifecycle au lieu de supposer une équivalence complète avec N2.