> ## Documentation Index
> Fetch the complete documentation index at: https://prism.ntecdev.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# ADR-32: ADR-32

> # Title Agent identity is a UUID (`agent_id`); display name is presentation only  # Decision Introduce `agents` table with `agent_id` UUID primary key as the st

<Info>**Status:** `accepted` · **ADR-32** · Filed 2026-04-30</Info>

# Title

Agent identity is a UUID (`agent_id`); display name is presentation only

# Decision

Introduce `agents` table with `agent_id` UUID primary key as the stable, immutable referent for any agent (persona). The human-readable persona name (`display_name`) becomes a presentation attribute on that row, not the identity. All routing layer code (channels, headers, signal\_queue FKs) keys on `agent_id`. Verb arguments may accept `display_name` as user-facing convenience but resolve server-side to `agent_id` within the sender's project scope. Replace today's `controller_registrations.agent_identity` (string) and `signal_queue.from_identity`/`to_identity` (string) with FK columns `agent_id` / `from_agent_id` / `to_agent_id`. Replace `X-Prism-Identity` header with `X-Prism-Agent-Id` (the UUID).

# Rationale

The legacy "identity = display name string" approach was usable while persona names were assumed unique-per-project and never expected to change. It breaks in three concrete future scenarios:

1. **Persona rename** — agents.display\_name = "Donna" → "DonnaR" must preserve identity continuity (same agent\_id, history intact, signals in flight delivered correctly). With name-as-identity, rename is identity break.
2. **Cross-tenant collaboration** (future) — a guest member from another tenant may have a name collision with a host project's persona; the host needs to resolve "Donna who is in this project" stably regardless of display-name choices.
3. **Audit trail integrity** — every `signal_queue` row needs a stable referent for "who sent this" that survives any future renames or moves; a string snapshot of the name at send-time loses connection to the identity if the persona is renamed later.
   A UUID PK with a separate display attribute is the standard relational shape for this. The cost is one new table + FK propagation.

# Alternatives Considered

1. **Keep `agent_identity` as a string, add a separate `agent_uuid` for stability.** Considered and rejected — half-step that forces every consumer to choose which to trust. Better to do the rename once.
2. **Make display\_name the PK, with a slug/canonical form.** Variation of the legacy model; same problems with rename + collisions.
3. **Use `(user_id, project_id, display_name)` as a composite key everywhere.** Workable for routing, but every FK across the schema becomes a 3-column composite — verbose and error-prone. UUID is cleaner.

# Status

accepted

# References

* SPEC-056 §Identity model
* Memory: `feedback_document_port_misses`
