Alerts from templates, and every alert as a sentence #45

Merged
jcoffey-dev merged 1 commits from feature/alert-templates into main 2026-09-28 22:01:41 +00:00
Owner

Fourth second-wave item from the settings-reorg spec. Based on main; independent of the other open PRs.

Monitoring › Alerts needed a metrics expression to do anything, and its list shows the condition as "-". The page now opens with every alert as a sentence (When more than 500 messages are waiting to be delivered, email [email protected].) and five templates. Pick one, set its number if it has one, say who to email (and optionally raise an event for webhooks), and it's added.

Template Condition Behaviour
The queue is backing up metric('queue.count') > N (default 500) gauge: fires again after it drains
Memory is running high metric('server.memory') > N MB (default 2048) gauge
Certificate renewal failed acme.order-invalid + acme.auth-error + acme.error > 0 counter: first time since start
The data store reported an error data-corruption + each backend's error counter > 0 counter
Publishing DNS records failed dns.record-creation-failed + dns.record-deletion-failed > 0 counter

Why no rate templates:

  • Per the monitoring spec (MON-25/26), counters in a condition are totals since the process started, and an alert fires when its condition turns true.
  • So a counter alert fires the first time and not again until a restart. That's right for rare, serious events, but "delivery failures per hour" can't be written honestly.
  • The spec's "certificate expiring within 14 days" idea has no metric behind it, so it's "renewal failed" instead.
  • The page explains both behaviours in one line.

Email defaults: to the signed-in address if it's one, from postmaster@<default domain>, and each template's own subject and body (with %{queue.count}%-style placeholders, MON-27). Existing template alerts are recognised ("In use"). An empty page says nothing tells you when something goes wrong.

Checked: unit tests for the conditions, recognising them back, and the sentences (428 total), plus typecheck, lint and build. In Chrome against a local server, the queue and storage templates were added (the storage one with an event). Read back over JMAP both conditions were as written; the server rejects unknown metric names on save (MON-26), so accepting them confirms the names. No config warnings, and neither fired.

English only: about 25 UI strings plus the five templates' titles, subjects and bodies.

Fourth second-wave item from the settings-reorg spec. Based on main; independent of the other open PRs. Monitoring › Alerts needed a metrics expression to do anything, and its list shows the condition as "-". The page now opens with every alert as a sentence (*When more than 500 messages are waiting to be delivered, email [email protected].*) and five templates. Pick one, set its number if it has one, say who to email (and optionally raise an event for webhooks), and it's added. | Template | Condition | Behaviour | |---|---|---| | The queue is backing up | `metric('queue.count') > N` (default 500) | gauge: fires again after it drains | | Memory is running high | `metric('server.memory') > N MB` (default 2048) | gauge | | Certificate renewal failed | `acme.order-invalid + acme.auth-error + acme.error > 0` | counter: first time since start | | The data store reported an error | data-corruption + each backend's error counter `> 0` | counter | | Publishing DNS records failed | `dns.record-creation-failed + dns.record-deletion-failed > 0` | counter | **Why no rate templates:** - Per the monitoring spec (MON-25/26), counters in a condition are totals since the process started, and an alert fires when its condition turns true. - So a counter alert fires the first time and not again until a restart. That's right for rare, serious events, but "delivery failures per hour" can't be written honestly. - The spec's "certificate expiring within 14 days" idea has no metric behind it, so it's "renewal failed" instead. - The page explains both behaviours in one line. Email defaults: to the signed-in address if it's one, from `postmaster@<default domain>`, and each template's own subject and body (with `%{queue.count}%`-style placeholders, MON-27). Existing template alerts are recognised ("In use"). An empty page says *nothing tells you when something goes wrong*. **Checked:** unit tests for the conditions, recognising them back, and the sentences (428 total), plus typecheck, lint and build. In Chrome against a local server, the queue and storage templates were added (the storage one with an event). Read back over JMAP both conditions were as written; the server rejects unknown metric names on save (MON-26), so accepting them confirms the names. No config warnings, and neither fired. English only: about 25 UI strings plus the five templates' titles, subjects and bodies.
jcoffey-dev added 6 commits 2026-09-28 21:57:20 +00:00
Guided setup: connect a sign-in directory
ci / build (pull_request) Successful in 2m4s
ci / publish (pull_request) Skipped
0c64ff214b
Directories and Authentication offer a guide ("Guided or manual?" each
time) that:

- starts from Active Directory, OpenLDAP, FreeIPA, Keycloak, Authentik
  or another OpenID Connect provider, with filters and attributes set for
  that directory and example connection values;
- saves the directory, which changes nothing while no domain uses it,
  and tests a real person against it with the server's directory test:
  found or not (with aliases and groups), and whether a password signs
  in, a wrong password told apart from a broken connection. The guide
  won't go on until a person is found and, if given, the password works;
- then asks which domains sign in through it, with each domain's account
  count, and the server default as a separate switch. Choosing the
  domain you sign in on, or the default, needs an explicit "I've checked
  I can still sign in";
- switches the chosen domains over, putting them back if making it the
  default is refused.

Needs inbuxa-server's POST /api/directory/test.
Sender checks as a level: Relaxed, Recommended or Strict
ci / build (pull_request) Successful in 1m38s
ci / publish (pull_request) Skipped
86ae2c6672
Mail flow › Receiving › Sender checks opens with one choice instead of
six strategy fields, and a table of what each level does to mail that
fails. From the SMTP code:

- Relaxed (the stock settings): SPF, DKIM, DMARC and reverse DNS are
  checked on port 25 and scored by the spam filter; nothing is refused.
- Recommended: also refuses mail that fails DMARC for a domain that
  publishes p=reject, and checks ARC.
- Strict: also refuses senders that fail reverse DNS or SPF on MAIL
  FROM (including senders with none), and broken ARC chains. It warns
  that some real mail from small or badly set-up servers will bounce.

No level refuses unsigned mail (strict DKIM, which RFC 6376 advises
against). Checks stay on port 25, like the stock settings. Values set by
hand show as "Set by hand below", and applying a level then says it
replaces them. The form reloads after a level is applied; DKIM signing
isn't touched.
Limits as sentences, with presets for who uses the server
ci / build (pull_request) Successful in 2m4s
ci / publish (pull_request) Skipped
8fdae4a32b
A stock server has no rate limits: one stolen password can send without
end. A guide ("Guided or manual?" each time) asks who uses the server
(me and my family, a company or school, open to the public) and offers
five rules as sentences with numbers you can change:

- each outside server may connect N times a minute on port 25;
- each signed-in person may send N messages an hour;
- each signed-in person may address N recipients an hour in total
  (keyed by account alone; the condition reads rcpt, so the server
  checks it at RCPT TO);
- at most N deliveries a minute to any one receiving server;
- each sender may have at most N messages waiting.

Rules it writes are marked "Preset:" so running it again edits them; it
never touches rules made by hand. Above the incoming, outgoing and quota
lists, every rule now reads as a sentence, and an empty list says that
nothing is limited.
Retention on one page, as sentences
ci / build (pull_request) Successful in 2m2s
ci / publish (pull_request) Skipped
7b65b8eb34
Every "how long is this kept" setting was spread over four pages of
fields named after the config, plus log files on the Hardening page.
Each retention page now opens with all of them as sentences:

- in people's mailboxes: empty Trash and Junk after, clear handled
  calendar invitations after, forget share notices after, forget the
  sending status of sent mail after;
- getting deleted things back: deleted items and deleted accounts;
- the server's own records: delivery history, charts' history, DMARC
  and TLS reports from other servers, and old log files.

Each has a number and unit (or its own never / off / forever), its
default beneath, and an unsaved mark until the changes are saved
together. It says that mail under a legal hold is kept whatever these
say. The page's own settings (schedules and the like) are folded
underneath and reload after a save.
Reports in a few sentences, on every report page
ci / build (pull_request) Successful in 1m29s
ci / publish (pull_request) Skipped
c12b117fe7
Six report pages were mostly From names, subjects and signing domains;
whether reports go out at all was a frequency or rate expression inside
them. Each report page now opens with:

- tell other domains how their mail fared here (DMARC summaries):
  every hour, once a day, once a week or never;
- tell them whether their mail reached us encrypted (TLS summaries):
  the same;
- report each message that fails their checks (DMARC, DKIM and SPF
  failure reports together): on, at most once a day per address, or off,
  noting they carry message headers and that most large providers don't
  send them. Off is a value that isn't a rate, which sends none;
- send them, and bounce messages, from addresses at the default domain
  or a chosen one;
- read reports sent to postmaster@* (or other addresses) and show them
  under Management › Reports, and whether to still deliver them.

A value set by a rule with conditions is shown as such and left to its
page. The page's own settings are folded underneath and reload after a
save.
Alerts from templates, and every alert as a sentence
ci / build (pull_request) Successful in 1m59s
ci / publish (pull_request) Skipped
db8b0b1d26
Monitoring › Alerts needed a metrics expression to do anything. It now
opens with each alert in words ("When more than 500 messages are waiting
to be delivered, email [email protected].") and five templates: pick one,
set the number if it has one, say who to email, done.

- The queue is backing up (queue.count, a gauge: re-arms when it
  drains).
- Memory is running high (server.memory in MB, a gauge).
- Certificate renewal failed, the data store reported an error, and
  publishing DNS records failed: counters, which are totals since the
  server started, so each fires the first time and again only after a
  restart. The page says so.

No template watches a rate: counters in a condition are totals since
start, so "failures per hour" can't be written honestly. Templates are
recognised again on the page ("In use"), and an empty page says that
nothing will tell you when something goes wrong.
jcoffey-dev force-pushed feature/alert-templates from 0e8afaf806 to db8b0b1d26 2026-09-28 21:57:20 +00:00 Compare
jcoffey-dev merged commit 0609dc9762 into main 2026-09-28 22:01:41 +00:00
jcoffey-dev deleted branch feature/alert-templates 2026-09-28 22:01:41 +00:00
Sign in to join this conversation.