Skip to main content
A realm is Meerkat’s state boundary. Sessions, config, auth bindings, runtime state, schedules, WorkGraph, jobs, blobs, artifacts, and mob state are all scoped by a realm_id. Sharing requires both the same logical realm and the same physical storage provider/root. Supplying the same ID with two deliberately different explicit state roots selects two different stores. For task-oriented commands and troubleshooting, see the realm guide.

Identity Rules

Explicit user-facing realm IDs:
  • are 1-64 characters;
  • start with an ASCII alphanumeric character;
  • contain only ASCII alphanumerics, _, and -;
  • cannot contain whitespace or :; and
  • cannot use a UUID-like opaque value.
Use a stable descriptive ID such as team-alpha, prod, or audit_2026. Meerkat-generated workspace and isolated IDs use separate typed construction paths.

Surface Defaults

The CLI is workspace-friendly by default. Server processes are isolated by default so unrelated launches do not collide.

Context Root And Project Root

Meerkat keeps two path facts distinct:
  • Invocation context is the supplied current directory or --context-root. Its canonicalized path determines the workspace-derived realm ID (raw path only if canonicalization fails), while the supplied path remains the no-walk-up boundary for MCP config/trust discovery.
  • Project root is found by walking upward from the invocation context to the nearest existing .rkat entry. Its .rkat/realms directory is the project-local realm-storage candidate. Outside any existing project, the exact invocation context is used for a fresh local candidate.
Running from a nested directory can therefore derive a different default ws-... realm while storing that realm under the ancestor project’s .rkat/realms. Use an explicit --realm or a common --context-root when the nested command should share the parent’s logical realm.

Realm-ID-First Root Resolution

Meerkat resolves identity first, then looks for that realm under candidate roots:
  1. --state-root selects one explicit root and disables candidate probing.
  2. Otherwise, the resolver probes the project-local candidate and user-global platform data root for the resolved realm ID.
  3. If the realm exists under exactly one candidate, Meerkat opens it where it already lives.
  4. If it exists under both, startup refuses with a typed split-brain error rather than choosing silently.
  5. If it exists nowhere, the surface creates it under its default root: local for CLI and user-global for servers.
Server surfaces include the project-local candidate only when started with an explicit context root. First creation reserves the realm across the candidate set that invocation actually resolved before writing the manifest. Processes using the same multi-root candidate set cannot mint twins, but a bare server that probes only the user-global root does not coordinate with a CLI probing a project-local root. Use a common --state-root or matching server --context-root when cross-surface first-start convergence matters. Use these operator commands when layout is unclear:
rkat storage migrate is a report-only dry run unless --apply is supplied. Adopting one root archives the other registered copy; it does not merge divergent state automatically.

Explicit Sharing

SDK clients pass the same value when connecting:
When separate hosts do not share a filesystem, use the same external RealmStorageProvider rather than assuming equal realm IDs make local disks shared.

Backend And Provider Pinning

The first open writes realm_manifest.json. It pins the built-in backend or external storage provider, so later surfaces cannot reinterpret the realm: sqlite is the normal durable same-realm multi-process profile. jsonl keeps inspectable session files and a durable runtime.sqlite3 companion for runtime authority. memory is explicitly ephemeral and process-local. Manifest format 2 can also record operator-declared ephemeral domains. A storage provider must declare exactly one durability result for each required domain: sessions, runtime, schedule, workgraph, jobs, blobs, and artifacts. A durable domain resolving to undeclared non-persistent storage refuses startup unless the manifest explicitly declares that domain ephemeral. A provider can instead return the typed DeclaredEphemeral resolution itself, as the JSONL backend does for its disabled schedule store; that typed provider declaration does not require a duplicate manifest entry. Readers reject a manifest format newer than they support and reject a provider or backend mismatch. Existing realms remain pinned when defaults change.

Config And State

The realm’s own config document is <state-root>/<realm>/config.toml, except for the reserved global realm, whose config is home-rooted at ~/.rkat/config.toml. Config can inherit from parent realms, but state never does. A child can inherit models, bindings, MCP servers, hooks, skills, and limits while keeping its sessions and every durable state domain local.

See Also