Opbox has one place a person is told something needs them. A gate is waiting on your sign-off, a budget tripped, a run failed, a matter you follow moved, someone mentioned you: every one of these arrives as a notification in your inbox, not as a separate alert in a separate corner of the system. The inbox is the signal; the gate, review, or matter it points at stays the canonical work. A notification references its subject by id and never re-owns it, so a notification that is never delivered leaves your work stale, never wrong.
What it does
One inbox, not five alert seams. Everything that needs a person routes through a single notification store rather than a per-feature alert table. Matter drift, a tripped budget cap, an agent or gate escalation, a gate pending human review, an assigned review, a failed run, a failed connection or webhook, a mention, an assignment, an SLA breach, a shared object, a watched matter or document changing: all of them land as one inbox row through one verb. Consolidating these onto a single substrate is what makes “what needs me right now” a question with one answer.
A fixed notification taxonomy, not free-form alerts. Every notification carries a kind drawn from a fixed, kernel-owned taxonomy. A producer cannot invent a free-form alert: an unknown kind is rejected, so a new signal source adds a taxonomy entry rather than a one-off notice. The taxonomy is the single source the preference matrix renders from, so the kinds you can tune are exactly the kinds the system can actually send.
Read tracking that stays honest. A notification is born unread. Marking it read records when you read it; archiving it dismisses it (and a dismissed signal is not counted as read). The per-section unread dot in the shell is a thin count over this same store, so the badge and the inbox can never disagree. Re-marking to a status it already holds is a no-op success, so the inbox behaves the same whether you click once or twice.
Your inbox is yours alone. Reads and marks are fenced to the calling actor: you see and act on only your own notifications, and another person’s notification reads back exactly as a missing one would, never leaking that it exists. The fence is enforced at the verb itself, not left to a UI filter.
Mute the noise, never the oversight. You can suppress the display of the kinds you do not want to see. The suppression is display-layer only: muting a kind never stops the inbox row being written, never pauses an SLA clock, and never changes escalation routing. A set of oversight kinds (escalation, gate pending, review assigned, SLA breach, budget tripped) are locked and cannot be muted at all, so the signals that exist to route work for human review always reach a human. A preference read that fails defaults to visible: when in doubt, the signal is shown.
Follow a matter or a document. A watch is a notify-only subscription: subscribe to a matter or a document and a change to it fans a notification to you. A watch grants zero access. Watching something you cannot already open does not open it; the read stays gated exactly as before, and the watch row alone never widens what you can see. A change never notifies the person who caused it, so following your own work does not echo back at you.
Follow, favourite, and see who is here. Beyond change subscriptions, you can follow an object, star it as a favourite, and record that you have viewed it, all as durable, self-scoped engagement markers that, like watches, grant no access of their own. Live presence is separate and short-lived: a heartbeat publishes your live cursor on a matter or document with a time-to-live, and the presence list returns only the people whose heartbeat has not expired. A cursor that stops beating simply drops out of the list within about a minute, so “who is on this right now” is always current without any cleanup.
How you use it
Check what needs you. Open the inbox to see your notifications newest first, with the authoritative unread count alongside. Filter by status to separate the unread from the already-seen, or by kind to look only at, say, gates pending or SLA breaches.
Clear an item. Open a notification, deal with the gate, review, or matter it points at, then mark it read. Archive the ones you are done with so they drop out of the working view. The unread dot in the shell follows along automatically.
Tune your notifications. Open notification preferences to see the full taxonomy of kinds rendered straight from the kernel, with the locked oversight kinds shown as locked. Mute the kinds you do not want surfaced; the locked ones stay on by design, and the underlying rows, SLA timing, and escalation routing keep running regardless of what you mute.
Follow the work you care about. Add a watch on a matter or document you want to track, and changes to it will reach your inbox. List your watches to see everything you are subscribed to, and remove a watch when you no longer need it. Star the objects you return to often as favourites, and list your follows and favourites to find them again.
See who else is on it. On a matter or document, the presence list shows the people live on it right now. Your own heartbeat keeps you in that list while you are looking, and you fall out of it shortly after you leave.
The kernel verbs behind it
Everything above runs through the kernel’s one front door: each call is permission-checked and audited before it executes. These are the key verbs.
The inbox:
notify.send- route a signal to a recipient’s inbox; the kind must be in the fixed taxonomy, and a re-fire for the same recipient, kind, and subject dedups to the existing row.notify.taxonomy- the fixed notification-kind taxonomy plus per-kind lockability, the one source the mute matrix renders from.inbox.list- your own notifications, optionally filtered by status or kind, with the authoritative unread count.inbox.get- read one of your own notifications in detail.inbox.mark- flip your own notification unread to read, or archive it to dismiss it.
Watching and following:
watch.add- subscribe yourself to an object’s change signals (notify-only, zero access).watch.list- read your own watches, optionally filtered by object type.watch.remove- unsubscribe yourself from an object.engagement.follow- follow an object as a durable engagement marker.engagement.favourite- star an object as a favourite.engagement.view- record that you have viewed an object, as a last-seen marker.engagement.list- your own durable engagements: follows and favourites.
Live presence:
engagement.presence.heartbeat- publish your live cursor on an object with a time-to-live.engagement.presence.list- read who is live on an object right now, expired heartbeats already filtered out.
The mute preferences you author are stored per user through the pref verb reference, which the kernel checks against the locked taxonomy before it lets you suppress a kind.