Appearance
Claim schema
A namespace claim is a typed Space-path mapped to a spaceId and authorityRoot. This page is the field-by-field reference for the record and the validation rules.
IHostPublicNamespaceClaim
Source: projects/matrix-3/packages/system-auth/src/host-auth.ts:71-85.
ts
interface IHostPublicNamespaceClaim {
readonly routeKey?: string; // v1 alias for spacePath
readonly publicNamespace: string; // typed name, e.g. 'space.alt.stories'
readonly canonicalRouteKey?: string;
readonly canonicalNamespace?: string;
readonly spaceId: string; // 'space_<hex>' or 'spc_<hex>'
readonly authorityRoot: string; // bus authority root
readonly canonical: boolean; // true if this is the canonical claim for the Space
readonly claimType: 'space' | 'domain' | 'system';
readonly parentNamespace?: string;
readonly verificationLevel: 'self' | 'org-admin' | 'dns' | 'platform';
readonly status: 'active' | 'reserved' | 'suspended' | 'released';
readonly createdAt: string; // ISO timestamp
updatedAt: string;
}Field meanings
| Field | Purpose |
|---|---|
routeKey | v1 alias for spacePath. New UI says "Space path"; existing storage keeps routeKey. |
publicNamespace | Typed claim. Always starts with space., domain., or system.. |
canonicalRouteKey | If multiple routeKeys map to the same Space, this is the canonical one. |
canonicalNamespace | Same idea for typed names. |
spaceId | The Space this claim points to. |
authorityRoot | The bus authority root associated. New: derived from spaceId. |
canonical | First claim per Space is canonical; later claims for the same Space are aliases. |
claimType | space for user-claimed, domain for DNS-verified, system for reserved. |
parentNamespace | If nested (e.g. space.alt.stories.ghost-stories has parent space.alt.stories). |
verificationLevel | self (just authentication), org-admin (delegated), dns (TXT verified), platform (system-managed). |
status | Active, reserved (target state), suspended, or released (target state). |
createdAt/updatedAt | Standard timestamps. |
Validation patterns
Source: host-auth.ts:1801-1854.
PUBLIC_NAMESPACE_PATTERN
regex
^(space|domain|system)\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?
(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$- Type prefix is one of
space,domain,system. - Each label is 1-63 chars, lowercase letters/digits/hyphens, must not start or end with hyphen.
ROUTE_KEY_PATTERN
regex
^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?
(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$Same shape but no type prefix. A routeKey that already matches PUBLIC_NAMESPACE_PATTERN is rejected (avoids ambiguity).
RESERVED_ROUTE_KEYS
A set of HTTP-path-reserved words rejected by normalizeRouteKey:
api, auth, login, logout, signup, setup, settings, apps, app, assets,
static, branding, nats-ws, matrix, system, admin, root, support, docs,
help, billing, status, healthz, well-known, favicon.ico,
manifest.json, hivecast, open-matrix, meThese are reserved because the HTTP gateway has paths under each.
DNS_LIKE_ROUTE_KEY_TLDS
If a multi-label routeKey ends in one of these (com, org, io, ai, app, dev, net, …), it's rejected as DNS-like:
ai, app, au, ca, co, com, de, dev, edu, fr, gov, io, jp, mil, net,
org, uk, us, xyzThe intent is to push DNS-like names through the domain.* typed path, which requires DNS verification.
Claim lifecycle
(no record) ──► [ auth.namespace.claim ]
├─► refused: invalid namespace
├─► refused: domain.* requires DNS
├─► refused: system.* reserved
├─► refused: parent not delegated
├─► refused: namespace already claimed
├─► refused: routeKey already claimed
└─► success: status: 'active'
active ──► [ Space suspended ] ──► status: 'suspended'
active ──► [ release op (target state) ] ──► status: 'released'
suspended ──► [ Space resumed ] ──► status: 'active'
released ──► [ available for new claim ]Cross-claim Space ownership
A Space (IHostSpaceRecord) can have multiple namespace claims. This happens when:
- A principal claims
space.alt.stories(creates a Space). - Later claims
space.aliases.alt-stories(sub-claim under same Space'sspaceId). - The first claim has
canonical: true; later ones don't.
canonicalRouteKey and canonicalNamespace point at the canonical public name, useful when rendering "Space path" in UI.
Sample record
json
{
"routeKey": "alt.stories.ghost-stories.funny",
"publicNamespace": "space.alt.stories.ghost-stories.funny",
"canonicalRouteKey": "alt.stories.ghost-stories.funny",
"canonicalNamespace": "space.alt.stories.ghost-stories.funny",
"spaceId": "spc_7f3a9b2c4d5e6f7a8b9c",
"authorityRoot": "space.spc-7f3a9b2c4d5e6f7a8b9c",
"canonical": true,
"claimType": "space",
"parentNamespace": "space.alt.stories.ghost-stories",
"verificationLevel": "self",
"status": "active",
"createdAt": "2026-05-04T12:00:00.000Z",
"updatedAt": "2026-05-04T12:00:00.000Z"
}See also
- Authorization / Namespace ownership — narrative.
- Identity model — how spaceId, authorityRoot, publicNamespace fit together.
- Token schema — session/bus tokens that reference
principalId.
Source:
projects/matrix-3/packages/system-auth/src/host-auth.ts(IHostPublicNamespaceClaimat lines 71-85,PUBLIC_NAMESPACE_PATTERN,ROUTE_KEY_PATTERN,RESERVED_ROUTE_KEYS,DNS_LIKE_ROUTE_KEY_TLDSat lines 1801-1854).