Allow subagents to spawn depth-limited subagents (or: enable two-round review workflows)
Problem
Multi-step workflows that benefit from independent second-opinion passes can't be expressed cleanly today. Concretely, the pattern I keep wanting:
- Parent agent spawns an implementor subagent in an isolated worktree.
- The implementor writes code, runs tests, opens a PR.
- Before returning to the parent, the implementor spawns a fresh-context reviewer to audit the diff.
- Reviewer returns a verdict; implementor addresses blockers and returns the consolidated result to the parent.
Step 3 is blocked: per the subagents docs (line 60), subagents cannot spawn other subagents — this is a runtime invariant, not missing config.
The current workaround is for the implementor to do an inline self-review, which works but loses the entire value of the pattern: a fresh-context reviewer who hasn't been steeping in the implementation decisions for the past hour and won't rubber-stamp them.
This came up consistently while landing a ~5-PR train in one session — the /land and /spike skill patterns both want this and currently degrade to self-review.
What I'd like
Primary: lift the recursion block with a small depth cap. Concretely:
Agent({
subagent_type: "code-reviewer",
prompt: "...",
// Decremented at runtime per spawn. Spawn rejected at zero.
// Inherited from the parent's own remaining_depth.
remaining_depth: 1,
})
A root depth of 2 covers ~all the realistic patterns I've hit (parent → implementor → reviewer; or parent → spike-panel-of-3 in parallel). 3 would be generous. Unbounded is what the current design correctly rejects.
Related asks, lower priority but in the same neighbourhood:
- Caller-time tool narrowing. Today only the subagent's definition controls tools (
tools/disallowedToolsin frontmatter). I can't say "spawngeneral-purposebut strip Edit/Write for this one call." For the review pattern this matters: I want one definition (code-reviewer) that's read-only by construction, but the general primitive of narrowing-at-spawn is useful beyond reviews. Proposed: adisallowed_tools: string[]ortool_overridesparameter on theAgenttool that further restricts (never expands) the child's allowlist.
- Read-only mode for
isolation: "worktree".isolation: "worktree"exists and is exactly what I want for review-in-worktree, but it's read-write. Aworktree_mode: "ro"or similar would let the reviewer read the parent's branch state without being able to scribble on it — defence in depth on top of the tool narrowing above.
PreSubagentSpawnhook. Hooks fire onSubagentStart/SubagentStopbut not pre-spawn, so depth caps / budget caps can't be enforced as policy. A pre-spawn hook with veto power would let the depth limit live in user settings rather than the runtime.
- Token budget propagation. Each spawned subagent gets a fresh budget today; for a depth-limited tree it'd be safer to debit from a shared root budget so the whole session has a single ceiling. Less load-bearing than the others — flagging in case it's already on the roadmap.
Why this matters more than \"just use agent teams\"
Agent teams (experimental, CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1) get me to 2-level depth via teammates messaging each other — close, but:
- Teams are an experimental flag; relying on them for a stable skill pattern (
/land) is fragile. - It's not clear from the docs whether teammates can use the
Agenttool to spawn subagents. If they can, the pattern works today; if they can't, it's just a renamed version of the same block. Worth clarifying in the docs either way. - Teams require a different mental model (peer messaging) than the natural \"spawn → wait → consume result\" of subagents. For the review pattern specifically, the implementor really does want to wait for the review before returning — that's exactly what
Agent({...})already does.
A remaining_depth parameter on the existing Agent tool is a much smaller surface change than reimplementing the review pattern on top of teams.
What I don't want
- Unbounded recursion — the existing block is there for good reasons (infinite-loop prevention, context-isolation guarantees).
- Workarounds via MCP tools (\"spawn a separate claude process\") — that loses the prompt-cache, the worktree integration, and the session context.
What I built today as a bridge
A read-only code-reviewer subagent definition at ~/.claude/agents/code-reviewer.md with tools: Read, Bash, Grep, WebFetch and disallowedTools: Edit, Write, NotebookEdit. This solves the \"reviewer can't accidentally edit\" half of the problem when a parent spawns it. It doesn't help when an implementor subagent wants to spawn it — that's the runtime block this issue is asking to lift.
Acceptance, were this to land
- [ ]
Agent({ ..., remaining_depth: N })parameter, decremented per spawn, rejected at zero - [ ] Subagent that hits depth zero gets a clean error, not a hang
- [ ] Default behaviour preserved: omitting
remaining_depthmeans depth=0 (current block) - [ ] Docs updated to describe the new pattern + the failure mode
Happy to send a PR if there's interest and pointers to the relevant runtime code.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗