# Structured entry documents

`crates/storage::document` exposes arbitrary password-store entries as ordered,
presentation-neutral documents. Frontends supply a logical entry path and a
secret provider to `EntryDocumentService::open`; storage resolves and reads the
entry, decrypts it, parses it, and returns fields with stable in-document IDs.
Frontends never inspect `.gpg` files, select recipients, parse entry text, or
write the repository.

The first physical line is always the conventional password field. Every later
physical line remains independently addressable and is classified as a dynamic
`name: value` field, valid `otpauth://` URI, blank line, or free-form note.
Recognized username, email and URL names receive semantic kinds. Passwords,
OTP URIs, notes and unknown/custom values are sensitive by default; ordinary
identity/navigation fields and blank lines receive separate sensitivity
metadata. Duplicate names are retained as distinct fields in their original
order. Unicode names and values are supported, while non-UTF-8 or otherwise
unrecognized lines remain lossless notes.

Line contents and their LF, CRLF or absent final endings are retained exactly.
Parsing and serializing an untouched document therefore returns byte-identical
plaintext, including mixed endings, empty values, blank lines and a missing
first line. Updates replace only the selected line. Structural operations keep
untouched line bytes and preserve the document's final-newline convention;
new dynamic fields serialize as the upstream-compatible `name: value` form.
No IDs or metadata are written to the password entry, so this does not create a
new on-disk format. IDs are stable for the lifetime of the opened document and
remain attached to fields through update and reorder operations.

Documents support indexed add, ID-based update and removal, ID-based reorder,
lossless serialization and a redacted conflict token derived from the original
ciphertext. `EntryDocumentService::save` consumes the edited document and uses
the existing `VaultWriter` edit session. It rechecks the original ciphertext,
resolves the current recipient policy in storage, encrypts, atomically replaces
the `.gpg` entry, and performs the storage mutation commit. Concurrent changes
are rejected before writing. A commit failure restores the original encrypted
entry, so clients never receive a successful save for an uncommitted or partial
mutation.

Compatibility tests round-trip every checked-in upstream-compatible fixture
and separately cover duplicate keys, Unicode, CRLF, multiline notes, empty
values, OTP URIs, blank and missing first lines, stable IDs, reorder, creation,
stale documents and commit rollback.
