v0.2.12-pre.009
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/019-V0_2_12_SOL_PRICES_DESK_PLAN.md -->
|
||||
<!-- version: 17 -->
|
||||
<!-- version: 18 -->
|
||||
|
||||
# Plan `0.2.12` — SOL Prices Desk + intégration prix Wallet Desk
|
||||
|
||||
@@ -250,9 +250,12 @@ Le périmètre Wallet Desk est volontairement réduit après validation complèt
|
||||
Wallet Desk existing shell
|
||||
-> Dashboard / Wallet courant
|
||||
-> Balance SOL existante
|
||||
-> une seule case “SOL/USD moyen”
|
||||
-> “SOL/USD moyen”
|
||||
-> valeur moyenne dérivée du refresh courant
|
||||
-> N.A. si aucune observation exploitable
|
||||
-> “Équivalent USD”
|
||||
-> balance SOL × moyenne du refresh courant, calcul exact côté Rust
|
||||
-> N.A. si le prix auxiliaire est indisponible
|
||||
-> bouton Refresh balance existant
|
||||
-> getBalance On-chain
|
||||
-> refresh_all Off-chain des providers éligibles
|
||||
@@ -262,7 +265,7 @@ Wallet Desk existing shell
|
||||
|
||||
Aucun inventaire provider, aucune availability détaillée et aucun bouton prix supplémentaire ne sont dupliqués dans Wallet Desk. Les fonctions avancées restent la responsabilité de `ksp-app-solprices-desk`. Le prix auxiliaire suit le lifecycle du refresh de balance existant et n'ajoute aucun nouveau droit VIEW/OWNER.
|
||||
|
||||
**Valorisation USD du solde : toujours hors scope `0.2.12`.** La moyenne est seulement affichée comme information SOL/USD ; aucun calcul `balance SOL × prix` n'est introduit.
|
||||
**Équivalent USD retenu par décision opérateur.** Il reste une projection auxiliaire strictement dérivée du refresh courant : calcul côté Rust sans `f64`, aucun prix canonique/fallback et aucune dépendance supplémentaire du frontend aux providers.
|
||||
|
||||
## 9. DTO map retenue
|
||||
|
||||
@@ -342,8 +345,8 @@ refresh_wallet_balance
|
||||
-> en parallèle : MarketPriceService::refresh_all
|
||||
-> ne garder que les observations réussies du refresh courant
|
||||
-> moyenne arithmétique backend sans f64, arrondie à 8 décimales maximum
|
||||
-> WalletBalanceDto { ..., sol_usd_average: Option<String> }
|
||||
-> une seule case UI “SOL/USD moyen” ou “N.A.”
|
||||
-> WalletBalanceDto { ..., sol_usd_average: Option<String>, sol_usd_equivalent: Option<String> }
|
||||
-> UI compacte “SOL/USD moyen” + “Équivalent USD”, ou “N.A.”
|
||||
```
|
||||
|
||||
La branche prix est **auxiliaire/best-effort** : un runtime Off-chain indisponible, zéro observation ou un échec structurel prix ne rend pas `getBalance` invalide. La balance SOL reste autoritative et la projection prix devient `None`.
|
||||
@@ -444,7 +447,7 @@ Canari obligatoire : `ksp-app-solprices-desk` référence son propre `package.js
|
||||
| TS-RS | bindings exportés par tests; prix exact en String |
|
||||
| workspace | fmt + audits + check + clippy + test |
|
||||
| SOL Prices Desk dev | parcours splash -> table -> row/many/all sur composition réelle |
|
||||
| Wallet Desk dev | refresh balance + une case moyenne SOL/USD/N.A. + non-régression Wallet |
|
||||
| Wallet Desk dev | refresh balance + moyenne SOL/USD + équivalent USD/N.A. + non-régression Wallet |
|
||||
| live composition | un smoke keyless applicatif opt-in suffit; ne réaudite pas les 8 wires |
|
||||
| production build | `cargo tauri build` crate-local pour SOL Prices Desk puis Wallet Desk |
|
||||
|
||||
@@ -459,7 +462,7 @@ OHLCV/historique/chart
|
||||
SSE/WebSocket prix
|
||||
consensus/fallback automatique
|
||||
provider canonique
|
||||
valorisation USD du solde Wallet
|
||||
panneau providers détaillé ou commandes prix dédiées dans Wallet Desk
|
||||
auto-refresh/polling périodique
|
||||
Store/worker/job prix
|
||||
éditeur Config dans Price Desk
|
||||
@@ -555,7 +558,7 @@ Finalisation de la table responsive sans changer le contrat de dispatch : résum
|
||||
|
||||
### `pre.008` — Intégration Wallet minimale + recalibrage de clôture
|
||||
|
||||
**Statut : réalisé ; corrigé par `pre.008-fix.001`, `pre.008-fix.002` puis `pre.008-fix.003`, gate opérateur final à confirmer.**
|
||||
**Statut : réalisé ; corrigé par `pre.008-fix.001`, `pre.008-fix.002` puis `pre.008-fix.003`, gate opérateur final PASS.**
|
||||
|
||||
Absorption de l'ancien couloir Wallet `pre.009`–`pre.011` dans une seule tranche : ajout `offchain_transport/public_keyless` au composite Wallet, runtime Off-chain auxiliaire, `refresh_all` lors de `refresh_wallet_balance`, moyenne SOL/USD backend sans `f64` et projection compacte dans Wallet Desk. La correction `fix.002` complète le besoin opérateur réellement attendu : `WalletBalanceDto` expose également un équivalent USD exact calculé côté Rust à partir des lamports et de la moyenne du refresh courant ; Dashboard et Details affichent le prix moyen et l'équivalent ou `N.A.`. Aucun panneau provider, aucune command prix Wallet et aucun provider ID frontend ne sont ajoutés. La tranche réconcilie également le forecast avec cette réduction de scope.
|
||||
|
||||
@@ -573,15 +576,15 @@ Correction du dernier écart fonctionnel de la tranche : le refresh produisait b
|
||||
|
||||
#### `pre.008-fix.003` — Correction du littéral de canari version dynamique
|
||||
|
||||
**Statut : implémenté ; gate opérateur à confirmer.**
|
||||
**Statut : réalisé ; gate opérateur Cargo/workspace intégralement PASS.**
|
||||
|
||||
Le gate de `pre.008-fix.002` confirme le fonctionnement runtime et visuel attendu : Dashboard et Details affichent la moyenne SOL/USD, l'équivalent USD et la version `0.2.12-pre.8.fix.2`. `cargo fmt`, les audits KSP et `cargo check --workspace` passent. Clippy `--all-targets` s'arrête uniquement sur le canari `desktop_contract.rs` : la raw string `r#"..."#` se ferme prématurément sur le fragment `"#appVersionBadge"`. Le fix remplace cette assertion par une chaîne Rust standard correctement échappée, sans modifier le runtime, le frontend ou le calcul prix.
|
||||
|
||||
### `pre.009` — Hardening transversal + gate technique/live final
|
||||
|
||||
**Statut : planifié.**
|
||||
**Statut : implémenté ; gate opérateur live/build à confirmer.**
|
||||
|
||||
Fusion des anciens hardenings `pre.008`/`pre.012` et du gate `pre.013` : canaris batch hostile/capabilities/resources, non-régression des deux Desks, workspace complet, smoke live keyless de composition, et `cargo tauri build` final des deux applications modifiées. Aucun nouveau comportement métier n'est ouvert.
|
||||
Fusion des anciens hardenings `pre.008`/`pre.012` et du gate `pre.013` : la sélection batch Price Desk est bornée à `1..=64` avant parsing des IDs opaques, les canaris capabilities/resources/CWD/version/package et provider-neutralité Wallet sont renforcés, et un smoke live opt-in prouve le chemin composite SOL Prices Desk -> Config -> `MarketPriceService::refresh_all` avec au moins une observation keyless. Les métadonnées npm/Tauri des deux Desks modifiés sont synchronisées avec `0.2.12-pre.9` pour les builds de production finaux. Aucun nouveau comportement métier n'est ouvert ; les seuls gates restant opérateur sont le workspace complet, le smoke live et les deux `cargo tauri build` crate-local.
|
||||
|
||||
### `pre.010` — Réconciliation documentaire + préparation de publication
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/015-V0_2_12_SOL_PRICES_DESK.md -->
|
||||
<!-- version: 16 -->
|
||||
<!-- version: 17 -->
|
||||
|
||||
# Validation `0.2.12` — SOL Prices Desk + intégration Wallet Desk
|
||||
|
||||
@@ -39,8 +39,8 @@ NOT RUN commande non exécutée dans le contexte indiqué
|
||||
| threat model desktop | PASS | plan 019 section 16 |
|
||||
| Wallet integration map | PASS | plan 019 section 12 |
|
||||
| auto-refresh | OUT | hors scope confirmé |
|
||||
| valorisation USD du solde | OUT | aucun prix canonique; hors scope confirmé |
|
||||
| forecast souple recalibré | PASS | 15 prereleases + rel; plan 019 section 19 |
|
||||
| équivalent USD du solde | PASS | demandé opérateur; calcul backend exact depuis moyenne du refresh |
|
||||
| forecast souple recalibré | PASS | clôture condensée jusqu’à `pre.010` + `rel.001` |
|
||||
| scope clôturable | PASS | pas de redécoupage requis avant `pre.002` |
|
||||
| code/scaffold fonctionnel ajouté en `pre.001` | OUT | interdit par le gate |
|
||||
|
||||
@@ -58,9 +58,9 @@ NOT RUN commande non exécutée dans le contexte indiqué
|
||||
| refresh selected/many | `MarketPriceService::refresh_many` | PASS |
|
||||
| refresh all | `MarketPriceService::refresh_all` | PASS |
|
||||
| Diagnostics | profils/counts sûrs seulement | PASS |
|
||||
| Wallet prix moyen | une case `SOL/USD moyen` / `N.A.` | PASS |
|
||||
| Wallet prix moyen | `SOL/USD moyen` / `N.A.` | PASS |
|
||||
| auto-refresh | aucun scheduler/polling | OUT |
|
||||
| Wallet USD valuation | aucune multiplication balance × prix | OUT |
|
||||
| Wallet équivalent USD | calcul Rust exact / `N.A.` | PASS |
|
||||
|
||||
## 4. DTO/command matrix
|
||||
|
||||
@@ -69,7 +69,7 @@ NOT RUN commande non exécutée dans le contexte indiqué
|
||||
| `MarketPriceRuntimeStatusDto` | profiles/counts sans secret | PASS |
|
||||
| `MarketPriceProviderRowDto` | ID/display/pair/semantics/auth/availability/price/timestamps/retry | PASS |
|
||||
| single refresh direct | provider_id opaque seulement | PASS |
|
||||
| `MarketPriceRefreshManyRequestDto` | liste d’IDs opaques ; borne hostile à durcir en `pre.009` | PASS |
|
||||
| `MarketPriceRefreshManyRequestDto` | liste d’IDs opaques ; garde app `1..=64` avant parsing | PASS |
|
||||
| `MarketPriceRefreshResultDto` | rows/outcome classifiés | PASS |
|
||||
| runtime/list/refresh/many/all commands | aucun URL/header/API key/body | PASS |
|
||||
| TS-RS exports | bindings générés non versionnés | PASS |
|
||||
@@ -78,20 +78,20 @@ NOT RUN commande non exécutée dans le contexte indiqué
|
||||
|
||||
## 5. Config/composite matrix
|
||||
|
||||
| Contrat | Valeur attendue | Statut |
|
||||
|---------------------------------------|--------------------------------------------------------------|---------|
|
||||
| Price Desk composite file | `config/composite.ksp-app-solprices-desk.json` | PASS |
|
||||
| Price Desk file_id | `cfg.composite.ksp-app-solprices-desk` | PASS |
|
||||
| schema | `schema.composite` existant | PASS |
|
||||
| components | `logging`, `offchain_transport` | PASS |
|
||||
| default profile | `public_keyless` | PASS |
|
||||
| optional profile | `all_free` | PASS |
|
||||
| test profile | `tests` -> offchain `public_keyless` | PASS |
|
||||
| Wallet composite | ajoute offchain `public_keyless` à devnet/temporary/tests | PENDING |
|
||||
| registry/resource count | 11 après nouveau composite | PASS |
|
||||
| registry + resources atomiques | Config + Config Desk + Wallet Desk + Price Desk même tranche | PASS |
|
||||
| nouveau schema Config | inutile | OUT |
|
||||
| modification `std.offchain_transport` | pas de lacune identifiée | OUT |
|
||||
| Contrat | Valeur attendue | Statut |
|
||||
|---------------------------------------|--------------------------------------------------------------|--------|
|
||||
| Price Desk composite file | `config/composite.ksp-app-solprices-desk.json` | PASS |
|
||||
| Price Desk file_id | `cfg.composite.ksp-app-solprices-desk` | PASS |
|
||||
| schema | `schema.composite` existant | PASS |
|
||||
| components | `logging`, `offchain_transport` | PASS |
|
||||
| default profile | `public_keyless` | PASS |
|
||||
| optional profile | `all_free` | PASS |
|
||||
| test profile | `tests` -> offchain `public_keyless` | PASS |
|
||||
| Wallet composite | ajoute offchain `public_keyless` à devnet/temporary/tests | PASS |
|
||||
| registry/resource count | 11 après nouveau composite | PASS |
|
||||
| registry + resources atomiques | Config + Config Desk + Wallet Desk + Price Desk même tranche | PASS |
|
||||
| nouveau schema Config | inutile | OUT |
|
||||
| modification `std.offchain_transport` | pas de lacune identifiée | OUT |
|
||||
|
||||
## 6. Provider-agnostic boundary matrix
|
||||
|
||||
@@ -109,22 +109,22 @@ NOT RUN commande non exécutée dans le contexte indiqué
|
||||
|
||||
## 7. Security matrix
|
||||
|
||||
| Risque/canari | Attendu | Statut |
|
||||
|--------------------------------|-------------------------------------------------|---------|
|
||||
| URL arbitraire depuis frontend | impossible par contrat command | PASS |
|
||||
| extraction API key/header | aucune projection/log | PASS |
|
||||
| provider_id inconnu | erreur KSP sûre | PASS |
|
||||
| batch duplicate | rejet avant dispatch | PASS |
|
||||
| batch oversized | borne hostile applicative à durcir en `pre.009` | PENDING |
|
||||
| refresh spam | limites/cooldown Off-chain toujours actifs | PASS |
|
||||
| stale observation | timestamps/état distingués | PASS |
|
||||
| double-click race | in-flight/order contrôlés | PASS |
|
||||
| close pendant refresh | aucune persistance/sûreté frontend requise | PENDING |
|
||||
| CWD/resource confusion | canaris propres à chaque app | PENDING |
|
||||
| Price Desk capabilities | `core:default`, `tracing:default` uniquement | PASS |
|
||||
| plugin dialog Price Desk | absent | PASS |
|
||||
| frontend sensitive logging | action/ID/count/code seulement | PASS |
|
||||
| Wallet VIEW/OWNER/secrets | non-régression | PENDING |
|
||||
| Risque/canari | Attendu | Statut |
|
||||
|--------------------------------|-------------------------------------------------------|--------|
|
||||
| URL arbitraire depuis frontend | impossible par contrat command | PASS |
|
||||
| extraction API key/header | aucune projection/log | PASS |
|
||||
| provider_id inconnu | erreur KSP sûre | PASS |
|
||||
| batch duplicate | rejet avant dispatch | PASS |
|
||||
| batch oversized | garde app `1..=64` avant parsing/dispatch | PASS |
|
||||
| refresh spam | limites/cooldown Off-chain toujours actifs | PASS |
|
||||
| stale observation | timestamps/état distingués | PASS |
|
||||
| double-click race | in-flight/order contrôlés | PASS |
|
||||
| close pendant refresh | état uniquement mémoire ; aucune persistance frontend | PASS |
|
||||
| CWD/resource confusion | frontendDist/cwd/ports/resources canarisés par app | PASS |
|
||||
| Price Desk capabilities | `core:default`, `tracing:default` uniquement | PASS |
|
||||
| plugin dialog Price Desk | absent | PASS |
|
||||
| frontend sensitive logging | action/ID/count/code seulement | PASS |
|
||||
| Wallet VIEW/OWNER/secrets | suite Wallet + compliance inchangées | PASS |
|
||||
|
||||
## 8. Wallet integration matrix
|
||||
|
||||
@@ -134,16 +134,16 @@ NOT RUN commande non exécutée dans le contexte indiqué
|
||||
| Config component | Wallet composite -> `cfg.std.offchain_transport/public_keyless` | PASS |
|
||||
| runtime | Config -> `ResolvedOffchainTransportConfig` -> `MarketPriceService` | PASS |
|
||||
| command | `refresh_wallet_balance` existante, aucun input prix/provider | PASS |
|
||||
| DTO | `WalletBalanceDto.sol_usd_average: Option<String>` | PASS |
|
||||
| DTO | moyenne + équivalent USD en `Option<String>` exacts | PASS |
|
||||
| moyenne | observations réussies du refresh courant, backend sans `f64`, 8 déc. max | PASS |
|
||||
| UI | une seule case `SOL/USD moyen` / `N.A.` | PASS |
|
||||
| UI | résumé compact `SOL/USD moyen` + `Équivalent USD` / `N.A.` | PASS |
|
||||
| balance HTTP On-chain | `getBalance` inchangé et toujours autoritatif | PASS |
|
||||
| dégradation prix | échec/absence prix -> `N.A.` sans faire échouer la balance | PASS |
|
||||
| WalletSession VIEW/OWNER | inchangée | PASS |
|
||||
| Wallet secret projections | aucune nouvelle | PASS |
|
||||
| provider ID frontend | aucun | PASS |
|
||||
| command prix Wallet | aucune | PASS |
|
||||
| USD balance multiplication | hors scope | OUT |
|
||||
| USD balance multiplication | calcul Rust exact depuis lamports + moyenne du refresh courant | PASS |
|
||||
|
||||
## 9. Tauri/package matrix
|
||||
|
||||
@@ -158,6 +158,7 @@ NOT RUN commande non exécutée dans le contexte indiqué
|
||||
| backend cross-app | aucune référence Wallet par erreur | PASS |
|
||||
| resources | registry complet packagé | PASS |
|
||||
| bundle | targets/icons cohérents | PASS |
|
||||
| versions apps modifiées | npm/Tauri = Cargo `0.2.12-pre.9` | PASS |
|
||||
| Tauri production build Price Desk | crate-local PASS attendu | PENDING |
|
||||
| Tauri production build Wallet Desk | crate-local PASS attendu | PENDING |
|
||||
|
||||
@@ -171,8 +172,8 @@ NOT RUN commande non exécutée dans le contexte indiqué
|
||||
| `cargo check --workspace` | PENDING |
|
||||
| `cargo clippy --workspace --all-targets` | PENDING |
|
||||
| `cargo test --workspace` | PENDING |
|
||||
| Price Desk functional dev path | PENDING |
|
||||
| Wallet Desk functional price path | PENDING |
|
||||
| Price Desk functional dev path | PASS |
|
||||
| Wallet Desk functional price path | PASS |
|
||||
| keyless app-composition live smoke | PENDING |
|
||||
| Price Desk `cargo tauri build` | PENDING |
|
||||
| Wallet Desk `cargo tauri build` | PENDING |
|
||||
@@ -726,3 +727,70 @@ cargo test -p ksp-app-wallet-desk
|
||||
cargo test --workspace
|
||||
```
|
||||
|
||||
## 28. Gate `0.2.12-pre.009` — hardening transversal et gate final
|
||||
|
||||
Le gate opérateur de `pre.008-fix.003` ferme définitivement la tranche Wallet condensée :
|
||||
|
||||
```text
|
||||
cargo fmt --all PASS
|
||||
python3 scripts/audit_rust_workspace_rules.py PASS
|
||||
python3 scripts/audit_markdown_tables.py README.md ... deltas PASS
|
||||
cargo check --workspace PASS
|
||||
cargo clippy --workspace --all-targets PASS
|
||||
cargo test -p ksp-app-wallet-desk PASS
|
||||
cargo test --workspace PASS
|
||||
```
|
||||
|
||||
Le parcours fonctionnel avait déjà confirmé sous `fix.002` puis `fix.003` la moyenne SOL/USD, l'équivalent USD, la version dynamique et le refresh balance réel.
|
||||
|
||||
`pre.009` ajoute les hardenings finaux suivants sans ouvrir de nouvelle fonctionnalité :
|
||||
|
||||
```text
|
||||
Price Desk batch IPC garde 1..=64 avant parsing des provider IDs
|
||||
batch vide rejet KSP sûr
|
||||
batch hostile 65 IDs rejet KSP sûr avant parsing provider
|
||||
Price Desk manual refresh aucun scheduler/fetch/browser persistence
|
||||
Price Desk package metadata npm/Tauri == CARGO_PKG_VERSION
|
||||
Wallet package metadata npm/Tauri == CARGO_PKG_VERSION
|
||||
Wallet frontendDist chemin Wallet dédié canarisé
|
||||
Wallet provider-neutrality aucun type provider concret dans src/
|
||||
Wallet exactness aucun f64/f32 backend, aucun calcul flottant frontend
|
||||
keyless live composition nouveau smoke opt-in SOL Prices Desk
|
||||
```
|
||||
|
||||
Le smoke live dédié est :
|
||||
|
||||
```bash
|
||||
cargo test -p ksp-app-solprices-desk --test market_price_composition_live_smoke -- --ignored --nocapture
|
||||
```
|
||||
|
||||
Validations sandbox après matérialisation de la tranche :
|
||||
|
||||
```text
|
||||
python3 scripts/audit_rust_workspace_rules.py PASS
|
||||
python3 scripts/audit_markdown_tables.py README.md ... deltas PASS
|
||||
JSON package/tauri des deux apps modifiées PASS
|
||||
contrôles statiques versions/resources/frontières PASS
|
||||
cargo fmt/check/clippy/test/live/tauri build NOT RUN — cargo indisponible
|
||||
```
|
||||
|
||||
Il doit résoudre le composite committed `public_keyless`, mapper `ResolvedOffchainTransportConfig`, conserver exactement les huit entrées génériques du registry, exécuter `MarketPriceService::refresh_all` et obtenir au moins une observation SOL/USD. Il ne réaudite pas les huit wire adapters individuellement.
|
||||
|
||||
Gate opérateur final à exécuter, dans cet ordre :
|
||||
|
||||
```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.12
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
cargo test -p ksp-app-solprices-desk
|
||||
cargo test -p ksp-app-wallet-desk
|
||||
cargo test --workspace
|
||||
cargo test -p ksp-app-solprices-desk --test market_price_composition_live_smoke -- --ignored --nocapture
|
||||
(cd crates/ksp-app-solprices-desk && cargo tauri build)
|
||||
(cd crates/ksp-app-wallet-desk && cargo tauri build)
|
||||
```
|
||||
|
||||
Conformément à `KSP-APP-034`, les deux `cargo tauri build` restent les dernières opérations lourdes.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user