Expand description
Process containment for agent-tool calls and SDK sessions (Unix).
Two rules hold for every signal sent from this module:
- A process group is signalled by its number only while that number is pinned by an unreaped child of the signalling process that belongs to the group (POSIX: a process id is not reused while a process group with that id exists, and a group exists until its last member — a zombie included — is gone).
- The signalling process has verified that it is not a member of the group. If that cannot be shown, nothing is signalled.
The parts:
CallGuard: one guard process per agent-tool call. It joins the call’s group, leaves a pin behind, moves to a group of its own and waits for its input to end — the call finished, or the Engine is gone. Then it ends the call’s group, repeatedly, until no live member is left.- the session starter (
starter): the process an SDK starts. It runs the Engine in a new group, stays outside, and ends that group when the Engine exits, when it is asked to, or when its parent is gone. A guard of the first kind covers the starter’s own death, and the Engine’s program is not executed before that guard is ready (gate). - the spawn helper (
spawn_helper,spawner): the MCP shell (server/execute.rs) leads a session of its own (setsid), and a guard started outside that session cannot join its group. One long-lived helper per Engine process is the parent of those shells instead; it ends what it still holds when the Engine is gone without a word.
Windows is not covered here; nothing in this module is built there. Its
containment is in shell::process_tree: a kill-on-close Job Object per
MCP shell call, and for an SDK session the Engine’s own kill-on-close job
(contain_requested_session), which answers the same request variable
with the same acknowledgement.
Structs§
- Call
Guard - The owner’s handle on a guard: the guard ends its group when this handle
goes away — by
CallGuard::finish, by a drop, or by the owner’s death. - Helped
Child - A shell whose parent is the spawn helper. What the Engine does with a child process, it does with this through the helper: learn its exit, end its group, let go of it.
Enums§
- Guard
Outcome - What a guard reported when its owner let go of it.
- Helper
Spawn - What became of the request to start a shell through the helper.
- Refusal
- Why nothing was started.
Constants§
- END_
NOTICE - What a caller is told when a call’s process group could not be confirmed as ended. Fixed text: no process id, no time, nothing of the run (#498).
- HELPER_
NOTICE - What a caller is told when an MCP shell command ran without the spawn helper: nothing would have ended it had lean-ctx died meanwhile. Fixed text, as above.
- RELEASE_
NOTICE - What a caller is told when a command finished and the word that lets what it left running go on could not be handed to the spawn helper: a helper that never read it ends those processes. Fixed text, as above.
- UNCLEAR_
NOTICE - What a caller is told when the spawn helper went away without saying whether it had started the command. Nothing seen afterwards can prove that a command did not run, so it is never started a second time. Fixed text, as above.
Functions§
- dispatch_
hidden_ mode - Runs the hidden mode this invocation asks for, if any, and returns its exit code. Called before any other start-up work: no configuration, no data directory, no logging, no telemetry.
- end_
notice - The notice for a guard outcome;
Nonewhen the group is known to be empty. - live_
members - How many live (not zombie) processes are members of
group, read from the process table.Nonewhen it cannot be read. Sends no signal. - shutdown_
spawn_ helper - The Engine ends in order: the helper exits and ends nothing. Without this message the helper takes the closed socket for the Engine’s death.
- spawn_
shell - Starts the shell described by
command— program, arguments, environment and working directory; its input is null and its outputs are the returned pipes — as a child of this process’s spawn helper. - start_
behind_ guard - Starts
command— which must ask for a process group of its own — with a guard on that group. The program is executed only after the guard is ready; on every refusal it was never executed, so there is nothing to end.