Expand description
The one place a human-readable agent slug becomes a canonical
db_agents.id.
Why this exists. AGENTMUX_AGENT_ID is a model-and-human-chosen slug,
not a key: db_agents.slug carries no UNIQUE constraint, deliberately
(storage::migrations declines the index because template launches copy
their template’s slug). Treating it as a primary key has produced the same
defect four times — Codex P1 on #2901, reagentx on #2428, reagentx on
#3480, and instance_get_by_slug itself on #3500 — each found and fixed
separately because the resolution logic existed in three places that drifted
apart.
Phase 0 of SPEC_CANONICAL_AGENT_ID_MIGRATION_2026_09_21.md. Later phases
call this instead of inventing a fourth resolver.
Resolve once, at the trust boundary. Callers pass the slug they already have — MCP arguments, audit-log display and agent-facing docs keep the readable name. Everything downstream of this function uses the id.
Statics§
- UID_
FALLBACK_ 🔒COUNTS - Process-wide fallback counters, keyed by call site (spec §9.2). In-memory only, same lifecycle as the reactive handler’s audit log; a phase’s exit criterion is read from these, not assumed.
Functions§
- record_
uid_ 🔒fallback - Bump the counter for
site(spec §9.2). Shared by the resolver’s dual-write misses and, since identity M2, the registry’s own registration/delivery/lookup counters — one snapshot for all of them. - resolve_
agent_ 🔒id - Resolve
slug_or_idto a canonicaldb_agents.id. - uid_
fallback_ 🔒counts - Snapshot of every fallback counter, for the exit-criterion check (spec §9.2). Sorted by site so output is stable.
- uid_
for_ 🔒block - The agent UID (
db_agents.id) for the agent shown onblock_id, if it has a row — the same block → row resolutionbuild_persistent_spawn_envuses, without minting a token. For the frontend presence path (handle_reactive_register), which does not trust the name it is sent (spec §0.1) and resolves identity by block instead. A synchronous store read: call it onspawn_blockingfrom async handlers.