Phase (b) of docs/DESIGN.md: HTTP JSON and MIME transports over
java.net.http with fixed HTTPS endpoints (Mailgun US and EU), error
mapping to permanent, transient (with Retry-After) and provider-level
failures, tracking flags and message streams, per-kind validation and
env-name allowlists, the Gmail SMTP preset, and docs/PROVIDERS.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- email.send no longer implies email.view.
- Provider-level failures (missing or refused credentials, SES account
errors) keep messages waiting without spending their retry budget and
mark the provider unhealthy at once, instead of dead-lettering.
- Unbuildable messages dead-letter at once.
- SMTP sign-in over a plaintext connection is refused (loopback or an
explicit flag excepted).
- One failing message or alert sink no longer stops the batch.
- CR/LF refused in provider sender fields and in MIME headers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Phase (a) part 1 of docs/DESIGN.md: the email_ tables (provider,
message, attempt, template, version, brand, suppression) with Postgres
DDL; provider rows with env-var-name credentials; EmailService with
idempotency keys, suppression and same-transaction enqueue; the
dispatcher with unique-attempt claims, leases, backoff, dead letters,
rate limits and provider health; SMTP (jakarta.mail with auth, TLS and
timeouts) and SES (AWS SDK v2 sesv2 raw) transports; the QBIT_EMAIL
core messaging provider; Resend, Cancel, Send Now and Send Test Email
record actions; scheduled dispatch, maintenance and retention.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>