v0.2.6-pre.015

This commit is contained in:
2026-08-22 03:21:49 +02:00
parent bd561cad47
commit d370027c02
27 changed files with 2630 additions and 364 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
<!-- file: docs/IDEAS.md -->
<!-- version: 20 -->
<!-- version: 21 -->
# Idées à explorer
@@ -202,13 +202,13 @@ Formats/cibles à inventorier et prioriser selon usage réel :
Chaque format doit être étudié côté sécurité, round-trip, secret/public, dépendances et compatibilité avant engagement.
### Conteneur binaire `.kspwallet` et formats logiques futurs
### `.kspwallet` V2 binaire et formats futurs
**Status :** Retenu pour audit en `0.2.7` / facteurs futurs à explorer
**Status :** V2 retenu et matérialisé en `0.2.6-pre.015` / facteurs futurs à explorer
Le JSON V1 actuel est un format dinterop lisible. Base64 seul napporte aucune sécurité et resterait un texte trivialement décodable avec environ un tiers de surcharge. `0.2.7` doit donc étudier un **conteneur de persistence binaire versionné** séparé du `format_version` logique/cryptographique : magic/framing explicite, lecture rétrocompatible du JSON V1 historique, écriture binaire par défaut après validation, migration explicite et test vectors. Le choix du codec/framing exact est audité avant engagement ; il ne doit pas casser les transcripts/AAD, VIEW/OWNER, keypair ou import/export.
Le JSON V1 actuel reste le format historique stable et lisible. Base64 seul napporte aucune sécurité et resterait un texte trivialement décodable avec environ un tiers de surcharge. La décision initialement envisagée pour `0.2.7` a été ramenée dans `0.2.6` : `pre.015` définit un **wire binaire V2 KSP** avec magic/framing explicite, entiers big-endian, identifiants numériques stables, longueurs bornées et lecture/écriture canonique stricte. V1 reste supporté sans réinterprétation ; la façade de lecture multi-version, la création V2 et la politique `DEFAULT_WALLET_FORMAT = V2` arrivent en `pre.016`, puis la migration explicite V1 -> V2 en `pre.017`. Le V2 ne modifie pas à lui seul les garanties cryptographiques de VIEW/OWNER, keypair ou import/export.
Un futur `format_version >= 2` pourra introduire dautres modèles dautorisation, notamment password + facteur supplémentaire. `ksp-wallet-lib` restera propriétaire du format, des challenges et de la vérification, mais toute interaction réelle (OTP, enrollment/recovery, hardware/WebAuthn, validation distante) exigera une évolution de Wallet Desk ou du client concerné. Un seed TOTP stocké uniquement dans le même fichier que le wallet ne doit pas être présenté automatiquement comme un second facteur indépendant contre un attaquant possédant ce fichier.
V2 est désormais réservé au wire binaire KSP sans second facteur. Un futur V3 pourra introduire dautres modèles dautorisation, notamment password + facteur supplémentaire. `ksp-wallet-lib` restera propriétaire du format, des challenges et de la vérification, mais toute interaction réelle (OTP, enrollment/recovery, hardware/WebAuthn, validation distante) exigera une évolution de Wallet Desk ou du client concerné. Un seed TOTP stocké uniquement dans le même fichier que le wallet ne doit pas être présenté automatiquement comme un second facteur indépendant contre un attaquant possédant ce fichier.
## Pipelines

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/004-COMPONENT_INVENTORY.md -->
<!-- version: 16 -->
<!-- version: 17 -->
# Inventaire initial des composants KSP
@@ -26,14 +26,14 @@ Ce document maintient l'inventaire synthétique des composants retenus ou presse
| On-chain HTTP | `ksp-onchain-transport-lib` | lib | Stable | `0.2.1``0.2.4` | HTTP standard complet : 52/52 current + 14/14 historical |
| Wallet | `ksp-wallet-lib` | lib | Stable | `0.2.5` | `.kspwallet`, VIEW/OWNER, secrets, signature, import/export |
| Wallet Desk | `ksp-app-wallet-desk` | app | Retenu | `0.2.6` | Wallet + Config composite + HTTP/balance |
| Wallet persistence | `ksp-wallet-lib` | lib | Retenu | `0.2.7` | conteneur binaire rétrocompatible autour du payload V1 |
| Standard WS | `ksp-onchain-transport-lib` | lib | Retenu | `0.2.8` | WebSocket Solana complet, sessions/subscriptions |
| Helius WS | `ksp-onchain-transport-lib` | lib | Retenu | `0.2.9` | LaserStream WebSocket comme extension du moteur standard |
| Yellowstone | `ksp-onchain-transport-lib` | lib | Pressenti | `0.2.10` | client gRPC standard/provider-neutral |
| Off-chain price | `ksp-offchain-transport-lib` | lib | Retenu | `0.2.11` | première abstraction/provider de prix SOL/USD, SOL/EUR |
| Price Desk | nom à fixer | app | Retenu | `0.2.12` | visualisation/validation des prix + intégration Wallet Desk |
| Wire | `ksp-interface-lib` | lib | Retenu | `0.2.13` | façade wire officielle + API publique wire |
| Program API | `ksp-program-api` | API | Retenu | `0.2.14` | contrats extensibles Program |
| Wallet V2 | `ksp-wallet-lib` | lib | En cours | `0.2.6` | wire binaire V2 + API default/versionnée + migration |
| Standard WS | `ksp-onchain-transport-lib` | lib | Retenu | `0.2.7` | WebSocket Solana complet, sessions/subscriptions |
| Helius WS | `ksp-onchain-transport-lib` | lib | Retenu | `0.2.8` | LaserStream WebSocket comme extension du moteur standard |
| Yellowstone | `ksp-onchain-transport-lib` | lib | Pressenti | `0.2.9` | client gRPC standard/provider-neutral |
| Off-chain price | `ksp-offchain-transport-lib` | lib | Retenu | `0.2.10` | première abstraction/provider de prix SOL/USD, SOL/EUR |
| Price Desk | nom à fixer | app | Retenu | `0.2.11` | visualisation/validation des prix + intégration Wallet Desk |
| Wire | `ksp-interface-lib` | lib | Retenu | `0.2.12` | façade wire officielle + API publique wire |
| Program API | `ksp-program-api` | API | Retenu | `0.2.13` | contrats extensibles Program |
| Program impl. | `ksp-program-lib` | lib | Retenu | vertical slices ultérieurs | implementations Program officielles |
| Program extension | `ksp-program-<name>-lib` | lib externe | À la demande | dès besoin | implementation externe de `ksp-program-api` |
| Store API | `ksp-store-api` | API | Retenu | `0.3.1` | contrats persistence backend-agnostic, RAW d'abord |

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/000-README.md -->
<!-- version: 5 -->
<!-- version: 6 -->
# Formats KSP
@@ -10,3 +10,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, `pre.009` ferme l'audit adversarial/interoperabilité/compliance et `pre.010` synchronise la documentation finale sans modifier le wire V1.
- [`KSPWALLET_V2.md`](KSPWALLET_V2.md) — wire binaire natif V2 introduit par `0.2.6-pre.015` : framing canonique KSP, IDs numériques, longueurs big-endian, aucun Base64/compression, domains/transcripts V2 distincts et politique `default != latest`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/KSPWALLET_V1.md -->
<!-- version: 11 -->
<!-- version: 12 -->
# `.kspwallet` V1 — spécification du format natif Wallet KSP
@@ -22,6 +22,8 @@ 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. `pre.009` ferme l'audit adversarial/interoperability/compliance et `pre.010` synchronise la documentation de clôture sans modifier le wire ni les primitives. Après publication stable de V1, toute évolution qui modifie un élément déclaré **figé** par cette spécification doit être explicitement tracée ; une incompatibilité de wire exige un nouveau `format_version`.
Depuis `0.2.6-pre.015`, V1 reste explicitement supporté comme format historique stable tandis que V2 définit le nouveau wire binaire. Les APIs versionnées V1 sont conservées et une lecture générique future doit auto-détecter V1/V2 sans migration implicite.
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`.
## 2. Modèle de confiance V1

View File

@@ -0,0 +1,441 @@
<!-- file: docs/formats/KSPWALLET_V2.md -->
<!-- version: 1 -->
# `.kspwallet` V2 — spécification du wire binaire natif KSP
## 1. Statut et objectif
Ce document est l'autorité normative du **wire `.kspwallet` `format_version = 2`** introduit par `0.2.6-pre.015`.
V2 remplace l'enveloppe JSON/Base64url de V1 par un framing binaire KSP canonique. L'objectif est :
```text
réduire fortement la taille persistée
supprimer l'encodage Base64 des champs déjà binaires
éviter qu'un .kspwallet nouvellement créé soit un document JSON lisible comme tel
conserver un format documenté et implémentable hors Rust
préserver les frontières cryptographiques Wallet
```
Le caractère binaire **n'ajoute aucune propriété cryptographique**. La confidentialité et l'authenticité continuent de dépendre d'Argon2id, XChaCha20-Poly1305 et Ed25519, jamais de l'absence de JSON.
`0.2.6-pre.015` fige la grammaire binaire, les identifiants numériques, les bornes structurelles et les transcripts/AAD V2. La création/ouverture/persistence V2, l'auto-détection V1/V2 et le basculement de l'API générique vers V2 sont matérialisés dans les tranches suivantes de `0.2.6`.
V1 reste un format stable supporté. V2 ne réinterprète jamais un document V1 avec sa propre grammaire.
## 2. Politique de version et API
Les notions suivantes sont distinctes :
```text
DEFAULT_WALLET_FORMAT
LATEST_SUPPORTED_WALLET_FORMAT
```
À partir de l'intégration V2 :
```text
DEFAULT_WALLET_FORMAT = V2
LATEST_SUPPORTED_WALLET_FORMAT = V2
```
Si un futur V3 apparaît, par exemple pour un modèle d'autorisation avec second facteur, `LATEST_SUPPORTED_WALLET_FORMAT` pourra devenir V3 tandis que `DEFAULT_WALLET_FORMAT` pourra **rester V2**. Le default ne suit jamais automatiquement la dernière version.
La politique d'API retenue est :
```text
create_wallet_file(...) -> format default explicitement choisi, V2
create_wallet_file_v1(...) -> force V1
create_wallet_file_v2(...) -> force V2
create_wallet_file_v3(...) -> force V3 si V3 existe un jour
open_wallet_*_file(...) -> détecte puis dispatch les versions supportées
open_wallet_*_file_v1(...) -> exige V1
open_wallet_*_file_v2(...) -> exige V2
open_wallet_*_file_v3(...) -> exige V3 si V3 existe un jour
```
Le même principe s'applique aux opérations dont la version de fichier est pertinente, notamment inspection et import natif.
## 3. Encodage général
Un document V2 est :
```text
binaire
maximum 1 048 576 octets
entiers multi-octets = unsigned big-endian
ordre des champs = normatif
aucun padding implicite
aucune Base64
aucune compression
aucun trailing byte
```
Les longueurs sont exprimées en **octets**.
Une implémentation conforme doit vérifier les bornes **avant** toute allocation dépendant d'une longueur reçue. Le document entier est déjà borné par `1 048 576` octets avant parsing.
## 4. Header V2
Le début de fichier est strictement :
| Ordre | Champ | Taille | Valeur / règle |
|------:|---------------------------|-----------------:|------------------------------------------------|
| 1 | `magic` | 9 | ASCII exact `KSPWALLET` |
| 2 | `format_version` | 2 | `0x0002` |
| 3 | `document_length` | 4 | longueur totale exacte du fichier |
| 4 | `flags` | 2 | bit 0 = VIEW activé ; tous les autres bits = 0 |
| 5 | `owner_auth_public_key` | 32 | clé publique Ed25519 OWNER |
| 6 | `view_descriptor.slot_id` | 16 conditionnels | présent uniquement si `flags & 0x0001 != 0` |
Offsets fixes avant le descripteur conditionnel :
```text
0x0000..0x0008 magic
0x0009..0x000A format_version
0x000B..0x000E document_length
0x000F..0x0010 flags
0x0011..0x0030 owner_auth_public_key
```
Pour un wallet VIEW-enabled, `view_descriptor.slot_id` occupe ensuite `0x0031..0x0040`.
### 4.1 Flags
```text
0x0001 VIEW_ENABLED
0xFFFE réservé, doit être zéro
```
Tout bit réservé non nul rend le document invalide. V2 n'emploie pas les bits réservés comme mécanisme d'extension silencieuse ; une modification incompatible exige un nouveau format.
## 5. Ordre canonique du body
Après le header :
```text
OWNER key slot obligatoire
VIEW key slot présent seulement si VIEW_ENABLED
OWNER-CONTROL encrypted compartment obligatoire
METADATA encrypted compartment obligatoire
SECRET encrypted compartment obligatoire
state signature obligatoire
EOF immédiat
```
Aucun compteur de slots ou de compartiments n'est nécessaire : leur cardinalité et leur ordre sont déterminés par V2.
## 6. Key slot V2
Chaque key slot est encodé ainsi :
| Champ | Taille | Valeur / règle |
|--------------------------|---------:|-----------------------------------------|
| `role` | 1 | `0x01` OWNER, `0x02` VIEW |
| `slot_id` | 16 | identifiant binaire exact |
| `kdf_algorithm` | 1 | `0x01` Argon2id |
| `kdf_version` | 4 | `19` |
| `memory_kib` | 4 | `1..1 048 576`, et `>= parallelism * 8` |
| `iterations` | 4 | `1..64` |
| `parallelism` | 4 | `1..64` |
| `salt_length` | 1 | `16..64` |
| `salt` | variable | exactement `salt_length` octets |
| `wrap_algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `wrap_nonce` | 24 | nonce exact |
| `wrap_ciphertext_length` | 2 | `16..4096` |
| `wrap_ciphertext` | variable | exactement la longueur déclarée |
Ordre obligatoire :
```text
premier slot = OWNER
second slot = VIEW seulement si VIEW_ENABLED
```
Si VIEW est activé :
```text
header.view_descriptor.slot_id == VIEW key slot.slot_id
```
Toute divergence est invalide avant KDF/déchiffrement.
## 7. Compartiments V2
Chaque compartiment est encodé :
| Champ | Taille | Valeur / règle |
|---------------------|---------:|------------------------------------------------------|
| `kind` | 1 | `0x01` OWNER-CONTROL, `0x02` METADATA, `0x03` SECRET |
| `payload_version` | 4 | `1` pour le profil initial V2 |
| `algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `nonce` | 24 | nonce exact |
| `ciphertext_length` | 4 | longueur exacte |
| `ciphertext` | variable | ciphertext + tag Poly1305 |
Bornes initiales :
```text
OWNER-CONTROL : 16..4096 octets
METADATA : 16..65552 octets
SECRET : 16..4096 octets
```
L'ordre exact est OWNER-CONTROL, METADATA, SECRET. Le `kind` encodé doit correspondre à la position attendue ; il n'autorise pas un réordonnancement.
Les payloads plaintext V2 conservent le modèle fonctionnel établi en V1 pour cette évolution : owner-control, metadata et secret Solana restent des compartiments distincts. Une future modification incompatible de leur sémantique exige une version de format explicite.
## 8. Signature d'état
La fin du document est :
| Champ | Taille | Valeur / règle |
|-----------------------------|-------:|---------------------------|
| `state_signature.algorithm` | 1 | `0x01` Ed25519 |
| `state_signature.signature` | 64 | signature detached exacte |
Aucun octet ne peut suivre ces 65 octets.
## 9. Identifiants numériques figés
### 9.1 Rôles
```text
0x01 OWNER
0x02 VIEW
```
### 9.2 Algorithmes
```text
KDF
0x01 Argon2id
AEAD
0x01 XChaCha20-Poly1305
state signature
0x01 Ed25519
```
### 9.3 Compartiments
```text
0x01 OWNER-CONTROL
0x02 METADATA
0x03 SECRET
```
`0x00` est invalide dans ces espaces. Les autres valeurs sont réservées et rejetées par V2 tant qu'elles ne sont pas explicitement normalisées par une évolution compatible documentée ; aucune valeur inconnue n'est devinée.
## 10. Canonicalité et rejet
Le parser V2 doit rejeter avant crypto :
```text
fichier > 1 MiB
magic incorrect
format_version != 2
document_length différent de la taille reçue
flag réservé non nul
champ tronqué
longueur qui dépasse le reste du document
role/algorithm/kind inconnu
ordre OWNER/VIEW invalide
VIEW descriptor et VIEW slot incohérents
Argon2 hors bornes
salt hors bornes
ciphertext hors bornes
payload_version non supporté
trailing bytes
```
Il n'existe qu'un encodage canonique d'un même état sémantique V2 : mêmes champs, même ordre, mêmes largeurs, même endianness et aucune donnée ignorée.
## 11. Transcripts et AAD V2
V2 possède ses propres domaines ; V1 et V2 ne partagent jamais un domain separator :
```text
KSPWALLET-V2-STATE
KSPWALLET-V2-AAD-OWNER-SLOT
KSPWALLET-V2-AAD-VIEW-SLOT
KSPWALLET-V2-AAD-OWNER-CONTROL
KSPWALLET-V2-AAD-METADATA
KSPWALLET-V2-AAD-SECRET
```
Le transcript/AAD V2 conserve la discipline TLV déterministe de V1 :
```text
domain || 0x00
puis pour chaque champ :
tag:u16 big-endian
length:u64 big-endian
value:length bytes
```
Les tags restent alignés avec les familles V1 :
```text
0x0001 magic
0x0002 format_version
0x0003 owner_auth_public_key
0x0010 view_enabled
0x0011 view_role
0x0012 view_slot_id
0x0100 slot_id
0x0101 slot_role
0x0102 kdf_algorithm
0x0103 kdf_version
0x0104 kdf_memory_kib
0x0105 kdf_iterations
0x0106 kdf_parallelism
0x0107 kdf_salt
0x0108 wrap_algorithm
0x0109 wrap_nonce
0x010A wrap_ciphertext
0x0200 compartment_kind
0x0201 compartment_version
0x0202 compartment_algorithm
0x0203 compartment_nonce
0x0204 compartment_ciphertext
0x0500 state_signature_algorithm
```
Différence normative V2 : les rôles/algorithmes/kinds sont transcriptés sous leur **ID numérique d'un octet**, et `format_version = 2` est transcripté en `u32` big-endian. Les domaines distincts empêchent qu'un transcript V1 et un transcript V2 soient interchangeables.
### 11.1 State transcript
Le state transcript contient :
```text
common
view descriptor
OWNER slot avec wrap nonce+ciphertext
OWNER-CONTROL avec nonce+ciphertext
METADATA avec nonce+ciphertext
SECRET avec nonce+ciphertext
state signature algorithm
```
Le VIEW wrap mutable n'est pas ajouté au state transcript, selon le modèle d'autorisation VIEW déjà retenu : son identité stable reste liée par le descriptor signé tandis que son credential peut être self-rotaté sans OWNER.
### 11.2 Slot AAD
Le slot AAD contient :
```text
common
slot_id
role
KDF algorithm/version/parameters/salt
wrap algorithm
```
Le wrap nonce/ciphertext n'est pas inclus dans son propre AAD.
### 11.3 Compartment AAD
Le compartment AAD contient :
```text
common
kind
payload_version
algorithm
```
Le nonce/ciphertext n'est pas inclus dans son propre AAD.
## 12. V1 et V2
V1 et V2 sont deux formats explicites :
| Propriété | V1 | V2 |
|--------------------------|------------------------------------|---------------|
| enveloppe | JSON UTF-8 | binaire KSP |
| champs binaires | Base64url no-pad | bytes directs |
| version | `1` | `2` |
| canonicalité | sémantique JSON + Base64 canonique | byte-exact |
| taille fixture wire-only | 2037 octets | 628 octets |
| Argon2id | oui | oui |
| XChaCha20-Poly1305 | oui | oui |
| Ed25519 OWNER state | oui | oui |
| VIEW/OWNER | oui | oui |
La réduction mesurée sur le fixture structurel de référence est :
```text
2037 -> 628 octets
-1409 octets
~69,2 %
```
Cette mesure n'est pas une promesse de ratio constant : la taille dépend notamment des metadata chiffrées.
## 13. Fixture structurelle
Fixture canonique de `pre.015` :
```text
crates/ksp-wallet-lib/tests/fixtures/kspwallet_v2_wire_only.bin
size = 628
sha256 = cbacb37326c76e6dde8d614601cd765a8c0fd9744f891d640b8a3cd71cf60a93
```
Préfixe hexadécimal :
```text
4b535057414c4c4554 0002 00000274 0001
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
202122232425262728292a2b2c2d2e2f
```
Lecture :
```text
4b535057414c4c4554 = "KSPWALLET"
0002 = format_version V2
00000274 = 628 octets
0001 = VIEW_ENABLED
```
La fixture `wire_only` vérifie framing/canonicalité ; elle n'est pas présentée comme une signature cryptographique V2 valide tant que la création/open V2 n'est pas intégrée par la tranche suivante.
## 14. Compatibilité et migration
V2 n'autorise aucune migration implicite à l'ouverture.
Politique prévue :
```text
lecture générique V1/V2 oui
création générique V2
création V1 forcée oui
création V2 forcée oui
réécriture V1 -> V2 cachée non
migration V1 -> V2 opération explicite
```
Une migration doit authentifier le wallet source avec la capability requise, produire un nouveau document V2 valide et respecter la persistence no-clobber/atomique. Une simple transcodification non authentifiée des bytes V1 n'est pas suffisante puisque V2 possède ses propres domains/transcripts.
## 15. Future V3 / second facteur
V2 ne réalise aucun second facteur.
Si un futur V3 ajoute une autorisation dépendant d'un facteur externe :
```text
ksp-wallet-lib possède la règle qui exige le facteur
ksp-wallet-lib possède le challenge et la validation cryptographique
aucun WalletOwner ne peut être obtenu si le facteur requis n'est pas satisfait
Wallet Desk ne décide jamais que le second facteur est valide
```
Une UI comme Wallet Desk peut néanmoins devoir évoluer pour orchestrer l'expérience : attente de confirmation, saisie OTP, enrollment, recovery, hardware/WebAuthn ou consentement externe.
Le réseau ou le fournisseur externe ne doit pas forcer `ksp-wallet-lib` à dépendre directement de Config/Transport/Tauri. Une abstraction/provider KSP séparée peut fournir la preuve à Wallet tandis que Wallet reste propriétaire de la politique d'autorisation.
L'arrivée d'un V3 ne change pas automatiquement le default : V2 peut rester `DEFAULT_WALLET_FORMAT` aussi longtemps que KSP le décide explicitement.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/000-README.md -->
<!-- version: 49 -->
<!-- version: 50 -->
# Plans KSP
@@ -21,7 +21,7 @@ Un plan décrit le périmètre, les décisions déjà acquises, les questions ou
- [`010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) — plan historique clôturé de la release stable `0.2.3 — HTTP Transactions`, ouvert par `pre.001`, exécuté jusqu'à `pre.009` puis publié par `rel.001`; il couvre les 11 méthodes, la classification `8 Read / 2 WriteSubmission / 1 Simulation`, `KSP-TRANSPORT-007`, le no-resend et la préparation de `0.2.4`.
- [`011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan historique clôturé de la release stable `0.2.4`, ouvert par `pre.001`, exécuté jusquà `pre.009`, complété par le fix documentaire Wallet `pre.009-fix.001` puis publié par `rel.001`; il couvre les 10 Blocks + 5 Economics et la compliance finale `52/52 + 14/14` sous `KSP-TRANSPORT-007`.
- [`012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](012-V0_2_5_WALLET_FOUNDATION_PLAN.md) — plan historique clôturé de la release stable `0.2.5 — Wallet foundation`, ouvert par `pre.001`, livré jusquà `pre.010`, renforcé par `pre.010-fix.001``fix.003` pour Dalek 3 et la normalisation Rust/audit structurel, puis publié par `rel.001`; il couvre `.kspwallet` V1, VIEW/OWNER, crypto, persistence, administration, transfer et compliance.
- [`013-V0_2_6_WALLET_DESK_PLAN.md`](013-V0_2_6_WALLET_DESK_PLAN.md) — plan actif de `0.2.6 — Wallet Desk`, ouvert par `pre.001`; `pre.002` matérialise le shell Tauri et `pre.003` la composition `std.wallet`/composite ainsi que la préparation des répertoires. Le plan fixe aussi secrets `KSP_SECRET_WALLET_PASS_*`, inventory DataTables/path safety, lifecycle VIEW/OWNER, screen/command/DTO maps, balance HTTP, administration retenue et forecast souple détaillé jusquà `pre.015`, avec `pre.014` réservé au polish Bootstrap/splashscreen puis `pre.015` à la documentation finale, au prompt `0.2.7` et au build Tauri final.
- [`013-V0_2_6_WALLET_DESK_PLAN.md`](013-V0_2_6_WALLET_DESK_PLAN.md) — plan actif de `0.2.6 — Wallet Desk`, ouvert par `pre.001`; `pre.002` matérialise le shell Tauri et `pre.003` la composition `std.wallet`/composite ainsi que la préparation des répertoires. Le plan fixe aussi secrets `KSP_SECRET_WALLET_PASS_*`, inventory DataTables/path safety, lifecycle VIEW/OWNER, screen/command/DTO maps, balance HTTP, administration retenue et forecast étendu jusquà `pre.018` : `pre.014` polish Bootstrap/splashscreen, `pre.015` wire binaire `.kspwallet` V2, `pre.016` APIs génériques/versionnées + V2, `pre.017` migration/canaris, puis `pre.018` documentation candidate et build Tauri final.
Le `pre.001` de chaque release fonctionnelle peut introduire son propre plan détaillé lorsque la release s'ouvre.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 75 -->
<!-- version: 76 -->
# Séquence des releases fonctionnelles KSP
@@ -361,14 +361,13 @@ Par défaut :
0.2.4 HTTP Blocks + Economics + compliance complète
0.2.5 wallet foundation (.kspwallet)
0.2.6 Wallet Desk
0.2.7 .kspwallet binary persistence container
0.2.8 standard Solana WebSocket
0.2.9 Helius LaserStream WebSocket
0.2.10 Yellowstone gRPC standard foundation
0.2.11 off-chain price transport
0.2.12 price visualization desk + intégration prix dans Wallet Desk
0.2.13 interface/wire foundation
0.2.14 program-api foundation
0.2.7 standard Solana WebSocket
0.2.8 Helius LaserStream WebSocket
0.2.9 Yellowstone gRPC standard foundation
0.2.10 off-chain price transport
0.2.11 price visualization desk + intégration prix dans Wallet Desk
0.2.12 interface/wire foundation
0.2.13 program-api foundation
```
`0.2.1-pre.001` a appliqué le gate de sizing et refusé le scope HTTP monolithique initial : l'inventaire du 2026-08-17 contient 52 méthodes courantes et 14 méthodes Deprecated historiques. Ce premier delta avait réparti la couverture typée sur `0.2.1``0.2.6`. `0.2.1-pre.001-fix.001` recalibre ensuite les 48 méthodes restantes sur trois releases complémentaires `0.2.2``0.2.4`, soit trois sessions nominales au maximum si chaque release utilise sa session complète. Si une release se clôt plus vite que prévu, la même session peut enchaîner la suivante après clôture complète de la précédente et nouveau gate de sizing positif. Un Wallet Desk utile doit pouvoir lire le solde du wallet : `getBalance` fait donc partie des quatre canaris de la foundation `0.2.1`, avant Wallet. Les transports live arrivent ensuite ; Interface/Program restent préparés avant les couches de données décodées.
@@ -443,29 +442,26 @@ pre.011 disable/recreate VIEW fort
pre.012 export OWNER fichier CLI JSON/Base58
pre.013 intégration, compliance, sécurité et smoke
pre.014 polish du gabarit Bootstrap et du splashscreen
pre.015 documentation finale, validations, prompt 0.2.7 et cargo tauri build en dernière opération
pre.015 .kspwallet V2 wire binaire + codec canonique
pre.016 APIs génériques/versionnées + création/ouverture V2
pre.017 migration V1 -> V2 + persistence/canaris + régression Wallet Desk
pre.018 documentation finale, validations, prompt 0.2.7 et cargo tauri build en dernière opération
rel.001 publication stable 0.2.6
```
La tranche `pre.014` est réservée aux défauts visuels/templating observés en usage réel, notamment les scrollbars occasionnelles du splashscreen ; son contenu précis sera borné à partir du retour opérateur avant implémentation. `ROADMAP.md` reste synthétique et `CHANGELOG.md` n'est synchronisé qu'à la phase documentaire finale.
## `0.2.7` — `.kspwallet` binary persistence container
Mission : faire évoluer uniquement la couche de persistence de `ksp-wallet-lib` afin quun `.kspwallet` nouvellement écrit ne soit plus un document JSON directement lisible dans un éditeur texte ordinaire, sans prétendre ajouter de sécurité cryptographique par simple obfuscation.
Le gate `pre.001` doit comparer framing binaire custom, codecs binaires stables et éventuelle compression, puis fixer un conteneur explicitement versionné. Base64 seul est exclu comme solution : il reste textuel, trivialement réversible et augmente la taille. Le conteneur et le `format_version` logique/cryptographique sont séparés afin de conserver V1 pour les semantics VIEW/OWNER actuelles et de réserver les futurs formats logiques à de vraies évolutions dautorisation. La lecture rétrocompatible des JSON V1 historiques et les migrations/test vectors sont obligatoires. Wallet Desk ne doit pas être modifié fonctionnellement ; ses tests/smokes sont rejoués comme preuve consommateur.
## `0.2.8` — WebSocket Solana standard
## `0.2.7` — WebSocket Solana standard
Mission : couvrir la surface WebSocket standard officielle ciblée.
Une URL peut avoir plusieurs sessions physiques ; une session peut avoir plusieurs subscriptions. Un pool automatique de sessions est reporté jusqu'à besoin concret.
## `0.2.9` — Helius LaserStream WebSocket
## `0.2.8` — Helius LaserStream WebSocket
Mission : étendre le moteur WebSocket standard avec les opérations/filtres/capabilities Helius ciblés sans copier le client.
## `0.2.10` — Yellowstone gRPC standard
## `0.2.9` — Yellowstone gRPC standard
Mission : introduire un backend Yellowstone standard/provider-neutral.
@@ -473,21 +469,21 @@ Le `pre.001` est un gate de sizing : inventorier toute la surface normative cibl
Les profiles/adapters Helius/Triton/ERPC/Chainstack/Shyft sont reportés après les priorités fondatrices.
## `0.2.11` / `0.2.12` — Off-chain price + app
## `0.2.10` / `0.2.11` — Off-chain price + app
`0.2.11` introduit `ksp-offchain-transport-lib` avec au minimum SOL/USD et SOL/EUR via une abstraction indépendante du premier provider.
`0.2.10` introduit `ksp-offchain-transport-lib` avec au minimum SOL/USD et SOL/EUR via une abstraction indépendante du premier provider.
`0.2.12` ajoute une petite application desk de visualisation/validation. Après stabilisation de cette application spécialisée, la même release doit intégrer la capacité de prix offchain dans `ksp-app-wallet-desk` sans dupliquer la récupération/normalisation appartenant au composant spécialisé.
`0.2.11` ajoute une petite application desk de visualisation/validation. Après stabilisation de cette application spécialisée, la même release doit intégrer la capacité de prix offchain dans `ksp-app-wallet-desk` sans dupliquer la récupération/normalisation appartenant au composant spécialisé.
Metadata HTTP/IPFS/Arweave viendra au premier besoin Metadata réel.
## `0.2.13` — Interface foundation
## `0.2.12` — Interface foundation
`ksp-interface-lib` devient la façade wire officielle et expose une API publique wire utilisable par les implementations officielles et externes.
Aucune `ksp-interface-api` séparée n'est retenue pour l'instant.
## `0.2.14` — Program API foundation
## `0.2.13` — Program API foundation
Introduire `ksp-program-api`, sans suffixe `-lib`, comme contrat d'extension Program.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/013-V0_2_6_WALLET_DESK_PLAN.md -->
<!-- version: 32 -->
<!-- version: 33 -->
# Plan `0.2.6` — Wallet Desk
@@ -771,32 +771,32 @@ outil de logging contrôlé
## 12. Command map
| Command | Entrée frontend | Sortie sûre | Délégation |
|----------------------------------------------|--------------------|-------------------------------------|---------------------------------|
| `get_runtime_status` | — | `WalletRuntimeStatusDto` | Config/app state |
| `list_wallets` | — | `Vec<WalletInventoryEntryDto>` | app filesystem + Wallet inspect |
| `refresh_wallets` | — | inventory DTO | app filesystem + Wallet inspect |
| `select_wallet` | wallet id | `LockedWalletDto` | app resolver + Wallet inspect |
| `deselect_wallet` | — | session DTO | app state |
| `create_wallet` | create request | `WalletAuthorizedDto` OWNER | Wallet create file |
| `unlock_wallet_view` | password | authorized VIEW | Wallet open VIEW |
| `unlock_wallet_owner` | password | authorized OWNER | Wallet open OWNER |
| `unlock_wallet_view_with_configured_secret` | — | authorized VIEW / operation result | Config env + Wallet open VIEW |
| `unlock_wallet_owner_with_configured_secret` | — | authorized OWNER / operation result | Config env + Wallet open OWNER |
| `lock_wallet` | — | `LockedWalletDto` | drop handle + inspect |
| `refresh_wallet_balance` | — | `WalletBalanceDto` | Transport getBalance |
| `inspect_import_source` | format only | transfer inspection DTO / cancel | Rust native picker + Wallet inspect |
| `import_wallet` | import request | authorized OWNER | staged bytes + Wallet import |
| `update_wallet_alias` | alias mutation | authorized DTO | WalletOwner |
| `add_wallet_note` | note create | authorized DTO | WalletOwner |
| `update_wallet_note` | note update | authorized DTO | WalletOwner |
| `delete_wallet_note` | note id | authorized DTO | WalletOwner |
| `rotate_owner_password` | rotation request | operation result | WalletOwner |
| `rotate_view_password` | rotation request | operation result | WalletOwner |
| `disable_view` | confirmation | authorized DTO | WalletOwner |
| `recreate_view` | new VIEW password | authorized DTO | WalletOwner |
| `export_wallet_owner` | format + save path | operation result | Wallet export file |
| `emit_frontend_log` | redacted payload | `()` | Logging facade |
| Command | Entrée frontend | Sortie sûre | Délégation |
|----------------------------------------------|--------------------|-------------------------------------|-------------------------------------|
| `get_runtime_status` | — | `WalletRuntimeStatusDto` | Config/app state |
| `list_wallets` | — | `Vec<WalletInventoryEntryDto>` | app filesystem + Wallet inspect |
| `refresh_wallets` | — | inventory DTO | app filesystem + Wallet inspect |
| `select_wallet` | wallet id | `LockedWalletDto` | app resolver + Wallet inspect |
| `deselect_wallet` | — | session DTO | app state |
| `create_wallet` | create request | `WalletAuthorizedDto` OWNER | Wallet create file |
| `unlock_wallet_view` | password | authorized VIEW | Wallet open VIEW |
| `unlock_wallet_owner` | password | authorized OWNER | Wallet open OWNER |
| `unlock_wallet_view_with_configured_secret` | — | authorized VIEW / operation result | Config env + Wallet open VIEW |
| `unlock_wallet_owner_with_configured_secret` | — | authorized OWNER / operation result | Config env + Wallet open OWNER |
| `lock_wallet` | — | `LockedWalletDto` | drop handle + inspect |
| `refresh_wallet_balance` | — | `WalletBalanceDto` | Transport getBalance |
| `inspect_import_source` | format only | transfer inspection DTO / cancel | Rust native picker + Wallet inspect |
| `import_wallet` | import request | authorized OWNER | staged bytes + Wallet import |
| `update_wallet_alias` | alias mutation | authorized DTO | WalletOwner |
| `add_wallet_note` | note create | authorized DTO | WalletOwner |
| `update_wallet_note` | note update | authorized DTO | WalletOwner |
| `delete_wallet_note` | note id | authorized DTO | WalletOwner |
| `rotate_owner_password` | rotation request | operation result | WalletOwner |
| `rotate_view_password` | rotation request | operation result | WalletOwner |
| `disable_view` | confirmation | authorized DTO | WalletOwner |
| `recreate_view` | new VIEW password | authorized DTO | WalletOwner |
| `export_wallet_owner` | format + save path | operation result | Wallet export file |
| `emit_frontend_log` | redacted payload | `()` | Logging facade |
Aucune commande de signature arbitraire n'est ajoutée dans cette release.
@@ -1677,7 +1677,7 @@ workspace checkpoint complet
Le smoke live est volontairement `ignored` dans `cargo test --workspace`. Il doit être déclenché explicitement avec un `KSP_WALLETS_DIRECTORY` dédié ; le test charge ce paramètre uniquement via `ConfigEnvironment`, crée un `.kspwallet` réel dans le répertoire effectif du profil composite, ouvre VIEW, exécute `getBalance` via le Transport composite puis supprime le wallet canari. Ainsi le smoke cross-crates vit dans la surface d'orchestration Wallet Desk et non dans Config ou Transport.
Cette tranche doit produire la preuve que les surfaces ajoutées fonctionnent ensemble avant le polish visuel `pre.014` et la documentation finale `pre.015`.
Cette tranche doit produire la preuve que les surfaces ajoutées fonctionnent ensemble avant le polish visuel `pre.014` et les tranches V2 binaires intercalées avant la candidate finale.
### `pre.014` — polish gabarit Bootstrap et splashscreen
@@ -1693,25 +1693,65 @@ réutilisation du gabarit commun sans déplacer de logique métier
Cette tranche n'est pas un prétexte pour refondre l'UX métier. Les détails précis des défauts et critères d'acceptation seront fournis par l'opérateur lorsqu'elle sera ouverte.
### `pre.015` — documentation finale, candidate build et prompt suivant
### `pre.015` — `.kspwallet` V2 : wire binaire + codec canonique
Cette tranche intercalée remplace l'ancien départ immédiat en documentation finale. Elle fixe le wire binaire V2 et son codec structurel dans `ksp-wallet-lib` sans modifier encore Wallet Desk ni les APIs de persistence V1 utilisées en production.
```text
KSPWALLET magic binaire
format_version = 2
longueur totale explicite
flags réservés stricts
OWNER puis VIEW optionnel
Argon2id / XChaCha20-Poly1305 / Ed25519 par IDs numériques
compartiments OWNER-CONTROL / METADATA / SECRET
entiers big-endian
aucune Base64
aucune compression
aucun trailing byte
domains/transcripts/AAD V2 distincts de V1
fixture wire-only canonique + comparaison de taille
```
La politique API est figée dès cette tranche : `DEFAULT_WALLET_FORMAT` et `LATEST_SUPPORTED_WALLET_FORMAT` sont deux notions distinctes. À l'intégration V2, le default devient V2. Une future V3 n'entraîne jamais automatiquement le déplacement du default.
### `pre.016` — APIs génériques/versionnées + création/ouverture V2
Matérialiser :
```text
create_wallet_file(...) -> V2 par default explicite
create_wallet_file_v1(...) conservé
create_wallet_file_v2(...) ajouté
open/inspect génériques -> détection V1/V2
open/inspect _v1/_v2 -> format forcé strict
create/open in-memory V2 + crypto/transcripts V2
Wallet Desk migre vers les APIs génériques, jamais vers un numéro de format
```
Une future API `_v3` pourra être ajoutée sans transformer automatiquement le default en V3.
### `pre.017` — migration V1 -> V2 + persistence/canaris
Ajouter la migration explicite et authentifiée V1 vers V2, les paths de remplacement/no-clobber nécessaires, les canaris adversariaux/interop et la régression complète Wallet Desk. Aucune migration silencieuse lors d'une simple ouverture.
### `pre.018` — documentation finale, candidate build et prompt suivant
Dernière tranche prévue avant `rel.001` :
```text
crates/ksp-app-wallet-desk/README.md
crates/ksp-app-wallet-desk/USAGE.md
docs/architecture / inventory / dependency graph synchronisés si impactés
README/USAGE Wallet Desk
docs/validation 0.2.6 finalisée
ROADMAP / functional sequence / CHANGELOG synchronisés
stratégie CWD/resources release packagée fermée
dépendances et versions finales réauditées
commandes smoke documentées
prompt de démarrage 0.2.7 préparé
validation Rust workspace finale
parcours fonctionnel cargo tauri dev final
prompt de démarrage 0.2.7 WebSocket finalisé
cargo tauri build en toute dernière opération
```
Si le build final ou la documentation révèle une correction technique, utiliser `pre.015-fix.NNN` ou insérer une tranche supplémentaire. `pre.015` n'est pas une obligation de clôture artificielle.
Si une correction technique apparaît, utiliser `pre.018-fix.NNN` ou insérer une tranche supplémentaire.
### `rel.001` — publication stable
@@ -1871,7 +1911,7 @@ KSP_WALLETS_DIRECTORY=var/wallet-desk-pre014 \
bash -lc 'cd crates/ksp-app-wallet-desk && cargo tauri dev'
```
Le build Tauri de production reste reporté à `pre.015` et doit demeurer labsolue dernière opération.
À ce stade de `pre.014`, le build Tauri de production était encore reporté à `pre.015`. Cette décision historique est **superseded par lextension décidée en `pre.015`** : le build final est désormais réservé à `pre.018` et doit demeurer labsolue dernière opération.
### Correctif `0.2.6-pre.014-fix.001` — layout desktop et canari durable
@@ -1887,6 +1927,6 @@ splash : feed #debug-info pleine largeur dans les deux Desks
pre.013 gate : le canari ne fige plus une shell_phase destinée à évoluer à chaque tranche
```
Le recalage du CWD n'existe actuellement qu'en `debug_assertions` dans les deux `main.rs`. La candidate `pre.015` doit donc vérifier explicitement la stratégie de résolution production/bundle pour `config`, `.env`, `logs` et `wallets` avant le build final ; le comportement release ne doit pas être supposé identique au parcours `cargo tauri dev`.
Le recalage du CWD n'existe actuellement qu'en `debug_assertions` dans les deux `main.rs`. La candidate finale `pre.018` doit donc vérifier explicitement la stratégie de résolution production/bundle pour `config`, `.env`, `logs` et `wallets` avant le build final ; le comportement release ne doit pas être supposé identique au parcours `cargo tauri dev`.
Ce fix touche le frontend/build contract et porte donc le signal technique `workspace.package.version = 0.2.6-pre.14.fix.1`. `ROADMAP.md`, `CHANGELOG.md` et `docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md` restent inchangés.

View File

@@ -1,11 +1,11 @@
<!-- file: docs/validation/009-V0_2_6_WALLET_DESK_COMPLIANCE.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# Validation `0.2.6` — Wallet Desk integration / compliance / security
## 1. Objet
Cette matrice est ouverte par `0.2.6-pre.013` comme preuve durable de composition et de conformité de `ksp-app-wallet-desk`. Elle sera complétée en `pre.015` avec les résultats finaux, le polish visuel de `pre.014`, la documentation de clôture et le dernier build Tauri.
Cette matrice est ouverte par `0.2.6-pre.013` comme preuve durable de composition et de conformité de `ksp-app-wallet-desk`. Le calendrier a été étendu après `pre.014` : `pre.015` introduit le wire V2, `pre.016` les APIs génériques/versionnées, `pre.017` migration/régression, puis `pre.018` porte la clôture documentaire et le dernier build Tauri.
Elle ne remplace ni le plan [`../plans/013-V0_2_6_WALLET_DESK_PLAN.md`](../plans/013-V0_2_6_WALLET_DESK_PLAN.md), ni la matrice Wallet V1 [`008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md), ni les deltas `0.2.6`.
@@ -51,19 +51,19 @@ Le checkpoint opérateur `pre.012` du 21 août 2026 est vert : `cargo fmt`, audi
## 3. Matrice de frontières
| Frontière | Contrat `0.2.6` | Preuve durable |
|---|---|---|
| Frontend -> Config | aucun accès direct env/.env | `release_compliance::backend_keeps_config_wallet_transport_and_logging_ownership_boundaries` + ownership Config |
| Frontend -> Wallet secret | passwords uniquement request-only ; jamais de keypair en IPC | `desktop_security` + `release_compliance::response_dtos_keep_secret_key_material_out_of_ipc` |
| Frontend -> filesystem | aucun path arbitraire ; picker natif Rust | tests import/export + capability audit |
| Frontend -> réseau Solana | aucun `fetch`/WebSocket/RPC direct | `release_compliance::frontend_has_no_direct_filesystem_network_or_secret_persistence_surface` |
| Wallet Desk -> Solana crates | aucune dépendance protocole directe | `release_compliance::wallet_desk_dependency_firewall_and_tauri_capabilities_are_minimal` |
| Wallet Desk -> HTTP | `ksp-onchain-transport-lib` uniquement | manifest + smoke Devnet |
| Wallet Desk -> Wallet crypto | `ksp-wallet-lib` uniquement | manifest + feature canaries |
| Wallet Desk -> logging | façade `ksp-logging-lib` + adapter `tauri-plugin-tracing` | source audit + workspace logging canary |
| locked -> frontend | format/version/VIEW enabled seulement | `desktop_security` |
| VIEW/OWNER handles | Rust-only `AppState` | session/security tests |
| export | OWNER-only, file direct, no-clobber | `desktop_security` + runtime `pre.012` |
| Frontière | Contrat `0.2.6` | Preuve durable |
|------------------------------|--------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|
| Frontend -> Config | aucun accès direct env/.env | `release_compliance::backend_keeps_config_wallet_transport_and_logging_ownership_boundaries` + ownership Config |
| Frontend -> Wallet secret | passwords uniquement request-only ; jamais de keypair en IPC | `desktop_security` + `release_compliance::response_dtos_keep_secret_key_material_out_of_ipc` |
| Frontend -> filesystem | aucun path arbitraire ; picker natif Rust | tests import/export + capability audit |
| Frontend -> réseau Solana | aucun `fetch`/WebSocket/RPC direct | `release_compliance::frontend_has_no_direct_filesystem_network_or_secret_persistence_surface` |
| Wallet Desk -> Solana crates | aucune dépendance protocole directe | `release_compliance::wallet_desk_dependency_firewall_and_tauri_capabilities_are_minimal` |
| Wallet Desk -> HTTP | `ksp-onchain-transport-lib` uniquement | manifest + smoke Devnet |
| Wallet Desk -> Wallet crypto | `ksp-wallet-lib` uniquement | manifest + feature canaries |
| Wallet Desk -> logging | façade `ksp-logging-lib` + adapter `tauri-plugin-tracing` | source audit + workspace logging canary |
| locked -> frontend | format/version/VIEW enabled seulement | `desktop_security` |
| VIEW/OWNER handles | Rust-only `AppState` | session/security tests |
| export | OWNER-only, file direct, no-clobber | `desktop_security` + runtime `pre.012` |
## 4. Inventory / path adversarial
@@ -238,4 +238,9 @@ cargo test --workspace : BLOCKED par un faux positif du canari Logging global
Le blocage workspace est limité à `ksp-logging-lib/tests/ownership.rs::workspace_crates_do_not_bypass_ksp_logging_facade` : le scanner voit le littéral `tracing::` dans `release_compliance.rs`, alors que ce littéral est la chaîne recherchée par le canari et non un usage de `tracing`. `pre.013-fix.002` supprime ce littéral statique en construisant le motif à l'exécution, sans modifier le scanner global ni relâcher la politique Logging.
La matrice reste ouverte jusqu'à `pre.015`, où seront ajoutés le résultat du polish `pre.014`, le parcours fonctionnel final, les docs README/USAGE et le build Tauri exécuté en toute dernière opération.
La matrice reste ouverte jusqu'à `pre.018`, après les tranches V2 `pre.015``pre.017`; `pre.018` ajoute le parcours fonctionnel final, README/USAGE et le build Tauri exécuté en toute dernière opération.
## 11. Intercalation V2 à partir de `pre.015`
`pre.015` ne modifie pas encore Wallet Desk : il ajoute dans `ksp-wallet-lib` un codec binaire V2 strict et une fixture canonique. Les gates Desk `pre.013`/`pre.014` restent donc applicables sans changement. `pre.016` devra faire migrer le Desk vers les APIs génériques afin quil ne connaisse plus `_v1`/`_v2`.