Multiplayer Collaborative Canvas · View 12 of 23 · Data
Decisions
- The document graph is not stored as rows. It is the fold of its operations, materialised into a checkpoint — which is why `document.head_seq` and not a shape table is the document's state (ADR-02).
- `operation` is keyed by (document_id, seq) with the epoch recorded on every row. The epoch is the fence: an append from a host holding an older epoch is rejected by the store, not by a service (ADR-03).
- `session_lease` is one row per document, and it is the only mutable row on the authority path. Everything else about authority is append-only.
Assumptions
- `comment.anchor_seq` records the version the anchor was valid at, so an orphaned comment can say when it was orphaned.
- `asset.scan_state` is part of the model rather than a side table, because an unscanned asset must be referenceable but not servable.
- Residency and customer-managed keys live on `tenant`, so a document's region and key are resolved without a join at admission.
Risks
- Partitioning by document means no cross-document transaction exists. A feature that needs one — moving a component library between documents atomically — is a new design, not a new query (ADR-08).