Nightly retention sweep (Oban Cron). One bulk :prune across all sites keeps the table small no
matter how many notifications are produced — read rows are dropped after notify.retention_read_days
and everything after the hard cap notify.retention_max_days (both admin-editable Settings).
Runs unscoped (tenant: nil on a global? true resource → all sites) with authorize?: false,
streaming so a huge backlog prunes in constant memory. A single bulk sweep is used instead of
per-record ash_oban triggers (house style).