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
No coalescing, no rate limit, no recent-duplicate check. Whatever a caller asks for, every caller,
every time.
The tag: type argument makes this look solved and is not: a web-push tag collapses the OS
tray visually, so N identical notifications show as one entry — while each still fires its own
alert and sound. And createNotification keeps every copy, so the in-app bell list accumulates all
N. The tray is the only surface that hides the duplication, and it is the one nobody audits.
Why a floor, rather than only fixing the callers
#359 is a caller bug: the deploy watcher polls every workflow in the repo, so one push produced 2–4
notifications and a three-hour session produced 40–80. That bug should be fixed on its own terms and
is.
But it reached the user's phone at full volume because nothing between the bug and the device was
willing to say "I have already sent this". That is the fourth notification defect in this area
(#338, #344, #349, #359); a floor is what makes the next one an annoyance instead of an incident.
Shape
Suppress a push whose (user_id, type, title, body) matches one already sent inside a short window —
minutes, not hours. Two properties matter:
The window is a floor, not a policy. It exists to bound a malfunction. Legitimate repeated
notifications — two different agents needing a CAPTCHA — differ in title/body and are unaffected.
Cheapest implementation is a read of the notifications table notifyUser is already writing to, so
there is no new store and no new state to keep consistent.
No floor under the notification layer
notifyUser(routes/push.ts:196-206) is the single funnel every notification passes through:No coalescing, no rate limit, no recent-duplicate check. Whatever a caller asks for, every caller,
every time.
The
tag: typeargument makes this look solved and is not: a web-pushtagcollapses the OStray visually, so N identical notifications show as one entry — while each still fires its own
alert and sound. And
createNotificationkeeps every copy, so the in-app bell list accumulates allN. The tray is the only surface that hides the duplication, and it is the one nobody audits.
Why a floor, rather than only fixing the callers
#359 is a caller bug: the deploy watcher polls every workflow in the repo, so one push produced 2–4
notifications and a three-hour session produced 40–80. That bug should be fixed on its own terms and
is.
But it reached the user's phone at full volume because nothing between the bug and the device was
willing to say "I have already sent this". That is the fourth notification defect in this area
(#338, #344, #349, #359); a floor is what makes the next one an annoyance instead of an incident.
Shape
Suppress a push whose
(user_id, type, title, body)matches one already sent inside a short window —minutes, not hours. Two properties matter:
interruption that needs bounding. Same principle as the Push notifications: suppress when user is actively using the app (tab visible / online) #176 visibility gate, which suppresses the
banner and still forwards the payload so the badge updates.
notifications — two different agents needing a CAPTCHA — differ in
title/bodyand are unaffected.Cheapest implementation is a read of the notifications table
notifyUseris already writing to, sothere is no new store and no new state to keep consistent.
Relationship to the others
the user should never have had to notice. Different jobs, both worth having.
Noted originally as the closing section of #359 and split out so it is not lost when that one closes.