Realtime sync protocol — v3
How editorzero converges concurrent edits from humans and agents into a single causal history — without a central lock, and with every keystroke attributable in the audit log.
Every document in editorzero is a conflict-free replicated data type (CRDT). Replicas hold their own copy of the doc and exchange compact update messages; the merge function is commutative, so the order of arrival never changes the result. Two editors — a person in the browser and an agent on the API — can both write into the same paragraph and converge to the same bytes.
01The causal model
Each update carries a logical clock. We never overwrite; we accumulate. A delete is itself an operation, tombstoned rather than erased, so that a replica which was offline can still reconcile cleanly when it returns to the field.
Verified against the durability property test: snapshot + replayed updates reproduce the live Y.Doc byte-for-byte. This claim is safe to publish.
02Presence & attribution
Awareness state rides a side channel — cursors, selections, and the principal behind each one. Humans render in cyan, agents in violet, everywhere in the product. Attribution is not cosmetic: it maps to a row in the audit log.
- Human principals — session-scoped, MFA-gated, cursor labelled by handle.
- Agent principals — token-scoped, rate-limited, revocable, every mutation signed with the agent's identity.
- Suggestions — agents may propose tracked changes that a human accepts or rejects before they land.
03The wire format
Updates are length-prefixed binary frames. The reference encoder is small enough to read in one sitting:
export function encodeFrame(u: Update): Uint8Array {
const body = Y.encodeStateAsUpdate(u.doc)
return frame("sync/v3", u.clock, body)
}
That is the entire contract a new surface needs to speak. The CLI, the MCP server, and the web client all encode the same frame — parity is a property test, not a promise.