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.

Anatomy ae-mail
01 Service
the main runtime, reached only over a private binding, never the open internet
02 Receiver
a small second runtime that takes delivery of inbound mail
03 Store
one operational store both runtimes share
04 Mailbox actors
per-mailbox actors that hold a mailbox's mail and run its agent reflex
05 Modules
hexagonal: contacts, segments, events, sending, inbound triage, the inbox, publishing
06 Send path
resolve a sending identity, screen against the consent store, dispatch through a provider adapter
07 Providers
one live, one dormant, both behind a single interface

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.

Out, and back in ae-mail
A send, or an arrival a send from the consumer, or a message arriving back
Outbound · the consumer's send
01 Compose
transactional, broadcast, or an agent reply
02 Identity
resolve an approved sending identity, server-side
03 Screen
campaign recipients checked against the consent store
04 Dispatch
through a provider adapter, recorded as accepted vs suppressed
Inbound · the routed path
01 Spam screen
reject high-confidence, quarantine the borderline
02 Route
dispatched by the address it arrived at
03 File
clean mail filed, projected into contact and event history
Delivered, or filed sent and recorded, or routed into the right mailbox

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.

What it gives you ae-mail
Sending
Transactional, broadcast, and agent-reply, one call.
Triage
Inbound spam-screened, then routed.
Agentic inbox
An agent drafts; only an approved draft sends.
Suppression
Stops on bounces; consent and unsubscribe kept.
Audience
Contacts, segments, and event history.
Opaque
Publishers and audiences by id, never the store.
Sending identity
Resolved server-side, never chosen by the caller.

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.

The gate ae-mail
Without it
An unsupervised agent sends the wrong thing to a customer, on its own authority.
With ae-mail
A human approves through a seam the agent cannot reach; only then is an approved draft claimed and dispatched, at most once.
work