The inbox that sorts itself. The reply that writes its first draft.
A mid-sized logistics company ran its entire inbound communication through one shared email address. Quotes, complaints, invoices, driver applications, partnership requests, all of it landed in the same place, up to 100 messages a day. One person forwarded everything by hand. We replaced the forwarding, not the person.
Hermes runtime IMAP / SMTP Supabase Draft-first delivery Human in the loop
Every inbound email arrived at a single company address. An office manager opened each one, decided which department it belonged to, forwarded it, and moved on. On a slow day this worked. On a busy day, messages waited hours before reaching the right desk. Some waited until the next morning. A quote request that sits overnight is a quote request answered by a competitor.
The forwarding itself was only half the cost. The person receiving the forwarded email still had to read it from scratch, figure out the context, and compose a reply from a blank page. The company was paying twice for every email: once to sort it, once to understand it.
The brief was narrow and honest: do not let the agent talk to our customers. Sort the mail, prepare the ground, and let our people send the answer.
> ingest
The agent connects to the shared inbox over IMAP and picks up every new message, including attachments.
> read
It reads the full email, not just the subject line. Attachments are parsed when they carry the actual request, which in logistics is often.
> classify
The message is matched against a routing contract covering six departments: sales, dispatch, accounting, HR, claims, and general support. Every classification carries a confidence score.
> route
High-confidence messages are forwarded to the department inbox with a structured summary header: who is writing, what they want, what deadline is implied.
> draft
The agent composes a first draft of the reply in the company's tone and saves it alongside the forwarded message. It never sends. Sending is a human act.
> fallback
Anything below the confidence threshold lands in a human triage queue instead of being guessed. A wrong guess costs more than a short wait.
Layer I · Visual Architecture
One diagram the client signed off on before any code existed: inbox in, six departments out, one fallback queue, one audit log. If it is not on the diagram, the agent does not do it.
Layer II · Contracts
The routing taxonomy is a written contract, co-designed with the client's department heads. Each department defined what belongs to it and, just as important, what does not. Ambiguity was resolved in a document, not in production.
Layer III · Technical Diagrams
Message flow, retry behavior, dedup logic, and the confidence threshold mechanics, specified before implementation. The fallback queue is not an afterthought, it is drawn on the same page as the happy path.
Layer IV · Implementation
Hermes runtime on a dedicated isolated instance. IMAP polling with queue persistence, so a restart never loses a message. Supabase holds the audit log and routing history.
runtime Hermes mail IMAP / SMTP, shared inbox + 6 department inboxes state Supabase (audit log, routing history, dedup index) delivery forward + draft, never auto-send oversight human triage queue for low-confidence messages
Misrouting
A confidence threshold splits traffic: certain messages route automatically, uncertain ones wait for a human. The threshold was tuned on the client's real historical mail, not on synthetic examples.
Mixed-topic emails
One message asking about an invoice and a new shipment routes to the primary department and flags the secondary one. Nothing is silently dropped.
Duplicate processing
Dedup by Message-ID. A customer resending the same email out of impatience does not create two tickets in two departments.
Injection through email content
Inbound email is untrusted input. The agent treats message text as data, never as instructions, and since it cannot send or delete, the blast radius of a malicious email is a badly sorted message, caught by a human.
Outages
The queue is persistent. If the instance restarts, processing resumes from the last confirmed message. No email is lost between ingestion and routing.
~100
Inbound emails on peak days
2,400+
Messages routed per month
94%
Routing precision on automatically routed mail
< 5 min
From arrival to the right desk, previously hours
7 in 10
Drafts sent with only light edits
Figures from the first three months in production, measured against the client's own routing log.
Draft-not-send was the trust unlock. The client did not want an agent talking to customers, and they were right not to. The moment the team understood that every outbound word still passed through human hands, resistance disappeared. Autonomy is not the product. Removed friction is.
The taxonomy is the project. The model was the easy part. The real work was sitting with department heads and writing down where sales ends and dispatch begins. Companies rarely have this written anywhere, it lives in one person's head. Now it lives in a contract, and the agent enforces it consistently at 3 AM as well as at 3 PM.
The office manager did not lose a job. They stopped being a human router and went back to the work the routing was crowding out. The queue they used to manage now manages itself, and they audit it instead.
Drowning in a shared inbox?
> ../book_a_call.sh