You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Decision #11 (resolved in #22) authorizes the email-purpose catalog. Recipients control optional
mail through the existing account-settings preference mechanism; this issue extends that mechanism
and the Relay delivery checks rather than introducing a second preference system.
Product contract
Preference categories
Event email is optional and applies only to a recipient registered for the relevant event. The
recipient may opt out of all event mail, including verification, confirmation, cancellation,
reschedule, reminder, and other event-lifecycle messages. Event preference is separate from
newsletter/marketing preference.
Marketing/newsletter is a separate optional category. New member/account signup defaults it on,
but an unverified new account is not a newsletter recipient. The recipient can unsubscribe later.
Slack access is a one-time requested-service message, not a recurring preference category. It has
no preference toggle and is not sent again automatically. Account verification and password
recovery are also non-optional security messages.
Audiences and onboarding
A new account receives email verification first. After successful verification, it receives one
Slack join-link email, and the current link is also available in the authenticated member area.
Legacy/imported contacts bypass the new-account verification-to-Slack sequence and do not receive
an automatic Slack message merely because they were imported.
Newsletter delivery targets verified contacts plus the explicit legacy/imported audience, which is
treated as assumed verified for newsletter delivery. A new account must verify before entering the
verified audience.
An identifiable logged-in interaction or a recipient-specific newsletter-link interaction may
move a legacy contact from legacy to verified. This is not a newsletter delivery prerequisite
and does not trigger another email. A bare anonymous visit does not identify a contact and does
not change status.
Mailchimp reconciliation
Mailchimp is authoritative for legacy marketing subscription state. Provide two separate,
idempotent import operations:
subscribed list: turn the matched legacy marketing preference on;
unsubscribed list: turn the matched marketing preference off.
The operations affect only the marketing/newsletter preference. A contact absent from both lists
keeps the current platform preference. The supported input lists are assumed clean and mutually
exclusive; overlap precedence is out of scope.
Unsubscribe and link safety
A visible body/footer unsubscribe link opens the website preference page. The recipient unticks
unwanted categories and submits; the initial GET is non-mutating.
A supported Gmail/email-header one-click action may immediately and idempotently disable only the
category represented by that message, without changing unrelated categories.
Preference and newsletter-attribution links use opaque, recipient- and purpose-scoped, expiring,
replay-safe tokens. Raw email addresses never appear in URLs or logs. A newsletter token is for
recipient attribution and legacy-status promotion, not an additional verification gate.
Ask
Extend the existing preference-toggle mechanism and shared application services to add event and
marketing/newsletter categories, enforce them before Relay submission, support the preference-center
unsubscribe flow plus the email-header one-click path, and add the two Mailchimp legacy preference
imports. Do not add a recurring Slack toggle or a separate preference implementation.
Acceptance criteria
Existing account settings exposes event and marketing/newsletter preferences without creating
a parallel toggle system; existing course categories remain unchanged.
Event mail is sent only to an active registrant for the relevant event and only while the
event preference is enabled. Opting out suppresses every event-lifecycle message.
Marketing/newsletter sends are made only to verified contacts and the explicit legacy audience;
unverified new accounts are excluded.
Preference state is enforced before Relay submission, with idempotent suppression and no
changes to unrelated categories.
A body/footer unsubscribe link opens the preference page, where the recipient can untick
categories and submit; the initial GET does not mutate state.
The supported email-header one-click action disables only the represented optional category,
immediately and idempotently.
New signup sends verification before the one-time Slack join-link delivery; the link is also
available in the authenticated member area, and retries do not create automatic duplicates.
Legacy/imported contacts bypass the new-signup sequence; identifiable account/newsletter
interactions may promote legacy to verified, while anonymous visits do not.
Subscribed and unsubscribed Mailchimp imports independently turn the legacy marketing
preference on/off; absent contacts preserve the current platform preference. List overlap is
outside the supported input contract.
Preference/attribution tokens are opaque, scoped, expiring, replay-safe, redacted, and never
expose raw email addresses in URLs or logs.
All email mutations use the existing application services, one durable EmailDelivery intent
and after-commit job, Relay routing, and the established idempotency/reconciliation model.
Dependencies
Depends on #22 (resolved). Coordinates with #21/#50 for Relay purpose/template identifiers and with #225 for the shared preference-center surface (GA4 remains a separate purpose).
Parent decision: #22
Related: #21, #50, #225
Context
Decision #11 (resolved in #22) authorizes the email-purpose catalog. Recipients control optional
mail through the existing account-settings preference mechanism; this issue extends that mechanism
and the Relay delivery checks rather than introducing a second preference system.
Product contract
Preference categories
recipient may opt out of all event mail, including verification, confirmation, cancellation,
reschedule, reminder, and other event-lifecycle messages. Event preference is separate from
newsletter/marketing preference.
but an unverified new account is not a newsletter recipient. The recipient can unsubscribe later.
no preference toggle and is not sent again automatically. Account verification and password
recovery are also non-optional security messages.
Audiences and onboarding
Slack join-link email, and the current link is also available in the authenticated member area.
an automatic Slack message merely because they were imported.
treated as assumed verified for newsletter delivery. A new account must verify before entering the
verified audience.
move a legacy contact from
legacytoverified. This is not a newsletter delivery prerequisiteand does not trigger another email. A bare anonymous visit does not identify a contact and does
not change status.
Mailchimp reconciliation
Mailchimp is authoritative for legacy marketing subscription state. Provide two separate,
idempotent import operations:
The operations affect only the marketing/newsletter preference. A contact absent from both lists
keeps the current platform preference. The supported input lists are assumed clean and mutually
exclusive; overlap precedence is out of scope.
Unsubscribe and link safety
unwanted categories and submits; the initial GET is non-mutating.
category represented by that message, without changing unrelated categories.
replay-safe tokens. Raw email addresses never appear in URLs or logs. A newsletter token is for
recipient attribution and legacy-status promotion, not an additional verification gate.
Ask
Extend the existing preference-toggle mechanism and shared application services to add event and
marketing/newsletter categories, enforce them before Relay submission, support the preference-center
unsubscribe flow plus the email-header one-click path, and add the two Mailchimp legacy preference
imports. Do not add a recurring Slack toggle or a separate preference implementation.
Acceptance criteria
a parallel toggle system; existing course categories remain unchanged.
event preference is enabled. Opting out suppresses every event-lifecycle message.
unverified new accounts are excluded.
changes to unrelated categories.
categories and submit; the initial GET does not mutate state.
immediately and idempotently.
available in the authenticated member area, and retries do not create automatic duplicates.
interactions may promote
legacytoverified, while anonymous visits do not.preference on/off; absent contacts preserve the current platform preference. List overlap is
outside the supported input contract.
expose raw email addresses in URLs or logs.
EmailDeliveryintentand after-commit job, Relay routing, and the established idempotency/reconciliation model.
Dependencies
Depends on #22 (resolved). Coordinates with #21/#50 for Relay purpose/template identifiers and with
#225 for the shared preference-center surface (GA4 remains a separate purpose).