You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Push wakes the phone for messages the app itself refuses to mark unread — the push lease subscribes to every channel message, the unread rule excludes untouched thread replies #7825
Buzz has two different, independently-written answers to "is this event worth telling the user about", and they disagree. The push lease is broad; the in-app unread rule is narrow. The result on a phone is the worst of both: it buzzes for a thread reply in a thread you have never touched, you open Buzz, and nothing is badged — because the client's own rule says that event was never notification-worthy.
buzzPushChannelKinds is [9] (:9). The filter is kind + #h only. The only narrowing is ignore (self-authored, muted channels) and suppress (pTagsMax: 20, the hellthread guard). Per NIP-CW a thread reply is a kind:9 carrying the channel's h tag — depth is derived from e reply markers, which this filter does not look at. So every reply in every non-muted channel you are a member of matches.
if (ref.parentId ==null) returntrue;
final rootId = ref.rootId;
if (rootId !=null&& mutedRootIds.contains(rootId)) returnfalse;
return rootId !=null&&
(participatedRootIds.contains(rootId) ||
followedRootIds.contains(rootId) ||
authoredRootIds.contains(rootId));
A reply only counts if you're p-tagged, it's broadcast, or you participated in / follow / authored the root. This is the right rule — it's what stops a busy channel's threads from lighting up the whole sidebar. It is also strictly narrower than the push filter.
Join a channel with active threads. Do not post in, follow, or get mentioned in thread T.
Lock the phone.
Have someone reply in thread T, with no p tag for you and no ["broadcast","1"].
Expected behavior
Either the phone stays quiet, or the app badges the thread when opened. The two surfaces agree.
Actual behavior
The phone wakes and shows a banner. Opening Buzz shows no unread badge for that channel or thread, because shouldNotifyForEvent returns false for the same event.
Why this matters more than it sounds
It's the mechanism behind "notifications are noisy and I still miss things" — the most common shape of notification complaint, and it's why muting-by-hand doesn't converge. It also makes every other notification issue harder to reproduce, because the reporter's phone and the reporter's app are describing different event sets.
Suggested direction
shouldNotifyForEvent is the product decision and it's already written down. The push lease should express the same predicate as far as a relay-side filter can: the self-directed #p subscription already covers mentions; the broad per-channel #h subscription is what over-fires. Options, roughly in order of how much protocol work they need:
Narrow the channel subscription to depth-0 (no ereply marker) plus broadcast — needs a NIP-PL filter primitive that can express "no reply marker", which today it can't.
Add followed/participated root ids as an #e subscription and drop the blanket #h one. Bounded by buzzPushMaxSubscriptions = 16 and the 50-per-chunk size, so it won't hold for a heavy user — but it's closer to correct than today.
Keep the broad lease and resolve on-device in the NSE: it already fetches relay data to rewrite title/body (mobile/ios/NotificationService/NotificationService.swift:76-79). Apply shouldNotifyForEvent there and suppress rather than present. Costs a wake per event but makes the two surfaces agree, and needs no protocol change.
Whichever, the predicate should live in one place and both surfaces should import it. Right now should_notify_for_event.dart has no test file (grep -rl shouldNotifyForEvent mobile/test → nothing), which is probably why the divergence went unnoticed.
Describe the bug
Buzz has two different, independently-written answers to "is this event worth telling the user about", and they disagree. The push lease is broad; the in-app unread rule is narrow. The result on a phone is the worst of both: it buzzes for a thread reply in a thread you have never touched, you open Buzz, and nothing is badged — because the client's own rule says that event was never notification-worthy.
Verified against
mainat312cf67.The two rules
Push —
mobile/lib/shared/push/push_subscription.dart:492-503,buildDesiredBuzzPushSubscriptions:buzzPushChannelKindsis[9](:9). The filter is kind +#honly. The only narrowing isignore(self-authored, muted channels) andsuppress(pTagsMax: 20, the hellthread guard). Per NIP-CW a thread reply is akind:9carrying the channel'shtag — depth is derived fromereply markers, which this filter does not look at. So every reply in every non-muted channel you are a member of matches.In-app unread —
mobile/lib/features/channels/unread_badge/should_notify_for_event.dart:39-49:A reply only counts if you're p-tagged, it's broadcast, or you participated in / follow / authored the root. This is the right rule — it's what stops a busy channel's threads from lighting up the whole sidebar. It is also strictly narrower than the push filter.
Steps to reproduce
BUZZ_PUSH_GATEWAY_URLbaked in, against a relay that advertisesnip-pl(see Hosted communities: enable iPhone push (NIP-PL) for sunnn.communities.buzz.xyz + is the public App Store build covered? #7415 — this is currently the hard part).ptag for you and no["broadcast","1"].Expected behavior
Either the phone stays quiet, or the app badges the thread when opened. The two surfaces agree.
Actual behavior
The phone wakes and shows a banner. Opening Buzz shows no unread badge for that channel or thread, because
shouldNotifyForEventreturnsfalsefor the same event.Why this matters more than it sounds
It's the mechanism behind "notifications are noisy and I still miss things" — the most common shape of notification complaint, and it's why muting-by-hand doesn't converge. It also makes every other notification issue harder to reproduce, because the reporter's phone and the reporter's app are describing different event sets.
Suggested direction
shouldNotifyForEventis the product decision and it's already written down. The push lease should express the same predicate as far as a relay-side filter can: the self-directed#psubscription already covers mentions; the broad per-channel#hsubscription is what over-fires. Options, roughly in order of how much protocol work they need:ereplymarker) plus broadcast — needs a NIP-PL filter primitive that can express "no reply marker", which today it can't.#esubscription and drop the blanket#hone. Bounded bybuzzPushMaxSubscriptions = 16and the 50-per-chunk size, so it won't hold for a heavy user — but it's closer to correct than today.title/body(mobile/ios/NotificationService/NotificationService.swift:76-79). ApplyshouldNotifyForEventthere and suppress rather than present. Costs a wake per event but makes the two surfaces agree, and needs no protocol change.Whichever, the predicate should live in one place and both surfaces should import it. Right now
should_notify_for_event.darthas no test file (grep -rl shouldNotifyForEvent mobile/test→ nothing), which is probably why the divergence went unnoticed.Version and platform
twelfth-ai.communities.buzz.xyz, relay software 0.2.1block/buzz@312cf67Related: #7447, #7779, #7186, #6092, #4657