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/namespaces to 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 wasm field in the manifest) work as before — no service name needed.
  • Multi-service bundles declare a services array in the manifest, each with a name and WASM path.
  • When creating a context for a multi-service app, specify service_name to choose which WASM to run.
  • All services in a bundle share the same ApplicationId and upgrade atomically.
  • Example: a chat application with services user-mgmt, chat, and storage — 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).

// conceptual bit layout
bit 0CAN_CREATE_CONTEXT
bit 1CAN_INVITE_MEMBERS
bit 2MANAGE_MEMBERS
bit 3MANAGE_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.