v0.2.5-pre.006
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/formats/KSPWALLET_V1.md -->
|
||||
<!-- version: 3 -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# `.kspwallet` V1 — spécification du format natif Wallet KSP
|
||||
|
||||
@@ -764,7 +764,7 @@ Une création KSP V1 en mémoire suit conceptuellement :
|
||||
10. vérifier immédiatement la signature produite avant de retourner le handle OWNER.
|
||||
```
|
||||
|
||||
Les opérations Argon2id sont exécutées hors du thread executor async par une frontière blocking dédiée. La création `pre.005` est **in-memory** : la persistence arrive en `pre.006`.
|
||||
Les opérations Argon2id sont exécutées hors du thread executor async par une frontière blocking dédiée. La construction cryptographique reste entièrement en mémoire ; `pre.006` ajoute ensuite la publication filesystem no-clobber décrite en section 23.
|
||||
|
||||
### 21.2 Ouverture VIEW
|
||||
|
||||
@@ -830,3 +830,22 @@ wallet JSON complet
|
||||
|
||||
Le vecteur a été généré et revérifié indépendamment du code Rust avec Argon2id, XChaCha20-Poly1305 construit via HChaCha20 + ChaCha20-Poly1305 IETF et Ed25519. Une implémentation externe conforme doit pouvoir reproduire les mêmes dérivations, déchiffrements et vérifications à partir des deux fichiers sans dépendre d'un type Rust KSP.
|
||||
|
||||
## 23. Persistence native matérialisée par `pre.006`
|
||||
|
||||
La persistence ne modifie aucun octet du wire V1. Elle définit uniquement comment un document V1 complet est publié et relu :
|
||||
|
||||
```text
|
||||
caller path explicite
|
||||
-> temp file unique dans le même répertoire
|
||||
-> écriture complète des bytes JSON verrouillés
|
||||
-> sync_all(temp)
|
||||
-> persist_noclobber(destination)
|
||||
-> sync_all(fichier publié)
|
||||
-> sync parent directory best-effort sur Unix
|
||||
```
|
||||
|
||||
`create_wallet_file_v1` n'écrase jamais une destination existante. Une collision ou une course concurrente retourne `wallet.destination_exists`; il n'existe aucun mode overwrite pour create/import. Les ouvertures fichier sont bornées à `KSPWALLET_MAX_FILE_BYTES` avant parser/KDF et délèguent ensuite exactement aux procédures VIEW/OWNER des sections 21.2/21.3.
|
||||
|
||||
La couche filesystem est async-first, mais les appels OS bloquants sont regroupés derrière `tokio::task::spawn_blocking`. KSP ne lit ni Config ni environnement pour choisir le chemin et ne journalise pas les chemins par défaut.
|
||||
|
||||
La durabilité est décrite sans surpromesse : `persist_noclobber` ne garantit pas une atomicité universelle sur tous les filesystems et un crash brutal peut laisser un artefact ou hard-link temporaire complet. KSP garantit le no-clobber et l'absence de publication partielle dans le flux normal et dans les fault tests avant publication ; il ne garantit pas la suppression des temporaires après kill/power-loss ni une durabilité identique de l'entrée de répertoire sur tous les OS. Ces limites concernent la persistence et ne changent pas les garanties cryptographiques du format.
|
||||
|
||||
@@ -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 d’administration + `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 l’indé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 l’interop 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.
|
||||
|
||||
@@ -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 d’enveloppe/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 d’enveloppe/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.
|
||||
|
||||
Reference in New Issue
Block a user