Answer the review: the mail modules are separate modules, the notifier has no process, nothing future in the as-is; 1433 depends on none
This commit is contained in:
@@ -15,8 +15,8 @@ decisions:
|
||||
|
||||
# The mail modules, as they run
|
||||
|
||||
**One module, `mesh-mail`, holds every mail account and is the mesh's one `mail-store`. A second module built
|
||||
from its source, `mesh-mail-web`, is the mesh's one mail web client. A third, `mesh-mail-notifier`, shows a
|
||||
**One module, `mesh-mail`, holds every mail account and is the mesh's one `mail-store`. A second module,
|
||||
`mesh-mail-web`, is the mesh's one mail web client. A third, `mesh-mail-notifier`, shows a
|
||||
desktop notice of new mail on the machines it is assigned to. A caller may read an account's mail, or ask to
|
||||
send from it, only when `mesh-mail`'s trusted setting `grants` names it for that account — one list per
|
||||
account, giving both at once, to the same callers. A send is never performed by a tool: it is queued for a
|
||||
@@ -26,7 +26,7 @@ process of its own, which sends only once the operator approves it on Telegram.*
|
||||
```
|
||||
mesh-mail (mail-store, once for the mesh — the control-node)
|
||||
accounts search read send send-status ── MAIL stream (headers only, 7 days) ──▶ a granted caller
|
||||
own database (index) · own object-store bucket (attachments) · two key-value buckets (account state, newest mails)
|
||||
own database (index) · own object-store bucket (attachments) · three key-value buckets (sends, account state, newest mails)
|
||||
process keep (IDLE + index) · process watch (mail_health) · process send (mesh-mail-send account; holds the passwords)
|
||||
▲ grants: one list per account, read AND send alike
|
||||
│
|
||||
@@ -44,11 +44,14 @@ mesh-mail (mail-store, once for the mesh — the control-node)
|
||||
2026-10-20). ADR 0378 §4 decided to move it to the home server as a step of its own, on the operator's
|
||||
Approve (issue 803); as built, that move has not happened: the live mesh still runs it, and `mesh-mail-web`
|
||||
beside it, on the control-node.
|
||||
- **`mesh-mail-web`** is built from `mesh-mail`'s own source, as `mesh-mail-notifier` is, and claims
|
||||
`mail-webclient`, held once for the mesh. It is assigned to the same machine as `mesh-mail` and runs as its
|
||||
- **`mesh-mail-web`** is a module of its own, with its own Go module and source under `modules/mesh-mail-web`;
|
||||
it claims `mail-webclient`, held once for the mesh. It is assigned to the same machine as `mesh-mail` and runs as its
|
||||
own account, `mesh-mail-web`. Its manifest declares no database and no store of its own: nothing beyond its
|
||||
route, its sign-in binding and its own settings on disk.
|
||||
- **`mesh-mail-notifier`** is built from the same source and claims `mail-notifier`, held once per machine; a
|
||||
- **`mesh-mail-notifier`** is a module of its own as well (`modules/mesh-mail-notifier`), and keeps a
|
||||
byte-identical copy of `mesh-mail`'s `mailevent.go`, held to it by its `copies_test.go`, because each module
|
||||
builds alone. ADR 0378 §9 and ADR 0440 §1 say both are "built from `mesh-mail`'s source"; as built, they are
|
||||
separate modules that share no code but that copied file. It claims `mail-notifier`, held once per machine; a
|
||||
module claiming it needs `node-notifier` held on the same machine (ADR 0378 §7). It is assigned today to two
|
||||
machines, the laptop and the workstation (live read of each machine's modules, 2026-10-20); the control-node
|
||||
and the home server hold no instance of it.
|
||||
@@ -66,6 +69,8 @@ mesh-mail (mail-store, once for the mesh — the control-node)
|
||||
the other folders; for each new, changed or removed message it publishes an event on its own stream `MAIL` —
|
||||
account, folder, message id, date, from, to, subject, size, flags and attachment references, never a body or
|
||||
an attachment's bytes (ADR 0359 §2). The stream keeps 7 days (`module.json`).
|
||||
- **A send's own record** lives in its state bucket `sends`, which only the `send` process and the tools write
|
||||
(`module.json`; ADR 0436 §8).
|
||||
- **The index and the attachment store are its own.** A row per message and folder lives in its own Postgres
|
||||
database; attachments live in an object-store bucket, each kept once by its SHA-256 digest (ADR 0359 §3, ADR
|
||||
0439 §5-§6).
|
||||
@@ -83,7 +88,7 @@ mesh-mail (mail-store, once for the mesh — the control-node)
|
||||
- **One check, every door.** The code that decides whether a caller may read an account's mail (`mail_search`,
|
||||
`mail_read`, the account's share of `MAIL`) and the code that decides whether it may ask to send from it
|
||||
(`mail_send`) is the same function, reading the one list (`modules/mesh-mail/cmd/mesh-mail/config.go`'s
|
||||
`Grants.Allows`, called from `tools.go` and `send.go`, confirmed on `origin/main` at `a67f0196`). There is no
|
||||
`Grants.Allows`, called from `tools.go` for every tool, `mail_send` included, confirmed on `origin/main` at `a67f0196`). There is no
|
||||
second list and no narrower grant for sending alone: a caller named for an account may do both, and a caller
|
||||
left out of it may do neither.
|
||||
- **Who is granted, today, for every account alike** (`mesh-controller.settings` for `mesh-mail`, read live on
|
||||
@@ -142,9 +147,10 @@ mesh-mail (mail-store, once for the mesh — the control-node)
|
||||
- **One notice per new inbox mail, at most once.** For each account it is granted, on hearing `mesh-mail`'s
|
||||
`added` event, it shows the sender (name and address), the subject and the account's name through the
|
||||
machine's `node-notifier`, under its own account (`runs-as`), never the tool runner's.
|
||||
- **Quiet rules.** It shows nothing for a mail outside the inbox, for a mail from the account's own address, for
|
||||
a mail already flagged read when it arrives, and for anything during an account's first sync or a resync
|
||||
(`notifier.go`, `mailevent.go`).
|
||||
- **Quiet rules.** It shows nothing for a mail outside the inbox, for a mail from the account's own address, and
|
||||
for a mail already flagged read when it arrives (`notifier.go`, `mailevent.go`). During an account's first sync
|
||||
or a resync `mesh-mail` publishes no `added` events, so nothing reaches the notifier then (`notifier.go`'s
|
||||
opening note, citing `mesh-mail`'s `imap.go`).
|
||||
- **Folding.** More than three qualifying mails of one account within a trailing 60-second window become one
|
||||
notice, shown once the window has passed since the fold's own first mail, naming how many and the latest
|
||||
sender; a message already shown — tracked by its message id, or by its folder, UIDVALIDITY and UID where it
|
||||
@@ -161,17 +167,10 @@ mesh-mail (mail-store, once for the mesh — the control-node)
|
||||
for five minutes, healthy otherwise; its `send` process is a plain unit (ADR 0359 §6; `health.go`).
|
||||
- **`mesh-mail-web`**'s own tool `mail_web_health` reads the one state its HTTP endpoint keeps: still setting up
|
||||
sign-in, listening, or ended with its error — unhealthy whenever it is not listening (`main.go`).
|
||||
- **`mesh-mail-notifier`**'s own tool `mail_notifier_health` is unhealthy once an account's notice has failed to
|
||||
show for more than ten minutes. As built it answers this only when asked directly: its one process (`notify`)
|
||||
is still declared with a plain unit health alone, because the catalogue's gate refuses a module judged only by
|
||||
its own tool with no check of another kind beside it, and the module has only the one process — a gap its own
|
||||
source names; a watching process of its own is tracked by issue 841, not yet decided (its `README.md` and
|
||||
`health.go`). Design 59's milestone 2 retires the module (issue 1418).
|
||||
|
||||
## What design 59 changes
|
||||
|
||||
- **The one `grants` list splits in two.** Reading an account's mail and asking to send from it, today one
|
||||
grant, become two the operator sets apart (design 59 §5; ADR 0460).
|
||||
- **The notifier's pop-up retires.** `mesh-mail-notifier`'s desktop notice for every new inbox mail is replaced
|
||||
by one mail signal per batch of mail reading, and it is unassigned from the laptop and the workstation once
|
||||
that proves itself live (design 59 §7; ADR 0461).
|
||||
- **`mesh-mail-notifier`** has no process of its own: its manifest declares only its account and its state
|
||||
directory, and its bundle, loaded by the machine's tool runner, runs the watcher inside the runner's own
|
||||
invocation (commit 12d78520, issue 859). Its tool `mail_notifier_health` is unhealthy once an account's notice
|
||||
has failed to show for more than ten minutes, and answers only when asked; no check of the node-engine judges
|
||||
the module by it. A watching process of its own is tracked by issue 841, not yet decided (its `README.md`).
|
||||
The comment in its `health.go` that still names a process `notify` predates that commit. It keeps one state
|
||||
bucket, `shown`, for 30 days, to show no mail twice (`module.json`).
|
||||
|
||||
@@ -293,8 +293,11 @@ order (each depends on the one before unless said):
|
||||
1429 (mail signals; after 1427), 1430 (the mail page; after 1428 and 1429), 1431 (the integration test; after
|
||||
1430 and 1227), 1418 (`mesh-mail-notifier` unassigned; after 1431 and test 13 live).
|
||||
- Milestone 3: 806 (Betterbird removed; after 1418).
|
||||
- Milestone 4: 1419 (the thread's reading-only caller; a decision first), 1433 (`mail_search`'s folder case and
|
||||
`-any` switches), 1432 (the mail conversation; after 1431, 1419 and design 58's milestone 3, issue 880). Milestone 2 is one release of `mesh-catalog`: the grant split, the new seat, the new
|
||||
- Milestone 4: 1433 (`mail_search`'s folder case and `-any` switches; depends on none), 1419 (the thread's
|
||||
reading-only caller; a decision first, after design 58's milestone 3, issue 880), 1432 (the mail conversation;
|
||||
after 1431, 1419 and issue 880).
|
||||
|
||||
Milestone 2 is one release of `mesh-catalog`: the grant split, the new seat, the new
|
||||
module and the page change ship together, and `mesh-mail-reader` is granted reading only after that delivery, on the
|
||||
operator's Approve; `mesh-mail-notifier` is unassigned only after test 13 passes live. Milestone 3 is issue 806.
|
||||
ADR 0379 §2's bar for removing Betterbird is milestone 1's; keeping Betterbird until mail reading (milestone 2) works,
|
||||
|
||||
Reference in New Issue
Block a user