Synchronize the selected TOTP subset to Apple Watch #55

Closed
opened 2026-08-09 20:00:46 +00:00 by hugo · 1 comment
Owner

Goal

Define secure, replaceable synchronization of the explicitly selected TOTP subset to the paired Apple Watch.

Scope

  • Add a storage-owned versioned Watch snapshot containing only the selected TOTP identities, display metadata, and the minimum secret parameters needed for offline calculation.
  • Define snapshot validation, replacement/removal semantics, revision ordering, pairing identity, and stale/duplicate handling in Rust.
  • Use Watch Connectivity only as an Apple transport adapter for opaque storage-produced bytes; use latest-state application context or an equivalent reliable background mechanism so removals replace stale selections.
  • Send changes after selection or entry updates and expose pending, delivered/current, unavailable, unpaired, and failed states to the iPhone UI.
  • On unpairing, active-watch change, disabled sharing, or invalid snapshot, revoke/wipe data according to storage policy and require a fresh pairing snapshot.
  • Do not send the GPG secret key, repository, application token, unrelated entries, or precomputed code history.

Acceptance criteria

  • Adding, updating, removing, and deselecting TOTP entries produces a deterministic minimal replacement snapshot.
  • Out-of-order or replayed payloads cannot restore removed/stale entries.
  • Swift transports opaque bytes and reports lifecycle state; snapshot contents and decisions remain in Rust.
  • Background transfer and pairing-change behavior are verified on a physical paired iPhone and Apple Watch, not only Simulator.
## Goal Define secure, replaceable synchronization of the explicitly selected TOTP subset to the paired Apple Watch. ## Scope - Add a storage-owned versioned Watch snapshot containing only the selected TOTP identities, display metadata, and the minimum secret parameters needed for offline calculation. - Define snapshot validation, replacement/removal semantics, revision ordering, pairing identity, and stale/duplicate handling in Rust. - Use Watch Connectivity only as an Apple transport adapter for opaque storage-produced bytes; use latest-state application context or an equivalent reliable background mechanism so removals replace stale selections. - Send changes after selection or entry updates and expose pending, delivered/current, unavailable, unpaired, and failed states to the iPhone UI. - On unpairing, active-watch change, disabled sharing, or invalid snapshot, revoke/wipe data according to storage policy and require a fresh pairing snapshot. - Do not send the GPG secret key, repository, application token, unrelated entries, or precomputed code history. ## Acceptance criteria - Adding, updating, removing, and deselecting TOTP entries produces a deterministic minimal replacement snapshot. - Out-of-order or replayed payloads cannot restore removed/stale entries. - Swift transports opaque bytes and reports lifecycle state; snapshot contents and decisions remain in Rust. - Background transfer and pairing-change behavior are verified on a physical paired iPhone and Apple Watch, not only Simulator.
hugo added this to the 04 - iPhone and Apple Watch apps milestone 2026-08-09 20:00:46 +00:00
hugo added the enhancement label 2026-08-09 20:00:46 +00:00
hugo added the untested label 2026-08-16 11:47:58 +00:00
Author
Owner

Implemented in commit a055c93.

What changed:

  • Added a storage-owned, versioned, bounded replacement snapshot containing only selected TOTP identity/display fields and the minimum offline TOTP parameters.
  • Added deterministic ordering, monotonic revisions, pairing identity, revocation, stale/duplicate/replay/conflict rejection, invalid-snapshot wiping, and Delivered/Current receipts in Rust.
  • Persisted only revision and SHA-256 state in a private atomic sender journal; no seeds, OTP URIs, generated codes, GPG keys, repositories, application tokens, or unrelated entries are stored there.
  • Added UniFFI lifecycle/status APIs and made Swift a Watch Connectivity adapter for opaque bytes using latest application context and background receipt fallback.
  • Wired selection, entry, authentication, pairing, app-installation, and active-Watch changes into synchronization and iPhone pending/delivered/current/unavailable/unpaired/failed presentation.
  • Fixed the transient TOTP failure path so errors use a dismissible alert instead of leaving a transparent blocking overlay.

Verification:

  • cargo fmt --all -- --check
  • RUSTFLAGS='-D warnings' cargo check --workspace --all-targets
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace
  • Xcode generation, Analyze, signed simulator builds, and signed Release iPhone/embedded-Watch build completed before the final unchanged-tree review.
  • Simulator validation preserved app state and biometric enrollment; selection, deselection, and reselection produced Delivered revisions 1, 2, and 3, and the error alert dismissed back to the intact list.

Physical Apple Watch installation/background delivery was not verified because Xcode 26.6 did not enumerate the paired Watch. At the user direction this issue is being closed with simulator-only verification and the untested label; no claim of physical-Watch acceptance is made.

Implemented in commit `a055c93`. What changed: - Added a storage-owned, versioned, bounded replacement snapshot containing only selected TOTP identity/display fields and the minimum offline TOTP parameters. - Added deterministic ordering, monotonic revisions, pairing identity, revocation, stale/duplicate/replay/conflict rejection, invalid-snapshot wiping, and Delivered/Current receipts in Rust. - Persisted only revision and SHA-256 state in a private atomic sender journal; no seeds, OTP URIs, generated codes, GPG keys, repositories, application tokens, or unrelated entries are stored there. - Added UniFFI lifecycle/status APIs and made Swift a Watch Connectivity adapter for opaque bytes using latest application context and background receipt fallback. - Wired selection, entry, authentication, pairing, app-installation, and active-Watch changes into synchronization and iPhone pending/delivered/current/unavailable/unpaired/failed presentation. - Fixed the transient TOTP failure path so errors use a dismissible alert instead of leaving a transparent blocking overlay. Verification: - `cargo fmt --all -- --check` - `RUSTFLAGS='-D warnings' cargo check --workspace --all-targets` - `cargo clippy --workspace --all-targets -- -D warnings` - `cargo test --workspace` - Xcode generation, Analyze, signed simulator builds, and signed Release iPhone/embedded-Watch build completed before the final unchanged-tree review. - Simulator validation preserved app state and biometric enrollment; selection, deselection, and reselection produced Delivered revisions 1, 2, and 3, and the error alert dismissed back to the intact list. Physical Apple Watch installation/background delivery was not verified because Xcode 26.6 did not enumerate the paired Watch. At the user direction this issue is being closed with simulator-only verification and the `untested` label; no claim of physical-Watch acceptance is made.
hugo closed this issue 2026-08-16 11:49:12 +00:00
Sign in to join this conversation.