Core Concepts

Groups, contexts, roles, capabilities, and CRDTs for app builders

Groups

A group is the top-level governance boundary. It has members, an application, and one or more contexts. All membership management, access control, and upgrades happen at the group level via signed governance operations that propagate via P2P gossip.

  • Think of the group as where you vote, invite people, and upgrade the app.
  • Contexts live inside a group; they do not replace group governance.
  • Every group has at least one Admin who can always perform administrative actions.

Contexts

A context is a running instance of a WASM application with its own isolated state. State stays in sync across context members automatically, using CRDT-based replication.

  • Each context belongs to exactly one group.
  • Multiple contexts can run the same application with independent state.
  • Joining a context is separate from joining the group; visibility rules apply (see below).

Member roles

Roles define what a member can do inside a group. The platform enforces them consistently on every node.

Admin

Full control: all governance operations, member management, and state writes.

Member

Standard participant: read and write app state. Some operations still require explicit capabilities.

ReadOnly

Observer: can join and read state. Mutations are rejected locally and on remote peers.

Subgroups

Groups form a tree. A child group links to a parent.

Membership and admin inheritance

  • Membership inherits downward: a parent member is also a member of descendant groups.
  • Admin authority inherits for structural operations on the tree, but not for access control inside child resources (see Restricted contexts).

Privacy boundary for Restricted contexts

Only direct group admins may manage the allowlist for a Restricted context in that group. Parent admins cannot manage those allowlists on behalf of a child—this keeps child-level privacy intact.

Capabilities

Beyond the base role, fine-grained capabilities gate specific actions.

  • Admins always pass capability checks.
  • Default capabilities can be configured per group and applied to new members automatically.

Flags

Each capability corresponds to a bit in the member’s capability set (shown conceptually below).

// conceptual bit layout
bit 0CAN_CREATE_CONTEXT
bit 1CAN_INVITE_MEMBERS
bit 2CAN_JOIN_OPEN_CONTEXTS
bit 3MANAGE_MEMBERS
bit 4MANAGE_APPLICATION

CAN_CREATE_CONTEXT

Bit 0. Create new contexts in this group.

CAN_INVITE_MEMBERS

Bit 1. Issue invitations for new members.

CAN_JOIN_OPEN_CONTEXTS

Bit 2. Join contexts whose visibility is Open.

MANAGE_MEMBERS

Bit 3. Add or remove non-admin members.

MANAGE_APPLICATION

Bit 4. Set the target application and handle migration.

Context visibility

When you create a context, you choose who may join it.

Open

Any group member (including membership inherited from a parent) may join when they hold the CAN_JOIN_OPEN_CONTEXTS capability. Admins satisfy this implicitly.

Restricted

Only members on the allowlist may join. There is no admin bypass. Direct group admins edit the list; if an admin is not listed, they may add themselves (as direct admins), then join like any other allowlisted member.

CRDT state

All application state uses CRDTs for conflict-free synchronization. State changes produce deltas that are broadcast via gossip. Every node converges to the same logical state even when messages arrive in different orders.

Built-in types

Pick the structure that fits your app; the runtime handles merging.

UnorderedMap

Key-value map with last-write-wins per key.

Vector

Ordered, append-only list of elements.

Counter

Distributed counter (G-Counter style, per-node slots).

LwwRegister

Single value with last-write-wins by timestamp.

ReplicatedGrowableArray (RGA)

Character-level text CRDT for collaborative editing.

What “converge” means for your app

Peers may receive updates in different orders. CRDT rules guarantee that once all deltas are applied, every replica shows the same logical state. You design against the data types above instead of inventing your own merge logic.

Cross-context communication

xcall is a fire-and-forget call from one context’s WASM into another context on the same node.

  • Calls are queued while your handler runs and execute after the current commit completes.
  • There is no return value; treat it like an async notification.
  • The target context processes the call as its own member.

When to use it

Good fits: secondary indexes, notifications, audit logs, or any work that should not block the caller’s transaction on a synchronous response.

Same-node scope

xcall is intentionally local to one node. For replication or network-wide effects, use normal context state and sync; use xcall for coordination between contexts co-located on that peer.