Symptom
In a 1:1 DM with a managed agent, once a thread exists, every agent reply anchors to the human's latest comment rather than the thread root. Each exchange therefore nests one level deeper — the user has to click-expand a sub-thread of a sub-thread of a sub-thread to follow a simple back-and-forth conversation with their own agent.
Root cause
crates/buzz-acp/src/queue.rs — the human-aware reply-anchor logic documents the right intent directly above the code:
Human-facing turns are anchored so replies stay readable at layer 1:
- in a thread → anchor to the thread ROOT (no depth-2 nesting)
…and resolve_reply_anchor implements exactly that for group channels. But the DM branch contradicts it:
let reply_anchor = if is_dm {
thread_tags
.root_event_id
.is_some()
.then(|| last_event.event.id.to_hex()) // ← anchors to the LATEST message, not the root
} else {
resolve_reply_anchor(...) // ← group channels: anchors to ROOT
};
When the triggering DM message is inside a thread, the anchor is last_event.event.id — the user's newest comment — so the agent's reply becomes a child of a child, and the nesting compounds every round.
Propose
In DMs, match the documented layer-1 rule: anchor to thread_tags.root_event_id when inside a thread (same as the group-channel human path). Worth discussing whether top-level DM exchanges should thread at all — a 1:1 DM arguably reads best flat, with threading reserved for explicit user-initiated threads — but the root-anchoring fix alone eliminates the compounding sub-chat nesting.
Observed on a self-hosted relay (ghcr.io/block/buzz:main 2026-07-24, desktop 0.4.24), desktop-managed agents, default settings. Sibling issues: #2270 (thread deafness without re-mention), and the DM mention-gate issue filed alongside this one.
Symptom
In a 1:1 DM with a managed agent, once a thread exists, every agent reply anchors to the human's latest comment rather than the thread root. Each exchange therefore nests one level deeper — the user has to click-expand a sub-thread of a sub-thread of a sub-thread to follow a simple back-and-forth conversation with their own agent.
Root cause
crates/buzz-acp/src/queue.rs— the human-aware reply-anchor logic documents the right intent directly above the code:…and
resolve_reply_anchorimplements exactly that for group channels. But the DM branch contradicts it:When the triggering DM message is inside a thread, the anchor is
last_event.event.id— the user's newest comment — so the agent's reply becomes a child of a child, and the nesting compounds every round.Propose
In DMs, match the documented layer-1 rule: anchor to
thread_tags.root_event_idwhen inside a thread (same as the group-channel human path). Worth discussing whether top-level DM exchanges should thread at all — a 1:1 DM arguably reads best flat, with threading reserved for explicit user-initiated threads — but the root-anchoring fix alone eliminates the compounding sub-chat nesting.Observed on a self-hosted relay (
ghcr.io/block/buzz:main2026-07-24, desktop 0.4.24), desktop-managed agents, default settings. Sibling issues: #2270 (thread deafness without re-mention), and the DM mention-gate issue filed alongside this one.