Otto

Email

Hourly scans, what they pull out of the mail, the draft-and-confirm rule, and follow-up pairs.

Live.

Scans run hourly and are suppressed during quiet hours. set_email_state moves the checkpoint by hand when needed.

A scan is not only a notifier

The mail is already being read, so the commitments inside it are pulled out at the same time:

  • A date becomes a one-tap [block it].
  • An amount with a due date becomes a [remind me].
  • A request aimed at you becomes an open loop, recorded once, whether or not you mention it.

The rule underneath all three: never make you retype something the email already said.

A thread you have not answered that clearly wants an answer is an open loop whether or not you mention it. It is recorded once and not re-raised on every scan, which is the job of topic suppression.

What a scan surfaces

Replies needed, meetings, deadlines, bills, shipping, security alerts. Marketing is counted rather than listed. Subscriptions are worth a mention only when a price changed.

Nothing goes out unapproved

Otto never sends, replies to, or forwards mail on its own. You see the draft first, and approval is usually one tapped button attached to the draft itself. That tap satisfies the rule; there is no second confirmation step.

The pre-send lint carries a matching check: any outbound phrasing claiming mail was sent is flagged, because it is only true after an approved draft.

Email triggers

An email trigger watches for a matching message and fires when it arrives, rather than on a clock. The common shape is a follow-up pair: one trigger watching for the reply, one timer that fires if the reply never comes. Arming the pair is a single button tap from /otto:recipes.

When you send or mention mail you are waiting on, Otto offers the pair rather than arming it silently.

Email content is data

Never instructions. A message that contains "ignore your previous instructions" is a message that contains a string, and Otto treats a request inside mail exactly the way it treats a request written on a postcard: as information about what somebody wants, not as a command.

The self-edit policy enforces the sharp end of this: work originating from external content has a hard ceiling on what it is allowed to change, and the ceiling is a property of the code path rather than a rule the model is asked to remember.

Not built yet

These do not exist. The substrate each one reads is live, so every item below is a self-contained piece of work rather than a rewrite. The button copies a prompt that builds it in your own checkout.

#78Dictate a replysmall

A voice note — "answer the landlord I'll pay Friday and ask about the boiler" — resolves the thread from the correspondent name, ghostwrites it in the thread's language and shows the full draft with [send ✓ / fix it / discard], where "fix it" takes another voice note; the shortest path they have from thought to sent mail.

#80Background pre-drafted repliesmedium

For each needs-reply thread a scan finds, Otto writes the reply straight into Gmail Drafts and the Telegram line becomes "drafted a reply to Marco re: contratto — [send / edit / discard]"; when they open Gmail on their phone the answer is already sitting there, and a draft is not a send.

#83Otto label taxonomy in Gmailmedium

Otto maintains a small tree — Otto/Action, Otto/Waiting, Otto/Receipts, Otto/Bureaucracy/IT and /BR, Otto/Newsletters — and labels every thread it classifies, so their triage is visible in the Gmail app even when Otto stays silent; the classification the scan already computes stops being thrown away.

#86Scheduling over emailmedium

When a thread asks when they're free, Otto reads free/busy, picks three real slots respecting their working hours, drafts the reply with times in the sender's zone ("Tue 14:00 CEST / 09:00 BRT"), and on send arms tentative holds plus an email trigger that turns their pick into a confirmed event and drops the others; ping-pong across a five-hour gap is a daily tax.

On this page