ADR-010: QNTX Identity System — Vanity Subjects and Attestation System Unique IDs

Date: 2026-03-06 Status: Accepted

Context

QNTX uses teranos/vanity-id (Go, v0.3.0) for all ID generation — attestation IDs, subject names, job IDs. The library is imported in 25+ files. It works, but it's a single Go module that can't run in the browser, and it conflates two fundamentally different concerns: human-readable names and unique attestation identity.

Decision

QNTX's identity system has three orthogonal layers, each with distinct properties:

LayerPurposeUniquenessMutabilityExample
Vanity IDHuman-readable subject handleSemi-unique (context disambiguates)Immutable once assignedSARAH, SBVH, ACME
ASUIDAttestation identityUnique (random suffix)Generated once per attestationAS-SARAH-AUTHOR-GITHUB-7K4M
Node DIDSigner identityGlobally unique (ed25519 keypair)Generated once per nodedid:key:z6Mk...

Node DIDs already exist (server/nodedid/). This ADR defines the first two layers and commits to implementing them in Rust.

Vanity IDs

Vanity IDs are human-readable handles for subjects only. They are names, not keys.

Vanity IDs do not apply to predicates, contexts, or actors.

ASUIDs (Attestation System Unique IDs)

ASUIDs are unique identifiers for attestations with readable SPC segments for log scanning.

Structure:

AS-SARAH-AUTHOR-GITHUB-7K4M3B9X
╰prefix╯╰─S──╯╰──P──╯╰──C──╯╰──suffix──╯

Randomness is caller-provided:

Implementation: Rust crate qntx-id

Both layers are implemented in a new Rust crate, maintained in this repository. The Go dependency on teranos/vanity-id is retired.

Design principles:

Migration order (each phase independently shippable):

  1. Core alphabet and normalization — Custom alphabet (Crockford-inspired, no 0/1), Unicode-to-ASCII, seed cleaning. Foundation for display segments in ASUIDs.
  2. ASUID generation — Prefix system (AS, JB, PX), SPC display segments, random suffix. Replaces all GenerateASID* calls (~20 call sites). This is the critical path.
  3. Random ID generation — For non-attestation uses (embedding IDs, run IDs). Replaces GenerateRandomID.
  4. WASM bridge — Expose to both wazero and browser targets as each piece lands, not as a separate phase.
  5. Vanity ID generation — Subject name derivation (name→handle). Not actively used in the codebase today — build when the feature is needed, not before.
  6. Retire teranos/vanity-id — Remove from go.mod once all callers are migrated.

Consequences

Positive

Negative

Neutral

References