New on Tapeboard: alerts you can actually control (and the honest story of why they weren't before)
We shipped the alert controls weeks after shipping the alerts. That was backwards. Today: a real mute, per-channel control, quiet hours that work, and a cap on the scanner firehose.
The scene
Tapeboard is a scanner. A scanner's job is to notice things before your eyes would. Alerts are the goose: the moment the scanner knows something you care about, it tells you — on your screen, on your phone, in your email. That's the pitch.
This week we took a hard, honest look at the alerting stack. What we found wasn't pretty, and some of it had been that way for months:
- In one 7-day window we wrote 16,232 notifications across ~330 accounts. Zero were ever marked read. Not because nobody cared — because the bell badge in the header was counting the *wrong table*. The stream everyone actually fires into (your price alerts, scanner movers, halts, fills) was almost completely invisible from the header.
- 20 users had push notifications enabled. Out of 644. Not because web-push is new or exotic — we built the whole RFC-grade stack in-house — but because the only place to turn it on was a PWA install prompt nobody reads.
- Three settings we shipped looked like they did something and did nothing: quiet hours saved to your browser instead of your account; an "alert email" toggle gated by an env var we never set; an "alert delivery" card writing to a setting nothing reads. You flipped a switch and nothing happened. That's a broken promise, not a bug.
If you're the type to ask "okay but was anything actually *broken* though" — yes: weekly digest emails stopped sending in early July, the synthetic user-journey probe that should have caught it was pinned red for a month (wrong reason: a security middleware was rejecting our own probe), and a wave of crons marked themselves broken while actually finishing their work. The alerting system was noisy where it should have been quiet and quiet where it should have been loud.
So this week we rebuilt the *control layer*.
What's actually shipped
One page for all of it: Settings → Notifications
!The new Notifications settings surface
One master switch — *Mute everything* — that silences every channel. Halted-stock warnings still get through (those are urgent; someone is mid-position right now).
Under it, an actual matrix: every alert kind (price alerts, halts, watchlist movers, earnings, simulator fills, digests, news, economic releases, options flow) × every channel (in-app inbox, device push, email). You decide: price alerts push to your phone but not email. Scanner moves to inbox only. Whatever you want.
Quiet hours that exist
The old quiet-hours wrote the setting to localStorage and never told the server. It looked right and did nothing. Now it saves to your account and the evaluator honors it.
The scanner firehose is capped
Watchlist mover alerts used to dedupe per-symbol per day — a full watchlist meant ~20 pushes/day into an inbox you weren't reading. Now: 3 pushes per day, tops. Everything over the cap collapses into one tidy "more movers on your list" inbox row. Your watchlist is still the feed on your dashboard; it's just no longer a mobile spammer.
The door to push alerts
The two moments when you actually *want* push are: just after you create an alert, and right after your first sim fill. So that's where the enable-prompt lives now — one tap from where you already were.
The bell counts what exists
The sidebar bell and the Notifications inbox now read and mark the *same* stream. The count is real, the rows are real, and clicking a row takes you to the thing.
For the number-watchers
Every alert now logs what happened to it: which channels it went down, or the exact reason it was suppressed (quiet hours, you muted the symbol, daily cap). Admins can see it. Eventually users will too.
What we didn't build
No new channels. No SMS farm, no Discord bot, no Slack integration. Not because those are bad ideas — because fixing the channels we already have mattered more and they were in worse shape than we admitted.
We also didn't re-do the brain: the conditions, thresholds, and evaluator logic were solid. What was janky was the *control*.
Why this took weeks instead of a day
Because "just add a toggle" was the bug. The real fix was answering, correctly: *when* does the user want this, *where*, *how often*, and *when absolutely not* — then making every one of those a real choice instead of a promise we didn't keep.
That's the bar now. If any toggle on that page lies to you, treat it as a bug and yell at us.
— The Tapeboard team