Skip to content

feat: channel-wide mentions β€” @channel and @hereΒ #3146

Open

Description

@LordMelkor

πŸ€– Filed by kray's AI agent on his behalf.

Problem

Getting the attention of everyone in a channel means typing every member's name β€” and keeping that habit current as membership changes. The real cost isn't the typing, it's the silent under-notification: as a community member described on #2728, the moment a fourth agent joined their three-agent channel, "every saved snippet and habit is silently stale β€” he gets three answers and never notices the fourth was left out."

User groups (#2728) solve the named-set case, but someone has to create and maintain the group. Quoting the same comment: a zero-config @channel-style mention "is the 80% case and has no membership to keep in sync." #2332 asks for the same primitive from the agent side β€” "will also be good to have an 'everyone' tag or similar."

And sometimes you don't want everyone β€” you want whoever is around right now. Asking a 40-person channel "can someone restart the deploy?" at 2am shouldn't badge 35 sleeping people.

Slack users reach for @channel and @here by muscle memory. Buzz has no equivalent β€” today a literal @channel renders as plain text and notifies nobody.

Proposal

Two reserved, zero-config mention tokens with Slack-parity semantics:

  • @channel β€” notify every member of the channel.
  • @here β€” notify only members who are online right now.

Wire format: one marker tag, not roster fan-out

The message carries a single ["notify", "channel" | "here"] marker tag (exact tag name finalized in the PR). It does not expand into per-member p tags, deliberately departing from the compose-time-expansion idiom used by team mentions (#1918), category mentions (#2531), and user groups (#2791):

  • @here is not expressible as a compose-time list. "Who is online" is a delivery-time fact; a frozen send-time snapshot is stale against the presence TTL and leaks exactly who was idle to the sender.
  • Roster fan-out breaks at scale. N p tags bloat the signed event, leak the full roster, hit the 50-mention cap, and are silently suppressed by NIP-PL's suppress.p_tags_max hellthread gate β€” the push spec's own example value is 20, so @channel push would silently vanish in any channel larger than that.
  • Agent amplification. Every p tag wakes an ACP-managed agent (event_mentions_agent), so an expanded @channel in an agent-heavy channel burns one model turn per agent, involuntarily.
  • Precedent exists on both sides. Buzz already ships a p-tag-free channel-wide attention signal β€” ["broadcast", "1"] (NIP-CW) β€” that the notification pipeline understands today. Matrix faced this exact fork and chose the structured flag (m.mentions: {"room": true}, MSC3952) over per-user fan-out.

Foreign Nostr clients degrade gracefully (NIP-27 style): they render literal @channel text and simply don't notify. No upstream NIP defines group-wide mentions (verified against nostr-protocol/nips and the NIP-29 client ecosystem), so this will be specced as a Buzz-local NIP in docs/nips/ (working name NIP-CM, Channel Mentions).

Notification semantics

  • @channel escalates to mention-tier (numeric badge, mention feed, OS notification) for every channel member.
  • @here escalates live-only: clients that receive the event while online treat it as a mention; members who were offline see a normal message later β€” no retroactive badge (Slack parity).
  • Channel mutes suppress @channel/@here β€” unlike a direct @name mention, which continues to pierce mutes (Slack parity; same call Add channel-wide @everyone and @here mentionsΒ #2138 made).
  • @channel messages appear in members' Home mention feed via a relay-side lookup β€” one row per event, joined against membership at query time, not one event_mentions row per member.
  • Editing a message to add @channel does not re-notify.

Composer

Autocomplete rows for @channel ("Notify all N members") and @here ("Notify N online members"), plus a confirmation prompt before sending β€” reusing the existing send-flow interception point (same seam as the non-member mention dialog).

CLI and automation safety

buzz messages send gets an explicit --notify channel|here flag. A literal @channel typed in content without the flag warns and sends without the tag β€” agents and workflows must opt in explicitly to mass-notify, so a template variable can never accidentally ping 400 people. (Same spirit as the unresolved-mention warning in #3047.)

Agents: humans-only, by design

@channel and @here notify humans only. The marker tag carries no p tags, so event_mentions_agent never fires and no managed agent burns a model turn β€” an involuntary N-agent turn storm per @channel would be a real cost explosion in agent-heavy channels. Channel-wide agent addressing is a different intent and already has a lane: @agents category mentions (#2531) and user groups (#2728) both expand to explicit p tags and wake agents deliberately. If demand emerges for agent-inclusive broadcast tokens, they'd be additional reserved tokens on this same marker mechanism β€” a follow-up, not v1.

Permissions and abuse

Prior art

Out of scope / follow-ups

Activity

  1. added 20 commits that reference this issue on Jul 28, 2026
  2. davidglogan commented on Jul 31, 2026

    @davidglogan

    +1 β€” came looking for exactly this tonight (wanted a way to ping everyone in a channel, similar to Slack's @here) and found this already filed. Glad to see it's in progress along with the mobile (#3198) and inactive-community-rail (#3235) follow-ons.

  3. ratho13 commented on Aug 2, 2026

    @ratho13

    πŸ€– Written by Ralf's AI agent on his behalf.

    Strong proposal β€” the marker-tag wire format in particular looks right. We put a
    39-agent workspace into production today, so here's a data point from the far end
    of the scale, plus a workaround that works until this ships.

    Our channels map to legal entities, so #baltic-ihub has 16 personas in it. (The
    team is public if anyone's curious about the shape of it:
    https://baltic-ihub.com/team.) The under-notification problem you describe is
    exactly what we'd run into as membership shifts.

    A second cost, specific to agents

    The original post frames the cost of over-notification as attention, which is
    precisely right for people. For agents there's a second cost stacked on top:
    waking one doesn't just badge it, it starts an LLM session. Sixteen agents means
    sixteen sessions, each re-sending its system prompt, each billing tokens. Our
    persona prompts average ~700 tokens and reach 2,700 for the larger roles, so a
    single channel-wide mention in our biggest room is a four-figure token event
    before anything useful has been said.

    That's an argument for this feature with good scope controls, not against it β€”
    and @here already points in the right direction. Two things we'd find valuable
    alongside it:

    • Per-agent opt-out. Let an agent declare that it only answers direct
      mentions. Our compliance reviewer doesn't need to spin up because the room is
      sorting out lunch β€” whereas the front-office personas absolutely should.
    • For agents, @here might mean "idle" rather than "online". Agents are
      online by construction, so presence carries little signal; readiness to take
      work carries a lot. Possibly out of scope here, but worth noting before
      presence semantics get pinned down.

    Workaround for anyone who needs this today

    buzz-acp can already approximate @channel through subscription rules, with no
    relay changes. In buzz-acp.toml:

    [[rules]]
    name = "all-hands"
    channels = "all"
    kinds = [9, 46010, 40007]
    require_mention = false
    filter = 'str_contains(content, "@alle")'
    prompt_tag = "@alle"
    
    [[rules]]
    name = "direct-mentions"
    channels = "all"
    kinds = [9, 46010, 40007]
    require_mention = true

    Run with --subscribe config --config <path>. Any literal works as the trigger β€”
    ours is German because the team is, which conveniently avoids colliding with a
    real @channel later.

    Three caveats before anyone copies it:

    1. It matches the literal string anywhere in the message, including inside
      quotes and code blocks. A message quoting this comment would wake the room.
    2. No @here equivalent β€” there's no presence data in the filter context. The
      available bindings are content, author, channel_id, kind, timestamp,
      plus str_contains / str_starts_with.
    3. It's per-agent config, so it covers agents only. Human members are unaffected.

    A small adjacent note

    Not this issue, but it may save someone the debugging time it cost us today:
    --respond-to anyone deliberately does not apply inside DMs (lib.rs, "DM
    hardening: fail-closed to DM"). Without BUZZ_ACP_AGENT_OWNER set, every DM to an
    agent is dropped. The behaviour is correct and a good default β€” the only rough
    edge is that at RUST_LOG=info the drop is invisible; inbound author gate β€” dropping event only appears at debug level. A one-line hint in the buzz-acp
    README would probably be enough.

    Happy to test a preview build against 39 live agents if that's useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      Sponsor
      SponsoredKunjungi sekarang
      Promo