Merge rules for sync
When your devices work apart (a laptop offline, two nodes changing the same list) their changes are replayed on every node in one canonical order. The contract decides what happens when two changes meet, action by action, in its front matter:
---
namespace: std.personal.shopping_list
version: 1.0.0
merge: CreateList=commutes, Archive=last_writer
---
| Rule | When two changes meet | Use for |
|---|---|---|
commutes | Both apply, in either order | Adding items, recording transactions, appending |
last_writer | The later one (by the hybrid clock) wins | A title, a preference, a status anyone may set |
exclusive | One applies; the other becomes a conflict | Approving, paying, reserving the last unit |
An action not listed is exclusive, so nothing merges silently that was not designed to.
Conflicts
A change that no longer passes the contract's validation after the merge is never dropped: it becomes a std.sync.conflict record, shown in Settings → Devices and sync → Didn't merge for a person to settle. See Sync and conflicts.
Designing for merge
- Make additions their own records. A list's items are separate records (
std.personal.shopping_item), so two people adding at once never touch the same record. - Keep money and stock exclusive.
std.business.payabledeclaresApprove=exclusive, Pay=exclusive: two devices cannot both pay one invoice without a conflict being recorded. - Prefer
last_writeronly for values where the latest truly wins.
Organisations whose operations need one agreed order (an order paid once, the last unit sold once) run their own cluster with consensus instead of merging; their people's devices act as clients.