Skip to content

Sync, phase one: a file, a button, and a merge that keeps both sides - #13

Merged
iamrraj merged 1 commit into
mainfrom
feat/sync-phase1
Aug 25, 2026
Merged

iamrraj merged 1 commit into
mainfrom
feat/sync-phase1

Conversation

@iamrraj

@iamrraj iamrraj commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Implements Phase 1 of the design in #10.

Transport adds nothing. You pick a file inside a folder your computer already syncs — iCloud Drive, Dropbox, OneDrive, Syncthing. No OAuth, no token, no provider API, no network request, and no new manifest permission. The syncing is done by software you already trust with your files, and KeyVault never learns which one it is.

The merge is three-way and pure — no storage, no network, no clock. Two-way merging cannot tell I added this from they deleted this, so each device keeps the state it last agreed with, sealed, and compares both sides against it.

Two rules carry the safety:

  • A conflict produces both versions, never a winner. Any rule that picks one — newest, longest, local — silently destroys somebody's password some of the time. A duplicate is visible and takes two clicks to fix; a lost password cannot be recovered.
  • An edit beats a delete. Deleted here, edited there → it comes back, and the UI says why. A lost edit is invisible; a restored item is obvious.

Ordering never uses the clock. A per-entry revision counter is added here and bumped on every write, including the soft-delete transitions. One laptop set to the wrong year would otherwise win every conflict forever — there is a test pinning that updatedAt is ignored.

Refusals worth having: a file whose KDF salt differs is a different vault and is rejected rather than merged into one belonging to neither; a file that does not decrypt fails closed rather than being read as an empty remote, which would let the next write overwrite a good file.

Tested through the real router and real sealing, not just the merge function: two devices exchanging a file converge, a genuine conflict keeps both passwords, a second sync reports Already up to date, and the file never contains a decrypted entry.

915 unit tests, 43 end-to-end.

… sides

Two machines stay in step through a file the user picks inside a folder
their computer already synchronises: iCloud Drive, Dropbox, OneDrive,
Syncthing. No OAuth, no token, no provider API, and no network request —
the syncing is done by software they already trust with their files, and
KeyVault never learns which one it is. The manifest gains no permission.

The merge is three-way and pure: no storage, no network, no clock. Two-way
merging cannot tell "I added this" from "they deleted this", so each device
keeps the state it last agreed with — sealed, in local storage — and
compares both sides against it.

Two rules carry the safety of the whole feature.

A conflict produces both versions, never a winner. Any rule that picks one
— newest, longest, local — silently destroys somebody's password some of
the time. A duplicate is visible and takes two clicks to resolve; a lost
password is a support request that cannot be answered.

An edit beats a delete. Deleted here and edited there means the entry comes
back, and the UI says why. Losing an edit is invisible; a restored item is
obvious.

Ordering uses a per-entry revision counter, added here and bumped on every
write including the soft-delete transitions. `updatedAt` is untrustworthy
across machines: one laptop set to the wrong year would win every conflict
forever, and a test pins that it is ignored.

Refusals worth having: a file whose KDF salt does not match is a different
vault and is rejected outright rather than merged into a vault belonging to
neither; a file that does not decrypt fails closed rather than being
treated as an empty remote, which would let the next write overwrite a good
file with this device's copy alone.

Settings stay local. They are per-device preferences — an auto-lock timer
that suits a laptop need not suit a desktop — and merging them would be the
least valuable place to spend the risk.

Manual on purpose. Merging two vaults is where password managers lose data,
and it should be watched working before anything automatic depends on it.

Tested through the real router and real sealing, not just the merge
function: two devices exchanging a file converge, a genuine conflict keeps
both passwords, a second sync with nothing new reports "Already up to
date", and the file never contains a decrypted entry.

915 unit tests, 43 end-to-end.
@iamrraj
iamrraj merged commit f1a5cde into main Aug 25, 2026
5 checks passed
@iamrraj
iamrraj deleted the feat/sync-phase1 branch August 25, 2026 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant