Files
khadhroony-solana-project/docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md
2026-08-26 12:06:51 +02:00

49 KiB

Validation 0.2.11 — Off-chain price transport SOL/USD

1. Objet

Cette matrice suit la release 0.2.11 — Off-chain price transport ouverte par pre.001.

Le contrat fonctionnel V1 est :

SOL/USD uniquement
plusieurs providers gratuits admis
HTTP REST reqwest uniquement
aucun SDK provider
provider/rate-limit/availability possédés par ksp-offchain-transport-lib
Config -> Off-chain Transport sans dépendance inverse
future ksp-app-solprices-desk purement HID et provider-agnostic

Les statuts PLANNED restent non validés tant que la tranche correspondante n'est pas exécutée.

2. Gate 0.2.11-pre.001

Critère Statut Preuve
archive stable v0.2.10 utilisée PASS archive Gitea fournie par l'opérateur
workspace.package.version = 0.2.10 à l'entrée PASS inspection Cargo.toml
deltas/0.2.10/rel.001.md présent PASS inspection archive
prompts/016-V0_2_11_START_PROMPT.md présent PASS inspection archive
.git absent de l'archive PASS inspection filesystem
ksp-offchain-transport-lib absent à l'entrée PASS inventaire workspace
primitives reqwest/serde/serde_json/tokio/http déjà présentes PASS inventaire [workspace.dependencies]
audit providers gratuit/live actuel PASS sources officielles CoinGecko, CMC, CoinPaprika, Kraken, Coinbase, Jupiter, Birdeye, DS
conditions d'usage gratuites distinguées du transport PASS plan 018, gratuité technique distincte de licence commerciale durable
SOL/USD retenu comme seule paire V1 PASS décision opérateur + plan 018
aucun SDK provider retenu PASS décision opérateur + plan 018
huit providers retenus pour implémentation PASS plan 018 section provider
DexScreener V1 limité à une paire SOL/USD configurée PASS décision opérateur + plan 018
future ksp-app-solprices-desk purement HID PASS décision opérateur + architecture
ownership rate limits/availability dans Off-chain Transport PASS décision opérateur + plan 018
threat model V1 établi PASS plan 018
forecast prereleases établi PASS plan 018
code runtime provider ajouté en pre.001 N/A interdit par le gate, aucune crate créée

3. Gate 0.2.11-pre.002

Critère Statut Preuve
crate ksp-offchain-transport-lib créée PASS membre workspace + package dédié
version workspace synchronisée sur 0.2.11-pre.2 PASS Cargo.toml racine
dépendance inverse vers Config absente PASS manifest crate
reqwest et SDK providers absents de la fondation PASS manifest crate
MarketPriceDecimal exact sans canon f64 PASS coefficient u128, scale 18, sérialisation string
SOL/USD seule paire publique V1 PASS MarketPricePair::SolUsd + MarketPriceObservation
identifiant/descripteur provider opaques PASS MarketPriceProviderId + MarketPriceProviderDescriptor
auth/rate-limit/quota représentables génériquement PASS types provider-neutral dédiés
settings communs sans faux endpoint/API key PASS MarketPriceProviderCommonSettings
availability provider-neutral représentable PASS MarketPriceProviderAvailability + MarketPriceProviderState
HTTP actif ou adapter provider ajouté N/A explicitement réservé à pre.003+

3.1 Taxonomie Off-chain et observabilité

Invariant Statut
crate ksp-offchain-transport-lib non assimilée à une crate price-only PASS
capacité V1 classée sous modules privés market_price_* PASS
modules partagés constants.rs et error.rs restent crate-wide PASS
futures quotes prévues sous famille distincte swap_quote_* PASS
aucune abstraction future créée sans responsabilité réellement partagée PASS
market_price V1 strictement read-only PASS
verbe HTTP distinct de la sémantique métier read/write PASS
soumission/signature Solana reste hors d'Off-chain Transport PASS
ksp-logging-lib utilisé pour les événements KSP de la crate PASS
src/constants.rs possède TRACING_TARGET = ksp-offchain-transport-lib PASS
aucune dépendance directe à tracing PASS
crate-rustdocs présentes dans les tests d'intégration PASS

3.2 Correctif 0.2.11-pre.002-fix.002

Le gate cargo clippy --workspace --all-targets de pre.002-fix.001 a détecté un unique écart clippy::implicit-return dans le canari tests/dependency_boundary.rs. Le correctif ajoute le return explicite attendu dans la closure de Iterator::any et synchronise workspace.package.version sur 0.2.11-pre.2.fix.2. Aucun contrat public, comportement runtime ou scope provider n'est modifié.

Les validations opérateur du 2026-08-25 sur pre.002-fix.002 sont : cargo fmt --all PASS, audit Rust PASS, audit Markdown PASS, cargo check --workspace PASS, cargo test -p ksp-offchain-transport-lib PASS avec 13 tests exécutés, et cargo clippy --workspace --all-targets PASS. cargo test --workspace n'a pas été rejoué après ce fix et n'est donc pas déclaré PASS pour cet état exact.

3.3 Correctif 0.2.11-pre.002-fix.003

Le nommage public initial Price* restait trop générique alors que les modules qui possèdent ces contrats sont explicitement la famille market_price_*. Le correctif synchronise workspace.package.version sur 0.2.11-pre.2.fix.3 et renomme sans alias de compatibilité toute la surface publique spécifique à cette famille en MarketPrice* / MARKET_PRICE_*.

Le contrat attendu après application est :

MarketPriceDecimal
MarketPriceObservation
MarketPriceTimestamp
MarketPriceProvenance
MarketPricePair
MarketPriceSemantics
MarketPriceProvider*
MARKET_PRICE_*
ERROR_CODE_MARKET_PRICE_*

Cette correction reste dans la responsabilité de pre.002 : elle stabilise la fondation et sa façade avant l'introduction du HTTP runtime en pre.003.

3.4 Gate 0.2.11-pre.003

Critère Statut Preuve
version workspace 0.2.11-pre.3 PASS Cargo.toml racine
reqwest utilisé directement, sans SDK provider PASS manifest ksp-offchain-transport-lib
primitives HTTP communes sous modules http_* crate-private PASS http_client, http_settings, http_admission
client HTTP générique non exporté aux consumers PASS façade lib.rs
redirects, Referer, proxy système et retries reqwest désactivés PASS construction HttpRestClient
connect/request timeouts bornés PASS HttpClientSettings
body borné pendant lecture chunked avant désérialisation PASS HttpRestClient::get_json
JSON syntaxiquement validé sans normalisation numérique intermédiaire PASS serde::de::IgnoredAny sur bytes bruts
401/403, 429, 408/5xx et autres statuts distingués PASS codes d'erreur HTTP dédiés
URL reqwest supprimée des sources d'erreur PASS reqwest::Error::without_url
body remote non recopié dans les erreurs PASS erreurs construites uniquement depuis metadata safe
limiter fixe lissé et burst absent traité conservativement PASS HttpAdmissionController
limite dynamique n'invente pas de cadence locale PASS HttpAdmissionPolicy::Dynamic
cooldown Retry-After borné et admission non bloquante PASS record_rate_limited + try_admit
adapters CoinGecko/Jupiter/etc. ajoutés N/A explicitement réservés à pre.004+
gate Cargo check/clippy/tests Off-chain sur pre.003-fix.001 PASS résultats opérateur du 2026-08-25
audit Rust final de pre.003-fix.001 CARRY seul RUST-FMT-108, cause supprimée en pre.004

Les tests déterministes de pre.003 couvrent en particulier le body chunked dépassant la limite, le refus des redirects, un 429 avec Retry-After, la non-propagation d'un body distant canari, le JSON invalide et le refill/cooldown du limiter.

3.5 Correctif 0.2.11-pre.003-fix.001

Le gate opérateur de pre.003 a révélé quatre classes d'écarts avant poursuite vers pre.004 : six violations RUST-FMT-104 dans src/error.rs, six réexports pub(crate) HTTP inutilisés dans le build normal, un test de burst rejeté par la validation burst > requests, et la non-utilisation de la façade crate-root dans les impl des items HTTP partagés. cargo check et cargo clippy terminaient avec les warnings de réexports, tandis que cargo test -p ksp-offchain-transport-lib échouait sur documented_burst_is_consumed_atomically_before_refill.

Le correctif applique les règles suivantes :

RUST-FMT-005 / RUST-FMT-104 : constantes homogènes triées alphabétiquement
RUST-IMPORT-009 / RUST-API-004 : items HTTP partagés consommés via crate::Item, y compris dans leurs impl
RUST-API-008 : helpers préparatoires sans consumer production sous #[cfg(test)], aucun #[allow(dead_code)] compensatoire
contrat limiter : burst documenté indépendant de la cadence moyenne et autorisé à la dépasser

Le cas 1 req/s avec burst 2 devient un canari déterministe ; il protège notamment la représentabilité du cas Coinbase documenté dans le plan à 10 req/s, burst 15. Les modules http_* restent donc testés et prêts en pre.003, mais leur compilation normale sera activée en pre.004 lorsque les premiers adapters de production les consommeront réellement.

La version Cargo du correctif est 0.2.11-pre.3.fix.1. Le gate opérateur du 2026-08-25 confirme cargo check --workspace PASS, cargo clippy --workspace --all-targets PASS et cargo test -p ksp-offchain-transport-lib PASS avec 22 unitaires, 2 boundary et 2 public API. L'audit Rust signale uniquement RUST-FMT-108 dans src/lib.rs, conséquence directe du staging #[cfg(test)] des modules http_*. L'opérateur a explicitement décidé de ne pas publier un fix artificiel pour ce point puisque pre.004 retire ce staging avec les premiers consumers de production.

3.6 Gate 0.2.11-pre.004

Critère Statut Preuve
version workspace 0.2.11-pre.4 PASS Cargo.toml racine
modules http_* actifs en production, sans staging crate-root test PASS src/lib.rs
cause RUST-FMT-108 de pre.003-fix.001 supprimée PASS modules production avant tests
CoinGecko SOL/USD adapter public PASS market_price_coingecko.rs
CoinGecko keyless et Demo key distingués PASS settings + descriptor + header sensible
CoinMarketCap SOL/USD adapter public PASS market_price_coinmarketcap.rs
CoinMarketCap Simple Price V2 utilisé, V1 deprecated absent du runtime PASS endpoints V2 fixes + canari dependency boundary
CoinMarketCap keyless et Basic key distingués PASS settings + descriptor + header sensible
CoinPaprika SOL/USD adapter public PASS market_price_coinpaprika.rs
CoinPaprika sans faux credential PASS settings keyless uniquement
prix JSON provider parsé exactement sans passage par f64 PASS RawValue -> MarketPriceDecimal::parse_json_raw
timestamps provider conservés lorsqu'ils existent PASS Unix seconds CoinGecko, RFC3339 CoinMarketCap/CoinPaprika
DTOs wire provider privés PASS structs privées dans chaque module provider
endpoints provider fixes et HTTPS PASS constantes privées + HttpGetRequest::new_https
API keys absentes de Debug et diagnostics PASS MarketPriceApiKey redacted + tests settings
429 alimente le cooldown local partagé PASS get_json -> record_rate_limited
aucun SDK provider PASS manifest + boundary tests
Config, registry global et refresh multiple non avancés PASS scopes réservés à pre.007+ / pre.009
audit Rust sandbox PASS clean, 0 candidate export
audit Markdown sandbox PASS clean, 119 tables / 110 fichiers
gate Cargo complet pre.004 FAIL audit Rust : 1 x RUST-FMT-104 ; Clippy : 2 warnings ; 1 fixture CMC KO

Les tests déterministes de pre.004 couvrent les modes d'auth, les headers sans fuite de credential, les URLs/query fixes, le parsing des réponses SOL/USD, le rejet d'identités ou schémas incohérents et le parsing exact des nombres JSON. Aucun smoke réseau n'est revendiqué dans cette tranche.

3.7 Correctif 0.2.11-pre.004-fix.001

Le gate opérateur du 2026-08-25 sur pre.004 a confirmé cargo check --workspace PASS, mais a détecté trois écarts avant pre.005 : une violation RUST-FMT-104 dans le bloc de constantes de src/error.rs, deux warnings clippy::collapsible_if dans les builders CoinGecko/CoinMarketCap et un échec du test coinmarketcap_v2_fixture_normalizes_string_status_and_exact_price.

L'échec CoinMarketCap provenait uniquement de la fixture : la concaténation produisait ...,151.987654321012345678,last_updated... au lieu de ...,151.987654321012345678,"last_updated".... Le parser runtime n'est pas modifié. Le correctif remet le bloc de constantes dans l'ordre alphabétique complet, utilise des let-chains pour les deux insertions de headers optionnels et corrige le JSON déterministe de la fixture.

La version Cargo du correctif est 0.2.11-pre.4.fix.1. Aucun endpoint, mode d'auth, descriptor, limite provider ou contrat public n'est modifié.

Le gate opérateur rejoué le 2026-08-25 est intégralement PASS : audit Rust clean avec 0 candidate export, audit Markdown clean à 118 tables / 109 fichiers, cargo check --workspace PASS, cargo clippy --workspace --all-targets PASS, cargo test -p ksp-offchain-transport-lib PASS avec 31 unitaires + 3 boundary + 3 public API, puis cargo test --workspace PASS avec uniquement les smokes/timing explicitement ignorés.

3.8 Gate 0.2.11-pre.005

Critère Statut Preuve
version workspace 0.2.11-pre.5 PASS Cargo.toml racine
Kraken Spot SOL/USD adapter public PASS market_price_kraken.rs
Kraken public keyless sans faux credential PASS settings + descriptor
Kraken dernier trade conservé avec sémantique exchange PASS ticker SOLUSD -> c[0] -> ExchangeLastTrade
Kraken ne fabrique aucun timestamp provider absent PASS provider_timestamp = None
Kraken cadence locale conservatrice 1 req/s IP PASS descriptor + canari unitaire
Coinbase Exchange SOL/USD adapter public PASS market_price_coinbase_exchange.rs
Coinbase Exchange public keyless sans faux credential PASS settings + descriptor
Coinbase dernier trade et timestamp provider conservés PASS price + time -> ExchangeLastTrade
Coinbase token bucket public 10 req/s IP, burst 15 PASS descriptor + canari unitaire
DTOs wire Kraken/Coinbase privés PASS structs privées dans les modules providers
endpoints provider fixes et HTTPS PASS constantes privées + boundary canary
prix exchange parsés exactement sans passage par f64 PASS RawValue -> MarketPriceDecimal::parse_json_raw
aucun SDK provider, Config ou registry global avancé PASS manifest + dependency boundary
audit Rust sandbox PASS clean, 0 candidate export
audit Markdown sandbox PASS clean, 119 tables / 110 fichiers
cargo check / Clippy / tests Off-chain PASS résultats opérateur du 2026-08-25
cargo test --workspace sur état exact pre.005 N/R non rejoué avant passage explicite à pre.006

Les tests déterministes de pre.005 couvrent les descriptors exchange, la précision décimale, le timestamp Coinbase, l'absence de timestamp Kraken, le rejet d'une erreur/identité Kraken incohérente et le rejet d'un timestamp Coinbase invalide. Le gate opérateur ciblé du 2026-08-25 est PASS : audit Rust clean, audit Markdown clean à 119 tables / 110 fichiers, cargo check --workspace PASS, cargo clippy --workspace --all-targets PASS et cargo test -p ksp-offchain-transport-lib PASS avec 37 unitaires + 3 boundary + 4 public API. cargo test --workspace n'a pas été rejoué sur cet état exact.

3.9 Gate 0.2.11-pre.006

Critère Statut Preuve
version workspace 0.2.11-pre.6 PASS Cargo.toml racine
Jupiter Price V3 adapter public PASS market_price_jupiter.rs
Jupiter keyless et Free key distingués PASS settings + descriptor + header sensible
Jupiter keyless 0,5 RPS et Free 1 RPS représentés PASS descriptors + canaries unitaires
Jupiter utilise uniquement le mint WSOL PASS query ids fixe
usdPrice Jupiter parsé exactement sans f64 canonique PASS RawValue -> MarketPriceDecimal
blockId Jupiter conservé en provenance sans faux timestamp PASS provenance bornée + provider_timestamp = None
DexScreener adapter public avec pair address explicite PASS MarketPriceDexScreenerSettings
DexScreener endpoint direct pair uniquement PASS /latest/dex/pairs/solana/{pairId}
DexScreener vérifie chainId, pair address et identité WSOL PASS parser provider
DexScreener utilise uniquement priceUsd PASS DTO wire privé + parsing exact
DexScreener 300 req/min représenté PASS descriptor provider
aucune découverte/selection/ranking automatique de pool PASS dependency boundary + absence search/token-pairs/tokens
aucun SDK provider, Config, registry ou refresh multiple avancé PASS manifest + scope des modules
audit Rust sandbox PASS clean, 0 candidate export
audit Markdown sandbox PASS clean, 120 tables / 111 fichiers
cargo check / Clippy / tests Off-chain PASS résultats opérateur du 2026-08-25
cargo test --workspace sur état exact pre.006 N/R non rejoué avant passage explicite à pre.007

Les fixtures de pre.006 couvrent Jupiter keyless/Free, redaction de la clé, prix exact, identité WSOL, blockId, absence volontaire de faux timestamp, ainsi que DexScreener avec pair Solana explicite, priceUsd, rejet de chain/pair/base invalides, réponse multiple et prix absent. Le gate opérateur ciblé du 2026-08-25 est PASS : audit Rust clean, audit Markdown clean à 120 tables / 111 fichiers, cargo check --workspace PASS, cargo clippy --workspace --all-targets PASS et cargo test -p ksp-offchain-transport-lib PASS avec 43 unitaires + 4 boundary + 5 public API. cargo test --workspace n'a pas été rejoué sur cet état exact.

3.10 Gate 0.2.11-pre.007

Critère Statut Preuve
version workspace 0.2.11-pre.7 PASS Cargo.toml racine
Birdeye Standard SOL/USD adapter public PASS market_price_birdeye.rs
Birdeye exige X-API-KEY lorsqu'activé PASS settings + header sensible
Birdeye fixe x-chain = solana et le mint WSOL PASS request builder
Birdeye Price Single value parsé exactement PASS RawValue -> MarketPriceDecimal
Birdeye updateUnixTime conservé comme timestamp provider PASS parser provider
Birdeye Standard 1 RPS compte modélisé PASS descriptor provider
quota Birdeye 30 000 compute units informatif PASS MarketPriceProviderLongTermQuota
coût Price Single 3 compute units informatif PASS MarketPriceProviderRequestCost
registry provider-neutral matérialisé PASS MarketPriceProviderRegistry
huit providers V1 présents dans le canari de complétude registry PASS test market_price_registry
registry trié par provider id et doublons rejetés PASS constructeur public générique + tests
entry publique limitée à descriptor + état générique PASS MarketPriceProviderRegistryEntry
availability expose éligibilité et retry_at génériques PASS MarketPriceProviderAvailability
registry sans mutation ou dispatch réseau PASS projection générique publique
registry ne contient aucun dispatch/name provider PASS dependency boundary
refresh single/multiple, Config et smoke live non avancés PASS scope réservé à pre.008+
audit Rust sandbox PASS clean, 0 candidate export
audit Markdown sandbox PASS clean, 121 tables / 112 fichiers
gate Cargo PASS gate opérateur complet du 2026-08-26

Les tests déterministes de pre.007 couvrent l'auth Birdeye et sa redaction, le descriptor 1 RPS / 30 000 CU / 3 CU, le parsing exact du prix et du timestamp, les réponses invalides, ainsi que le registry complet des huit providers, son ordre déterministe, le rejet de doublons et les projections d'availability. Le gate opérateur du 2026-08-26 est intégralement PASS : audits Rust/Markdown, cargo check --workspace, cargo clippy --workspace --all-targets, tests ciblés Off-chain et cargo test --workspace. Aucun smoke live provider n'est revendiqué.

3.11 Gate 0.2.11-pre.008

Critère Statut Preuve
version workspace 0.2.11-pre.8 PASS Cargo.toml racine
MarketPriceService provider-agnostic public PASS market_price_service.rs
setup provider-specific limité à la composition PASS MarketPriceProviderSetup
registry détachable sans dispatch provider PASS MarketPriceService::registry
refresh individuel par MarketPriceProviderId PASS MarketPriceService::refresh
refresh multiple par liste d'identifiants opaques PASS MarketPriceService::refresh_many
refresh all en ordre provider déterministe PASS MarketPriceService::refresh_all
doublons / provider inconnu rejetés avant dispatch PASS tests market_price_service
provider non éligible projeté sans requête réseau PASS eligibility + test huit providers disabled
429 / defer local projetés en CoolingDown PASS classification générique
401/403 keyed projetés en AuthenticationUnavailable PASS classification auth-aware
transport temporaire projeté sans rendre le service global inutilisable PASS outcome provider-neutral
aucune attente/sleep de rate limit dans le service PASS dependency boundary
aucun fallback, consensus ou agrégation multi-provider PASS scope + dependency boundary
Config, scheduling périodique et smoke live non avancés PASS scope réservé à pre.009+
audit Rust sandbox PASS clean, 0 candidate export
audit Markdown sandbox PASS clean, 122 tables / 113 fichiers
gate pre.008 brut FAIL 1 warning Clippy + 1 canari boundary FAIL
fix pre.008-fix.001 statique PASS audits Rust/Markdown sandbox
gate Cargo du fix PASS gate opérateur complet du 2026-08-26

Les tests déterministes de pre.008 vérifient le registry de service sur les huit setups V1, refresh_all sans réseau lorsque tous les providers sont désactivés, le rejet pré-dispatch des doublons/providers inconnus, les classes auth/rate-limit/temporaire/local misconfiguration et l'éligibilité temporelle des cooldowns. Les méthodes multiples restent séquentielles et déterministes dans V1 ; elles ne dorment jamais pour attendre un provider et ne font aucun fallback/consensus. Le gate opérateur initial a toutefois trouvé un warning clippy::collapsible_if et un canari boundary trop large (!service.contains("consensus")) qui échouait sur la rustdoc décrivant justement l'absence de consensus. pre.008-fix.001 corrige ces deux points sans modifier le comportement runtime. Le gate rejoué sur 0.2.11-pre.8.fix.1 est intégralement PASS : audits Rust/Markdown, cargo check --workspace, cargo clippy --workspace --all-targets, 54 tests unitaires + 6 boundary + 7 public API Off-chain, puis cargo test --workspace avec uniquement les smokes/timing explicitement ignorés.

3.12 Gate 0.2.11-pre.009

Critère Statut Preuve
version workspace 0.2.11-pre.9 PASS Cargo.toml racine
document cfg.std.offchain_transport enregistré PASS registry Config + std.offchain_transport.json
schema schema.std.offchain_transport enregistré PASS registry Config + schema Draft 2020-12
domaine actuel imbriqué sous market_price PASS document/schema V1
profils public_keyless et all_free versionnés PASS document standard + exemple
huit branches provider Config obligatoires PASS schema + fixture
credentials conditionnés par mode/provider PASS if/then du schema
credentials effectifs exigent une provenance Config Secret PASS adapter offchain_transport.rs + tests
littéral credential rejeté par l'adapter effectif PASS test literal_or_nonsecret_provider_credentials...
DexScreener pair requis seulement lorsque le provider est activé PASS schema + MarketPriceDexScreenerSettings
Dex pair via environnement exige une provenance Public PASS adapter Config + test
.env.example inventorie quatre secrets et la paire publique PASS .env.example
Config construit MarketPriceService via MarketPriceProviderSetup PASS ResolvedOffchainTransportConfig
Off-chain Transport ne dépend pas de Config PASS dependency ownership + manifest
aucune cadence provider libre ajoutée à Config PASS schema/document sans rate-limit override
Config Debug/safe view ne divulgue pas les API keys PASS tests adapter
applications desktop embarquent document + schema PASS deux tauri.conf.json + canaries desktop
audit Rust sandbox PASS clean, 0 candidate export
audit Markdown sandbox PASS clean, 123 tables / 115 fichiers
cargo check / Clippy / tests Config et workspace PASS gate opérateur complet du 2026-08-26

La tranche n'ajoute aucune URL provider configurable, aucun SDK provider et aucune lecture directe de l'environnement dans ksp-offchain-transport-lib. Les secrets restent résolus par ksp-config-lib; le service runtime reçoit uniquement les settings typés nécessaires. La modification DexScreener est capability-aware : une paire absente est valide uniquement lorsque l'adapter est désactivé, ce qui permet de conserver son entrée dans l'inventaire générique sans fabriquer de fausse configuration. 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 Off-chain, 119 tests unitaires Config et cargo test --workspace. Seuls les smokes live et probes de timing explicitement ignored restent non exécutés par le gate déterministe.

3.13 Gate 0.2.11-pre.010

Critère Statut Preuve
version workspace 0.2.11-pre.10 PASS Cargo.toml racine
enums publiques évolutives marquées #[non_exhaustive] PASS provider/access modes/setup + canari completeness
adapter Config future-safe face aux access modes non exhaustifs PASS branches wildcard vers erreur effective sûre
inventaire exact des huit providers et sémantiques verrouillé PASS tests/release_completeness.rs
aucun environnement lu par les modules market_price_* PASS tests/security_hardening.rs
aucun as_f64 utilisé comme vérité de prix market_price PASS tests/security_hardening.rs
aucun tracing:: direct dans market_price_* PASS tests/security_hardening.rs
Debug keyed settings/service ne divulgue pas les API keys PASS canari secret déterministe
Config rejette URL provider et override de rate limit PASS schema strict + test Config adversarial
timestamps RFC3339/pre-epoch/overflow durcis PASS unit test market_price_adapter
JSON numeric pathologique/null/non-numérique rejeté PASS unit test market_price_decimal
provenance accepte la borne et rejette trim/control/oversize PASS unit test market_price_observation
refresh_many / refresh_all V1 documentés séquentiels/déterministes PASS plan + README.md / USAGE.md Off-chain
README/USAGE techniques créés sans usurper la réconciliation finale PASS crate Off-chain + compléments Config
audit Rust sandbox PLANNED à exécuter sur l'état final de l'archive
audit Markdown sandbox PLANNED à exécuter sur l'état final de l'archive
cargo check / Clippy / tests ciblés et workspace PLANNED gate opérateur requis après application de pre.010

pre.010 ne fait aucun smoke live, ne change aucun endpoint provider et n'introduit ni fallback, ni consensus, ni scheduler. Les documents crate créés ici sont des brouillons techniques courants ; pre.012 reste seule propriétaire de la réconciliation documentaire finale après le gate technique/live de pre.011.

4. Matrice provider prévue

Provider SOL/USD V1 Gratuit V1 Mode auth prévu Test déterministe Smoke live Statut courant
CoinGecko Oui Oui keyless ou Demo key PASS PLANNED IMPLEMENTED
CoinMarketCap Oui Oui keyless ou Basic key PASS PLANNED IMPLEMENTED
CoinPaprika Oui Oui aucune PASS PLANNED IMPLEMENTED
Kraken Oui Oui aucune PASS PLANNED IMPLEMENTED
Coinbase Exchange Oui Oui aucune PASS PLANNED IMPLEMENTED
Jupiter Price V3 Oui Oui keyless ou Free key PASS PLANNED IMPLEMENTED
Birdeye Oui Oui API key Standard PASS PLANNED IMPLEMENTED
DexScreener Oui Oui aucune PASS PLANNED IMPLEMENTED

AUDITED signifie uniquement que la documentation officielle actuelle satisfait le gate d'entrée. Ce statut ne vaut pas preuve d'un smoke réseau KSP.

Avant la stable, les conditions d'usage et la persistance des offres gratuites doivent être réauditées ; un provider peut rester techniquement supporté tout en nécessitant un plan différent pour certains usages.

5. Contrat public prévu

Invariant Statut
surface publique limitée à SOL/USD dans V1 PASS
identifiants provider opaques pour les consumers PASS
provenance provider toujours observable PASS
sémantique de prix observable sans prétendre à une équivalence PASS
timestamp requête/réception KSP présents PASS
timestamp provider optionnel seulement lorsqu'il est réellement fourni PASS
absence de prix distincte de zéro PASS
f64 non utilisé comme canon public PASS
aucune structure wire provider exportée PASS
aucune URL/header/asset id provider requis côté app PASS
registry provider et état runtime possédés par Off-chain Transport PASS
refresh provider par identifiant générique PASS
refresh multiple sans connaissance provider côté consumer PASS

6. Rate limiting et availability

Cas Statut
cadence locale fixe représentable PASS
burst documenté supérieur à la cadence moyenne représentable PASS
limite dynamique keyless représentable PASS
429 classé PASS
Retry-After honoré lorsqu'exploitable PASS
cooldown expose prochain instant admissible PASS
refresh all ne lance que les providers éligibles PASS
provider en cooldown ne bloque pas les autres PASS
provider down ne rend pas le service global inutilisable PASS
auth rejetée distinguée d'un transport down PASS
quota indisponible distingué d'un transport down PLANNED
quota mensuel local non présenté comme compteur authoritative PASS

7. Numeric safety

Cas Statut
décimal string valide PASS
JSON number valide sans passage canonique par f64 PASS
notation scientifique bornée PASS
coefficient/scale overflow rejeté PASS
valeur négative rejetée PASS
zéro rejeté pour une observation réussie PASS
NaN/Inf impossibles dans le type canonique PASS
serialization canonique sans perte PASS
round-trip public déterministe PASS

8. HTTP et sécurité

Invariant Statut
reqwest seul client provider PASS
aucun SDK provider PASS
endpoint provider officiel fixe en V1 PASS
redirects désactivés PASS
proxy implicite désactivé selon policy KSP PASS
connect timeout borné PASS
request timeout borné PASS
body réponse borné avant parsing PASS
URL retirée des erreurs reqwest PASS
réponse remote brute absente des KspError/logs PASS
API key absente de Debug/log/error PASS
401/403 classés auth/access PASS
429 classé rate limit PASS
5xx classé transient PASS
schema drift classé provider protocol PLANNED

9. DexScreener V1

Invariant Statut
pair address SOL/USD explicite si provider actif PASS
chainId = solana vérifié PASS
identité SOL de la paire vérifiée PASS
priceUsd utilisé comme prix commun PASS
aucune recherche automatique de pool PASS
aucun tri automatique par liquidité PASS
aucune moyenne/consensus entre pools PASS

10. Config -> Off-chain Transport

Invariant Statut
Off-chain Transport ne dépend pas de Config PASS
document standard offchain dédié PASS
branches provider conditionnelles dans schema PASS
CoinGecko keyless/Demo représentés PASS
CoinMarketCap keyless/Basic représentés PASS
Jupiter keyless/Free représentés PASS
Birdeye exige credential lorsqu'activé PASS
DexScreener exige pair address lorsqu'activé PASS
providers sans auth n'exposent pas de faux champ API key PASS
secrets via Config uniquement PASS
.env.example synchronisé pour les secrets réellement ajoutés PASS
aucune cadence provider configurable au-dessus de la limite sûre PASS

11. Frontière future ksp-app-solprices-desk

Invariant Statut
nom de l'application fixé à ksp-app-solprices-desk DECIDED
rôle HID uniquement DECIDED
aucun enum/provider spécifique requis dans l'UI PLANNED
aucun endpoint/header/provider id propriétaire dans l'app PLANNED
table construite depuis l'inventaire générique Off-chain Transport PLANNED
refresh row appelle une opération générique PLANNED
refresh multiple appelle une opération générique PLANNED
cooldown/availability affichables depuis état générique PLANNED
aucune logique de rate limiting dans Tauri/frontend PLANNED

Cette section valide l'architecture préparée par 0.2.11; l'application elle-même reste hors scope et sera testée en 0.2.12.

12. Non-régression et gates finaux prévus

Gate Statut
cargo fmt --all PLANNED
audit Rust workspace PLANNED
audit Markdown tables PLANNED
cargo check --workspace PLANNED
cargo clippy --workspace --all-targets PLANNED
cargo test --workspace PLANNED
tests ksp-offchain-transport-lib PLANNED
tests Config PLANNED
cargo tree Off-chain Transport PLANNED
absence de dépendances provider SDK PLANNED
smokes keyless gratuits PLANNED
smokes keyed gratuits disponibles à l'opérateur PLANNED
réconciliation README/USAGE/plan/validation PLANNED

13. Hors scope validé

SOL/EUR et autres quotes
SPL token price générique
OHLCV/historique
streaming price
fallback automatique
consensus/moyenne/médiane
pool discovery DexScreener
Price Desk dans 0.2.11
Wallet Desk dans 0.2.11
Pyth V1
Binance SOL/USDT assimilé à SOL/USD