Two failure modes that should never share a codebase.
Sending and audience logic used to live inside the app that wrote and styled the content, two concerns knotted into one. The failure modes do not match. A content bug is cosmetic. A delivery bug marks a domain as spam, mails someone who asked to stop, or lets an unsupervised agent send the wrong thing to a customer.
ae-mail is a single TypeScript codebase that carves delivery, triage, and the audience into their own platform behind a hard boundary, with a human gate on anything an agent might send. The consuming app builds and renders content; ae-mail owns how it leaves and to whom it must not. The two never blur.
Two runtimes, one shared store, per-mailbox actors.
One main service the consumer calls over a private binding, and a small receiver for inbound mail. Each feature is a hexagonal module that keeps pure rules apart from the parts that touch the store, the provider, or storage.
One platform, two directions. Out, and back in.
A send from the consumer resolves an identity and screens its audience before it leaves. A message arriving back is screened for spam, then routed by the address it arrived at, and projected into the contact's history.
Delivery owned, content delegated.
The consumer references publishers and audiences by opaque reference and hands over already-rendered content; ae-mail decides everything about how a message goes out, and to whom it must not.
The agent drafts. A human sends. Always.
For the support route, an agent drafts a reply the moment a customer email lands, but that draft cannot leave on its own. Approval lives on a seam the agent cannot reach.