Bug
When agent A spawns a cross-agent sub-agent targeting agent B (via sessions_spawn(agentId: "B")), the sub-agent runs under the correct session namespace (agent:B:subagent:<uuid>) but inherits agent A's workspace and persona files instead of agent B's.
Root Cause
Two code paths interact:
1. resolveSpawnedWorkspaceInheritance uses the requester's session key
src/agents/spawned-context.ts:59-74 extracts the agent ID from requesterSessionKey (the caller), not the target agent. For cross-agent spawns this resolves the wrong workspace.
2. Caller's ctx.workspaceDir is passed as explicitWorkspaceDir
src/agents/subagent-spawn.ts:540-554 passes toolSpawnMetadata.workspaceDir (derived from ctx.workspaceDir, the caller's workspace) as explicitWorkspaceDir. This short-circuits the resolution function via its if (explicit) return explicit path before the target agent ID is ever considered.
3. Spawned metadata overrides session-key-based fallback
src/commands/agent.ts:549-551 uses normalizedSpawned.workspaceDir ?? resolveAgentWorkspaceDir(cfg, sessionAgentId). Since spawned metadata always carries the (wrong) workspace, the correct fallback never fires.
Reproduction
- Configure two agents (
pm and ops) with distinct workspaces and identity files
- Add
subagents.allowAgents: ["ops"] to PM's agent config
- From PM, spawn:
sessions_spawn(agentId: "ops", task: "Read IDENTITY.md from your workspace")
- The sub-agent reads PM's
IDENTITY.md instead of Ops'
Expected
Sub-agent should use target agent's workspace (workspace-ops) and persona files.
Actual
Sub-agent uses caller's workspace (workspace-pm) and persona files.
Related
Files Involved
| File |
Lines |
Role |
src/agents/subagent-spawn.ts |
549-553 |
Calls resolveSpawnedWorkspaceInheritance with requester's context |
src/agents/spawned-context.ts |
59-74 |
Extracts agent ID from requester's session key |
src/commands/agent.ts |
549-551 |
Uses spawned metadata workspace with ?? fallback |
Bug
When agent A spawns a cross-agent sub-agent targeting agent B (via
sessions_spawn(agentId: "B")), the sub-agent runs under the correct session namespace (agent:B:subagent:<uuid>) but inherits agent A's workspace and persona files instead of agent B's.Root Cause
Two code paths interact:
1.
resolveSpawnedWorkspaceInheritanceuses the requester's session keysrc/agents/spawned-context.ts:59-74extracts the agent ID fromrequesterSessionKey(the caller), not the target agent. For cross-agent spawns this resolves the wrong workspace.2. Caller's
ctx.workspaceDiris passed asexplicitWorkspaceDirsrc/agents/subagent-spawn.ts:540-554passestoolSpawnMetadata.workspaceDir(derived fromctx.workspaceDir, the caller's workspace) asexplicitWorkspaceDir. This short-circuits the resolution function via itsif (explicit) return explicitpath before the target agent ID is ever considered.3. Spawned metadata overrides session-key-based fallback
src/commands/agent.ts:549-551usesnormalizedSpawned.workspaceDir ?? resolveAgentWorkspaceDir(cfg, sessionAgentId). Since spawned metadata always carries the (wrong) workspace, the correct fallback never fires.Reproduction
pmandops) with distinct workspaces and identity filessubagents.allowAgents: ["ops"]to PM's agent configsessions_spawn(agentId: "ops", task: "Read IDENTITY.md from your workspace")IDENTITY.mdinstead of Ops'Expected
Sub-agent should use target agent's workspace (
workspace-ops) and persona files.Actual
Sub-agent uses caller's workspace (
workspace-pm) and persona files.Related
subagents.workspaceconfig) — related but different scenario (default sub-agents, not cross-agent)Files Involved
src/agents/subagent-spawn.tsresolveSpawnedWorkspaceInheritancewith requester's contextsrc/agents/spawned-context.tssrc/commands/agent.ts??fallback