---
title: "External document changes merge into the draft, and the draft wins"
description: "Local-first visual environment for building and running AI workflows. Build agents visually, deploy anywhere, privacy by design."
canonical: https://docs.nodetool.ai/adr/0001-document-sync-draft-wins
markdown: https://docs.nodetool.ai/adr/0001-document-sync-draft-wins.md
product: NodeTool
source: https://github.com/nodetool-ai/nodetool/blob/main/docs/adr/0001-document-sync-draft-wins.md
---

# External document changes merge into the draft, and the draft wins

# External document changes merge into the draft, and the draft wins

An agent, the CLI, or another tab writes a document while an editor holds a dirty draft. Before this decision the editor kept the draft and the next autosave failed the `updated_at` CAS with no way forward except a refresh. We now merge the external change into the draft per merge unit (shot, clip, layer, line, node, edge). Where both sides changed the same unit the draft wins and the external value is listed in a document-level conflict banner. An external change never enters the undo stack: Cmd-Z only reverts the user's own edits, so undo cannot silently delete an agent's work.

## Considered options

- Server-side merge: rejected, the server does not know which units the user is still typing in.
- Locks for the duration of an agent run: rejected, a run takes minutes and would block the editor.
- Agent wins on a conflict: rejected, it drops keystrokes the user can see.
- External changes on the undo stack: rejected, undo would remove work the user did not make and write that removal back to the server.

## Consequences

- The `resource_change` payload carries the ops the write was made with. The headless bridge attaches its `ui_*` op list to the document mutation, and the server broadcasts it as the patch. The document mutations keep their whole-section inputs.
- A write with no ops (another tab's autosave, a CLI restore) is one merge unit: a dirty draft keeps everything and the banner lists one conflict, "document replaced elsewhere".
- Draft wins also over an external delete: a unit the user is editing survives, and the next autosave recreates it.
- An agent write that fails the CAS re-reads and reapplies its ops once, then fails the tool call.
- Accepting an external value from the conflict banner is the user's own edit and goes on the undo stack.
- A dangling edge (its node deleted in the draft) is dropped and listed as a conflict.
