# Validation `0.2.6` — Wallet Desk integration / compliance / security ## 1. Objet Cette matrice est ouverte par `0.2.6-pre.013` comme preuve durable de composition et de conformité de `ksp-app-wallet-desk`. Le calendrier a été étendu après `pre.014` : `pre.015` introduit le wire V2, `pre.016` les APIs génériques/versionnées, `pre.017` migration/régression, puis `pre.018` porte la clôture documentaire et le dernier build Tauri. Elle ne remplace ni le plan [`../plans/013-V0_2_6_WALLET_DESK_PLAN.md`](../plans/013-V0_2_6_WALLET_DESK_PLAN.md), ni la matrice Wallet V1 [`008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md), ni les deltas `0.2.6`. Le gate `pre.013` porte sur : ```text composition Config -> Wallet -> Transport inventory/path adversarial DTO / IPC / frontend secret boundaries capabilities Tauri KSP dependency ownership smoke Devnet opt-in Wallet Desk Cargo tree / inverse tree workspace checkpoint complet ``` ### Checkpoint `pre.013-fix.001` Le premier run opérateur de `pre.013` du 21 août 2026 a validé `cargo fmt`, l'audit Python, `cargo check` et Clippy. Les tests ont ensuite révélé un défaut du **canari**, pas du DTO : `WalletAuthorizedDto` documente `configured_secret_candidate_count` avec les mots `Wallet password candidates`, et le scanner de `release_compliance` inspectait commentaires et champs ensemble. Le correctif restreint désormais l'analyse aux lignes de champs `pub(crate)`, comme le canari éprouvé depuis `pre.006-fix.001`. Les frontières IPC ne changent pas. ## 2. Surface intégrée auditée Au démarrage de `pre.013`, Wallet Desk a déjà validé en runtime : ```text Config composite logging + wallet + transport répertoire Wallet effectif Config-owned inventory locked .kspwallet create import Solana CLI JSON / Base58 unlock manuel et Config-owned VIEW / OWNER getBalance via Transport alias / notes OWNER rotation OWNER rotation VIEW par OWNER self-rotation VIEW strong disable/recreate VIEW export OWNER Solana CLI JSON / Base58 no-clobber export ``` Le checkpoint opérateur `pre.012` du 21 août 2026 est vert : `cargo fmt`, audit Python, `cargo check`, Clippy sans warning, tests Wallet Desk, tests workspace complets et parcours `cargo tauri dev`. Le runtime confirme aussi l'export des deux formats, le refus `wallet.destination_exists` sans invalidation de la session OWNER et l'annulation du save picker sans effet. ## 3. Matrice de frontières | Frontière | Contrat `0.2.6` | Preuve durable | |------------------------------|--------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------| | Frontend -> Config | aucun accès direct env/.env | `release_compliance::backend_keeps_config_wallet_transport_and_logging_ownership_boundaries` + ownership Config | | Frontend -> Wallet secret | passwords uniquement request-only ; jamais de keypair en IPC | `desktop_security` + `release_compliance::response_dtos_keep_secret_key_material_out_of_ipc` | | Frontend -> filesystem | aucun path arbitraire ; picker natif Rust | tests import/export + capability audit | | Frontend -> réseau Solana | aucun `fetch`/WebSocket/RPC direct | `release_compliance::frontend_has_no_direct_filesystem_network_or_secret_persistence_surface` | | Wallet Desk -> Solana crates | aucune dépendance protocole directe | `release_compliance::wallet_desk_dependency_firewall_and_tauri_capabilities_are_minimal` | | Wallet Desk -> HTTP | `ksp-onchain-transport-lib` uniquement | manifest + smoke Devnet | | Wallet Desk -> Wallet crypto | `ksp-wallet-lib` uniquement | manifest + feature canaries | | Wallet Desk -> logging | façade `ksp-logging-lib` + adapter `tauri-plugin-tracing` | source audit + workspace logging canary | | locked -> frontend | format/version/VIEW enabled seulement | `desktop_security` | | VIEW/OWNER handles | Rust-only `AppState` | session/security tests | | export | OWNER-only, file direct, no-clobber | `desktop_security` + runtime `pre.012` | ## 4. Inventory / path adversarial `pre.013` renforce le canari déterministe d'inventory : ```text seuls les fichiers réguliers directs *.kspwallet sont candidats suffixe exact et sensible à la casse backup.kspwallet.bak ignoré upper.KSPWALLET ignoré nested/hidden.kspwallet ignoré répertoire nommé *.kspwallet ignoré symlink *.kspwallet ignoré sélection ../... rejetée sélection ..\... rejetée sélection absolue rejetée sélection nested/... rejetée sélection suffixe non exact rejetée sélection vide rejetée ``` La sélection continue de réinspecter le fichier verrouillé au moment de l'ouverture de session ; l'inventory n'est jamais utilisé comme autorité de sécurité durable. ## 5. DTO / IPC / frontend audit Les réponses IPC auditées ne doivent jamais contenir : ```text password secret_key private_key keypair_bytes ciphertext ``` Les projections import/export ne contiennent aucun path complet. `WalletAuthorizedDto` peut exposer Pubkey/alias/notes uniquement après VIEW/OWNER ; le locked inventory ne peut jamais les exposer. Le frontend doit rester sans : ```text @tauri-apps/plugin-dialog @tauri-apps/plugin-fs window.alert / confirm / prompt localStorage / sessionStorage navigator.clipboard pour secret fetch / XMLHttpRequest / WebSocket / EventSource KSP_SECRET_WALLET_PASS_* concret sourcePath / destinationPath ``` Les opérations natives import/export utilisent le plugin Dialog côté Rust, sans permission Dialog/FS accordée au guest frontend. ## 6. Capabilities Tauri La capability Wallet Desk doit rester exactement : ```text core:default tracing:default ``` Aucune permission `dialog:*` ou `fs:*` n'est accordée au frontend. La CSP reste `null` tant qu'un besoin concret n'impose pas une politique spécifique ; `pre.013` n'ajoute aucune ressource réseau frontend. ## 7. Dependency firewall Dépendances KSP directes attendues de Wallet Desk : ```text ksp-config-lib ksp-core-lib ksp-logging-lib ksp-onchain-transport-lib ksp-wallet-lib ``` Aucune dépendance directe `solana-*`, `reqwest` ou `tracing` n'est admise dans le manifest Wallet Desk. `tauri-plugin-tracing` reste l'adapter Tauri justifié ; l'émission applicative reste via `ksp-logging-lib`. Commandes opérateur `pre.013` : ```bash cargo tree -p ksp-app-wallet-desk --depth 1 cargo tree -p ksp-app-wallet-desk -d cargo tree -i ksp-wallet-lib cargo tree -i ksp-onchain-transport-lib cargo tree -i tauri-plugin-dialog ``` Le résultat attendu est qu'aucune nouvelle dépendance Solana/protocole directe ne soit introduite par `pre.013`; le seul changement de feature est `tokio/macros` requis pour le smoke opt-in de la crate application. ## 8. Smoke Devnet Wallet Desk Le smoke live est : ```text Config composite devnet -> resolve Wallet profile Composite -> ConfigEnvironment -> répertoire Wallet effectif -> create .kspwallet réel VIEW+OWNER -> inspect locked -> open VIEW -> resolve Transport profile Composite -> HttpTransportPool -> getBalance(confirmed) sur la Pubkey du wallet créé -> suppression du .kspwallet canari ``` Il est volontairement `ignored` dans la suite déterministe afin d'éviter une dépendance réseau lors de `cargo test --workspace`. Commande recommandée : ```bash KSP_WALLETS_DIRECTORY=var/wallet-desk-pre013-smoke \ cargo test -p ksp-app-wallet-desk \ --test wallet_desk_devnet_smoke \ -- --ignored --nocapture ``` Ce placement est intentionnel : le smoke cross-crates `Config -> Wallet -> Transport -> Devnet getBalance` appartient à la surface d'orchestration Wallet Desk. Il ne doit pas migrer dans `ksp-config-lib` ou `ksp-onchain-transport-lib`. Un solde `0` est un succès valide ; le gate vérifie l'exécution RPC et un contexte de slot non nul, pas un montant particulier. ## 9. Gate déterministe `pre.013` ```bash cargo fmt --all python3 scripts/audit_rust_workspace_rules.py cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-app-wallet-desk cargo test --workspace ``` Attendus : ```text audit structurel clean aucun warning check/Clippy release_compliance vert wallet_desk_devnet_smoke présent mais ignored dans workspace inventory adversarial renforcé vert aucune régression Config/Core/Logging/Transport/Wallet ``` ## 10. Checkpoint runtime `pre.012` déjà acquis Le runtime communiqué avant ouverture de `pre.013` confirme notamment : ```text export Base58 OWNER : OK export Solana CLI JSON OWNER : OK destination existante : wallet.destination_exists, session OWNER conservée annulation save picker : aucun export, session conservée VIEW : export indisponible aucun secret/path complet observé dans les logs frontend/backend fournis ``` Ce checkpoint n'est pas rejoué automatiquement par `pre.013`; la tranche ajoute les canaries transversaux qui rendent ces frontières durables. ## 11. Résultats `pre.013` Checkpoint opérateur après `pre.013-fix.001` : ```text fmt / audit / check / clippy : PASS cargo test -p ksp-app-wallet-desk : PASS release_compliance : PASS (4/4) smoke Devnet Wallet Desk opt-in : PASS cargo tree / inverse tree : exécutés ; tauri-plugin-fs observé uniquement transitivement via tauri-plugin-dialog cargo test --workspace : BLOCKED par un faux positif du canari Logging global ``` Le blocage workspace est limité à `ksp-logging-lib/tests/ownership.rs::workspace_crates_do_not_bypass_ksp_logging_facade` : le scanner voit le littéral `tracing::` dans `release_compliance.rs`, alors que ce littéral est la chaîne recherchée par le canari et non un usage de `tracing`. `pre.013-fix.002` supprime ce littéral statique en construisant le motif à l'exécution, sans modifier le scanner global ni relâcher la politique Logging. La matrice reste ouverte jusqu'à `pre.018`, après les tranches V2 `pre.015`–`pre.017`; `pre.018` ajoute le parcours fonctionnel final, README/USAGE et le build Tauri exécuté en toute dernière opération. ## 11. Intercalation V2 à partir de `pre.015` `pre.015` ne modifie pas encore Wallet Desk : il ajoute dans `ksp-wallet-lib` un codec binaire V2 strict et une fixture canonique. Les gates Desk `pre.013`/`pre.014` restent donc applicables sans changement. `pre.016` matérialise ensuite la façade version-neutral et fait migrer Wallet Desk vers elle : ```text create/import Desk API générique -> default V2 open VIEW/OWNER Desk API générique -> détection V1/V2 inventory/selection Desk inspect générique -> détection V1/V2 aucun appel Desk à *_v1 ou *_v2 gate durable V1 existant reste ouvrable sans migration V2 nouvellement créé/importé administration complète conservée en V2 ``` Les canaris `pre.016` couvrent également le refus croisé des lecteurs explicitement versionnés et le maintien du format V2 après metadata/rotations/disable/recreate/self-rotation VIEW. La migration V1 -> V2 reste explicitement hors de cette tranche et appartient à `pre.017`.