# Delta `0.2.11-pre.010` — Hardening et complétude technique Off-chain Transport ## 1. Base requise Cette tranche s'applique exclusivement après l'état validé : ```text v0.2.10 + 0.2.11-pre.001 + 0.2.11-pre.001-fix.001 + 0.2.11-pre.002 + 0.2.11-pre.002-fix.001 + 0.2.11-pre.002-fix.002 + 0.2.11-pre.002-fix.003 + 0.2.11-pre.003 + 0.2.11-pre.003-fix.001 + 0.2.11-pre.004 + 0.2.11-pre.004-fix.001 + 0.2.11-pre.005 + 0.2.11-pre.006 + 0.2.11-pre.007 + 0.2.11-pre.008 + 0.2.11-pre.008-fix.001 + 0.2.11-pre.009 ``` Le gate opérateur de `pre.009` est intégralement PASS : audits Rust/Markdown, `cargo check --workspace`, `cargo clippy --workspace --all-targets`, tests ciblés `ksp-offchain-transport-lib`, tests Config et `cargo test --workspace`. Seuls les smokes live et probes de timing explicitement `ignored` restent hors du gate déterministe. La version workspace devient : ```text 0.2.11-pre.10 ``` ## 2. Mission `pre.010` ne crée aucun provider ni endpoint supplémentaire. La tranche durcit l'état fonctionnel complet obtenu par `pre.009` avant le gate technique/live de `pre.011`. Le scope est limité à : ```text forward compatibility de la façade publique complétude exacte des huit providers V1 hardening numeric/timestamps/provenance redaction et ownership de diagnostics/secrets interdiction durable des URL/rate-limit provider libres dans Config brouillons techniques README/USAGE correction de la documentation technique du refresh multiple V1 ``` La réconciliation documentaire finale reste explicitement réservée à `pre.012`. ## 3. Forward compatibility de la façade publique Les enums publiques dont l'espace de valeurs doit pouvoir évoluer sont désormais `#[non_exhaustive]` : ```text MarketPricePair MarketPriceSemantics MarketPriceProviderAuthMode MarketPriceProviderRateLimitScope MarketPriceProviderRateLimitKind MarketPriceProviderQuotaPeriod MarketPriceProviderQuotaUnit MarketPriceProviderAvailability MarketPriceCoinGeckoAccessMode MarketPriceCoinMarketCapAccessMode MarketPriceJupiterAccessMode MarketPriceProviderSetup ``` Cette décision évite qu'une future paire, sémantique, classe de quota, disponibilité, access mode ou provider impose une rupture source aux consumers qui respectent la façade évolutive. Les structs à champs privés restent extensibles sans attribut supplémentaire. `ksp-config-lib` étant une crate downstream, ses matches CoinGecko/CoinMarketCap/Jupiter absorbent maintenant explicitement les futures variantes inconnues via une erreur Config effective sûre. La Config ne suppose donc plus que ces enums resteront exhaustifs pour toujours. ## 4. Complétude release-level des huit providers Un nouveau canari `tests/release_completeness.rs` construit les huit setups désactivés et vérifie l'inventaire exact, ordonné et provider-neutral : ```text birdeye coinbase_exchange coingecko coinmarketcap coinpaprika dexscreener jupiter kraken ``` Il verrouille pour chaque entrée : ```text provider_id MarketPriceSemantics MarketPriceProviderAuthMode du mode testé support SOL/USD availability Disabled ``` Le même canari vérifie statiquement que les enums évolutives restent `#[non_exhaustive]`. Aucun neuvième provider, autre paire ou abstraction wire publique n'est ajouté. ## 5. Hardening adversarial numeric, timestamps et provenance Les tests déterministes sont complétés pour couvrir : ### 5.1 `MarketPriceDecimal` Rejet explicite de formes JSON qui ne doivent jamais devenir un prix réussi : ```text null booléens objet tableau zéro string négatif string scale/exposant pathologique overflow d'exposant ``` Le chemin canonique reste sans `serde_json::Value::as_f64` dans les modules `market_price_*`. ### 5.2 Timestamps provider Les helpers communs couvrent désormais : ```text RFC3339 valide avec millisecondes fractionnelles pré-epoch rejeté RFC3339 invalide rejeté Unix seconds valide multiplication Unix seconds overflow rejetée ``` Aucun timestamp provider n'est inventé lorsqu'une source ne fournit pas une vraie information temporelle du prix. ### 5.3 Provenance `MarketPriceProvenance` est canarisée à sa borne maximale exacte et rejette : ```text dépassement de borne leading/trailing whitespace contrôle tabulation ``` Les erreurs provider invalides conservent seulement le provider et le champ sûrs dans leur contexte. ## 6. Hardening secrets, diagnostics et ownership Le nouveau canari `tests/security_hardening.rs` vérifie notamment : ```text Debug Birdeye/CoinGecko/CoinMarketCap/Jupiter ne contient pas la clé Debug MarketPriceService ne contient pas la clé aucun module market_price_* ne lit std::env aucun module market_price_* n'utilise as_f64 comme vérité prix aucun module market_price_* n'utilise tracing:: directement schema Config sans base_url/endpoint_url/rate_limit/requests_per provider ``` Les origines HTTPS, headers et cadences restent donc possédés par Off-chain Transport. ## 7. Hardening Config Un test Config adversarial injecte dans le document standard des champs non autorisés représentant : ```text base_url provider arbitraire rate_limit provider arbitraire ``` Le schema strict doit les rejeter avant le mapping runtime. Cette protection complète les canaries statiques et empêche qu'une future modification du document transforme silencieusement Config en bypass SSRF/credential-redirection ou en moyen d'augmenter une cadence provider. Les access modes `#[non_exhaustive]` reçoivent aussi une branche downstream future-safe dans l'adapter Config ; aucune variante inconnue n'est interprétée arbitrairement. ## 8. Refresh multiple V1 explicitement séquentiel Le plan d'origine conservait encore une phrase préparatoire affirmant que les providers éligibles seraient lancés concurremment. Cette phrase était devenue fausse depuis `pre.008`, qui a délibérément matérialisé V1 comme séquentielle et déterministe. `pre.010` réconcilie le **contrat technique courant**, sans attendre la documentation finale : ```text refresh_many valide tous les IDs avant dispatch ordre demandé conservé refresh_all suit l'ordre stable du registry aucun sleep pour attendre un cooldown provider non éligible projeté immédiatement aucun fallback aucun consensus aucune agrégation ``` La concurrence n'est pas interdite pour toujours, mais elle nécessitera un contrat futur explicite sur ordre observable, admission et rate limiting. ## 9. Brouillons techniques README/USAGE La nouvelle crate reçoit ses premiers documents techniques : ```text crates/ksp-offchain-transport-lib/README.md crates/ksp-offchain-transport-lib/USAGE.md ``` Ils décrivent la taxonomie hétérogène, la façade `MarketPrice*`, les huit providers, les frontières Config/HTTP, numeric safety, refresh séquentiel V1 et les règles de diagnostic. `ksp-config-lib/README.md` et `USAGE.md` sont complétés pour documenter `cfg.std.offchain_transport`, les nouvelles ressources du registry et la direction : ```text ksp-config-lib -> ksp-offchain-transport-lib ``` Ces textes sont explicitement qualifiés de brouillons techniques. Ils ne remplacent pas la réconciliation documentaire finale de `pre.012` et ne revendiquent aucun résultat live de `pre.011`. ## 10. Scope inchangé La tranche n'ajoute pas : ```text provider supplémentaire SOL/EUR ou autre paire endpoint nouveau SDK provider fallback consensus/moyenne/médiane scheduler périodique concurrence de refresh multiple cache/historique smoke live swap_quote application Price Desk ``` ## 11. Validations sandbox et gate opérateur demandé Les audits exécutables dans le sandbox sur l'état final donnent : ```text General Rust rule audit: clean Rust export completeness audit: 0 candidate(s) KSP workspace Rust rule audit: clean Markdown table audit: clean (124 tables / 118 files) Rust > 160 colonnes dans les crates touchées: 0 ``` Cargo n'est pas disponible dans le sandbox de production du delta ; aucune compilation locale n'est donc revendiquée. Après application : ```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.11 cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-offchain-transport-lib cargo test -p ksp-config-lib cargo test --workspace ``` Le gate attendu doit rester sans warning. Les smokes live demeurent réservés à `pre.011`. ## 12. Fichiers ajoutés ```text crates/ksp-offchain-transport-lib/README.md crates/ksp-offchain-transport-lib/USAGE.md crates/ksp-offchain-transport-lib/tests/release_completeness.rs crates/ksp-offchain-transport-lib/tests/security_hardening.rs crates/ksp-offchain-transport-lib/unit_tests/market_price_adapter.rs deltas/0.2.11/pre.010.md ``` ## 13. Fichiers modifiés ```text Cargo.toml crates/ksp-config-lib/README.md crates/ksp-config-lib/USAGE.md crates/ksp-config-lib/src/offchain_transport.rs crates/ksp-config-lib/unit_tests/offchain_transport.rs crates/ksp-offchain-transport-lib/src/lib.rs crates/ksp-offchain-transport-lib/src/market_price_adapter.rs crates/ksp-offchain-transport-lib/src/market_price_coingecko.rs crates/ksp-offchain-transport-lib/src/market_price_coinmarketcap.rs crates/ksp-offchain-transport-lib/src/market_price_jupiter.rs crates/ksp-offchain-transport-lib/src/market_price_provider.rs crates/ksp-offchain-transport-lib/src/market_price_service.rs crates/ksp-offchain-transport-lib/unit_tests/market_price_decimal.rs crates/ksp-offchain-transport-lib/unit_tests/market_price_observation.rs docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md ``` ## 14. Fichiers supprimés Aucun. ## 15. Autorité du delta Le présent delta décrit uniquement `0.2.11-pre.010`. Les résultats Cargo du gate opérateur demandé après application devront être reportés dans la validation courante ou dans un éventuel fix si un défaut réel est détecté. `pre.011` reste propriétaire du gate technique/live final ; `pre.012` de la réconciliation documentaire finale ; `pre.013` de la préparation minimale de publication.