Duplicate subagent completion announces fixed
Completion announcements from subagents will no longer duplicate in parent session transcripts when cleanup retries after partial failure, eliminating transcript bloat and lane contention issues.
When a sub-agent completed its task, the parent session could receive duplicate completion messages if the announcement delivery failed partway through and then retried. Each retry injected another synthetic internal-context turn into the parent transcript, creating bloat and triggering repeated lockfile activity that could starve the parent session lane.
A timestamp field now tracks whether completion was already successfully announced. On retry or re-entry, the cleanup flow detects this and skips re-announcing, proceeding directly to bookkeeping. The change ensures parent sessions receive each completion exactly once, regardless of how many times cleanup is retried.
This fix sits in the subagent registry lifecycle controller, part of a broader effort to stabilize multi-agent session management.
View Original GitHub Description
What this fixes (plain English)
When a sub-agent completed its task but the completion announcement failed partway, retrying the cleanup would re-announce the completion to the parent agent — causing duplicate messages. This fix tracks whether the announcement was already delivered and skips re-announcing on retry, only performing cleanup bookkeeping.
Technical details
Root cause: No deduplication of the completion announce flow. On retry/re-entry after a partial cleanup failure, the entire announce+inject cycle re-ran even if the parent had already received the completion message.
Fix:
- Persist
completionAnnouncedAton the subagent run record after successful delivery - Skip announce injection for runs where delivery already succeeded, proceeding directly to cleanup
- Lifecycle regression test covering retry/re-entry after successful delivery
Files changed:
src/agents/subagent-registry.ts— sweep integration with dedup tracking,completionAnnouncedAtpersistencesrc/agents/subagent-registry.types.ts— type definition forcompletionAnnouncedAtfield on subagent run recordssrc/agents/subagent-registry-lifecycle.ts— announce dedup and delivery tracking logicsrc/agents/subagent-registry-lifecycle.test.ts— lifecycle regression tests for dedup announce behavior
Related
- Fixes #61479
- Companion PRs: #61801 (orphan reconciliation), #61803 (heartbeat routing)
Test plan
- 8/8 lifecycle tests pass
- Deduped announce skips re-injection for already-delivered completions
- Ended hook fires correctly on retry with sendFarewell: true
- cleanupCompletedAt set correctly on dedup path