Summary
Skill-forked subagents record origin: "unknown" in the witness trace instead of the owning surface (cli/telegram/daemon), the same class of bug fixed for agent-tool and compose forks in #468 (follow-up to #466).
Root cause
In src/agent/tools/skill-executor.ts, the session surface is threaded onto the child executor context (this.ctx.surface used at :651) but is not passed to the SubagentManager constructions that actually fork the skill subagents:
skill-executor.ts:625 (nested child manager for grandchild dispatch)
skill-executor.ts:767 (forked skill subagent manager)
skill-executor.ts:1011 (registry/plugin skill subagent manager)
None pass surface, so SubagentManager.parentSurface is undefined and forkSubagent's origin fill (subagent.ts:634) no-ops → deriveOrigin(undefined) → 'unknown' (session-identity.ts:38-53).
Why separate from #468
This gap is pre-existing — skill forks were already trace-visible before #466 (they thread traceWriter via SkillExecutorContext), so it is outside both #466's scope ("agent-tool and compose forks") and the Codex findings on #466. #468 fixed the agent-tool/compose/root-manager/daemon sites and deliberately left this for a focused follow-up.
Fix (expected shape)
Add ...(this.ctx.surface !== undefined ? { surface: this.ctx.surface } : {}) to each of the three skill-executor manager constructions, mirroring how traceWriter/cwd are already threaded there and how #468 fixed the other paths. Confirm this.ctx.surface is populated at each (it drives routing telemetry via deriveOrigin at :293). Add a regression test analogous to the child-config.test.ts surface tests added in #468.
Verify
afk trace show on a session that dispatches a skill should show the skill subagent's session_init_start with the real origin, not unknown.
Summary
Skill-forked subagents record
origin: "unknown"in the witness trace instead of the owning surface (cli/telegram/daemon), the same class of bug fixed foragent-tool andcomposeforks in #468 (follow-up to #466).Root cause
In
src/agent/tools/skill-executor.ts, the sessionsurfaceis threaded onto the child executor context (this.ctx.surfaceused at:651) but is not passed to theSubagentManagerconstructions that actually fork the skill subagents:skill-executor.ts:625(nested child manager for grandchild dispatch)skill-executor.ts:767(forked skill subagent manager)skill-executor.ts:1011(registry/plugin skill subagent manager)None pass
surface, soSubagentManager.parentSurfaceisundefinedandforkSubagent's origin fill (subagent.ts:634) no-ops →deriveOrigin(undefined)→'unknown'(session-identity.ts:38-53).Why separate from #468
This gap is pre-existing — skill forks were already trace-visible before #466 (they thread
traceWriterviaSkillExecutorContext), so it is outside both #466's scope ("agent-tool and compose forks") and the Codex findings on #466. #468 fixed the agent-tool/compose/root-manager/daemon sites and deliberately left this for a focused follow-up.Fix (expected shape)
Add
...(this.ctx.surface !== undefined ? { surface: this.ctx.surface } : {})to each of the three skill-executor manager constructions, mirroring howtraceWriter/cwdare already threaded there and how #468 fixed the other paths. Confirmthis.ctx.surfaceis populated at each (it drives routing telemetry viaderiveOriginat:293). Add a regression test analogous to thechild-config.test.tssurface tests added in #468.Verify
afk trace showon a session that dispatches a skill should show the skill subagent'ssession_init_startwith the real origin, notunknown.