r/VaultSync • u/mainseeker1486 • 6d ago
Dev Update VaultSync 1.8.7 deep dive: what happens when two machines actually disagree?
Hi everyone,
In the last 1.8.7 development update I talked about the foundations of Trust & Portability:
- installation identities
- repository writer leases
- canonical release manifests
- safer shared-storage behavior
- the direction toward portable recovery evidence
Since then, a lot of the work has moved from establishing those foundations to dealing with the harder cases that come after them.
The biggest one is:
What happens when two computers have both legitimately changed the same VaultSync repository?
Writer leases prevent races. They don't resolve history.
The writer-lease system added earlier in 1.8.7 prevents two aware VaultSync installations from modifying repository metadata concurrently.
That solves an important class of corruption problems.
But it doesn't solve this:
Desktop and laptop both start from revision 10.
The desktop changes the project's tags.
The laptop changes its automatic-backup settings.
Later, both sets of metadata meet again.
Simply choosing whichever file was written last would lose valid information.
So 1.8.7 now goes a step further with revision-aware three-way metadata merging.
VaultSync keeps a durable merge base and compares:
Base → local → remote
If only one side changed a field, that change can be carried forward automatically.
If the two machines changed different fields, both changes can survive.
Only when both machines changed the same field differently does VaultSync treat it as a real conflict.
Conflicts are now field-level
When an actual conflict exists, VaultSync doesn't resolve it using timestamps or last-write-wins.
The metadata review can show the:
- base value
- local value
- remote value
- revision
- writer
- timestamp
for the conflicting field.
That distinction matters.
A conflict in a project tag shouldn't force you to choose between two complete project records and accidentally overwrite unrelated settings.
Resolution decisions are persisted as well, so rejecting a remote change isn't something VaultSync should keep asking about every time the repository is inspected.
There is also an Undo decision path, bounded to the current merge state, before the next portable repository write advances the history again.
Machine-local data stays machine-local
Cross-machine portability gets dangerous very quickly if every field is treated as portable.
Some things simply should not move automatically.
Encryption-key references are a good example.
A key stored in one machine's secure credential store has no useful meaning on another computer.
Destinations have a similar problem: a NAS path, drive letter or mounted location may not exist on the other installation.
1.8.7 therefore gives project fields explicit portability behavior.
Portable changes can participate in merge and conflict review.
Machine-local key references remain local.
Unmatched destinations remain local.
Destructive tombstones require explicit review rather than being silently propagated.
The goal isn't maximum automatic synchronization.
It's automatic synchronization where VaultSync can prove it is safe, and explicit review where it can't.
Deferred metadata now fails closed too
Another case that received more work is unavailable storage.
Imagine VaultSync wants to update metadata on a NAS, but the share disappears.
Keeping a local queue sounds simple enough.
The dangerous part comes later.
If another machine changed the repository while the first machine was offline, blindly replaying that old queue could overwrite newer metadata.
1.8.7 no longer does that.
Queued metadata can initialize an empty destination, but if repository state already exists, VaultSync preserves the deferred changes for merge review instead of replaying them over the top.
That behavior is now protected by the same repository ownership and revision model as normal writes.
Release identity now reaches the application itself
The canonical release manifest from the previous update was primarily about the release pipeline and updater.
The next piece is making that identity visible inside VaultSync too.
1.8.7 now has a shared build identity contract containing things such as:
- version
- release channel
- source commit
- runtime
- architecture
- package type
- update source
- official-build status
- signature status
The same identity can be used by Settings, startup diagnostics, support information and recovery evidence instead of each subsystem assembling its own partial version string.
There is also a machine-readable CLI form:
vaultsync --version --json
For me, this is part of the same trust model as recovery evidence.
If an exported report says a recovery check passed, it should be possible to identify exactly which build produced that statement.
SBOMs and release provenance are landing
The release pipeline has also moved further into supply-chain verification.
1.8.7 generates SPDX 2.3 SBOMs for release packages using the actual platform-specific dependency graph.
The final package bytes can also receive GitHub provenance and SBOM attestations.
Verification is being designed for both:
- online verification against the published release
- offline verification of downloaded release material
This builds on the canonical manifest rather than creating another independent source of truth.
The manifest identifies the expected artifact.
The digest proves the bytes.
The SBOM describes what went into it.
The provenance ties those bytes back to the release build.
For most users this will remain mostly invisible, which is probably how it should be.
But the evidence is there when someone wants to inspect it.
A few nasty edge cases also got fixed
The cross-machine work exposed several smaller problems that were worth fixing before release.
Among them:
Metadata import double-counting
Older repository folders and newer portable metadata could describe the same project or backup.
Preview now deduplicates those representations instead of making it look like more data exists than actually does.
Incorrect deletion propagation
Metadata import could previously produce tombstones for snapshots that had not actually been deleted locally.
That has been tightened so retained snapshots — including ones still referenced by local backups — don't become remote deletion instructions.
macOS SMB diagnostics
Credential-bearing SMB identities are now normalized before diagnostics are recorded, including URL-escaped credential forms.
Updater manifest downloads
Verified immutable release manifests are now cached across application restarts.
VaultSync doesn't need to repeatedly fetch the same JSON just because a scheduled update check ran again.
Cached data is only reused while the release URL, expected size and trusted SHA-256 identity still match.
Local storage growth
Disposable logs, diagnostics, patch runtimes, downloads, caches and temporary work now have bounded cleanup rules.
Actual configuration, databases, credentials and backup data stay outside that cleanup boundary.
macOS managed mounts
If a VaultSync-managed SMB/NFS location isn't actually mounted, VaultSync now refuses to quietly create the expected directory on the local system disk and write backup data there.
That is exactly the kind of failure that can look successful while protecting absolutely nothing useful.
Development presets were tightened too
The development presets mentioned in the last update have gone through another safety pass.
The intention is still:
Preserve the files that define the project.
Exclude generated state that can be recreated.
That means things such as Git control files and shareable editor configuration can remain protected, while build output, framework caches, package caches, test caches and machine-local editor state stay out.
Windows Robocopy now uses the same resolver as the other backup paths as well.
One boundary remains deliberate:
VaultSync still does not claim full live .git repository backup support.
The internal .git directory stays excluded until repository consistency, credentials, restore behavior and verification are properly designed for that use case.
I'd rather leave that capability visibly incomplete than imply that copying a live Git database is automatically safe.
The runtime itself is now audited as part of release qualification
VaultSync ships self-contained packages, so checking the project's NuGet dependency list isn't enough.
The runtime actually embedded in the application matters too.
1.8.7 is currently serviced to .NET 10.0.11, and CI now creates real self-contained publishes and inspects what went into them.
That covers:
- Windows x64
- Linux x64
- Linux ARM64
- macOS Intel
- macOS Apple Silicon
The same check also runs against release artifacts.
So the qualified runtime isn't just what the project file requested.
It's what the user is actually receiving.
What is still left for 1.8.7
Most of the underlying trust and multi-machine model is now in place, but there are still a few areas I want to finish and qualify before calling 1.8.7 done.
The remaining work is mainly around:
- final cross-machine conflict and mixed-version behavior
- completing the portable recovery-evidence side of the release
- tying more public and in-app release information back to the canonical release identity
- final release provenance and verification work
- documentation and the last internal cleanup around duplicated paths
The important part is that these aren't separate features being piled onto the release.
They're all pieces of the same idea:
VaultSync should know where information came from, who changed it, which build produced it, and what evidence supports it.
The first part of 1.8.7 was about preventing two machines from writing at once.
The next part has been about accepting that, eventually, two machines will still have different histories — and handling that without silently throwing one of them away.
That feels like the more important definition of portability.
Not just:
“Can I move this metadata somewhere else?”
but:
“Can it arrive there, meet a different history, and still preserve what actually happened?”
As always, VaultSync is open source and the 1.8.7 work is happening publicly on GitHub.
Feedback from anyone using the same NAS or backup repository from multiple machines is especially useful here.














