pub struct SpawnContext {Show 16 fields
pub parent_messages: Vec<Message>,
pub parent_cancel: Option<CancellationToken>,
pub parent_provider_name: Option<String>,
pub spawn_depth: u32,
pub mcp_tool_names: Vec<String>,
pub seed_trajectory_score: Option<f32>,
pub content_isolation: ContentIsolationConfig,
pub orchestrator_name: Option<String>,
pub orchestrator_role: Option<String>,
pub session_mcp_servers: Vec<McpServerConfig>,
pub max_trust_level: Option<SkillTrustLevel>,
pub inherited_tool_allowlist: Option<HashSet<String>>,
pub durable_resolver: Option<DurableResolverSeat>,
pub network_denied: bool,
pub progress_at: Option<Arc<AtomicU64>>,
pub debug_dump_sink: Option<Arc<dyn DebugDumpSink>>,
}Expand description
Parent-derived state propagated to a spawned sub-agent at spawn time.
All fields default to empty/None, preserving existing behavior when callers
pass SpawnContext::default().
§Constraint propagation
max_trust_level and
inherited_tool_allowlist implement transitive
constraint propagation: safety constraints set at orchestration time are enforced on
every sub-agent in the spawn chain, regardless of nesting depth.
When a sub-agent spawns its own sub-agents it must forward these fields downward so that grandchild agents cannot silently receive more privileges than the original orchestration policy allowed.
§Examples
use zeph_subagent::manager::SpawnContext;
// Minimal context — all fields use their defaults.
let ctx = SpawnContext::default();
assert!(ctx.parent_messages.is_empty());
assert_eq!(ctx.spawn_depth, 0);
assert!(ctx.max_trust_level.is_none());
assert!(ctx.inherited_tool_allowlist.is_none());Fields§
§parent_messages: Vec<Message>Recent parent conversation messages (last N turns).
parent_cancel: Option<CancellationToken>Parent’s cancellation token for linked cancellation (foreground spawns).
parent_provider_name: Option<String>Parent’s active provider name (for context propagation).
spawn_depth: u32Current spawn depth (0 = top-level agent).
mcp_tool_names: Vec<String>MCP tool names available in the parent’s tool executor (for diagnostics).
seed_trajectory_score: Option<f32>Seeded trajectory risk score from the parent sentinel (spec 050 §4).
When Some, the subagent’s TrajectorySentinel starts with this pre-seeded score
rather than 0.0, preventing a subagent spawn from acting as a free risk reset.
The subagent loop applies this via TrajectorySentinel::seed_score after build.
content_isolation: ContentIsolationConfigParent’s content isolation config, propagated so the subagent loop can run the same sanitizer settings on hook-replaced tool output.
orchestrator_name: Option<String>Name of the orchestrator that spawned this subagent.
When set, the subagent’s system prompt includes an identity header naming the orchestrator, so the subagent can validate that instructions are consistent with the expected authority.
orchestrator_role: Option<String>Role or task label of the orchestrating agent (e.g., "planner", "tool-router").
Injected alongside orchestrator_name when both are set.
Omitted from the identity header when only orchestrator_name is provided.
session_mcp_servers: Vec<McpServerConfig>Per-session MCP servers to inject into this subagent’s tool name annotations.
The parent is responsible for connecting these servers and including them in the
tool_executor passed to SubAgentManager::spawn. This field only carries the
server metadata so the subagent’s system prompt lists the additional tool names.
max_trust_level: Option<SkillTrustLevel>Maximum trust level cap inherited from the parent agent or orchestration policy.
When Some(cap), the spawned sub-agent’s effective trust level is clamped to
min(own_trust, cap) so that sub-agents can never receive higher privileges than
the orchestration policy originally allowed.
§Caller responsibility for nested spawns
This field does not propagate automatically. When a sub-agent itself spawns a
grandchild, it must copy this field from its own received SpawnContext into the
grandchild’s SpawnContext. Passing None (the default) at that point means the
grandchild receives no cap, which is a privilege escalation if the parent was
constrained. Only the top-level session (spawned by build_spawn_context) correctly
leaves this None — that represents an unconstrained top-level entry point.
None means no cap is imposed by the parent (the sub-agent’s own definition
determines its trust level).
inherited_tool_allowlist: Option<HashSet<String>>Tool names that this sub-agent is allowed to invoke, inherited from the parent.
When Some(set), the effective tool allowlist for the spawned agent is the
intersection of set and the agent’s own definition policy. This prevents a
sub-agent from accessing tools that the parent is itself not allowed to use.
§Caller responsibility for nested spawns
Like max_trust_level, this field does not propagate
automatically. When a constrained sub-agent spawns its own children, it must copy
this field from its received SpawnContext into the child’s SpawnContext.
Passing None at that point would grant the grandchild unrestricted tool access,
defeating the original orchestration policy.
None means no additional allowlist restriction is imposed by the parent
(the agent’s definition policy applies without narrowing).
durable_resolver: Option<DurableResolverSeat>Durable resolver seat for promise-based subagent spawn/await (spec-064 §P4, INV-9).
When Some, the spawned background task resolves the parent’s durable promise after the
agent loop terminates. The seat carries the resolver token and MUST NOT be forwarded to
the child’s tool executor or LLM surface — only the background task wrapper consumes it.
None when durable.enabled && durable.subagent is false (plain spawn/collect path).
network_denied: boolDeny network egress for this sub-agent’s bash tool calls.
Set by the orchestration layer when the spawning TaskNode carries
network_scope: NetworkScope::Deny (spec 069-threat-model OQ-1). When true,
build_filtered_executor wraps the tool executor with
NetworkDenyToolExecutor, which blocks bash
invocations of curl, wget, nc, ncat, and netcat for this spawn only —
sibling tasks and the parent agent’s own executor are unaffected.
§Caller responsibility for nested spawns
Like max_trust_level, this field does not propagate
automatically. A sub-agent that itself spawns a grandchild must copy this field
from its own received SpawnContext into the grandchild’s SpawnContext, or the
grandchild spawns with network access regardless of the original task’s scope.
false (the default) imposes no restriction beyond the executor/global
allow_network default.
progress_at: Option<Arc<AtomicU64>>Shared progress heartbeat for idle-timeout detection (issue #6245).
Set by the orchestration driver (handle_scheduler_spawn_action in zeph-core’s
scheduler_loop.rs) alongside network_denied — same
post-construction assignment pattern, not part of build_spawn_context’s base
literal. The driver creates the Arc, clones it in here, and keeps the original for
zeph_orchestration::DagScheduler::record_spawn’s last_progress_at parameter so
both the running loop and the scheduler observe the same counter.
None (the default) for spawns not tracked by a DagScheduler — e.g. the standalone
/agent run command — which are never idle-tracked.
debug_dump_sink: Option<Arc<dyn DebugDumpSink>>Cross-crate debug-dump sink, threaded down so sub-agent LLM calls are captured
through the same pipeline as the top-level agent loop’s --debug-dump output (#6391).
Set by zeph-core’s build_spawn_context from DebugState::debug_dumper. None
when debug dumps are disabled — no sub-agent dump is written in that case, mirroring
the top-level debug_dumper: None behavior.
§Caller responsibility for nested spawns
Like max_trust_level, this does not propagate
automatically — a sub-agent that spawns its own children must copy this field from
its received SpawnContext into the child’s, or grandchild LLM calls go undumped.
Trait Implementations§
Source§impl Default for SpawnContext
impl Default for SpawnContext
Source§fn default() -> SpawnContext
fn default() -> SpawnContext
Auto Trait Implementations§
impl !RefUnwindSafe for SpawnContext
impl !UnwindSafe for SpawnContext
impl Freeze for SpawnContext
impl Send for SpawnContext
impl Sync for SpawnContext
impl Unpin for SpawnContext
impl UnsafeUnpin for SpawnContext
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request