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).
bit 0 — CAN_CREATE_CONTEXT
bit 1 — CAN_INVITE_MEMBERS
bit 2 — CAN_JOIN_OPEN_CONTEXTS
bit 3 — MANAGE_MEMBERS
bit 4 — MANAGE_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.