v0.2.9-pre.006

This commit is contained in:
2026-08-24 13:17:24 +02:00
parent 15e3402e1c
commit b32de48c0b
16 changed files with 1299 additions and 115 deletions

View File

@@ -1,9 +1,9 @@
<!-- file: docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md -->
<!-- version: 13 -->
<!-- version: 15 -->
# Plan `0.2.9` — moteur Yellowstone gRPC + standard Solana + PublicNode
> **Statut : `0.2.9-pre.004-fix.001` est fermée sur gate opérateur sans warning : fmt/audit/check/Clippy/workspace PASS, Transport 359 unit + 44 public API + 37 completeness + 4 doctests. `0.2.9-pre.005` est fonctionnellement verte sur le gate opérateur (364 unit + 45 public API + 38 completeness + workspace PASS) mais nécessite `pre.005-fix.001` pour supprimer quatre warnings `dead_code` test-only et deux diagnostics Clippy de forme dans `grpc_subscribe.rs`. Le fix ne change ni le contrat Accounts/Slots ni le wire. Transactions/Blocks, PublicNode et Config V3 restent hors tranche. `0.2.9` reste bornée à un moteur client Yellowstone partagé, une façade Solana Yellowstone standard et une première intégration concrète PublicNode. Seuls OrbitFlare puis Helius LaserStream gRPC sont actuellement planifiés comme releases provider suivantes ; les autres providers restent en TODO/IDEAS sans numéro réservé. Chaque prerelease vise 1520 minutes de travail effectif et la release complète doit rester clôturable dans une seule session de chat.**
> **Statut : `0.2.9-pre.005-fix.001` est fermée sur gate opérateur intégralement vert et sans warning : fmt/audit/check/Clippy/workspace PASS, Transport 364 unit + 45 public API + 38 completeness + 4 doctests. `0.2.9-pre.006` est une tranche structurelle dédiée au nommage des modules privés : les cinq modules sans ambiguïté HTTP (`client`, `executor`, `pool`, `resilience`, `settings`) deviennent `http_*`, avec leurs unit tests miroirs. Les modules `rpc_*`, `json_rpc`, `constants` et `error` ne sont pas préfixés artificiellement car ils décrivent une couche/protocole partagé ou portent déjà des DTOs utilisés par WS/gRPC. Cette insertion décale lancien forecast fonctionnel `pre.006011` vers `pre.007012` sans changer son contenu. Aucun contrat public ni comportement runtime ne change.**
## 1. Objet, base et état d'ouverture
@@ -442,7 +442,7 @@ accounts_data_slice length <= 64 MiB
offset + length aucun overflow u64
```
Les bornes account/owner/include/exclude/required, memcmp et Cuckoo restent volontairement dans les tranches de famille `pre.005007`.
Les bornes Accounts sont matérialisées en `pre.005`; les bornes include/exclude/required et Cuckoo propres aux Transactions/Blocks restent dans `pre.007008`.
## 8. Matrice `SubscribeUpdate`
@@ -709,7 +709,7 @@ max logical filter groups/names
reconnect attempts/backoff
```
La forme JSON exacte et les bornes sont matérialisées en `pre.010`, mais **la décision V3 + `grpc_endpoints` séparés + metadata publique/secrète séparée est fermée par `pre.001`**.
La forme JSON exacte et les bornes sont matérialisées en `pre.011`, mais **la décision V3 + `grpc_endpoints` séparés + metadata publique/secrète séparée est fermée par `pre.001`**.
## 14. Audit fournisseurs gRPC gratuits et durables
@@ -822,7 +822,7 @@ OrbitFlare et Helius sont validés dans leurs releases dédiées. Les autres pro
Le smoke 1/2 peut vivre dans `ksp-onchain-transport-lib/tests` car il construit ses settings programmatiquement et ne teste que Transport.
Le smoke 3 ne doit pas être ajouté à `ksp-config-lib` par facilité. Si aucune surface d'intégration dédiée n'existe encore, il peut rester une procédure opérateur/documentée ou être placé sur une surface de composition déjà légitime ; le plan doit revalider l'owner au moment de `pre.010/pre.011`.
Le smoke 3 ne doit pas être ajouté à `ksp-config-lib` par facilité. Si aucune surface d'intégration dédiée n'existe encore, il peut rester une procédure opérateur/documentée ou être placé sur une surface de composition déjà légitime ; le plan doit revalider l'owner au moment de `pre.011/pre.012`.
Aucun secret provider n'est versionné.
@@ -922,31 +922,34 @@ pre.003 DONE — moteur TLS/metadata + façade N2 unary + fixture locale + 7 un
pre.004 DONE — standard Solana : Subscribe foundation + maps/commitment/ping/from_slot/data slices/bounds
budget : 1520 min ; gate final fix.001 : fmt/audit/check/Clippy/workspace PASS sans warning + Transport 359/44/37/4
pre.005 CANDIDATE — standard Solana : Accounts + Slots filters/updates
budget : 1520 min ; preuve : request wire complet + Cuckoo/memcmp/predicates + Account/Slot updates exacts/malformed/adversarial
pre.005 DONE — standard Solana : Accounts + Slots filters/updates
budget : 1520 min ; gate final fix.001 : fmt/audit/check/Clippy/workspace PASS sans warning + Transport 364/45/38/4
pre.006 standard Solana : Transactions + transaction_status
pre.006 CANDIDATE — structure Transport : namespace privé HTTP explicite
budget : 1520 min ; preuve : 5 modules + 5 unit tests renommés `http_*`, API publique inchangée, canari d'absence des anciens modules
pre.007 standard Solana : Transactions + transaction_status
budget : 1520 min ; preuve : include/exclude/required/Cuckoo/token expansion + tx/meta
pre.007 standard Solana : Blocks + block_meta + entry
pre.008 standard Solana : Blocks + block_meta + entry
budget : 1520 min ; preuve : counts/arrays/optional/oneof/payload bounds
pre.008 moteur partagé : bidi mutation + Ping/Pong + half-close + backpressure + shutdown
pre.009 moteur partagé : bidi mutation + Ping/Pong + half-close + backpressure + shutdown
budget : 1520 min ; preuve : actor/session local + bounded queues + cleanup déterministe
pre.009 moteur partagé : reconnect/resubscribe + from_slot/ReplayInfo + gaps/duplicates
pre.010 moteur partagé : reconnect/resubscribe + from_slot/ReplayInfo + gaps/duplicates
budget : 1520 min ; preuve : reconnect local déterministe + aucune promesse lossless
pre.010 Config V3 + séparation protocol/provider + profils PublicNode Mainnet/Testnet
pre.011 Config V3 + séparation protocol/provider + profils PublicNode Mainnet/Testnet
budget : 1520 min ; preuve : V1/V2 backward + schema/mapping/redaction + Config -> Transport
pre.011 intégration PublicNode + smokes live + compliance + docs finales + prompt 0.2.10 OrbitFlare
pre.012 intégration PublicNode + smokes live + compliance + docs finales + prompt 0.2.10 OrbitFlare
budget : 1520 min ; preuve : Mainnet/Testnet opt-in + HTTP 52/14 + WS 18/18 + Helius + cargo graphs + workspace final
rel.001 publication stable stricte
```
Prévision : **11 prereleases**, soit environ **165220 minutes de travail effectif nominal hors temps d'attente des commandes**, compatible avec une session complète. Si une tranche réelle excède son budget ou si `pre.011` ne peut pas raisonnablement fermer la release dans la session, on scinde avant de poursuivre au lieu de prolonger artificiellement `0.2.9`.
Prévision : **12 prereleases**, soit environ **180240 minutes de travail effectif nominal hors temps d'attente des commandes**, compatible avec une session complète. Si une tranche réelle excède son budget ou si `pre.012` ne peut pas raisonnablement fermer la release dans la session, on scinde avant de poursuivre au lieu de prolonger artificiellement `0.2.9`.
### Critères de split
@@ -1118,7 +1121,7 @@ Slot update : filters/created_at + slot + parent? + 7 SlotStatus + dead_error?
Les bornes provider-neutral KSP de cette tranche couvrent notamment les sélecteurs Accounts, predicates, memcmp, Cuckoo, taille account-data, noms de filtres d'update, timestamp nanos, signature fixe 64 octets et `dead_error`. Les Debug KSP n'exposent ni pubkeys sélectionnées, ni payload memcmp/Cuckoo/account-data, ni texte `dead_error`.
Les conversions protobuf et décodeurs update restent sous `#[cfg(test)]` jusqu'à `pre.008`, car aucun stream runtime ne les consomme encore. Cette décision évite du faux `dead_code` sans créer une seconde implémentation : les mêmes helpers seront remis en runtime au moment de l'ouverture bidi.
Les conversions protobuf et décodeurs update restent sous `#[cfg(test)]` jusqu'à `pre.009`, car aucun stream runtime ne les consomme encore. Cette décision évite du faux `dead_code` sans créer une seconde implémentation : les mêmes helpers seront remis en runtime au moment de l'ouverture bidi.
OUT de `pre.005` : Transactions/transaction_status, Blocks/block_meta/entry, stream bidi, provider PublicNode, Config V3 et `SubscribeDeshred`.
@@ -1176,13 +1179,40 @@ Pour toute intégration provider future, la règle reste : N1 n'est jamais dupli
Le premier gate opérateur de `pre.005` confirme la surface fonctionnelle : 364/364 unit, 45/45 public API, 38/38 release-completeness et workspace complet PASS. Les seuls écarts sont quatre constantes utilisées uniquement par les décodeurs `#[cfg(test)]`, une convention `to_wire(&self)` sur un type `Copy`, et une closure `is_some_and` soumise à `-D clippy::implicit-return`.
| Correction | Traitement | Impact runtime |
|-------------------------------------------|-------------------------------------------------|-------------------------|
| quatre constantes de bounds update | `#[cfg(test)]` | aucun avant `pre.008` |
| `YellowstoneSubscribeSlotFilter::to_wire` | receiver `self` | aucun, helper test-only |
| closure `dead_error.is_some_and` | `return` explicite | aucun |
| tableaux `016` et `012` | réalignement systématique des colonnes Markdown | documentaire uniquement |
| Correction | Traitement | Impact runtime |
|-------------------------------------------|----------------------------------------------------------------------|-------------------------|
| quatre constantes de bounds update | `#[cfg(test)]` | aucun avant `pre.009` |
| `YellowstoneSubscribeSlotFilter::to_wire` | receiver `self` | aucun, helper test-only |
| closure `dead_error.is_some_and` | `return` explicite | aucun |
| tableaux `016` et `012` | reformatage JetBrains RustRover (largeur max + un espace de padding) | documentaire uniquement |
Le réalignement documentaire conserve le contenu des cellules et ne modifie que les espaces de padding et les séparateurs de tableaux.
Le reformatage documentaire reproduit le comportement RustRover : largeur calculée sur le contenu le plus large de chaque colonne et exactement un espace de padding de chaque côté du contenu avant les pipes.
**Verdict `pre.005-fix.001` : correctif minimal prêt ; `pre.005` reste ouverte jusqu'à réexécution sans warning de check/Clippy/workspace.**
### 19.6 Gate final `pre.005-fix.001`
Le second gate opérateur confirme la fermeture complète de `pre.005` : fmt, audit Rust, check et Clippy passent sans warning ; Transport passe 364 unit + 45 public API + 38 release-completeness + 4 doctests ; le dependency canary Core passe 3/3 et `cargo test --workspace` est vert.
**Verdict : `pre.005` fermée.**
## 20. `pre.006` — namespace privé HTTP explicite
Le développement simultané de HTTP, WebSocket et Yellowstone gRPC rend les anciens noms privés `client`, `executor`, `pool`, `resilience` et `settings` trop ambigus. Ces cinq modules sont exclusivement propriétaires de la pile HTTP et deviennent donc :
```text
client.rs -> http_client.rs
executor.rs -> http_executor.rs
pool.rs -> http_pool.rs
resilience.rs -> http_resilience.rs
settings.rs -> http_settings.rs
```
Les unit tests miroirs reçoivent les mêmes noms. Le changement reste privé à la crate : les types publics sont déjà explicitement nommés `Http*` et leurs chemins au crate root ne changent pas.
Le mini-audit interdit un renommage aveugle des autres modules : `rpc_accounts`, `rpc_blocks`, `rpc_transactions` et `rpc_common` portent des DTOs/types déjà réutilisés par WebSocket et/ou gRPC ; `json_rpc` décrit le protocole d'enveloppe ; `constants` et `error` sont transverses. Ils conservent donc leur nom actuel.
Cette tranche est volontairement séparée de Transactions afin de respecter le budget 1520 minutes et d'éviter de combiner un refactor de fichiers avec une nouvelle surface protobuf. L'ancien forecast fonctionnel `pre.006011` est décalé vers `pre.007012` sans changement de contenu.
**Gate candidat :** audit Rust clean, public API inchangée, cinq anciens modules absents après suppression opérateur, cinq nouveaux modules `http_*` compilés, release-completeness canary dédié, workspace complet vert.

View File

@@ -1,9 +1,9 @@
<!-- file: docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md -->
<!-- version: 15 -->
<!-- version: 16 -->
# Validation `0.2.9` — moteur Yellowstone + standard Solana + PublicNode
> **Statut : `pre.004-fix.001` est fermé sur gate opérateur intégralement vert et sans les 10 warnings `dead_code` précédents : fmt/audit/check/Clippy/workspace PASS, Transport 359 unit + 44 public API + 37 completeness + 4 doctests. `0.2.9-pre.005` est fonctionnellement verte (364 unit + 45 public API + 38 completeness + workspace PASS) mais nécessite `pre.005-fix.001` : quatre warnings `dead_code` provenant de constantes utilisées seulement par les décodeurs test-only, un warning `wrong_self_convention` et un `implicit_return` Clippy. Aucun stream bidi n'est encore ouvert ; Transactions/Blocks restent `pre.006007`, puis lifecycle en `pre.008`. PublicNode et Config V3 restent hors tranche. OrbitFlare et Helius sont les seules releases provider suivantes planifiées ; les autres providers restent en TODO/IDEAS sans numéro réservé.**
> **Statut : `0.2.9-pre.005-fix.001` est fermé sur gate opérateur intégralement vert et sans warning : fmt/audit/check/Clippy/workspace PASS, Transport 364 unit + 45 public API + 38 completeness + 4 doctests. `pre.006` est une tranche structurelle de namespace privé : `client/executor/pool/resilience/settings` deviennent `http_*` avec leurs tests miroirs, sans changement dAPI publique. Les `rpc_*`, `json_rpc`, `constants` et `error` restent volontairement non préfixés lorsquils sont partagés ou déjà groupés. Le forecast fonctionnel est décalé dun numéro : Transactions `pre.007`, Blocks `pre.008`, bidi `pre.009`, reconnect `pre.010`, Config V3 `pre.011`, PublicNode final `pre.012`.**
## 1. Autorités du gate
@@ -57,7 +57,7 @@ crate proto : 12.6.0
| RPC | Forme | Classification | Scope | Preuve cible | État |
|-----------------------|-------|------------------------------------------------------|-------|-----------------------|------------------------------------------------------|
| `Subscribe` | bidi | standard | IN | fixture locale + live | PARTIAL pre.005 Accounts/Slots / stream TODO pre.008 |
| `Subscribe` | bidi | standard | IN | fixture locale + live | PARTIAL pre.005 Accounts/Slots / stream TODO pre.009 |
| `SubscribeDeshred` | bidi | Triton extension/pré-exécution malgré présence proto | OUT | canari d'absence/API | OUT |
| `SubscribeReplayInfo` | unary | standard | IN | fixture unary | DONE pre.003 |
| `Ping` | unary | standard | IN | fixture unary | DONE pre.003 |
@@ -247,7 +247,7 @@ prost/prost-types 0.14.x (0.14.4 latest observé)
| no raw Tonic client escape hatch | public API canary | IMPLEMENTED / Cargo pending |
| moteur Yellowstone partagé sans duplication provider | source/API canary | N1 FOUNDATION IMPLEMENTED |
| façade Solana Yellowstone standard distincte du moteur | public API canary | PARTIAL : 7 unary N2 / Subscribe TODO |
| PublicNode représenté comme provider/capabilities, pas comme nouveau protocole | public API/config canary | TODO `pre.010/011` |
| PublicNode représenté comme provider/capabilities, pas comme nouveau protocole | public API/config canary | TODO `pre.011/012` |
| provider peut réutiliser, restreindre ou étendre N2 sans dupliquer N1 | capability/completeness review | architecture conservée |
| aucune équivalence provider/standard présumée sans preuve | provider matrix/tests | architecture conservée |
| façade provider spécialisée seulement si delta réel | completeness review | TODO provider integration |
@@ -405,14 +405,15 @@ Les autres providers restent en TODO/IDEAS sans release dédiée. Aucune façade
pre.001 DONE audit/sizing/architecture 1520 min nominal
pre.002 DONE moteur: deps/settings/errors/channel 1520 min ; gate final fix.002 PASS
pre.003 DONE TLS/metadata + fixture + 7 unary standard 1520 min ; gate final fix.001 PASS
pre.004 CANDIDATE standard: Subscribe common/from_slot/bounds 1520 min
pre.005 TODO standard: accounts + slots 1520 min
pre.006 TODO standard: transactions + transaction_status 1520 min
pre.007 TODO standard: blocks + block_meta + entry 1520 min
pre.008 TODO moteur: bidi/backpressure/half-close/shutdown 1520 min
pre.009 TODO moteur: reconnect/replay/gap/duplicate 1520 min
pre.010 TODO Config V3 + protocol/provider + profils PublicNode 1520 min
pre.011 TODO PublicNode live + compliance + docs/prompt 0.2.10 1520 min
pre.004 DONE standard: Subscribe common/from_slot/bounds 1520 min ; gate final fix.001 PASS
pre.005 DONE standard: accounts + slots 1520 min ; gate final fix.001 PASS
pre.006 CANDIDATE structure: namespace privé HTTP `http_*` 1520 min
pre.007 TODO standard: transactions + transaction_status 1520 min
pre.008 TODO standard: blocks + block_meta + entry 1520 min
pre.009 TODO moteur: bidi/backpressure/half-close/shutdown 1520 min
pre.010 TODO moteur: reconnect/replay/gap/duplicate 1520 min
pre.011 TODO Config V3 + protocol/provider + profils PublicNode 1520 min
pre.012 TODO PublicNode live + compliance + docs/prompt 0.2.10 1520 min
rel.001 TODO stable
```
@@ -649,7 +650,7 @@ Le proto publié `yellowstone-grpc-proto 12.6.0` a été recontrôlé avant impl
| Core dependency canary | 3/3 PASS | inchangé |
| `cargo test --workspace` | PASS + mêmes warnings à la compilation | à réexécuter sans warning |
Les dix symboles concernés (`to_wire` et `commitment_to_wire`) servent uniquement aux tests de projection protobuf de `pre.004`. Le stream bidi n'étant pas ouvert avant `pre.008`, ils ne font pas encore partie du runtime. `#[cfg(test)]` évite donc un faux code mort de production sans créer une seconde implémentation ni modifier le contrat public. Lors de l'intégration runtime du stream, ces helpers seront naturellement retirés du `cfg(test)` au moment où ils auront un consommateur de production.
Les dix symboles concernés (`to_wire` et `commitment_to_wire`) servent uniquement aux tests de projection protobuf de `pre.004`. Le stream bidi n'étant pas ouvert avant `pre.009`, ils ne font pas encore partie du runtime. `#[cfg(test)]` évite donc un faux code mort de production sans créer une seconde implémentation ni modifier le contrat public. Lors de l'intégration runtime du stream, ces helpers seront naturellement retirés du `cfg(test)` au moment où ils auront un consommateur de production.
**Verdict `pre.004-fix.001` : fermé.**
@@ -693,7 +694,7 @@ Les dix symboles concernés (`to_wire` et `commitment_to_wire`) servent uniqueme
| audit Rust workspace local | PASS / clean |
| fmt/check/Clippy/tests | opérateur TODO |
Les conversions request protobuf et les décodeurs Account/Slot sont test-only jusqu'à `pre.008`, faute de consommateur runtime avant l'ouverture du stream. Le contrat public reste entièrement KSP-owned.
Les conversions request protobuf et les décodeurs Account/Slot sont test-only jusqu'à `pre.009`, faute de consommateur runtime avant l'ouverture du stream. Le contrat public reste entièrement KSP-owned.
**Verdict `pre.005` : candidate source prête ; fermeture après gate Cargo opérateur.**
@@ -714,8 +715,48 @@ Les conversions request protobuf et les décodeurs Account/Slot sont test-only j
| Core dependency canary | 3/3 PASS | inchangé |
| `cargo test --workspace` | PASS + 4 warnings à la compilation | à réexécuter sans warning |
Les quatre constantes concernées sont exclusivement consommées par les décodeurs Account/Slot eux-mêmes sous `#[cfg(test)]` jusqu'à l'ouverture du stream en `pre.008`. Elles passent donc sous le même `cfg(test)` plutôt que d'introduire un `allow(dead_code)`. Le receiver du helper Slot devient `self` car le type est `Copy`; la closure `is_some_and` reçoit un `return` explicite conformément à la politique Clippy KSP.
Les quatre constantes concernées sont exclusivement consommées par les décodeurs Account/Slot eux-mêmes sous `#[cfg(test)]` jusqu'à l'ouverture du stream en `pre.009`. Elles passent donc sous le même `cfg(test)` plutôt que d'introduire un `allow(dead_code)`. Le receiver du helper Slot devient `self` car le type est `Copy`; la closure `is_some_and` reçoit un `return` explicite conformément à la politique Clippy KSP.
Le même fix réaligne tous les tableaux Markdown de `016` et `012` sans modifier leur contenu sémantique.
**Verdict `pre.005-fix.001` : correctif source/documentaire prêt ; fermeture de `pre.005` après gate opérateur sans warning.**
### 20.2 Gate final opérateur `pre.005-fix.001`
| Gate | Résultat final |
|------------------------------------------|----------------|
| `cargo fmt --all` | PASS |
| audit Rust workspace | PASS / clean |
| `cargo check --workspace` | PASS |
| `cargo clippy --workspace --all-targets` | PASS |
| Transport unit | 364/364 PASS |
| Transport `public_api` | 45/45 PASS |
| Transport `release_completeness` | 38/38 PASS |
| Transport doctests | 4/4 PASS |
| Core dependency canary | 3/3 PASS |
| `cargo test --workspace` | PASS |
**Verdict : `pre.005` fermée.**
## 21. Gate `pre.006` — namespace privé HTTP
| Surface / invariant | État candidate |
|----------------------------------------------------------------|----------------|
| `client.rs -> http_client.rs` | SOURCE PASS |
| `executor.rs -> http_executor.rs` | SOURCE PASS |
| `pool.rs -> http_pool.rs` | SOURCE PASS |
| `resilience.rs -> http_resilience.rs` | SOURCE PASS |
| `settings.rs -> http_settings.rs` | SOURCE PASS |
| unit tests miroirs `http_*` | SOURCE PASS |
| types/fonctions publics HTTP | INCHANGÉS |
| `rpc_common/accounts/blocks/transactions` restent partagés | SOURCE PASS |
| `json_rpc`, `constants`, `error` non artificiellement préfixés | SOURCE PASS |
| anciens fichiers supprimés après application overlay | opérateur TODO |
| release-completeness canary namespace | SOURCE PASS |
| audit Rust workspace local | PASS / clean |
| fmt/check/Clippy/tests/workspace | opérateur TODO |
Le renommage est limité aux cinq modules dont l'ownership HTTP est sans ambiguïté. Il ne modifie aucune signature publique et n'introduit aucune dépendance. L'overlay ZIP ajoute les nouveaux chemins ; les cinq anciens fichiers source et leurs cinq unit tests miroirs doivent être supprimés explicitement par l'opérateur après extraction.
**Verdict `pre.006` : candidate structurelle prête ; fermeture après suppressions opérateur et gate Cargo complet.**