Skip to content
C.W.K.
Stream
Lesson 07 of 09 · published

A Rename Is a Fact

~11 min · sync-engine, rename, identity, three-way-merge, v3

Level 0Cold Draft
0 XP0/43 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"A path is where a note lives today. It was never who the note is."

One Note, Two Files

On 2026-09-24 Dad ran a plain test: one note, edited on office and on the iPhone, then retitled "sync" on office. The Mac names a note's file after its title, so office moved untitled-note-16.md to sync.md. The next sync round compared paths, the way the plan always had: against the shared base, office had deleted untitled-note-16.md and the phone had changed it. An edit beats a deletion, so the phone's version came back under the old name — and office now held both files. Office's older records showed the same thing had already happened to two earlier untitled notes. Nothing was lost; the library just quietly grew strangers.

Why the Plan Could Not See It

The sync plan is a three-way comparison per path: the base checkpoint, this side, the other side. That is exactly right for edits and deletions, and exactly blind to a rename, because a rename is the one change that is about the path. To the plan, "moved from A to B" and "A deleted, unrelated B appeared" were the same evidence. The files-are-truth rule from track 7 still held — but it had been resting on an assumption nobody wrote down: that a note's path is its identity.

Make the Rename a Synced Fact

The fix gives renames their own record instead of inferring them. Whenever a root renames a note — the Mac on a title change, the device through its explicit Rename — it writes a small JSON file under meta/renames/ with from and to (root-relative note paths) and renamedAt (milliseconds since 1970). Only a note-to-note move inside notes/ is followed; any other record is ignored as invalid. Those files are a new sync kind, renameLog, carried additively to every replica like assets are, admitted by the engine's path policy and added to the device kinds. So a third replica that only ever talks to office still learns a rename the phone made.

The plan now chains each base note through the combined log in time order. When the base and one side still hold the old name and the other side holds only the new one, the holder's copy, the base and the note's portable sidecar and snapshots are read under the new name, and the executor moves them there whichever version wins — a plain move when the bytes match, both versions kept when they conflict (the device's text under the name, the other under a conflict name), the tag merge when only tags differ. A rename both sides made, or one onto a name the holder already uses, falls back to the old path rules. And the untouched case — renamed on one side, unchanged on the other — no longer asks anyone to confirm a deletion.

One ordering rule rides along: office must be installed before any device build that asks for the new kind, because an older engine refuses kinds it does not know. A new fact on the wire is a protocol change, even when the protocol version number does not move.

Code

meta/renames/{id}.json — the rename, written down at the moment it happens (illustrative values)·json
{
  "schemaVersion": 1,
  "id": "<a UUID per rename>",
  "from": "notes/untitled-note-16.md",
  "to": "notes/sync.md",
  "renamedAt": 1790000000000
}
What the plan saw before, and what it sees now·text
base: untitled-note-16.md     office: sync.md (renamed)     phone: untitled-note-16.md (edited)

before (paths only)
  untitled-note-16.md   deleted on office, changed on phone -> edit wins, file comes back
  sync.md               new on office                       -> kept
  result                two files, one note

now (paths + renameLog)
  rename log: untitled-note-16.md -> sync.md
  read the phone's copy and the base UNDER sync.md, then compare
  result                one file, sync.md, with the phone's edit (or both kept on conflict)

External links

Exercise

Think of any system you use that keeps two copies of a folder in step. Rename a file on one side and edit it on the other while they are apart. Predict what happens when they meet: one file, two files, or a conflict? Then design the smallest record that would let the system follow the rename instead of guessing.
Hint
Most path-based tools either duplicate the file or ask you to confirm a deletion. The record that fixes it is tiny — old path, new path, time — but it has to be written by the side that renamed, at the moment of the rename, and it has to travel to every copy.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.