v0.2.5-pre.006

This commit is contained in:
2026-08-19 17:31:29 +02:00
parent dcd23abb92
commit 6094d33120
12 changed files with 649 additions and 22 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 50 -->
<!-- version: 51 -->
# Séquence des releases fonctionnelles KSP
@@ -416,6 +416,8 @@ La release doit fournir `docs/formats/KSPWALLET_V1.md` comme spécification sép
`0.2.5-pre.005` consomme ce benchmark (`64 MiB / 3 / 1 ≈ 1742 ms`, `128 MiB ≈ 3459 ms`, `256 MiB ≈ 6925 ms` sur la machine opérateur) et retient pour les créations KSP V1 `65 536 KiB / 3 / 1` avec salt 32 octets, tout en conservant les paramètres sérialisés comme autorité de lecture de chaque wallet. La tranche fixe les payloads `owner_control` (seed Ed25519 dadministration + `K_metadata` + `K_secret`), metadata strictes et secret Solana 64 octets, ajoute une autorité Ed25519 séparée de la keypair Solana et vérifie sa signature détat avant tout KDF. Les API in-memory `create_wallet_v1`, `open_wallet_view_v1`, `open_wallet_owner_v1` et `inspect_locked_wallet_v1` matérialisent lindépendance VIEW/OWNER : VIEW ne déchiffre jamais `owner_control`/secret, OWNER ne dépend pas de VIEW et la Pubkey reste un `ksp_core_lib::Pubkey`. Un vecteur `.kspwallet` complet test-only, revérifiable hors Rust, ferme linterop de cette tranche. La persistence filesystem reste explicitement `pre.006`; signature Solana publique et mutations/rotations restent `pre.007+`.
`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.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: 8 -->
<!-- version: 9 -->
# Plan `0.2.5` — Wallet foundation
@@ -432,14 +432,14 @@ L'absence d'une ligne « audited » dans ce document ne signifie donc pas « sû
### 8.7 Encodage et persistence
État au terme de `pre.005` :
État au terme de `pre.006` :
```text
base64 0.23.1 acquis depuis pre.003 pour Base64url sans padding des champs binaires JSON
tempfile 3.27.0 candidate pre.006 pour temp files same-directory + persist/persist_noclobber
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` ne sera ajouté que si `pre.006` confirme sa sémantique portable et son besoin réel pour l'atomicité/no-clobber.
`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
@@ -783,7 +783,7 @@ Pour créer/remplacer un `.kspwallet` :
6. synchroniser le répertoire parent lorsque la plateforme le permet ;
7. ne jamais considérer un fichier partiellement écrit comme nouveau wallet valide.
`tempfile::NamedTempFile`/`persist_noclobber`/`persist` est la candidate de `pre.006`, complétée par les fsync nécessaires. Sa sémantique exacte doit être testée par plateforme avant de revendiquer la durabilité crash-safe.
`pre.006` retient `tempfile::NamedTempFile` créé dans le même répertoire que la destination et `persist_noclobber` pour les créations. Le temp file est synchronisé avant publication puis le fichier publié est resynchronisé. Sur Unix, une synchronisation du répertoire parent est tentée en best-effort ; son échec est journalisé sans transformer une publication déjà réussie en échec ambigu. KSP ne revendique donc pas une durabilité power-loss/crash-safe universelle sur tous les OS/filesystems.
### 14.2 No-clobber
@@ -803,7 +803,7 @@ L'import ne fournit aucun mode overwrite/replace d'un `.kspwallet` existant et n
### 14.4 Écriture interrompue
Un crash peut laisser un temp artifact complet à nettoyer ; l'invariant prioritaire est de ne pas transformer l'ancien wallet valide en fichier partiellement remplacé. Les ACL/permissions du système d'exploitation ne font pas partie des garanties de `ksp-wallet-lib`.
`pre.006` teste un fault injecté après écriture+`sync_all` du temp file mais avant publication : aucune destination partielle n'apparaît et le temp est nettoyé lors d'un retour d'erreur normal. Un crash brutal du processus peut néanmoins laisser un temp artifact/hard-link complet selon la plateforme ; KSP ne traite jamais ces noms temporaires comme le wallet destination et ne promet pas leur suppression après kill/power-loss. L'invariant prioritaire est que `create` ne publie jamais un contenu partiel et ne remplace jamais une destination existante. Les ACL/permissions du système d'exploitation ne font pas partie des garanties de `ksp-wallet-lib`.
## 15. Erreurs et non-oracle
@@ -1049,7 +1049,20 @@ create/open KDF via spawn_blocking
vecteur complet test-only généré et revérifié indépendamment du Rust
```
La persistence, la signature Solana publique, les mutations metadata et les rotations restent volontairement absentes de cette tranche.
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`.
### 19.8 État acquis après `pre.006`
`pre.006` ajoute la frontière filesystem sans Config ni environnement :
```text
create_wallet_file_v1(path, ...) -> create in-memory -> JSON verrouillé -> temp same-directory -> sync_all -> persist_noclobber
open_wallet_view_file_v1(path, ...) -> bounded read -> open VIEW acquis
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.
## 20. Sizing
@@ -1110,7 +1123,7 @@ Toutes les dépendances tierces communes restent centralisées sous `[workspace.
Candidates restantes, à réauditer juste avant insertion :
```text
tempfile ^3.27 # pre.006 si la sémantique atomic/no-clobber est confirmée
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
```
@@ -1218,4 +1231,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.006` : persistence async/atomique/no-clobber**, 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 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.