Collaborative board × Interocitor

Two local boards. One encrypted mesh.

Maya and Noah can add or move cards against their own local state. Nothing reaches the other board until you sync; then both clients exchange protected row changes and converge.

Working stateLocal to each clientEdits do not wait for a server round trip.
ConflictsDeterministic field mergeConcurrent edits to the same field resolve by the mesh rule.
MailboxProtected payloadsPaths, sizes, timing, and device identifiers remain visible.

Both local boards start in sync.

Trusted client 01

Maya’s board

0 local cards

Ideas

    Doing

      Done

        Trusted client 02

        Noah’s board

        0 local cards

        Ideas

          Doing

            Done

              What this proves

              Convergence is not workflow policy.

              Interocitor moves and merges row changes. The application still owns card permissions, ordering semantics, notifications, deletion policy, and any rule that must reject or serialize a move. This demo deliberately keeps those product rules small.

              The minimal shape

              Illustrative excerpt: client construction, encrypted key custody, and rendering are omitted. The linked TypeScript source is the complete runnable demo.

              const schema = {
                tables: {
                  cards: {
                    fields: {
                      id: types.string,
                      title: types.string,
                      column: types.string,
                      rank: types.index(types.number),
                      updatedBy: types.string
                    }
                  }
                }
              } satisfies DatabaseSchemaDefinition<BoardDB>;
              
              const cards = db.table("cards");
              
              await cards.patch(cardId, { column: "done", updatedBy: deviceName });
              await db.flush();
              await peer.pull();
              Read the full board source →