From 263464ddd77149e577aa16c1781eddb37e186ec5 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Fri, 21 Aug 2026 17:27:20 +0200 Subject: [PATCH] v0.2.6-pre.013-fix.001 --- Cargo.toml | 4 +- crates/ksp-app-wallet-desk/package.json | 2 +- crates/ksp-app-wallet-desk/tauri.conf.json | 2 +- .../tests/release_compliance.rs | 16 +++---- deltas/0.2.6/pre.013-fix.001.md | 44 +++++++++++++++++++ docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md | 7 ++- .../009-V0_2_6_WALLET_DESK_COMPLIANCE.md | 6 ++- 7 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 deltas/0.2.6/pre.013-fix.001.md diff --git a/Cargo.toml b/Cargo.toml index 033d238..408ace8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 183 +# version: 184 [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-onchain-transport-lib", "crates/ksp-wallet-lib"] [workspace.package] -version = "0.2.6-pre.13" +version = "0.2.6-pre.13.fix.1" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/crates/ksp-app-wallet-desk/package.json b/crates/ksp-app-wallet-desk/package.json index d41b347..2ea3adc 100644 --- a/crates/ksp-app-wallet-desk/package.json +++ b/crates/ksp-app-wallet-desk/package.json @@ -1,7 +1,7 @@ { "name": "ksp-app-wallet-desk", "private": true, - "version": "0.2.6-pre.13", + "version": "0.2.6-pre.13.fix.1", "type": "module", "scripts": { "dev": "vite", diff --git a/crates/ksp-app-wallet-desk/tauri.conf.json b/crates/ksp-app-wallet-desk/tauri.conf.json index 620b1f4..fca364f 100644 --- a/crates/ksp-app-wallet-desk/tauri.conf.json +++ b/crates/ksp-app-wallet-desk/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "KSP Wallet Desk", - "version": "0.2.6-pre.13", + "version": "0.2.6-pre.13.fix.1", "identifier": "com.sasedev.ksp-app-wallet-desk", "build": { "beforeDevCommand": "npm run dev", diff --git a/crates/ksp-app-wallet-desk/tests/release_compliance.rs b/crates/ksp-app-wallet-desk/tests/release_compliance.rs index ad169c1..0b7f911 100644 --- a/crates/ksp-app-wallet-desk/tests/release_compliance.rs +++ b/crates/ksp-app-wallet-desk/tests/release_compliance.rs @@ -1,5 +1,5 @@ // file: crates/ksp-app-wallet-desk/tests/release_compliance.rs -// version: 1 +// version: 2 //! Release-wide deterministic compliance canaries for Wallet Desk. @@ -43,16 +43,16 @@ fn read_rust_source_tree(root: &std::path::Path) -> String { return combined; } -fn struct_field_block<'a>(source: &'a str, name: &str) -> &'a str { +fn struct_field_lines(source: &str, name: &str) -> String { let marker = std::format!("struct {name}"); let start = source.find(marker.as_str()); assert!(start.is_some(), "missing struct {name}"); let start = match start { std::option::Option::Some(value) => value, - std::option::Option::None => return "", + std::option::Option::None => return String::new(), }; - let tail = &source[start..]; - return tail.split("}\n").next().unwrap_or_default(); + let block = source[start..].split("}\n").next().unwrap_or_default(); + return block.lines().filter(|line| return line.trim_start().starts_with("pub(crate) ")).collect::>().join("\n"); } #[test] @@ -135,13 +135,13 @@ fn response_dtos_keep_secret_key_material_out_of_ipc() { (security.as_str(), "WalletViewSecurityStatusDto"), (common.as_str(), "RuntimeStatusDto"), ] { - let fields = struct_field_block(source, name); + let fields = struct_field_lines(source, name); for forbidden in ["password", "secret_key", "private_key", "keypair_bytes", "ciphertext"] { assert!(!fields.contains(forbidden), "response DTO {name} contains forbidden field material {forbidden}"); } } - let inspection = struct_field_block(import.as_str(), "WalletTransferInspectionDto"); - let export_result = struct_field_block(export.as_str(), "WalletExportResultDto"); + let inspection = struct_field_lines(import.as_str(), "WalletTransferInspectionDto"); + let export_result = struct_field_lines(export.as_str(), "WalletExportResultDto"); assert!(!inspection.contains("path")); assert!(!export_result.contains("path")); assert!(!export_result.contains("content")); diff --git a/deltas/0.2.6/pre.013-fix.001.md b/deltas/0.2.6/pre.013-fix.001.md new file mode 100644 index 0000000..3e12540 --- /dev/null +++ b/deltas/0.2.6/pre.013-fix.001.md @@ -0,0 +1,44 @@ + + + +# Delta `0.2.6-pre.013-fix.001` — correction du canari DTO/IPC + +## Objet + +Corriger le faux positif du gate `response_dtos_keep_secret_key_material_out_of_ipc` révélé par la validation opérateur de `pre.013`, sans modifier le runtime Wallet Desk ni assouplir les frontières de sécurité. + +## Diagnostic + +`WalletAuthorizedDto` ne contient aucun champ password. Son champ sûr `configured_secret_candidate_count` possède toutefois une documentation mentionnant `Wallet password candidates`. Le helper `struct_field_block` de `release_compliance.rs` analysait le bloc Rust complet, commentaires inclus, puis interprétait ce mot comme du matériau de champ interdit. + +Cette classe de faux positif avait déjà été rencontrée et corrigée en `pre.006-fix.001`. + +## Changements + +- remplace le scan du bloc struct complet par `struct_field_lines`, limité aux lignes de champs `pub(crate)` ; +- applique cette extraction aux sept DTOs de réponse audités ; +- applique la même extraction aux contrôles `path`, `content` et `bytes` d'import/export ; +- conserve strictement les listes de matériaux interdits ; +- ne modifie aucun DTO, aucune commande Tauri, aucune capability, aucune dépendance et aucun comportement runtime ; +- documente le checkpoint dans la matrice de compliance et le plan détaillé `0.2.6`. + +## Version + +```text +workspace.package.version = 0.2.6-pre.13.fix.1 +commit attendu = v0.2.6-pre.013-fix.001 +aucun tag +``` + +## Validation attendue + +```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 +``` + +Puis exécuter le smoke Devnet `pre.013` déjà prévu. Aucun nouveau `cargo tauri dev` n'est requis par ce correctif test-only. diff --git a/docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md b/docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md index bb8868b..7c9b5e0 100644 --- a/docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md +++ b/docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md @@ -1,5 +1,5 @@ - + # Plan `0.2.6` — Wallet Desk @@ -25,6 +25,11 @@ Les validations opérateur du `2026-08-20` ont ensuite confirmé la base `pre.00 `0.2.6-pre.003` matérialise la composition Config prévue : `cfg.std.wallet`/`schema.std.wallet`, le composite `cfg.composite.ksp-app-wallet-desk`, les profils Wallet `default`/`temporary`/`tests`, `ResolvedWalletConfig` et les adapters qui peuvent consommer un profil déjà sélectionné par composite sans perdre la provenance `Composite`. Wallet Desk valide les composants `logging`/`transport`/`wallet`, crée la racine et le sous-répertoire effectif absents avec logs `debug`, refuse les objets filesystem invalides/symlinks de sous-répertoire avec logs `error`, et expose uniquement les chemins/profils non secrets dans le statut runtime. Aucun inventory `.kspwallet` n’est encore effectué. `pre.003-fix.001` corrige les deux régressions de tests révélées par la validation workspace et le warning Clippy, puis rend visibles les événements `trace` frontend. `pre.003-fix.002` corrige ensuite le canari d’inventaire `.env.example` qui confondait un fragment d’identifiant Rust avec une variable KSP, remplace le profil temporaire `wallet_desk_dev` par une famille Logging réutilisable (`console_*`, `file_info`, `superdev`, `supertrace`) et fait sélectionner temporairement `supertrace` par le composite Wallet Desk afin de conserver la visibilité des actions frontend sans profil spécifique à l’application. `pre.003-fix.003` corrige uniquement les canaris révélés par la validation de `fix.002` : conformité `clippy::implicit_return` et séparation explicite entre fragment lexical KSP incorporé dans un identifiant et nom d’environnement concret suffixé. `pre.003-fix.004` ferme le dernier défaut Clippy de cette série en ajoutant les `return` explicites aux cinq closures restantes du test de composition `supertrace`, sans changer les profils Logging ni le composite. `pre.004` matérialise ensuite l’inventory locked réel. Sa validation opérateur confirme le comportement fonctionnel et le workspace complet, mais révèle deux warnings `unused_imports` sur des réexports crate-root internes uniquement utiles aux unit tests ; `pre.004-fix.001` les limite à `#[cfg(test)]` : ils disparaissent du build runtime mais restent disponibles au crate-root pour les unit tests, conformément aux règles d’exports KSP, sans changement de comportement. `pre.005` matérialise ensuite la création native dans Wallet Desk et le premier lifecycle durable `WalletSession` : création no-clobber sous la racine Config via `create_wallet_file_v1`, session OWNER conservée uniquement en Rust après création, sélection locked durable, `Lock`/`Deselect`/Refresh/changement de wallet avec drop des handles et purge frontend des projections protégées/passwords. Les unlock VIEW/OWNER de wallets existants restent strictement `pre.006`. `pre.005-fix.001` corrige le gate de compilation/tests révélé par l'opérateur sans modifier le lifecycle : la variante `WalletSession::Owner` contient désormais `Box` afin de fermer `clippy::large_enum_variant`, et le canari de sécurité définit explicitement `request_start` avant de contrôler les champs password request-only. `pre.006` matérialise ensuite les unlock existants : VIEW/OWNER manuel, découverte Config des candidats `KSP_SECRET_WALLET_PASS_*`, ordre déterministe filename normalisé -> numérique -> nommé, actions configurées explicites et jamais automatiques, `PrivilegedOperation` pendant Argon2, puis sessions `View`/`Owner` Rust-only avec candidate count seul projeté vers l’UI. `pre.006-fix.001` corrige les deux canaris `desktop_security` qui inspectaient trop largement le texte de `WalletAuthorizedDto` : la documentation du compteur de candidats contient légitimement le mot `password`, mais aucun champ password n’est sérialisé ; le test filtre désormais uniquement les lignes de champs `pub(crate)` de la structure. `pre.007` ferme ensuite le MVP réseau : Config sait mapper un profil Transport déjà sélectionné par composite sans perdre la provenance `Composite`; Wallet Desk construit et conserve `HttpTransportPool`, publie uniquement profile/role/cluster/provider/compteurs sûrs, et `refresh_wallet_balance` accepte zéro argument frontend. Rust copie la Pubkey depuis `WalletView`/`WalletOwner`, libère le mutex avant l'I/O `getBalance`, utilise `confirmed`, puis projette lamports, SOL exact à neuf décimales, slot et `api_version`. Une réponse arrivée après lock/deselect/changement d'autorisation est refusée afin d'empêcher une balance stale de réapparaître. `pre.007-fix.001` corrige uniquement le canari d'intégration qui utilisait le constructeur test-only `ConfigEnvironment::from_maps`; le test passe désormais par `ConfigEnvironment::load`, API publique utilisée en production. `pre.007-fix.002` corrige le second défaut du même canari : son message d'assertion ne formate plus `environment` avec `{:?}`, ce qui aurait exigé `ConfigEnvironment: Debug`. ConfigEnvironment reste volontairement non-`Debug` et le runtime n'est pas modifié. `pre.008` ajoute ensuite l'import de keypairs Solana CLI JSON/Base58 via le plugin Dialog utilisé exclusivement côté Rust : le frontend choisit seulement le format, Rust ouvre le picker natif, convertit le résultat en chemin local, lit la source avec une borne stricte, valide la Pubkey via `ksp-wallet-lib`, conserve les octets secrets dans `Zeroizing>` et ne renvoie que basename/format/Pubkey. L'import consomme cette source staged en mémoire avec `import_wallet_transfer_v1`, publie no-clobber sous la racine Wallet Config et ouvre la session OWNER avec de nouveaux credentials KSP. Aucun chemin source, contenu secret ou permission guest Dialog/FS ne traverse l'IPC. + +### Correctif `0.2.6-pre.013-fix.001` + +Le premier passage opérateur de `pre.013` a confirmé `fmt`, audit, `check` et Clippy, mais le nouveau canari `response_dtos_keep_secret_key_material_out_of_ipc` a produit un faux positif sur `WalletAuthorizedDto` : le scanner analysait aussi les commentaires du bloc de structure et rencontrait la documentation légitime `Wallet password candidates`. `pre.013-fix.001` aligne ce gate sur la règle déjà éprouvée en `pre.006-fix.001` : seuls les champs `pub(crate)` réellement sérialisables sont inspectés pour `password`, key material, path/content/bytes. Aucun DTO ni contrat IPC runtime n'est assoupli. + ## 2. Sources relues et hiérarchie appliquée L'audit suit l'ordre d'autorité demandé : diff --git a/docs/validation/009-V0_2_6_WALLET_DESK_COMPLIANCE.md b/docs/validation/009-V0_2_6_WALLET_DESK_COMPLIANCE.md index 8df7210..6c4084b 100644 --- a/docs/validation/009-V0_2_6_WALLET_DESK_COMPLIANCE.md +++ b/docs/validation/009-V0_2_6_WALLET_DESK_COMPLIANCE.md @@ -1,5 +1,5 @@ - + # Validation `0.2.6` — Wallet Desk integration / compliance / security @@ -22,6 +22,10 @@ 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 :