v0.2.5-pre.007

This commit is contained in:
2026-08-19 18:08:01 +02:00
parent 25edcc231e
commit 46afe10423
17 changed files with 1431 additions and 59 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 51 -->
<!-- version: 52 -->
# Séquence des releases fonctionnelles KSP
@@ -418,6 +418,8 @@ 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` reprend les adapters import/export Solana CLI JSON et Base58 générique.
## `0.2.6` — Wallet Desk
Mission : valider Config composite + `.kspwallet` + transport HTTP dans une application Tauri mince.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md -->
<!-- version: 9 -->
<!-- version: 10 -->
# Plan `0.2.5` — Wallet foundation
@@ -436,9 +436,11 @@ L'absence d'une ligne « audited » dans ce document ne signifie donc pas « sû
```text
base64 0.23.1 acquis depuis pre.003 pour Base64url sans padding des champs binaires JSON
tempfile 3.27.0 acquis en pre.006 pour temp files same-directory + publication no-clobber
tempfile 3.27.0 acquis en pre.006 pour temp files same-directory + publication no-clobber / replacement administratif contrôlé
```
`pre.007` n'ajoute aucune dépendance tierce. Le remplacement administratif est lié aux capabilities VIEW/OWNER et réutilise `tempfile`; aucune primitive publique générale d'overwrite n'est introduite.
`pre.006` retient `NamedTempFile::new_in` et `persist_noclobber` parce que la publication reste sur le même filesystem et ne peut pas écraser une destination existante. La documentation upstream précise que `persist_noclobber` n'est pas atomique sur absolument toutes les plateformes/filesystems et peut laisser un hard-link temporaire après certains crashes : KSP documente cette limite au lieu de surpromettre une durabilité universelle.
## 9. Format natif `.kspwallet` V1
@@ -1049,7 +1051,7 @@ create/open KDF via spawn_blocking
vecteur complet test-only généré et revérifié indépendamment du Rust
```
La signature Solana publique, les mutations metadata et les rotations restent volontairement absentes de cette tranche ; la persistence est désormais acquise par `pre.006`.
La signature Solana publique, les mutations metadata, les rotations OWNER/VIEW, disable/recreate VIEW avec rekey metadata fort et le remplacement administratif capability-bound sont désormais acquis par `pre.007`. La keypair Solana reste encapsulée dans OWNER et n'est jamais réexportée via Core ou un getter Wallet.
### 19.8 État acquis après `pre.006`
@@ -1062,7 +1064,26 @@ open_wallet_owner_file_v1(path, ...) -> bounded read -> open OWNER acquis
inspect_locked_wallet_file_v1(path) -> bounded read -> signature-state verify sans KDF
```
La lecture est bornée à `KSPWALLET_MAX_FILE_BYTES` avant parsing, y compris si le fichier grossit entre metadata et lecture. Le filesystem blocking est exécuté via `tokio::task::spawn_blocking`. La création concurrente a exactement un gagnant ; les autres reçoivent `wallet.destination_exists`. Aucun répertoire n'est créé ou choisi par Wallet. Le replace administratif reste volontairement pour `pre.007`, où il pourra être lié à une capability OWNER ou à la self-rotation VIEW au lieu d'exposer une primitive générale d'overwrite.
La lecture est bornée à `KSPWALLET_MAX_FILE_BYTES` avant parsing, y compris si le fichier grossit entre metadata et lecture. Le filesystem blocking est exécuté via `tokio::task::spawn_blocking`. La création concurrente a exactement un gagnant ; les autres reçoivent `wallet.destination_exists`. Aucun répertoire n'est créé ou choisi par Wallet.
### 19.9 État acquis après `pre.007`
`pre.007` complète l'administration native sans ouvrir de surface de secret brut :
```text
WalletOwner::sign(message) -> signature Ed25519 Solana 64 octets
WalletOwner::update_alias(path, alias) -> metadata reencrypt + OWNER resign
WalletOwner::add/update/delete_note(path, ...) -> metadata reencrypt + OWNER resign
WalletView::rotate_view_password(path, new_pass) -> même slot_id + même K_metadata + state signature inchangée
WalletOwner::rotate_view_password(path, new_pass) -> même rotation sans ancien VIEW password
WalletOwner::rotate_owner_password(path, new_pass) -> même K_owner_root + nouveau credential + OWNER resign
WalletOwner::disable_view(path) -> nouveau K_metadata + VIEW supprimé + OWNER resign
WalletOwner::recreate_view(path, new_pass) -> nouveau K_metadata + nouveau slot_id VIEW + OWNER resign
```
Toutes les mutations persistent un état staged puis ne mettent à jour le handle qu'après publication réussie. Le replacement est crate-private et vérifie que la destination courante correspond sémantiquement à l'enveloppe authentifiée attendue ; un mauvais chemin ou un handle stale retourne `wallet.state_conflict`. Deux handles OWNER ouverts sur le même état ne peuvent donc pas s'écraser silencieusement dans le flux KSP : après la première mutation publiée, le second est stale. Ce garde-fou n'est pas présenté comme un CAS filesystem portable : une fenêtre TOCTOU subsiste entre la dernière vérification et le remplacement, et V1 ne fournit ni verrou interprocess universel ni anti-rollback externe.
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.
## 20. Sizing
@@ -1105,7 +1126,7 @@ Une `fix` ou tranche supplémentaire est préférable à la suppression d'une ga
## 22. Dépendances par tranche
État réellement acquis au terme de `pre.005` :
État réellement acquis au terme de `pre.007` :
```text
pre.002 zeroize ^1.9
@@ -1116,6 +1137,8 @@ pre.004 argon2 ^0.5
pre.005 ed25519-dalek ^2.2
solana-keypair ^3.1
tokio déjà workspace, feature locale rt pour spawn_blocking
pre.006 tempfile ^3.27
pre.007 aucune nouvelle dépendance tierce
```
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.
@@ -1123,11 +1146,12 @@ Toutes les dépendances tierces communes restent centralisées sous `[workspace.
Candidates restantes, à réauditer juste avant insertion :
```text
tempfile ^3.27 # acquis pre.006 : temp same-directory + persist_noclobber
solana-signer ^3.0 # seulement si un contrat public/impl l'exige réellement
solana-signature ^3.5 # seulement si le type public l'exige
solana-signature ^3.5 # seulement si un type public futur l'exige réellement
```
`pre.007` confirme qu'une signature Solana publique peut rester un `[u8; 64]` KSP sans ajouter `solana-signature` à la surface publique. `solana-keypair` reste propriétaire de Wallet : Core continue de réexporter uniquement la `Pubkey` transversale et ne devient pas propriétaire d'un secret/signing capability.
Déjà présents et réutilisés :
```text
@@ -1231,4 +1255,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 a ensuite permis à `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, de créer/ouvrir réellement VIEW et OWNER en mémoire et de publier un vecteur `.kspwallet` complet interopérable. **La suite immédiate est `pre.007` : signature Solana publique + administration metadata/passwords/VIEW**, sans déplacer de logique filesystem dans Config.
`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 maintenant signature Solana, administration metadata, rotations OWNER/VIEW, révocation forte VIEW et remplacement administratif contrôlé. **La suite immédiate est `pre.008` : adapters import/export, Solana CLI JSON, keypair Base58 générique et inspect des formats de transfert**, sans déplacer les secrets ni la logique Wallet dans Config.