Files
khadhroony-solana-project/deltas/0.2.6/pre.004.md
2026-08-20 23:01:41 +02:00

181 lines
5.6 KiB
Markdown

<!-- file: deltas/0.2.6/pre.004.md -->
<!-- version: 1 -->
# Delta `0.2.6-pre.004` — inventory `.kspwallet` et inspection locked
## Base requise
```text
0.2.6-pre.003-fix.004 appliquée
workspace.package.version = 0.2.6-pre.3.fix.4
```
Les preuves opérateur de `pre.003-fix.004` sont vertes : `cargo fmt --all`, audit structurel Python, `cargo check --workspace`, `cargo clippy --workspace --all-targets`, `cargo test -p ksp-app-config-desk`, `cargo test --workspace` et `cargo tauri dev -c crates/ksp-app-wallet-desk/tauri.conf.json`. Le runtime utilise le profil composite Logging `supertrace` et démarre correctement.
## Type de livraison
```text
ksp-general-0.2.6-pre.004.zip
```
Cette tranche ajoute une dépendance interne Wallet et du runtime Rust/frontend ; le signal technique devient :
```text
workspace.package.version = 0.2.6-pre.4
commit = v0.2.6-pre.004
```
Aucun tag stable.
## Objet
Brancher l'inventory réel des fichiers natifs `.kspwallet` dans Wallet Desk sans introduire encore de password, de handle VIEW/OWNER ni de projection d'identité protégée.
## Frontière Wallet
`ksp-app-wallet-desk` dépend désormais directement de `ksp-wallet-lib` et délègue l'inspection locked à :
```text
ksp_wallet_lib::inspect_locked_wallet_file_v1
```
Aucune crypto, parser `.kspwallet`, keypair ou signature n'est réimplémenté dans l'application.
## Inventory filesystem
La racine unique est :
```text
ResolvedWalletConfig::effective_wallets_directory
```
Politique :
```text
read_dir asynchrone non récursif
filename UTF-8
suffixe exact .kspwallet
un seul composant filename
slash et backslash rejetés pour les sélections frontend
fichiers réguliers uniquement
symlinks d'entrée exclus
répertoires même nommés *.kspwallet exclus
tri déterministe par filename
```
Le bootstrap Config durcit aussi la racine globale : un `wallets_directory` existant sous forme de symlink est désormais refusé au lieu d'être suivi par `metadata()`.
Une erreur de lecture de la racine fait échouer la commande avec `wallet_desk.wallet_inventory_failed`. Une entrée `.kspwallet` présente mais invalide ne fait pas échouer tout l'inventory : elle reste visible avec état `error`, inspection `invalid` et `CommandErrorDto` sans context/source.
## DTOs locked
La tranche ajoute :
```text
WalletInventoryEntryDto
WalletInventoryStateDto
WalletInspectionStatusDto
LockedWalletDto
WalletSelectionRequestDto
```
Une ligne valide expose uniquement :
```text
wallet_id / filename
format_version
view_enabled
state = locked
inspection_status = valid
```
Une ligne invalide expose filename + diagnostic sûr. Aucun DTO ne porte Pubkey, alias, notes, password, path complet ou handle Wallet.
## Commandes Tauri
```text
list_wallets
refresh_wallets
select_wallet
```
`select_wallet` reçoit uniquement un `wallet_id`/filename, reconstruit le path sous la racine effective, rejette traversal/séparateurs/symlink/non-file puis relance l'inspection locked avant de répondre. La sélection n'installe pas encore un `WalletSession` durable ; celui-ci reste `pre.005`.
## Frontend
Le tableau Wallet devient un vrai DataTable alimenté par le backend :
```text
État -> fa-lock ou fa-triangle-exclamation
Filename -> texte DOM sûr
Format -> version ou —
VIEW -> enabled / disabled / —
Inspection -> Valide ou code diagnostic sûr
```
Le bouton Refresh appelle `refresh_wallets`. La sélection d'une ligne valide appelle `select_wallet` et affiche seulement filename/format/VIEW dans la carte « Wallet courant ». Les lignes invalides restent visibles mais ne sont pas sélectionnables. Un refresh purge la projection sélectionnée frontend afin de ne pas conserver une vue stale.
Le rendu utilise `textContent`/création DOM pour les valeurs issues du filesystem ; aucun filename n'est injecté par HTML.
## Logging
Les opérations suivantes sont instrumentées :
```text
inventory refresh start/completion
invalid locked inspection
non-regular/symlink skip
selection accepted/rejected
frontend inventory load/render/refresh/row selection
```
Le profil composite reste `supertrace`; aucun changement de `std.logging` n'est requis.
## Tests
Les canaris ajoutés couvrent :
```text
valid .kspwallet + invalid .kspwallet dans le même inventory
wrong extension ignorée
subdirectory *.kspwallet ignoré
tri déterministe
traversal slash/backslash rejeté
symlink Wallet ignoré et non sélectionnable sur Unix
root wallets_directory symlink rejeté sur Unix
DTO locked sans Pubkey/alias/notes/password
commands Tauri list/refresh/select présentes
frontend DataTable réellement branché sur les DTOs Wallet
```
## Dépendances
Cargo :
```text
ksp-wallet-lib = { path = "../ksp-wallet-lib" }
tokio features += fs, rt
```
Aucune dépendance npm et aucun script npm ne changent. **Aucune commande npm directe n'est nécessaire pour cette tranche.**
## 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-pre004 cargo tauri dev -c crates/ksp-app-wallet-desk/tauri.conf.json
```
Pour la vérification UI, placer si souhaité un ou plusieurs `.kspwallet` existants dans `var/wallet-desk-pre004`, ainsi qu'un fichier `invalid.kspwallet` non valide, puis tester recherche/tri, Refresh et sélection des lignes valides.
Toujours aucun `cargo tauri build` à ce stade.
## Suite
Après validation de `pre.004`, `pre.005` introduira la création de Wallet et le lifecycle/session Rust sans avancer encore la balance HTTP.