# Insert and edit domains

`VaultWriter` in `crates/storage` owns insertion, edit concurrency, recipient
selection, encryption, repository mutation, rollback, and commit intent.
Frontends collect input and overwrite decisions but cannot write an encrypted
entry directly.

## Insert

`InsertContent` has distinct constructors for hidden confirmed input, echoed
single-line input, and exact multiline bytes. Hidden values must match their
confirmation; both single-line modes reject empty values and embedded line
breaks. Multiline input preserves every byte and may be empty. The content mode
must equal the parsed `InsertRequest`, preventing an adapter from silently
changing stdin semantics.

An existing entry requires either `--force` or an explicit allow decision. A
decline returns before recipient resolution or encryption. The nearest signed
or unsigned recipient policy is resolved for the destination, plaintext is
consumed by embedded OpenPGP encryption, and repository replacement is atomic.
The storage commit boundary is invoked only afterward with the compatible
`Add given password ...` intent. Commit failure restores the exact old
ciphertext or removes a newly created entry and its empty parent directories.

## Edit sessions

Beginning a session snapshots the original encrypted bytes and decrypts an
existing entry into redacted `SecretBytes`; a missing entry starts with empty
contents so `pass edit` can create it. Finishing consumes replacement
`SecretBytes`. Unchanged content returns without encryption or commit. Before
writing, storage compares current encrypted bytes with the snapshot (or checks
that a new path is still absent), so concurrent replacement, removal, or
creation is rejected without overwriting the other writer.

Successful replacement uses the destination's current recipient policy and
records compatible editor commit intent. A commit error restores the prior
state. Rollback failure retains both the commit and repository errors.

## CLI editor boundary

Editor precedence remains TOML configuration, `VISUAL`, `EDITOR`, then `vim`,
with the program and arguments parsed without a shell. The CLI adapter converts
that value to one `EditorInvocation` for a narrowly injected `EditorHost`;
storage, TUI, GUI, iOS, and watchOS never receive executable information and
continue to use the in-process replacement API.

Before invoking the host, the CLI creates a mode-0600 plaintext file inside a
private temporary directory. Linux prefers `/dev/shm` when available; native
temporary storage is the fallback. The file is never inside the vault. A saved
file is bounded before reading. Saved, cancelled, failed, and host-error paths
all overwrite the file with zeros, truncate and sync it, remove it, and finally
drop the private directory. Returned replacement bytes remain zeroizing.
