Standardize Object IDs to URI Form
Context and Problem Statement
The Vultron ActivityStreams 2.0 (AS2) object model requires every object to
have an id field. The generate_new_id() utility in
vultron/wire/as2/vocab/base/utils.py currently returns a bare UUID-4 string
(e.g., 2196cbb2-fb6f-407c-b473-1ed8ae806578) as the default as_id for
new objects. The AS2 specification and the Vultron object-IDs spec
(specs/object-ids.yaml OID-01-001) require that id values be full URI
identifiers. Bare UUIDs are not valid AS2 identifiers and will cause
interoperability problems once federation is implemented.
Decision Drivers
- AS2 compliance: ActivityStreams 2.0 requires
idto be an absolute IRI. Bare UUIDs are not IRIs. - Federation readiness: Federated delivery requires globally unique, resolvable identifiers. Bare UUIDs cannot be resolved across systems.
- Blackboard key safety: py_trees blackboard keys derived from full-URI IDs must not use the raw URI (which contains slashes). Using the last path segment or UUID suffix as the key avoids hierarchical key-parsing issues (OID-03-001).
- DataLayer compatibility: The DataLayer uses
as_idas the primary lookup key. Changing the default ID format is a migration applied going forward; any existing bare-UUID records are a prototype artifact.
Considered Options
urn:uuid:prefix —urn:uuid:{uuid4}(e.g.,urn:uuid:2196cbb2-fb6f-407c-b473-1ed8ae806578)- Configurable HTTPS base URL —
https://{base}/{type}/{uuid4}driven by aVULTRON_BASE_URLenvironment variable - Continue using bare UUIDs — defer the change
Decision Outcome
Chosen option: Configurable HTTPS base URL with urn:uuid: fallback,
because:
- HTTPS URLs are the canonical AS2
idform and are directly resolvable. - A configurable base URL (via
VULTRON_BASE_URLenv var) allows deployment flexibility without hard-coding a hostname. - When
VULTRON_BASE_URLis not set, the helper defaults tourn:uuid:form, which is a valid absolute IRI and avoids any need for a running HTTP server during development and testing. - The
make_id()helper invultron/api/v2/data/utils.py(which already uses HTTPS base-URL form) becomes the shared canonical ID factory for all layers, satisfying OID-01-004.
Consequences
- Good: all newly created objects carry globally unique, AS2-compliant
idvalues. - Good:
VULTRON_BASE_URLenables environment-specific ID namespaces (dev / staging / production) without code changes. - Good:
urn:uuid:default keeps development and test setups self-contained. - Neutral: existing bare-UUID records in prototype data stores remain usable during the prototype phase; a migration script is not required until production deployment (OID-04-002, PROTO-01-001).
- Bad:
generate_new_id()now produces IDs that contain colons, which must not be used directly as py_trees blackboard keys (use the UUID suffix portion only — see OID-03-001).
Validation
- Unit tests in
test/wire/as2/vocab/base/test_utils.pyassert thatgenerate_new_id()returns a value starting withurn:uuid:or a configured HTTPS prefix. - Unit tests in
test/api/v2/data/test_utils.pyconfirm thatmake_id()produces HTTPS-prefixed IDs and thatBASE_URLis read fromVULTRON_BASE_URLwhen set. - Code review: no new code should assign a bare UUID directly to
as_idwithout wrapping it in a URI prefix.
Pros and Cons of the Options
urn:uuid: prefix
- Good: simple — no environment configuration required.
- Good: valid absolute IRI; accepted by AS2 parsers.
- Good: no slashes in the ID, so the full ID can be used as a path segment without percent-encoding.
- Neutral: not directly HTTP-resolvable.
- Bad: does not support the future federation model where IDs are resolvable URLs on actor servers.
Configurable HTTPS base URL
- Good: IDs are HTTP-resolvable, matching the ActivityPub federation model.
- Good: per-environment namespacing via
VULTRON_BASE_URL. - Bad: IDs contain slashes; API routes must URL-encode or use query parameters for ID-based lookups.
- Bad: requires a configured hostname to produce meaningful IDs.
Continue using bare UUIDs
- Good: no code changes required.
- Bad: violates AS2 spec; blocks federation.
- Bad: violates
specs/object-ids.yamlOID-01-001.
More Information
specs/object-ids.yaml— normative requirements OID-01 through OID-04.notes/codebase-structure.md— "Technical Debt: Object IDs Should Be URL-Like, Not Bare UUIDs" section.plan/IMPLEMENTATION_PLAN.md— TECHDEBT-3.- Related ADRs:
- ADR-0005 — rationale for using AS2 as the wire format.
- ADR-0009 — hexagonal architecture that separates wire format concerns from domain logic.