diff --git a/Cargo.toml b/Cargo.toml index f03ca45..afc98e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 279 +# version: 280 [workspace] resolver = "3" members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"] [workspace.package] -version = "0.2.11-pre.8" +version = "0.2.11-pre.8.fix.1" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/crates/ksp-offchain-transport-lib/src/market_price_service.rs b/crates/ksp-offchain-transport-lib/src/market_price_service.rs index 0c41c34..2f8dfc8 100644 --- a/crates/ksp-offchain-transport-lib/src/market_price_service.rs +++ b/crates/ksp-offchain-transport-lib/src/market_price_service.rs @@ -1,5 +1,5 @@ // file: crates/ksp-offchain-transport-lib/src/market_price_service.rs -// version: 1 +// version: 2 //! Generic market-price refresh service owning provider dispatch and availability transitions. @@ -204,10 +204,10 @@ impl crate::MarketPriceService { availability: crate::MarketPriceProviderAvailability, ) -> crate::MarketPriceProviderState { let mut guard = lock_registry(&self.registry); - if guard.set_availability(provider_id, availability) { - if let std::option::Option::Some(state) = guard.state(provider_id) { - return state.clone(); - } + if guard.set_availability(provider_id, availability) + && let std::option::Option::Some(state) = guard.state(provider_id) + { + return state.clone(); } return crate::MarketPriceProviderState::new(provider_id.clone(), availability); } diff --git a/crates/ksp-offchain-transport-lib/tests/dependency_boundary.rs b/crates/ksp-offchain-transport-lib/tests/dependency_boundary.rs index 837a9be..f28987b 100644 --- a/crates/ksp-offchain-transport-lib/tests/dependency_boundary.rs +++ b/crates/ksp-offchain-transport-lib/tests/dependency_boundary.rs @@ -1,5 +1,5 @@ // file: crates/ksp-offchain-transport-lib/tests/dependency_boundary.rs -// version: 9 +// version: 10 #![warn(missing_docs)] #![deny(unreachable_pub)] @@ -123,5 +123,6 @@ fn pre_008_refresh_service_owns_dispatch_while_registry_and_consumer_surface_sta assert!(!service.contains("std::thread::sleep")); assert!(!service.contains("tokio::time::sleep")); assert!(!service.contains("fallback_provider")); - assert!(!service.contains("consensus")); + assert!(!service.contains("fn aggregate(")); + assert!(!service.contains("fn consensus(")); } diff --git a/deltas/0.2.11/pre.008-fix.001.md b/deltas/0.2.11/pre.008-fix.001.md new file mode 100644 index 0000000..7dcdd03 --- /dev/null +++ b/deltas/0.2.11/pre.008-fix.001.md @@ -0,0 +1,126 @@ + + + +# Delta `0.2.11-pre.008-fix.001` — Clippy et canari boundary du service de refresh + +## 1. Base requise + +Ce correctif s'applique exclusivement après `0.2.11-pre.008`. + +Version Cargo attendue à l'entrée : + +```text +0.2.11-pre.8 +``` + +Version Cargo de sortie : + +```text +0.2.11-pre.8.fix.1 +``` + +## 2. Motif du correctif + +Le gate opérateur du `2026-08-26` a produit : + +```text +cargo fmt --all exécuté +audit Rust workspace PASS +audit Markdown PASS, 122 tables / 113 files +cargo check --workspace PASS +cargo clippy --workspace --all-targets 1 warning collapsible_if +cargo test -p ksp-offchain-transport-lib 54 unit PASS, dependency boundary FAIL +``` + +Le canari en échec était : + +```text +pre_008_refresh_service_owns_dispatch_while_registry_and_consumer_surface_stay_generic +``` + +Il utilisait une interdiction lexicale trop large : + +```text +!service.contains("consensus") +``` + +alors que `market_price_service.rs` contient légitimement une rustdoc indiquant que `refresh_many` fonctionne « without fallback or consensus ». + +## 3. Correction Clippy + +`MarketPriceService::update_availability` collapse les deux `if` imbriqués en une `let`-chain conforme à `clippy::collapsible_if`. + +Le comportement ne change pas : + +```text +set_availability réussi + état retrouvé -> clone de l'état registry +sinon -> projection de secours avec la même availability +``` + +Aucune transition d'availability, classification d'erreur, cadence ou logique réseau n'est modifiée. + +## 4. Correction du canari boundary + +Le test ne bannit plus le mot documentaire `consensus`. + +Il vérifie désormais l'absence de surfaces exécutables concrètes hors scope : + +```text +fallback_provider +fn aggregate( +fn consensus( +``` + +Les rustdocs peuvent donc documenter explicitement l'absence de fallback/consensus sans faire échouer le canari, tandis qu'une implémentation réelle de ces mécanismes resterait détectée. + +Les assertions existantes sur l'absence de `std::thread::sleep` et `tokio::time::sleep` sont conservées. + +## 5. Scope fonctionnel inchangé + +Ce fix ne modifie pas : + +```text +les huit adapters V1 +MarketPriceProviderSetup +MarketPriceService public +refresh / refresh_many / refresh_all +registry et availability +rate limits / cooldowns +classification HTTP/provider +Config +scheduler périodique +fallback +consensus +agrégation multi-provider +smoke live +``` + +## 6. Fichiers modifiés + +```text +Cargo.toml +crates/ksp-offchain-transport-lib/src/market_price_service.rs +crates/ksp-offchain-transport-lib/tests/dependency_boundary.rs +docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md +docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md +``` + +## 7. Fichier ajouté + +```text +deltas/0.2.11/pre.008-fix.001.md +``` + +## 8. Gate opérateur requis + +```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 --workspace +``` + +`pre.009` ne doit commencer qu'après ce gate propre. diff --git a/docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md b/docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md index 221ade6..66ac43d 100644 --- a/docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md +++ b/docs/plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md @@ -1,9 +1,9 @@ - + # Plan `0.2.11` — Off-chain price transport SOL/USD multi-provider -**Statut courant : `0.2.11-pre.008` matérialise le service générique de refresh SOL/USD au-dessus des huit adapters V1. `MarketPriceService` possède le dispatch provider, le registry runtime et les transitions d'availability ; les consumers utilisent uniquement les provider ids opaques, `registry()`, `refresh`, `refresh_many` et `refresh_all`. Les limites/cooldowns restent non bloquants et aucun fallback, consensus ou scheduler provider n'est introduit. `MarketPriceProviderSetup` reste la frontière provider-specific destinée à la composition/Config de `pre.009`. Le gate opérateur complet de `pre.007` est PASS, y compris `cargo test --workspace`.** +**Statut courant : `0.2.11-pre.008-fix.001` corrige le gate de `pre.008` sans modifier son contrat fonctionnel. `MarketPriceService` possède toujours le dispatch provider, le registry runtime et les transitions d'availability ; les consumers utilisent uniquement les provider ids opaques, `registry()`, `refresh`, `refresh_many` et `refresh_all`. Le fix supprime un warning Clippy `collapsible_if` et remplace un canari lexical trop large sur le mot `consensus` par des vérifications de surfaces exécutables réellement interdites. `MarketPriceProviderSetup` reste la frontière provider-specific destinée à la composition/Config de `pre.009`.** ## 1. Base et autorité @@ -746,10 +746,12 @@ Implémentation de Birdeye Standard avec `X-API-KEY`, endpoint Price Single Sola ### `pre.008` — Refresh individuel et multiple -**Statut : réalisé, gate Cargo opérateur à exécuter.** +**Statut : réalisé ; `pre.008-fix.001` corrige le gate opérateur Clippy/boundary sans changement fonctionnel.** `MarketPriceService` possède les huit adapters configurés, le registry runtime et le dispatch provider-specific interne. La construction accepte `MarketPriceProviderSetup` pour la future couche de composition, puis l'usage devient intégralement provider-agnostic via `registry()`, `refresh(provider_id)`, `refresh_many(...)` et `refresh_all()`. Les échecs provider sont classés en availability générique ; un résultat en erreur n'interrompt pas les autres providers d'un batch. Les états non éligibles sont projetés sans requête réseau, les cooldowns expirés redeviennent tentables, et aucune opération ne dort pour attendre un rate limit. Aucun fallback, consensus, agrégation, Config ou scheduling périodique n'est avancé. +`pre.008-fix.001` conserve ce contrat. Il collapse uniquement un `if` signalé par Clippy et rend le canari de boundary précis : les rustdocs peuvent mentionner explicitement l'absence de consensus, tandis que le test interdit les fonctions exécutables `aggregate`/`consensus` et le chemin `fallback_provider`. + ### `pre.009` — Config Off-chain Transport **Statut : planifié.** diff --git a/docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md b/docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md index 63da910..972cef7 100644 --- a/docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md +++ b/docs/validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md @@ -1,5 +1,5 @@ - + # Validation `0.2.11` — Off-chain price transport SOL/USD @@ -280,9 +280,11 @@ Les tests déterministes de `pre.007` couvrent l'auth Birdeye et sa redaction, l | 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 Cargo | PLANNED | à exécuter par l'opérateur | +| 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 | PLANNED | à exécuter par l'opérateur | -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. +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. ## 4. Matrice provider prévue