# Delta `v0.2.1-pre.003` ## Base Base attendue : `v0.2.1-pre.002-fix.001`, validée localement avant ouverture de cette tranche. Version Cargo cible : ```text 0.2.1-pre.3 ``` ## Objectif Matérialiser la première couche de client/routing HTTP de `ksp-onchain-transport-lib` sans encore exécuter de méthode JSON-RPC : - client endpoint logique autour de `reqwest::Client` ; - pool logique KSP ; - matching rôle/capability ; - priorité globale ; - round-robin équitable dans un même tier ; - fallback lorsque les candidats plus prioritaires ne sont pas sélectionnables ; - snapshots sûrs sans URL ; - préparation des états passifs nécessaires à la résilience de `pre.004`. Cette tranche corrige également l'usage de `ROADMAP.md` afin de respecter son contrat existant : le ROADMAP décrit l'état synthétique et la planification majeure, pas l'historique des prereleases/fixes. ## Modifications ### Workspace - `workspace.package.version` passe de `0.2.1-pre.2.fix.1` à `0.2.1-pre.3` ; - `reqwest` reste centralisé sous `[workspace.dependencies]`, avec `default-features = false` ; - activation explicite de la feature `rustls`, nécessaire à la construction réelle de clients HTTPS dans cette tranche ; - aucune feature `json` n'est ajoutée : les envelopes JSON-RPC restent possédées par KSP via `serde_json` ; - aucune dépendance Tokio directe n'est ajoutée à Transport dans cette tranche. ### `HttpEndpointClient` Nouveau client endpoint logique : - encapsule un `reqwest::Client` partageable ; - applique `connect_timeout`, `request_timeout` et `max_idle_connections_per_host` depuis les settings KSP ; - désactive les redirects automatiques ; - désactive les proxies système/environnement implicites ; - fixe un `User-Agent` KSP `ksp-onchain-transport-lib/` ; - conserve l'URL hors de toute surface `Debug`/snapshot ; - expose uniquement identité, provider, cluster, état et capability matching sûrs. ### Snapshots et état passif Nouveaux contrats publics : ```text HttpEndpointAvailability HttpEndpointRoleSnapshot HttpEndpointSnapshot HttpTransportPoolSnapshot ``` Les snapshots ne contiennent jamais l'URL endpoint. `HttpEndpointAvailability` réserve : ```text Disabled Available Degraded RateLimited ``` `pre.003` ne produit activement que `Disabled` et `Available`. Les transitions `Degraded` / `RateLimited` appartiennent à `pre.004` avec cooldown, limiter et observations runtime. ### `HttpTransportPool` Nouveaux contrats publics : ```text HttpTransportPool HttpEndpointSelection ``` Algorithme concret de `pre.003` : 1. valider les settings Transport ; 2. construire un client logique par endpoint ; 3. exclure les endpoints disabled ; 4. rechercher un rôle exact enabled ; 5. exiger la capability exacte ou `*` ; 6. choisir la plus faible priorité numérique ; 7. appliquer un round-robin par couple rôle/request-kind dans ce meilleur tier ; 8. utiliser un tier moins prioritaire lorsque les candidats plus prioritaires ne sont pas sélectionnables ; 9. retourner `endpoint_selection_failed` si aucun candidat n'existe. Le mutex synchrone du pool protège uniquement les curseurs de fairness et ne couvre aucune I/O ni aucun `await` réseau. `select_for_method()` dérive le `request_kind` depuis le registre central et appelle `ensure_runtime_supported()` avant sélection ; une méthode historique `Removed` ne peut donc pas être routée comme méthode standard. ### ROADMAP `ROADMAP.md` est ramené à son rôle défini par `FILE_CONTRACTS.md` : - suppression des lignes servant de journal `0.2.1-pre.*` / `fix.*` ; - conservation d'un état synthétique de `0.2.0` ; - état synthétique courant de `0.2.1` ; - conservation des releases fonctionnelles `0.2.1+` et de leur planification majeure. Aucune règle normative nouvelle n'est nécessaire : cette correction applique le contrat `ROADMAP.md` déjà documenté. ### Plan `008` Le plan est synchronisé avec : - la feature TLS réellement retenue ; - la politique client `reqwest` ; - le statut réalisé de `pre.003` ; - l'état exact après la tranche ; - le report explicite des limiteurs/concurrence/cooldown/retry effectifs à `pre.004`. ## Tests ajoutés La crate Transport passe de 40 à **53 tests déclarés**. Nouvelles preuves : - snapshot client sans URL/secret ; - endpoint disabled visible mais non sélectionnable ; - matching rôle/wildcard capability ; - priorité globale ; - round-robin dans le meilleur tier ; - fallback depuis un endpoint plus prioritaire disabled ; - filtrage capability avant priorité ; - erreur structurée lorsque rien ne correspond ; - routing d'une méthode standard via son descriptor ; - snapshot pool sûr conservant les endpoints disabled ; - consommation du nouveau pool depuis l'API publique. ## Hors périmètre conservé Restent à `pre.004` : - token bucket RPS/burst ; - semaphore/max concurrent ; - cooldown après `429` ; - deadline effective de sélection/exécution ; - retry/backoff effectif ; - classification des erreurs `reqwest` pendant une requête ; - transitions runtime `Degraded` / `RateLimited`. Restent à `pre.005+` : - exécution JSON-RPC HTTP ; - méthodes canari typées ; - document Config standard et adapter ; - smoke tests réseau. ## Sources externes revérifiées Pour `reqwest 0.13` : - dépôt/documentation officielle `reqwest` : rustls est le backend TLS de référence actuel ; - changelog `reqwest` : en `0.13`, la feature historique `rustls-tls` a été renommée `rustls` ; - `ClientBuilder` officiel : `connect_timeout`, `timeout`, `pool_max_idle_per_host`, `redirect` et `no_proxy` sont disponibles sur le client async retenu. ## Validation Non exécutée dans le sandbox de génération : `cargo` et `rustc` n'y sont pas installés. À exécuter après application : ```bash cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-onchain-transport-lib cargo test --workspace cargo tree -p ksp-onchain-transport-lib cargo tree -p ksp-onchain-transport-lib -d cargo tree -p ksp-onchain-transport-lib -e features cargo tree -p ksp-onchain-transport-lib -e normal ``` Les quatre `cargo tree` doivent être rejoués dans cette tranche car le feature-set de `reqwest` change avec l'activation de `rustls`. ## Suite Tranche suivante prévue : ```text 0.2.1-pre.004 ``` Périmètre : RPS/burst, concurrence, cooldown/429, timeout/deadline et retry/backoff borné, avec respect strict de `TransportRetryClass` et interdiction de resend après dispatch ambigu.