Skip to content
Hussein Jarrar edited this page Sep 12, 2026 · 2 revisions

v0.29.0

7 changes · 3 Bugfixes, 4 New Features.

Bugfix

  • RADD-970 Finish the env→row split: the poller gate, the ack sender, and one definition of our own addresses
    RADD-958 moved mail config into rows but three seams still read the environment:
    109c8f84
  • RADD-971 Two of the nine mute checkboxes do nothing: AUTOMATION and PAGE_UPDATED bypass muted_types
    muted_types is enforced in exactly one place — notify/consumer.py:361, inside the event-consumer path. The two notification types that are created by DIRECT service.create_notification calls skip it entirely:
    c978d168
  • RADD-965 RADD_SMTP_FROM is documented everywhere and read nowhere — outbound mail says radd@localhost
    The settings field is smtp_from_address, so pydantic-settings reads RADD_SMTP_FROM_ADDRESS. Every document and the live deployment set RADD_SMTP_FROM — which nothing reads. The field silently kept its default, so for months outbound mail (notify digests, CSAT, canned send_email) went out as Radd… [b8f497ef`](https://git.radd-hq.com/Radd/Radd/commit/b8f497ef)

New Feature

  • RADD-686 Per-user notification & email preferences
    Notification fan-out (spec 26) is instance-shaped on the email side: notification_prefs lets a user mute a type's inbox row and toggle the digest, but there is no per-type choice of CHANNEL. RADD-968 built the delivery path (notify/mailer.py mails notification rows immediately for DEFAULT_IMMEDIATE_EMAIL_TYPES =… notify · [cac3ca7d`](https://git.radd-hq.com/Radd/Radd/commit/cac3ca7d)
  • RADD-969 Gmail and Outlook out of the box: sender/source presets on the spec-110 pattern, and Settings → Email catches up to Sign-in
    MailSenderKind has exactly one member (SMTP); the add-sender form hardcodes kind: "smtp" as const and prefills smtp.migadu.com / imap.migadu.com — this instance's own relay baked into the product's React state. An admin wiring a Gmail or Hotmail/Outlook mailbox must know four hostnames, two ports and a TLS…
    c69afb2a
  • RADD-968 One fan-out: notify decides who hears, mailintake carries the mail — permission-gated, team-participant-complete
    Two recipient models decide email, and neither is the one deciding the inbox. mailintake/outbound.py:_recipients mails notify.watcher_ids minus the author on every public comment — while the inbox fans out over watchers ∪ participant-team members THROUGH notify/consumer._allowed (item.read + relation scope +…
    141a3d1f
  • RADD-967 One rendering layer: every product email says who did what, quotes it, and links the issue — in text and HTML
    An outbound comment reply's body is await comments.comment_body(...) verbatim (mailintake/outbound.py:172-177) — raw markdown, no author name (the comment.created payload's author ref is never read), no issue key/title in the body, no link (settings.app_base_url appears nowhere in mailintake), no footer…
    81ac607c

Changes from v0.28.0 to v0.29.0.


Mirrored from project.radd-hq.com on 2026-09-12. Documentation is written there; this copy is regenerated by scripts/publish_wiki.py and hand edits do not survive it.

Clone this wiki locally