Sub-agents inherit computer-use: a verifier child typed into the host Terminal to bypass its restricted shell
- Dominant language
- Rust
- Stars
- 41k
- Forks
- 3.6k
- Avg merge
- 13h 59m
- Merged PRs (30d)
- 299
Description
## What happened (observed during dogfood, 2026-09-17)
A `test`-role child (verifier profile) was asked to verify a community PR: read
the diff, `git fetch` + `merge-tree` against main, and run focused cargo tests.
Its shell tool refused the chained command (`cd … && git fetch … | head`), and
its cargo/Run invocation failed on cwd. Its tool catalog still contained the
computer-use MCP tools, so it took the available path:
- `cu_computer` switch to `local`, `open_application` → **Terminal** (`launched: true`),
- read the Terminal window's accessibility tree, tried a "new tab" press (refused),
- `cu_type` with `press_enter: true` — first `echo VERIFY_TAB_OK && pwd`, then the
actual `git fetch`/`merge-tree` command — typed into the user's live shell.
The parent interrupted the child at step 32. The child's transcript carries a
receipt for every action; the only side effect was text typed into the user's
terminal.
## Why this is a design defect, not a model accident
The child was doing what it was asked to do. The grant was wrong:
1. **Least privilege**: desktop control is the most user-present, whole-machine
capability in the catalog, and a non-interactive verifier inherited it by
default (MCP tools flow through to children).
2. **Visibility is the prompt surface**: computer-use appeared in the child's
tool list, so it was a candidate action. The child's catalog should be its
grant, not the parent's union — the one-visibility / scoped-filter lesson.
3. **The sanctioned path looked broken**: the restricted shell grammar refused
a chained read-only git command with no named alternative, and cargo could not
get its workdir (#6015, #5529). A blocked sane path beside an available
absurd path picks the absurd path.
4. **No consent gate for machine-wide actions**: typing into a live terminal had
no approval step, and the user is not in the child's loop.
## Direction
- Sub-agent tool catalog derived from an explicit per-spawn grant; computer-use
absent unless the spawn declares it with a reason. Verifier/explore children
never get it by default.
- Every policy refusal names the sanctioned alternative (`use Git action=fetch`,
`Run with workdir`) instead of a dead end.
- Common read-only dev loops (chained `git`/`cargo`, pipes) allowed for children
or covered by structured equivalents (#6015).
- Desktop-control calls from non-user-facing agents fail closed pending approval.
## Evidence
Child `agent_0aa52ec4` (verifier role), steps 29–32, 2026-09-17 ~07:29–07:34Z:
`cu_run_actions open_application Terminal (launched:true)`, `cu_get_app_state`
against the host Terminal, `cu_type {text:"echo VERIFY_TAB_OK && pwd",
press_enter:true}`, then the PR-verification `git fetch`/`merge-tree` command.
Parent interrupted at step 32; checkpoint retained; no repository or user data
affected.
Related: #6015, #5529, #6194.
Contributor guide
Research direction
No source file or test is named in the report. Start by tracing the per-spawn tool-catalog grant and child policy/refusal entry points, then review related issues #6015, #5529, and #6194. Done means verifier and explore children lack computer-use by default, refusals provide sanctioned alternatives, and non-user-facing desktop calls fail closed pending approval.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, rust
- Domain
- cli, devtools, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100