Collaboration: Shared and Model
Knopper's multi-user story is a type-level discipline, not a subsystem. The
Machine trait's Shared / Model split is the collaboration seam.
The split
Shared— projection state a machine projects from. The host computes projections (roster, transcript, task board, artifact index) from its own session state and pushes them whole viaRuntime::set_shared. Multiple machines may consume slices of the same projection.Model— participant-local UI state (focus, scroll, selection, input buffer). Machine-internal; never host-pushed, never synced wholesale.
One Runtime per participant. Convergence across participants is the host's
problem (a CRDT or event-sourced core); Knopper receives already-merged
projections. This is deliberate: Knopper never sees a terminal byte stream and
never owns a network protocol.
Canonical payload types
knopper::collaboration provides the vocabulary downstream apps share:
ParticipantId— stable participant identityPresence/PresenceTone— presence state and its render toneParticipantRoster— the canonicalShared-resident roster
Remote cursors and selections render as Annotation::PresenceSlot /
Annotation::RemoteCursor overlays — they annotate the scene without
entering layout or focus.
What this buys a host
- Focus stays honest. Because focus is participant-local from day one, adding a second participant never invalidates the first's assumptions.
- Machines are testable single-user.
Sharedstarts as()or a static projection; collaboration arrives by pushing real projections later. - The seam can't be painted shut. Standard machines keep selection/commit
in
Model, so they're multi-user-safe by construction.
Roadmap
The 0.1.0 seam is whole-projection push. Designed and mapped for 0.2.0:
CRDT-backed incremental Shared updates and the Schubert capability
integration (capability-gated actions per participant). See
Collaboration-Ready Contract.