Collaboration via passthrough relay — substrate pattern
sweep 2j batch 2: patterns/ + infrastructure/ EN+ES vocab scrub — Foundry/Doctrine removed
@@ -27,7 +27,7 @@ Tools such as Etherpad and HackMD operate on a server-authoritative document mod The passthrough design eliminates that second record entirely. The server is a message conduit, not a store. When a Yjs client sends a binary update message to `GET /ws/collab/{slug}`, the Rust handler receives the raw bytes from the WebSocket and broadcasts them to all other clients in the same slug room via `tokio::sync::broadcast`. The server never deserialises the Yjs protocol; it never constructs a Y.Doc; it never writes anything to disk as a side effect of a relay operation. The only document state the server knows is whatever the client sends through `POST /edit` — the HTTP save path. This matters for the disclosure-substrate posture in Doctrine claim #29 (Substrate Substitution). The canonical disclosure record is the git tree: every topic's content history is a sequence of signed commits, and that sequence is what a regulatory audit would produce. A server-authoritative CRDT store would exist in parallel with that sequence, would not be signed, and would represent content states that never appeared in git. Under the passthrough design, no such parallel record exists: in-flight CRDT state is definitionally not part of the disclosure record because it is never written anywhere. The record closes at `POST /edit` time, not before. This matters for the disclosure-substrate posture. The canonical disclosure record is the git tree: every topic's content history is a sequence of signed commits, and that sequence is what a regulatory audit would produce. A server-authoritative CRDT store would exist in parallel with that sequence, would not be signed, and would represent content states that never appeared in git. Under the passthrough design, no such parallel record exists: in-flight CRDT state is definitionally not part of the disclosure record because it is never written anywhere. The record closes at `POST /edit` time, not before. The 256-message lag buffer configured on each `tokio::sync::broadcast` channel addresses the one race this design must handle: a client that joins a collab session after other editors have already made changes will not have received those earlier Yjs update messages. Because Yjs CRDTs are convergent, a client that receives all prior update messages in any order arrives at the same document state. The 256-message buffer lets a late joiner catch up on recent activity without the server needing to materialise or store the full document state. If the buffer fills before a late joiner connects, Yjs's sync protocol handles the gap through its state-vector exchange on connection open — the server's job remains forwarding, not resolving. @@ -55,7 +55,7 @@ The following is a precise enumeration of what the relay layer deliberately omit ## What this means for disclosure posture In-flight CRDT state — the sequence of Yjs update messages exchanged between clients during a collab session — is not part of the disclosure record and cannot be, by construction. Because the relay never persists those messages, there is no server-side artefact that could later be produced in response to a disclosure obligation. The collab session leaves no shadow state on the server. This is not a gap in the record; it is a design property that aligns the collab implementation with Doctrine claim #29's requirement that canonical storage — here the git tree — be the sole authoritative record. A server-authoritative CRDT store would create a second authoritative record that is not git, not signed, and not suitable for regulatory production. In-flight CRDT state — the sequence of Yjs update messages exchanged between clients during a collab session — is not part of the disclosure record and cannot be, by construction. Because the relay never persists those messages, there is no server-side artefact that could later be produced in response to a disclosure obligation. The collab session leaves no shadow state on the server. This is not a gap in the record; it is a design property that makes canonical storage — here the git tree — the sole authoritative record. A server-authoritative CRDT store would create a second authoritative record that is not git, not signed, and not suitable for regulatory production. Saved edits enter the disclosure record through the same path as all other edits: `POST /edit/{slug}` sends the full Markdown text of the document, the server performs an atomic file rename, and the next git commit in the sequence captures that snapshot. From git's perspective, a collab-edited save is identical to a single-author save. The commit records what the document contained at save time; it does not record who typed which characters during the collab session. The disclosure unit is the committed document state, not the authorship decomposition of how that state was reached.