Living Document Notice
Published 2026-09-23. The evolving architecture, revisions, and connected notes for this dispatch live in the Stax Digital Garden.

AST-Aware Reconciliation: Fixing Git Merge Anxiety in Notes

AST-Aware Reconciliation: 1980s CRT data visualization of diff conflict chevrons parsed by AST syntax tree with sidecar isolation

Why Standard Git Merge Fails on Prose

Git is the standard for text revision control, but engineers frequently abandon it when synchronizing personal notes across multiple workstations and mobile devices.

The friction stems from a fundamental mismatch: Git’s standard three-way merge algorithm (diff3 or ort) is strictly line-oriented. It assumes source code semantics, where statements rarely span arbitrary wrapping boundaries and indentation denotes structure.

When applied to Markdown documents, line-based merges produce catastrophic failures:

  • Frontmatter Corruption: If you update a note’s status tag on mobile while modifying the title on a laptop, Git often treats the entire YAML header as a single colliding block, injecting raw conflict markers (<<<<<<< HEAD) that break parser validation.
  • Paragraph Collisions: Editing two sentences in the same reflowed paragraph results in a textual collision rather than an intuitive merge.
  • List Demolition: Appending items to the bottom of a daily task list from two disconnected machines produces conflicting tail markers instead of an interleaved list.

When a non-technical user (or a developer typing quickly on a phone) opens an editor to find syntax errors and conflict fences, confidence in the version control system collapses.

Semantic Document Reconciliation

A note is not an arbitrary array of lines; it is a structured tree consisting of a metadata dictionary and a hierarchy of block elements (headers, paragraphs, lists, and code fences).

By configuring Git to use an AST-aware custom merge driver, reconciliation shifts from blunt line comparisons to semantic AST operations:

# .gitattributes
*.md merge=bosun-note
# Register the semantic AST merge driver in local git configuration
git config merge.bosun-note.driver "bpt-merge --ancestor %O --current %A --other %B --result %P"

When a merge occurs, the driver parses the ancestor and both modified versions into Concrete Syntax Trees (CST):

  1. Dictionary Merging for YAML: Frontmatter properties are evaluated as independent key-value pairs. Adding a tag on device A and changing last_modified on device B resolves automatically without conflict.
  2. Block-Level Independence: Edits occurring within separate sections or under distinct headings never trigger collisions, even if adjacent lines shifted due to text reflow.
  3. Append-Only Interleaving: Unordered task lists and daily journal logs merge by timestamped item insertion rather than failing on line-position overlap.

Sidecars Over In-Document Pollution

When a genuine textual conflict occurs—such as two radically different rewrites of the exact same paragraph—the driver never injects <<<<<<< HEAD syntax into the active document. Doing so corrupts downstream static site generators, breaks indexing parsers, and makes the file unreadable in standard previewers.

Instead, the driver accepts the local version cleanly into the primary document and writes the colliding branch to a dedicated sidecar file:

# Primary file remains valid and fully parseable
02-Notes/Database-Architecture.md
 
# Isolated conflicting hunk preserved for review
02-Notes/Database-Architecture.conflict-b

The user retains a fully functional workspace, and resolution can take place when convenient without halting automated sync pipelines.


  • Directus Target: blog
  • Garden Source Reference: MOC - Bosun PKM Engine, MOC - Bosun PKM Tools, MOC - Local-First Systems and Synchronization, [BSN-1013 - Plain Text as a Durable Substrate](BSN-1013 - Plain Text as a Durable Substrate)