Core Concepts
Groups, contexts, roles, capabilities, and CRDTs for app builders
Namespaces
A namespace is a root group (a group with no parent). It is the application instance boundary and the identity scope for a node.
- Each namespace gets its own Ed25519 keypair, auto-generated on first use and persisted in the datastore.
- All subgroups and contexts within the namespace share the same node identity.
- Different namespaces have different keys — identity isolation across application instances.
- Subgroups inherit the namespace’s
target_application_id; upgrading the root upgrades the entire tree. - The admin API exposes
GET /admin-api/namespacesto list, query, and inspect namespace identity. - All groups within a namespace share a single governance DAG. Operations are either cleartext (RootOps: group creation, member join, key delivery) or encrypted (GroupOps: membership changes, capabilities).
- New members receive group encryption keys via ECDH-wrapped KeyDelivery on the namespace DAG.
Groups
A group is a governance boundary within a namespace. It has members, an application (inherited from the namespace root), 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 (or different services from the same bundle) with independent state.
- Joining a context requires group membership. By default (
auto_join: true), joining a group auto-joins all its contexts. - For multi-service applications, each context specifies which service it runs via an optional
service_name.
Services (multi-WASM bundles)
An application bundle (.mpk) can contain multiple named services, each with its own WASM binary and optional ABI.
- Single-service bundles (one
wasmfield in the manifest) work as before — no service name needed. - Multi-service bundles declare a
servicesarray in the manifest, each with a name and WASM path. - When creating a context for a multi-service app, specify
service_nameto choose which WASM to run. - All services in a bundle share the same
ApplicationIdand upgrade atomically. - Example: a chat application with services
user-mgmt,chat, andstorage— each running in its own context with independent state.
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 (add/remove members, manage subgroups).
Restricting access via subgroups
To restrict access to specific contexts, create a subgroup and add only the intended members. Contexts within that subgroup are only accessible to its direct members (and inherited parent members). This replaces the former per-context visibility/allowlist model with a simpler group-membership-based approach.
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 — MANAGE_MEMBERS
bit 3 — MANAGE_APPLICATION
CAN_CREATE_CONTEXT
Bit 0. Create new contexts in this group.
CAN_INVITE_MEMBERS
Bit 1. Issue invitations for new members.
MANAGE_MEMBERS
Bit 2. Add or remove non-admin members.
MANAGE_APPLICATION
Bit 3. Set the target application and handle migration.
Context access
Context access is determined entirely by group membership. Any member of a group can join any context within that group. To restrict access to a subset of contexts, create a subgroup and register those contexts there — only subgroup members (direct or inherited) can join them.
By default, auto_join: true causes joining a group to automatically subscribe to all its contexts. Context membership is implicit from group membership — no separate governance op is required.
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.