Skip to content

Atespace

An atespace is Substrate’s isolation boundary for actors - the closest thing to a “namespace,” but a Substrate-native resource rather than a Kubernetes one. Every actor is created into an atespace, and an actor’s name is only unique within its atespace. So the real identity of an actor is the tuple (atespace, name), not a bare id.

Where the atespace shows up

SurfaceForm
DNS name<actor_name>.<atespace>.actors.resources.substrate.ate.dev
Redis actor recordactor:<atespace>:<name>
Per-actor locklock:actor:<atespace>:<name>
Control APIrequests carry an ObjectRef{atespace, name} (or an Actor whose metadata.atespace/metadata.name are set)
ListActorsoptional atespace field scopes the scan to actor:<atespace>:*

The atespace is caller-specified at creation and immutable thereafter, just like the actor name.

It is a first-class resource

Atespaces are Substrate-native records stored in Redis (not Kubernetes objects), with their own CRUD RPCs on the Control service:

flowchart LR
  subgraph API["ateapi · Control service"]
    CA["CreateAtespace"]
    GA["GetAtespace"]
    LA["ListAtespaces"]
    DA["DeleteAtespace"]
  end
  REDIS[("Redis / Valkey")]
  CA --> REDIS
  GA --> REDIS
  LA --> REDIS
  DA --> REDIS

  click API "/components/ateapi/" "ateapi"
  click REDIS "/components/storage/" "Storage"

An Atespace is global-scoped: it does not itself live inside another atespace, so its metadata.atespace is empty and its identity is just metadata.name. DeleteAtespace refuses to remove an atespace that still contains actors.

The reserved golden atespace

Per-template golden actors (the throwaway boots used to capture a golden snapshot) live in a reserved system atespace named ate-golden rather than in any tenant atespace.

Why identity is scoped this way

Scoping the name to an atespace lets two tenants each have an actor named, say, checkout without collision, and lets scheduling, locking, and routing all key off the same (atespace, name) pair. Worker assignment and the per-actor workflow lock are both scoped by this tuple, so the same actor name in two different atespaces never contends.

  • Actor - what lives inside an atespace.
  • Snapshot - snapshots are keyed under the actor, which is keyed under its atespace.
  • ateapi - serves the atespace CRUD and actor RPCs.