tasks: decompose vault, core, call crates into 28 atomic implementation tasks
Break down the three initial crates (alknet-vault, alknet-core, alknet-call) into dependency-ordered task files for implementation agents. Structure: - tasks/vault/ (10 tasks) — drift fixes from ADR-025/026 refactor, review, spec sync. Vault is independent and can run fully in parallel with core/call. - tasks/core/ (6 tasks) — crate init, core types, config, auth, endpoint, review. Core is foundational; call depends on it. - tasks/call/ (12 tasks) — split into registry/ and protocol/ topic subdirs reflecting the two subsystems. CallAdapter is the merge point. Key decisions: - Drifts 3+9+10 grouped as one task (key-versioning-rotation) — the complete ADR-021 rotation feature that doesn't compile in pieces - Reviews injected at end of each crate phase (vault, core, call) - Vault spec-sync task removes the drift table and bumps doc status to stable - ACME deferred in core/endpoint (noted as TODO; X509 manual certs for now) - OperationEnv kept as a trait (load-bearing for ADR-024 layering) Validated: 28 tasks, no cycles, 11 generations of parallel work. Critical path runs through call (11 tasks). Vault completes by generation 4. 6 high-risk tasks identified (21%): irpc-removal, endpoint, operation-context, operation-env, call-adapter, abort-cascade.
This commit is contained in:
79
tasks/vault/unlock-new-zeroizing-return.md
Normal file
79
tasks/vault/unlock-new-zeroizing-return.md
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: vault/unlock-new-zeroizing-return
|
||||
name: Change unlock_new return type from String to Zeroizing<String>
|
||||
status: pending
|
||||
depends_on: [vault/irpc-removal]
|
||||
scope: single
|
||||
risk: low
|
||||
impact: isolated
|
||||
level: implementation
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Fix drift item #8: `unlock_new` currently returns `String`, which is not
|
||||
zeroized on drop. The mnemonic phrase is the root of trust — it must not linger
|
||||
in freed heap memory. Change the return type to `Zeroizing<String>` (from the
|
||||
`zeroize` crate, already a dependency).
|
||||
|
||||
### Current state
|
||||
|
||||
```rust
|
||||
pub fn unlock_new(&self, word_count: usize) -> Result<String, VaultServiceError>;
|
||||
```
|
||||
|
||||
### Target state
|
||||
|
||||
```rust
|
||||
pub fn unlock_new(&self, word_count: usize) -> Result<Zeroizing<String>, VaultServiceError>;
|
||||
```
|
||||
|
||||
Per `docs/architecture/crates/vault/service.md` → unlock_new:
|
||||
|
||||
> The returned phrase is the root of trust — it is heap-allocated and zeroized
|
||||
> on drop, so it does not linger in freed memory. The caller should extract the
|
||||
> phrase for secure storage (write down, display to user) and let the
|
||||
> `Zeroizing<String>` drop when done. Do not clone the returned value or store
|
||||
> it in a non-zeroizing container.
|
||||
|
||||
### Caller adaptation
|
||||
|
||||
The assembly layer (CLI binary, not yet implemented) will call `unlock_new` and
|
||||
extract the phrase. The `Zeroizing<String>` wrapper derefs to `String`, so
|
||||
`&*result` or `result.as_str()` works for reading. The caller must not clone the
|
||||
inner `String` into a non-zeroizing container.
|
||||
|
||||
Existing tests that call `unlock_new` need updating to handle the new return
|
||||
type — use `&*phrase` or `phrase.as_str()` to read the string.
|
||||
|
||||
### Scope
|
||||
|
||||
This task touches `service.rs` (the method signature and body) and test files.
|
||||
It depends on the irpc removal task (drift #4) because both modify `service.rs`.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] `unlock_new` return type changed from `Result<String, ...>` to `Result<Zeroizing<String>, ...>`
|
||||
- [ ] Method body constructs `Zeroizing<String>` from the generated phrase
|
||||
- [ ] Existing tests updated to handle `Zeroizing<String>` return type
|
||||
- [ ] No `clone()` of the returned value in non-test code
|
||||
- [ ] `cargo check` succeeds
|
||||
- [ ] `cargo test` succeeds
|
||||
- [ ] `cargo clippy` succeeds with no warnings
|
||||
|
||||
## References
|
||||
|
||||
- docs/architecture/crates/vault/README.md — Known Source Drift table item #8
|
||||
- docs/architecture/crates/vault/service.md — unlock_new section
|
||||
- docs/architecture/decisions/025-vault-local-only-dispatch.md — ADR-025 (resolves W7)
|
||||
|
||||
## Notes
|
||||
|
||||
> The mnemonic is the root of trust. Returning a plain `String` means the phrase
|
||||
> lingers in freed heap memory after the caller drops it. `Zeroizing<String>`
|
||||
> zeroizes the bytes on drop. This resolves review #002 W7. Depends on irpc
|
||||
> removal because both modify `service.rs`.
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
Reference in New Issue
Block a user