Email Invites Are Mail State Before Calendar State

Email invites are mail state before calendar state

A received calendar invite is first an email with a scheduling payload. Treating it as mail state before calendar state keeps the product slice honest: parse the payload, show what it means, let the recipient answer safely, and stop there until there is a separate validated calendar problem.

The trap is to see .ics and accidentally build a calendar product. That jumps from "make this email understandable" to CalDAV, provider calendar APIs, reminders, free/busy, time-zone history, recurrence expansion, conflict resolution, and calendar UI. Those are real products, not incidental features.

The rule

When a protocol object arrives inside another workflow, make the receiving workflow better first.

For calendar email:

mxr search 'has:calendar newer_than:30d' --format ids
mxr invite show MESSAGE_ID

That gives scheduling context from mail without taking ownership of the user's whole calendar.

Why this generalises

Plenty of apps receive adjacent-domain objects: receipts in email, shipping events in email, identity challenges in chat, workflow approvals in comments. The smallest good feature is usually to make the embedded object legible and actionable where it already showed up.

In mxr

Mxr now handles invite email over iMIP: parse text/calendar and .ics, persist local invite rows, search has:calendar, show invite cards, and send accept/tentative/decline replies through outbound email. It still does not do CalDAV, external calendar APIs, calendar-grid UI, or automatic remote event mutation.

See Calendar Email Support in Mxr.