Expand description
Which spawned agent processes carry an identity token — identity M4a
(docs/specs/SPEC_AGENT_IDENTITY_CARRIED_NOT_DERIVED_2026_09_23.md
§6.5.6).
Two measurements, because request-side counters cannot gate anything: an unattributed request from the UI and one from a tokenless agent look the same (§6.5.1).
spawn.no_token.<path>counts process spawns, per controller, of an agent that has a row (a UID) but got noAGENTMUX_AGENT_TOKEN— the gap M4b closes, gated on these reaching zero. “Has a row” is decided by the store, not by the environment: the gap paths (agent.send, App Server) are exactly the ones whose environment carries noAGENTMUX_AGENT_UIDalthough their block has a row (adversarial review of #3571).spawn.no_row.<path>counts spawns with no row at all (quick-launch panes, template-based continuations before M4b binds them), kept apart so the gate can be met. Recorded where a process is actually started, never where an environment is merely built: a turn delivered to a running process rebuilds the environment without spawning anything (review on #3571).live.tokenless_or_unknowncounts live registered agents (with a row, so they should carry a token) whose process is not known to carry one — including a process spawned before this srv started, which never passes a spawn site again. M4d and M5 wait for this to drain to zero, not for a counter that merely stops moving.
Enums§
- Spawn
Path 🔒 - The controller a process was spawned by — the
<path>in the counters.
Statics§
- CARRIED_
BY_ 🔒BLOCK - ROW_
STORE 🔒 - This channel’s object store, for deciding whether a spawned block has a
row. Attached once at boot (
bootstrap/stores.rs), beside the token index, sorecord_process_spawn’s callers need not pass a store.
Functions§
- attach_
row_ 🔒store - block_
has_ 🔒row - Whether
block_idshows an agent that has a row — the same block → row resolutionbuild_persistent_spawn_envuses, which also finds the row a template-based continuation folded into. A synchronous store read; spawn paths call it only when the environment carries no UID. - carried_
by_ 🔒block - carried_
token 🔒 - Whether the process this srv last spawned on
block_idcarried a token;Noneif this srv has not spawned one there. - forget_
block 🔒 - Drop
block_id’s record when its processes are released (blockcontroller::release_block_processes), so the map is bounded by open blocks, not by every block ever opened. - live_
gauges 🔒 - The two live gauges over
registrations:(tokenless_or_unknown, unidentified). An agent with a row whose process is not known to carry a token counts toward the first; an agent with no row (a quick-launch pane — outside the identity system, §6.5.6) toward the second. A registration without a UID is not taken as row-less on its word: a block driven only throughagent.sendregisters without one although it has a row, sohas_rowasks the store.is_livefilters out registrations whose block no longer runs anything here, so a stale registration cannot hold the gauge up. - record_
process_ 🔒spawn - Record a process spawn on
block_idfrom the environment it was actually given. Call at the point the process is started. - record_
process_ 🔒spawn_ with - record_
spawn 🔒 - Record that this srv spawned a process on
block_id, and whether it carried a token.no_token_sitenames the launch path’s counter;Nonefor a path that is not an agent launch by itself (a terminal pane, where an agent CLI is only one possibility — the live gauge covers that case). - store_
block_ 🔒has_ row block_has_rowagainst a given store. A store fault answers “has a row” (counted): a gate must never read clear because a read failed.