Files
khadhroony-solana-project/docs/plans/019-V0_2_12_SOL_PRICES_DESK_PLAN.md

39 KiB
Raw Blame History

Plan 0.2.12 — SOL Prices Desk + intégration prix Wallet Desk

1. Base et autorité

La release est ouverte exclusivement depuis l'archive opérateur stable v0.2.11 fournie au démarrage de session. L'archive ne contient pas de metadata .git; le tag ne peut donc pas être revérifié localement par git describe. Les marqueurs internes sont cohérents : workspace.package.version = 0.2.11, deltas/0.2.11/rel.001.md et prompts/017-V0_2_12_START_PROMPT.md sont présents.

Le log opérateur fourni avec la base exécute sur le checkout stable v0.2.11 :

cargo fmt --all                                               PASS
python3 scripts/audit_rust_workspace_rules.py                 PASS
python3 scripts/audit_markdown_tables.py ... deltas/0.2.11   PASS
cargo check --workspace                                       PASS
cargo clippy --workspace --all-targets                        PASS
cargo test --workspace                                        PASS

Dans le sandbox de préparation, cargo n'est pas disponible. Les deux audits Python ont néanmoins été rejoués sur l'archive extraite et sont propres. Aucune commande Cargo non exécutée dans ce sandbox n'est déclarée localement PASS; le gate Cargo de base repose sur la preuve opérateur fournie pour le même état stable.

0.2.12-pre.001 est une tranche documentaire d'audit/sizing. Elle ne crée ni crate Tauri, ni Config runtime nouveau, ni commande prix, ni code frontend fonctionnel.

2. Mission et frontières

Mission concrète de la release :

1. créer ksp-app-solprices-desk comme HID Tauri provider-agnostic
2. valider son contrat Config + MarketPriceService + DTO/commands + UI
3. intégrer ensuite la même capacité générique dans ksp-app-wallet-desk

Ownership durable :

ksp-offchain-transport-lib  providers, wire REST, endpoints, normalisation, rate limits, cooldowns, dispatch
ksp-config-lib              documents, profils, composite, env, secrets, construction MarketPriceService
apps Tauri                  composition, état de présentation courant, IPC, UI, instrumentation
frontend                    projection/interaction uniquement; aucun réseau provider ni secret

La release ne crée ni ksp-offchain-transport-api, ni crate UI partagée spéculative, ni provider supplémentaire.

3. Audit de la surface stable Off-chain Transport

La façade publique 0.2.11 suffit au besoin HID. Le nouveau desk n'a pas besoin d'accéder aux adapters concrets.

Contrat stable Usage 0.2.12 Décision
MarketPriceService::registry inventaire détaché provider-neutral consommer directement
MarketPriceService::refresh refresh dun provider_id opaque consommer directement
MarketPriceService::refresh_many batch borné, validation avant dispatch, ordre déterministe consommer directement
MarketPriceService::refresh_all refresh de linventaire dans lordre stable consommer directement
MarketPriceProviderRegistry / Entry descriptor + état génériques source unique des lignes
MarketPriceProviderDescriptor display name, semantics, auth, limites génériques projection bornée; pas de wire
MarketPriceProviderAvailability Ready/Disabled/CoolingDown/etc. + retry_at projection UI sans scheduler
MarketPriceObservation prix exact + timestamps + provenance + semantics projection sûre
MarketPriceDecimal vérité décimale exacte DTO frontend en chaîne, jamais f64
MarketPriceProviderId identifiant opaque borné seul identifiant accepté par les commands

Constats structurants :

  • le service ne constitue pas un cache historique ;
  • refresh_many rejette les doublons et IDs inconnus avant dispatch ;
  • refresh_many/all V1 est volontairement séquentiel et ne dort pas pour attendre un provider ;
  • disponibilité, cooldown et retry provider sont déjà possédés par Off-chain Transport ;
  • les erreurs provider sont normalisées sans recopier de body distant dans les diagnostics sûrs ;
  • huit setups concrets existent côté composition, mais ils ne doivent jamais apparaître dans le code applicatif par branche provider.

Verdict : aucune modification de ksp-offchain-transport-lib n'est nécessaire pour ouvrir la HID.

4. Audit Config et composition

ResolvedOffchainTransportConfig transporte déjà la sélection Config résolue, la provenance sûre et un MarketPriceService. ConfigDocumentEngine expose les chemins load_resolved_offchain_transport_config et resolve_offchain_transport_config_profile; l'application n'a donc pas à reconstruire les setups providers.

La base stable possède :

cfg.std.offchain_transport
schema.std.offchain_transport
format_version = 1
default profile = public_keyless
explicit profile = all_free
schema.composite générique
cfg.composite.ksp-app-wallet-desk

4.1 Composite SOL Prices Desk retenu

Créer pendant pre.003 :

filename      config/composite.ksp-app-solprices-desk.json
file_id       cfg.composite.ksp-app-solprices-desk
schema        schema.composite existant
component_id  logging
component_id  offchain_transport

Profils retenus :

Composite profile Logging Off-chain Transport Rôle
public_keyless (default) console_info public_keyless démarrage sans credential et profil de référence stable
all_free console_info all_free opt-in Config; credentials résolus exclusivement par Config
tests console_info public_keyless tests déterministes sans secrets

console_info est retenu pour les profils de référence afin de ne pas créer en 0.2.12 une dépendance artificielle à des filtres/fichiers de logging spécialisés. L'instrumentation trace reste présente dans le code frontend/Rust conformément aux règles KSP, même si ce profil stable ne l'affiche pas par défaut.

Aucun nouveau schema composite n'est nécessaire.

4.2 Extension Wallet Desk retenue

Chaque profil du composite Wallet Desk (devnet, temporary, tests) recevra :

component_id = offchain_transport
file_id      = cfg.std.offchain_transport
profile_id   = public_keyless

Le défaut Wallet reste donc keyless et ne gagne aucune exigence de secret. all_free n'est pas injecté arbitrairement dans Wallet Desk.

4.3 Contrainte atomique registry/packaging

prepare_packaged_runtime parcourt tous les descriptors de ConfigFileRegistry::defaults(). L'ajout du composite SOL Prices Desk augmente donc l'inventaire de ressources packagées de 10 à 11.

La tranche qui ajoute le descriptor doit synchroniser dans le même delta :

Config registry
nouveau document composite
Config unit/public tests
resources Tauri ksp-app-config-desk
resources Tauri ksp-app-wallet-desk
resources Tauri ksp-app-solprices-desk
tests desktop/package qui comptent ou valident les resources

Il ne faut pas publier un état intermédiaire dans lequel le registry exige le nouveau composite mais un Desk packagé ne l'embarque pas.

5. Audit des gabarits desktop stables

La base confirme :

Surface Config Desk Wallet Desk Décision SOL Prices Desk
ports Vite/HMR 1430 / 1431 1432 / 1433 1434 / 1435
Rust package lib + bin lib + bin lib + bin
windows splash + main splash + main splash + main
commands centralisés tauri.rs centralisés tauri.rs même pattern
window modules tw_splash, tw_main tw_splash, tw_main même pattern
frontendDist hors source sous builds/... hors source sous builds/... même pattern dédié
Vite strictPort + HMR dédié strictPort + HMR dédié strictPort 1434 + HMR 1435
capabilities core + tracing core + tracing core + tracing seulement
dialog plugin absent Rust-side pour import/export Wallet absent
browser network aucun fetch direct attendu aucun fetch direct attendu interdit
Config resources 10 resources registry 10 resources registry 11 après nouveau composite

Le nouveau desk doit avoir ses propres productName, identifier, chemins frontendDist, hooks NPM et backend Rust. Un canari doit empêcher une copie erronée qui lancerait Vite ou le backend Wallet Desk.

Les versions package.json/tauri.conf.json des deux Desks historiques sont encore 0.2.6 alors que leurs crates héritent de la version workspace 0.2.11. Les tests stables imposent seulement un plancher >= 0.2.6. Cette release ne lancera pas une harmonisation globale de versions d'apps historiques par principe. Le nouveau package SOL Prices Desk utilisera la version de release 0.2.12-pre.*/0.2.12 selon le mécanisme retenu dans son scaffold, et toute modification du package Wallet sera auditée pour cohérence sans élargir la release à Config Desk.

6. Audit externe desktop du 2026-08-26

Sources officielles réauditées :

https://v2.tauri.app/reference/config/
https://v2.tauri.app/security/
https://v2.tauri.app/security/capabilities/
https://v2.tauri.app/reference/acl/core-permissions/
https://github.com/tauri-apps/tauri/releases
https://github.com/Aleph-Alpha/ts-rs
https://github.com/Aleph-Alpha/ts-rs/releases

Constats :

  • Tauri documente toujours beforeDevCommand, beforeBuildCommand, devUrl et frontendDist dans tauri.conf.json ; le pattern KSP actuel reste aligné ;
  • les capabilities restent la frontière d'autorisation du WebView vers les commandes/plugin permissions ; core:default est toujours un permission set officiel ;
  • la release Tauri courante observée est 2.11.5, cohérente avec la contrainte workspace tauri = ^2.11 ;
  • TS-RS publie 12.0.0 comme release courante et recommande ts-rs = "12.0", cohérent avec ts-rs = ^12.0 déjà présent ;
  • aucun besoin pre.001 ne justifie une mise à niveau globale de Tauri, TS-RS ou des dépendances frontend.

Le nouveau desk réutilisera le baseline frontend actuel uniquement pour les dépendances réellement utilisées. tauri-plugin-dialog n'est pas retenu pour SOL Prices Desk.

7. État de présentation courant

Décision : backend Tauri en mémoire.

Un runtime applicatif dédié possède :

Resolved Off-chain profile metadata sûre
MarketPriceService
snapshot courant des lignes de présentation
état in-flight borné par provider pour éviter les races d'affichage

Le snapshot de présentation n'est ni un historique, ni une source métier, ni une nouvelle vérité de marché. Une observation vient toujours d'un MarketPriceRefreshOutcome Off-chain.

Règles :

  • aucun prix n'est persisté dans Config, Store, filesystem navigateur, localStorage ou sessionStorage ;
  • l'inventaire initial provient du registry() et affiche price = None avant première observation ;
  • une erreur de refresh peut conserver l'ancienne observation uniquement si elle reste explicitement marquée comme antérieure et accompagnée du nouvel état provider ;
  • received_at et provider_timestamp sont projetés séparément ; l'UI ne fabrique jamais un timestamp provider ;
  • l'UI ne remplace un snapshot que par un résultat backend ordonné/accepté, évitant qu'une réponse plus ancienne écrase une plus récente.

Cette décision reste dans la couche application et ne transforme pas Off-chain Transport en store UI.

8. Screen map SOL Prices Desk

splash
  -> bootstrap Config + Logging + Off-chain runtime
  -> main shell
       -> Prices (vue par défaut)
            -> runtime summary compact
            -> table provider-neutral SOL/USD
                 provider display name
                 semantics
                 auth capability générique
                 availability
                 exact price ou “aucune observation”
                 provider timestamp ou “non fourni”
                 received_at
                 retry_at si présent
                 row refresh
            -> selection DataTable optionnelle
            -> Refresh selected
            -> Refresh all
            -> loading / empty / classified error states
       -> Diagnostics
            -> app/composite/offchain profile
            -> provider count / ready count / unavailable count
            -> aucun endpoint/credential/header

Le shell reste volontairement petit : pas de dashboard trading, graphe, historique, quote routing ou éditeur Config.

Point d'insertion Wallet Desk

Wallet Desk existing shell
  -> Dashboard
       -> panneau compact “SOL/USD prices”
            -> quelques/toutes lignes provider-neutral selon espace
            -> availability + fraîcheur
            -> refresh row / refresh all borné
  -> aucune dépendance à une Wallet sélectionnée ou déverrouillée

Le panneau prix est indépendant du lifecycle VIEW/OWNER. Il ne modifie ni la balance SOL ni les opérations Wallet.

Valorisation USD du solde : hors scope 0.2.12. Il n'existe pas de prix KSP canonique et la release ne choisit pas arbitrairement le premier provider.

9. DTO map retenue

Les DTO sont applicatifs, sérialisables et exportés TS-RS. Les enums évolutifs de la crate Off-chain ne sont pas exposés directement si cela rigidifie l'IPC ; ils sont projetés en codes/labels génériques bornés.

Le prix exact traverse IPC comme chaîne décimale, jamais comme f64. Les timestamps sont des millisecondes Unix ou chaînes de présentation selon le canari TS-RS final; la source de vérité reste MarketPriceTimestamp.

DTO Champs principaux Sensibilité
MarketPriceRuntimeStatusDto app version, composite profile, offchain profile, provider counts, fallback logging Public/safe
MarketPriceProviderRowDto provider_id, display_name, pair, semantics, auth_mode, availability, price?, timestamps?, retry_at?, refreshed Public/safe
MarketPriceRefreshRequestDto provider_id opaque Public input borné
MarketPriceRefreshManyRequestDto provider_ids opaques bornés Public input borné
MarketPriceRefreshResultDto rows affectées + refreshed/classification Public/safe
CommandErrorDto domain/code/message borné sans context sensible Public/safe

Explicitement exclus de tout DTO :

API key
header name/value
endpoint URL
raw response provider
provider-specific request/response DTO
bucket/token internals
Config effective secret values

10. Command map SOL Prices Desk

Command Input Output Owner Sensibilité
get_runtime_status aucun MarketPriceRuntimeStatusDto AppState/Config runtime safe
list_market_prices aucun Vec<MarketPriceProviderRowDto> MarketPriceRuntime + registry safe
refresh_market_price provider_id MarketPriceRefreshResultDto MarketPriceService::refresh safe ID
refresh_market_prices liste bornée provider_id MarketPriceRefreshResultDto MarketPriceService::refresh_many safe IDs
refresh_all_market_prices aucun MarketPriceRefreshResultDto MarketPriceService::refresh_all safe
splash_frontend_ready fenêtre invoquante ordre splash existant Tauri window lifecycle safe
emit_frontend_log niveau/target/message déjà contrôlés ack logging bridge safe-only by contract

Aucune command n'accepte URL, credential, header, rate-limit override ou payload provider.

Wallet Desk réutilise la même sémantique de commands (list/refresh/refresh_all), avec noms éventuellement préfixés pour éviter collision avec ses commandes existantes. L'input reste uniquement le provider_id opaque.

11. Refresh UX

Décisions :

  • ordre initial des lignes = ordre stable du registry ; un tri visuel DataTable ne change pas l'ordre de dispatch backend ;
  • bouton row désactivé pendant le refresh de cette ligne ;
  • batch : sélection bornée, doublons éliminés/rejetés côté UI pour UX mais validation authoritative conservée par Off-chain ;
  • refresh_many/all suit l'implémentation séquentielle V1, sans parallélisme ajouté par l'app ;
  • un provider non éligible est représenté par son availability, pas par un retry/sleep local ;
  • CoolingDown affiche retry_at si disponible ; aucun countdown actif n'est nécessaire ;
  • AuthenticationUnavailable, Misconfigured, Disabled, QuotaUnavailable, TemporarilyUnavailable restent des états génériques ;
  • provider_timestamp = None s'affiche comme « non fourni par le provider », pas comme heure de réception ;
  • une observation précédente peut rester visible après un échec seulement avec sa fraîcheur réelle et le nouvel état provider clairement distingués ;
  • fermeture de fenêtre : la commande/backend peut terminer/cancel selon lifecycle Tauri, mais aucun état frontend persistant ne doit être requis pour la sûreté.

Auto-refresh périodique : hors scope. Aucun setInterval, scheduler ou worker prix n'est ajouté en 0.2.12.

12. Intégration Wallet Desk

Wallet Desk ajoutera une dépendance directe à ksp-offchain-transport-lib parce qu'il consomme le contrat public générique retourné par Config. Cette direction est déjà admise par l'architecture; Off-chain Transport ne dépend jamais de Wallet ni de Config.

Flux :

Config composite Wallet Desk
 -> component offchain_transport / cfg.std.offchain_transport / public_keyless
 -> ConfigDocumentEngine::resolve_offchain_transport_config_profile
 -> ResolvedOffchainTransportConfig
 -> MarketPriceService dans AppState/MarketPriceRuntime
 -> DTO provider-neutral
 -> panneau Dashboard

Non-régressions obligatoires :

WalletSession inchangée
VIEW/OWNER inchangés
Wallet secrets inchangés
getBalance On-chain inchangé
aucune Pubkey requise pour obtenir un prix SOL/USD
aucune multiplication balance x prix
aucun provider canonique

Aucun adapter, parser, limiter ou fetch TS n'est copié dans Wallet Desk.

13. Mutualisation entre applications

La mutualisation métier existe déjà dans ksp-offchain-transport-lib et la mutualisation de construction dans ksp-config-lib.

pre.001 ne retient aucune nouvelle crate partagée. Les deux apps peuvent posséder de petits adapters DTO/runtime propres parce qu'ils sont de la présentation/composition et que leurs AppState/runtime status diffèrent déjà.

Un helper partagé ne sera envisagé que si pre.009pre.011 démontrent une duplication non triviale, stable et réellement réutilisable. Il ne sera pas créé pour éviter quelques conversions enum -> label.

14. Capabilities et plugins

SOL Prices Desk :

permissions  core:default
             tracing:default
plugins      tauri-plugin-tracing uniquement

Aucun plugin filesystem, HTTP, shell, CLI ou dialog n'est nécessaire au WebView.

Wallet Desk conserve sa capability actuelle core:default + tracing:default. Son tauri-plugin-dialog Rust-side reste limité aux workflows Wallet existants et n'est pas utilisé par les prix.

Le threat model considère le WebView comme moins fiable que le core Rust : les commands Rust restent la frontière de validation et n'exposent que les capacités applicatives nécessaires.

15. Packaging et build

SOL Prices Desk :

productName       KSP SOL Prices Desk
identifier        com.sasedev.ksp-app-solprices-desk
dev URL           http://localhost:1434
Vite HMR          1435 strict
frontendDist      ../../../builds/khadhroony-solana-project/ksp-app-solprices-desk/dist
windows           splash + main
bundle targets    all, comme le gabarit stable
icons             même baseline KSP, copiée explicitement dans la nouvelle crate
beforeDevCommand  npm run dev, cwd .
beforeBuildCommand npm run build, cwd .

Les commandes Tauri de validation finales sont exécutées depuis chaque crate ciblée. Aucun cargo tauri ... -c ne sert de sélecteur de crate.

Canari obligatoire : ksp-app-solprices-desk référence son propre package.json, son propre Vite config, ses ports 1434/1435, son frontendDist et son backend; aucune chaîne ksp-app-wallet-desk ne doit apparaître dans les hooks/paths qui sélectionnent le runtime.

16. Threat model desktop 0.2.12

Risque Contrôle retenu
frontend compromis choisit une URL aucun champ URL dans IPC; origine possédée par adapter Off-chain
frontend demande API key/header aucun DTO/command ne les expose; secrets restent Config -> service
provider_id arbitraire/inconnu validation par registry/service; erreur KSP sûre
batch oversized/duplicate borne app + validation authoritative refresh_many avant dispatch
spam refresh admission/rate limits/cooldown Off-chain; UI disable seulement ergonomique
cooldown non expiré availability générique; aucun sleep/retry dans app
provider unavailable ligne reste visible avec état générique; autres providers indépendants
raw error body hostile projection CommandErrorDto classifiée; jamais de body brut
stale observation affichée comme fraîche timestamps réels conservés; état provider séparé; pas de timestamp inventé
race double-click état in-flight backend + UI disable; ordre de snapshot contrôlé
fermeture fenêtre pendant refresh aucune persistance requise; lifecycle/cancel borné testé
CWD/resource confusion cross-app CWD KSP normalisé + resources registry + canari paths/ports/backend dédiés
capabilities trop larges core + tracing seulement pour Price Desk; aucun network/fs/dialog guest
logs frontend sensibles log seulement action, provider_id, compte, code KSP; jamais DTO brut/secret/body
faux prix canonique semantics visibles; aucune moyenne/fallback/first-provider
perte de précision JS prix transmis comme chaîne décimale exacte

17. Stratégie de tests et gates

Gate Preuve attendue
unit Rust app mapping descriptor/state/outcome -> DTO; exact decimal string; stale/in-flight/error
Config composition composite Price Desk et extension Wallet résolus par file_id/profile exacts
Config packaging 11 descriptors/resources synchronisés, seed/schemas propres
public/API boundary aucun provider-specific type requis par lapp; dépendances exactes
desktop contract ports, windows, hooks, frontendDist, header, DataTable, backend propre
desktop security aucun fetch/network/fs/secret storage; capabilities minimales; DTO sans URL/key/body
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 panneau prix + non-régression Wallet/balance
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

Le live gate 0.2.12 vérifie la composition application -> Config -> service avec au moins un provider keyless disponible. Il ne répète pas le smoke exhaustif 7/7 de 0.2.11 sauf contradiction live réelle.

18. Hors périmètre confirmé

nouveau provider ou modification des 8 adapters V1
SOL/EUR ou token arbitraire
OHLCV/historique/chart
SSE/WebSocket prix
consensus/moyenne/fallback automatique
provider canonique
valorisation USD du solde Wallet
auto-refresh/polling périodique
Store/worker/job prix
éditeur Config dans Price Desk
filesystem/network/dialog plugin frontend
nouvelle crate API/UI partagée spéculative

19. Forecast souple recalibré

Chaque tranche technique vise environ 15 à 20 minutes de travail effectif lorsque le sujet s'y prête. Cette durée est une cible de granularité et non une durée maximale : build Tauri, live test, diagnostic ou difficulté réelle peuvent légitimement prolonger une tranche.

Le forecast reste volontairement souple. Une tranche peut être scindée, fusionnée ou réordonnée par delta si la réalité technique l'exige, à condition de préserver les responsabilités de clôture. Le nombre de prereleases prévu n'impose ni une session de conversation par tranche, ni une clôture artificielle sur le numéro initialement prévu.

Chaque prerelease possède un statut directement modifiable. Lorsqu'un correctif d'une tranche est nécessaire, il est ajouté sous la prerelease concernée avec un titre #### pre.NNN-fix.MMM, ce qui conserve l'historique de progression sans transformer le forecast en tableau.

pre.001 — Audit, sizing et cadrage SOL Prices Desk

Statut : réalisé ; gate opérateur complet PASS.

Audit/sizing de la base v0.2.11, screen map, DTO/command map, composition Config, threat model, stratégie de tests/build/live, intégration Wallet Desk et recalibrage de la release. Aucun scaffold Tauri ni code prix fonctionnel n'est avancé dans cette tranche.

pre.001-fix.001 — Forecast souple éditable et statuts

Statut : réalisé.

Remplacement du forecast tabulaire par des sous-sections éditables avec statut explicite. Les futurs correctifs peuvent être insérés sous leur prerelease avec un titre ####, sans modifier le découpage technique, le scope fonctionnel ni les responsabilités de clôture de 0.2.12.

pre.002 — Scaffold ksp-app-solprices-desk

Statut : réalisé ; gate opérateur de tranche PASS.

Création du scaffold strict de ksp-app-solprices-desk : crate lib/bin, shell Tauri, frontend de base, splash, logging et paire de ports réservée 1434/1435. La tranche n'implémente encore ni table prix, ni MarketPriceService, ni refresh réseau.

pre.002-fix.001 — Alignement strict du gabarit desktop commun

Statut : réalisé ; gate opérateur de tranche PASS.

Correction du scaffold pour reprendre réellement les conventions communes Config/Wallet Desk : dépendances frontend de gabarit, ResizeObserver, identité de fenêtre, footer, police/provenance splash, vocabulaire SCSS partagé, commande get_runtime_status, instrumentation shell et canaris anti-dérive. Aucun runtime Off-chain, composite ni table prix n'est avancé.

pre.003 — Composite Config et bootstrap Off-chain

Statut : réalisé ; gate opérateur de tranche PASS après pre.003-fix.001.

Ajout atomique du composite cfg.composite.ksp-app-solprices-desk, de son descriptor registry et des resources packagées nécessaires aux trois Desks concernés, puis bootstrap Config -> Off-chain Transport du nouveau Desk. Le gate exige que le packaging Config reste cohérent ; aucune UI prix n'est ajoutée ici.

pre.003-fix.001 — Correction du canari ConfigEnvironment sans élargissement de contrat

Statut : réalisé ; gate opérateur de tranche PASS.

Correction strictement locale du test config_composition : le message d'assertion ne tente plus de formater le Result<ConfigEnvironment, Error> en Debug. ConfigEnvironment reste volontairement sans contrat Debug; aucun comportement runtime, composite, provider ou frontend n'est modifié.

pre.004 — Runtime prix, registry rows et DTOs

Statut : implémenté ; corrigé par pre.004-fix.001 puis pre.004-fix.002, gate opérateur à confirmer.

Création du MarketPriceRuntime applicatif, projection provider-neutral du registry, DTOs TS-RS et états initiaux/loading/empty. list_market_prices projette les lignes depuis le registry sans dispatch réseau ; l'état de présentation reste uniquement en mémoire backend. Les providers restent opaques à l'UI, le prix exact et les timestamps traversent l'IPC sous forme de chaînes exactes, et aucun refresh n'est encore disponible avant pre.005.

pre.004-fix.001 — Synchronisation de la fixture composite Config Desk

Statut : implémenté ; gate opérateur à confirmer.

Correction du gate workspace révélé après pre.004 : le registry Config contient désormais le composite SOL Prices Desk, donc le jeu de fixtures utilisé par ksp-app-config-desk doit contenir le document correspondant. Le fix ajoute la fixture dédiée avec des profils valides dans l'environnement de test et renforce le canari d'inventory pour vérifier explicitement cfg.composite.ksp-app-solprices-desk. Aucun runtime prix, provider, DTO ou frontend n'est modifié.

pre.004-fix.002 — Canari de version desktop rendu version-neutral

Statut : réalisé ; gate opérateur intégralement PASS.

Le gate de pre.004-fix.001 a révélé que desktop_contract.rs comparait encore package.json et tauri.conf.json à la chaîne figée 0.2.12-pre.4. Le fix reprend la convention déjà utilisée par Config Desk et Wallet Desk : validation SemVer-like avec plancher compatible, puis égalité entre les deux métadonnées desktop. Les futures prereleases/fixes peuvent ainsi avancer la version sans rendre le canari historique pre.002 artificiellement rouge. Aucun runtime prix, provider, DTO ou frontend n'est modifié.

pre.005 — Refresh individuel

Statut : implémenté ; corrigé par pre.005-fix.001, gate opérateur à confirmer.

Branchement du refresh d'une ligne via MarketPriceService::refresh, projection de l'observation exacte, de la fraîcheur et de l'availability, gestion d'erreur sûre et maintien du dernier état applicatif uniquement en mémoire backend. Le backend marque la ligne loading sans conserver le mutex de présentation pendant l'await, puis applique l'outcome provider-neutral ; une tentative sans nouvelle observation conserve la dernière observation réussie. L'UI ajoute un bouton Refresh par ligne, journalise le clic en debug, et n'expose encore aucun refresh multiple/global avant pre.006.

pre.005-fix.001 — Canari de centralisation Tauri rendu structurel

Statut : implémenté ; gate opérateur à confirmer.

Le gate de pre.005 confirme que le refresh individuel fonctionne et que le runtime Tauri démarre, mais révèle un faux positif dans desktop_security.rs : le canari assimilait toute occurrence du nom métier refresh_market_price hors tauri.rs à du plumbing de commande. Le fix conserve l'interdiction structurelle de #[tauri::command] hors tauri.rs, ajoute l'interdiction de tauri::generate_handler! hors tauri.rs, et autorise les méthodes applicatives homonymes dans AppState. Aucun comportement réseau, DTO, provider, row, frontend ou commande n'est modifié.

pre.006 — Refresh multiple et global

Statut : planifié.

Ajout des refresh selected/many/all, suivi in-flight, ordre déterministe et projection des cooldown/retry deadlines sans scheduling consommateur. Aucun polling périodique, fallback automatique ou consensus provider n'est introduit.

pre.007 — UX et instrumentation SOL Prices Desk

Statut : planifié.

Finalisation de la table responsive, interactions utilisateur, états visuels, instrumentation frontend/backend et polish du Desk. La tranche reste manuelle : aucun auto-refresh ni persistance navigateur n'est ajouté.

pre.008 — Hardening SOL Prices Desk

Statut : planifié.

Durcissement des boundaries desktop/security/package, canaris de capabilities minimales, parcours fonctionnel complet et non-régression du bootstrap avant d'étendre Wallet Desk. Le Desk doit être stable isolément à la sortie de cette tranche.

pre.009 — Extension composite/runtime Wallet Desk

Statut : planifié.

Extension additive du composite Wallet Desk avec Off-chain Transport et intégration du runtime prix backend, sans modifier les contrats Wallet existants, le lifecycle VIEW/OWNER ni le chemin getBalance.

pre.010 — DTOs et commands prix Wallet Desk

Statut : planifié.

Ajout de la surface IPC provider-neutral nécessaire au Wallet Desk pour l'inventaire et le refresh prix. Aucun secret, URL provider, wire provider-specific ou valorisation USD du solde ne traverse cette surface.

pre.011 — Panneau prix Wallet Desk

Statut : planifié.

Ajout du panneau Dashboard prix avec refresh manuel et projection des observations/availability, puis vérification des non-régressions balance et autorisations VIEW/OWNER. Le solde SOL et les prix restent deux informations distinctes ; aucune valorisation USD canonique n'est calculée.

pre.012 — Hardening cross-app et complétude

Statut : planifié.

Revue croisée des deux Desks, capabilities/resources, contracts IPC, dépendances, sécurité et canaris de complétude. Cette tranche ferme le comportement applicatif avant le gate technique/live final.

pre.013 — Gate technique/live final

Statut : planifié.

Gate workspace complet, tests applicatifs pertinents, smoke live keyless de composition application -> Config -> MarketPriceService, graphes de dépendances utiles et builds Tauri finaux des applications modifiées. Cette tranche ne réconcilie pas README/USAGE ni les documents finaux.

pre.014 — Réconciliation documentaire finale

Statut : planifié.

Réconciliation du plan, de la validation, des README/USAGE et autres documents durables concernés avec le runtime réellement livré après le gate technique. Cette tranche ne finalise ni CHANGELOG.md, ni ROADMAP.md, ni le prompt suivant.

pre.015 — Préparation minimale de publication

Statut : planifié.

Préparation du prompt de la release suivante, de CHANGELOG.md et de ROADMAP.md, avec la mécanique Cargo/delta imposée par le workflow. Aucun code, test, plan, validation, README ou USAGE n'est rouvert dans cette dernière prerelease.

rel.001 — Publication stable v0.2.12

Statut : planifié.

Mécanique de publication stable uniquement, après validation de la dernière prerelease et vérification de la cohérence de release. Aucun défaut fonctionnel ou documentaire ne doit être absorbé par rel.001.

Le point de packaging transversal de pre.003 est désormais fermé. Le prochain risque fonctionnel est borné aux refresh pre.005/pre.006, sans remettre en cause le découpage souple ni les responsabilités documentaires de clôture.

20. Critères de sortie pre.001

Critère Verdict
base stable v0.2.11 cohérente PASS
règles/architecture relues PASS
baseline opérateur verte; limites sandbox documentées PASS
surface Off-chain/Config réelle inventoriée PASS
gabarits Config/Wallet Desk audités PASS
audit Tauri/TS-RS actuel PASS
screen map PASS
DTO/command map PASS
Config/composite map PASS
threat model PASS
Wallet integration map PASS
tests/build/live strategy PASS
forecast recalibré PASS
scope clôturable PASS

pre.001 n'autorise aucune implémentation fonctionnelle supplémentaire dans ce delta. La prochaine responsabilité est exclusivement pre.002 : scaffold du nouveau Desk et canaris de gabarit.