DocsOperateNotifications

Notifications

Three separate mechanisms, for three different jobs.

Mechanism

Subscriptions

Tell my system when something happened

Channels

Tell a person, in the place they already are

Sinks

Put every decision somewhere outside this trust boundary

Subscriptions, signed webhooks

Add one under Settings → Notifications: an endpoint of yours, and the events it should receive. Memnox posts to it as they happen.

json
{
  "url": "https://ops.acme.com/hooks/memnox",
  "events": ["incident.opened", "suggestion.queued"]
}

Two customer-facing events today:

Event

incident.opened

One of the four detectors opens an incident

suggestion.queued

A candidate decision lands in the review queue

Adding an event is additive; renaming one is a breaking change, which is why the list is short and grows slowly.

Verifying a delivery

Each subscription has a shared signing secret, returned once at creation and stored encoded. Deliveries carry an HMAC over the body; verify it with a constant-time comparison before trusting the payload.

ts
const expected = createHmac('sha256', secret).update(rawBody).digest('hex');
if (timingSafeEqual(Buffer.from(expected), Buffer.from(received)) === false) {
  return reply.code(401).send();
}

Verify over the raw bytes, before any JSON parsing. A re-serialized body is a different byte string, and the signature will not match.

Channels, telling a person

Notifications reach people through Slack, Microsoft Teams, or email. Configure them per workspace under Settings → Notifications.

The runtime has its own, independent of the cloud:

bash
memnox serve --approval-webhook https://hooks.slack.com/services/…

A Slack-compatible webhook that announces pending approvals. It is intentionally the lowest-common-denominator format, so anything that accepts a Slack payload works.

Sinks, the copy you cannot rewrite

Sinks deliver every decision to a destination you own.

Type

splunk

Splunk HTTP Event Collector

datadog

Datadog logs intake

ndjson

Newline-delimited JSON to any endpoint

s3

One NDJSON object per batch, partitioned by workspace and day

kafka

One record per decision onto a topic, keyed by workspace

This is the answer to the limit of hash chaining. The chain detects edits to a log you control; a sink writing into a bucket with object lock, or a topic your security team owns, produces a copy nobody administering Memnox can touch.

Console → Settings → Notifications, showing subscriptions and sinks side by side

Console → Settings → Notifications, showing subscriptions and sinks side by side

screenshot slot, save as public/screens/…png and set  src

Subscriptions notify; sinks archive. An organization that needs to prove something later wants at least one sink.

Rate and failure behaviour

Delivery failures are retried with a backoff, then surfaced rather than swallowed. A subscription whose endpoint has been down for a day is listed with its failure count on Settings → Notifications, next to the subscription itself.

Nothing is silently dropped. A notification system you cannot audit is one you cannot rely on, and "we never got the alert" is only answerable if the failed deliveries were kept.