← al-engr

July 14, 2026

miloh-mail

A Hermes-native system to grok correspondence — not just fetch unread mail. Design locked after a full grill; implementation not started.

Decision: Build greenfield miloh-mail on the M4 Max. SQLite is system of record (metadata + extracted text, forever). v1 is read-only IMAP across four accounts, plus one allowlisted morning digest email. Retire legacy milo-mail after explicit gates; keep milo-email for general send until a later phase.

The gap

Existing tools can list and send mail. They don’t compound into a model of people, threads, commitments, and open loops. “Read my inbox” ≠ “what’s outstanding with X?”

Tonbi’s Masterclass doesn’t ship a dedicated email episode; the pattern is still clear: tools for hands, layered memory for brain, cron for continuity, skills for procedure, quarantine for untrusted text.

What we’re replacing

SystemTodayFate
milo-mailPersonal triage: IMAP → SQLite → classify → Telegram digestsOne-time import, freeze, retire after gates
milo-emailFastmail client for agent identity (send/fetch)Stays until miloh-mail send phase
miloh-mailHermes-owned knowledge + index + digest

Locked architecture

IMAP ×4  (every 15 min)
   → extract text + injection flags + rules
   → SQLite  (~/.hermes/work/miloh-mail/)

Hermes cron  05:00 America/Chicago
   → delta + open loops + project suggestions
   → email digest  (agent From → primary human To)

Hermes chat
   → miloh-mail CLI  (search / loops / dossier)
ChoiceLock
Code / data~/code/miloh-mail · ~/.hermes/work/miloh-mail/
HostM4 Max
StoreSQLite: metadata + extracted body text forever
AttachmentsMetadata only (no bulk download v1)
FoldersINBOX + Archive/All-Mail (deduped) + Sent; no Trash/Spam
History90 days live first, then rate-limited forever backfill
SyncHermes cron every 15 minutes
Write policyStrict read-only IMAP; digest SMTP allowlist only
Agent APICLI + small Python library (no MCP v1)
SecretsVaultwarden source of truth + local secret files
InjectionFlag on ingest; default safe/redacted read path

Accounts (roles)

MailboxRole
Apple (me.com)Primary human; digest destination
GmailHuman secondary
al-engr personalHuman / work-adjacent
milo@ agent identityAgent actor on Sent; digest From

Open loops & dossiers

Open loops: needs-reply · waiting-on-them · commitments (suggest + confirm) · noise ignore (noreply blocklist + editable domains). Noise can still be archived forever; it just doesn’t become a loop.

Dossiers: rules + manual assignment; LLM may suggest on the morning digest only — no silent full auto-file.

Seed projects: nous-hermes, bob-roxy, milo-trials, al-engr, family, finance-personal, legal-admin, travel, shopping-orders, uncategorized.

Human surface: v1 = SQLite + CLI only. Later, gated one-way markdown export into a dedicated Obsidian Mail/dossiers/ tree (generated, do-not-edit, stable slugs). Never Obsidian as co-source of truth. (Opus 4.8 agreed: protect vault trust until dossier quality is proven.)

Morning digest

FieldValue
When05:00 America/Chicago
ChannelEmail only (not Telegram)
From → ToAgent mailbox → Apple primary only
LLMGrok primary, OpenAI subscription fallback (local too flaky for cron)
SMTPNew code in miloh-mail day one (not a thin wrap of legacy mail.py)
Sync pathRules-only — no per-message LLM

Success & retirement gates

Product success without opening Mail.app: answer “what’s open with X?”; actually read the digest most mornings for a week; ≥3 seed projects populated; open loops catch a real drop.

Retire milo-mail when: 7 days stable four-account sync · 5 consecutive useful digests · CLI useful without fallback · import done · explicit go. milo-email remains until send ships.

Build phases

  1. 0 Skeleton — package, schema, secrets layout, seed projects
  2. 1 Sync — four IMAP accounts, extract + flags, 15m cron, 90-day window
  3. 2 Rules / loops / dossiers — blocklist, open loops, assign CLI, import legacy DB
  4. 3 Digest — renderer, Grok/OpenAI, SMTP allowlist, 05:00 CT cron
  5. 4 Hermes skill — documented CLI, chat smokes
  6. 5 Backfill + retire — forever backfill, kill milo-mail crons, optional Obsidian export

Why not just “better IMAP in chat”?

Because forever + open loops + dossiers need a durable index outside any single session. Session search and Honcho can sit on top of digests and summaries later; they are not the archive. Quarantine stays mandatory: email is untrusted content until proven otherwise.

Inspired by Tonbi email→GBrain (pattern only)

After design lock, I watched Tonbi’s Feeding GBrain Your Emails Autonomously with Hermes Agent and the GBrain email-to-brain recipe. No locks changed. The useful doctrine is the same split we already grilled:

Script collects · agent judges · brain remembers. Never both collect and judge in one path. IDs, deep links, timestamps, noise class → code. Who matters, action items, project suggestions → LLM. Hermes cron pre-run scripts exist exactly for that.

Stealmiloh-mail mapping
Deterministic collector15m IMAP → SQLite (rules + injection flags)
Code-generated deep linksNever let the model invent mail URLs
Noise vs review/allowlistArchive forever ≠ promote to open loops / dossiers
Sent mail as negative filterRequired so open loops don’t lie
Verbatim quotes; summary ≠ recordDigest carries short quotes + structure
Silent when emptyNo spam digest on zero delta
Typed write contract for “brains”Future one-way exporters (Obsidian dossiers; optional GBrain-shaped MD)

Not adopting for v1: GBrain as system of record, GWS/Google Cloud OAuth as the only access plane, Telegram digests, or auto-writing a people graph on every mail. miloh-mail is multi-account (Apple primary), SQLite forever, morning email digest, rules+manual dossiers. GBrain can sit downstream later as an optional renderer — same one-way posture as Obsidian, not a second SoR.

Design grilled and locked July 14, 2026. Tonbi pattern note added same day. Private plan: Obsidian AI Inbox · miloh-mail Plan.md. Implementation waits for an explicit go.