v0.2.10-pre.004

This commit is contained in:
2026-08-25 15:26:04 +02:00
parent be5e3464ee
commit 0edeed1c48
8 changed files with 493 additions and 245 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml # file: Cargo.toml
# version: 265 # version: 266
[workspace] [workspace]
resolver = "3" resolver = "3"
members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"] members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"]
[workspace.package] [workspace.package]
version = "0.2.10-pre.3" version = "0.2.10-pre.4"
edition = "2024" edition = "2024"
license = "MIT" license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-onchain-transport-lib/README.md --> <!-- file: crates/ksp-onchain-transport-lib/README.md -->
<!-- version: 23 --> <!-- version: 24 -->
# `ksp-onchain-transport-lib` # `ksp-onchain-transport-lib`
@@ -245,6 +245,8 @@ Config Transport V3 peut mapper des `grpc_endpoints` vers ces settings sans inve
Le smoke live opt-in ouvre un `Subscribe` slots authentifié sur PublicNode Mainnet et Testnet, attend un update `Slot` non nul puis ferme de manière bornée. Les deux endpoints sont versionnés. Le harness reçoit ses personal tokens sur stdin ; aucun secret nest committé ni placé dans lURL. Le même token a été validé par lopérateur sur les deux réseaux, même si Config conserve deux variables distinctes pour laisser cette policy flexible. Le smoke live opt-in ouvre un `Subscribe` slots authentifié sur PublicNode Mainnet et Testnet, attend un update `Slot` non nul puis ferme de manière bornée. Les deux endpoints sont versionnés. Le harness reçoit ses personal tokens sur stdin ; aucun secret nest committé ni placé dans lURL. Le même token a été validé par lopérateur sur les deux réseaux, même si Config conserve deux variables distinctes pour laisser cette policy flexible.
`0.2.10` ajoute le profil `orbitflare_devnet` sur le même moteur provider-neutral. Lendpoint validé est `http://devnet.rpc.orbitflare.com:10000`; la License Key `ORBIT-*` est fournie par Config via `KSP_SECRET_ORBITFLARE_DEVNET_GRPC_X_TOKEN` et devient la metadata secrète `x-token`. Le smoke live dédié a validé `Subscribe` slots à commitment confirmed, un `Slot` non nul et un `SubscribeUpdate::Ping` standard. Cette preuve confirme quaucune façade OrbitFlare, aucun heartbeat provider et aucune modification N1/N2 ne sont nécessaires.
## Résilience ## Résilience
L'admission est calculée par couple endpoint/rôle. Le pool applique : L'admission est calculée par couple endpoint/rôle. Le pool applique :
@@ -299,16 +301,20 @@ Transport WebSocket pur : settings programmatiques -> WsSession
Composition historique : Config -> std.transport/devnet_public -> HttpTransportPool Composition historique : Config -> std.transport/devnet_public -> HttpTransportPool
-> getHealth/getGenesisHash/getVersion/getBalance -> getHealth/getGenesisHash/getVersion/getBalance
Transport Yellowstone gRPC : settings programmatiques + x-token secret Transport Yellowstone gRPC PublicNode : settings programmatiques + x-token secret
-> PublicNode Mainnet + Testnet -> Mainnet + Testnet
-> TLS -> Subscribe slots -> Slot non nul -> close borné -> TLS -> Subscribe slots -> Slot non nul -> close borné
Transport Yellowstone gRPC OrbitFlare : settings programmatiques + License Key x-token
-> Devnet
-> Subscribe slots -> Slot non nul + server Ping -> close borné
``` ```
Le smoke HTTP Transport utilise pour sa branche Token la forme Devnet documentée `getTokenAccountsByOwner(owner, { programId }, { commitment: finalized, encoding: jsonParsed })`. L'owner est une Pubkey ordinaire de l'exemple officiel ; aucune présence de token account n'est exigée, donc une liste vide reste valide. Le smoke HTTP Transport utilise pour sa branche Token la forme Devnet documentée `getTokenAccountsByOwner(owner, { programId }, { commitment: finalized, encoding: jsonParsed })`. L'owner est une Pubkey ordinaire de l'exemple officiel ; aucune présence de token account n'est exigée, donc une liste vide reste valide.
Le smoke WebSocket Transport cible uniquement la famille stable `slotSubscribe` sur l'endpoint public Devnet `wss://api.devnet.solana.com`. Il borne connexion, attente de notification, unsubscribe et fermeture ; il ne transforme aucune famille unstable en gate live. Le smoke WebSocket Transport cible uniquement la famille stable `slotSubscribe` sur l'endpoint public Devnet `wss://api.devnet.solana.com`. Il borne connexion, attente de notification, unsubscribe et fermeture ; il ne transforme aucune famille unstable en gate live.
Les quatre tests sont `ignored` par défaut ; le test Yellowstone contient deux cas live Mainnet/Testnet. Les trois familles de smokes Transport appartiennent durablement à cette crate ; le smoke cross-crates hébergé dans Config reste transitoire jusqu'à l'existence d'une surface KSP d'intégration/orchestration appropriée. Un rate-limit, refus externe ou incident Devnet n'est pas assimilé automatiquement à une régression locale. Les cinq tests sont `ignored` par défaut ; le test PublicNode Yellowstone contient deux cas live Mainnet/Testnet et le test OrbitFlare contient un cas Devnet. Les trois familles de smokes Transport appartiennent durablement à cette crate ; le smoke cross-crates hébergé dans Config reste transitoire jusqu'à l'existence d'une surface KSP d'intégration/orchestration appropriée. Un rate-limit, refus externe ou incident Devnet n'est pas assimilé automatiquement à une régression locale.
Aucun smoke Helius live supplémentaire nest committé en `0.2.8-pre.010`. Un tel test devrait à la fois obtenir `KSP_SECRET_HELIUS_API_KEY` via Config et exercer Transport ; lajouter dans Transport violerait lownership environnement/secret, tandis que lajouter dans Config étendrait lexception cross-crates que le projet veut au contraire résorber. La première surface KSP dintégration/orchestration dédiée devra héberger ce smoke. Le scénario live recommandé est alors `helius_devnet -> HeliusLaserStreamWsSession -> slotSubscribe -> notification -> unsubscribe -> close`; `transactionSubscribe` reste un smoke optionnel dépendant des droits provider et ne devient pas un gate stable de release. Aucun smoke Helius live supplémentaire nest committé en `0.2.8-pre.010`. Un tel test devrait à la fois obtenir `KSP_SECRET_HELIUS_API_KEY` via Config et exercer Transport ; lajouter dans Transport violerait lownership environnement/secret, tandis que lajouter dans Config étendrait lexception cross-crates que le projet veut au contraire résorber. La première surface KSP dintégration/orchestration dédiée devra héberger ce smoke. Le scénario live recommandé est alors `helius_devnet -> HeliusLaserStreamWsSession -> slotSubscribe -> notification -> unsubscribe -> close`; `transactionSubscribe` reste un smoke optionnel dépendant des droits provider et ne devient pas un gate stable de release.
@@ -324,4 +330,6 @@ Aucun smoke Helius live supplémentaire nest committé en `0.2.8-pre.010`. Un
- [`../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée `52/52 + 14/14` et audit `KSP-TRANSPORT-007` global ; - [`../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée `52/52 + 14/14` et audit `KSP-TRANSPORT-007` global ;
- [`../../docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md`](../../docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md) — plan Yellowstone gRPC standard/provider-neutral et PublicNode ; - [`../../docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md`](../../docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md) — plan Yellowstone gRPC standard/provider-neutral et PublicNode ;
- [`../../docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md`](../../docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md) — matrice de compliance Yellowstone ; - [`../../docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md`](../../docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md) — matrice de compliance Yellowstone ;
- [`../../docs/plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md`](../../docs/plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md) — composition OrbitFlare Devnet sur le standard Yellowstone ;
- [`../../docs/validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md`](../../docs/validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md) — validation finale OrbitFlare `x-token`, `Slot + Ping` et non-régression N1/N2 ;
- [`../../config/std.transport.json`](../../config/std.transport.json) — configuration standard Transport V3 HTTP + WebSocket + gRPC, avec lecture backward V1/V2. - [`../../config/std.transport.json`](../../config/std.transport.json) — configuration standard Transport V3 HTTP + WebSocket + gRPC, avec lecture backward V1/V2.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-onchain-transport-lib/USAGE.md --> <!-- file: crates/ksp-onchain-transport-lib/USAGE.md -->
<!-- version: 22 --> <!-- version: 23 -->
# Utilisation de `ksp-onchain-transport-lib` # Utilisation de `ksp-onchain-transport-lib`
@@ -331,6 +331,36 @@ let channel = ksp_onchain_transport_lib::YellowstoneGrpcChannel::connect(endpoin
`protocol = solana_yellowstone` est validé par Config et reste distinct du descripteur `provider`. Une valeur provider nautorise pas Transport à introduire une API provider-specific sans divergence réelle. `protocol = solana_yellowstone` est validé par Config et reste distinct du descripteur `provider`. Une valeur provider nautorise pas Transport à introduire une API provider-specific sans divergence réelle.
### Profil OrbitFlare Devnet
Le profil committé `orbitflare_devnet` réutilise exactement le même accès Config -> Transport :
```rust
let resolved = match engine.load_resolved_transport_config(Some("orbitflare_devnet"), &environment) {
Ok(value) => value,
Err(error) => return Err(error),
};
let grpc_settings = match resolved.grpc_settings() {
Some(value) => value,
None => return Err(ksp_core_lib::Error::new(
ksp_onchain_transport_lib::ERROR_CODE_INVALID_SETTINGS,
"selected OrbitFlare profile has no Yellowstone gRPC endpoint",
)),
};
let endpoint = match grpc_settings.endpoints().iter().find(|candidate| candidate.enabled()) {
Some(value) => value,
None => return Err(ksp_core_lib::Error::new(
ksp_onchain_transport_lib::ERROR_CODE_INVALID_SETTINGS,
"selected OrbitFlare profile has no enabled Yellowstone gRPC endpoint",
)),
};
let channel = ksp_onchain_transport_lib::YellowstoneGrpcChannel::connect(endpoint).await;
```
Config résout `KSP_SECRET_ORBITFLARE_DEVNET_GRPC_X_TOKEN` vers la metadata secrète `x-token`. Sa valeur effective est la License Key `ORBIT-*` du produit Solana ; `X-ORBIT-KEY` et le Bearer du Customer API ne doivent pas être utilisés pour Yellowstone. Transport ne lit jamais cette variable lui-même.
Lendpoint validé par `0.2.10` est `http://devnet.rpc.orbitflare.com:10000`. Il reste volontairement en `http` : KSP ne remplace pas le transport provider par `https` sans endpoint TLS explicitement fourni.
### Subscribe bidirectionnel ### Subscribe bidirectionnel
Une session standard part dune requête typed complète : Une session standard part dune requête typed complète :
@@ -519,6 +549,26 @@ Testnet https://solana-testnet-yellowstone-grpc.publicnode.com:443
Les profils Config conservent deux variables secrètes distinctes afin d'autoriser des credentials différents si nécessaire ; cette séparation ne signifie pas que PublicNode impose actuellement un token différent par réseau. Un timeout KSP de half-close après réception du slot est accepté par le smoke comme fermeture bornée du provider ; aucune absence de slot ni autre erreur n'est masquée. Les profils Config conservent deux variables secrètes distinctes afin d'autoriser des credentials différents si nécessaire ; cette séparation ne signifie pas que PublicNode impose actuellement un token différent par réseau. Un timeout KSP de half-close après réception du slot est accepté par le smoke comme fermeture bornée du provider ; aucune absence de slot ni autre erreur n'est masquée.
Le smoke **Transport Yellowstone gRPC OrbitFlare** est lui aussi indépendant de Config. Il lit une seule License Key sur stdin, la classe comme metadata secrète `x-token`, ouvre le standard `Subscribe`, demande `slots` à commitment confirmed, attend un Slot non nul et un `SubscribeUpdate::Ping`, puis ferme la session de manière bornée :
```bash
read -rsp 'OrbitFlare License Key: ' ORBITFLARE_LICENSE_KEY
echo
printf '%s\n' "$ORBITFLARE_LICENSE_KEY" \
| cargo test -p ksp-onchain-transport-lib \
--test yellowstone_orbitflare_smoke \
-- --ignored --nocapture
unset ORBITFLARE_LICENSE_KEY
```
Endpoint validé :
```text
Devnet http://devnet.rpc.orbitflare.com:10000
```
Le gate `0.2.10-pre.003` a passé ce scénario en live avec `Slot + Ping`. Le Ping reçu est le message Yellowstone standard auquel N1 sait déjà répondre sans remplacer la dernière requête complète mémorisée ; aucun heartbeat OrbitFlare supplémentaire nest donc requis.
Le smoke de **composition Config -> Transport** reste également disponible : Le smoke de **composition Config -> Transport** reste également disponible :
```bash ```bash

128
deltas/0.2.10/pre.004.md Normal file
View File

@@ -0,0 +1,128 @@
<!-- file: deltas/0.2.10/pre.004.md -->
<!-- version: 1 -->
# Delta `0.2.10-pre.004` — réconciliation documentaire finale OrbitFlare Yellowstone
## 1. Base
```text
0.2.10-pre.003
```
Cette tranche est exclusivement le couloir de réconciliation documentaire finale. Le gate technique/live de `pre.003` est vert ; aucun correctif runtime, Config exécutable, test, schema, dependency ou feature n'est introduit ici.
## 2. Version technique
Comme toute prerelease non-fix, la version Cargo est synchronisée mécaniquement :
```text
workspace.package.version = 0.2.10-pre.4
```
Aucune sémantique runtime ne change.
## 3. Preuve technique réconciliée
Le gate opérateur `pre.003` du 2026-08-25 est fermé avec :
```text
cargo fmt --all PASS
Rust workspace audit PASS / 0 export candidate
Markdown audit PASS / 99 tables / 100 files
cargo check --workspace PASS
cargo clippy --workspace --all-targets PASS
Config unit 114/114 PASS
Config ownership 5/5 PASS
Config public API 15/15 PASS
Transport unit 383/383 PASS
Transport public API 49/49 PASS
Transport release completeness 43/43 PASS
Transport doctests 4/4 PASS
workspace dependency canary 3/3 PASS
cargo test --workspace PASS
OrbitFlare Devnet Subscribe + Slot + Ping 1/1 PASS, 5.19 s
```
Les graphes Cargo direct Transport, doublons Transport et doublons workspace ont été inspectés. La pile reste :
```text
yellowstone-grpc-proto 12.6.0
tonic / tonic-prost 0.14.6
prost / prost-types 0.14.4
```
Aucun `yellowstone-grpc-client` runtime, aucun `orbitflare-sdk` runtime et aucune dépendance `Transport -> Config` n'ont été ajoutés.
## 4. OrbitFlare final
Contrat durable réconcilié :
```text
Devnet endpoint http://devnet.rpc.orbitflare.com:10000
auth License Key ORBIT-* -> secret metadata x-token
Config secret KSP_SECRET_ORBITFLARE_DEVNET_GRPC_X_TOKEN
Subscribe standard Yellowstone N2
live Slot non nul + server Ping
N1 inchangé
N2 inchangé
provider facade non nécessaire
heartbeat N3 non nécessaire
Config V4 non nécessaire
```
Le premier échec `pre.002` sans metadata reste conservé dans son delta historique comme caractérisation ayant conduit au fix d'auth `pre.002-fix.001`.
## 5. Documents réconciliés
```text
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md
docs/validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
docs/000-README.md
```
Les anciennes affirmations `PENDING` sont remplacées par les résultats `pre.003` réellement observés. README/USAGE documentent désormais le profil OrbitFlare Devnet et son smoke live durable.
## 6. Frontière avec `pre.005`
Cette tranche ne touche pas :
```text
CHANGELOG.md
ROADMAP.md
prompt suivant
```
La décision sur la release suivante est prise pendant cette réconciliation, sans générer encore son prompt : Helius LaserStream gRPC est reporté dans les TODO Yellowstone sans numéro de release faute d'accès live raisonnable ; la séquence active avance et `0.2.11` devient `off-chain price transport`, suivie de `0.2.12` Price Desk + intégration Wallet Desk, `0.2.13` interface/wire foundation et `0.2.14` program-api foundation. Le futur `ROADMAP.md` de `pre.005` devra refléter exactement ce report et cette renumérotation.
Une fois cette décision prise, `pre.005` reste strictement publication-minimal : prompt suivant + `CHANGELOG.md` + `ROADMAP.md` + signal Cargo + delta.
Si un défaut technique de `0.2.10` est découvert après ce gate documentaire, il ne doit pas être glissé dans `pre.005`; ouvrir une nouvelle prerelease du couloir approprié puis rejouer les tranches finales nécessaires.
## 7. Fichiers modifiés/ajoutés
```text
Cargo.toml
docs/000-README.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md
docs/validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
deltas/0.2.10/pre.004.md
```
## 8. Gate opérateur
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.10
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test --workspace
```
Aucun smoke live ni `cargo tree` n'est à rejouer si le delta est appliqué exactement : aucune surface technique ou dépendance n'est modifiée.

File diff suppressed because one or more lines are too long

View File

@@ -365,11 +365,10 @@ Par défaut :
0.2.8 Helius LaserStream WebSocket 0.2.8 Helius LaserStream WebSocket
0.2.9 Yellowstone gRPC engine + Solana standard + PublicNode 0.2.9 Yellowstone gRPC engine + Solana standard + PublicNode
0.2.10 OrbitFlare Yellowstone gRPC 0.2.10 OrbitFlare Yellowstone gRPC
0.2.11 Helius LaserStream gRPC 0.2.11 off-chain price transport
0.2.12 off-chain price transport 0.2.12 price visualization desk + intégration prix dans Wallet Desk
0.2.13 price visualization desk + intégration prix dans Wallet Desk 0.2.13 interface/wire foundation
0.2.14 interface/wire foundation 0.2.14 program-api foundation
0.2.15 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. `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.
@@ -487,15 +486,12 @@ Mission active : obtenir en priorité un provider Yellowstone gratuit sur **Devn
Le plan actif est [`017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md`](017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md) et la matrice active [`../validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md`](../validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md). Le plan actif est [`017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md`](017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md) et la matrice active [`../validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md`](../validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md).
### `0.2.11` — Helius LaserStream gRPC
Cette release réauditera Helius indépendamment après fermeture stable de `0.2.10`. Elle réutilisera le même moteur N1 et le standard N2 sans les modifier ; seules les capacités, restrictions, auth et policies provider démontrées pourront être ajoutées au-dessus.
### TODO/IDEAS — providers Yellowstone en attente ### TODO/IDEAS — providers Yellowstone en attente
Aucune release n'est réservée pour : Aucune release n'est réservée pour :
```text ```text
TODO Helius LaserStream gRPC — réauditer lorsque l'accès live gRPC est disponible
TODO eRPC TODO eRPC
TODO Triton TODO Triton
TODO Alchemy TODO Alchemy
@@ -508,23 +504,25 @@ IDEAS NodeFlare
IDEAS autres providers à réauditer IDEAS autres providers à réauditer
``` ```
Helius LaserStream gRPC est explicitement reporté : l'audit 2026-08-25 indique une compatibilité wire Yellowstone élevée et une intégration KSP probablement légère au-dessus de N1/N2, mais aucun accès live Helius gRPC n'est actuellement disponible sans plan payant. Il ne reçoit donc plus de numéro de release tant que l'auth, les endpoints, le Subscribe, le Ping, le replay/from_slot et les erreurs provider ne peuvent pas être validés live. Les extensions Helius non standard, notamment les preprocessed transactions, restent un sujet provider séparé.
Ces providers ne déplacent pas la séquence active et ne reçoivent ni façade, ni Config profile, ni smoke tant qu'une décision explicite d'implémentation n'est pas prise. Ces providers ne déplacent pas la séquence active et ne reçoivent ni façade, ni Config profile, ni smoke tant qu'une décision explicite d'implémentation n'est pas prise.
### `0.2.12` / `0.2.13` — Off-chain price + app ### `0.2.11` / `0.2.12` — Off-chain price + app
`0.2.12` introduit `ksp-offchain-transport-lib` avec au minimum SOL/USD et SOL/EUR via une abstraction indépendante du premier provider. `0.2.11` introduit `ksp-offchain-transport-lib` avec au minimum SOL/USD et SOL/EUR via une abstraction indépendante du premier provider.
`0.2.13` 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.12` 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. Metadata HTTP/IPFS/Arweave viendra au premier besoin Metadata réel.
### `0.2.14` — Interface foundation ### `0.2.13` — Interface foundation
`ksp-interface-lib` devient la façade wire officielle et expose une API publique wire utilisable par les implementations officielles et externes. `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. Aucune `ksp-interface-api` séparée n'est retenue pour l'instant.
### `0.2.15` — Program API foundation ### `0.2.14` — Program API foundation
Introduire `ksp-program-api`, sans suffixe `-lib`, comme contrat d'extension Program. Introduire `ksp-program-api`, sans suffixe `-lib`, comme contrat d'extension Program.

View File

@@ -1,9 +1,9 @@
<!-- file: docs/plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md --> <!-- file: docs/plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md -->
<!-- version: 3 --> <!-- version: 4 -->
# Plan `0.2.10` — OrbitFlare Yellowstone gRPC # Plan `0.2.10` — OrbitFlare Yellowstone gRPC
**Statut courant : `0.2.10-pre.002-fix.001` corrige lhypothèse dauth de `pre.002`. Le live sans metadata a atteint OrbitFlare puis `SubscribeOpen` a été rejeté `Unauthenticated`. Le Dashboard opérateur et la référence Yellowstone OrbitFlare établissent désormais que la License Key `ORBIT-*` du produit Solana Free doit être envoyée comme metadata secrète `x-token`. Config V3 et le smoke sont corrigés sans aucune modification N1/N2 ; le rerun authentifié `Slot + Ping` reste le gate live.** **Statut courant : le gate technique/live final `0.2.10-pre.003` est vert. OrbitFlare Devnet est validé avec la License Key `ORBIT-*` portée par la metadata secrète `x-token` ; le smoke final observe un Slot non nul puis le `SubscribeUpdate::Ping` Yellowstone standard et ferme proprement la session. N1 et N2 restent inchangés, aucune façade provider ni heartbeat N3 nest nécessaire. `0.2.10-pre.004` est exclusivement la réconciliation documentaire finale.**
## 1. Base et autorité ## 1. Base et autorité
@@ -326,23 +326,31 @@ Cette propriété est testée déterministiquement par le moteur N1.
### 8.4 Décision `pre.001` ### 8.4 Décision `pre.001`
**Aucun heartbeat OrbitFlare supplémentaire n'est retenu à ce stade.** La décision initiale de ne pas modifier le moteur est confirmée par le live final.
Le premier smoke Devnet doit vérifier que l'endpoint OrbitFlare émet bien le `SubscribeUpdate::Ping` standard. Si ce Ping live est observé, la combinaison suivante suffit : Le smoke authentifié `pre.002-fix.001`, puis son rerun dans `pre.003`, ont observé le `SubscribeUpdate::Ping` standard sur OrbitFlare Devnet :
```text ```text
OrbitFlare server Ping live OrbitFlare server Ping live
+ +
KSP N1 automatic Ping reply deterministic test KSP N1 automatic Ping reply deterministic test
= =
client-side activity périodique sans code provider supplémentaire activité bidirectionnelle standard suffisante sans code provider supplémentaire
``` ```
Il est interdit d'ajouter un timer dans `grpc_stream.rs` ou `YellowstoneGrpcSessionSettings` pour OrbitFlare. Résultat final :
Si le live montre qu'OrbitFlare ne produit pas le Ping standard ou exige réellement un heartbeat proactif indépendant, cela ouvre un **gate provider spécifique séparé**. La solution doit alors être composée au-dessus de N1 sans modifier le moteur et sans corrompre la requête de reconnect mémorisée. ```text
heartbeat OrbitFlare N3 non nécessaire
façade provider non nécessaire
YellowstoneGrpcSessionSettings inchangé
grpc_stream.rs inchangé
latest_request reconnect sémantique N1 préservée
```
Point de sécurité important : appeler naïvement la mutation standard avec un request `ping` seul n'est pas acceptable, car le moteur mémorise la dernière mutation complète pour le replay/reconnect. Une éventuelle façade provider doit préserver cette sémantique au lieu de contourner N1. Il reste interdit d'ajouter un timer dans `grpc_stream.rs` ou `YellowstoneGrpcSessionSettings` pour OrbitFlare. La recommandation provider dun ping client périodique ne devient pas une policy globale tant que le chemin standard serveur Ping -> réponse automatique N1 satisfait le service live.
Le point de sécurité initial reste durable : envoyer naïvement une requête `ping` seule via la mutation publique remplacerait la dernière subscription mémorisée pour reconnect. Si un futur provider exige un heartbeat proactif indépendant, cette policy doit être composée au-dessus de N1 sans corrompre cette sémantique.
## 9. Capabilities OrbitFlare ## 9. Capabilities OrbitFlare
@@ -366,7 +374,7 @@ Le CLI/SDK montre également les filtres account/transaction/slot/block standard
### 9.2 Surface non encore prouvée provider ### 9.2 Surface non encore prouvée provider
Ces capacités existent dans N2 KSP mais ne sont pas déclarées supportées sur OrbitFlare sans preuve supplémentaire : Ces capacités existent dans N2 KSP mais n'ont pas été exhaustivement sondées sur le plan OrbitFlare Free pendant `0.2.10` :
```text ```text
SubscribeReplayInfo SubscribeReplayInfo
@@ -381,16 +389,18 @@ transactions_status complet
champs récents compressed/cuckoo/token expansion selon endpoint déployé champs récents compressed/cuckoo/token expansion selon endpoint déployé
``` ```
L'absence de documentation n'est pas une preuve d'absence. Le live provider doit distinguer : La clôture de `0.2.10` ne transforme pas l'absence de probe en absence de support. Le live final requis portait sur le chemin opérationnel utile à la release : authentification, standard Subscribe, Slot, Ping serveur et close borné.
Classification durable :
```text ```text
standard KSP disponible standard KSP disponible oui dans N2
provider support prouvé provider support live prouvé Subscribe slots + commitment + Ping
provider entitlement éventuel provider entitlement éventuel provider-owned
unknown non testé reste unknown / non exhaustivement testé
``` ```
Aucune capacité N2 n'est supprimée du standard global à cause d'une restriction OrbitFlare. Aucune capacité N2 n'est supprimée du standard global à cause d'une restriction ou d'un inconnu OrbitFlare.
## 10. Limits et quotas utiles ## 10. Limits et quotas utiles
@@ -401,7 +411,7 @@ La documentation actuelle des services partagés indique :
| connexions gRPC simultanées | 50 par IP | information provider, pas borne N1 | | connexions gRPC simultanées | 50 par IP | information provider, pas borne N1 |
| portée du cap | globale par IP et régions gRPC partagées | éviter les reconnect storms | | portée du cap | globale par IP et régions gRPC partagées | éviter les reconnect storms |
| subscriptions par connexion | unlimited | ne pas convertir en garantie universelle | | subscriptions par connexion | unlimited | ne pas convertir en garantie universelle |
| idle timeout | environ 10 minutes | gate heartbeat live | | idle timeout | environ 10 minutes | chemin Ping standard validé live |
| dépassement | gRPC `RESOURCE_EXHAUSTED` | status distant safe existant | | dépassement | gRPC `RESOURCE_EXHAUSTED` | status distant safe existant |
| reconnect conseillé | exponential backoff | KSP N1 possède déjà un budget/backoff borné | | reconnect conseillé | exponential backoff | KSP N1 possède déjà un budget/backoff borné |
@@ -459,35 +469,50 @@ cluster = devnet
protocol = solana_yellowstone protocol = solana_yellowstone
auth = x-token <- License Key lue sur stdin auth = x-token <- License Key lue sur stdin
request = Subscribe slots à commitment confirmed request = Subscribe slots à commitment confirmed
preuve = au moins un Slot non nul preuve = au moins un Slot non nul + SubscribeUpdate::Ping
close = borné close = borné
``` ```
La valeur secrète ne doit apparaître ni dans Debug ni dans la ligne de commande. La valeur secrète n'apparaît ni dans Debug ni dans la ligne de commande.
Résultats opérateur :
```text
pre.002-fix.001 Subscribe -> Slot + Ping PASS en 5.10 s
pre.003 final Subscribe -> Slot + Ping PASS en 5.19 s
```
Le second passage ferme le gate live sur la version `0.2.10-pre.3` utilisée pour la clôture technique.
### 12.3 Preuve heartbeat ### 12.3 Preuve heartbeat
Le smoke corrigé attend encore suffisamment pour observer : Le `SubscribeUpdate::Ping` standard est observé live sur OrbitFlare Devnet avec l'auth correcte.
La combinaison suivante est donc prouvée :
```text ```text
SubscribeUpdate::Ping Subscribe authentifié
-> Slot non nul
-> SubscribeUpdate::Ping serveur
-> chemin de réponse automatique N1 déjà couvert déterministiquement
-> close borné
``` ```
Un `Ping` serveur live, combiné au test déterministe N1 qui prouve la réponse automatique, ferme le besoin heartbeat sans code OrbitFlare. Si aucun Ping serveur nest observé après authentification, cette divergence est traitée dans une tranche provider dédiée au-dessus de N1/N2. Verdict final : aucune divergence heartbeat OrbitFlare ne justifie une façade ou une policy provider. Le moteur gRPC et le standard Yellowstone restent inchangés.
Le smoke final durable peut rester court après cette caractérisation ; il na pas besoin de patienter 10 minutes à chaque workspace run.
### 12.4 Unary et replay ### 12.4 Unary et replay
Après le canari Subscribe authentifié : Les sept unary N2, `SubscribeReplayInfo` et la retention `from_slot` n'ont pas été rendus obligatoires pour le gate OrbitFlare Free.
Cette décision évite de confondre :
```text ```text
probe 7 unary N2 complétude du standard KSP N2
probe SubscribeReplayInfo support/entitlement d'un provider particulier
probe from_slot si support observable preuve minimale nécessaire à la mission Devnet de 0.2.10
``` ```
Les probes provider ne doivent pas rendre indisponible le smoke minimal `Subscribe -> Slot` si le plan gratuit restreint certaines unary. Le moteur N1 reste capable d'utiliser `SubscribeReplayInfo` quand il est disponible et tolère son indisponibilité pendant reconnect en poursuivant avec le `from_slot` conservateur demandé. Aucun comportement provider n'est introduit pour combler un inconnu de service.
## 13. Threat model recalibré ## 13. Threat model recalibré
@@ -541,44 +566,25 @@ README/USAGE dans la tranche documentaire finale
## 15. Forecast recalibré ## 15. Forecast recalibré
Le fix dauth ne change pas lordre des couloirs finaux. Le chemin effectif de `0.2.10` est désormais figé :
```text ```text
pre.001 audit actuel + architecture immuable N1/N2 + auth/endpoints + free Devnet + heartbeat + sizing pre.001 audit actuel + architecture immuable N1/N2 + auth/endpoints + Free Devnet + heartbeat + sizing
preuve : plan 017 + validation 013 + delta + baseline pre.002 profil Config V3 OrbitFlare Devnet + smoke de caractérisation sans metadata
pre.002-fix.001 auth corrigée : License Key -> secret x-token ; live Subscribe -> Slot + Ping PASS
pre.002 profil Config V3 OrbitFlare Devnet + smoke de caractérisation standard N2 pre.003 gate technique/live final ; workspace + graphes + rerun OrbitFlare PASS
hypothèse initiale sans metadata ; live classifie Unauthenticated au SubscribeOpen pre.004 réconciliation documentaire finale
pre.005 publication minimale après décision explicite sur la release suivante
pre.002-fix.001 rel.001 publication stable stricte
corrige lauth par License Key -> secret x-token
adapte .env.example, Config test et smoke stdin
live : Subscribe -> Slot + observation Ping serveur ; aucune modification moteur gRPC
pre.003 soit gate technique/live final si le rerun authentifié reste 100 pourcent standard,
soit tranche provider-specific minimale uniquement si le live démontre une divergence heartbeat réelle
pre.004 gate technique/live final si pre.003 a porté une divergence ; sinon réconciliation documentaire finale
pre.005 publication minimale si pre.004 est documentaire ; sinon réconciliation documentaire finale
pre.006 publication minimale uniquement si la divergence a décalé les couloirs précédents
rel.001 publication stable stricte
``` ```
Chemins effectifs : La branche de divergence heartbeat n'a pas été déclenchée. Aucun couloir supplémentaire n'est requis.
```text Le numéro n'est jamais le critère de clôture ; l'ordre technique, documentaire puis publication reste obligatoire.
standard pre.001 -> pre.002 -> pre.002-fix.001 -> pre.003 technique -> pre.004 docs -> pre.005 publication -> rel.001
divergence pre.001 -> pre.002 -> pre.002-fix.001 -> pre.003 provider -> pre.004 technique -> pre.005 docs -> pre.006 publication -> rel.001
```
Le numéro nest jamais le critère de clôture ; lordre technique, documentaire, publication reste obligatoire.
## 16. Critères de split ## 16. Critères de split
Ouvrir une tranche provider dédiée avant le gate final si et seulement si le live démontre l'un de ces cas : Les critères de split définis pendant l'audit étaient :
```text ```text
OrbitFlare n'émet pas le Ping standard et exige un Ping client proactif OrbitFlare n'émet pas le Ping standard et exige un Ping client proactif
@@ -589,39 +595,65 @@ le replay/from_slot exige une policy provider visible au consumer
un failover provider impose une sémantique que N1 ne peut pas composer sans modification un failover provider impose une sémantique que N1 ne peut pas composer sans modification
``` ```
Dans le dernier cas, ne pas modifier N1 dans `0.2.10` : qualifier le blocker et replanifier l'architecture. **Aucun de ces critères n'a été déclenché par le gate live final.**
Le principe reste durable pour les providers futurs : si une divergence ne peut pas être composée proprement au-dessus de N1/N2, ne pas modifier le moteur pour le provider ; qualifier le blocker et replanifier l'architecture.
## 17. Critères de clôture ## 17. Critères de clôture
`0.2.10` est stable seulement si : État à l'entrée de `pre.004` :
```text ```text
Devnet OrbitFlare Free réellement atteint par KSP ou bloc externe qualifié Devnet OrbitFlare Free atteint par KSP PASS
N1 gRPC inchangé N1 gRPC inchangé PASS
N2 Yellowstone inchangé N2 Yellowstone inchangé PASS
aucun SDK OrbitFlare runtime aucun SDK OrbitFlare runtime PASS
provider/auth correctement classifiés provider/auth correctement classifiés PASS
aucune Customer API key sur le data-plane Yellowstone aucune Customer API key sur le data-plane Yellowstone PASS
heartbeat live classifié heartbeat live classifié PASS
Config V3 cohérente sans nouveau format inutile Config V3 cohérente sans nouveau format PASS
smoke provider architecture-safe smoke provider architecture-safe PASS
PublicNode non régressé PublicNode non régressé déterministiquement PASS
Yellowstone standard non régressé Yellowstone standard non régressé PASS
HTTP 52+14 non régressé HTTP 52+14 non régressé PASS
WebSocket standard 18/18 non régressé WebSocket standard 18/18 non régressé PASS
Helius WebSocket non régressé Helius WebSocket non régressé PASS
workspace complet vert workspace complet vert PASS
graphes Cargo inspectés graphes Cargo inspectés PASS
réconciliation documentaire séparée réconciliation documentaire séparée EN COURS pre.004
publication minimale séparée publication minimale séparée À FAIRE pre.005
``` ```
Le gate technique est donc fermé. La stabilité `0.2.10` reste conditionnée à la validation documentaire `pre.004`, au couloir publication-minimal `pre.005`, puis à `rel.001`.
## 18. Release suivante ## 18. Release suivante
La release suivante reste : La décision préalable à `pre.005` est désormais prise. L'ancien forecast :
```text ```text
0.2.11 — Helius LaserStream gRPC 0.2.11 — Helius LaserStream gRPC
``` ```
Elle doit appliquer le même invariant : le moteur gRPC `0.2.9` est une fondation stable ; Helius ne peut ajouter que des fonctionnalités provider au-dessus. est reporté dans les TODO Yellowstone sans numéro de release. L'audit du 2026-08-25 conclut que la surface Helius reste largement wire-compatible Yellowstone et pourrait probablement se composer au-dessus de N1/N2, mais l'accès gRPC Helius exige actuellement un plan payant que l'opérateur ne retient pas uniquement pour ce test. La release provider est donc différée jusqu'à disponibilité d'un accès live permettant de valider réellement auth, endpoints, Subscribe, Ping, replay/from_slot et erreurs provider. Les extensions Helius non standard restent un sujet séparé.
La séquence active avance d'un cran :
```text
0.2.11 — off-chain price transport
0.2.12 — Price Desk + intégration prix Wallet Desk
0.2.13 — interface/wire foundation
0.2.14 — program-api foundation
```
Décision de publication :
```text
aucun prompt suivant dans pre.004
aucun changement CHANGELOG/ROADMAP dans pre.004
Helius gRPC -> TODO futur sans numéro
0.2.11 -> off-chain price transport
pre.005 préparera seulement le prompt 0.2.11 + CHANGELOG + ROADMAP
```
Quel que soit le provider futur, l'invariant reste le même : N1 gRPC et N2 Yellowstone sont des fondations stables ; les différences provider se composent au-dessus et ne modifient jamais le moteur pour satisfaire un fournisseur.

View File

@@ -1,9 +1,9 @@
<!-- file: docs/validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md --> <!-- file: docs/validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md -->
<!-- version: 3 --> <!-- version: 4 -->
# Validation `0.2.10` — OrbitFlare Yellowstone gRPC # Validation `0.2.10` — OrbitFlare Yellowstone gRPC
**Statut courant : `0.2.10-pre.002` est commité et son gate statique/workspace est vert. Son live sans metadata a atteint OrbitFlare mais `SubscribeOpen` a été rejeté `Unauthenticated`. `0.2.10-pre.002-fix.001` corrige lauth en License Key `ORBIT-*` transmise comme secret `x-token`, sans modification N1/N2. Le rerun authentifié `Subscribe -> Slot + Ping` reste `PENDING OPERATOR`.** **Statut courant : `0.2.10-pre.003` ferme le gate technique/live final. Le workspace complet est vert, les graphes Cargo ont été inspectés et le smoke OrbitFlare Devnet authentifié par License Key `ORBIT-*` en secret `x-token` observe `Subscribe -> Slot + Ping` puis ferme proprement. N1/N2 restent inchangés ; `pre.004` réconcilie uniquement la documentation finale.**
## 1. Autorités ## 1. Autorités
@@ -63,7 +63,7 @@ Toute modification de `grpc_stream.rs`, `grpc_channel.rs`, `grpc_settings.rs`, `
| TPS Free | 1 | INFO | | TPS Free | 1 | INFO |
| crédit | unlimited dans le RPS | INFO | | crédit | unlimited dans le RPS | INFO |
| Devnet gRPC endpoint | `http://devnet.rpc.orbitflare.com:10000` | **PASS** | | Devnet gRPC endpoint | `http://devnet.rpc.orbitflare.com:10000` | **PASS** |
| Devnet live KSP | service atteint, Subscribe auth rejeté | **AUTH GATE** | | Devnet live KSP | Subscribe authentifié, Slot + Ping | **PASS LIVE** |
| Mainnet gratuit | non documenté | **OUT** | | Mainnet gratuit | non documenté | **OUT** |
| Testnet endpoint | non prouvé | **UNKNOWN** | | Testnet endpoint | non prouvé | **UNKNOWN** |
@@ -114,50 +114,50 @@ Le CLI OrbitFlare courant nest pas utilisé comme oracle positif pour laut
## 7. Heartbeat ## 7. Heartbeat
| Point | Preuve | Verdict | | Point | Preuve | Verdict |
|----------------------------------------|------------------------------------------|-------------| |----------------------------------------|---------------------------------------------|----------|
| OrbitFlare idle timeout partagé | environ 10 minutes | **PASS** | | OrbitFlare idle timeout partagé | environ 10 minutes | **PASS** |
| OrbitFlare recommande client Ping | 30 secondes | **PASS** | | OrbitFlare recommande client Ping | 30 secondes | **PASS** |
| Yellowstone serveur Ping périodique | upstream documenté | **PASS** | | Yellowstone serveur Ping périodique | upstream documenté | **PASS** |
| KSP auto reply au serveur Ping | test N1 `0.2.9` | **PASS** | | KSP auto reply au serveur Ping | test N1 `0.2.9` et non-régression `pre.003` | **PASS** |
| moteur N1 à modifier | non | **PASS** | | moteur N1 à modifier | non | **PASS** |
| Ping serveur OrbitFlare Devnet observé | live non encore exécuté | **PENDING** | | Ping serveur OrbitFlare Devnet observé | live `pre.002-fix.001` + `pre.003` | **PASS** |
| heartbeat provider additionnel | non justifié tant que live non contraire | **NO** | | heartbeat provider additionnel | aucune divergence live | **NO** |
Critère de fermeture : observer le Ping standard sur OrbitFlare Devnet ou qualifier précisément pourquoi il n'est pas observable et quelle divergence provider existe. Le gate est fermé : OrbitFlare émet le Ping Yellowstone standard et le chemin de réponse automatique N1 reste suffisant sans timer provider.
## 8. Capabilities streaming ## 8. Capabilities streaming
| Capability | Docs OrbitFlare | KSP N2 | Live provider | | Capability | Docs OrbitFlare | KSP N2 | Live provider |
|---------------------|-----------------|--------|---------------| |---------------------|-----------------|--------|--------------------------|
| accounts | oui | PASS | PENDING | | accounts | oui | PASS | non sondé exhaustivement |
| slots | oui | PASS | PENDING | | slots | oui | PASS | **PASS** |
| transactions | oui | PASS | PENDING | | transactions | oui | PASS | non sondé exhaustivement |
| transactions_status | partiel | PASS | PENDING | | transactions_status | partiel | PASS | non sondé exhaustivement |
| blocks | oui | PASS | PENDING | | blocks | oui | PASS | non sondé exhaustivement |
| blocks_meta | oui | PASS | PENDING | | blocks_meta | oui | PASS | non sondé exhaustivement |
| entry | oui | PASS | PENDING | | entry | oui | PASS | non sondé exhaustivement |
| commitment | oui | PASS | PENDING | | commitment | oui | PASS | **PASS confirmed** |
| accounts_data_slice | oui | PASS | PENDING | | accounts_data_slice | oui | PASS | non sondé exhaustivement |
| Subscribe Ping/Pong | oui | PASS | PENDING | | Subscribe Ping/Pong | oui | PASS | **PASS Ping serveur** |
Le premier smoke n'a pas besoin de démontrer chaque famille. Il doit prouver que le provider exécute le standard KSP sur Devnet ; les capacités supplémentaires sont sondées sans élargir N2. La release prouve le chemin provider nécessaire à sa mission sans transformer les familles non sondées en capacités absentes.
## 9. Unary et replay ## 9. Unary et replay
| Capability | N2 KSP | OrbitFlare docs | Live | | Capability | N2 KSP | OrbitFlare docs | Verdict provider |
|---------------------|--------|-----------------|---------| |---------------------|--------|-----------------|-----------------------------------|
| SubscribeReplayInfo | PASS | non prouvé | PENDING | | SubscribeReplayInfo | PASS | non prouvé | UNKNOWN / non bloquant |
| Ping unary | PASS | non prouvé | PENDING | | Ping unary | PASS | non prouvé | UNKNOWN / non bloquant |
| GetLatestBlockhash | PASS | non prouvé | PENDING | | GetLatestBlockhash | PASS | non prouvé | UNKNOWN / non bloquant |
| GetBlockHeight | PASS | non prouvé | PENDING | | GetBlockHeight | PASS | non prouvé | UNKNOWN / non bloquant |
| GetSlot | PASS | non prouvé | PENDING | | GetSlot | PASS | non prouvé | UNKNOWN / non bloquant |
| IsBlockhashValid | PASS | non prouvé | PENDING | | IsBlockhashValid | PASS | non prouvé | UNKNOWN / non bloquant |
| GetVersion | PASS | non prouvé | PENDING | | GetVersion | PASS | non prouvé | UNKNOWN / non bloquant |
| from_slot | PASS | non prouvé | PENDING | | from_slot | PASS | non prouvé | N1 disponible, provider non sondé |
| retention | N/A | non documentée | UNKNOWN | | retention | N/A | non documentée | UNKNOWN / provider-owned |
Une restriction provider ne rétrograde jamais la disponibilité de la méthode dans le standard global KSP. Une restriction ou un inconnu provider ne rétrograde jamais la disponibilité de la méthode dans le standard global KSP. Le reconnect N1 tolère déjà l'indisponibilité de `SubscribeReplayInfo` et poursuit avec le `from_slot` conservateur demandé.
## 10. Limits provider ## 10. Limits provider
@@ -174,29 +174,29 @@ Ces valeurs restent provider-owned et ne deviennent pas des validations généri
## 11. Config V3 ## 11. Config V3
| Exigence | Verdict | | Exigence | Verdict |
|---------------------------------------|-----------------| |---------------------------------------|----------|
| nouveau format Config nécessaire | **NO** | | nouveau format Config nécessaire | **NO** |
| `provider = orbitflare` | **PASS STATIC** | | `provider = orbitflare` | **PASS** |
| `protocol = solana_yellowstone` | **PASS STATIC** | | `protocol = solana_yellowstone` | **PASS** |
| `cluster = devnet` | **PASS STATIC** | | `cluster = devnet` | **PASS** |
| Devnet URL publique | **PASS STATIC** | | Devnet URL publique | **PASS** |
| secret metadata `x-token` | **REQUIRED** | | secret metadata `x-token` | **PASS** |
| valeur License Key via `KSP_SECRET_*` | **PASS DESIGN** | | valeur License Key via `KSP_SECRET_*` | **PASS** |
| `X-ORBIT-KEY` dans Transport Config | **FORBID** | | `X-ORBIT-KEY` dans Transport Config | **NO** |
| heartbeat dans `grpc_defaults` | **NO** | | heartbeat dans `grpc_defaults` | **NO** |
`pre.002-fix.001` corrige le profil en : Contrat final :
```text ```text
secret_metadata = x-token <- ${KSP_SECRET_ORBITFLARE_DEVNET_GRPC_X_TOKEN} secret_metadata = x-token <- ${KSP_SECRET_ORBITFLARE_DEVNET_GRPC_X_TOKEN}
``` ```
La valeur effective doit rester redacted dans toutes les projections safe/debug. Le test Config prouve la classification secrète et la redaction ; le live prouve que ce credential ouvre le Subscribe OrbitFlare Devnet.
## 12. Smoke Devnet attendu ## 12. Smoke Devnet final
Smoke corrigé : Smoke durable :
```text ```text
License Key lue sur stdin License Key lue sur stdin
@@ -207,28 +207,35 @@ url = http://devnet.rpc.orbitflare.com:10000
open standard Subscribe open standard Subscribe
request slots confirmed request slots confirmed
receive Slot non nul receive Slot non nul
observe Ping serveur pendant fenêtre bornée de caractérisation observe Ping serveur
close borné close borné
``` ```
Verdicts actuels :
| Preuve | Verdict | | Preuve | Verdict |
|----------------------------------------------|--------------------------------| |----------------------------------------------|--------------------------------|
| endpoint parsé par N1 | **PASS STATIC** | | endpoint parsé par N1 | **PASS** |
| sans metadata | **FAIL EXPECTED / CLASSIFIED** | | sans metadata | **FAIL EXPECTED / CLASSIFIED** |
| secret `x-token` représentable par Config V3 | **PASS STATIC** | | secret `x-token` représentable par Config V3 | **PASS** |
| License Key redacted | **PASS STATIC** | | License Key redacted | **PASS** |
| connect authentifié | **PENDING OPERATOR** | | connect authentifié | **PASS LIVE** |
| Subscribe authentifié | **PENDING OPERATOR** | | Subscribe authentifié | **PASS LIVE** |
| Slot reçu | **PENDING OPERATOR** | | Slot reçu | **PASS LIVE** |
| server Ping reçu | **PENDING OPERATOR** | | server Ping reçu | **PASS LIVE** |
| auto reply KSP déterministe | **PASS N1** | | auto reply KSP déterministe | **PASS N1** |
| close borné | **PASS N1 / LIVE PENDING** | | close borné | **PASS LIVE** |
Résultats :
```text
pre.002-fix.001 1/1 PASS en 5.10 s
pre.003 final 1/1 PASS en 5.19 s
```
## 13. Provider overlay gate ## 13. Provider overlay gate
La release reste sans façade OrbitFlare si `pre.002` démontre : Verdict final : **aucune façade/policy OrbitFlare n'est nécessaire**.
Les conditions de réutilisation directe sont toutes satisfaites :
```text ```text
standard Subscribe fonctionne standard Subscribe fonctionne
@@ -237,64 +244,56 @@ Config V3 exprime endpoint/auth
aucune restriction consumer-visible ne requiert un type provider aucune restriction consumer-visible ne requiert un type provider
``` ```
Une façade/policy OrbitFlare devient admissible seulement après preuve live d'une divergence. Même dans ce cas : Les interdictions restent durables :
```text ```text
N1 ne change pas N1 ne change pas
N2 ne change pas N2 ne change pas
pas de raw Tonic pas de raw Tonic
pas de SDK OrbitFlare pas de SDK OrbitFlare
ownership/close provider bornés
``` ```
## 14. Non-régressions finales ## 14. Non-régressions finales
| Surface | Baseline | Final | | Surface | Baseline | Final |
|-----------------------------------|--------------|---------| |-----------------------------------|--------------|------------------------|
| HTTP current typed | 52 sur 52 | PENDING | | HTTP current typed | 52 sur 52 | **PASS** |
| HTTP historical | 14 sur 14 | PENDING | | HTTP historical | 14 sur 14 | **PASS** |
| WebSocket standard | 18 sur 18 | PENDING | | WebSocket standard | 18 sur 18 | **PASS** |
| Helius LaserStream WebSocket | stable 0.2.8 | PENDING | | Helius LaserStream WebSocket | stable 0.2.8 | **PASS** |
| Yellowstone N1/N2 | stable 0.2.9 | PENDING | | Yellowstone N1/N2 | stable 0.2.9 | **PASS** |
| PublicNode Mainnet/Testnet | stable 0.2.9 | PENDING | | PublicNode Mainnet/Testnet | stable 0.2.9 | **PASS deterministic** |
| Config V1/V2/V3 backward readable | stable 0.2.9 | PENDING | | Config V1/V2/V3 backward readable | stable 0.2.9 | **PASS** |
| dependency firewall | stable 0.2.9 | PENDING | | dependency firewall | stable 0.2.9 | **PASS** |
Les smokes PublicNode live n'ont pas été rejoués en `pre.003` car N1/N2 et les profils PublicNode n'ont pas changé ; leurs preuves live de `0.2.9` restent la baseline et la non-régression déterministe est verte.
## 15. Gate `pre.001` ## 15. Gate `pre.001`
| Critère | Verdict | | Critère | Verdict |
|-------------------------------------|------------------------| |-------------------------------------|----------------------|
| base stable `v0.2.9` | **PASS** | | base stable `v0.2.9` | **PASS** |
| baseline fmt/audits/check/clippy | **PASS** | | baseline fmt/audits/check/clippy | **PASS** |
| workspace test | **PASS** | | workspace test | **PASS** |
| graph duplicates | **PASS** | | graph duplicates | **PASS** |
| graph complet Transport | **PASS** | | graph complet Transport | **PASS** |
| sources OrbitFlare actuelles | **PASS** | | sources OrbitFlare actuelles | **PASS** |
| sources Yellowstone actuelles | **PASS** | | sources Yellowstone actuelles | **PASS** |
| Free Devnet gRPC confirmé | **PASS** | | Free Devnet gRPC confirmé | **PASS** |
| endpoints classifiés | **PASS** | | endpoints classifiés | **PASS** |
| auth planes distingués | **PASS** | | auth planes distingués | **PASS** |
| heartbeat KSP vs provider classifié | **PASS, LIVE PENDING** | | heartbeat KSP vs provider classifié | **PASS FINAL** |
| capabilities auditées | **PASS, LIVE PENDING** | | capabilities auditées | **PASS** |
| replay/from_slot | **UNKNOWN PROVIDER** | | replay/from_slot | **UNKNOWN PROVIDER** |
| N1 immutable | **PASS** | | N1 immutable | **PASS** |
| N2 immutable | **PASS** | | N2 immutable | **PASS** |
| Config V3 shape | **PASS** | | Config V3 shape | **PASS** |
| smoke ownership | **PASS** | | smoke ownership | **PASS** |
| threat model | **PASS** | | threat model | **PASS** |
| sizing/forecast | **PASS** | | sizing/forecast | **PASS** |
| provider runtime lourd ajouté | **NO** | | provider runtime lourd ajouté | **NO** |
Verdict : Verdict final : architecture positive, inconnus provider non requis qualifiés, aucun split déclenché.
```text
architecture/sizing gate = POSITIVE
operator pre.001 gate = PASS
pre.002 static/workspace gate = PASS
pre.002 live auth hypothesis = FAIL CLASSIFIED
pre.002-fix.001 static gate = READY FOR OPERATOR VALIDATION
live provider gate = PENDING authenticated characterization
```
## 16. Gate `pre.002` commité ## 16. Gate `pre.002` commité
@@ -319,44 +318,77 @@ Validation opérateur du 2026-08-25 :
| live sans metadata | **FAIL CLASSIFIED** | | live sans metadata | **FAIL CLASSIFIED** |
| `SubscribeOpen` | **UNAUTHENTICATED** | | `SubscribeOpen` | **UNAUTHENTICATED** |
Le failure live est un résultat de caractérisation utile et non une régression du moteur. Il impose un fix de configuration/auth provider parce que `pre.002` est déjà commité. Le failure live est la caractérisation historique qui a imposé le fix d'auth, pas une régression du moteur.
## 17. Gate `pre.002-fix.001` ## 17. Gate `pre.002-fix.001`
| Critère | Verdict | | Critère | Verdict |
|-----------------------------------------------------------------|----------------------| |-----------------------------------------------------------------|------------------------|
| Cargo `0.2.10-pre.2.fix.1` | **PASS STATIC** | | Cargo `0.2.10-pre.2.fix.1` | **PASS** |
| `.env.example` inventorie le secret OrbitFlare | **PASS STATIC** | | `.env.example` inventorie le secret OrbitFlare | **PASS** |
| Config `secret_metadata` contient `x-token` | **PASS STATIC** | | Config `secret_metadata` contient `x-token` | **PASS** |
| valeur provenant de `KSP_SECRET_ORBITFLARE_DEVNET_GRPC_X_TOKEN` | **PASS STATIC** | | valeur provenant de `KSP_SECRET_ORBITFLARE_DEVNET_GRPC_X_TOKEN` | **PASS** |
| test Config prouve redaction et classification secrète | **PASS STATIC** | | test Config prouve redaction et classification secrète | **PASS** |
| smoke lit la License Key sur stdin | **PASS STATIC** | | smoke lit la License Key sur stdin | **PASS** |
| secret absent des arguments CLI | **PASS STATIC** | | secret absent des arguments CLI | **PASS** |
| moteur N1 modifié | **NO** | | moteur N1 modifié | **NO** |
| standard N2 modifié | **NO** | | standard N2 modifié | **NO** |
| SDK OrbitFlare ajouté | **NO** | | SDK OrbitFlare ajouté | **NO** |
| connect authentifié | **PENDING OPERATOR** | | connect authentifié | **PASS LIVE** |
| `Subscribe -> Slot` live | **PENDING OPERATOR** | | `Subscribe -> Slot` live | **PASS LIVE / 5.10 s** |
| `SubscribeUpdate::Ping` live | **PENDING OPERATOR** | | `SubscribeUpdate::Ping` live | **PASS LIVE** |
| close live | **PENDING OPERATOR** | | close live | **PASS LIVE** |
Commande live dédiée, avec secret saisi sans linscrire dans lhistorique : Le fix ferme l'auth et confirme que le chemin standard suffit.
```bash ## 18. Gate `pre.003` technique/live final
read -rsp 'OrbitFlare License Key: ' ORBITFLARE_LICENSE_KEY; echo
printf '%s\n' "$ORBITFLARE_LICENSE_KEY" | cargo test -p ksp-onchain-transport-lib --test yellowstone_orbitflare_smoke -- --ignored --nocapture
unset ORBITFLARE_LICENSE_KEY
```
Interprétation : Gate opérateur du 2026-08-25 :
| Critère | Verdict |
|------------------------------------------|----------------------------------|
| Cargo `0.2.10-pre.3` | **PASS** |
| `cargo fmt --all` | **PASS** |
| audit Rust | **PASS / 0 export candidate** |
| audit Markdown | **PASS / 99 tables / 100 files** |
| `cargo check --workspace` | **PASS** |
| `cargo clippy --workspace --all-targets` | **PASS** |
| Config unit | **114 sur 114 PASS** |
| Config ownership | **5 sur 5 PASS** |
| Config public API | **15 sur 15 PASS** |
| Transport unit | **383 sur 383 PASS** |
| Transport public API | **49 sur 49 PASS** |
| Transport release completeness | **43 sur 43 PASS** |
| Transport doctests | **4 sur 4 PASS** |
| workspace dependency canary | **3 sur 3 PASS** |
| `cargo test --workspace` | **PASS** |
| OrbitFlare Devnet live | **1 sur 1 PASS / 5.19 s** |
| graphes Cargo | **INSPECTÉS / PAS DE BLOCAGE** |
| moteur N1 modifié | **NO** |
| standard N2 modifié | **NO** |
Pile directe réconciliée :
```text ```text
Slot + Ping PASS yellowstone-grpc-proto 12.6.0
-> auth et heartbeat standards composables ; pre.003 devient gate technique/live final tonic / tonic-prost 0.14.6
prost / prost-types 0.14.4
Subscribe/Slot PASS mais Ping absent
-> divergence heartbeat provider à traiter au-dessus de N1/N2 dans pre.003
auth encore rejetée avec la License Key x-token
-> blocker provider/account à qualifier ; ne jamais modifier N1 pour contourner le gate
``` ```
Verdict : **gate technique/live final fermé**.
## 19. Gate `pre.004` documentaire
Cette tranche doit uniquement synchroniser :
```text
plan 017
validation 013
README Transport
USAGE Transport
docs/000-README.md
```
Elle ne change ni code, ni Config runtime, ni schema, ni test, ni dependency. `CHANGELOG.md`, `ROADMAP.md` et le prompt suivant restent réservés au couloir publication-minimal.
La décision de séquence est prise avant `pre.005` : Helius LaserStream gRPC est reporté dans les TODO Yellowstone sans numéro de release faute d'accès live raisonnable, et `0.2.11` devient `off-chain price transport`. Aucun prompt suivant n'est généré dans `pre.004`.