Living Document Notice
Published 2026-09-17. The evolving architecture, revisions, and connected notes for this dispatch live in the Stax Digital Garden.
Offline Conflict-Free Note Reconciliation
Summary
Editing contact dossiers across disconnected laptops and mobile devices inevitably causes merge conflicts. Yeoman utilizes deterministic state clocks and append-only union semantics to resolve concurrent relationship updates without data loss.
The Perils of Distributed Relationship Editing
When an operator updates a contact’s phone number on a laptop while traveling and simultaneously logs a voice call note on a mobile phone, standard file synchronization tools (such as Syncthing or Git) encounter conflict markers:
<<<<<<< HEAD
last_contact_date: '2026-09-16'
=======
channels:
- kind: phone
value: '+15550199999'
>>>>>>> branch-mobile
Conflict markers corrupt automated parsers, break JSON-RPC adapters, and force manual resolution.
Yeoman avoids conflict markers by structuring contact updates around Conflict-Free Replicated Data Type (CRDT) principles applied to plain text frontmatter.
+-------------------------------------------------------------+
| Deterministic Three-Way Merge Engine |
| |
| Base Note: v1.0 (Cadence: 14d, Last Contact: 09-01) |
| │ │ |
| ▼ ▼ |
| Node A: Update Channel Node B: Log Interaction |
| (+ Signal Handle) (Last Contact: 09-16) |
| │ │ |
| └────────────────┬───────────────┘ |
| │ |
| v |
| Merged Note: v2.0 |
| - Channels: Merged Set Union |
| - Last Contact: max(09-01, 09-16) -> 09-16 |
| - Interaction Log: Append-only concatenate |
+-------------------------------------------------------------+
Semantic Merge Strategies by Field Type
Rather than treating the note as an opaque array of text lines, Yeoman decomposes frontmatter into typed field primitives with specialized merge rules:
| Field Name | Data Type | Merge Strategy | Resolution Logic |
|---|---|---|---|
last_contact_date | ISO Date | Monotonic Max | Latest chronological date wins |
cadence_days | Integer | Last-Write-Wins | Highest timestamp in $pkm.updated_at wins |
channels | Array of Dicts | Keyed Set Union | Union by kind + value; preserve verified flags |
relations | Key-Value Pairs | Dictionary Merge | Union of relation predicates |
| Body Notes | Markdown Text | Sectional Concatenation | Appends new log blocks under unique timestamp headers |
Implementation of Monotonic Frontmatter Merging
The reconciliation engine parses the abstract syntax tree (AST) of conflicting files and computes a deterministic unified state:
pub fn merge_contact_dates(base: NaiveDate, local: NaiveDate, remote: NaiveDate) -> NaiveDate {
// Monotonically take the latest verified interaction date
std::cmp::max(local, remote)
}
pub fn merge_channels(local: Vec<Channel>, remote: Vec<Channel>) -> Vec<Channel> {
let mut merged = local;
for r in remote {
if !merged.iter().any(|l| l.kind == r.kind && l.value == r.value) {
merged.push(r);
}
}
merged
}Zero-Data-Loss Guarantees
If a structural collision occurs that cannot be resolved deterministically (such as conflicting edits to the same biographical paragraph), Yeoman never discards content. The conflicting variant is preserved as an archival child note (contact-name.conflict-20260917.md), and an administrative notification is placed in the review queue.
- Directus Target: yeoman
- Garden Source Reference: MOC - Bosun PKM Tools, MOC - Fleet Operations
- Garden Source Reference: [YMN-1009 - Offline Conflict-Free Note Reconciliation](YMN-1009 - Offline Conflict-Free Note Reconciliation)