Skip to content

Run agent.run_command under its calling run's posture - #2081

Merged
ppXD merged 1 commit into
mainfrom
fix/run-agent-run-command-under-its-callers-posture
Oct 7, 2026
Merged

ppXD merged 1 commit into
mainfrom
fix/run-agent-run-command-under-its-callers-posture

Conversation

@ppXD

@ppXD ppXD commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • Before this change, an agent calling agent.run_command got a sandbox narrowed only by the deployment ceiling. A network-off run could ask for "network": true and get the host network, and its commands were uncapped.
    • The run's MCP endpoint now stamps AgentRunPosture (run id, tier, permissions) onto every tool call, server-side.
    • RunCommandService.BuildSpec narrows the command to it, narrow-only. The network stays only if the command asked, the deployment ceiling allows it, and the run has it. An allowlisted run's command reaches only the operator's extra hosts, and is severed when there are none. Ceilings are the run's tier row.
    • Workflow-node commands are unchanged.
  • The command's ceilings sit on a cgroup leaf of its own, beside the agent's.
    • Because the run token lets an agent open many endpoint connections, a run's commands now queue (CallerCommandLanes): one runs at a time per run, so they never hold more than one tier row between them.
    • The agent and its one running command can still hold two rows together. The SandboxSpec and RunCommandService docs say so.
  • When a run's posture takes or narrows requested network, the result carries networkNarrowed, for example off: the calling run (Standard) has no network — severed only where the sandbox confines. The agent and the approver can then see why the command could not connect.
  • Owner-visible changes:
    • agent-called commands can lose requested network
    • they run under tier cgroup ceilings (Unleashed included)
    • an agent's parallel run_command calls now wait their turn

Test plan

  • Unit:
    • caller tier × deployment-ceiling matrix
    • own-permissions and allowlist narrowing
    • host memory budget
    • bwrap argv per lane
    • cgroup plan for an agent command (capped) and a workflow node (uncapped)
    • networkNarrowed rows
    • per-run queue: same run serial, other runs and workflow nodes concurrent, cancelled waiter, cleanup
    • handler stamps run id and posture
    • node output present only on the agent path
  • Integration: a network-off agent through the real MCP dispatch gets a severed, ceilinged sandbox and networkNarrowed; two connections of one run never run commands at once while two runs do; a workflow node keeps its network through the real engine
  • Regression: full unit suite (11895 passed, 1 skipped); integration RunCommand|AgentMcpEndpoint|McpTool|AgentToolRegistry|AgentToolActor|McpNodeLifetime|ToolCallAudit|GetContextFlow|WorkflowNodeLifetime|RerunMapBranch|ToolCallLedger|AgentRunExecutorTests (382 passed, 1 skipped)
  • Mutation: removing the queue fails the overlap test; MaxMemoryMb = 0 fails the cgroup cap test

An agent that reached agent.run_command through its MCP tool fabric got
a sandbox of its own, narrowed only by the deployment ceiling. A run
whose own network was off could ask the tool for "network": true and get
the host network, and every command it ran was uncapped.

The run's MCP endpoint now stamps the run's id, autonomy tier and
permissions onto every tool call (AgentRunPosture), server-side and
never from the model's arguments. NodeAgentTool carries it onto the node
context, the node into its RunCommandRequest, and
RunCommandService.BuildSpec narrows the spec to it, narrow-only: the
network stays only when the command asked, the deployment ceiling allows
it and the run has it; an allowlisted run's command reaches only the
operator-named extra hosts, and is severed when there are none; memory
and cpu ceilings follow the run's tier clamped by the deployment ceiling
and narrowed by the host memory budget. A workflow node's command has no
calling run and keeps exactly the posture it had.

Those ceilings sit on a cgroup leaf of the command's own, beside the
agent's, so they bound the command and not the run. The run token lets
an agent open as many endpoint connections as it likes, so commands it
started at once would each hold a full tier row. A run's commands now
queue (CallerCommandLanes), so the ones it has running never hold more
than one row between them; the agent and its one running command can
together still hold two, and the docs now say so.

When the run's posture takes or narrows the network a command asked
for, the result carries networkNarrowed saying which, so the agent and
the approver are not left reading a connection error.
@ppXD
ppXD merged commit ed6512e into main Oct 7, 2026
6 checks passed
@ppXD
ppXD deleted the fix/run-agent-run-command-under-its-callers-posture branch October 7, 2026 04:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant