Expose structured entry documents for frontend clients #15

Closed
opened 2026-08-09 19:10:06 +00:00 by hugo · 1 comment
Owner

Objective

Expose a presentation-neutral structured entry document from crates/storage so every frontend can view and edit arbitrary pass entries without parsing display strings.

Scope

  • Parse the first line as the conventional password field while preserving arbitrary remaining content.
  • Represent dynamic name: value fields, duplicate field names, OTP URIs, blank lines, free-form notes, and unrecognized lines with stable field IDs and ordering.
  • Mark sensitivity and semantic field kinds in storage-provided metadata rather than frontend heuristics.
  • Provide add, update, remove, reorder, serialize, conflict-token, and atomic-save operations.
  • Preserve untouched bytes where possible and never introduce a new on-disk format.

Acceptance criteria

  • Parse/serialize round trips do not change untouched pass entries.
  • Edited documents remain readable by upstream pass and preserve dynamic and unstructured content.
  • Tests cover duplicate keys, Unicode, multiline notes, empty values, OTP URIs, missing first lines, reordering, and concurrent modification.
  • Frontends need no repository reads, entry parsing, recipient selection, encryption, or file writes.

Prerequisites

Safe password-store repository core; embedded GPG-compatible cryptography; insert/edit behavior.

## Objective Expose a presentation-neutral structured entry document from `crates/storage` so every frontend can view and edit arbitrary pass entries without parsing display strings. ## Scope - Parse the first line as the conventional password field while preserving arbitrary remaining content. - Represent dynamic `name: value` fields, duplicate field names, OTP URIs, blank lines, free-form notes, and unrecognized lines with stable field IDs and ordering. - Mark sensitivity and semantic field kinds in storage-provided metadata rather than frontend heuristics. - Provide add, update, remove, reorder, serialize, conflict-token, and atomic-save operations. - Preserve untouched bytes where possible and never introduce a new on-disk format. ## Acceptance criteria - Parse/serialize round trips do not change untouched pass entries. - Edited documents remain readable by upstream pass and preserve dynamic and unstructured content. - Tests cover duplicate keys, Unicode, multiline notes, empty values, OTP URIs, missing first lines, reordering, and concurrent modification. - Frontends need no repository reads, entry parsing, recipient selection, encryption, or file writes. ## Prerequisites Safe password-store repository core; embedded GPG-compatible cryptography; insert/edit behavior.
hugo added this to the 01 - Full Rust pass CLI parity milestone 2026-08-09 19:10:06 +00:00
hugo added the enhancement label 2026-08-09 19:10:06 +00:00
Author
Owner

Implemented in commit 2aabd58 (pushed to main).

What changed:

  • Added a presentation-neutral crates/storage::document API that opens logical entries through storage and exposes ordered fields with stable in-document IDs.
  • The first physical line is always the password; later lines are classified as dynamic fields, valid OTP URIs, blanks, or free-form notes. Duplicate names, Unicode, empty values, unrecognized bytes, LF/CRLF, and missing final newlines are preserved.
  • Added storage-owned semantic kinds and conservative sensitivity metadata so frontends do not infer domain meaning from display strings.
  • Added indexed add, ID-based update/remove/reorder, lossless serialization, redacted ciphertext-derived conflict tokens, and validated field/OTP constructors.
  • Added EntryDocumentService::save, which consumes the original edit session and therefore reuses recipient resolution, GPG-compatible encryption, atomic replacement, automatic commit, concurrent-ciphertext detection, and rollback on commit failure. No document metadata or competing format is written to disk.
  • Added tests that round-trip every compatibility fixture byte-for-byte and cover duplicate keys, Unicode, multiline notes, empty values, blank/missing first lines, OTP URIs, stable IDs, reordering, creation, concurrent modification, and commit rollback.
  • Documented the frontend/storage boundary and document lifecycle.

Verification completed:

  • cargo fmt --all -- --check
  • RUSTFLAGS="-D warnings" cargo check --workspace --all-targets
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace

All checks passed. The implementation was reviewed against every acceptance criterion; frontends require no repository reads, plaintext parsing, recipient selection, encryption, or file writes.

Implemented in commit 2aabd58 (pushed to main). What changed: - Added a presentation-neutral `crates/storage::document` API that opens logical entries through storage and exposes ordered fields with stable in-document IDs. - The first physical line is always the password; later lines are classified as dynamic fields, valid OTP URIs, blanks, or free-form notes. Duplicate names, Unicode, empty values, unrecognized bytes, LF/CRLF, and missing final newlines are preserved. - Added storage-owned semantic kinds and conservative sensitivity metadata so frontends do not infer domain meaning from display strings. - Added indexed add, ID-based update/remove/reorder, lossless serialization, redacted ciphertext-derived conflict tokens, and validated field/OTP constructors. - Added `EntryDocumentService::save`, which consumes the original edit session and therefore reuses recipient resolution, GPG-compatible encryption, atomic replacement, automatic commit, concurrent-ciphertext detection, and rollback on commit failure. No document metadata or competing format is written to disk. - Added tests that round-trip every compatibility fixture byte-for-byte and cover duplicate keys, Unicode, multiline notes, empty values, blank/missing first lines, OTP URIs, stable IDs, reordering, creation, concurrent modification, and commit rollback. - Documented the frontend/storage boundary and document lifecycle. Verification completed: - cargo fmt --all -- --check - RUSTFLAGS="-D warnings" cargo check --workspace --all-targets - cargo clippy --workspace --all-targets -- -D warnings - cargo test --workspace All checks passed. The implementation was reviewed against every acceptance criterion; frontends require no repository reads, plaintext parsing, recipient selection, encryption, or file writes.
hugo closed this issue 2026-08-10 02:04:28 +00:00
Sign in to join this conversation.