Deepanshu's Diary

Designing Append‑First Data Models for Docs‑Style Collaboration and Auditing

--system-designcollaborationdata

I was debugging a billing dispute when two things happened: a product manager edited the same paragraph I had just summarized, and an automated summarizer had already emitted a citation that no longer matched the new text. That tiny race—human edit, background job, and model output colliding—exposed a core tension: collaboration is not just about low-latency syncing; it changes what you record, how you index it, and who owns the truth.

In this post I explain a mental model for collaboration-aware data models, show a concrete architecture/data-flow example, and describe what I implemented in the ARIL tenancy and audit model. I end with failure modes, mitigations, and a practical checklist you can apply to similar systems.

Why collaboration changes the data model

Traditional data models assume a primary record that gets updated in place. Collaboration, especially Google Docs-style concurrent editing, undermines that assumption in four ways:

- Multiplicity of truth: multiple users (and automated agents) can change state concurrently. - Temporal reasoning: consumers need to know which version produced a downstream artifact (a summary, a vector embedding, an audit decision). - Tenant isolation: collaborative systems are often multi-tenant, so isolation and policy must travel with the data. - Auditability: you must be able to reconstruct who changed what, when, and which downstream outputs used which inputs.

Mental model: append-first, lineage-second

Treat the document store as an append-only stream of operations (or deltas), and treat the current document state as a projection. Record edits, citations, and derived artifacts (embeddings, summaries) as first-class, versioned objects with stable identifiers. Key concepts:

- Operation: an atomic user or system change (insert, delete, attribute change) with author, timestamp, and op-id. - Snapshot: a point-in-time projection of operations (can be a CRDT state, or a compacted diff). - Artifact: anything derived from a snapshot (embedding vectors, summaries, classification labels), annotated with source snapshot-id and a digest of the inputs. - Tenant context: the tenant id and policy tags travel with every operation and artifact.

This model makes lineage explicit: an artifact references the exact snapshot (or op-range) that produced it. You can invalidate or recompute artifacts if the referenced snapshot changes.

A concrete architecture/data-flow example

Below is a compact flow for “document edited -> embedding updated -> retrieval used for a model response”:

1. User edits document in the browser. The client emits a sequence of operations to the collaboration service (CRDT or OT). Each op includes tenant-id and user-id. 2. The collaboration service appends ops into the tenant-scoped operation log and emits a committed snapshot event with snapshot-id (compaction runs asynchronously). 3. A downstream worker subscribes to snapshot events and computes deterministic artifacts: chunking, text cleaning, embeddings. The worker writes artifacts to a tenant-scoped vector table with artifact metadata including snapshot-id and op-range used. 4. A retrieval query resolves candidate artifacts by vector similarity and then verifies artifact snapshot-ids against the latest document snapshot for staleness; if stale, it either re-ranks or queues recomputation. 5. The final model pipeline emits a response and records an audit event referencing: request id, tenant id, artifact ids used, model version, and snapshot-ids.

A minimal table to clarify responsibilities

| Component | Responsibility | |---|---| | Collaboration log | Append ops, low-latency sync (CRDT/OT), tenant scoping | | Snapshot service | Compact ops into snapshots, assign snapshot-ids | | Artifact worker | Deterministic chunking/embeddings; store artifact metadata referencing snapshots | | Retrieval service | Vector queries + snapshot staleness checks | | Audit store | Durable events linking request -> artifacts -> snapshots -> users |

What I built around this idea (ARIL tenancy and audit model)

In the ARIL local monorepo I implemented the core pieces of this approach:

- Tenant-scoped knowledge bases, documents, and chunks with protected routes and per-tenant isolation. (Implemented) - Embedding generation and pgvector-backed retrieval with artifact metadata that references document/chunk ids and snapshot markers. (Implemented) - Citation and evaluation metrics attached to artifacts and model outputs so each response can be traced back to sources. (Implemented) - An audit trail model that logs events (who, when, what artifacts were used). (Implemented)

What remains a gate or operational work:

- Real production Postgres migration and deployment are environment gates; the monorepo includes migrations and schemas, but the production migration pipeline is not yet executed in a live environment. (Gate)

Where this breaks (failure modes and mitigations)

1) Out-of-order artifacts: a worker computes embeddings for a snapshot, but subsequent edits make them stale. - Mitigation: embed snapshot-id and op-range in artifact metadata; on retrieval, validate freshness and prefer artifacts whose snapshot-id matches the latest compacted snapshot or trigger async recompute.

2) Audit log growth and query cost: logging every low-level op and artifact can balloon storage and slow queries. - Mitigation: tiered retention (raw ops short-term, compactions and snapshots long-term), partitioned audit indices by tenant, precomputed materialized audit views for common queries.

3) Cross-tenant leakage: misconfigured tenancy enforcement could expose artifacts across tenants. - Mitigation: fail-closed middleware that enforces tenant-scoped DB schemas or row-level security, encryption of tenant secrets, and protected routes (what ARIL uses).

4) Model/operator confusion: automated agents (summarizers, rankers) produce edits concurrently with humans, causing frequent invalidations. - Mitigation: explicit agent identities and approval gates for automated edits; use merge policies (human-precedence or causal merge) and surface conflicting ranges in the UI for quick resolution.

5) Vector drift and retrieval inconsistency: embeddings evolve (model updates) causing mismatches between stored vectors and new model behaviors. - Mitigation: record embedding model version in artifact metadata and include scheduled re-embedding jobs when models update.

A practical checklist (5–8 checks)

- Check tenant isolation: enforce tenant-id at every layer (API, DB, vector store). - Check lineage: every artifact must reference a snapshot-id or op-range. - Check audit linkage: record request -> artifact -> snapshot -> user for each model response. - Check artifact freshness: retrieval must detect and handle stale artifacts. - Check retention policy: define and implement audit and artifact retention/compaction. - Check model versioning: include model/version metadata for embeddings and generative models. - Check gates for automated agents: require approval for any auto-edits that affect persistent documents.

Conclusion

Google Docs-style collaboration forces you to stop thinking of a single canonical record and start thinking in terms of append-only operations, versioned snapshots, and explicit lineage. That shift makes retrieval, embedding, and audit correct-by-construction: artifacts are always tied to the inputs that generated them, tenants remain isolated, and operators can reason about recomputation and retention. In ARIL I implemented a tenant-scoped append-and-artifact model with pgvector retrieval and audit trails; production migration and operational hardening remain deliberate gates.

References

[1] Model Context Protocol — https://modelcontextprotocol.io/introduction

[2] Anthropic — Model Context Protocol news — https://www.anthropic.com/news/model-context-protocol

[3] Operational transforms and CRDTs (survey) — https://arxiv.org/abs/2005.11401

[4] On consistency and collaboration (relevant theories) — https://arxiv.org/abs/2307.03172

[5] My portfolio repo (ARIL & related projects) — https://github.com/deepanshuvermaa/my-portfolio

[6] Additional portfolio projects and examples — https://github.com/deepanshuvermaa/museum-of-failure

Copied!
Back to all posts