← the Atlas

Shared canvas — read-only multiplayer, one writer, comments

Features·seedling·proposed·

Share a live kolu canvas with someone else — read-only viewers first with exactly one writer, then anchored comments; the broker machinery already exists, the new work is capability links and honest presence.

The feature, in plain words. Send someone a link; they see your live canvas — terminals streaming, agent states, urgency — but can’t type. Exactly one person holds the pen (you, until you hand it over). Later: comments pinned to tiles, so a reviewer can say “this agent went off the rails” on the terminal it happened in. (tmate, Upterm, Warp session sharing and Zellij multiplayer prove the demand for terminal sharing; kolu’s differentiated form is sharing a workspace of agents with their attention state visible — see the future-work survey.)

What already exists (the reason this is smaller than it looks)

kolu-server already brokers N clients onto one binding — two browser tabs on the same host are the shipped, e2e-pinned case (the switch’s “two tabs stay independent” test), and padi already serializes concurrent writes (last-write-wins on chrome/layout — the multi-client risk the plan has always carried). So multiplayer viewing is not new transport; the genuinely new work is three things:

  1. A capability link (the auth story — the real work). kolu’s trust model today is the origin gate + the ssh user; there are no per-person identities. The honest MVP that doesn’t invent an account system: a share link carrying an unguessable capability token, minted per share (scope: this host’s canvas, read-only, revocable, optional expiry), checked at the ws-upgrade beside the origin gate. Revoking kills the socket. This extends the existing gate rather than replacing the trust model — and it must be loud in the UI (a standing “shared with 2 viewers” chip; nothing silent).
  2. Read-only enforcement server-side. A viewer connection gets the surface’s cells and byte streams but its writes are rejected at the router — a capability-scoped router variant (the per-host router machinery from the switch makes this a filter, not a fork). Never client-side-only enforcement.
  3. One writer, made explicit. Today “one writer” is social. Formalize it as a writer lease on the binding (the sharer holds it by default; handoff is explicit, surrendered on disconnect) — turning padi’s last-write-wins from a collision policy into a non-event, and giving the UI an honest pen indicator.

Comments on the canvas (phase 2)

Anchored annotations: a comment attaches to a terminal id (and optionally a scrollback position), rendered as a pin on the tile; a thread panel per tile. Storage: a per-host comments cell on the kolu surface (server-side Conf, like recents — comments are about the workspace, not the daemon, so they live in kolu-server, not padi). Viewers with the capability can comment even while read-only — that’s the point of review. Deliberately out of scope until asked: mentions, resolution workflows, cross-host comment feeds.

Phasing

Constraints from the future-work note apply: the ssh-user caveat means a share link shares YOUR authority over that host’s canvas — the note must say so plainly in the share dialog; and viewer connections count against the per-binding wire budget (viewers subscribe the same re-served surface — bounded, but not free).