# Delta `0.2.6-pre.006` — unlock VIEW/OWNER manuel et secrets Config ## Base requise ```text 0.2.6-pre.005-fix.001 appliquée workspace.package.version = 0.2.6-pre.5.fix.1 ``` Les preuves opérateur de `pre.005-fix.001` sont vertes : formatage, audit structurel, `cargo check --workspace`, Clippy, tests Wallet Desk, workspace complet et `cargo tauri dev`. La création native, le no-clobber, la sélection locked, Deselect et Refresh ont été vérifiés en runtime. ## Type de livraison ```text ksp-general-0.2.6-pre.006.zip ``` Cette tranche modifie le runtime Rust/frontend ; le signal technique devient : ```text workspace.package.version = 0.2.6-pre.6 commit = v0.2.6-pre.006 ``` Aucun tag stable. ## Objet Permettre l'ouverture explicite d'un `.kspwallet` existant avec VIEW ou OWNER, soit par password manuel éphémère, soit par les secrets Wallet possédés par Config depuis le process ou `.env`, sans auto-unlock et sans faire traverser à ces secrets la frontière Rust -> frontend. ## Session Rust `WalletSession` matérialise désormais : ```text NoSelection Locked PrivilegedOperation View Owner ``` Transitions d'un unlock : ```text Locked -> PrivilegedOperation -> View / Owner sur succès -> Locked sur échec ``` `PrivilegedOperation` conserve le path et `LockedWalletInfo` côté Rust pendant Argon2 sans conserver le mutex `std::sync::Mutex` à travers `.await`. Une seconde tentative concurrente est refusée. Si une autre action purge/change la session pendant la KDF, la complétion obsolète ne peut pas réinstaller son handle. `WalletView` et `WalletOwner` sont tous deux boxed dans la session ; chemins complets et handles ne traversent jamais IPC. ## Unlock manuel Nouvelles commandes : ```text unlock_wallet_view_manual unlock_wallet_owner_manual ``` `WalletUnlockRequestDto` transporte uniquement : ```text password: String ``` Le DTO ne dérive ni `Debug` ni `Clone`. Le `String` est immédiatement déplacé dans `ViewPassword` ou `OwnerPassword`, puis zeroized par le wrapper Wallet à sa destruction. Rust ne renvoie jamais ce password. VIEW est refusé avant KDF lorsque le wallet locked annonce `view_enabled = false`. ## Secrets Config `KSP_SECRET_WALLET_PASS_*` Wallet Desk utilise exclusivement les APIs publiques Config : ```text ConfigManagement::environment_report ConfigManagement::reveal_effective_environment_value ``` La première API découvre les noms disponibles sans valeur réelle. La seconde n'est appelée que pendant une action d'unlock configuré explicitement demandée. Normalisation filename : ```text strip .kspwallet uppercase ASCII hors [A-Z0-9] -> _ runs de _ compactés _ de bord supprimés ``` Ordre des candidats : ```text 1. suffixe exactement égal au filename normalisé 2. suffixes numériques dans l'ordre numérique 3. autres suffixes nommés dans l'ordre lexicographique ``` Les suffixes nommés restent des identifiants opérateur/filename ; l'alias interne protégé du wallet n'est jamais utilisé pour choisir un secret. Nouvelles commandes explicites : ```text unlock_wallet_view_configured unlock_wallet_owner_configured ``` Aucun candidat n'est essayé lors de `select_wallet`. L'action configurée tente les candidats jusqu'au premier succès ou épuisement. Le frontend reçoit uniquement : ```text configured_secret_candidate_count ``` Les noms, suffixes, sources et valeurs des variables Config restent côté Rust et ne sont pas journalisés. ## Projection autorisée `WalletAuthorizedDto` est maintenant commun à VIEW et OWNER et ajoute seulement : ```text configured_secret_candidate_count ``` Après VIEW/OWNER, l'UI peut afficher Pubkey, alias et notes puisque la capability est explicitement autorisée. Aucun secret Solana/password/path complet n'est sérialisé. ## Frontend L'écran Security devient fonctionnel : ```text Unlock VIEW manuel Unlock OWNER manuel Unlock VIEW avec secret configuré Unlock OWNER avec secret configuré ``` L'UI affiche le nombre de candidats Config, jamais leurs identifiants. Les actions sont désactivées si aucun wallet locked n'est sélectionné ; VIEW est aussi désactivé si le wallet ne possède pas de capability VIEW. Pendant Argon2, l'état frontend devient `privileged_operation`, les actions concurrentes sont désactivées et un message indique le coût attendu. Les inputs password sont purgés après succès ou échec. La DataTable distingue désormais une session ouverte VIEW ou OWNER avec `fa-lock-open`. ## Tests et canaris Ajouts/renforcements : ```text normalisation filename -> label secret ordre filename / numérique / nommé WalletUnlockRequestDto request-only états ViewOpen / OwnerOpen / PrivilegedOperation quatre commandes unlock présentes Config environment_report + reveal utilisés côté Rust aucun nom de secret Config dans frontend candidate count uniquement pas d'auto-unlock dans selectWallet purge des passwords manuels ``` Les tests cryptographiques et non-oracle restent la responsabilité de `ksp-wallet-lib`. ## Dépendances Aucune dépendance Cargo ou npm n'est ajoutée/modifiée. **Aucune commande npm directe n'est nécessaire.** ## Validation opérateur requise ```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 KSP_WALLETS_DIRECTORY=var/wallet-desk-pre006 cargo tauri dev -c crates/ksp-app-wallet-desk/tauri.conf.json ``` Pour tester les secrets Config sans modifier `.env`, il est possible de lancer explicitement par exemple : ```bash KSP_WALLETS_DIRECTORY=var/wallet-desk-pre006 \ KSP_SECRET_WALLET_PASS_WALLET_01='' \ KSP_SECRET_WALLET_PASS_01='' \ cargo tauri dev -c crates/ksp-app-wallet-desk/tauri.conf.json ``` Sur `wallet-01.kspwallet`, le candidat `WALLET_01` sera essayé avant `_01`. Les deux actions VIEW/OWNER restent distinctes ; aucun essai n'est déclenché à la simple sélection du wallet. Toujours aucun `cargo tauri build` à ce stade. ## Suite Après validation de `pre.006`, `pre.007` branchera la composition Transport du composite Wallet Desk et `getBalance` à partir de la Pubkey du handle VIEW/OWNER autorisé afin de fermer le MVP identité + balance.