Files
mesh-catalog/modules/mesh-mail-reader
jochen 4f3ebe370b issue 1859: answer the mail page's greeting and reading pane from mail reading
ADR 0515 §1, §5: list also answers the mails the mail signal told of today, and each line its mail's folder
and UID; entries takes an id and answers that one entry whole, with its sender's address, tasks, promises
and read-later, for the reading pane's corrections.
2026-10-22 20:00:44 +02:00
..

mesh-mail-reader — the default holder of mail-reading

Design 59, milestone 2 (mail reading); built from mesh-mail's own source, like mesh-mail-web and mesh-mail-notifier (novox/hq ADR 0459). One instance, held once for the mesh, on the machine mesh-mail runs on, under its own account (runs-as) — it hears mesh-mail's restricted stream MAIL, which the operator account never does. It reads mail; it moves, flags, deletes and sends nothing (ADR 0459 §11).

What it does

  • Claims mail-reading (held once for the mesh), declared in mesh-mail's own manifest beside its three mail seats, serving twelve verbs (ADR 0459 §2, ADR 0517 §4). Each answers only a caller the trusted setting callers names (default ["mesh-mail-web"]); any other caller is refused, naming why.
  • Hears mesh-mail's added events and judges a batch of up to 6 at a time (ADR 0516 §3) against a question put to claude_code_judge, keeping one entry per message — never its body — in its own database: one Gmail message in INBOX and All Mail is one entry, by its Message-ID, else its folder and UID (issue 1849).
  • Notes what each mail asks (ADR 0516, issue 1857): at most 3 tasks (a line and a due date), 3 promises (you promised, waiting on others, on its way; who and a date) and whether it is read later, each line the model's own words of at most 120 characters; a line sharing 8 words in a row with the mail fails the batch.
  • Reads the last 14 days once more after delivery (ADR 0516 §5): the inbox mail of each granted account, in ordinary batches after any mail just heard; kept as done, and the journal says its start, end and count.
  • Keeps the operator's handling and an action log (ADR 0517, issue 1858): an item (a task, a promise or the mail itself) handled, undone until the day ends, or reminded until the next day (Europe/Brussels); one line per act — what, mail id, item, mode, when, never mail text — kept 365 days, removed each night.
  • Keeps a health of its own, mail_reader_health: unhealthy once a judgement is refused, times out or answers out of shape; healthy once one succeeds, saying when, or that no batch has run yet (issue 1580).
  • Tells the operator at most once a batch when a mail matters, and corrects itself at once, keeping a reading lesson, when the operator says it judged wrong (issue 1428, 1429, 1522).

Its database

Its own postgres-database: mail entries with their tasks and promises, mail groups, reading lessons, the mails heard but not yet read, its health state, whether the 14-day re-reading was done, each item's handling and the action log. No column holds a mail body or text taken from one. The schema is numbered migrations (migrations/) and the consolidated schema.sql; a unit test proves the two agree.

Tools

tool does
mail-reading.entries every mail entry: headers, mail group, summary, mark and why, due date. Read-only
mail-reading.groups every mail group a batch has made, largest first. Read-only
mail-reading.correct correct one entry's mark, mail group, why or due date, say a task is not one, remove a promise, set or clear read later; kept at once as a reading lesson, with one corrected line
mail-reading.lessons the reading lessons kept, at most 40. Read-only
mail-reading.undo undo one reading lesson
mail-reading.status healthy or not, when a batch last succeeded (or that none has run yet), lessons per 100 mails read each week. Read-only
mail-reading.list the operator's list for a mode: today, this week, later, the promises by kind, good to know, read later, handled today, scam warnings, and when the operator last looked. Read-only
mail-reading.handle mark an item handled (the mail itself handles all its items); one handled line
mail-reading.unhandle undo a handling of today; one undone line
mail-reading.remind hide an item until the next day, when it is under today; one reminded line
mail-reading.record one line for an act that changes no entry: opened, mode, page opened
mail-reading.actions the action log, newest first. Read-only
mail_reader_health how mesh-mail-reader is: unhealthy once a judgement is refused, times out or answers out of shape, naming which and since when; healthy, saying when the last batch succeeded or that none has run yet. Read-only

Where it runs

Its own account (runs-as), because it hears mesh-mail's restricted stream MAIL (novox/hq ADR 0376 §2). Held once for the mesh, on the machine mesh-mail runs on; it is granted reading only, after issue 1227's split of mesh-mail's grants is delivered (ADR 0472: that split is won't-fix — mesh-mail's grants stays one list per account, and mesh-mail-reader is put on it after delivery, never asking to send).