CRDT model
NodalMerge convergence comes from deterministic conflict resolution over immutable operations. This page explains the three core data models and the ordering rules that make multi-writer state converge.Design objective
Given the same set of valid operations, every peer resolves the same final state. That guarantee is independent of:- Network delivery order
- Offline vs online write timing
- Which peer receives which update first
Operation families
NodalMerge transactions carry operations in three families:MapOpfor key/value stateTextOpfor collaborative textListOpfor ordered item identity and position
Global ordering and tie-break rules
Most conflict resolution in NodalMerge uses a deterministic comparator based on:- Lamport timestamp
- Author public key (as deterministic tie-break)
- Higher Lamport wins when two operations conflict
- If Lamport ties, author key order breaks the tie consistently
Map model (LWW map)
Map keys use last-write-wins (LWW) semantics.Supported operations
Set { key, value }Delete { key }SetBlob { key, blob_hash }
Conflict resolution
For a given key, NodalMerge keeps the winning operation under(lamport, author) ordering.
Outcomes:
- Concurrent
Seton same key: one deterministic winner SetvsDelete: deterministic winnerSetBlobbehaves likeSetfor conflict purposes, but value is a blob hash reference
Use map when
Use maps for object-shaped state where deterministic single-winner behavior is correct, such as:- User preferences
- Session metadata
- Canonical pointers and references
Text model (RGA)
Text uses an RGA-style CRDT with stable character identities and tombstones.Supported operations
InsertandInsertRangeDeleteandDeleteRange
Identity and ordering
Each inserted character gets a stable operation identity derived from transaction ordering metadata. When concurrent inserts target the same anchor:- Higher-priority character appears leftward
- Priority is deterministic from operation identity
Deletion behavior
Deletes are tombstones, not destructive erase from causal history. Implications:- Deleted characters stop appearing in visible text
- Anchors remain stable for future inserts
- Peers still converge under out-of-order delivery
List model (fractional-index list)
Lists model ordered item identity with separate content storage.Supported operations
Insert { item_id, position }Move { item_id, position }Delete { item_id }
Core behavior
- Item identity is stable (
item_id) and independent of position - Position is fractional-index based for efficient between-item inserts
InsertandMoveresolve with LWW semantics for position winnerDeleteis absorbing for that item identity
item_id do not resurrect it.
Why this model
This avoids common “reorder as delete+insert” pitfalls and composes better with sidecar content updates. Use lists for ordered entities like tasks, cards, timeline entries, and playlist items.Choosing the right model
Pick the CRDT that matches user intent:Mapfor winner-takes-key object stateTextfor collaborative character streamsListfor stable-item ordered collections
Practical modeling guidance
- Keep canonical and speculative lanes in separate key spaces when both exist
- Use map values for item content, list ops for item order/identity
- Treat blob references as map values; keep binary payload lifecycle in blob storage flows
- Avoid ad-hoc custom conflict logic in app code when CRDT model already defines deterministic behavior