Advisories.

Curated intelligence written by a platform admin and published to every subscribed tenant, with an immutability rule that protects the delivery record.

Lifecycle

drafteditablequeuedscheduled_send_atsentimmutablearchivedkept for auditSEND NOWUNSCHEDULEREOPEN (NOT FROM SENT)
Fig. Advisory states. A sent advisory is terminal — it can be archived but never edited.

The states

  • draft — fully editable. Nothing has been delivered.
  • queued — has a scheduled_send_at. Still editable.
  • sent — delivered. Immutable.
  • archived — retired from the active list, retained for audit.

Why sent is immutable

The delivery record has to stay honest

Once an advisory is sent, recipients hold that text. Editing the row afterwards would leave advisory_deliveries pointing at content that was never actually delivered — so the audit trail would claim something untrue.

The server refuses edits and deletes on a sent advisory. The correct move is to archive it and publish a correction, which leaves both the original and the correction in the record.

Fan-out

Sending inserts one delivery row per (tenant, channel) where the tenant's subscription is enabled and the advisory's severity meets their configured minimum. Subscriptions are backfilled with defaults, so a tenant does not have to opt in before it can receive anything.

The portal channel is delivered inline — a notification row is written and the delivery flipped to sent in the same operation. Email and webhook are left pending for the dispatcher.

Every mutation is audited

Create, update, schedule, unschedule, send, reopen, archive and discard each write an audit_log row with the actor, the target and the time. Publishing intelligence to tenants is exactly the class of action that needs provenance.

Scheduling is not yet dispatched

queued does not mean it will send

An advisory can be moved to queued with a scheduled_send_at, and both the workbench and the API will report that time. No worker consumes it. Nothing sends until a human presses send.

This is the one place where the interface currently promises behaviour the backend does not implement. Treat queued as “marked for sending”, not “will send”.

Advisories — OmniIntel docs · OmniIntel