Files
khadhroony-solana-project/deltas/0.2.5/pre.002.md
2026-08-19 09:56:01 +02:00

366 lines
12 KiB
Markdown

<!-- file: deltas/0.2.5/pre.002.md -->
<!-- version: 1 -->
# Delta `0.2.5-pre.002` — foundation crate/capabilities/passwords/errors/logging
## Base requise
```text
release : 0.2.5
prerelease : pre.002
identifiant de commit attendu : v0.2.5-pre.002
workspace.package.version : 0.2.5-pre.2
base : v0.2.5-pre.001-fix.001
```
Le delta `pre.001-fix.001` est appliqué avant cette tranche. Les deltas historiques `pre.001.md` et `pre.001-fix.001.md` restent inchangés.
## Objectif
Créer la foundation Rust de `ksp-wallet-lib` sans commencer encore le codec `.kspwallet`, le KDF/AEAD, la persistence, la keypair Solana ou la signature.
Cette tranche matérialise uniquement :
```text
crate + frontières Cargo
WalletCapability
WalletView / WalletOwner opaques
LockedWalletInfo / WalletInfo / WalletNote
ViewPassword / OwnerPassword
codes d'erreur Wallet
contrat de logging KSP
canaries public API / dependency firewall
```
Les opérations `create/open/rotate/sign/import/export` restent volontairement absentes tant que leurs invariants cryptographiques/persistence ne sont pas implémentés dans les tranches prévues.
## Version Cargo
Conformément à `VER-ID-009` :
```text
0.2.5-pre.1 -> 0.2.5-pre.2
```
Toutes les crates membres continuent d'hériter `version.workspace = true`.
## Workspace et dépendances
Nouveau membre :
```text
crates/ksp-wallet-lib
```
Dépendances directes :
```text
ksp-core-lib
ksp-logging-lib
zeroize.workspace = true
```
`zeroize` est centralisé dans `[workspace.dependencies]` :
```toml
zeroize = { version = "^1.9" }
```
La génération courante `zeroize 1.9.0` a été réauditée avant insertion. La crate est utilisée immédiatement pour nettoyer au `Drop` les buffers `String` possédés par les wrappers de passwords. Aucun `secrecy`, Argon2, AEAD, CSPRNG, Solana keypair/signer/signature ou codec supplémentaire n'est ajouté par anticipation.
Interdictions confirmées dans le manifest Wallet :
```text
ksp-config-lib
ksp-onchain-transport-lib
ksp-execution-policy-api
ksp-store-api / ksp-store-lib
Tauri
tracing direct
solana-pubkey direct
```
### Ownership de `Pubkey`
`ksp-wallet-lib` ne dépend pas directement de `solana-pubkey`.
Toute surface Wallet utilise :
```text
ksp_core_lib::Pubkey
```
qui est le re-export possédé par `ksp-core-lib`. Les futures crates `solana-keypair`/`solana-signer` ne seront ajoutées que lorsqu'un chemin de compilation les consommera réellement ; leur compatibilité avec la génération de `Pubkey` possédée par Core sera alors contrôlée par compilation et `cargo tree`.
### Aucun ownership Config
Wallet n'a aucune configuration runtime propre et ne lit ni document Config, ni `.env`, ni environnement processus.
Le futur chemin/répertoire de destination d'une création/import sera fourni explicitement par le caller. Une application pourra faire résoudre son propre défaut par Config puis transmettre ce chemin à Wallet sans créer de dépendance inverse Wallet -> Config.
## Capabilities publiques
### `WalletCapability`
Deux rôles uniquement :
```text
View
Owner
```
`View` signifie metadata autorisées plus future rotation de **son propre password VIEW uniquement**.
`Owner` signifie metadata autorisées plus futures capacités de signature/export explicite/administration.
Aucun rôle recovery/hardware/automation n'est ajouté en V1.
### `WalletView`
Handle opaque exposant actuellement uniquement la projection metadata :
```text
capability() -> View
pubkey()
alias()
notes()
info()
```
Il n'expose aucun constructeur public, aucune signature, aucun export secret, aucune mutation alias/notes et aucune administration OWNER.
La future méthode de rotation de son propre password sera ajoutée lorsque le slot VIEW réel et sa persistence existent ; `pre.002` ne simule pas cette opération.
### `WalletOwner`
Handle opaque exposant actuellement la même lecture metadata autorisée :
```text
capability() -> Owner
pubkey()
alias()
notes()
info()
```
Il n'expose encore ni secret ni signature ni méthode d'administration. Les opérations OWNER réelles sont ajoutées avec les matériaux cryptographiques/persistence correspondants dans les tranches suivantes.
### Projections metadata
`LockedWalletInfo` contient uniquement :
```text
format_version
view_enabled
```
Il ne contient aucune Pubkey, alias ou note.
`WalletInfo` contient après autorisation :
```text
format_version
capability
ksp_core_lib::Pubkey
alias optionnel
notes
```
`WalletNote` expose un identifiant stable et un texte protégé après autorisation.
Les constructors de ces projections ne sont pas publics : elles sont destinées à être produites par Wallet, pas à fabriquer une capability.
Les `Debug` de `WalletInfo`/`WalletNote` ne rendent pas alias, identifiant de note ou contenu de note. La Pubkey peut apparaître dans `WalletInfo::Debug` car cette projection n'existe qu'après autorisation et la Pubkey n'est pas un secret blockchain ; Wallet verrouillé ne possède pas cette projection.
## Password wrappers
Deux types distincts :
```text
ViewPassword
OwnerPassword
```
Ils :
- prennent ownership d'un `String` ;
- n'implémentent ni `Clone` ni `Copy` ;
- n'implémentent pas `Display` ;
- exposent un `Debug` strictement redacted ;
- implémentent un `Drop` appelant `zeroize::Zeroize` sur le buffer possédé ;
- n'exposent aucun getter public du password en clair.
Deux doctests `compile_fail` canaris interdisent la régression vers `Clone`.
Cette zeroization reste une hygiène best-effort sur le buffer possédé et ne prétend pas effacer des copies antérieures conservées par le caller, l'allocateur, les registres ou d'autres couches du runtime.
## Erreurs
Le domaine stable est :
```text
wallet
```
Les 13 codes réservés/stabilisés dans cette foundation sont :
```text
format_invalid
format_version_unsupported
crypto_parameters_invalid
authentication_failed
view_unlock_failed
owner_unlock_failed
capability_insufficient
io_failed
destination_exists
atomic_persistence_failed
transfer_format_unsupported
key_material_invalid
signature_failed
```
Ils utilisent exclusivement `ksp_core_lib::ErrorCode`. Aucun type d'erreur parallèle n'est créé.
Les codes de déverrouillage restent volontairement orientés rôle/opération afin que l'implémentation crypto future puisse éviter de distinguer publiquement password incorrect, unwrap incorrect et tag AEAD incorrect lorsqu'une telle distinction créerait un oracle inutile.
## Logging
Le target Wallet est possédé explicitement par :
```text
crates/ksp-wallet-lib/src/constants.rs
```
avec :
```text
pub(crate) const TRACING_TARGET: &str = "ksp-wallet-lib";
```
Les émissions utilisent exclusivement `ksp_logging_lib::*` et jamais `tracing` directement ni `env!("CARGO_PKG_NAME")` comme target.
La foundation instrumente seulement la demande explicite de projection `info()` au niveau `trace`, avec :
```text
operation=wallet_info_projection
capability=view|owner
```
Aucun alias, note, password, secret, payload arbitraire ou path n'est loggé.
## Tests ajoutés
La tranche définit **13 tests Rust déterministes** plus **2 doctests `compile_fail`** :
- variants `WalletCapability` ;
- redaction `Debug` des deux password wrappers ;
- présence d'un `Drop` pour les wrappers secrets ;
- projection metadata autorisée ;
- redaction alias/note dans `Debug` ;
- projection locked sans identité/metadata ;
- canary crate-root pour `WalletView`/`WalletOwner`/`WalletCapability` ;
- canary crate-root pour les wrappers de password ;
- signatures de méthodes Pubkey typées en `ksp_core_lib::Pubkey` ;
- disponibilité des 13 codes d'erreur depuis le crate root ;
- manifest firewall Wallet ;
- source ownership canary Core Pubkey / Logging facade / absence env direct.
Les tests d'intégration de firewall restent spécifiques à `ksp-wallet-lib`; aucun nouveau canary général du workspace n'est déplacé arbitrairement dans cette crate.
## Documentation synchronisée
Le plan Wallet est passé en version 5 pour :
- figer `ksp_core_lib::Pubkey` comme seule frontière Pubkey de Wallet ;
- corriger le target de logging vers `ksp-wallet-lib` dans `src/constants.rs` conformément à `DEP-LOG-010` ;
- enregistrer `zeroize ^1.9` comme seul ajout tiers de `pre.002` ;
- repousser les crates Solana directes à leur premier usage réel ;
- confirmer qu'aucun répertoire par défaut n'appartient à Wallet et que le path sera fourni par le caller ;
- pointer la suite immédiate sur `pre.003`.
`ROADMAP.md` et `docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md` enregistrent la matérialisation de la foundation sans recopier le détail des futures prereleases.
## Fichiers ajoutés
```text
crates/ksp-wallet-lib/Cargo.toml
crates/ksp-wallet-lib/src/capability.rs
crates/ksp-wallet-lib/src/constants.rs
crates/ksp-wallet-lib/src/error.rs
crates/ksp-wallet-lib/src/lib.rs
crates/ksp-wallet-lib/src/metadata.rs
crates/ksp-wallet-lib/src/owner.rs
crates/ksp-wallet-lib/src/password.rs
crates/ksp-wallet-lib/src/view.rs
crates/ksp-wallet-lib/unit_tests/capability.rs
crates/ksp-wallet-lib/unit_tests/metadata.rs
crates/ksp-wallet-lib/unit_tests/password.rs
crates/ksp-wallet-lib/tests/dependency_boundary.rs
crates/ksp-wallet-lib/tests/public_api.rs
deltas/0.2.5/pre.002.md
```
## Fichiers modifiés
```text
Cargo.toml
ROADMAP.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md
```
## Fichiers supprimés
Aucun.
## Validations exécutées dans l'environnement de préparation
Contrôles statiques réellement exécutés :
- parsing TOML du `Cargo.toml` racine et du manifest Wallet ;
- comparaison de l'arbre avec la base `pre.001-fix.001` ;
- inventaire exact des fichiers ajoutés/modifiés ;
- scan des sources Wallet : aucun `use` statement ;
- scan production : aucun `unwrap`, `expect`, `panic`, opérateur `?` ou bloc `unsafe` ajouté ;
- manifest firewall : absence Config/Transport/ExecutionPolicy/Store/Tauri/tracing/solana-pubkey directs ;
- source ownership : `ksp_core_lib::Pubkey`, `ksp_logging_lib::trace!`, target explicite `ksp-wallet-lib`, aucun `solana_pubkey::`, `tracing::` ou `std::env::` ;
- contrôle des headers `file:` / `version:` des fichiers ajoutés/modifiés ;
- contrôle de l'archive d'échange contre `VER-ARCHIVE-004` avant livraison.
## Validations non exécutées
L'environnement de préparation ne fournit pas la toolchain Rust/Cargo. Les validations suivantes doivent donc être exécutées par l'opérateur après application du delta :
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-wallet-lib
```
Un `cargo tree` complet des primitives Solana/crypto n'est pas encore pertinent : aucune primitive Solana/keypair/KDF/AEAD nouvelle n'est ajoutée en `pre.002`. `zeroize` doit néanmoins apparaître sans duplication injustifiée lors du contrôle Cargo opérateur.
## Décisions prises
- `Pubkey` Wallet est exclusivement `ksp_core_lib::Pubkey`; aucune dépendance directe `solana-pubkey` dans Wallet.
- Logging Wallet utilise exclusivement `ksp-logging-lib` et `TRACING_TARGET = "ksp-wallet-lib"` dans `src/constants.rs`.
- Wallet ne dépend pas de Config et ne choisira pas lui-même un répertoire par défaut ; le caller fournit le path.
- `zeroize ^1.9` est le seul nouveau tiers de `pre.002`.
- Les password wrappers sont distincts OWNER/VIEW, owned, redacted, non-Clone et zeroized au drop.
- Les handles VIEW/OWNER restent opaques et ne simulent aucune opération cryptographique non encore implémentée.
- VIEW conserve comme contrat futur la seule mutation de son propre password ; OWNER conserve les futures rotations OWNER/VIEW et l'administration complète.
## Questions ouvertes
Aucune question bloquante pour `pre.003`.
Restent volontairement à décider/figer dans leurs tranches prévues :
- wire exact JSON/key slots/transcript/AAD (`pre.003`) ;
- paramètres Argon2 benchmarkés et crypto effective (`pre.004`) ;
- matériaux owner-control/metadata/secret et state signature (`pre.005`) ;
- persistence async/atomique/no-clobber (`pre.006`) ;
- keypair/signature et rotations réelles (`pre.007`) ;
- adapters import/export (`pre.008`).