Tool and prompt-section visibility is inherited along dsh-scope's parent chain, and an agent's scope key is minted with no parent. Per-session agent presets moved every model-facing row onto the agent plane and made AgentPresets.mount() the one thing that binds that link, from the api-proxy's session create, resume, and fork paths. The two in-process subagent drivers installed only the per-child persona and tool filter, so a child's scope chain had length one and its registry view resolved the global layer alone — which is empty wherever a preset roster is composed. One-shot children reached the model with no tools, continuable ones with only the host-plane `report`, and neither carried its parent's persona, workspace context, or skill catalog. AgentPresets.composeFrom() joins one agent to the standing composition another already runs on. It is a bind, not a mount: the child gets its parent's exact generation, so a composition edited since the parent started cannot fork it onto another one, and it is synchronous, which is what lets a child creation window use it. applyChildComposition() now takes the parent and performs the join first, making a child composed without it unrepresentable at the call sites. childSessionMeta() records the joined id so a cold read rebuilds the composition the child actually ran under. The audit that followed found two api-proxy readers on the wrong authority: presenterScopeFor() and the live-agent branch of assertPresetUnchanged() both read header.agentPreset, which goes stale the moment a blank session switches preset. A switched session's cold transcript resolved presenters in the older composition's layer and silently degraded to generic cards, and the gateway refused to adopt a live session under the preset it actually runs while accepting the one it left. Both now resolve through resolveSessionPreset(), matching the resume branch fifteen lines above. The owning architecture Agent Note carried the stale claim that the header records what a session runs; it is corrected to name the header/log pair and its three readers. Fixes #2165
subagent/ — subagent capability family
English | 中文
This family lets an agent delegate work to child agents. Multiple named providers may coexist in one context.
| Package | Role | ctx key |
|---|---|---|
subagent/ |
Defines provider registration, delegation, and continuation | ctx.subagents |
subagent-inprocess/ |
Provides the shared in-process run driver | — |
subagent-spawn/ |
Starts a fresh in-process child | registers on ctx.subagents |
subagent-fork/ |
Starts an in-process child from the parent's completed history | registers on ctx.subagents |
subagent-acp/ |
Starts an out-of-process child over ACP | registers on ctx.subagents |
subagent-codex/ |
Starts a real Codex app-server child | registers on ctx.subagents |
subagent-claude-code/ |
Starts a real Claude Code child through the official Claude Agent SDK | registers on ctx.subagents |
subagent-dsh-sdk/ |
Starts an out-of-process Harness child through the TypeScript SDK | registers on ctx.subagents |
tool-subagent/ |
Exposes delegation to the model | registers on ctx.tools |
tool-subagent-control/ |
Exposes child messaging and listing to the model | registers on ctx.tools |
tool-subagent-report/ |
Provides the child-to-parent report channel | registers in child scopes |
See the decisions for the capability family, continuable children, and control tools.
The subsystem reference — start requests, results, live runs, the provider contract, continuable background children — is docs/subsystems/subagent.md; design rationale in the subagent capability seam, continuable background subagents, and merged subagent control service Agent Notes.