Skip to main content

Module agent_admission

Module agent_admission 

Source
Expand description

One live instance per agent — the host tier (docs/specs/SPEC_AGENT_SINGLE_LIVE_INSTANCE_2026_09_24.md, Phase 1).

An agent identity (its UID) may be driven by at most one process on this host. Two layers:

  • acquire — the binding decision. A persistent pane claims the agent’s LeaseStore lease right before its CLI process is spawned and holds it for that process’s lifetime (HeldAgentLease): renewed on its own task, released on drop, and fenced — a holder that loses the lease (suspended past the TTL and reclaimed) is told through on_lost so it stops driving, and HeldAgentLease::verify lets it refuse a turn before starting one.
  • check_before_spawn — the early, read-only check the async spawn paths run before they write anything shared on the agent’s behalf (spec I9: in the 2026-09-25 incident the second instance broke the first by rebinding its account, before any spawn). It reads the lease and, for instances too old to take one, asks every other live AgentMux instance on this host whether it is running this UID.

Structs§

HeldAgentLease
A lease held for the lifetime of one CLI process. Dropping it stops the renewal task and releases the lease.
HolderEndpoint
Where the instance currently running an agent can be reached.
LegacyHolder
A live instance on this host that is running the same agent UID but took no lease (it predates Phase 1) — found by asking it.
LostReason 🔒
The first loss message, kept for every later refusal.
PeerHolding
A LAN peer’s answer to GET /agentmux/agent/holding?uid=….
RecordFence
The writer-side fence on the agent’s shared record (spec §4.3, Phase 3).

Constants§

HANDOVER_HOLD
How long, after this srv hands an agent over to another instance, it refuses to claim that agent again on its own. Covers the gap between the holder’s process exiting and the requester claiming, in which a jekt delivered here would otherwise respawn the agent and win it straight back. A takeover the user starts from this srv clears it.
LAN_QUERY_TIMEOUT 🔒
How long one LAN peer gets to answer.
LAN_RECHECK_TICKS 🔒
Renewals between LAN re-checks: 6 × RENEW_INTERVAL_MS = 30 s.
LAN_SKEW_BUDGET_MS
Start times closer than this are “simultaneous”: clocks on two hosts are not compared finer than this; the hostname decides instead (§4.4).
REFUSAL_MARKERS
Wording every single-live-instance refusal contains (lower-cased), so the failure classifier and callers can recognise one without a type.
RELEASE_REQUEST_TIMEOUT 🔒
How long a release request may take to be answered (see request_release).

Statics§

HANDOVER_HOLDS 🔒
One entry per agent this srv handed over: until when, and to whom (for the refusal text). A single map, so an expired hold goes away whole (ReAgent P2 on #3742).
HELD_BY_NAME 🔒
The held leases of this process by agent name (lower-cased) — the key the muxbus relay and its pending queue use — so the WAN side can fence the local holder when the relay says another instance holds the agent.
LAN_DISCOVERY 🔒
PROBE_CLIENT 🔒

Functions§

acquire
Claim uid for this process’s block_id, and keep it renewed until the returned handle is dropped. on_lost runs (once, off the caller’s thread) if the lease is found to belong to someone else — the holder must then stop driving the agent.
check_before_spawn
The early, read-only admission check (see module doc). Err is the user-facing refusal; callers must run it before any shared write.
claimant_info
What this instance records about itself in a lease it takes.
clear_handover_hold
Drop any handover hold on uid — the user is taking it back.
denied_message
The refusal a user sees when agent is already running elsewhere.
endpoint_for_channel
The running instance on this computer in channel, from the host-global shared registry — how Take over reaches a holder it knows by channel (from the local lease file, or from the relay’s holder record).
fence_agent_named
The relay says another instance holds agent_name (WAN tier): fence this process’s holder of that agent, if any — record the loss (the pre-turn fence refuses its next turn) and stop its CLI process. true when a local holder was fenced.
fenced_zone
zone unless fence says this process may no longer write the agent’s shared record.
find_uid_block 🔒
The block of the first registration in regs carrying uid.
handover_hold_refusal 🔒
Some(refusal) while uid is inside a handover hold on this srv. An expired hold is removed here.
hold_after_handover
Record that this srv just handed uid over (see HANDOVER_HOLD).
is_admission_refusal
Is message a single-live-instance refusal (any of this module’s user-facing refusal texts)?
is_this_host 🔒
lan_denied_message
The refusal when a LAN peer runs the agent. Carries the same marker as the host refusal, so it classifies as LiveElsewhere.
lan_holders
Every reachable LAN peer on another host that says it holds uid. Unreachable or older peers (no route) are skipped: not evidence either way (D2, fail open). Answers from this host are dropped: another AgentMux instance here also shows up as a LAN peer, but it reads this host’s own lease store, so it would report this process’s own lease back — the host tier already governs this host.
lan_lost_message 🔒
lan_place 🔒
lease_store_for
The lease store under a shared agent registry root, None if there is no registry or its lease directory can’t be opened (logged).
local_holding
What this host answers to a LAN peer asking about uid: held when any instance on this host holds a live lease for it.
locate_holder
Find the other instance on this host that runs uid: the lease holder (its channel’s live srv, from the shared registry) or — for an instance that takes no lease — the compat probe’s hit. None when nobody else runs it, or the holder’s srv can’t be found.
lost_message 🔒
peer_wins
The LAN tie-break (§4.4): does a peer that started the agent at peer_at on peer_host win over this host’s claim at mine_at? The earlier start wins; starts within the skew budget are simultaneous and the lower hostname wins. Deterministic and symmetric: exactly one side wins for any pair of distinct hosts.
probe_other_instances
Ask every other live AgentMux instance on this host (from the host-global cross-channel registry) whether it has uid registered. Matched by UID, never by name (display names are not unique — Codex P2 on #3730). An instance too old to report UIDs, or one that doesn’t answer, is not evidence either way and is skipped (logged).
register_by_name 🔒
registered_uid_blocks 🔒
GET <local_url>/agentmux/reactive/agents and return the block of the first registration whose uid equals uid.
request_release
Ask the holder’s srv to stop running uid so this instance can take it (POST /agentmux/agent/release). Err is user-facing.
set_lan_discovery
Called once at bootstrap: gives admission the LAN peer list. Without it (tests, LAN discovery off) the LAN tier is skipped.
spawn_renewal 🔒
this_host_label 🔒
This host’s label, as a LAN peer reports it and as the tie-break compares.
unregister_by_name 🔒
wait_until_free
Wait until no other instance holds uid (lease and compat probe both clear), polling. Err after timeout.
wan_denied_message
The refusal when the relay says another instance runs the agent. Carries the host refusal’s marker, so it classifies as LiveElsewhere.
wan_lost_message 🔒
wan_place 🔒
Where the relay says the holder is: “on another computer (computer X, …)”, or “on this computer (channel Y, vZ)” for another instance on this host (charlie, 2026-09-26: a same-host holder was called “another computer”).

Type Aliases§

LostCallback 🔒