Safe Spawn
How agent-initiated child sessions are bounded by lineage, TTL, caps, workspace inheritance, and permission narrowing.
compozy spawn lets a managed session ask the daemon to create a child agent session. Spawn is the
delegation surface for the autonomy MVP, but it is safe by default: the daemon owns lineage, TTL,
caps, workspace inheritance, permission narrowing, and cleanup.
Parent lineage is also used as informational creation provenance for some daemon-managed system sessions, including Loop Goals. Those sessions can appear beneath their origin in session views, but they do not inherit the origin's TTL, parent-stop behavior, permission policy, or spawn budget. Spawned children remain governed by their own lineage. Coordinator roots retain their daemon-owned TTL, caps, and permission policy.
Required constraints
| Constraint | Behavior |
|---|---|
| Valid parent identity | The caller must be a CompozyOS-managed session resolved from daemon-issued identity. |
| TTL | --ttl-seconds is required and must be positive. Spawned sessions cannot be unbounded. |
| Depth cap | The MVP default max spawn depth is 1. |
| Child cap | The MVP default max children per parent is 5. |
| Workspace target | Children inherit the parent workspace. --workspace may target another workspace when the policy allows. |
| Coordinator role denial | --role coordinator is rejected. Coordinators are daemon-managed root sessions, not child sessions. |
| Permission subset | Child tools, skills, MCP servers, workspace paths, network channels, and sandbox profiles must be a subset of the parent set. |
| Unknown atoms | Unknown child permission atoms count as widening and reject the spawn. |
| Parent stop | Children auto-stop when the parent stops unless configured otherwise within hard caps. |
The daemon rejects invalid spawn requests. It does not silently narrow a child request and continue.
Spawning a worker
compozy spawn --agent reviewer --ttl-seconds 1800Add narrowed permissions and a role when the parent has those atoms:
compozy spawn \
--agent reviewer \
--role reviewer \
--ttl-seconds 1800 \
--prompt-overlay "Review only the implementation diff." \
--tool read \
--skill code-review \
--channel coord-run-123Permission flags are repeatable:
--tool--skill--mcp-server--workspace-path--channel--sandbox-profile
--channel narrows the channel permission atoms a child may use. It does not select Live
participation, create Network state, or make the child inherit its parent's participation. A spawned
execution remains Local unless it submits a separate, authorized Network participation request.
--workspace-path narrows the workspace-path permission atoms a child may use. It is a permission
grant checked against the parent set, not a placement flag — it does not choose which workspace the
child runs in. Use --workspace for that.
The response includes the child session, lineage, and safe permission projection. It does not create or claim task work by itself.
Wake the creator
CompozyOS queues a sanitized synthetic turn on the parent when a child stops, fails, or enters a
needs-you state. This notify_creator behavior defaults to on and never interrupts an active parent
prompt. It is suppressed when the parent is no longer live or the delivery would wake the same
session.
Opt out for one child when the parent already has another coordination channel:
compozy spawn \
--agent reviewer \
--ttl-seconds 1800 \
--no-notify-creatorHTTP, UDS, and compozy__session_spawn use the presence-aware notify_creator boolean: omission
keeps the default, while explicit false opts out. There is no config.toml key for this default.
Cross-workspace spawn
--workspace overrides the workspace the child runs in. It takes a workspace id, a workspace name,
or an absolute path to a registered workspace root; a path inside a registered root resolves to that
workspace. Omit the flag and the child inherits the parent workspace.
compozy spawn --agent reviewer --ttl-seconds 1800 --workspace ws_4f2c9a1b7d3e5086
compozy spawn --agent reviewer --ttl-seconds 1800 --workspace billing-api
compozy spawn --agent reviewer --ttl-seconds 1800 --workspace /Users/dev/code/billing-apiThe daemon resolves the reference to a canonical workspace id before anything else. A reference that
does not resolve to a registered workspace is denied — spawn never registers a new workspace. When
the resolved target equals the parent workspace, nothing changes. When it differs, the request goes
through the workspace-access policy on the spawn seam, and the parent session's effective
permission mode decides:
| Parent permission mode | Cross-workspace spawn |
|---|---|
approve-all | Allowed. |
approve-reads | Denied, unless the session already recorded a cross-workspace allow answer. |
deny-all | Denied. |
The spawn seam never prompts. A denial the policy marks prompt-eligible is still returned as an
error here — no approval request reaches the operator. The consent an approve-reads session can
reuse is captured elsewhere: the tool seam does prompt, and an allow answer there is cached for the
rest of that session's lifetime. Absent such an answer — or with a recorded reject answer —
approve-reads denies. deny-all denies regardless of any recorded answer.
The daemon rejects a denied request with 403 Forbidden and a message naming the target workspace,
the parent workspace, and the operator fix — set the agent's permissions.mode to approve-all, or
approve the prompt when one is asked.
Workspace access is re-checked after spawn.pre_create hook patches. Hooks cannot move a child into
a workspace the policy denies.
What crossing does and does not change:
- The child's home is the target workspace. Its agent process starts with that workspace's root
as
cwdand that workspace's additional roots, not the parent's. - Permissions do not widen. Child tools, skills, MCP servers, workspace paths, network channels, and sandbox profiles are still subset-checked against the parent, in the target workspace as in the parent's.
- Every decision is audited. Allow and deny both append a
workspace.access_grantedorworkspace.access_deniedevent carrying thespawnseam, the decision source, and the effective permission mode.
Cleanup and active leases
The reaper wins over active leases. If TTL expiry or parent-stop cleanup terminates a spawned session, CompozyOS first releases active task-run leases owned by that session with a structured reason, then stops the child. Stale child claim tokens cannot complete or heartbeat recovered work.
Hooks
Spawn exposes these hook events:
spawn.pre_createspawn.createdspawn.parent_stoppedspawn.ttl_expiredspawn.reaped
spawn.pre_create may deny or narrow a request, but hook patches cannot widen child permissions.
The daemon enforces the permission subset after hook patches.
Related pages
- Agent Spawning explains normal session launch behavior.
- Session Lifecycle explains the
spawnedsession type. - Session Orchestration covers wait, interaction resolution, prompt cancel, and native tools.
- Task Runs and Leases explains child lease release.
- Spawn CLI Reference lists exact flags.
Task-Run Coordination Conversations
How future coordinated task runs opt into bounded Live conversations without moving task ownership into Network.
Overview
How CompozyOS stores durable Markdown memory across global, workspace, and agent scopes, gates dreaming runs, and routes every write through the controller.