Files
email_agent/docs/outline/01-system-overview.md
Documenter c5760db43d docs: Phase 8 documentation - Gitea, Obsidian, Outline, Vikunja, map (AUD-74)
- README: architecture Mermaid, Phase 8 status, Phase 7 endpoints, Documentation index
- docs/outline/: AI-context collection (index, system, config, code map, runbook)
- docs/email-agent-architecture.mmd + rendered PNG + Archify map (showcase pass)
- docs/vikunja-tasks.json (Vikunja project 17, tasks 179-185)
- docs/phase8-documentation.md evidence
2026-10-13 10:46:21 +11:00

4.6 KiB

Email Agent — System Overview

Purpose

The Email Agent triages the family inbox. All mail lands in one Gmail account (samuelrolfe@gmail.com). PurelyMail forwards every domain address there.

Sam opens one page. He clears the inbox in a few minutes. He knows that nothing important was missed.

The build spec is AGENTS.md. The outcome statement is in AGENTS.md section 1.

Architecture

Sam (phone or desktop browser)
  -> Caddy on .35 (mail.lab.audasmedia.com.au)
  -> Email Agent container on .13 :8790
       |- HTMX dashboard (Go, server-rendered HTML)
       |- SQLite (/data/email_agent.db, own volume)
       |- IMAP read  -> imap.gmail.com:993 (IPv4 only)
       |- SMTP send  -> smtp.gmail.com:587 (IPv4 only, STARTTLS)
       |- JEV        -> https://api.typesafe.ai (classification)
       |- OmniRoute  -> http://192.168.20.13:20129/v1 (reply drafts)
       |- Apprise    -> http://192.168.20.35:8210 (daily summary email)
       \- Hub API    -> read-only /ask, /capabilities, /notify
Hub on .13 :8788 asks this service with a shared bearer token.
n8n runs the CLI jobs (-fetch, -classify, -summary-send) on a schedule.

Services and connections

Service Host Address Role
email-agent .13 :8790 Web app, API, and CLI jobs.
Caddy .35 :443 TLS reverse proxy for mail.lab.audasmedia.com.au.
Gmail IMAP cloud imap.gmail.com:993 Read mail. Force IPv4.
Gmail SMTP cloud smtp.gmail.com:587 Send replies. Force IPv4.
JEV cloud api.typesafe.ai Classify each message.
OmniRoute .13 :20129 Draft reply replies. Not JEV.
Apprise .35 :8210 Deliver the daily summary by email.
Central AI Hub .13 :8788 Ask questions. Read-only.
n8n .13 — Trigger the CLI jobs.

Functional requirements in use

ID Requirement Where
FR-1 Fetch mail with the Gmail path on a schedule. -fetch, /actions/fetch
FR-2 Record the source address from X-Pm-Original-To. internal/mailfetch
FR-3 Classify with JEV: category, importance, action, confidence. internal/classify
FR-4 Apply user rules over the classification. internal/classify/rules.go
FR-5 Show a triage list grouped by category. internal/server/inbox.go
FR-6 Bulk delete, move, and mark. internal/server/actions.go
FR-7 Detect unsubscribe links. Keep an ignore list. internal/unsubscribe
FR-8 Draft a reply with the LLM. Edit, then send. internal/reply, internal/mailops
FR-9 Move mail to Gmail labels. Deletes are recoverable. internal/mailops
FR-10 Build a daily summary and send it by email. internal/summary, internal/apprise
FR-11 Edit rules as plain text. Save and version. /rules, internal/server/rules.go
FR-12 Expose GET /capabilities, POST /ask, POST /notify. internal/hub
FR-13 Log every action. internal/store actions_log
FR-14 Edit the category list in the UI. /categories
FR-15 Send as the address the mail arrived at. internal/reply, FR-2 value

Build phase status

Phases 1 to 7 are complete and deployed. Phase 8 documents the project.

Phase Scope State
1 Go skeleton, SQLite, session login, Docker, Caddy. Done.
2 Gmail IMAP read, FR-2 source address. Done.
3 JEV classification, rules table, editable categories. Done.
4 Triage actions: delete, move, mark, bulk select. Done.
5 Reply drafts, edit, send. Done.
6 Unsubscribe detection and the rules editor. Done.
7 Daily summary by email and the read-only Hub API. Done.
8 Documentation across Gitea, Obsidian, Outline, Vikunja, and the map. Done.

Key rules

  • Force IPv4 for every Gmail connection. IPv6 to Gmail failed from .13.
  • The source address header is X-Pm-Original-To. Never use Delivered-To.
  • /ask is read-only. It never changes state.
  • Spam is recommended, never auto-deleted.
  • Deletes are recoverable. The app uses a Delete label.
  • Sending a reply needs Sam's action in the UI. No auto-send.
  • Every action is logged.
  • Message bodies are kept for one month. The -retain job clears older bodies and caps actions_log. Metadata stays.
  • AGENTS.md — the build spec and the phase plan.
  • README.md — the technical repository README.
  • docs/phase7-summary-hub.md — the Phase 7 evidence.
  • docs/outline/ — these AI-context documents.
  • docs/email-agent-map.html — the interactive architecture map.