acpmux: an adopted host's running subagents keep their tags
Summary
After a daemon restart, the new daemon adopts the running agent host (host_adopted). The hub's subagent tree (SubagentTree) started empty, so it no longer knew which subagents the chat was running. Until each subagent's next progress event, that subagent's lines reached clients without a tag (_meta.acpmux.subagent), so they read as the chat's own. The web pane then showed a helper's grep as the chat's own call. Leo saw this after a finished turn: "why does it say you're still running grep". #30416 (cf818b16) made the pane attribute updates by sessionId. This PR fixes the cause on the hub side, so the hub keeps the list.
adopt_held(hub/hosts.rs) now callsseed_subagents_from_log(hub/work_below.rs) before the host's replay reaches the tap. It rebuilds two things from the durable log, the same way the tap followed them live:- which subagents the chat started, so tagging continues from the first replayed line
- which subagents still run, so the summary's
subagentsRunningandsubagentNamesand the work-below state are right
- A harness start, stop or exit ends the background subagents. A turn start ends the foreground ones. Both match live behaviour, and
processes.rsread_processesrebuilds the same way. - New
SubagentTree::adoptmerges the rebuilt tree into the live one. A subagent the live tree already knows keeps its own state. - The head predicate for "this line may name a subagent" is now shared with
open_work_reads(names_subagents).SubagentTree's background tests move tosubagents_background_tests.rs, so the god-file-cappedsubagents.rsandhosts.rsshrink instead of growing.
Builds on #30439, which added the running-subagent counts that are now rebuilt too.
Test
tests/durable_agents.rs a_subagent_running_across_a_restart_keeps_its_tag_after_adoption. A turn starts subagent child-1 and its tool call. The daemon is killed and restarted, then adopts the host. The test checks that the summary still counts the subagent, then that the child's next line (tool_call_update cg-1) is tagged child-1.
Command: cargo test -p acpmux --test durable_agents a_subagent_running_across_a_restart_keeps_its_tag_after_adoption
- Base plus test only (78a63f7): see the comment below
- Head: see the comment below
Observed / Not run
Observed: rustfmt, prepush-gate, and the post-edit god-file check (no growth). The test results are in the comments.
Not run: the full acpmux suite locally (it runs through cmux-ci).
Changelog
Fixed: after an acpmux restart, a running subagent's activity no longer shows as the chat's own.
Agent session: agent session
š¤ Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes running subagents losing their tags after a daemon restart adopts their host. The adopting daemon's subagent tree started empty, so until each subagent's next progress event its lines reached clients untagged and read as the chat's own activity.
Bug Fixes
adopt_heldnow rebuilds the subagent tree from the durable log before the host's replay reaches the tap, restoring which subagents the chat started and which still run.- Added
SubagentTree::adoptto merge the rebuilt tree into the live one, keeping live state for subagents the tree already knows. names_subagentsis now shared between replay seeding andopen_work_reads.- Moved
SubagentTree's background tests tosubagents_background_tests.rsso the file-size-cappedsubagents.rsandhosts.rsdon't grow.