A Space answers where does this thing live and who owns it. Every typed object is anchored to exactly one, addressed by a SpaceRef — a xema:// URI whose segments are <plural-kind>/<id>: xema://system, xema://orgs/acme/projects/billing, xema://biomes/<biomeId>, xema://users/<userId>.

SpaceKind is closed and has seven members: system, org, project, app, session, biome, user. There is no second ownership enum anywhere in the platform. A registry that legitimately owns fewer tiers — credentials own four, execution targets own two — declares an admissible subset (spaceKindSubset) over this one enum and fails fast on anything outside it. That keeps the address universal, which is what makes re-scoping expressible at all: with a private enum per registry there is no address a "publish this to my organization" request could name.

Two facts are deliberately separate. The tree (system at the root, org → project → app nesting, and user, session, biome as sibling roots) answers what contains what. It cannot rank a biome-owned row against an org-owned one, because those two share only the root. So the merge order — which of two rows at one slug wins — is its own declared rank map — SPACE_KIND_RANK, app most specific through system least — and never derived from the ancestor walk. Where the tree speaks the two agree; where it is silent the ladder supplies.

A Space row is a declaration, not a materialised node: a row exists only where something was declared about that Space, nothing stores a parent pointer, and ancestry is derived from the URI with no I/O. space-registry-api owns them. Each Space also carries a DataClassification floor that joins down the chain — absent is the identity, the more restrictive side wins, and a descendant may only ever raise it.

Moving a row to a broader owner is the one first-class ownership operation. isLegalSpacePromotion permits user → project, user → org and project → org, and refuses everything else — demotion, because narrowing an owner silently orphans every broader consumer that already references the row, and same-tier, because answering "done" would report a publish that never happened. See the Spaces page for the URI grammar, the classification set and the re-scope routes.