2.3 KiB
Read-only password-store domains
VaultReader in crates/storage owns the semantics for list/ls, explicit
and implicit show, find/search, and decrypted grep. Frontends receive
typed models and render storage-provided paths; they do not inspect tree text,
ciphertext names, or decrypted display strings to infer domain state.
Trees and dispatch
Tree models contain separate entry and directory node kinds, logical paths,
names, and deterministic children. Entry names never contain the .gpg storage
suffix. Policy files, signatures, other metadata, .git, and .extensions
trees are not nodes. The plain renderer produces the stable uncolored tree used
by command-line output.
No show path selects the root tree. A path is resolved against the repository
snapshot: an entry decrypts to redacted SecretBytes, while a directory returns
its subtree. Missing and ambiguous paths remain typed repository errors and map
to the normal pass failure status.
Clipboard and QR requests use the parsed Presentation enum and a nonzero line
number. Storage selects that line directly from decrypted bytes and returns a
PresentationSecret containing the logical entry, line, channel, and redacted
zeroizing contents. The adapter never parses rendered terminal output, and a
missing or empty requested line is an explicit failure.
Name and plaintext search
Find performs Unicode case-insensitive substring matching against logical entry
and directory names. Multiple terms are alternatives, as in upstream pass.
Results include typed matches plus a pruned deterministic tree with the
necessary ancestors. Hidden implementation directories, metadata, and
ciphertext suffixes cannot become matches.
Decrypted grep uses the Rust regex byte engine, which provides linear-time
matching without invoking GNU grep. The accepted command contract is limited to
case-insensitive, inverted, line-number, and fixed-string behavior; unsupported
GNU options fail during command parsing. Entries are visited in repository
order, each plaintext is decrypted only while its lines are examined, and the
full plaintext buffer is zeroed when that iteration ends. Matched lines are
copied into redacted SecretBytes; rendered grep output is also returned as
SecretBytes, and both are zeroed with their result values. Debug output
includes paths and counts but never matched contents.