From 0e72914237a0d7fa6560ead18470159ba19f963c Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Thu, 20 Aug 2026 21:23:09 +0200 Subject: [PATCH] v0.2.6-pre.003-fix.001 --- Cargo.toml | 2 +- ROADMAP.md | 4 +- config/composite.ksp-app-wallet-desk.json | 6 +- ...composite.ksp-app-wallet-desk.example.json | 6 +- config/std.logging.json | 112 ++++++++++++++++++ .../unit_tests/profiles.rs | 10 +- .../ksp-app-wallet-desk/frontend/ts/main.ts | 30 ++++- crates/ksp-app-wallet-desk/package.json | 2 +- crates/ksp-app-wallet-desk/tauri.conf.json | 2 +- .../tests/config_composition.rs | 45 ++++++- .../tests/desktop_contract.rs | 14 ++- crates/ksp-config-lib/src/wallet.rs | 4 +- .../composite.ksp-app-wallet-desk.json | 66 +++++++++++ .../unit_tests/fixtures/std.wallet.json | 18 +++ crates/ksp-config-lib/unit_tests/registry.rs | 18 +-- deltas/0.2.6/pre.003-fix.001.md | 89 ++++++++++++++ docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md | 4 +- docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md | 12 +- 18 files changed, 409 insertions(+), 35 deletions(-) create mode 100644 crates/ksp-config-lib/unit_tests/fixtures/composite.ksp-app-wallet-desk.json create mode 100644 crates/ksp-config-lib/unit_tests/fixtures/std.wallet.json create mode 100644 deltas/0.2.6/pre.003-fix.001.md diff --git a/Cargo.toml b/Cargo.toml index 98b40a5..acc4392 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ 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.3" +version = "0.2.6-pre.3.fix.1" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/ROADMAP.md b/ROADMAP.md index 77c69f6..7a76365 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,5 @@ - + # Roadmap KSP @@ -50,7 +50,7 @@ Le roadmap décrit les objectifs à atteindre et les grandes étapes prévues. U - [X] `0.2.3` — HTTP Transactions stable : 11/11 wrappers typés publiés, classification `8 Read / 2 WriteSubmission / 1 Simulation`, no-resend ambigu prouvé pour les write submissions, `KSP-TRANSPORT-007` réaudité conforme sur les 37 wrappers HTTP courants, graphes Cargo et deux smokes Devnet validés ; `0.2.4` reprend les 15 Blocks/Economics restants. - [X] `0.2.4` — HTTP Blocks + Economics stable : 15/15 wrappers `V0_2_4` publiés, surface typed complète à 52/52 méthodes courantes, 14/14 historiques conservées, réaudit SIMD/inventaire final et `KSP-TRANSPORT-007` global validés ; deux smokes Devnet passés avant publication. - [X] `0.2.5` — Wallet foundation stable : `.kspwallet` V1, VIEW/OWNER indépendants, Argon2id/XChaCha20-Poly1305, autorité Ed25519 OWNER, persistence no-clobber, signature, administration/rotations/révocation VIEW forte, import/export Solana CLI JSON + Base58, canaris adversariaux, interop externe et documentation durable publiés. La clôture `pre.010-fix.001`–`fix.003` ajoute `ed25519-dalek 3.0.0` direct, normalise le Rust workspace et installe l’audit structurel Python complémentaire à rustfmt/Clippy. `Pubkey` reste via `ksp-core-lib`, la keypair reste encapsulée dans Wallet et Config/Transport/ExecutionPolicy/Store/Tauri restent hors Wallet. -- [ ] `0.2.6` — Introduire `ksp-app-wallet-desk` utilisant Config composite + Wallet + transport HTTP. `pre.001` fixe le sizing et le gabarit ; `pre.002` matérialise la crate Tauri et son shell splash/main avec Config + Logging bootstrap, ports `1432/1433`, Bootstrap, Font Awesome, DataTables/Select, SimpleBar, resize-observer-polyfill, TS-RS et bridge frontend Logging. `pre.003` matérialise `cfg.std.wallet`/`schema.std.wallet`, le composite `cfg.composite.ksp-app-wallet-desk`, `ResolvedWalletConfig`, `wallets_directory` global + `wallets_subdirectory` par profil et la préparation automatique des répertoires côté application avec logs debug/error. Les tranches suivantes ajoutent inventory, lifecycle VIEW/OWNER, secrets `KSP_SECRET_WALLET_PASS_*`, identité autorisée + `getBalance`, puis administration/import/export, avec une dernière tranche prévue pour README/USAGE/docs/validation, prompt `0.2.7` et build Tauri final. +- [ ] `0.2.6` — Introduire `ksp-app-wallet-desk` utilisant Config composite + Wallet + transport HTTP. `pre.001` fixe le sizing et le gabarit ; `pre.002` matérialise la crate Tauri et son shell splash/main avec Config + Logging bootstrap, ports `1432/1433`, Bootstrap, Font Awesome, DataTables/Select, SimpleBar, resize-observer-polyfill, TS-RS et bridge frontend Logging. `pre.003` matérialise `cfg.std.wallet`/`schema.std.wallet`, le composite `cfg.composite.ksp-app-wallet-desk`, `ResolvedWalletConfig`, `wallets_directory` global + `wallets_subdirectory` par profil et la préparation automatique des répertoires côté application avec logs debug/error. `pre.003-fix.001` corrige les canaris Config révélés par les tests workspace, rend le composite explicite sur un profil Logging `wallet_desk_dev` et active la visibilité trace des interactions frontend Wallet Desk sans exposer les valeurs de contrôles. Les tranches suivantes ajoutent inventory, lifecycle VIEW/OWNER, secrets `KSP_SECRET_WALLET_PASS_*`, identité autorisée + `getBalance`, puis administration/import/export, avec une dernière tranche prévue pour README/USAGE/docs/validation, prompt `0.2.7` et build Tauri final. - [ ] `0.2.7` — Étendre `ksp-onchain-transport-lib` au WebSocket Solana standard complet ; permettre plusieurs sessions sur une même URL sans imposer encore un pool automatique complexe. - [ ] `0.2.8` — Ajouter Helius LaserStream WebSocket comme extension du moteur WebSocket standard, sans duplication de client. - [ ] `0.2.9` — Ajouter une première fondation Yellowstone gRPC standard/provider-neutral ; dimensionner la surface exacte à `pre.001` selon la documentation normative actuelle. diff --git a/config/composite.ksp-app-wallet-desk.json b/config/composite.ksp-app-wallet-desk.json index e81ede7..f8e1953 100644 --- a/config/composite.ksp-app-wallet-desk.json +++ b/config/composite.ksp-app-wallet-desk.json @@ -8,7 +8,7 @@ { "component_id": "logging", "file_id": "cfg.std.logging", - "profile_id": "local_dev" + "profile_id": "wallet_desk_dev" }, { "component_id": "transport", @@ -28,7 +28,7 @@ { "component_id": "logging", "file_id": "cfg.std.logging", - "profile_id": "local_dev" + "profile_id": "wallet_desk_dev" }, { "component_id": "transport", @@ -48,7 +48,7 @@ { "component_id": "logging", "file_id": "cfg.std.logging", - "profile_id": "local_dev" + "profile_id": "wallet_desk_dev" }, { "component_id": "transport", diff --git a/config/examples/composite.ksp-app-wallet-desk.example.json b/config/examples/composite.ksp-app-wallet-desk.example.json index e81ede7..f8e1953 100644 --- a/config/examples/composite.ksp-app-wallet-desk.example.json +++ b/config/examples/composite.ksp-app-wallet-desk.example.json @@ -8,7 +8,7 @@ { "component_id": "logging", "file_id": "cfg.std.logging", - "profile_id": "local_dev" + "profile_id": "wallet_desk_dev" }, { "component_id": "transport", @@ -28,7 +28,7 @@ { "component_id": "logging", "file_id": "cfg.std.logging", - "profile_id": "local_dev" + "profile_id": "wallet_desk_dev" }, { "component_id": "transport", @@ -48,7 +48,7 @@ { "component_id": "logging", "file_id": "cfg.std.logging", - "profile_id": "local_dev" + "profile_id": "wallet_desk_dev" }, { "component_id": "transport", diff --git a/config/std.logging.json b/config/std.logging.json index 93b2f2e..f40ebc6 100644 --- a/config/std.logging.json +++ b/config/std.logging.json @@ -93,6 +93,118 @@ "level": "info" } ] + }, + { + "profile_id": "wallet_desk_dev", + "default_filter": "info", + "span_events": "new_and_close", + "console": { + "enabled": true, + "output": "stderr", + "ansi": true, + "format": "compact", + "filter": { + "level": "trace", + "targets": [ + "ksp-app-wallet-desk" + ], + "domains": [ + "*" + ] + } + }, + "files": [ + { + "output_id": "file.all.info", + "enabled": true, + "path": "info/ksp-info.log", + "rotation": "daily", + "format": "human", + "ansi": false, + "filter": { + "level": "info", + "targets": [ + "*" + ], + "domains": [ + "*" + ] + } + }, + { + "output_id": "file.wallet_desk.trace", + "enabled": true, + "path": "wallet-desk/ksp-app-wallet-desk.log", + "rotation": "daily", + "format": "human", + "ansi": false, + "filter": { + "level": "trace", + "targets": [ + "ksp-app-wallet-desk" + ], + "domains": [ + "*" + ] + } + }, + { + "output_id": "file.onchain_transport.info", + "enabled": true, + "path": "transport/onchain/ksp-onchain-transport.log", + "rotation": "daily", + "format": "human", + "ansi": false, + "filter": { + "level": "info", + "targets": [ + "ksp-onchain-transport-lib" + ], + "domains": [ + "*" + ] + } + }, + { + "output_id": "file.config.error", + "enabled": true, + "path": "config/ksp-config-errors.jsonl", + "rotation": "daily", + "format": "json", + "ansi": false, + "filter": { + "level": "error", + "targets": [ + "ksp-config-lib" + ], + "domains": [ + "config" + ] + } + } + ], + "target_filters": [ + { + "target_prefix": "ksp-app-config-desk", + "level": "info" + }, + { + "target_prefix": "ksp-app-wallet-desk", + "level": "trace" + }, + { + "target_prefix": "ksp-config-lib", + "level": "info" + }, + { + "target_prefix": "ksp-logging-lib", + "level": "info" + }, + { + "target_prefix": "ksp-onchain-transport-lib", + "level": "info" + } + ] } ] } diff --git a/crates/ksp-app-config-desk/unit_tests/profiles.rs b/crates/ksp-app-config-desk/unit_tests/profiles.rs index 5f09000..e53c7c4 100644 --- a/crates/ksp-app-config-desk/unit_tests/profiles.rs +++ b/crates/ksp-app-config-desk/unit_tests/profiles.rs @@ -1,8 +1,8 @@ // file: crates/ksp-app-config-desk/unit_tests/profiles.rs -// version: 5 +// version: 6 #[test] -fn profile_inventory_exposes_registered_standard_profile_documents() { +fn profile_inventory_exposes_registered_profile_documents() { let management = fixture_management(); assert!(management.is_ok(), "fixture management should construct: {management:?}"); if let std::result::Result::Ok(management) = management { @@ -15,6 +15,12 @@ fn profile_inventory_exposes_registered_standard_profile_documents() { assert!(inventory.iter().any(|document| -> bool { return document.file_id == ksp_config_lib::FILE_ID_STD_TRANSPORT; })); + assert!(inventory.iter().any(|document| -> bool { + return document.file_id == ksp_config_lib::FILE_ID_STD_WALLET; + })); + assert!(inventory.iter().any(|document| -> bool { + return document.file_id == ksp_config_lib::FILE_ID_COMPOSITE_KSP_APP_WALLET_DESK; + })); for document in inventory { assert!(!document.default_profile.is_empty()); assert!(document.profile_ids.iter().any(|profile_id| -> bool { diff --git a/crates/ksp-app-wallet-desk/frontend/ts/main.ts b/crates/ksp-app-wallet-desk/frontend/ts/main.ts index f13aa6f..d5907df 100644 --- a/crates/ksp-app-wallet-desk/frontend/ts/main.ts +++ b/crates/ksp-app-wallet-desk/frontend/ts/main.ts @@ -1,5 +1,5 @@ // file: crates/ksp-app-wallet-desk/frontend/ts/main.ts -// version: 2 +// version: 3 import "bootstrap"; import DataTable from "datatables.net-bs5"; @@ -55,6 +55,33 @@ function activateView(viewId: ViewId, source: "startup" | "user"): void { frontendTrace("main", "Wallet Desk view DOM updated", { viewId, source }); } +function bindFrontendInteractions(): void { + document.addEventListener( + "click", + event => { + const source = event.target; + if (!(source instanceof Element)) { + return; + } + const control = source.closest('button, a, input, select, textarea, [role="button"], [role="tab"], [data-view], [data-shell-action]'); + if (!control) { + return; + } + frontendTrace("main", "Frontend control clicked", { + controlId: control.id || null, + controlType: control instanceof HTMLButtonElement ? control.type : null, + disabled: control instanceof HTMLButtonElement ? control.disabled : control.getAttribute("aria-disabled") === "true", + role: control.getAttribute("role"), + shellAction: control.dataset.shellAction ?? null, + tagName: control.tagName.toLowerCase(), + viewId: control.dataset.view ?? null, + }); + }, + true, + ); + frontendTrace("main", "Frontend control interaction logger installed"); +} + function bindNavigation(): void { document.querySelectorAll("[data-view]").forEach(button => { button.addEventListener("click", () => { @@ -159,6 +186,7 @@ function bindShellActions(): void { async function initializeMain(): Promise { const windowLabel = getCurrentWindow().label; frontendInfo("main", "Wallet Desk main frontend loaded", { windowLabel }); + bindFrontendInteractions(); bindNavigation(); bindShellActions(); initializeWalletTable(); diff --git a/crates/ksp-app-wallet-desk/package.json b/crates/ksp-app-wallet-desk/package.json index 4772e19..9c90767 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.3", + "version": "0.2.6-pre.3.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 c383145..97585cd 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.3", + "version": "0.2.6-pre.3.fix.1", "identifier": "com.sasedev.ksp-app-wallet-desk", "build": { "beforeDevCommand": "npm run dev", diff --git a/crates/ksp-app-wallet-desk/tests/config_composition.rs b/crates/ksp-app-wallet-desk/tests/config_composition.rs index 90855cf..e794cf9 100644 --- a/crates/ksp-app-wallet-desk/tests/config_composition.rs +++ b/crates/ksp-app-wallet-desk/tests/config_composition.rs @@ -1,5 +1,5 @@ // file: crates/ksp-app-wallet-desk/tests/config_composition.rs -// version: 1 +// version: 2 //! Config composition contracts introduced for Wallet Desk pre.003. @@ -29,7 +29,8 @@ fn wallet_desk_composite_selects_logging_transport_and_wallet_by_file_id() { assert!(composite.is_ok(), "committed Wallet Desk composite should resolve: {composite:?}"); if let std::result::Result::Ok(composite) = composite { assert_eq!(composite.profile_id(), "devnet"); - assert_component(&composite, "logging", ksp_config_lib::FILE_ID_STD_LOGGING, "local_dev"); + assert_component(&composite, "logging", ksp_config_lib::FILE_ID_STD_LOGGING, "wallet_desk_dev"); + assert_wallet_desk_logging_trace_profile(&composite); assert_component(&composite, "transport", ksp_config_lib::FILE_ID_STD_TRANSPORT, "devnet_public"); assert_component(&composite, "wallet", ksp_config_lib::FILE_ID_STD_WALLET, "default"); } @@ -37,6 +38,46 @@ fn wallet_desk_composite_selects_logging_transport_and_wallet_by_file_id() { } } +fn assert_wallet_desk_logging_trace_profile(composite: &ksp_config_lib::ResolvedConfigComposite) { + let component = composite.component("logging"); + assert!(component.is_some(), "missing logging component"); + if let std::option::Option::Some(component) = component { + let profile = component.resolved().profile(); + assert_eq!(profile.get("default_filter").and_then(serde_json::Value::as_str), std::option::Option::Some("info")); + let console = profile.get("console").and_then(serde_json::Value::as_object); + let console_filter = console + .and_then(|value| { + return value.get("filter"); + }) + .and_then(serde_json::Value::as_object); + let console_level = console_filter + .and_then(|value| { + return value.get("level"); + }) + .and_then(serde_json::Value::as_str); + assert_eq!(console_level, std::option::Option::Some("trace")); + let targets = console_filter + .and_then(|value| { + return value.get("targets"); + }) + .and_then(serde_json::Value::as_array); + assert!(targets.is_some(), "Wallet Desk console targets should exist"); + if let std::option::Option::Some(targets) = targets { + assert!(targets.iter().any(|target| -> bool { + return target.as_str() == std::option::Option::Some("ksp-app-wallet-desk"); + })); + } + let target_filters = profile.get("target_filters").and_then(serde_json::Value::as_array); + assert!(target_filters.is_some(), "Wallet Desk target filters should exist"); + if let std::option::Option::Some(target_filters) = target_filters { + assert!(target_filters.iter().any(|filter| -> bool { + return filter.get("target_prefix").and_then(serde_json::Value::as_str) == std::option::Option::Some("ksp-app-wallet-desk") + && filter.get("level").and_then(serde_json::Value::as_str) == std::option::Option::Some("trace"); + })); + } + } +} + fn assert_component(composite: &ksp_config_lib::ResolvedConfigComposite, component_id: &str, file_id: &str, profile_id: &str) { let component = composite.component(component_id); assert!(component.is_some(), "missing component {component_id}"); diff --git a/crates/ksp-app-wallet-desk/tests/desktop_contract.rs b/crates/ksp-app-wallet-desk/tests/desktop_contract.rs index 493cf65..fbbdc7f 100644 --- a/crates/ksp-app-wallet-desk/tests/desktop_contract.rs +++ b/crates/ksp-app-wallet-desk/tests/desktop_contract.rs @@ -1,5 +1,5 @@ // file: crates/ksp-app-wallet-desk/tests/desktop_contract.rs -// version: 2 +// version: 3 //! Desktop build, shell and Config-status contract audits for Wallet Desk. @@ -85,3 +85,15 @@ fn shell_contains_wallet_navigation_datatable_and_lock_state_icons() { assert!(main.contains("ResizeObserver")); assert!(main.contains("simplebar")); } + +#[test] +fn frontend_control_interactions_are_trace_logged_without_control_values() { + let root = app_root(); + let main = read_text(root.join("frontend/ts/main.ts").as_path()); + assert!(main.contains("bindFrontendInteractions")); + assert!(main.contains("Frontend control clicked")); + assert!(main.contains("[role=\"tab\"]")); + assert!(main.contains("shellAction: control.dataset.shellAction")); + assert!(main.contains("viewId: control.dataset.view")); + assert!(!main.contains("control.value")); +} diff --git a/crates/ksp-config-lib/src/wallet.rs b/crates/ksp-config-lib/src/wallet.rs index 38a9e0a..28f740d 100644 --- a/crates/ksp-config-lib/src/wallet.rs +++ b/crates/ksp-config-lib/src/wallet.rs @@ -1,5 +1,5 @@ // file: crates/ksp-config-lib/src/wallet.rs -// version: 1 +// version: 2 /// Effective standard Wallet configuration resolved from Config. #[derive(Clone, Eq, PartialEq)] @@ -146,7 +146,7 @@ pub(crate) fn validate_wallet_document_contract(document: &crate::ConfigJsonDocu let subdirectory = profile.get("wallets_subdirectory").and_then(serde_json::Value::as_str); if let std::option::Option::Some(value) = subdirectory { let validation = validate_relative_subdirectory(value); - if let std::result::Result::Err(_) = validation { + if validation.is_err() { return std::result::Result::Err( wallet_document_error(document, "wallets_subdirectory must contain only relative normal path components") .with_context("profile_index", profile_index.to_string()), diff --git a/crates/ksp-config-lib/unit_tests/fixtures/composite.ksp-app-wallet-desk.json b/crates/ksp-config-lib/unit_tests/fixtures/composite.ksp-app-wallet-desk.json new file mode 100644 index 0000000..107eaa0 --- /dev/null +++ b/crates/ksp-config-lib/unit_tests/fixtures/composite.ksp-app-wallet-desk.json @@ -0,0 +1,66 @@ +{ + "format_version": 1, + "default_profile": "devnet", + "profiles": [ + { + "profile_id": "devnet", + "documents": [ + { + "component_id": "logging", + "file_id": "cfg.std.logging", + "profile_id": "local_dev" + }, + { + "component_id": "transport", + "file_id": "cfg.std.transport", + "profile_id": "secret_test" + }, + { + "component_id": "wallet", + "file_id": "cfg.std.wallet", + "profile_id": "default" + } + ] + }, + { + "profile_id": "temporary", + "documents": [ + { + "component_id": "logging", + "file_id": "cfg.std.logging", + "profile_id": "local_dev" + }, + { + "component_id": "transport", + "file_id": "cfg.std.transport", + "profile_id": "secret_test" + }, + { + "component_id": "wallet", + "file_id": "cfg.std.wallet", + "profile_id": "temporary" + } + ] + }, + { + "profile_id": "tests", + "documents": [ + { + "component_id": "logging", + "file_id": "cfg.std.logging", + "profile_id": "local_dev" + }, + { + "component_id": "transport", + "file_id": "cfg.std.transport", + "profile_id": "secret_test" + }, + { + "component_id": "wallet", + "file_id": "cfg.std.wallet", + "profile_id": "tests" + } + ] + } + ] +} diff --git a/crates/ksp-config-lib/unit_tests/fixtures/std.wallet.json b/crates/ksp-config-lib/unit_tests/fixtures/std.wallet.json new file mode 100644 index 0000000..950b096 --- /dev/null +++ b/crates/ksp-config-lib/unit_tests/fixtures/std.wallet.json @@ -0,0 +1,18 @@ +{ + "format_version": 1, + "wallets_directory": "${KSP_WALLETS_DIRECTORY:-wallets}", + "default_profile": "default", + "profiles": [ + { + "profile_id": "default" + }, + { + "profile_id": "temporary", + "wallets_subdirectory": "temporary" + }, + { + "profile_id": "tests", + "wallets_subdirectory": "tests" + } + ] +} diff --git a/crates/ksp-config-lib/unit_tests/registry.rs b/crates/ksp-config-lib/unit_tests/registry.rs index 968a2d4..12c042c 100644 --- a/crates/ksp-config-lib/unit_tests/registry.rs +++ b/crates/ksp-config-lib/unit_tests/registry.rs @@ -1,5 +1,5 @@ // file: crates/ksp-config-lib/unit_tests/registry.rs -// version: 7 +// version: 8 #[test] fn descriptors_expose_complete_registry_in_deterministic_file_id_order() { @@ -310,24 +310,24 @@ fn absolute_fixture_path() -> std::path::PathBuf { } #[test] -fn defaults_register_generic_composite_schema_without_runtime_composite() { +fn defaults_register_generic_composite_schema_and_wallet_desk_runtime_composite() { let registry = crate::ConfigFileRegistry::defaults(); let schema_id = crate::ConfigFileId::new(crate::FILE_ID_SCHEMA_COMPOSITE); - let runtime_id = crate::ConfigFileId::new("cfg.composite.ksp-app-wallet-desk"); + let runtime_id = crate::ConfigFileId::new(crate::FILE_ID_COMPOSITE_KSP_APP_WALLET_DESK); assert!(registry.is_ok(), "default registry should be valid: {registry:?}"); assert!(schema_id.is_ok(), "composite schema file_id should be valid: {schema_id:?}"); - assert!(runtime_id.is_ok(), "future composite runtime file_id syntax should be valid: {runtime_id:?}"); + assert!(runtime_id.is_ok(), "Wallet Desk composite runtime file_id should be valid: {runtime_id:?}"); if let (std::result::Result::Ok(registry), std::result::Result::Ok(schema_id), std::result::Result::Ok(runtime_id)) = (registry, schema_id, runtime_id) { let schema = registry.descriptor(&schema_id); let runtime = registry.descriptor(&runtime_id); assert!(schema.is_ok(), "generic composite schema should be registered: {schema:?}"); - assert!(runtime.is_err(), "no fictitious runtime composite should be registered"); - if let std::result::Result::Ok(schema) = schema { + assert!(runtime.is_ok(), "Wallet Desk runtime composite should be registered: {runtime:?}"); + if let (std::result::Result::Ok(schema), std::result::Result::Ok(runtime)) = (schema, runtime) { assert_eq!(schema.kind(), crate::ConfigFileKind::Schema); assert_eq!(schema.filename(), std::path::Path::new(crate::DEFAULT_COMPOSITE_SCHEMA_FILENAME)); - } - if let std::result::Result::Err(error) = runtime { - assert_eq!(error.code(), crate::ERROR_CODE_FILE_ID_UNKNOWN); + assert_eq!(runtime.kind(), crate::ConfigFileKind::Config); + assert_eq!(runtime.filename(), std::path::Path::new(crate::DEFAULT_COMPOSITE_KSP_APP_WALLET_DESK_FILENAME)); + assert_eq!(runtime.schema_file_id(), std::option::Option::Some(&schema_id)); } } } diff --git a/deltas/0.2.6/pre.003-fix.001.md b/deltas/0.2.6/pre.003-fix.001.md new file mode 100644 index 0000000..24fdd24 --- /dev/null +++ b/deltas/0.2.6/pre.003-fix.001.md @@ -0,0 +1,89 @@ + + + +# Delta `0.2.6-pre.003-fix.001` — corrections Config + visibilité Logging frontend + +## Base requise + +```text +0.2.6-pre.003 appliquée +workspace.package.version = 0.2.6-pre.3 +``` + +La validation opérateur de `pre.003` a confirmé `cargo fmt --all`, l'audit structurel, `cargo check --workspace`, `cargo test -p ksp-app-wallet-desk` et le démarrage `cargo tauri dev`. Elle a également révélé un warning Clippy dans l'adapter Wallet, un test registry obsolète et une fixture Config Desk incomplète ; `cargo test -p ksp-config-lib` puis `cargo test --workspace` ne sont donc pas verts sur la livraison initiale. + +## Type de livraison + +```text +ksp-general-0.2.6-pre.003-fix.001.zip +``` + +Le correctif touche Rust, TypeScript et configuration runtime. Conformément à `VER-ID-007`/`VER-ID-010`, la version technique devient : + +```text +workspace.package.version = 0.2.6-pre.3.fix.1 +commit = v0.2.6-pre.003-fix.001 +``` + +## Corrections de validation + +Le warning Clippy `redundant_pattern_matching` de `ksp-config-lib/src/wallet.rs` est corrigé avec `validation.is_err()`. + +Le canari registry historique n'affirme plus qu'aucun runtime composite n'existe : `cfg.composite.ksp-app-wallet-desk` est maintenant un document réellement enregistré et associé à `schema.composite`. + +Les fixtures utilisées par Config Desk sont complétées avec `std.wallet.json` et `composite.ksp-app-wallet-desk.json`. Le test d'inventory vérifie désormais Logging, Transport, Wallet et le composite enregistré au lieu d'échouer sur un fichier fixture absent. + +## Logging composite Wallet Desk + +`cfg.composite.ksp-app-wallet-desk` référençait déjà le composant `logging`. Le correctif rend cette sélection explicite et spécifique à Wallet Desk : + +```text +logging -> cfg.std.logging / wallet_desk_dev +``` + +Le profil `wallet_desk_dev` ajouté à `std.logging.json` conserve le niveau global KSP à `info`, mais ouvre `ksp-app-wallet-desk` à `trace`. La console est routée à `trace` uniquement pour ce target prefix et un fichier dédié `wallet-desk/ksp-app-wallet-desk.log` reçoit également les événements `trace`. Les profils `devnet`, `temporary` et `tests` du composite utilisent tous ce profil Logging. + +Cette configuration est volontairement orientée développement de Wallet Desk afin de rendre immédiatement observables les actions frontend sans rendre tous les targets KSP globalement verbeux. Elle pourra être resserrée plus tard sans modifier le bridge. + +## Instrumentation frontend + +Le bridge existant `frontend -> emit_frontend_log -> ksp-logging-lib` est conservé. `main.ts` ajoute un listener de capture générique pour les contrôles interactifs : + +```text +button +a +input / select / textarea +[role=button] / [role=tab] +[data-view] +[data-shell-action] +``` + +Chaque clic produit un événement `trace` `Frontend control clicked` avec uniquement des métadonnées techniques sûres : tag, id, type, rôle, état disabled, `data-view` et `data-shell-action`. Le texte et la valeur du contrôle ne sont pas sérialisés ; cela évite de créer plus tard une fuite de password ou d'autre donnée sensible lorsque les formulaires Wallet seront ajoutés. Les logs sémantiques spécifiques (`navigation activated`, actions shell, IPC) restent en complément. + +## Dépendances + +Aucune dépendance Cargo ou npm n'est ajoutée/modifiée. `package.json` et `tauri.conf.json` changent uniquement leur version applicative vers `0.2.6-pre.3.fix.1`. Aucune commande npm directe n'est requise. + +## Validation opérateur requise + +Après application : + +```bash +cargo fmt --all +python3 scripts/audit_rust_workspace_rules.py +cargo check --workspace +cargo clippy --workspace --all-targets +cargo test -p ksp-config-lib +cargo test -p ksp-app-config-desk +cargo test -p ksp-app-wallet-desk +cargo test --workspace +KSP_WALLETS_DIRECTORY=var/wallet-desk-pre003 cargo tauri dev -c crates/ksp-app-wallet-desk/tauri.conf.json +``` + +Dans l'application, cliquer sur les boutons de navigation et les contrôles du shell doit produire des événements `TRACE` sous `ksp-app-wallet-desk.frontend.main` visibles dans la console et dans le fichier de log Wallet Desk du lancement. Aucun password/value de contrôle ne doit apparaître. + +`cargo tauri build -c crates/ksp-app-wallet-desk/tauri.conf.json` reste exclu de ce fix et réservé à la toute dernière validation de `0.2.6`. + +## Suite + +Après validation de ce fix, `pre.004` peut brancher l'inventory réel `.kspwallet` sur la base Config/Logging désormais cohérente. diff --git a/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md b/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md index dbcd69c..c058899 100644 --- a/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md +++ b/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md @@ -1,5 +1,5 @@ - + # Séquence des releases fonctionnelles KSP @@ -430,7 +430,7 @@ Le prompt [`../../prompts/011-V0_2_6_START_PROMPT.md`](../../prompts/011-V0_2_6_ `0.2.6-pre.001` confirme que le registre Config doit être étendu pour `cfg.std.wallet`/`schema.std.wallet` et `cfg.composite.ksp-app-wallet-desk`. `wallets_directory` reste global avec fallback `${KSP_WALLETS_DIRECTORY:-wallets}` et chaque profil peut définir un `wallets_subdirectory` relatif pour isoler tests, temporaires ou futurs scénarios. Wallet Desk prépare/crée le répertoire effectif après résolution Config et journalise le succès en debug ou l'échec en error. Le gabarit Config Desk est réutilisé avec Bootstrap, Font Awesome, DataTables/Select, SimpleBar et `resize-observer-polyfill`. L'inventory reste non récursive `.kspwallet`, sans symlink d'entrée et root-scoped; les handles VIEW/OWNER restent exclusivement côté Rust. L'ouverture accepte un password éphémère saisi ou une tentative explicite de secrets Config `KSP_SECRET_WALLET_PASS_*`, dont ni nom ni valeur ne traversent le frontend. `getBalance` utilise la Pubkey du handle autorisé et les flows OWNER metadata/rotations/revocation/export fichier délèguent à Wallet. La CSP reste `null` par défaut comme dans Config Desk et n'est réauditée qu'en présence d'un besoin WebView concret. Le forecast souple détaillé s'étend jusqu'à `pre.014`, dernière tranche prévue pour README/USAGE/docs/validation, prompt `0.2.7` et build Tauri final; le plan actif est `docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md`. -`0.2.6-pre.002` matérialise le shell Tauri spécialisé. `0.2.6-pre.003` matérialise ensuite la première composition Config propre à Wallet Desk : `cfg.std.wallet`/`schema.std.wallet`, le composite `cfg.composite.ksp-app-wallet-desk`, `ResolvedWalletConfig`, la racine `${KSP_WALLETS_DIRECTORY:-wallets}`, les sous-répertoires de profils `temporary`/`tests`, la préservation de provenance `Composite` dans les adapters Logging/Wallet et la création sûre des répertoires par l’application. Aucun inventory ou fichier `.kspwallet` n’est encore ouvert dans cette tranche. +`0.2.6-pre.002` matérialise le shell Tauri spécialisé. `0.2.6-pre.003` matérialise ensuite la première composition Config propre à Wallet Desk : `cfg.std.wallet`/`schema.std.wallet`, le composite `cfg.composite.ksp-app-wallet-desk`, `ResolvedWalletConfig`, la racine `${KSP_WALLETS_DIRECTORY:-wallets}`, les sous-répertoires de profils `temporary`/`tests`, la préservation de provenance `Composite` dans les adapters Logging/Wallet et la création sûre des répertoires par l’application. Aucun inventory ou fichier `.kspwallet` n’est encore ouvert dans cette tranche. `0.2.6-pre.003-fix.001` corrige ensuite les tests de registry/fixtures devenus obsolètes, sélectionne le profil Logging composite `wallet_desk_dev` avec trace ciblée `ksp-app-wallet-desk`, et instrumente les clics frontend génériques sans sérialiser la valeur des contrôles. ## `0.2.7` — WebSocket Solana standard 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 def1558..ba7331a 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 @@ -23,7 +23,7 @@ Les validations opérateur du `2026-08-20` ont ensuite confirmé la base `pre.00 `0.2.6-pre.002` matérialise ensuite la première tranche technique : la crate `ksp-app-wallet-desk` rejoint le workspace avec le shell splash/main du gabarit Config Desk, le bootstrap Config + Logging commun, les ports `1432/1433`, Bootstrap, Font Awesome, DataTables/Select, SimpleBar, `resize-observer-polyfill`, TS-RS et le bridge frontend -> Rust -> `ksp-logging-lib`. Cette tranche ne branche encore ni `std.wallet`, ni inventory filesystem réel, ni `ksp-wallet-lib`, ni Transport : ces responsabilités restent dans les prereleases déjà dimensionnées. -`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é. +`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 sélectionne un profil Logging composite `wallet_desk_dev` qui rend visibles les événements `trace` de `ksp-app-wallet-desk`; les clics frontend sur boutons/navigation/tabs sont instrumentés avec des métadonnées techniques sans valeur de contrôle. ## 2. Sources relues et hiérarchie appliquée @@ -367,7 +367,7 @@ Shape de référence : { "profile_id": "devnet", "documents": [ - {"component_id": "logging", "file_id": "cfg.std.logging"}, + {"component_id": "logging", "file_id": "cfg.std.logging", "profile_id": "wallet_desk_dev"}, {"component_id": "transport", "file_id": "cfg.std.transport", "profile_id": "devnet_public"}, {"component_id": "wallet", "file_id": "cfg.std.wallet", "profile_id": "default"} ] @@ -375,7 +375,7 @@ Shape de référence : { "profile_id": "tests", "documents": [ - {"component_id": "logging", "file_id": "cfg.std.logging"}, + {"component_id": "logging", "file_id": "cfg.std.logging", "profile_id": "wallet_desk_dev"}, {"component_id": "transport", "file_id": "cfg.std.transport", "profile_id": "devnet_public"}, {"component_id": "wallet", "file_id": "cfg.std.wallet", "profile_id": "tests"} ] @@ -1255,12 +1255,14 @@ wallets_subdirectory optionnel, relatif et multi-composants normaux profils default / temporary / tests ResolvedWalletConfig avec root/subdirectory/effective path/provenance resolve_logging_config_profile / resolve_wallet_config_profile pour profils composites -cfg.composite.ksp-app-wallet-desk = logging + transport + wallet +cfg.composite.ksp-app-wallet-desk = logging(wallet_desk_dev) + transport + wallet .env.example documente KSP_WALLETS_DIRECTORY et le pattern futur KSP_SECRET_WALLET_PASS_* bootstrap Wallet Desk valide les trois component_id/file_id requis création automatique du root et du sous-répertoire effectif absents rejet d'un root non-directory et d'un composant de sous-répertoire symlink/non-directory debug sur répertoires prêts/créés ; error sur préparation impossible +profil Logging wallet_desk_dev : target ksp-app-wallet-desk à trace, console et fichier dédiés +trace frontend metadata-only sur clics boutons/navigation/tabs et actions shell status DTO/UI : profil composite, profils Logging/Wallet, root/subdirectory/effective directory ```