Skip to content

Notifications

Tessule raises a notification when something happens that a person should know about but might otherwise miss: a usage limit is reached, an import rejects rows, a colleague mentions you in a comment, a subscription falls past due. Notifications surface in three places — a badge on the bell icon, the notification centre behind it, and (for the most serious states) a banner across the top of the app — and some kinds also send email.

If you only remember one thing: a notification explains a situation, it never enforces one. Dismissing a banner or clearing the badge changes nothing about what you or anyone else can do — the restriction a notification describes (a blocked limit, a suspended organization) is enforced by the subsystem that owns it, and it stays in force until the underlying fact changes.


  • See notifications — requires the notifications:read action, granted to every built-in role (Admin, Member, and Reader).
  • Holding notifications:read only lets you ask, though. Each notification kind declares who its audience is — usually the people holding the permission action that can fix the situation — and visibility is decided per notification, per person, on every read. Two admins can therefore open the same centre and see different lists, and that is by design: alerts go to whoever can act on them, never to “everyone”.
  • There is no separate “manage notifications” permission: nothing in the centre can be edited or deleted, only read and acknowledged.

The audience actions are ordinary actions from the roles model — a custom role granting, say, limits:manage also puts its holders in the audience for limit alerts.


Conditions and events — the one distinction that explains everything

Section titled “Conditions and events — the one distinction that explains everything”

Every notification is one of two kinds, and every behaviour below follows from which one it is:

  • A condition is a state that is true until it isn’t — “this workspace is at its daily limit”, “this organization is past due”. Conditions never duplicate (re-detecting the same fact updates the existing entry rather than adding another) and they resolve themselves the moment the fact stops being true — when the usage window resets, the invoice is settled.
  • An event is a point-in-time fact — “Tuesday’s backup failed”, “Ana mentioned you at 14:02”. Events append (three mentions are three entries) and never resolve, because a past fact cannot stop having happened. They simply age out of the list (see retention below).

Only a condition can appear as a banner: a banner is a claim about now, and only a condition can stop being true.

Condition open acknowledged resolved anyone dismisses fact stops being true resolves automatically, acknowledged or not Event unread read you read it never resolves — ages out after 90 days
The two lifecycles. Read state is always personal; acknowledgement and resolution are shared, and only conditions have them.

These are the notification kinds Tessule raises today. “Who sees it” is the audience rule — the exact permission action whose holders are notified.

Notification Kind Severity Who sees it Emailed?
Limit reached — a quota is exhausted and requests are being rejected condition critical Workspace limit admins (limits:manage plus the action owning the affected feature); escalates to org admins (org:limits:manage) and billing (org:billing:manage) when the binding ceiling is an org policy or plan allowance Yes
Limit warning — usage passed the advisory threshold (75% by default), nothing rejected yet condition warning Same as above No — deliberately, so the 100% alert stays loud
Import finished with issues — a CSV import failed, or landed but rejected rows event warning schema:apply holders (workspace admins); the entry names who ran the import Only on outright failure, not for rejected rows
Backup or restore failed event warning Org backup admins (org:backups:manage) Yes
Domain verification lost — a verified sign-in domain’s DNS record disappeared, so its sign-in policies stopped applying condition critical Org domain admins (org:domains:manage) Yes
Organization past due — the subscription fell out of good standing (trial ended, payment failed, or no payment method) condition critical Org billing admins (org:billing:manage) Yes
Organization suspended — non-payment has blocked writes; data remains readable and exportable condition critical Org billing admins (org:billing:manage) Yes
You were mentioned — a colleague named you in a record comment event info Only the mentioned person No

A few deliberate absences worth knowing about:

  • A clean import raises nothing. The data is simply there — a notification saying nothing went wrong is how a badge becomes wallpaper.
  • Approval requests and decisions are not notification-centre items. Approvals have their own built-in emails to the approvers and requester, plus the My Approvals page — see Approvals.
  • Mentions are only raised when the mentioned person can actually see the record — a mention on a record outside their visibility is suppressed, so a notification never leaks a record’s existence.

Where a notification appears is derived from its severity and kind — nothing chooses its own placement:

Condition Event
critical banner + badge + centre centre + badge
warning badge + centre centre + badge
info centre centre
  • The badge on the bell icon counts your unread events plus all open conditions — so acknowledging a banner drops it to the badge rather than making it vanish. It updates live (a raised notification arrives over the workspace’s realtime connection) with a slow poll as backstop.
  • The notification centre (click the bell) lists everything you can see: conditions pinned first (they are claims about now), then events, newest first. Each entry shows a severity chip, the message, a relative timestamp, and — where there is somewhere useful to go — an action button deep-linking to the page where the state can be understood or fixed. Mark all read is in the header.
  • The banner renders only open, unacknowledged, critical conditions — and only one at a time (any others are noted as “+N more in notifications”). It is always dismissible: critical deliberately tops out at a banner, never a modal or a lockout.

Read vs acknowledge — two different verbs

Section titled “Read vs acknowledge — two different verbs”

These are easy to conflate and the system keeps them strictly apart:

  • Read is personal. Marking a notification read (POST /notifications/{notificationId}/read, or POST /notifications/read for everything at once) affects only your badge. It never changes the notification’s status for anyone else, and it does not assert the underlying fact has gone away — a still-open condition keeps its banner even after you mark it read.
  • Acknowledgement is shared. Dismissing a banner (POST /notifications/{notificationId}/acknowledge) drops it to the badge for the whole audience — one admin acknowledging means five admins don’t each dismiss the same true fact. Acknowledging does not resolve the condition and does not change what anyone can do; it only stops the app shouting about it. Events cannot be acknowledged — read state is their whole lifecycle.
  • Resolution is automatic. Nobody “closes” a condition by hand: it resolves when the fact it describes stops being true, whether or not anyone ever acknowledged it.

The app shell fetches the badge count and banner set in one cheap request, GET /notifications/summary; the full list is GET /notifications (pass status=all to include recently resolved conditions).


Kinds marked “emailed” above send a plain-text email to each person in the audience, at the address on their account. Three rules keep this channel trustworthy:

  • A condition emails once. Re-detecting an already-notified condition updates the in-app entry but does not email again — no daily nagging about the same true fact.
  • In-app is the record; email is a channel. Organizations have a daily cap on notification email (200/day by default across all workspaces, adjustable per plan). Past the cap the in-app notification still exists — nothing is lost, only the email.
  • There are no per-user email preferences today. Which kinds email is a platform decision per kind (chosen so that only things genuinely worth an inbox entry send one); individual opt-out per kind is not currently a setting. Verify against the table above rather than assuming a toggle exists.

Tessule is an installable web app and can show system-level notifications via your browser’s push service, using standard VAPID web push.

  • Enabling: shortly after signing in you may see a one-time prompt asking for notification (and location) permission; you can also toggle push any time from the profile menu (your avatar, top right) — the “Push Notifications” switch. Enabling asks the browser for permission, then registers this browser with the server (POST /push/subscribe).
  • Per device, deliberately. A push subscription belongs to one browser on one device. Enable it on your laptop and your phone separately; disabling it on one device (DELETE /push/unsubscribe) leaves the others subscribed. A test or push send goes to all devices you have registered.
  • Testing: once subscribed, a Send Test button appears under the toggle — it calls POST /push/test and reports how many of your devices received it. Use it to confirm the browser-side plumbing before relying on push.
  • If the toggle says “Blocked”, you previously denied notification permission for the site; re-enable it from the browser’s site settings (the lock icon in the address bar), then refresh.

Notifications are working memory, not the audit trail:

  • Resolved conditions are pruned about 30 days after resolving.
  • Events are pruned after about 90 days.
  • Security- and billing-shaped kinds (lost domain verification, past-due, suspended) are exempt and never auto-pruned.

The authoritative record of what happened is the audit log — a pruned notification removes the reminder, never the evidence.


Q: A banner disappeared and I never dismissed it. Either a colleague in the same audience acknowledged it (acknowledgement is shared), or the condition resolved itself — the usage window reset, the payment landed. Check the centre with status=all if you want to see recently resolved entries.

Q: My colleague sees a notification I don’t. Is something broken? No — each kind is visible only to the people holding the permission action that can act on it. A limit alert goes to limits:manage holders, a billing alert to org billing admins, a mention only to the person mentioned. Your badge count is personal to what you can see.

Q: I marked everything read but the badge still shows a number. The badge counts unread events plus open conditions. An open condition keeps contributing until it resolves — that’s deliberate, because the state it describes is still true. Acknowledged conditions still count too; only resolution clears them from the badge.

Q: Can I turn off emails for a particular kind of notification? Not currently — email policy is fixed per kind (see the table). The kinds that email are chosen to be low-frequency and genuinely actionable; high-frequency kinds like mentions never email.

Q: I enabled push on my laptop but got nothing on my phone. Push subscriptions are per device. Open Tessule on the phone and enable the toggle there too.

Open the app