Expand description
AgentProcessRegistry — app-wide map from block_id → tracker handle.
Created once at host startup, passed into each SubprocessController
/ PersistentSubprocessController instance so it can wrap spawns
in its per-block job. Polled periodically from a background task
that emits agent:process-added / agent:process-exited events to
the frontend’s swarm activity panel.
Centralizing this here (rather than one tracker per controller) means the lifetime of the tracker matches the lifetime of the pane — multiple turns on the same block share the same job, so descendants from turn N are still visible on turn N+1.
Structs§
- Agent
Process Registry - Block
Members - One block’s tracked tree, as
AgentProcessRegistry::members_by_blockreports it. - Registry
Entry 🔒
Enums§
- Join
- How a spawn joins its block’s tracker (see
spawn_tracked).
Constants§
- SETTING_
AGENT_ BELOW_ NORMAL_ PRIORITY - Settings key: run agents’ process trees at below-normal CPU priority so their builds and tests yield to AgentMux (and the user’s foreground apps) under contention, while still using every idle core. Default on.
Statics§
- GLOBAL 🔒
- Host-wide registry, set once at startup. Exposed as a global so
SubprocessController/PersistentSubprocessControllercan reach it without threading anArcthrough every constructor + test site. Tests that don’t initialize it seeNoneand silently skip tracker registration — the job-object spawn path no-ops cleanly.
Functions§
- global
- place_
pty_ spawn place_spawnfor an agent’s PTY spawn, which has no pre-exec hook: the command is wrapped to join first (cgroup_linux::join_before_exec_pty).- place_
spawn - Make a child about to be spawned for
block_idjoin its tracker before it execs, so nothing it forks escapes between spawn andtrack_spawned(Linux: the agent’s cgroup).create: start the block’s tracker if it has none (an agent’s own CLI); otherwise join only an existing one (Shell(),!cmd, liketrack_adopted). Still calltrack_spawned*/track_adoptedafter the spawn: that records the PID and covers platforms with no pre-exec placement. - set_
global - spawn_
poller - Spawn the polling task. Drops when the registry’s
Arcrefcount hits zero (host shutdown). ~2s cadence balances latency (new processes show up fast) with CPU overhead (job queries are cheap but not free). - spawn_
target 🔒 - Where a spawn for
block_idjoins its agent’s tree, if anywhere. - spawn_
tracked - Spawn
cmdforblock_idalready inside the block’s tracker, so nothing it starts can escape between spawn and assignment: on Linux it joins the cgroup before exec (place_spawn); on Windows it starts suspended, is assigned to the job, then resumed. The one way an agent-side tokio spawn should start (the Codex App Server, which spawns internally, usesplace_spawnandtrack_spawned_agent). - track 🔒
- track_
adopted - Put a process srv spawned on an agent’s behalf (
Shell(),!cmd) into that agent’s tracker, so it dies with the agent like anything the agent started itself (SPEC_AGENT_TEARDOWN_SINGLE_PATH_2026_10_01.md §6.5). Unliketrack_spawnedit never creates a tracker (a block with no agent process has nothing to join) and doesn’t mark the PID as a root, so the process still counts as something the agent started. Best-effort, liketrack_spawned. - track_
spawned - Assign a freshly-spawned child PID to
block_id’s tracker, creating the tracker if needed. The single call site everyControllerimpl should use immediately after its own spawn — no-ops silently if the registry global isn’t initialized (tests), and with a warn log if the platform tracker rejects the PID, since this is opportunistic enrichment, not a liveness signal on its own (seebroker::process::ProcessStatus’s own doc comment). - track_
spawned_ agent track_spawnedfor an agent process: also applies the agent CPU priority policy to the block’s whole tree. Terminal panes a human types in keep callingtrack_spawnedand are never deprioritized.