v0.2.9-pre.014

This commit is contained in:
2026-08-25 05:44:41 +02:00
parent dcabceb52f
commit 6ddf2b4995
7 changed files with 366 additions and 198 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +1,9 @@
<!-- file: docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md -->
<!-- version: 24 -->
<!-- version: 25 -->
# Plan `0.2.9` — moteur Yellowstone gRPC + standard Solana + PublicNode
**Statut courant : `0.2.9-pre.012` a passé son gate déterministe local sans warning ; le smoke PublicNode live et les graphes Cargo finaux n'ont pas été exécutés dans le log opérateur fourni. `pre.012-fix.001` introduit une règle durable de séparation des dernières prereleases et recalibre la fermeture : `pre.013` technique/live, `pre.014` réconciliation documentaire, `pre.015` préparation de publication minimale, puis `rel.001`.**
**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
@@ -49,7 +49,7 @@ 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 sans credential versionné
smoke live opt-in avec credential secret non versionné
non-régressions HTTP, WebSocket standard et Helius WebSocket
```
@@ -118,7 +118,7 @@ https://docs.rs/crate/yellowstone-grpc-proto/latest
https://docs.rs/crate/yellowstone-grpc-client/latest
```
Une réaudite finale est requise en `pre.012` si l'upstream a changé matériellement pendant la release.
Le réaudit final a été exécuté en `pre.012`; aucun changement upstream matériel na remis en cause la surface retenue.
### 4.2 Licence
@@ -514,42 +514,43 @@ Le tuple historique n'est pas modifié silencieusement.
### 9.1 Mainnet
La surface publique réauditée le 2026-08-24 confirme Yellowstone gRPC Solana Mainnet et affiche le host/port :
Endpoint retenu et validé en live :
```text
solana-yellowstone-grpc.publicnode.com:443
https://solana-yellowstone-grpc.publicnode.com:443
```
Le wrapper KSP attend une URL `http/https`; Config matérialise donc le même endpoint TLS sous la forme `https://solana-yellowstone-grpc.publicnode.com:443`.
`pre.011` versionne donc un profil :
Le profil committé est :
```text
profile_id = publicnode_mainnet
provider = publicnode
cluster = mainnet-beta
protocol = solana_yellowstone
credential = aucun
metadata = x-token secret via KSP_SECRET_PUBLICNODE_MAINNET_GRPC_X_TOKEN
```
La partie HTTP/WS de ce profil reste standard Solana ; seul l'endpoint gRPC est PublicNode.
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
Le réaudit final du 2026-08-24 confirme que PublicNode annonce bien une capacité Solana Testnet gRPC. La surface officielle consultable ne fournit cependant toujours pas un hostname Testnet exact suffisamment autoritatif pour être versionné.
Décision finale `0.2.9` :
L'endpoint exact confirmé par l'opérateur et validé en live est :
```text
existence Testnet gRPC confirmée
hostname Testnet exact non obtenu depuis une source autoritative
hostname déduit ou tiers interdit
profil Testnet committé non
smoke Testnet non
statut EXTERNAL BLOCK documentaire / NOT GUESSED
https://solana-testnet-yellowstone-grpc.publicnode.com:443
```
Ce bloc externe ne remet pas en cause la fondation Mainnet. Une release provider ultérieure peut matérialiser Testnet dès qu'une source PublicNode autoritative expose l'endpoint exact.
Le profil committé est :
```text
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
@@ -589,14 +590,14 @@ Config sensitivity gate avant construction de metadata secret
Ordre de preuve :
```text
Transport programmatic -> PublicNode Mainnet Yellowstone
Transport programmatic -> PublicNode Testnet seulement si endpoint exact confirmé
Config V3 -> Transport -> PublicNode via composition légitime, jamais un smoke réseau placé dans Config par facilité
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 procédure reste opérateur/documentée en `pre.012`.
Un smoke cross-crates Config -> Transport ne doit pas devenir une responsabilité durable de `ksp-config-lib`. Sil nexiste pas encore de surface dinté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é.
@@ -604,24 +605,24 @@ Aucun secret provider n'est versionné.
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 | **ACTIVE DOCUMENTARY FIX** |
| `pre.013` | gate technique/live PublicNode + graphes finaux | **PLANNED** |
| `pre.014` | réconciliation documentaire finale | **PLANNED** |
| `pre.015` | prompt + CHANGELOG + ROADMAP | **PLANNED** |
| 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 :
@@ -643,34 +644,50 @@ 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 seront réconciliés en `pre.014`.
`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 :
```text
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
### `pre.013` — gate technique/live final — **CLOSED**
Payload autorisé :
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 :
```text
workspace.package.version = 0.2.9-pre.13
exécution du smoke PublicNode Mainnet déjà versionné
cargo tree Transport direct
cargo tree Transport --duplicates
cargo tree --duplicates
constat factuel de tout incident réseau/provider/TLS
aucune réconciliation README/USAGE
aucune finalisation prompt/CHANGELOG/ROADMAP
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
```
Commande live centrale :
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.
```bash
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
```
Un échec local du smoke est corrigé dans `pre.013-fix.NNN`. Un incident externe est documenté comme tel. Un fix de `pre.013` ne contient pas de correction documentaire de clôture.
### `pre.014` — réconciliation documentaire finale
### `pre.014` — réconciliation documentaire finale — **ACTIVE CANDIDATE**
Payload :
@@ -724,20 +741,7 @@ moteur Yellowstone + façade Solana standard + Config provider-neutral + premiè
## 15. Gates opérateur restants
Gate `pre.013` :
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
cargo tree --duplicates
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
```
Gate `pre.014` :
Le gate `pre.013` est fermé. Gate `pre.014` :
```bash
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.9
@@ -760,8 +764,9 @@ bounds/backpressure/shutdown verts
reconnect/replay documentés sans lossless implicite
Config V3 backward V1/V2
provider/protocol distincts
PublicNode Mainnet live exécuté avec résultat consigné
Testnet reporté factuellement si endpoint exact non confirmé
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é

View File

@@ -1,9 +1,9 @@
<!-- file: docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md -->
<!-- version: 26 -->
<!-- version: 27 -->
# Validation `0.2.9` — Yellowstone gRPC standard + PublicNode
**Statut courant : le gate déterministe de `pre.012` est vert sans warning ; le smoke PublicNode live et les graphes Cargo finaux ne figurent pas comme exécutés dans le log opérateur fourni. `pre.012-fix.001` ajoute la règle durable de séparation de fermeture et déplace les gates restants vers `pre.013` technique/live, `pre.014` réconciliation documentaire et `pre.015` publication minimale.**
**Statut courant : la validation technique `pre.013-fix.004` est fermée et verte : `clippy --all-targets`, workspace, graphes Cargo, puis smoke PublicNode authentifié Mainnet + Testnet `2/2 PASS`. `pre.014` réconcilie et ferme cette matrice documentaire ; seule la tranche `pre.015` de préparation de publication restera avant `rel.001`.**
## 1. Autorités et baseline courante
@@ -40,15 +40,15 @@ Cette baseline est le seuil de non-régression de `pre.012`.
## 2. Gate dépendances et licence
| Exigence | Décision / preuve | État |
|--------------------------------|------------------------------------------|-------------------|
| proto officiel sans vendoring | `yellowstone-grpc-proto ^12.6` | **PASS** |
| pas de client upstream runtime | `yellowstone-grpc-client` absent | **PASS** |
| runtime Tonic KSP-owned | `tonic ^0.14` + `tonic-prost ^0.14` | **PASS** |
| proto subtree compatible | Apache-2.0 selon `LICENSING.md` upstream | **PASS** |
| source AGPL copiée | aucune | **PASS** |
| raw client Tonic public | aucun | **PASS** |
| graph final | réinspection `pre.012` | **PENDING FINAL** |
| Exigence | Décision / preuve | État |
|--------------------------------|------------------------------------------|----------|
| proto officiel sans vendoring | `yellowstone-grpc-proto ^12.6` | **PASS** |
| pas de client upstream runtime | `yellowstone-grpc-client` absent | **PASS** |
| runtime Tonic KSP-owned | `tonic ^0.14` + `tonic-prost ^0.14` | **PASS** |
| proto subtree compatible | Apache-2.0 selon `LICENSING.md` upstream | **PASS** |
| source AGPL copiée | aucune | **PASS** |
| raw client Tonic public | aucun | **PASS** |
| graph final | graphes `pre.013` inspectés | **PASS** |
Le graphe de dépendances n'est pas modifié par `pre.012`; aucune nouvelle dépendance Cargo n'est introduite dans cette tranche.
@@ -276,30 +276,33 @@ Les tests V3 démontrent le cas valide et les deux croisements invalides sans ex
Profil committé et validé :
```text
profile_id = publicnode_mainnet
provider = publicnode
cluster = mainnet-beta
protocol = solana_yellowstone
url = https://solana-yellowstone-grpc.publicnode.com:443 # provider affiche host:port ; KSP ajoute le scheme TLS requis
metadata = aucune
profile_id = publicnode_mainnet
provider = publicnode
cluster = mainnet-beta
protocol = solana_yellowstone
url = https://solana-yellowstone-grpc.publicnode.com:443
secret_metadata = x-token <- ${KSP_SECRET_PUBLICNODE_MAINNET_GRPC_X_TOKEN}
```
Le mapping produit un endpoint TLS Yellowstone standard ; le test `committed_v3_publicnode_mainnet_maps_provider_neutral_yellowstone_grpc` passe et `Debug` ne doit pas exposer l'URL.
Le mapping produit un endpoint TLS Yellowstone standard et une metadata secrète redacted. Le smoke final ouvre `Subscribe`, reçoit un update `Slot` non nul et ferme de manière bornée : **PASS**.
### 8.5 PublicNode Testnet
Verdict final documentaire : **EXTERNAL BLOCK, NOT GUESSED**.
Le réaudit officiel du 2026-08-24 confirme une capacité Solana Testnet gRPC chez PublicNode, mais l'hostname exact n'a pas été obtenu depuis une source PublicNode suffisamment autoritative. Aucun profil, aucun hostname déduit et aucun smoke Testnet ne sont versionnés.
Profil committé et validé :
```text
capacité Testnet gRPC confirmée
hostname exact non confirmé
profil KSP absent
smoke KSP absent
raison interdiction d'inventer un endpoint provider
profile_id = publicnode_testnet
provider = publicnode
cluster = testnet
protocol = solana_yellowstone
url = https://solana-testnet-yellowstone-grpc.publicnode.com:443
secret_metadata = x-token <- ${KSP_SECRET_PUBLICNODE_TESTNET_GRPC_X_TOKEN}
```
Le hostname exact a été fourni par l'opérateur puis validé par le smoke live. `Subscribe` reçoit un update `Slot` non nul : **PASS**.
Le même personal token opérateur a été validé sur les deux réseaux. Les deux variables KSP restent distinctes afin de permettre des valeurs différentes si la policy provider change ; cette modélisation ne constitue pas une preuve que les tokens PublicNode sont network-scoped.
## 9. Provider-neutrality
| Point | Verdict |
@@ -326,107 +329,96 @@ Transport -> std::env KSP_* interdit
tracing direct Transport interdit
```
`pre.012` ne modifie pas le runtime Transport ; elle ajoute uniquement un smoke live ignoré par défaut et de la documentation/audit. Son seuil de non-régression est la baseline `pre.011`.
La baseline `pre.011` reste conservée. Les changements `pre.013` ont porté uniquement le gate live, la Config PublicNode/Testnet et le harness de smoke ; le gate final `pre.013-fix.004` confirme les non-régressions workspace.
## 11. Historique des gates fermé
Les détails de commandes, warnings corrigés et fichiers exacts restent dans leurs deltas immuables.
| Tranche | Gate consolidé |
|-----------------------------------|--------------------------------------|
| `pre.001` + `fix.001` + `fix.002` | audit/sizing/providers/licence fermé |
| `pre.002` + `fix.001` + `fix.002` | moteur/settings/channel fermé |
| `pre.003` + `fix.001` | TLS/metadata/unary fermé |
| `pre.004` + `fix.001` | Subscribe common fermé |
| `pre.005` + `fix.001` | Accounts/Slots fermé |
| `pre.006` | namespace HTTP fermé |
| `pre.007` | Transactions fermé |
| `pre.008` + `fix.001` | Blocks fermé |
| `pre.009` + `fix.001` | bidi/backpressure fermé |
| `pre.010` + `fix.001` | reconnect/replay fermé sans warning |
| `pre.011` | Config V3/PublicNode mapping fermé |
| Tranche | Gate consolidé |
|-----------------------------------|---------------------------------------|
| `pre.001` + `fix.001` + `fix.002` | audit/sizing/providers/licence fermé |
| `pre.002` + `fix.001` + `fix.002` | moteur/settings/channel fermé |
| `pre.003` + `fix.001` | TLS/metadata/unary fermé |
| `pre.004` + `fix.001` | Subscribe common fermé |
| `pre.005` + `fix.001` | Accounts/Slots fermé |
| `pre.006` | namespace HTTP fermé |
| `pre.007` | Transactions fermé |
| `pre.008` + `fix.001` | Blocks fermé |
| `pre.009` + `fix.001` | bidi/backpressure fermé |
| `pre.010` + `fix.001` | reconnect/replay fermé sans warning |
| `pre.011` | Config V3/PublicNode mapping fermé |
| `pre.012` + `fix.001` | réaudit + règles de fermeture |
| `pre.013` + `fix.001``fix.004` | live PublicNode + graphes fermé |
| `pre.014` | réconciliation documentaire candidate |
Cette table remplace les anciens appendices numérotés successivement `19.x`, `20`, `21`, etc. qui rendaient le document ambigu.
## 12. Verdict opérateur `pre.012`
## 12. Verdict opérateur consolidé jusqu'à `pre.013-fix.004`
### 12.1 Gate déterministe reçu
Le gate technique final reçu le 2026-08-24 est :
| Exigence | Résultat opérateur |
|----------------------------------------------|--------------------------------------|
| `cargo fmt --all` | **PASS** |
| audit Rust workspace | **PASS, 0 candidate export** |
| audit Markdown | **PASS, 87 tableaux / 252 fichiers** |
| `cargo check --workspace` | **PASS** |
| `cargo clippy --workspace --all-targets` | **PASS sans warning** |
| Config unit | **113/113 PASS** |
| Config public API | **15/15 PASS** |
| Config ownership | **5/5 PASS** |
| Transport unit | **383/383 PASS** |
| Transport public API | **49/49 PASS** |
| Transport release completeness | **43/43 PASS** |
| Transport doctests | **4/4 PASS** |
| workspace dependencies | **3/3 PASS** |
| `cargo test --workspace` | **PASS** |
| smoke Mainnet programmatique sans credential | **NOT RUN, ignored** |
| graphes Cargo finaux | **NOT PROVIDED / NOT RUN** |
| Exigence | Résultat opérateur |
|-----------------------------------------------|--------------------------------------|
| `cargo fmt --all` | **PASS** |
| audit Rust workspace | **PASS, 0 candidate export** |
| audit Markdown | **PASS, 87 tableaux / 258 fichiers** |
| `cargo check --workspace` | **PASS** |
| `cargo clippy --workspace --all-targets` | **PASS sans warning** |
| Transport unit | **383/383 PASS** |
| Transport public API | **49/49 PASS** |
| Transport release completeness | **43/43 PASS** |
| Transport doctests | **4/4 PASS** |
| Config unit dans workspace | **113/113 PASS** |
| Config ownership dans workspace | **5/5 PASS** |
| Config public API dans workspace | **15/15 PASS** |
| workspace dependencies | **3/3 PASS** |
| `cargo test --workspace` | **PASS** |
| graphes Cargo finaux | **PASS / inspectés** |
| smoke PublicNode Mainnet `Subscribe` + `Slot` | **PASS** |
| smoke PublicNode Testnet `Subscribe` + `Slot` | **PASS** |
| smoke live total | **2/2 PASS** |
Le test `yellowstone_publicnode_smoke` compile et apparaît correctement comme `ignored` dans les tests Transport et workspace, mais cela ne constitue pas une exécution live. Aucune preuve de `cargo tree` final n'est présente dans le log fourni.
### 12.2 Effet de `pre.012-fix.001`
Le fix ne change ni runtime, ni schema, ni Config, ni smoke. Il corrige le workflow de fermeture afin que les responsabilités restantes ne soient plus mélangées :
Les graphes résolus confirment la stack attendue :
```text
pre.013 technique/live : smoke PublicNode + graphes Cargo finaux
pre.014 réconciliation documentaire : plan/validation/README/USAGE/références
pre.015 publication minimale : prompt suivant + CHANGELOG + ROADMAP
rel.001 mécanique stable uniquement
yellowstone-grpc-proto 12.6.0
tonic 0.14.6
tonic-prost 0.14.6
prost 0.14.4
prost-types 0.14.4
yellowstone-grpc-client absent du runtime KSP
```
Le contenu prompt/README/USAGE déjà préparé en `pre.012` n'est pas supprimé rétroactivement. Le prompt reste un brouillon jusqu'à `pre.015` ; README/USAGE seront réconciliés définitivement en `pre.014`.
Les graphes ont été exécutés avant `pre.013-fix.004`; ils restent valides car `fix.004` n'a modifié ni dépendance ni feature Cargo.
## 13. Gate `pre.013` — technique/live
## 13. Verdict PublicNode live final
Commandes minimales :
Les essais intermédiaires ont établi deux faits utiles : les appels sans credential peuvent atteindre le service mais recevoir `PERMISSION_DENIED`, et la validation représentative de la foundation doit porter sur `Subscribe` plutôt que sur une unary provider éventuellement restreinte.
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
cargo tree --duplicates
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
```
Verdicts attendus :
Le smoke final :
```text
smoke Mainnet réellement exécuté
GetVersion + GetSlot via TLS sans credential ou incident externe précisément classifié
graphes Cargo inspectés
aucun changement README/USAGE/prompt/CHANGELOG/ROADMAP
reçoit deux personal tokens par stdin, Mainnet puis Testnet
accepte que les deux lignes contiennent la même valeur
construit une metadata secrète x-token
ouvre TLS puis Subscribe
filtre slots
attend un YellowstoneSubscribeUpdate::Slot sous timeout
exige slot > 0
ferme de manière bornée
n'expose aucun secret dans URL/Debug/arguments
```
Un défaut local découvert dans ce gate reste dans `pre.013-fix.NNN`. Un incident externe n'est jamais maquillé en PASS local.
Résultat opérateur final : **Mainnet PASS, Testnet PASS, 2/2**.
Le timeout KSP de half-close est un résultat accepté par le harness uniquement après réception prouvée d'un slot ; le runtime conserve son contrat de timeout explicite.
## 14. Gate `pre.014` — réconciliation documentaire
Cette tranche ferme les documents durables après le gate technique réel :
Cette tranche ne modifie ni runtime, ni Config, ni schema, ni smoke. Elle synchronise le plan, la présente validation, README/USAGE Transport et les références durables avec les faits exécutés en `pre.013`.
```text
plan 016
validation 012
README/USAGE Transport
documents de référence 0.2.9 réellement concernés
audit Markdown des documents touchés
```
Elle n'introduit aucun nouveau runtime/smoke et ne finalise pas `CHANGELOG.md`, `ROADMAP.md` ni le prompt suivant.
Le verdict de la validation 012 devient définitif dans cette tranche, sur la base exclusive des preuves réellement exécutées en `pre.013` et des gates antérieurs.
Le verdict technique de `0.2.9` est donc **PASS**. Après le gate documentaire `pre.014`, seuls le prompt suivant, `CHANGELOG.md` et `ROADMAP.md` restent à finaliser en `pre.015`.
## 15. Gate `pre.015` — préparation de publication
@@ -463,8 +455,9 @@ resource/backpressure/lifecycle verts
reconnect/replay sans promesse lossless
Config V3 backward V1/V2
provider/protocol distincts
PublicNode Mainnet live exécuté avec résultat consigné
Testnet jamais inventé
PublicNode Mainnet live Subscribe + Slot PASS
PublicNode Testnet live Subscribe + Slot PASS
x-token secret requis par les profils PublicNode, aucun secret versionné
HTTP/WS/Helius non régressés
dependency firewall vert
cargo graphs inspectés