v0.2.6-pre.003-fix.001

This commit is contained in:
2026-08-20 21:23:09 +02:00
parent f9f9ac79b6
commit 0e72914237
18 changed files with 409 additions and 35 deletions

View File

@@ -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"

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md -->
<!-- version: 59 -->
<!-- version: 60 -->
# 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 laudit 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.

View File

@@ -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",

View File

@@ -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",

View File

@@ -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"
}
]
}
]
}

View File

@@ -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 {

View File

@@ -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<HTMLElement>('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<HTMLButtonElement>("[data-view]").forEach(button => {
button.addEventListener("click", () => {
@@ -159,6 +186,7 @@ function bindShellActions(): void {
async function initializeMain(): Promise<void> {
const windowLabel = getCurrentWindow().label;
frontendInfo("main", "Wallet Desk main frontend loaded", { windowLabel });
bindFrontendInteractions();
bindNavigation();
bindShellActions();
initializeWalletTable();

View File

@@ -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",

View File

@@ -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",

View File

@@ -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}");

View File

@@ -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"));
}

View File

@@ -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()),

View File

@@ -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"
}
]
}
]
}

View File

@@ -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"
}
]
}

View File

@@ -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));
}
}
}

View File

@@ -0,0 +1,89 @@
<!-- file: deltas/0.2.6/pre.003-fix.001.md -->
<!-- version: 1 -->
# 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.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 58 -->
<!-- version: 59 -->
# 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 lapplication. Aucun inventory ou fichier `.kspwallet` nest 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 lapplication. Aucun inventory ou fichier `.kspwallet` nest 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

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md -->
<!-- version: 6 -->
<!-- version: 7 -->
# 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` nest 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` nest 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
```