Collaboration and concurrent-edit recovery
Understand how Open Knowledge preserves content under concurrent editing and how to restore an auto-saved checkpoint if a race ever slips through.
Open Knowledge's editor is collaborative out of the box — two collaborators (or an agent and a user) can type in the same document at the same time, in either the WYSIWYG or source view, and both sets of edits are preserved. The collaboration layer is a Y.js CRDT; it handles the overwhelming majority of concurrent edits without any visible signal.
A very small class of interleavings can still trip the underlying CRDT's structural limit (formally proven by Khanna-Kunal-Pierce 2007). When that happens, Open Knowledge automatically:
- Logs a structured
bridge-merge-content-lossevent (visible in the server's stdout / log aggregator). - Writes a silent checkpoint of the pre-merge state to the timeline.
- Keeps the editor responsive — you keep typing.
No toast, no modal, no interruption. The recovery affordance lives in the [[timeline]] panel — always available, never in your way.
What you'll see
If you notice a paragraph blink, or feel like "a chunk of my text just vanished," open the Timeline panel for the affected document. Recent entries carry distinct icons:
- Diamond — a user-triggered Save Version. Nothing automatic.
- Amber alert-triangle — "Auto-saved before a concurrent edit (<size>)". Open Knowledge saved a snapshot of the document right before a concurrent edit finalized. If your lost content is anywhere, it's here.
- Sky file-archive — "Recovered from an external change (<size>)". An external writer (another process, a
git checkout, a file-watcher sync) overrode an in-memory draft. The draft is preserved under this entry.
Click the entry to view the snapshot. The editor shows the pre-merge state in read-only preview; from there you can copy out the missing fragment or restore the whole snapshot over the current doc.
How often does this happen?
For typical usage (one or two collaborators, normal typing cadence), the rate is well under one checkpoint per document per day. If you see checkpoints accumulating faster than that, file an issue — it's worth investigating the specific interleaving.
What if I don't notice in time?
The server retains the most-recent 50 auto-saved checkpoints per branch per kind, plus anything within a 30-day TTL (whichever is more generous). Older silent checkpoints are garbage-collected automatically so the Timeline stays readable. User-triggered Save Version checkpoints are retained permanently.
Advanced
- Set
OK_TELEMETRY_VERBOSE=1on the server to include the raw lost-substring content in thebridge-merge-content-losslog line (default is a redacted length + FNV-1a digest so verbatim user content never reaches a log aggregator). - Set
OK_RETHROW_BRIDGE_LOSS=1to force the merge error to throw rather than silently recover. Useful for local debugging or CI harnesses that want the loud-fail path. Production deployments should leave this unset — the default keeps users typing.
Restart and reconnect
Open Knowledge keeps a per-tab copy of each document's CRDT state in your browser's IndexedDB so a server restart, a Cmd-R, or a flaky network never costs you content.
Instant Cmd-R
When you reload an Open Knowledge tab, the editor renders the prior state from local IndexedDB before the WebSocket reconnect completes. You don't see a loading spinner; you see your document. The reconnect happens in the background — once the server's state arrives, any unsynced edits you had in the buffer replay onto the fresh provider and propagate.
Where the data lives
Each open document gets one IndexedDB database under your editor's origin, named:
ok-ydoc:<branch>:<doc-name>The branch prefix scopes the cache per git branch — switching branches doesn't surface stale-branch content into the post-switch session. You can inspect (and clear) these databases via your browser's DevTools → Application → IndexedDB.
If a document ever gets stuck in a bad state — content not converging, repeated reconnect loops — clearing the matching ok-ydoc:<branch>:<doc-name> database and reloading the tab gets you back to the server's canonical markdown state. Your in-progress edits since the last server ack are forfeit, but disk-persisted content always survives.
Server restart
When the Open Knowledge server restarts, every tab connected to it sees an authentication mismatch on reconnect — the new server has a different per-process instance ID. The recycle flow is:
- Buffer each open document's unsynced delta (edits the server hasn't durably persisted yet) in memory.
- Wipe the per-document IndexedDB cache.
- Drop and rebuild the WebSocket provider.
- Replay the buffered delta onto the freshly-rebuilt provider once it finishes its first sync.
The whole sequence usually completes in 50–500 ms. The disk-ack channel narrows the durability boundary further: edits the server has already flushed to disk are recovered from the post-restart markdown rebuild, so the actual loss window is "edits that hadn't yet flushed" — typically sub-second under normal write debouncing.
Trade-offs
- Tab-crash mid-restart (within the 50–500 ms recycle window) loses unsynced edits — the buffer-and-replay is in-memory only.
- Two tabs of the same document can block IndexedDB cleanup if both hold the connection open. The pool will skip the recycle for any document whose IDB couldn't be cleared and emit
ok-mismatch-recycle-partial-clears-failedto the console; close the other tab (or the DevTools IDB pane) and reload to recover. - Branch switch (via the CC1
branch-switchedchannel) clears every open document's IDB without buffer-and-replay — branch-A edits aren't semantically valid on branch B and are intentionally discarded.
Where to learn more
- Architectural detail: the [[architecture]] internals page covers the settlement-based observer bridge and the content-preservation post-condition.
- Full spec:
specs/2026-04-16-bridge-correctness/SPEC.mdin the repo. - Restart-recovery design:
specs/2026-04-24-client-persistence-replaces-sidecar/SPEC.mdandpackages/server/README.md§ "CRDT server-restart recovery".
Agent Activity Panel
Click any agent's avatar in the presence bar to see every file they've edited this session — per-burst diffs, filename-click nav, and selective per-file rollback.
Service topology
How the Hocuspocus server, file watcher, persistence pipeline, and shadow repo work together per project.