Repository navigation
Sync, phase one: a file, a button, and a merge that keeps both sides - #13
Merged
Merged
Conversation
… 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
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
updatedAtis 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.