Skip to content

A delegated child of a scheduled task runs unconfined #2477

Closed

Description

@argszero

What happens

A session spawned by the subagent or boss tool inherits its sandbox tier by reading the parent session object (emrg/server/daemon.py, child.set_sandbox(parent.sandbox)). A scheduled task's tier is not there. It is resolved from tasks.yml into the request (emrg/server/scheduler.py, _resolve_sandbox → the task message → TaskRequest.sandbox), and the only writers of a tier onto a session are the client handler _handle_set_sandbox and those two inheritance sites.

So a task running at workspace-write — what a task gets when it declares nothing — has parent.sandbox is None: the child inherits nothing, its own tool calls carry no tier, and a call that carries no tier resolves to policy.DEFAULT_MODE, which is danger-full-access. A delegated child can write where the task that spawned it may not. The boss case is the sharper one, because the owner is the session whose answer the executor then acts on.

Measured on a clean checkout by running the same delegation twice:

  • a parent session with set_sandbox("read-only") → the child stored read-only;
  • a parent session with no tier, the turn carrying read-only → the child stored None.

The existing test for this rule sets the tier on the session before delegating, so it models a client's session and never reaches the task shape.

What the fix must satisfy

  1. The tier a child runs at is the tier the spawning turn runs under — req.sandbox, the same value the turn's own shell and write calls are injected with — falling back to the session's tier when the turn declared none.
  2. That tier reaches the tool through the daemon's argument injection, unconditionally, exactly as the parent's session and tool set already do: a tier the model can name for its own child is not a boundary.
  3. Silence keeps its meaning: when neither the turn nor the session declares a tier, the child stays unconfined.
  4. Guarded at the seam that broke. A test must drive _inject_tool_arguments and then the tool — for both subagent and boss — and must fail on the unfixed tree; a test that hands the tier straight to the runner would stay green either way.

Activity

  1. argszero commented on Oct 22, 2026

    @argszero
    OwnerAuthor

    Handled by #2478

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions