Underthe hood.
Six gates, and none of them ask the model for permission.
Most of what makes Surve safe is not the model. It is the code around the model — checks that run before it is called, after it has answered, and that an email cannot argue with. This page is what is actually in there, including the parts that are not finished.
What happens to
a message.
Every message goes the same way round. It runs on a five-minute timer, or within seconds when the mail provider can push.
It does not trust the flag
Surve keeps its own read cursor rather than relying on whether a message is marked unread. Mail you already opened on your phone still gets handled.
The model never writes the whole email
It supplies the answer. The greeting, the sign-off and the AI disclosure are assembled by code, so the shape of a reply is not something a message can talk it out of.
Everything becomes a ticket
Replied, filed or held — there is a record either way, so nothing disappears silently.
Six gates, strongest
first.
They are independent. A message has to get past all six, and no single one of them is the thing holding the line.
Prompt injection
The raw email is scanned before any model call. The text is folded first — Cyrillic lookalikes mapped back to Latin, spaced-out letters collapsed — so r e f u n d and a Cyrillic е do not slip through. On a hit the model is never invoked at all: a fixed safe reply is drafted, not sent. That last detail was a fix — auto-sending the safe reply had turned the guard itself into a way to make Surve send something.
Prompt hygiene
Quoted history is cut, because it is the classic carrier. What remains is wrapped in a delimiter generated fresh for every call — UNTRUSTED-<16 hex> — which the sender cannot guess and therefore cannot close.
Money
A scan of the raw email that can only raise sensitivity. There is deliberately no argument, from any input, that lowers it. Money, legal, GDPR, safeguarding and complaints get a holding acknowledgement and a ticket, every time. You can add your own subjects to the list; you cannot remove the built-in ones.
Three kill switches, all fail-closed
An environment variable, a file on disk that survives a reboot, and a flag in the database. Checked per message, not per run, so stopping it mid-cycle stops the very next email. If the check itself errors it reports failed-closed and holds. Resume refuses to lie to you — it tells you if another switch is still down.
Rate limits
Per hour, per domain, per sender, per conversation, plus a cooling-off period and a ceiling at 60% of your own provider's daily allowance — so Surve can never spend your whole send quota. The per-conversation limit is keyed on the counterparty and subject rather than the threading headers, because a loop is precisely the case where those headers go missing.
The outgoing filter
The last gate reads the assembled reply, not the model's output — including the HTML part, which is where the first version of this was blind. Any figure, any promise of money, any refund or waiver and it does not go out. Links to anywhere but your own domains are stripped, so a support address cannot be turned into a phishing relay.
Confidence is self-reported.
“confidence is SELF-REPORTED by the model. A jailbroken model returns 0.99. It is a quality dial for ‘send now or hold for review’ and must never be the only thing standing between an injection and a customer.”
— the comment at the top of guard.py
Plenty of tools gate an automatic send on a confidence score. A score is a useful dial and a terrible guard, because the thing reporting it is the thing you are trying to check. Surve shows you the number, and does not rely on it: every gate above works whether the model says 0.4 or 0.99.
Swappable where it
matters.
Python, and very little else
Five dependencies. The HTTP server, IMAP, SMTP, the database layer, password hashing and webhook signature checking are all standard library. Fewer moving parts is a security property, not an aesthetic one.
Locked down at the OS
It runs as its own user with a read-only filesystem, no capabilities, no ability to make memory both writable and executable, and a syscall allow-list. If it were ever compromised, there is very little for it to do.
Mailbox passwords are sealed before they touch disk
Sealed with AES-256-GCM, and the key never lives in the database beside them. With no key configured, Surve refuses to store the credential at all rather than writing one in the clear. Note the narrowness of that claim: it covers the mailbox password, and not the Gmail OAuth tokens, which are still written as plain files.
What is measurable.
Attachments are never opened. Every reply says it is an AI. There is a test that fails the build if this page ever claims something the code does not do — which is how the list below stays honest.
What isn't finished.
Every company's technical page is a list of what works. This is the rest of it, because you will find out anyway and it is better you find out here.
Gmail OAuth is built but dormant
The connector is written and unit-tested, but the live loop still reads and sends over IMAP with an app password that Surve holds. So we do not say "we never see your password", because today that would not be true.
Microsoft 365 is not supported
Microsoft switched off password access for new tenants, and the Graph connector is not built yet. If you are on Microsoft 365 we cannot help you today, and we will say so rather than take your money.
Card payments are not live
Stripe is integrated in code but not switched on. Invoices are sent for bank transfer in the meantime.
The legal pages have not been reviewed by a lawyer
They are accurate about what the software does — 45-day retention because the purge enforces it, "never moves money" because the code blocks it. They have not been read by someone qualified, and the DPA is a contract.
See it on your own inbox.
The fastest way to judge any of this is to watch it work on your real mail, in draft mode, where it cannot send anything.