fix(subagent): inherit parent policy overrides in continuable children
A continuable background child (the default backgroundMode for both delegation tools) never received the parent session's explicit sandbox/approval overrides: materialization applied only child composition, so a danger-full-access parent produced workspace-write children whose every out-of-workspace operation raised an approval prompt. Move the one-shot driver's capture/append pair into the shared child-agent module (captureDelegatedPolicyOverrides / appendDelegatedPolicyOverrides) and call it from both paths: startContinuable captures before its first await, only fresh materialization appends the source-tagged events (after any fork seed), and a cold resume replays the persisted delegation events instead of re-capturing the parent. Adds the continuable inheritance unit suite, the ACP snapshot scenario subagent-continuable-inheritance (fails without the fix), the continuable policy-inheritance Agent Note, and the seam-level README contract, with bilingual counterparts. Fixes #1692
This commit is contained in:
@@ -52,6 +52,10 @@ The seam owns the depth vocabulary shared by Service providers and Consumers: th
|
||||
|
||||
`inheritsParentContext` is descriptive rather than enforceable. It says only whether the child sees completed parent conversation history (`fork` does; `spawn` and the out-of-process one-shot providers do not), not whether it inherits tools, services, or authority.
|
||||
|
||||
## Delegated policy inheritance
|
||||
|
||||
Both in-process delegation paths seed the parent's explicit policy overrides into the child through the shared child-agent helpers: `captureDelegatedPolicyOverrides(parent)` snapshots `sandboxPolicy.overrideOf()` and `approval.overrideOf()` synchronously at the delegation boundary (both services are optional `ctx.get` consumers), and `appendDelegatedPolicyOverrides()` writes each captured value onto the child's own log as a `source: 'delegation'` `sandbox/mode` or `approval/policy` event during unpublished setup, after any fork seed — so fresh policy wins stale seed state, a later child switch wins the snapshot, and the child's effective policy stays reconstructable from its log alone. Deployment defaults are never copied: an unswitched parent stamps nothing and its child follows the deployment default dynamically. A continuable start captures before its first await and seeds only fresh materialization; a cold resume replays the persisted delegation events instead of re-capturing the parent, so a parent switch after creation never retroactively changes a durable child. See the [one-shot](../../../.agents/notes/implemented/feature/2026-07-25-subagent-policy-inheritance.md) and [continuable](../../../.agents/notes/implemented/feature/2026-08-10-continuable-subagent-policy-inheritance.md) policy-inheritance Agent Notes.
|
||||
|
||||
## One-shot ownership and lifecycle
|
||||
|
||||
`provider.start(request): Promise<SubagentRun>` is the ownership-transfer boundary; the delegation tool also uses it inside its one-shot Task-backed background path. Before fulfillment, the provider owns setup and must cancel, roll back, and quiesce unpublished resources on every failure. After fulfillment, the caller owns the run and must call `dispose()` on every path; remaining prompt and turn work belongs to `SubagentRun.result`.
|
||||
|
||||
Reference in New Issue
Block a user