Finding
Opening a vault path that does not exist mutates the filesystem before confirming that a vault is present. The failed open leaves a directory and lock file behind, after which normal Vault::create rejects the same path as already existing.
Evidence
crates/kryphos/src/storage.rs:184-188 calls acquire_lock(path) before reading header.json.
acquire_lock at lines 517-525 calls create_owner_only_dir(vault_path) and creates/truncates the lock file. The subsequent header read fails, but those artifacts remain.
Vault::create at lines 135-139 rejects any existing path with VaultError::AlreadyExists. Thus a harmless list/get before initialization—or simply a mistyped path—can make the intended initialization path unusable without manual cleanup.
Why this matters
A read/open operation should not create durable state that changes the outcome of a later initialization. The current ordering makes a routine user error self-poisoning and gives callers no typed distinction between “not initialized” and general I/O failure.
Desired correction
Separate create and open lock acquisition. For open, validate that the vault directory and header already exist before creating any lock artifact, or acquire a non-creating lock through a parent-scoped mechanism. Return a typed NotInitialized/not-found error without filesystem mutation.
Done when opening a missing path leaves no files or directories, returns the typed absence error, and a subsequent Vault::create at that same path succeeds.
Finding
Opening a vault path that does not exist mutates the filesystem before confirming that a vault is present. The failed open leaves a directory and lock file behind, after which normal
Vault::createrejects the same path as already existing.Evidence
crates/kryphos/src/storage.rs:184-188callsacquire_lock(path)before readingheader.json.acquire_lockat lines 517-525 callscreate_owner_only_dir(vault_path)and creates/truncates the lock file. The subsequent header read fails, but those artifacts remain.Vault::createat lines 135-139 rejects any existing path withVaultError::AlreadyExists. Thus a harmlesslist/getbefore initialization—or simply a mistyped path—can make the intended initialization path unusable without manual cleanup.Why this matters
A read/open operation should not create durable state that changes the outcome of a later initialization. The current ordering makes a routine user error self-poisoning and gives callers no typed distinction between “not initialized” and general I/O failure.
Desired correction
Separate create and open lock acquisition. For open, validate that the vault directory and header already exist before creating any lock artifact, or acquire a non-creating lock through a parent-scoped mechanism. Return a typed
NotInitialized/not-found error without filesystem mutation.Done when opening a missing path leaves no files or directories, returns the typed absence error, and a subsequent
Vault::createat that same path succeeds.