Skip to content

core: HookBus agent attribution is a save/restore slot that concurrent sibling children will corrupt the moment a bus is attached #1853

Description

@macanderson

Problem

crates/stella-core/src/subagent.rs:451-472 (AgentAttribution) saves the previous ambient agent id and restores it on drop; HookBus::set_agent (bus.rs:591-594) mutates one process-shared Mutex<Context>. Correct only under strict LIFO nesting — concurrent siblings (live once PR #1836 lands) violate it: A enters (prev None), B enters (prev Some(a)), A drops → ambient None while B runs, B drops → ambient permanently Some(a); the parent's remaining bus events are attributed to a finished child.

Not live today: both dispatchers build SubAgentHost::new with no bus (stella-cli/src/subagent.rs:378, stella-serve/src/subagents.rs:265), so enter is a no-op. It arms the instant anyone calls SubAgentHost::with_bus — and stella-serve/src/session.rs:764 already attaches a bus to the engine, so this is the obvious next step for someone.

Fix direction

Make attribution a stack or (better) thread-local/task-local carried by the child's own execution context, not a global slot. If that is deferred, put a debug_assert/comment on with_bus refusing concurrent-sibling use so the trap is at least fenced.

Verify

Witness: two overlapping AgentAttribution scopes on one bus must leave the ambient id equal to the pre-entry value after both drop, and events emitted between drops must carry the still-running child's id.

Constraints

stella-core; bus.rs is a god file — plan new code into a sibling module.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Important — next in linetriageUntyped request — convert by adding bug / feature / epic

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions