Issue generated by Kimi K3
Describe the bug
The buzz-acp agent harness only responds to messages that explicitly @mention the agent. Once an agent has joined a thread, follow-up replies in that thread are silently ignored unless the human re-tags the agent on every single message.
The gate exists at two levels:
- Relay subscription —
SubscribeMode::Mentions (the default) sets require_mention: true on channel filters, so the relay never even delivers untagged thread replies to the harness.
- Rule matching —
match_event in the filter module re-checks for the agent's p tag; no match → event dropped.
To Reproduce:
- Start a buzz-acp agent with default config (Mentions subscribe mode) joined to a channel.
- In that channel, send a message @mentioning the agent — it responds in a thread.
- Reply in that same thread without tagging the agent (e.g. "yes, go ahead").
- The agent never sees the reply — no reaction, no response. Re-tag the agent in the same thread and it responds immediately.
Expected behavior:
The agent should follow threads it is participating in — like Slack/Discord thread notifications — so a human can continue the conversation naturally without re-mentioning on every reply. Agents must never auto-reply to each other without an explicit mention (anti-loop invariant).
Agreed solution direction (participation-based thread following):
- Track per-channel "participating thread roots" in the harness — seeded when the agent is mentioned in or replies to a thread (NIP-10
root_event_id via the existing thread-tag parser), with TTL/LRU expiry so stale threads don't wake the agent forever.
- Widen the relay subscription in Mentions mode (drop relay-side
require_mention for chat message kinds) and move gating fully into rule matching: queue if mentioned(agent) OR root_event_id ∈ participating[channel].
- Anti-loop invariant: participation-follow applies to human-authored replies only; agent-authored replies still require an explicit mention. Never queue the agent's own events. The existing author gate, per-channel in-flight dedup, and fail-closed filter semantics stay unchanged.
- Config: new per-rule fields
follow_participating_threads (default true in Mentions mode) and follow_thread_authors = "humans" | "all".
- Scope:
buzz-acp only — no relay changes, no new event kinds, no protocol changes.
Supporting Material
- The mention gate:
match_event stage 3 (require_mention) in crates/buzz-acp/src/filter.rs; channel filter construction in crates/buzz-acp/src/config.rs (SubscribeMode::Mentions sets require_mention: !config.no_mention_filter).
- The thread-tag parser already exists (
parse_thread_tags in the queue module) and yields root_event_id / parent_event_id — the seed data for participation tracking.
- Existing loop-breakers that must be preserved: author gate (
respond_to owner/allowlist/sibling modes), one in-flight prompt per channel with batched queueing, fail-closed evalexpr filter semantics, relay-side exclusion of workflow execution kinds from triggers.
Environment
- Component:
buzz-acp agent harness (Rust)
- Affects: all deployments using the default Mentions subscribe mode
Additional context
Repo conventions: read AGENTS.md first (Nostr-first patterns, kind registry in buzz-core, just ci quality gates). Existing unit tests live alongside the filter/queue modules; relay-level E2E lives in the integration test client crate.
User story seed: As a Buzz user, I want the agent to keep responding in a thread it has joined without me re-tagging it on every message, so conversation flows naturally — while agents never auto-reply to each other without a mention.
Describe the bug
The buzz-acp agent harness only responds to messages that explicitly @mention the agent. Once an agent has joined a thread, follow-up replies in that thread are silently ignored unless the human re-tags the agent on every single message.
The gate exists at two levels:
SubscribeMode::Mentions(the default) setsrequire_mention: trueon channel filters, so the relay never even delivers untagged thread replies to the harness.match_eventin the filter module re-checks for the agent'sptag; no match → event dropped.To Reproduce:
Expected behavior:
The agent should follow threads it is participating in — like Slack/Discord thread notifications — so a human can continue the conversation naturally without re-mentioning on every reply. Agents must never auto-reply to each other without an explicit mention (anti-loop invariant).
Agreed solution direction (participation-based thread following):
root_event_idvia the existing thread-tag parser), with TTL/LRU expiry so stale threads don't wake the agent forever.require_mentionfor chat message kinds) and move gating fully into rule matching: queue ifmentioned(agent)ORroot_event_id ∈ participating[channel].follow_participating_threads(default true in Mentions mode) andfollow_thread_authors = "humans" | "all".buzz-acponly — no relay changes, no new event kinds, no protocol changes.Supporting Material
match_eventstage 3 (require_mention) incrates/buzz-acp/src/filter.rs; channel filter construction incrates/buzz-acp/src/config.rs(SubscribeMode::Mentionssetsrequire_mention: !config.no_mention_filter).parse_thread_tagsin the queue module) and yieldsroot_event_id/parent_event_id— the seed data for participation tracking.respond_toowner/allowlist/sibling modes), one in-flight prompt per channel with batched queueing, fail-closed evalexpr filter semantics, relay-side exclusion of workflow execution kinds from triggers.Environment
buzz-acpagent harness (Rust)Additional context
Repo conventions: read
AGENTS.mdfirst (Nostr-first patterns, kind registry inbuzz-core,just ciquality gates). Existing unit tests live alongside the filter/queue modules; relay-level E2E lives in the integration test client crate.User story seed: As a Buzz user, I want the agent to keep responding in a thread it has joined without me re-tagging it on every message, so conversation flows naturally — while agents never auto-reply to each other without a mention.