LC-77-REPLY: reply-by-email (depends on per-message notification email surface) #201
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Background
LC-77 v1 (PRs #194-#199) shipped per-room email ingress: an external sender mails
<token>@<ingress-domain>and the message posts to the inbox's room as a synthetic "Email" actor.The brainstorm split LC-77 into two halves: per-room ingress (shipped) and reply-by-email (this ticket). Reply-by-email lets a chat user mail a response to a chat notification email and have it post to chat as that user, not as the synthetic actor.
Reply-by-email was explicitly deferred from v1 because it depends on a surface that doesn't exist yet: per-message notification emails to reply TO. The current outbound mail surfaces (digest, password reset, email verification, login alerts) don't carry a per-message Reply-To that maps back to a chat user + room.
Scope (two stages, in order)
Stage 1: per-message notification email surface
Build the outbound side that reply-by-email replies AGAINST. Likely shape:
/notify/mention(or per-mention email) gated by per-user opt-in (mirror existing email-digest opt-in pattern).Reply-To: <reply-token>@<ingress-domain>where<reply-token>is HMAC-SHA256 of(message_id, user_id, issued_at)keyed byLETS_CHAT_SECRET_KEY. Expiry: 7 days (lean conservative, lengthen on feedback). Token is opaque to the user.Stage 2: reply-by-email ingress
Build the inbound side that consumes those replies:
email_ingress::resolvefor<reply-token>@<ingress-domain>addresses: verify the HMAC, parse(message_id, user_id, issued_at), checkissued_at + EXPIRY > now().routes/room.rs:434-474). The token does NOT carry permission state.routes::room::finalize_message_send(the existing real-user path), NOTfinalize_email_inbox_message_send(that's for the synthetic-actor surface).Auto-Submitted: auto-generatedheader on the notification email to break reciprocal-loop chains.Why this depends on v1
Reply-by-email reuses everything v1 built: the poll loop, the
resolveheader-precedence walk, the failure-log taxonomy, the rate-limit infrastructure, the IMAP transport. The only new pieces are the HMAC token scheme + the per-message notification email + the real-user post path.Anti-scope
AddressNoMatch(the v1 posture).References
docs/email-ingress.md"Not supported" section names this asLC-77-REPLY.crate::email_ingress::resolvefor the v1 resolution surface to extend.