v0.2.5-pre.010

This commit is contained in:
2026-08-20 09:58:14 +02:00
parent e91bf36e9e
commit 5bf9651038
15 changed files with 1363 additions and 43 deletions

View File

@@ -1,5 +1,5 @@
# file: Cargo.toml
# version: 158
# version: 159
[workspace]
resolver = "3"
@@ -16,7 +16,7 @@ publish = false
[workspace.dependencies]
argon2 = { version = "^0.5", default-features = false }
chacha20poly1305 = { version = "^0.11", default-features = false }
ed25519-dalek = { version = "^2.2", default-features = false }
ed25519-dalek = { version = "^3.0", default-features = false }
getrandom = { version = "^0.4", default-features = false }
base64 = { version = "^0.23" }
fs2 = { version = "^0.4" }

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md -->
<!-- version: 52 -->
<!-- version: 53 -->
# Roadmap KSP
@@ -49,8 +49,8 @@ Le roadmap décrit les objectifs à atteindre et les grandes étapes prévues. U
- [X] `0.2.2` — HTTP Accounts + Tokens + Cluster : 22 wrappers typés (5 Accounts + 5 Tokens + 12 Cluster), canaries de complétude 52+14, smoke Devnet Transport pur et smoke historique Config -> Transport validés, documentation durable et prompt `0.2.3` publiés stables.
- [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.
- [/] `0.2.5` — Wallet foundation : `pre.001` fixe threat model/format autonome ; `pre.002` crée la crate et les capabilities ; `pre.003` fige wire/transcript/AAD ; `pre.004` ajoute Argon2id/XChaCha20-Poly1305/CSPRNG ; `pre.005` fixe defaults benchmarkés, payloads, autorité Ed25519 et create/open ; `pre.006` ajoute persistence no-clobber ; `pre.007` ajoute signature Solana, administration, rotations et révocation forte VIEW ; `pre.008` ajoute inspection/import/export Solana CLI JSON + keypair Base58 complet ; `pre.009` clôt maintenant l'audit adversarial/security/interoperability/compliance et le graphe Cargo. `Pubkey` reste via `ksp-core-lib`, la keypair reste encapsulée dans Wallet et Config/Transport/ExecutionPolicy/Store/Tauri restent hors Wallet. `pre.010` = documentation finale/README/USAGE/prompt Wallet Desk.
- [ ] `0.2.6` — Introduire `ksp-app-wallet-desk` utilisant Config composite + Wallet + transport HTTP, notamment pour afficher l'identité et le solde d'un wallet.
- [/] `0.2.5` — Wallet foundation : `pre.001``pre.009` ont livré puis audité `.kspwallet` V1, VIEW/OWNER, crypto, persistence, administration, signature et transfer ; `pre.010` finalise maintenant README/USAGE, spec, graphes, matrice de clôture et prompt Wallet Desk sans changement de code/Cargo. `Pubkey` reste via `ksp-core-lib`, la keypair reste encapsulée dans Wallet et Config/Transport/ExecutionPolicy/Store/Tauri restent hors Wallet. La candidate est prête pour `rel.001` après validation documentaire/opérateur finale.
- [ ] `0.2.6` — Introduire `ksp-app-wallet-desk` utilisant Config composite + Wallet + transport HTTP, notamment pour afficher l'identité et le solde d'un wallet ; le prompt de démarrage est préparé par `0.2.5-pre.010`.
- [ ] `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

@@ -0,0 +1,192 @@
<!-- file: crates/ksp-wallet-lib/README.md -->
<!-- version: 1 -->
# `ksp-wallet-lib`
`ksp-wallet-lib` est la bibliothèque KSP propriétaire du Wallet Solana natif. Elle possède le format autonome `.kspwallet` V1, les capacités indépendantes VIEW/OWNER, la protection du secret Solana, la signature, l'administration des metadata, les rotations de credentials, la persistence native et les adapters d'import/export explicitement supportés.
La crate est volontairement indépendante de Config, du réseau et de Tauri. Un consumer fournit les chemins, passwords et metadata ; Wallet ouvre, protège, signe et persiste sans décider d'une policy de dépense ni contacter un RPC.
## Responsabilités
La crate possède :
- le format natif `.kspwallet` V1 et son parser JSON strict ;
- les key slots OWNER/VIEW indépendants ;
- Argon2id pour les KDF de passwords ;
- XChaCha20-Poly1305 pour le wrapping et les compartiments ;
- une autorité Ed25519 d'administration distincte de la keypair Solana ;
- les compartiments `owner_control`, `metadata` et `secret` ;
- la création et l'ouverture in-memory ;
- la création et l'ouverture fichier async-first ;
- la projection verrouillée minimale ;
- la signature Solana via OWNER sans getter secret ;
- l'alias et les notes protégés ;
- les rotations OWNER/VIEW ;
- la révocation forte VIEW par OWNER ;
- la persistence create/import no-clobber ;
- le remplacement administratif capability-bound avec détection de handle stale ;
- l'inspection/import/export Solana CLI JSON et Base58 de keypair complète ;
- les diagnostics et erreurs Wallet sans exposition de secrets.
La crate ne possède pas :
```text
Config
Transport HTTP/WebSocket/gRPC
balance/réseau
WalletPolicy / execution policy
construction ou envoi de transaction
Store
Tauri/UI
hardware wallet / remote signer
anti-rollback externe
```
## Frontières de dépendances
La direction de production est :
```text
ksp-wallet-lib
-> ksp-core-lib
-> ksp-logging-lib
-> argon2 / chacha20poly1305 / getrandom
-> ed25519-dalek / solana-keypair
-> serde / serde_json
-> tempfile / tokio
-> zeroize
```
Les dépendances suivantes sont interdites :
```text
ksp-wallet-lib -X-> ksp-config-lib
ksp-wallet-lib -X-> ksp-onchain-transport-lib
ksp-wallet-lib -X-> execution policy
ksp-wallet-lib -X-> Store
ksp-wallet-lib -X-> Tauri
ksp-wallet-lib -X-> tracing direct
ksp-wallet-lib -X-> std::env
ksp-wallet-lib -X-> solana-pubkey direct
ksp-wallet-lib -X-> solana-signer direct
ksp-wallet-lib -X-> solana-signature direct
```
La Pubkey publique est toujours `ksp_core_lib::Pubkey`. `solana-keypair` reste un détail secret/signing interne à Wallet et n'est pas réexportée.
## Modèle de capacités
### Verrouillé
Sans password, `inspect_locked_wallet_v1` et `inspect_locked_wallet_file_v1` exposent uniquement :
```text
format_version
view_enabled
```
La Pubkey, l'alias et les notes restent chiffrés.
### VIEW
`WalletView` expose :
```text
Pubkey
alias
notes
rotation de son propre password VIEW
```
VIEW ne possède aucune API de signature, d'export secret, de mutation metadata, de rotation OWNER ou de désactivation/recréation VIEW.
### OWNER
`WalletOwner` expose toutes les metadata autorisées et ajoute :
```text
signature Solana
export du secret via adapters explicites
alias/notes administration
rotation OWNER
rotation VIEW sans ancien password VIEW
disable VIEW avec rekey metadata fort
recreate VIEW avec nouveau slot et nouveau K_metadata
```
OWNER ne dépend jamais du password VIEW.
## Format `.kspwallet` V1
Le format est publiquement spécifié dans [`../../docs/formats/KSPWALLET_V1.md`](../../docs/formats/KSPWALLET_V1.md). Il est autonome : un fichier valide et le password de la capacité concernée suffisent à l'ouverture ; aucun pepper KSP, keychain, OTP, service distant, réseau ou secret externe n'est requis.
Les principales primitives sont :
```text
KDF Argon2id v19
profil création 65 536 KiB / 3 iterations / 1 lane
AEAD XChaCha20-Poly1305
CSPRNG OS via getrandom
state signature Ed25519
wire binary Base64url sans padding
format JSON UTF-8 strict
```
Les paramètres KDF sont sérialisés dans chaque slot afin que de futurs defaults puissent évoluer sans rendre les wallets existants illisibles.
## Persistence
Toute création/import reçoit un chemin explicite du caller et applique le no-clobber. Wallet ne découvre ni ne crée un répertoire configuré par lui-même.
Les mutations OWNER/VIEW persistées utilisent un remplacement capability-bound : le fichier courant doit encore correspondre à l'enveloppe authentifiée attendue par le handle. Un handle stale ou une mauvaise cible retourne `wallet.state_conflict`.
Cette protection ne constitue pas un CAS filesystem linéarisable et ne fournit pas d'anti-rollback externe. Les garanties d'atomicité/crash-durability dépendent également de l'OS et du filesystem.
## Import/export
Les formats built-in V1 sont :
```text
WalletTransferFormat::SolanaCliJson
WalletTransferFormat::SolanaKeypairBase58
```
L'inspection d'un transfert retourne seulement sa Pubkey et son format. L'import crée toujours un nouveau `.kspwallet` no-clobber autour de la keypair validée. L'export secret appartient uniquement à `WalletOwner`.
`WalletTransferFormat` est `#[non_exhaustive]` afin de permettre des formats built-in supplémentaires sans prétendre fournir un plugin public arbitraire de codec secret.
## Sécurité et limites
Le threat model V1 considère notamment un attaquant possédant une copie complète du fichier et capable d'essais de password offline sans limite serveur. Argon2id augmente le coût de chaque essai ; il ne compense pas un password faible.
Limites explicitement assumées :
- remplacement total par un autre wallet valide non détectable depuis le nouveau fichier seul ;
- rollback vers une ancienne copie valide non détectable sans état/ancre externe ;
- absence de second facteur, keychain, hardware wallet ou remote signer en V1 ;
- `zeroize` réduit les copies possédées mais ne prouve pas l'effacement physique de toute copie potentielle ;
- les permissions filesystem sont une hygiène externe, pas une garantie cryptographique.
La matrice durable [`../../docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](../../docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) enregistre les canaris adversariaux, l'interop indépendante et l'audit Cargo.
## Tests et vecteurs
Les fixtures publiques test-only sont sous `tests/fixtures/` :
```text
kspwallet_v1_wire_only.json
kspwallet_v1_crypto_vectors.json
kspwallet_v1_full_vector.json
kspwallet_v1_full_vector_meta.json
```
Elles couvrent le wire, Argon2id/XChaCha20-Poly1305, l'ouverture VIEW/OWNER, la signature d'état et l'interop transfer. Les tests adversariaux couvrent tampering, wrong passwords, frontières VIEW/OWNER, persistence, concurrence et diagnostics secrets.
## Documentation
- [`USAGE.md`](USAGE.md) — exemples des principales surfaces publiques ;
- [`../../docs/formats/KSPWALLET_V1.md`](../../docs/formats/KSPWALLET_V1.md) — spécification normative indépendante de Rust ;
- [`../../docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](../../docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md) — plan historique et threat model de `0.2.5` ;
- [`../../docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](../../docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) — matrice de sécurité/interoperabilité/compliance ;
- [`../../prompts/011-V0_2_6_START_PROMPT.md`](../../prompts/011-V0_2_6_START_PROMPT.md) — reprise vers Wallet Desk après publication stable de `0.2.5`.

View File

@@ -0,0 +1,279 @@
<!-- file: crates/ksp-wallet-lib/USAGE.md -->
<!-- version: 2 -->
# Utilisation de `ksp-wallet-lib`
Ce guide présente les principales surfaces publiques de Wallet V1. La spécification cryptographique du fichier reste [`../../docs/formats/KSPWALLET_V1.md`](../../docs/formats/KSPWALLET_V1.md).
Les exemples utilisent des chemins explicites : Wallet ne lit ni Config ni environnement pour découvrir un répertoire.
## 1. Créer un nouveau `.kspwallet`
```rust
async fn create_example() -> ksp_core_lib::Result<()> {
let metadata = ksp_wallet_lib::WalletCreateMetadataV1::new(
Some(std::string::String::from("devnet-main")),
vec![std::string::String::from("wallet de test")],
);
let owner_password = ksp_wallet_lib::OwnerPassword::new(std::string::String::from("OWNER-PASSWORD"));
let view_password = ksp_wallet_lib::ViewPassword::new(std::string::String::from("VIEW-PASSWORD"));
let created = ksp_wallet_lib::create_wallet_file_v1(
"wallets/devnet-main.kspwallet",
owner_password,
Some(view_password),
metadata,
)
.await;
let owner = match created {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("{}", owner.pubkey());
return Ok(());
}
```
La destination doit avoir un parent existant. Une destination existante n'est jamais remplacée par une création.
Pour créer uniquement en mémoire, utiliser `create_wallet_v1` puis `WalletOwner::to_json_bytes()` si le caller possède lui-même une autre boundary de stockage.
## 2. Inspecter un wallet verrouillé
```rust
async fn inspect_example() -> ksp_core_lib::Result<()> {
let inspected = ksp_wallet_lib::inspect_locked_wallet_file_v1("wallets/devnet-main.kspwallet").await;
let locked = match inspected {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("format={}", locked.format_version());
println!("view_enabled={}", locked.view_enabled());
return Ok(());
}
```
Cette projection ne contient volontairement ni Pubkey, ni alias, ni notes.
## 3. Ouvrir avec VIEW
```rust
async fn open_view_example() -> ksp_core_lib::Result<()> {
let password = ksp_wallet_lib::ViewPassword::new(std::string::String::from("VIEW-PASSWORD"));
let opened = ksp_wallet_lib::open_wallet_view_file_v1("wallets/devnet-main.kspwallet", password).await;
let mut view = match opened {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("pubkey={}", view.pubkey());
println!("alias={:?}", view.alias());
for note in view.notes() {
println!("note={} text={}", note.id(), note.text());
}
let rotated = view
.rotate_view_password(
"wallets/devnet-main.kspwallet",
ksp_wallet_lib::ViewPassword::new(std::string::String::from("NEW-VIEW-PASSWORD")),
)
.await;
if let Err(error) = rotated {
return Err(error);
}
return Ok(());
}
```
VIEW ne possède aucune API `sign`, `export_transfer`, `update_alias`, `add_note`, `rotate_owner_password`, `disable_view` ou `recreate_view`.
## 4. Ouvrir avec OWNER et signer
```rust
async fn sign_example(message: &[u8]) -> ksp_core_lib::Result<[u8; ksp_wallet_lib::KSPWALLET_SOLANA_SIGNATURE_BYTES]> {
let password = ksp_wallet_lib::OwnerPassword::new(std::string::String::from("OWNER-PASSWORD"));
let opened = ksp_wallet_lib::open_wallet_owner_file_v1("wallets/devnet-main.kspwallet", password).await;
let owner = match opened {
Ok(value) => value,
Err(error) => return Err(error),
};
return owner.sign(message);
}
```
La signature retournée contient 64 octets Ed25519. Aucun getter public ne retourne la keypair Solana.
## 5. Administrer alias et notes
```rust
async fn metadata_example() -> ksp_core_lib::Result<()> {
let password = ksp_wallet_lib::OwnerPassword::new(std::string::String::from("OWNER-PASSWORD"));
let opened = ksp_wallet_lib::open_wallet_owner_file_v1("wallets/devnet-main.kspwallet", password).await;
let mut owner = match opened {
Ok(value) => value,
Err(error) => return Err(error),
};
let alias_result = owner
.update_alias("wallets/devnet-main.kspwallet", Some(std::string::String::from("primary-devnet")))
.await;
if let Err(error) = alias_result {
return Err(error);
}
let added = owner
.add_note("wallets/devnet-main.kspwallet", std::string::String::from("rotation trimestrielle"))
.await;
let note_id = match added {
Ok(value) => value,
Err(error) => return Err(error),
};
let updated = owner
.update_note(
"wallets/devnet-main.kspwallet",
note_id.as_str(),
std::string::String::from("rotation contrôlée"),
)
.await;
if let Err(error) = updated {
return Err(error);
}
return Ok(());
}
```
Chaque mutation vérifie que le fichier courant correspond encore à l'état authentifié attendu par le handle. Un handle stale reçoit `wallet.state_conflict`.
## 6. Rotations de credentials
OWNER peut changer son password :
```rust
let result = owner
.rotate_owner_password(
"wallets/devnet-main.kspwallet",
ksp_wallet_lib::OwnerPassword::new(std::string::String::from("NEW-OWNER-PASSWORD")),
)
.await;
```
OWNER peut aussi changer le password VIEW sans connaître l'ancien :
```rust
let result = owner
.rotate_view_password(
"wallets/devnet-main.kspwallet",
ksp_wallet_lib::ViewPassword::new(std::string::String::from("NEW-VIEW-PASSWORD")),
)
.await;
```
Ces rotations de credentials ne changent pas la keypair Solana.
## 7. Révocation forte VIEW
La simple rotation VIEW remplace le credential courant mais ne peut pas retirer des metadata déjà connues d'un ancien détenteur VIEW. OWNER peut effectuer une révocation forte pour les metadata futures :
```rust
let disabled = owner.disable_view("wallets/devnet-main.kspwallet").await;
if let Err(error) = disabled {
return Err(error);
}
let recreated = owner
.recreate_view(
"wallets/devnet-main.kspwallet",
ksp_wallet_lib::ViewPassword::new(std::string::String::from("FRESH-VIEW-PASSWORD")),
)
.await;
```
`disable_view` rekey les metadata. `recreate_view` crée ensuite un nouveau slot VIEW autour du nouveau `K_metadata`. La keypair Solana reste inchangée.
## 8. Inspecter et importer une keypair externe
Le format doit être choisi explicitement ; Wallet ne fait pas d'auto-détection heuristique.
```rust
async fn inspect_transfer_example(source: &[u8]) -> ksp_core_lib::Result<()> {
let inspected = ksp_wallet_lib::inspect_wallet_transfer(
source,
ksp_wallet_lib::WalletTransferFormat::SolanaCliJson,
);
let info = match inspected {
Ok(value) => value,
Err(error) => return Err(error),
};
println!("{}", info.pubkey());
return Ok(());
}
```
Import fichier vers un nouveau `.kspwallet` :
```rust
let imported = ksp_wallet_lib::import_wallet_transfer_file_v1(
"wallets/imported.kspwallet",
"wallets/legacy-id.json",
ksp_wallet_lib::WalletTransferFormat::SolanaCliJson,
ksp_wallet_lib::OwnerPassword::new(std::string::String::from("OWNER-PASSWORD")),
None,
ksp_wallet_lib::WalletCreateMetadataV1::new(Some(std::string::String::from("imported")), vec![]),
)
.await;
```
L'import valide la cohérence secret/public, conserve exactement la keypair Solana et génère un nouvel environnement cryptographique KSP. Une destination native existante n'est jamais écrasée.
## 9. Exporter avec OWNER
En mémoire :
```rust
let exported = owner.export_transfer(ksp_wallet_lib::WalletTransferFormat::SolanaKeypairBase58);
```
Vers un fichier no-clobber :
```rust
let exported = owner
.export_transfer_file(
"exports/devnet-main.keypair",
ksp_wallet_lib::WalletTransferFormat::SolanaCliJson,
)
.await;
```
Les octets retournés par `export_transfer` contiennent volontairement le secret. Le caller doit limiter leur durée de vie et les zeroize lorsqu'approprié. Sur Unix, l'export fichier tente `0600`, qui reste une hygiène filesystem et non une garantie cryptographique.
## 10. Surfaces in-memory
Les équivalents sans I/O filesystem sont :
```text
create_wallet_v1
open_wallet_view_v1
open_wallet_owner_v1
inspect_locked_wallet_v1
inspect_wallet_transfer
```
Les handles `WalletOwner` et `WalletView` peuvent être sérialisés vers le document natif courant avec `to_json_bytes()`. Ces bytes restent un `.kspwallet` chiffré, pas un export de la keypair.
## 11. Erreurs et diagnostics
Les erreurs Wallet sont des `ksp_core_lib::Error` avec codes `wallet.*`. Les erreurs de password restent génériques (`owner_unlock_failed`, `view_unlock_failed`) et ne doivent jamais être transformées en oracle détaillant KDF/wrap/ciphertext.
Les `Debug` des passwords et metadata protégées sont redacted. Les logs Wallet ne doivent contenir ni password, ni keypair, ni payload exporté.
## 12. Intégration avec Config et Transport
Wallet lui-même ne dépend ni de Config ni de Transport. Une application compose explicitement les couches :
```text
ksp-config-lib
-> fournit chemins/profils applicatifs
ksp-wallet-lib
-> ouvre le wallet et fournit la Pubkey autorisée
ksp-onchain-transport-lib
-> utilise cette Pubkey pour getBalance et autres lectures réseau
```
Cette composition est le rôle de `0.2.6 — ksp-app-wallet-desk`, pas de `ksp-wallet-lib`.

221
deltas/0.2.5/pre.010.md Normal file
View File

@@ -0,0 +1,221 @@
<!-- file: deltas/0.2.5/pre.010.md -->
<!-- version: 1 -->
# Delta `0.2.5-pre.010`
## Objet
Clôturer documentairement `0.2.5 — Wallet foundation` après le gate security/interoperability/compliance `pre.009` validé, sans modifier le code de production, les dépendances, la cryptographie ni le wire `.kspwallet` V1.
Cette tranche prépare la candidate de publication `rel.001` et le prompt d'ouverture de `0.2.6 — Wallet Desk`.
## Base validée
Base fonctionnelle :
```text
0.2.5-pre.009
workspace.package.version = 0.2.5-pre.9
```
Checkpoint opérateur communiqué le 2026-08-19 :
```text
cargo fmt --all OK
cargo check --workspace OK, aucun warning
cargo clippy --workspace --all-targets OK, aucun warning
cargo test -p ksp-wallet-lib OK
unit 58 passed / 1 ignored
dependency_boundary 3 passed
public_api 9 passed
doctests 2 passed
cargo test --workspace OK
```
Audit inverse final communiqué :
```text
ed25519-dalek 2.2.0
<- ksp-wallet-lib
<- solana-keypair 3.1.2 <- ksp-wallet-lib
solana-keypair 3.1.2
<- ksp-wallet-lib uniquement comme parent KSP direct
solana-address 2.7.0
<- solana-keypair 3.1.2
<- solana-pubkey 4.3.0 via ksp-core-lib
```
Aucune remédiation de code, dépendance ou wire n'est requise par ce checkpoint.
## Version Cargo
`pre.010` est **strictement documentaire**. Conformément à la règle KSP faisant de `workspace.package.version` un signal technique, `Cargo.toml` n'est pas modifié et reste :
```text
0.2.5-pre.9
```
La livraison/delta reste néanmoins identifiée :
```text
0.2.5-pre.010
```
`0.2.5-rel.001` effectuera le passage Cargo vers `0.2.5` lors de la publication stable.
## Documentation Wallet ajoutée
### `crates/ksp-wallet-lib/README.md`
Ajoute la synthèse consumer-facing de Wallet :
- responsabilités et hors-périmètre ;
- dépendances et frontières KSP ;
- états Locked/VIEW/OWNER ;
- format V1 et primitives ;
- persistence/no-clobber/state conflict ;
- import/export ;
- threat model et limites ;
- fixtures/tests et liens durables.
### `crates/ksp-wallet-lib/USAGE.md`
Ajoute des exemples des surfaces publiques :
```text
create_wallet_file_v1
inspect_locked_wallet_file_v1
open_wallet_view_file_v1
open_wallet_owner_file_v1
WalletOwner::sign
metadata administration
OWNER/VIEW password rotation
disable/recreate VIEW
inspect/import transfer
OWNER export
surfaces in-memory
```
Le guide rappelle explicitement que les octets d'export contiennent le secret et que Config/Transport restent hors de Wallet.
## Spécification et validation finales
`docs/formats/KSPWALLET_V1.md` passe en candidate documentaire finale :
- toutes les tranches `pre.006``pre.010` sont indiquées acquises ;
- aucune opération V1 n'est encore annoncée comme restant à implémenter ;
- la boundary async KDF est décrite au présent ;
- le tree final est rattaché au gate `pre.009` ;
- une section de statut de clôture rappelle que `rel.001` ne doit pas changer le wire.
`docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md` devient la matrice finale :
- ajoute les résultats opérateur `pre.009` ;
- enregistre les convergences Dalek/Solana-address/keypair ;
- ajoute le gate documentaire `pre.010` ;
- porte le verdict final candidate positif ;
- pointe vers `rel.001` strictement publicationnelle.
## Graphes et plans
Le graphe Wallet documente désormais les dépendances réelles et rappelle :
```text
Pubkey -> ksp-core-lib
Keypair -> encapsulée dans ksp-wallet-lib
Wallet -X-> Config/Transport/Tauri/Store/tracing direct/env
```
ROADMAP, séquence fonctionnelle, plan `0.2.5`, indices formats/validation/docs et prompts sont synchronisés sur :
```text
pre.010 acquis
rel.001 prochaine étape
0.2.6 Wallet Desk ensuite
```
## Prompt `0.2.6`
Ajoute :
```text
prompts/011-V0_2_6_START_PROMPT.md
```
Le prompt impose `0.2.6-pre.001` comme gate d'audit/sizing avant UI lourde et cadre notamment :
- `ksp-app-wallet-desk` Tauri mince ;
- composition Config composite + Wallet + HTTP ;
- besoin minimal identité autorisée + `getBalance` ;
- audit d'un `std.wallet` minimal sans secret ;
- handles VIEW/OWNER possédés côté Rust ;
- passwords éphémères et aucun secret en Config/frontend persistence ;
- inventory/path safety ;
- administration OWNER via les APIs Wallet existantes ;
- logging Tauri via l'écosystème tracing KSP ;
- TS-RS uniquement à la frontière applicative ;
- smoke Devnet de composition possible dans l'app ;
- `cargo tauri build` comme dernière validation.
## Fichiers
Ajoutés :
```text
crates/ksp-wallet-lib/README.md
crates/ksp-wallet-lib/USAGE.md
prompts/011-V0_2_6_START_PROMPT.md
deltas/0.2.5/pre.010.md
```
Modifiés :
```text
ROADMAP.md
docs/000-README.md
docs/architecture/005-DEPENDENCY_GRAPH.md
docs/formats/000-README.md
docs/formats/KSPWALLET_V1.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md
docs/validation/000-README.md
docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md
prompts/000-README.md
```
Total delta : **14 fichiers**.
## Contrôles attendus
Le delta étant documentaire, aucun `cargo tree` supplémentaire n'est requis. Le checkpoint de clôture recommandé reste :
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-wallet-lib
cargo test --workspace
```
Vérifications documentaires :
```text
liens Markdown relatifs valides
aucun fichier Rust modifié
Cargo.toml identique à pre.009
workspace.package.version toujours 0.2.5-pre.9
README/USAGE/spec/validation/plan/prompt cohérents
```
## Suite
Si le checkpoint reste vert :
```text
commit : v0.2.5-pre.010
next : 0.2.5-rel.001
```
Aucun tag stable n'est créé pour `pre.010`.

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/005-DEPENDENCY_GRAPH.md -->
<!-- version: 10 -->
<!-- version: 11 -->
# Graphe de dépendances KSP
@@ -131,17 +131,28 @@ La première surface est un reader de prix ; metadata HTTP/IPFS/Arweave et autre
```text
ksp-wallet-lib
-> ksp-core-lib
-> ksp-logging-lib
-> low-level crypto/key primitives explicitement retenues
-> ksp-core-lib # Pubkey/Error/Result
-> ksp-logging-lib # observabilité KSP
-> argon2 / chacha20poly1305 # KDF + AEAD
-> getrandom / zeroize # CSPRNG + secret memory
-> ed25519-dalek # autorité d'état OWNER
-> solana-keypair # keypair Solana encapsulée
-> serde / serde_json # wire JSON V1
-> tempfile / tokio # persistence + spawn_blocking
```
`ksp-core-lib::Pubkey` reste le type public transversal. `solana-keypair` est volontairement possédée directement par Wallet : elle contient le secret et la capacité de signature, n'est pas réexportée et n'est pas remontée dans Core par anticipation.
Interdictions :
```text
ksp-wallet-lib -X-> ksp-config-lib
ksp-wallet-lib -X-> ksp-onchain-transport-lib
ksp-wallet-lib -X-> ksp-execution-policy-api
ksp-wallet-lib -X-> Tauri / Store
ksp-wallet-lib -X-> tracing direct / std::env
ksp-wallet-lib -X-> solana-pubkey direct
ksp-wallet-lib -X-> solana-signer / solana-signature direct
```
Le Wallet stocke/ouvre/signe. Il ne décide pas si une dépense est autorisée.
@@ -377,7 +388,7 @@ ksp-app-wallet-desk
-> ksp-logging-lib
```
L'app compose ; elle ne déplace pas Config/Wallet/Transport dans Tauri.
L'app compose ; elle ne déplace pas Config/Wallet/Transport dans Tauri. Les handles `WalletView`/`WalletOwner` restent côté Rust, et le frontend ne reçoit que des DTOs sûrs. Config peut fournir la racine Wallet et le profil Transport ; les passwords et le secret Solana ne deviennent jamais des valeurs Config.
## Price Desk

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/000-README.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# Formats KSP
@@ -9,4 +9,4 @@ Une spécification de format décrit le wire exact, les encodages, les limites,
## Formats actifs
- [`KSPWALLET_V1.md`](KSPWALLET_V1.md) — spécification du format natif autonome `.kspwallet` V1. `0.2.5-pre.003` fige l'enveloppe/wire et les transcripts/AAD, `pre.004` ajoute Argon2id/XChaCha20-Poly1305/CSPRNG OS, `pre.005` fixe les payloads plaintext, le profil de création KSP calibré, l'autorité Ed25519 OWNER et le vecteur complet, `pre.006``pre.008` matérialisent persistence/administration/transfert, et `pre.009` clôt l'audit adversarial/interoperabilité/compliance avant la documentation finale.
- [`KSPWALLET_V1.md`](KSPWALLET_V1.md) — spécification du format natif autonome `.kspwallet` V1. `0.2.5-pre.003` fige l'enveloppe/wire et les transcripts/AAD, `pre.004` ajoute Argon2id/XChaCha20-Poly1305/CSPRNG OS, `pre.005` fixe les payloads plaintext, le profil de création KSP calibré, l'autorité Ed25519 OWNER et le vecteur complet, `pre.006``pre.008` matérialisent persistence/administration/transfert, `pre.009` ferme l'audit adversarial/interoperabilité/compliance et `pre.010` synchronise la documentation finale sans modifier le wire V1.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/KSPWALLET_V1.md -->
<!-- version: 7 -->
<!-- version: 9 -->
# `.kspwallet` V1 — spécification du format natif Wallet KSP
@@ -20,7 +20,7 @@ AAD des compartiments owner-control / metadata / secret
règles unknown-field / unknown-version
```
`0.2.5-pre.004` ajoute les primitives KDF/AEAD normatives et un premier vecteur cryptographique public. `0.2.5-pre.005` fixe les payloads plaintext V1, l'autorité Ed25519 OWNER, les procédures de création et d'ouverture VIEW/OWNER, le profil de création KSP issu du benchmark opérateur et un vecteur `.kspwallet` complet généré indépendamment du code Rust. `0.2.5-pre.006` matérialise la persistence filesystem bornée et la création no-clobber. `0.2.5-pre.007` matérialise la signature Solana OWNER, l'administration des metadata, les rotations OWNER/VIEW, la révocation forte VIEW et leur remplacement filesystem capability-bound. `0.2.5-pre.008` matérialise les adapters Solana CLI JSON et Base58 complet, leur inspection sûre, l'import no-clobber vers un nouveau `.kspwallet` et l'export secret OWNER explicite. Toute évolution qui modifie un élément déjà déclaré **figé** par cette spécification exige une évolution explicitement tracée avant la release stable ; après publication de V1, une incompatibilité de wire exige un nouveau `format_version`.
`0.2.5-pre.004` ajoute les primitives KDF/AEAD normatives et un premier vecteur cryptographique public. `0.2.5-pre.005` fixe les payloads plaintext V1, l'autorité Ed25519 OWNER, les procédures de création et d'ouverture VIEW/OWNER, le profil de création KSP issu du benchmark opérateur et un vecteur `.kspwallet` complet généré indépendamment du code Rust. `0.2.5-pre.006` matérialise la persistence filesystem bornée et la création no-clobber. `0.2.5-pre.007` matérialise la signature Solana OWNER, l'administration des metadata, les rotations OWNER/VIEW, la révocation forte VIEW et leur remplacement filesystem capability-bound. `0.2.5-pre.008` matérialise les adapters Solana CLI JSON et Base58 complet, leur inspection sûre, l'import no-clobber vers un nouveau `.kspwallet` et l'export secret OWNER explicite. `pre.009` ferme l'audit adversarial/interoperability/compliance et `pre.010` synchronise la documentation de clôture sans modifier le wire ni les primitives. Toute évolution qui modifie un élément déclaré **figé** par cette spécification exige une évolution explicitement tracée avant publication stable ; après publication de V1, une incompatibilité de wire exige un nouveau `format_version`.
Le but final est qu'une implémentation indépendante en Rust, Python, Go, C/C++, Java ou autre puisse créer, parser, vérifier et ouvrir un `.kspwallet` sans lire le code source de `ksp-wallet-lib`.
@@ -663,18 +663,19 @@ round-trip du codec
Le premier vecteur cryptographique public KDF+wrapping est ajouté par `pre.004`. `pre.005` ajoute en plus un `.kspwallet` complet cryptographiquement valide et ses métadonnées de contrôle test-only, décrits en section 22.
## 19. Invariants encore à compléter sans modifier le wire figé
## 19. État de matérialisation avant publication stable
Les opérations autour du wire V1 sont désormais matérialisées jusqu'aux adapters de transfert :
Toutes les opérations V1 prévues par `0.2.5` sont matérialisées et auditées :
```text
pre.006 : persistence async/atomique/no-clobber acquis
pre.007 : signature Solana, metadata admin, rotations et révocation acquis
pre.008 : import/export Solana CLI JSON + Base58 complet acquis
pre.009+ : audit adversarial, compliance et documentation de clôture restant
pre.009 : audit adversarial/interoperability/compliance acquis
pre.010 : README/USAGE/spec/graphes/matrice de clôture acquis
```
Toute découverte imposant de modifier la grammaire, les payloads plaintext, les tags, l'ordre transcript ou les domain separators définis dans ce document doit être traitée explicitement avant la publication stable, jamais masquée par une tolérance du parseur.
`pre.010` ne modifie ni la grammaire, ni les payloads plaintext, ni les tags, ni l'ordre du transcript, ni les domain separators. Toute découverte imposant un tel changement après publication stable devra passer par une évolution explicitement versionnée ; une incompatibilité de wire V1 ne peut pas être introduite silencieusement sous `format_version = 1`.
## 20. Primitives cryptographiques effectives depuis `pre.004`
@@ -695,7 +696,7 @@ pepper = aucun
secret Argon2 externe = aucun
```
Un password vide est rejeté. V1 limite l'entrée password à 1024 octets UTF-8. Le KDF est une opération CPU/mémoire coûteuse ; les futures API async create/open l'exécuteront hors du thread executor conformément au plan Wallet.
Un password vide est rejeté. V1 limite l'entrée password à 1024 octets UTF-8. Le KDF est une opération CPU/mémoire coûteuse ; les API async create/open l'exécutent hors du thread executor via la boundary blocking documentée par Wallet.
Le default de création n'est **pas** déterminé par les defaults de la crate RustCrypto. Le benchmark opérateur a comparé :
@@ -1028,7 +1029,7 @@ Cette sonde n'est pas une dépendance KSP et n'est pas requise au runtime ; elle
Le profil de création `64 MiB / 3 / 1` est cohérent avec la seconde recommandation Argon2id de RFC 9106 pour les environnements contraints. Les paramètres restent sérialisés par slot afin que les futurs defaults puissent évoluer sans rendre les wallets existants illisibles. XChaCha20-Poly1305 conserve une clé 256 bits et un nonce 192 bits généré par le CSPRNG OS. Les signatures d'état utilisent Ed25519 au format 64 octets défini par RFC 8032.
Le graphe Cargo observé au gate `pre.008` conserve une seule génération `ed25519-dalek 2.2.0`, une seule `solana-address 2.7.0` et un unique parent KSP direct de `solana-keypair 3.1.2` : `ksp-wallet-lib`. Les doublons `digest 0.10/0.11`, `crypto-common 0.1/0.2`, `block-buffer 0.10/0.12`, `cpufeatures 0.2/0.3`, `getrandom 0.3/0.4`, `rand 0.9/0.10`, `rand_core 0.6/0.9/0.10`, `sha2 0.10/0.11` et `syn 2/3` sont transitoires et imposés par les générations actuellement consommées par RustCrypto, Solana et Logging ; KSP n'ajoute pas une deuxième dépendance directe pour les contourner.
Le graphe Cargo final observé au gate `pre.009` conserve une seule génération `ed25519-dalek 2.2.0`, une seule `solana-address 2.7.0` et un unique parent KSP direct de `solana-keypair 3.1.2` : `ksp-wallet-lib`. Les doublons `digest 0.10/0.11`, `crypto-common 0.1/0.2`, `block-buffer 0.10/0.12`, `cpufeatures 0.2/0.3`, `getrandom 0.3/0.4`, `rand 0.9/0.10`, `rand_core 0.6/0.9/0.10`, `sha2 0.10/0.11` et `syn 2/3` sont transitoires et imposés par les générations actuellement consommées par RustCrypto, Solana et Logging ; KSP n'ajoute pas une deuxième dépendance directe pour les contourner.
Limites explicitement conservées en V1 :
@@ -1038,3 +1039,11 @@ Limites explicitement conservées en V1 :
- la zeroization réduit les copies possédées mais ne constitue pas une preuve d'effacement physique de toute copie potentielle produite par le compilateur, l'OS ou le matériel ;
- aucune revendication de résistance side-channel supplémentaire au-delà des primitives et bibliothèques retenues.
## 26. Statut de clôture V1
À `0.2.5-pre.010`, cette spécification constitue la candidate finale du format `.kspwallet` V1. Les guides d'utilisation KSP sont [`../../crates/ksp-wallet-lib/README.md`](../../crates/ksp-wallet-lib/README.md) et [`../../crates/ksp-wallet-lib/USAGE.md`](../../crates/ksp-wallet-lib/USAGE.md) ; ils ne remplacent pas le présent document comme autorité normative du wire.
La matrice [`../validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](../validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) enregistre les canaris adversariaux, la reproduction indépendante des vecteurs, les limites V1 et le checkpoint opérateur final de `pre.009`.
La publication stable `0.2.5` ne doit apporter aucune nouvelle décision cryptographique ou changement de wire. Elle publie la candidate validée ; toute correction fonctionnelle découverte avant le tag stable doit repasser par une tranche/fix explicite.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 53 -->
<!-- version: 54 -->
# Séquence des releases fonctionnelles KSP
@@ -418,13 +418,15 @@ La release doit fournir `docs/formats/KSPWALLET_V1.md` comme spécification sép
`0.2.5-pre.006` ajoute la persistence native sans Config : `create_wallet_file_v1` reçoit un chemin explicite du caller et publie uniquement en no-clobber via un fichier temporaire créé dans le même répertoire, écrit puis `sync_all` avant `persist_noclobber`; `open_wallet_view_file_v1`, `open_wallet_owner_file_v1` et `inspect_locked_wallet_file_v1` effectuent une lecture bornée à la limite V1 avant de déléguer au parser/crypto acquis. Les opérations filesystem bloquantes sont isolées par `spawn_blocking`. Les tests couvrent destination existante, concurrence avec un seul gagnant, fault injection avant publication, cleanup ordinaire des temporaires et rejet d'un fichier surdimensionné. La synchronisation du répertoire parent est best-effort sur Unix et n'est pas transformée en garantie portable de crash-durability. Les ACL/permissions OS restent hors du modèle Wallet.
`0.2.5-pre.007` complète l'administration native capability-bound : OWNER signe des messages Solana sans getter secret, modifie alias/notes, change son password ou celui de VIEW et peut disable/recreate VIEW avec rekey metadata fort ; VIEW ne peut que tourner son propre credential en rewrappant le même `K_metadata`. Les mutations sont staged puis remplacent le fichier uniquement si la destination courante correspond encore à l'enveloppe authentifiée attendue ; un handle stale ou une mauvaise cible reçoit `wallet.state_conflict`. Ce garde-fou ne prétend pas fournir un CAS filesystem portable ni un anti-rollback externe. La keypair reste encapsulée dans Wallet et aucune nouvelle dépendance tierce n'est ajoutée. `pre.008` ajoute ensuite les adapters `solana_cli_json` et `solana_keypair_base58`, linspection sûre limitée à Pubkey+format, limport no-clobber vers un nouveau `.kspwallet` et lexport OWNER en mémoire/fichier. La source dimport reste inchangée, VIEW nexporte jamais, aucun `bs58` direct nest ajouté puisque `solana-keypair 3.1.2` possède déjà le codec Base58 complet. `pre.009` devient le prochain gate security/compliance.
`0.2.5-pre.007` complète l'administration native capability-bound : OWNER signe des messages Solana sans getter secret, modifie alias/notes, change son password ou celui de VIEW et peut disable/recreate VIEW avec rekey metadata fort ; VIEW ne peut que tourner son propre credential en rewrappant le même `K_metadata`. Les mutations sont staged puis remplacent le fichier uniquement si la destination courante correspond encore à l'enveloppe authentifiée attendue ; un handle stale ou une mauvaise cible reçoit `wallet.state_conflict`. Ce garde-fou ne prétend pas fournir un CAS filesystem portable ni un anti-rollback externe. La keypair reste encapsulée dans Wallet et aucune nouvelle dépendance tierce n'est ajoutée. `pre.008` ajoute ensuite les adapters `solana_cli_json` et `solana_keypair_base58`, linspection sûre limitée à Pubkey+format, limport no-clobber vers un nouveau `.kspwallet` et lexport OWNER en mémoire/fichier. La source dimport reste inchangée, VIEW nexporte jamais, aucun `bs58` direct nest ajouté puisque `solana-keypair 3.1.2` possède déjà le codec Base58 complet. `pre.009` ferme ensuite le gate adversarial/security/interoperability/compliance : canaris de tampering et non-oracle, reproduction indépendante des vecteurs, audit des frontières et graphes Cargo. Le checkpoint opérateur est vert. `pre.010` finalise README/USAGE, la spec, les graphes, la matrice de clôture et le prompt `0.2.6` sans changement de code ni de version Cargo technique. `rel.001` est la prochaine étape et reste strictement publicationnelle.
## `0.2.6` — Wallet Desk
Mission : valider Config composite + `.kspwallet` + transport HTTP dans une application Tauri mince.
Le solde d'un wallet constitue un premier cas de validation réseau obligatoire.
Le solde d'un wallet constitue un premier cas de validation réseau obligatoire. L'application garde les handles VIEW/OWNER côté Rust, ne persiste aucun password dans Config/frontend et délègue toute crypto/signature/administration à `ksp-wallet-lib`.
Le prompt [`../../prompts/011-V0_2_6_START_PROMPT.md`](../../prompts/011-V0_2_6_START_PROMPT.md), préparé par `0.2.5-pre.010`, impose un `pre.001` d'audit/sizing couvrant Config `std.wallet`/composite, inventory/path safety, lifecycle VIEW/OWNER, balance `getBalance`, bridge Tauri/TS-RS, sécurité password/export, logging et validation finale Tauri.
## `0.2.7` — WebSocket Solana standard

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md -->
<!-- version: 12 -->
<!-- version: 13 -->
# Plan `0.2.5` — Wallet foundation
@@ -1085,6 +1085,22 @@ Toutes les mutations persistent un état staged puis ne mettent à jour le handl
La rotation simple VIEW rewrappe le même `K_metadata` et n'est pas une révocation forte. `disable_view`/`recreate_view` génèrent au contraire un nouveau `K_metadata`, rechiffrent les metadata et réécrivent `owner_control`; elles constituent la révocation forte des futures metadata de l'état courant. Dans tous les cas, `format_version` et la keypair Solana restent inchangés.
### 19.10 État acquis après `pre.010`
La tranche de clôture est documentaire et ne modifie ni Rust, ni Cargo, ni wire :
```text
README Wallet final
USAGE Wallet final
KSPWALLET_V1.md synchronisée en candidate V1
matrice validation 008 enrichie des preuves opérateur pre.009
graphe de dépendances Wallet finalisé
prompt 0.2.6 Wallet Desk préparé
liens Markdown locaux audités
```
`workspace.package.version` reste `0.2.5-pre.9` pendant `pre.010` conformément à la règle KSP de version technique ; `rel.001` effectuera le passage à `0.2.5`.
## 20. Sizing
| Domaine | Taille | Risque principal |
@@ -1117,16 +1133,16 @@ pre.005 owner-control + metadata/secret compartments + create/open VIEW/OWNER +
pre.006 persistence async/atomic/no-clobber + interrupted-write + fault/concurrency tests
pre.007 signature Solana + alias/notes + rotations passwords + disable/recreate VIEW avec rekey metadata
pre.008 import/export adapters + Solana CLI JSON + generic keypair Base58 + inspect
pre.009 audit security/interoperability/compliance + adversarial vectors/tests + cargo trees
pre.010 spec finale + README/USAGE + graphes/docs + candidate de clôture + prompt 0.2.6
rel.001 publication strictement publicationnelle
pre.009 audit security/interoperability/compliance + adversarial vectors/tests + cargo trees acquis
pre.010 spec finale + README/USAGE + graphes/docs + candidate de clôture + prompt 0.2.6 acquis
rel.001 publication strictement publicationnelle prochaine
```
Une `fix` ou tranche supplémentaire est préférable à la suppression d'une garantie sécurité si un des gates révèle une incompatibilité.
## 22. Dépendances par tranche
État réellement acquis au terme de `pre.009` :
État réellement acquis au terme de `pre.010` (aucune dépendance ajoutée par la tranche documentaire finale) :
```text
pre.002 zeroize ^1.9
@@ -1141,6 +1157,7 @@ pre.006 tempfile ^3.27
pre.007 aucune nouvelle dépendance tierce
pre.008 aucune nouvelle dépendance tierce
pre.009 aucune nouvelle dépendance tierce
pre.010 aucune nouvelle dépendance tierce (documentation uniquement)
```
Toutes les dépendances tierces communes restent centralisées sous `[workspace.dependencies]`; le membre Wallet active uniquement les features nécessaires. `ed25519-dalek ^2.2` est volontairement aligné avec la contrainte `^2.1.1` de `solana-keypair 3.1.2` afin de permettre une seule génération Dalek et d'activer `zeroize` sur la `SigningKey` partagée par résolution Cargo.
@@ -1179,7 +1196,7 @@ Solana RPC clients
Config/Store/Tauri
```
Le fait que `bs58` ne soit pas requis sera révalidé lorsque les adapters sont codés : `solana-keypair` fournit déjà la conversion Base58 du keypair complet.
L'absence de dépendance `bs58` directe est désormais acquise : `pre.008` utilise le codec Base58 de keypair complète déjà fourni par `solana-keypair`, et `pre.009` confirme le graphe Cargo sans ajout correspondant.
## 23. Sources externes réauditées
@@ -1232,6 +1249,8 @@ cargo tree et diagnostics secrets sont audités
README/USAGE/spec/vecteurs sont cohérents
```
À `pre.010`, ces critères sont satisfaits par la candidate documentée et par le checkpoint opérateur `pre.009` vert. La publication stable reste conditionnée à la validation du delta documentaire puis au workflow `rel.001`.
## 25. Hors périmètre confirmé
```text
@@ -1258,4 +1277,4 @@ Une future `format_version >= 2` pourra réétudier des facteurs/ancrages extern
## 26. Suite immédiate
`0.2.5-pre.003` fige le codec JSON strict, les limites structurelles, `slot_id` 16 octets, le descripteur VIEW, les DTOs denveloppe/key slots, les TLV transcript/AAD et la première spécification `docs/formats/KSPWALLET_V1.md`. `pre.004` ajoute Argon2id/XChaCha20-Poly1305/CSPRNG OS et le wrapping de content keys. Le benchmark opérateur permet à `pre.005` de retenir le profil initial `64 MiB / 3 / 1`, de figer les payloads `owner_control`/metadata/secret, d'introduire l'autorité Ed25519 OWNER distincte de la keypair Solana et de publier un vecteur complet. `pre.006` ajoute la persistence no-clobber et les ouvertures fichier. `pre.007` ajoute signature Solana, administration metadata, rotations OWNER/VIEW, révocation forte VIEW et remplacement administratif contrôlé. `pre.008` ajoute les adapters import/export Solana CLI JSON et keypair Base58 complet, l'inspection sûre, l'import vers un nouveau `.kspwallet` no-clobber et l'export OWNER explicite sans `bs58` direct. `pre.009` ajoute maintenant les canaris adversariaux, formalise les règles Wallet durables, reproduit les vecteurs hors Rust/KSP et audite le graphe Cargo/les duplications transitoires. **La suite immédiate est `pre.010` : documentation finale, README/USAGE Wallet, candidate de clôture et prompt `0.2.6`.**
`0.2.5-pre.003` fige le codec JSON strict, les limites structurelles, `slot_id` 16 octets, le descripteur VIEW, les DTOs denveloppe/key slots, les TLV transcript/AAD et la première spécification `docs/formats/KSPWALLET_V1.md`. `pre.004` ajoute Argon2id/XChaCha20-Poly1305/CSPRNG OS et le wrapping de content keys. Le benchmark opérateur permet à `pre.005` de retenir le profil initial `64 MiB / 3 / 1`, de figer les payloads `owner_control`/metadata/secret, d'introduire l'autorité Ed25519 OWNER distincte de la keypair Solana et de publier un vecteur complet. `pre.006` ajoute la persistence no-clobber et les ouvertures fichier. `pre.007` ajoute signature Solana, administration metadata, rotations OWNER/VIEW, révocation forte VIEW et remplacement administratif contrôlé. `pre.008` ajoute les adapters import/export Solana CLI JSON et keypair Base58 complet, l'inspection sûre, l'import vers un nouveau `.kspwallet` no-clobber et l'export OWNER explicite sans `bs58` direct. `pre.009` ajoute les canaris adversariaux, formalise les règles Wallet durables, reproduit les vecteurs hors Rust/KSP et audite le graphe Cargo/les duplications transitoires. `pre.010` finalise README/USAGE, spec, graphes, matrice de validation et prompt `0.2.6` sans changement de code ni de Cargo version. **La suite immédiate est `0.2.5-rel.001`, strictement publicationnelle.**

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/000-README.md -->
<!-- version: 12 -->
<!-- version: 13 -->
# Validations KSP
@@ -17,4 +17,4 @@ Documents :
- [`006-V0_2_3_HTTP_TRANSACTIONS.md`](006-V0_2_3_HTTP_TRANSACTIONS.md) — matrice finale validée de `0.2.3`, 11 wrappers Transactions, sécurité write/simulation, réaudit 52+14, `KSP-TRANSPORT-007` 37/37, graphes Cargo et deux smokes Devnet passés avant publication stable.
- [`007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée de `0.2.4`, inventaire exact 52 current + 14 Deprecated, preuve typed 52/52, audit SIMD final, `KSP-TRANSPORT-007`, workspace complet et deux smokes Devnet passés avant publication stable.
- [`008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) — matrice security/interoperability/compliance de `0.2.5`, threat model V1, adversarial canaries, reproduction externe des vecteurs, audit de frontières et graphes Cargo Wallet.
- [`008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) — matrice finale security/interoperability/compliance de `0.2.5`, threat model V1, adversarial canaries, reproduction externe des vecteurs, audit de frontières, preuves opérateur `pre.009`, graphes Cargo et gate documentaire `pre.010`.

View File

@@ -1,11 +1,11 @@
<!-- file: docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md -->
<!-- version: 1 -->
<!-- version: 3 -->
# Validation `0.2.5` — Wallet security / interoperability / compliance
## 1. Objet
Cette matrice ferme le gate technique de `0.2.5-pre.009` avant la documentation finale `pre.010`. Elle ne remplace ni la spécification [`../formats/KSPWALLET_V1.md`](../formats/KSPWALLET_V1.md), ni le threat model du plan [`../plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](../plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md), ni les deltas.
Cette matrice constitue la validation durable de clôture de `0.2.5`. `pre.009` ferme le gate technique security/interoperability/compliance et `pre.010` y ajoute les preuves opérateur et le gate documentaire final. Elle ne remplace ni la spécification [`../formats/KSPWALLET_V1.md`](../formats/KSPWALLET_V1.md), ni le threat model du plan [`../plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](../plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md), ni les deltas.
Le verdict recherché porte sur quatre axes :
@@ -111,7 +111,7 @@ Références cryptographiques normatives/primaires réauditées :
- documentation `solana-keypair 3.1.2` — keypair Ed25519 64 octets, validation secret/public et codecs Base58/JSON ;
- documentation `tempfile 3.27` — publication/replacement et limites d'atomicité selon OS/filesystem.
## 6. Audit Cargo observé après `pre.008`
## 6. Audit Cargo final observé après `pre.009`
Commande opérateur :
@@ -198,7 +198,7 @@ Le verdict security est positif **dans le threat model documenté**, avec les li
6. `zeroize` s'applique aux buffers possédés explicitement mais ne prouve pas l'effacement physique de toutes les copies potentielles ;
7. aucune protection hardware, second facteur, keychain, remote signer ou anti-rollback externe n'est incluse en V1.
Aucune de ces limites ne doit être masquée dans `pre.010`.
`pre.010` les conserve explicitement dans README/USAGE/spec et ne les transforme pas en garanties.
## 9. Gate opérateur `pre.009`
@@ -217,8 +217,59 @@ cargo tree -i solana-keypair@3.1.2
cargo tree -i solana-address@2.7.0
```
Le gate est vert seulement si les canaris adversariaux passent sans warning et si le tree ne révèle aucune nouvelle dépendance directe ou génération Dalek/Solana-address inattendue.
Ce gate est considéré vert uniquement si les canaris adversariaux passent sans warning et si le tree ne révèle aucune nouvelle dépendance directe ou génération Dalek/Solana-address inattendue ; le résultat effectivement observé est enregistré en section 10.
## 10. Verdict avant `pre.010`
## 10. Résultat opérateur `pre.009`
Le verdict de conception et d'interopérabilité est **positif sous réserve du checkpoint Cargo opérateur `pre.009`**. Aucun changement de wire/crypto n'est requis par l'audit. `pre.010` doit donc rester documentaire : README/USAGE Wallet, synchronisation finale de la spec/graphes, candidate de clôture et prompt `0.2.6`.
Checkpoint communiqué le 2026-08-19 après application de `0.2.5-pre.009` :
```text
cargo fmt --all OK
cargo check --workspace OK, aucun warning
cargo clippy --workspace --all-targets OK, aucun warning
cargo test -p ksp-wallet-lib OK
unit 58 passed / 1 ignored
dependency_boundary 3 passed
public_api 9 passed
doctests 2 passed
cargo test --workspace OK
```
Le tree opérateur confirme :
```text
ed25519-dalek 2.2.0
<- ksp-wallet-lib
<- solana-keypair 3.1.2 <- ksp-wallet-lib
solana-keypair 3.1.2
<- ksp-wallet-lib uniquement comme parent KSP direct
solana-address 2.7.0
<- solana-keypair 3.1.2
<- solana-pubkey 4.3.0 via ksp-core-lib
```
Les doublons transitifs déjà inventoriés restent inchangés et aucun nouveau bypass de frontière n'est observé.
## 11. Gate documentaire `pre.010`
La candidate finale doit vérifier :
```text
crates/ksp-wallet-lib/README.md existe et décrit les responsabilités/frontières
crates/ksp-wallet-lib/USAGE.md couvre create/open/sign/admin/rotation/import/export
KSPWALLET_V1.md ne laisse aucune opération V1 planifiée comme restant à implémenter
le graphe Wallet documente Pubkey via Core et keypair encapsulée dans Wallet
le plan 0.2.5 pointe désormais vers rel.001
le prompt 0.2.6 Wallet Desk existe et commence par audit/sizing
les liens Markdown locaux modifiés sont valides
aucun fichier Rust ni manifest Cargo n'est modifié par pre.010
workspace.package.version reste 0.2.5-pre.9 car pre.010 est doc-only
```
## 12. Verdict final candidate `0.2.5`
Le verdict security/interoperability/compliance est **positif**. Le checkpoint opérateur `pre.009` est vert et n'impose aucune remédiation de code, de dépendance, de wire ou de cryptographie. `pre.010` reste donc strictement documentaire et nintroduit aucun changement technique.
Après validation du delta documentaire, la suite est `0.2.5-rel.001`, strictement publicationnelle : version Cargo stable `0.2.5`, statut stable/CHANGELOG/delta de publication, validations finales puis tag Git `v0.2.5`. Aucune nouvelle fonctionnalité Wallet n'est attendue dans `rel.001`.

View File

@@ -1,5 +1,5 @@
<!-- file: prompts/000-README.md -->
<!-- version: 15 -->
<!-- version: 16 -->
# Prompts KSP
@@ -31,3 +31,4 @@ Le prompt générique `0.1.x` a été affiné pendant `0.0.3` puis remplacé par
- [`008-V0_2_3_START_PROMPT.md`](008-V0_2_3_START_PROMPT.md) — prompt préparé par la dernière prerelease de `0.2.2`, destiné à ouvrir `0.2.3 — HTTP Transactions` après publication stable de `0.2.2`; il cible les 11 méthodes Transactions et impose un audit actuel ainsi que la politique no-resend des write submissions.
- [`009-V0_2_4_START_PROMPT.md`](009-V0_2_4_START_PROMPT.md) — prompt préparé par `0.2.3-pre.009`, destiné à ouvrir `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale` après publication stable de `0.2.3`; il cible les 15 wrappers restants et impose `KSP-TRANSPORT-007` ainsi qu'un nouvel audit/sizing à `pre.001`.
- [`010-V0_2_5_START_PROMPT.md`](010-V0_2_5_START_PROMPT.md) — prompt préparé par `0.2.4-pre.009` puis finalisé en version 2 par `pre.009-fix.001`, destiné à ouvrir `0.2.5 — Wallet foundation` sur la base stable `v0.2.4`; il impose audit/threat-model/sizing avant choix cryptographiques et cadre `.kspwallet` interopérable, capacités indépendantes VIEW/OWNER, metadata protégées, key slots/rotations, signature, persistence atomique et import/export extensible sans `WalletPolicy`.
- [`011-V0_2_6_START_PROMPT.md`](011-V0_2_6_START_PROMPT.md) — prompt préparé par `0.2.5-pre.010`, destiné à ouvrir `0.2.6 — Wallet Desk` après publication stable de `v0.2.5`; il cadre une application Tauri mince composant Config composite + Wallet + HTTP `getBalance`, avec audit/sizing préalable, lifecycle VIEW/OWNER, sécurité password/export et validation frontend/Tauri.

View File

@@ -0,0 +1,535 @@
<!-- file: prompts/011-V0_2_6_START_PROMPT.md -->
<!-- version: 1 -->
# Prompt de démarrage `0.2.6` — Wallet Desk
## 1. Contexte de reprise
La base attendue est la release stable :
```text
v0.2.5
```
`0.2.1``0.2.4` ont stabilisé le transport HTTP Solana complet :
```text
52/52 méthodes HTTP courantes typées
14/14 méthodes historiques Deprecated conservées pour compliance
getBalance disponible depuis la foundation
Config -> Transport autorisé
Transport -X-> Config
```
`0.2.5` stabilise `ksp-wallet-lib` et `.kspwallet` V1 :
```text
format autonome documenté hors Rust
VIEW / OWNER indépendants
Pubkey/alias/notes cachés wallet verrouillé
create/open/inspect in-memory et fichier
Argon2id + XChaCha20-Poly1305 + Ed25519 state authentication
signature Solana OWNER sans getter secret
alias/notes administration
rotations OWNER/VIEW
révocation forte VIEW
create/import no-clobber
remplacement administratif capability-bound
Solana CLI JSON + keypair Base58 import/export
interop et adversarial/security audit validés
```
Le Wallet reste indépendant de Config, Transport, Tauri, Store et execution policy. `solana-keypair` reste encapsulée dans Wallet ; les applications consomment les contrats KSP publics.
La release à ouvrir est :
```text
0.2.6 — ksp-app-wallet-desk
```
La première tranche est `0.2.6-pre.001` et commence par **audit de l'état actuel + brainstorming UX/Config/bridge + sizing** avant implémentation UI lourde.
## 2. Mission
Créer :
```text
crates/ksp-app-wallet-desk
```
comme application Tauri spécialisée et mince qui valide réellement la composition :
```text
ksp-config-lib
+ Config composite
+ ksp-wallet-lib
+ ksp-onchain-transport-lib HTTP
+ ksp-logging-lib
```
La première version doit au minimum permettre à un utilisateur de :
```text
sélectionner/créer un .kspwallet
inspecter son état verrouillé sans fuite d'identité
ouvrir avec VIEW ou OWNER
voir Pubkey + alias + notes après autorisation
interroger le solde de la Pubkey via le transport HTTP configuré
verrouiller/fermer la capability courante
```
Le release planning doit également évaluer la surface UI raisonnable pour :
```text
import Solana CLI JSON / Base58
export OWNER explicite
mutation alias/notes
rotation OWNER
rotation VIEW
strong disable/recreate VIEW
```
Ces capacités appartiennent déjà à Wallet ; l'application ne doit jamais les réimplémenter. `pre.001` décide leur découpage exact après sizing, mais ne réduit pas le MVP en dessous de l'ouverture VIEW/OWNER + identité autorisée + balance réseau.
## 3. Frontières architecturales
Direction autorisée :
```text
ksp-app-wallet-desk
-> ksp-config-lib
-> ksp-wallet-lib
-> ksp-onchain-transport-lib
-> ksp-core-lib lorsque types/erreurs partagés nécessaires
-> ksp-logging-lib
-> Tauri / frontend dependencies
```
Interdictions :
```text
ksp-wallet-lib -X-> Config/Transport/Tauri
ksp-app-wallet-desk -X-> cryptographie Wallet directe
ksp-app-wallet-desk -X-> solana-keypair direct
ksp-app-wallet-desk -X-> solana-signer direct
ksp-app-wallet-desk -X-> solana-signature direct
ksp-app-wallet-desk -X-> client RPC Solana alternatif
ksp-app-wallet-desk -X-> tracing direct hors adapter Tauri explicitement nécessaire
frontend -X-> secret key material
frontend -X-> localStorage/sessionStorage pour passwords
```
L'application compose les couches ; elle ne déplace aucune logique métier ou cryptographique dans les commands Tauri ou TypeScript.
## 4. Config et composition
`0.2.6-pre.001` doit réauditer la surface Config existante avant de créer un document.
Le besoin attendu est un document standard Wallet minimal, probablement autour d'un global non secret :
```text
wallets_directory
```
avec un fallback Config du type :
```text
${KSP_WALLETS_DIRECTORY:-wallets}
```
mais le shape final doit être décidé par l'audit et validé par JSON Schema. Les règles existantes restent :
- Config est l'unique propriétaire des variables d'environnement KSP ;
- aucun password OWNER/VIEW ni keypair ne doit entrer dans Config ;
- une valeur globale reste hors profils lorsqu'elle ne varie pas par profil ;
- le document standard est enregistré sous un `file_id` logique `cfg.std.*` ;
- le composite propre à l'application utilise `cfg.composite.ksp-app-wallet-desk` ;
- les compositions référencent des `file_id`, jamais des filenames physiques ;
- les overrides CLI `cfgpath`/`schemapath`/file mappings restent ceux de Config.
Le composite Wallet Desk doit sélectionner au minimum les composants nécessaires parmi :
```text
logging
wallet
transport
```
Le nom exact des `component_id`, filenames et profils doit être fixé par `pre.001`/la tranche Config correspondante, pas inventé dans le frontend.
## 5. Wallet lifecycle dans l'application
Le runtime Rust doit posséder les handles `WalletView` / `WalletOwner`. Le frontend ne reçoit que des DTO sûrs.
États UI conceptuels :
```text
aucun wallet sélectionné
wallet sélectionné mais verrouillé
VIEW ouvert
OWNER ouvert
opération privilégiée en cours
```
Projection verrouillée autorisée :
```text
format_version
view_enabled
filename/path affichable selon policy UI décidée
```
Projection après unlock :
```text
capability
Pubkey
alias
notes
balance/rpc status lorsque demandé
```
Les handles OWNER/VIEW ne doivent pas être sérialisés ou copiés dans le frontend.
Le lock explicite doit supprimer le handle Rust possédé par l'application et purger les projections frontend protégées.
## 6. Passwords et secrets
Les passwords OWNER/VIEW sont des entrées éphémères :
```text
UI input
-> invoke Tauri
-> wrapper OwnerPassword/ViewPassword côté Rust
-> utilisation Wallet
-> drop/zeroization selon contrat Wallet
```
Interdictions :
- ne jamais écrire un password dans Config, `.env`, logs, `Debug`, localStorage ou sessionStorage ;
- ne jamais retourner un password dans un DTO ;
- ne jamais exposer la keypair ou les 64 octets secret au frontend pour signer ;
- ne jamais journaliser le contenu d'un export secret ;
- ne pas conserver inutilement les passwords en état TypeScript après l'invocation.
Les exports OWNER sont des opérations explicitement privilégiées et doivent utiliser une UX de confirmation intégrée.
## 7. Balance réseau
Le cas réseau minimal est :
```text
Wallet VIEW/OWNER ouvert
-> ksp_core_lib::Pubkey
-> HttpTransportPool::getBalance
-> DTO balance sûr
-> UI
```
Wallet ne dépend pas de Transport. L'application possède la composition et choisit le profil Transport via Config.
Le balance refresh doit :
- fonctionner avec VIEW comme avec OWNER ;
- rester explicitement déclenchable/rafraîchissable ;
- distinguer erreur Wallet, erreur Config et erreur Transport sans recopier des payloads secrets ;
- ne pas inventer de cache réseau dans Wallet ;
- préserver les règles de redaction URL/credentials de Transport.
## 8. UI/UX à auditer en `pre.001`
Évaluer au minimum les vues/flows suivants :
```text
Dashboard / status runtime
Wallet inventory ou sélection fichier
Locked wallet inspection
Create wallet
Import wallet
Unlock VIEW
Unlock OWNER
Wallet details : Pubkey / alias / notes
Balance / transport profile / refresh
Metadata administration OWNER
Credentials/security : rotate OWNER/VIEW, disable/recreate VIEW
Export OWNER
Logging diagnostics contrôlés
```
Le sizing décide si tous ces flows tiennent dans `0.2.6` sans dégrader la qualité. Une tranche supplémentaire est préférable à une UI qui contourne les contracts Wallet.
Les interactions destructives ou privilégiées utilisent des modals Bootstrap intégrés, pas `window.alert`, `window.confirm` ou `window.prompt`.
## 9. Référence Tauri existante
`ksp-app-config-desk` est le template principal à réauditer avant création :
```text
frontend/
frontend/ts/
frontend/sass/
frontend/ts/bindings/
Vite
Bootstrap
SimpleBar si utile
TS-RS pour DTO applicatifs
splash + main window
Tauri capabilities explicites
```
Ne pas copier aveuglément les dépendances inutiles. Réutiliser les patterns éprouvés et supprimer ce qui n'a pas de besoin Wallet Desk réel.
Le port de développement doit être réservé distinctement de Config Desk après audit des ports déjà utilisés.
Le build frontend standalone `npm run check` reste un type-check/lint/test, pas un production build. Le build production final est déclenché par Tauri via `beforeBuildCommand`.
## 10. Logging
L'application doit rester dans l'écosystème `tracing` KSP :
```text
ksp-logging-lib
+ tauri-plugin-tracing
+ @fltsci/tauri-plugin-tracing
```
Ne pas utiliser `tauri-plugin-log`.
Le bridge frontend -> Rust doit reprendre/refondre le pattern validé de Config Desk. Toutes les interactions UI importantes doivent être instrumentées à `debug` ou `trace` sans secret : clics, navigation, sélection wallet, refresh balance, unlock result, mutations, modals, changements d'état et remplacements DOM pertinents.
Les fichiers logs restent uniques par lancement selon la politique KSP existante.
## 11. DTOs Tauri
Les commands Tauri doivent exposer des DTOs applicatifs sûrs, pas les types internes Wallet complexes lorsque cela élargit la surface inutilement.
DTOs à auditer :
```text
WalletInventoryEntryDto
LockedWalletDto
WalletAuthorizedDto
WalletBalanceDto
WalletCreateRequestDto
WalletImportRequestDto
WalletUnlockRequestDto
WalletMetadataMutationDto
WalletSecurityStatusDto
WalletOperationResultDto
```
Les noms sont indicatifs ; `pre.001` doit les rationaliser. Les DTOs ne contiennent jamais de secret key material.
TS-RS reste une frontière applicative Tauri. Ne pas ajouter des dérivations TS-RS dans `ksp-wallet-lib` uniquement pour cette app.
## 12. Inventory et chemins Wallet
Wallet core reçoit toujours un chemin explicite. Si Wallet Desk affiche un inventaire de fichiers sous un répertoire configuré, cette énumération est une responsabilité de composition/application, pas une raison d'ajouter Config ou directory discovery dans `ksp-wallet-lib`.
L'audit doit fixer :
- extension `.kspwallet` filtrée ;
- symlinks et fichiers non réguliers ;
- traversal/path escape ;
- comportement sur répertoire absent ;
- refresh manuel/automatique ;
- affichage filename vs alias protégé ;
- no-clobber create/import/export.
Aucun alias ne doit être dérivé du filename ; l'alias reste metadata protégée interne au wallet.
## 13. Administration OWNER
Les opérations OWNER existent déjà et doivent être appelées directement :
```text
sign
update_alias
add_note
update_note
delete_note
rotate_owner_password
rotate_view_password
disable_view
recreate_view
export_transfer / export_transfer_file
```
Le frontend doit refléter les permissions : les controls OWNER ne sont pas affichés/activés comme disponibles sous VIEW.
Un `wallet.state_conflict` doit déclencher un message de conflit/refresh explicite, pas une réécriture forcée ou un retry aveugle.
## 14. Import/export
Formats acquis :
```text
Solana CLI JSON
Solana keypair Base58 complet
```
Import :
```text
source externe
-> inspection facultative
-> nouveau .kspwallet no-clobber
```
Export :
```text
OWNER uniquement
-> destination nouvelle no-clobber
```
Le frontend ne doit pas recevoir le secret si un export fichier peut être effectué entièrement côté Rust. Un éventuel export texte/copie clipboard doit être traité comme une nouvelle surface de fuite et n'est pas supposé requis par défaut.
## 15. Tests
### 15.1 Rust déterministe
Couvrir au minimum :
- mapping Config composite -> wallet path + transport settings ;
- inventory/path safety ;
- locked projection sans Pubkey/metadata ;
- VIEW/OWNER capability mapping ;
- secret absence des DTOs et `Debug` ;
- balance DTO mapping avec serveur HTTP local/fixture ;
- no-clobber create/import/export ;
- state conflict surfacé correctement ;
- commands Tauri délèguent aux APIs Wallet/Transport au lieu de réimplémenter.
### 15.2 Frontend
Au minimum :
```text
npm run check
```
Ajouter des tests ciblés seulement lorsque leur valeur est démontrée ; ne pas construire le bundle production dans ce script.
### 15.3 Smoke Devnet opt-in
Wallet Desk est une surface légitime de composition `Config -> Wallet -> Transport`. Un smoke Devnet opt-in peut donc vivre dans l'application ou une sous-surface d'intégration qu'elle possède.
Scénario recommandé :
```text
Config composite Devnet
-> Wallet test-only/éphémère ouvert
-> Pubkey
-> Transport getBalance
-> résultat RPC valide, y compris 0 lamport
```
Le smoke ne doit pas utiliser un secret de production ni exiger un wallet financé.
## 16. Sécurité desktop
Préserver les règles acquises de Config Desk :
- pas de dialogues navigateur natifs pour les interactions applicatives normales ;
- pas de persistence frontend des secrets ;
- CSP/capabilities Tauri réaudités ;
- commands privilégiées minimales ;
- aucun path arbitraire non validé ne doit permettre de sortir silencieusement de la racine Wallet choisie lorsqu'une opération est censée être root-scoped ;
- les erreurs UI ne recopient pas de payload secret ou d'URL RPC credentialée.
Les file pickers natifs éventuellement nécessaires doivent être évalués comme surface Tauri explicite, pas ajoutés implicitement.
## 17. Validation finale Tauri
Après les validations ciblées et workspace :
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-app-wallet-desk
cargo test --workspace
npm run check --prefix crates/ksp-app-wallet-desk
```
Le build Tauri de production est la **dernière** opération de validation :
```bash
cargo tauri build -c crates/ksp-app-wallet-desk/tauri.conf.json
```
Le smoke Devnet opt-in, s'il est livré, est exécuté séparément avec une commande documentée.
## 18. Gate `pre.001`
Avant toute implémentation lourde, `0.2.6-pre.001` doit produire :
1. audit de `ksp-app-config-desk` comme template Tauri ;
2. audit de la surface publique finale `ksp-wallet-lib` ;
3. audit de Config composite et besoin exact d'un `std.wallet` ;
4. audit de la surface Transport nécessaire (`getBalance` au minimum) ;
5. UX/screen map ;
6. DTO/command map ;
7. threat model desktop/password/export ;
8. stratégie inventory/path ;
9. stratégie tests + smoke Devnet ;
10. sizing détaillé et forecast souple des prereleases.
Si le scope UI complet ne tient pas dans une release clôturable, scinder les fonctionnalités non essentielles avant implémentation lourde, mais préserver le MVP identité + balance.
## 19. Forecast initial non contraignant
Point de départ à réviser par `pre.001` :
```text
pre.001 audit/sizing/UX/Config/bridge/security
pre.002 crate Tauri + frontend shell + logging + splash/main
pre.003 std.wallet + composite Wallet Desk + adapters Config
pre.004 inventory/selection + locked inspection + DTOs
pre.005 create/import + unlock VIEW/OWNER + lifecycle
pre.006 wallet details + balance HTTP + refresh/diagnostics
pre.007 metadata administration + rotations VIEW/OWNER
pre.008 strong VIEW disable/recreate + export OWNER + security UX
pre.009 integration tests + Devnet smoke + compliance/security review
pre.010 README/USAGE/build final + prompt 0.2.7 si nécessaire
rel.001 publication stable
```
Cette séquence est un forecast, pas un engagement. `pre.001` peut la réduire, l'étendre ou la resegmenter selon l'audit réel.
## 20. Hors périmètre
```text
modification du wire .kspwallet V1 sans défaut démontré
WalletPolicy / execution policy
construction/simulation/envoi de transaction
WebSocket/gRPC
Store
hardware wallet/Ledger
remote signer
mobile/browser extension
cloud custody
trading
```
Le Wallet Desk valide et administre Wallet ; il ne devient pas l'application globale KSP.
## 21. Résultat attendu de `0.2.6`
À la clôture stable :
```text
une app Tauri spécialisée existe
Config composite sélectionne logging/wallet/transport proprement
aucun secret Wallet n'est déplacé dans Config ou frontend persistence
un .kspwallet peut être créé/sélectionné/ouvert avec VIEW ou OWNER
Pubkey/alias/notes ne sont affichés qu'après autorisation
la balance de la Pubkey est lisible via Transport HTTP
les opérations OWNER retenues par le sizing délèguent à ksp-wallet-lib
logging frontend/Rust est instrumenté sans secret
les validations Rust/frontend/Tauri sont vertes
un smoke Devnet de composition est disponible si retenu par le gate
README/USAGE et prompt de suite sont synchronisés
```