Merge pull request 'Graduate research 066 into design 59: mail reading, mail signals, reading and sending granted apart, the mail conversation; Mail as the thirteenth domain' (#442) from research-066-graduate into main
This commit was merged in pull request #442.
This commit is contained in:
@@ -772,6 +772,54 @@ it was told, and the servarr apps' own libraries. **Upstream of** nothing. **Dec
|
||||
- **grab** — an engine handing one media release to a download client. It names the work it is for, so
|
||||
the media-importer knows where the copy belongs.
|
||||
|
||||
## Mail — the operator's own correspondence, which the mesh holds and reads for them
|
||||
|
||||
**Purpose.** To hold the operator's mail accounts, say each mail on the bus, find and read mail for whoever the
|
||||
operator granted, note each mail for the operator and tell them of the mail that matters, and send a mail only on
|
||||
the operator's Approve. **Recorded by** `mesh-mail` (its index database and attachment bucket, ADR 0359 §3; its
|
||||
account buckets, ADR 0439) and `mesh-mail-reader` (its database of mail entries, mail groups and reading lessons,
|
||||
ADR 0459). **Downstream of** Identity and access and Operator and conversation; **upstream of** nothing.
|
||||
**Decided by** ADR 0359, 0361, 0378, 0439, 0440, 0458, 0459, 0460, 0461, 0462.
|
||||
**Uses:** operator, person, module, seat; grant, identity (Identity and access); ask, warrant, operator channel,
|
||||
content rule, untrusted input (Operator and conversation). A *judgement* is one call of the model with no tools
|
||||
and no session (ADR 0278), in its plain sense.
|
||||
|
||||
- **mail account** — one of the operator's mailboxes that `mesh-mail` holds, of a kind of adapter (`imap`,
|
||||
`imap-oauth`, `graph`), named by its address (ADR 0359 §1).
|
||||
- **`mail-store`** — the seat holding the mail accounts: `accounts`, `search`, `read`, `send`, `send_status` (ADR
|
||||
0378 §2, ADR 0440 §7). Always the seat's name: the bare *store* is Core's.
|
||||
- **mail event** — what `mesh-mail` publishes on its stream `MAIL` for a new, changed or removed mail: headers,
|
||||
flags and attachment references, never a body (ADR 0359 §2).
|
||||
- **mail send** — a mail the mesh sends, which goes out only on the operator's warrant for that one mail (ADR 0361
|
||||
§2), with the states `mail_send_status` answers (ADR 0440 §7). Only a caller granted asking to send for that
|
||||
account may ask for one (ADR 0460).
|
||||
- **mail web client** — the module `mesh-mail-web`, holder of `mail-webclient`: the operator's mail in a browser on
|
||||
the private network (ADR 0440 §1). The page it serves is the mail page.
|
||||
- **mail notice** — `mesh-mail-notifier`'s desktop pop-up for a new inbox mail (ADR 0378 §7, §9). It retires when
|
||||
`mesh-mail-notifier` is unassigned everywhere (ADR 0461 §7) and then moves to *mail signal*'s *Not:* line
|
||||
(issue 1418).
|
||||
- **mail reading** — the model's reading of each new mail as it arrives, in batches, into its mail group and mail
|
||||
entry; the seat `mail-reading`, held by `mesh-mail-reader` (ADR 0459). Not *triage* (the issue tracker's
|
||||
judgement), and not `mail_read`, `mail-store`'s tool that fetches one mail's text.
|
||||
- **mail entry** — what mail reading keeps about one mail: its mail group, a one-line summary, its mark and why, a
|
||||
due date; never the body (ADR 0459 §4). Not *catalogue entry*: the catalogue is Delivery's.
|
||||
- **mark** — what a mail entry says the mail is to the operator: *matters*, *scam warning* or neither, never two
|
||||
(ADR 0459 §7). Not *kind* (Media's).
|
||||
- **mail group** — a set of mails the model put together because they belong to one subject (ADR 0459 §4). Not *delivery
|
||||
group* or *account group*.
|
||||
- **reading lesson** — one correction the operator made on the mail page (a mark or a mail group), kept so later
|
||||
mail reading follows it (ADR 0459 §8 to §10). Always qualified: the bare *lesson* is Operator and conversation's.
|
||||
- **mail signal** — the notice on the operator's channel, one `tell` per batch in words only, and the place at the
|
||||
top of the mail page, that tells the operator mail matters (ADR 0461). Always qualified: the bare *signal* is
|
||||
Health and repair's.
|
||||
- **scam warning** — the mark of a mail the model judges an attempt to deceive the operator, with why; shown in
|
||||
its own place on the mail page and never a mail signal (ADR 0459 §7, ADR 0461 §6).
|
||||
- **mail conversation** — a thread (ADR 0383) with a mail context, followed on the mail page: the mail questions
|
||||
and their answers, each answer with the mails it found. The mail context is the framing that a mail is data, the
|
||||
tools `mail_search` and `mail_read` only, the operator's senders and folders, and the reading lessons (ADR 0462).
|
||||
- **mail question** — what the operator writes in the mail conversation to find or understand mail. Not *ask*
|
||||
(Operator and conversation's request for the operator's input).
|
||||
|
||||
## The record — how this repository works
|
||||
|
||||
Not a domain of the mesh but of the way it is built, listed because its words meet the mesh's.
|
||||
@@ -877,6 +925,7 @@ renaming one sense, the old sense moves to a *Not:* line and becomes mechanical.
|
||||
| store | the one database server | **store** | Core |
|
||||
| | the OCI registry | **artifact store** | Delivery |
|
||||
| | a node's own copy of its last declaration | **last declaration** | Placement |
|
||||
| | the seat holding the mail accounts | **`mail-store`** | Mail |
|
||||
| record | a numbered decision | **decision record** | The record |
|
||||
| | the literal reader of this repository, searched first for a symptom | **the record** (the `records` module) | Operator and conversation |
|
||||
| | the upgrade policy that sends nowhere | `record` | Module |
|
||||
@@ -903,6 +952,12 @@ renaming one sense, the old sense moves to a *Not:* line and becomes mechanical.
|
||||
| | a file the mesh writes, such as the agent's instruction file or `managed_settings` | the file's own name, or *a file the mesh places* | — |
|
||||
| trusted | a config value that decides what runs or who can reach what | **trusted** config value | Config |
|
||||
| | a sender on the operator's own list | **trusted** sender, its message an **operator message** | Operator and conversation |
|
||||
| lesson | an agent's proposal after the operator corrects its way of working | **lesson** | Operator and conversation |
|
||||
| | the operator's correction of mail reading | **reading lesson** | Mail |
|
||||
| signal | something that must keep happening | **signal** | Health and repair |
|
||||
| | the notice that mail matters | **mail signal** | Mail |
|
||||
| conversation | the domain *Operator and conversation* | the domain's name | Operator and conversation |
|
||||
| | the mail questions and answers on the mail page | **mail conversation** | Mail |
|
||||
|
||||
## How this page is kept
|
||||
|
||||
|
||||
@@ -2,21 +2,23 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [hq 00-META/checks/words.py, mesh-catalog merge-check.sh]
|
||||
updated: 2026-10-18
|
||||
updated: 2026-10-20
|
||||
decisions:
|
||||
- "ADR 0429"
|
||||
- "ADR 0244"
|
||||
- "ADR 0006"
|
||||
- "ADR 0008"
|
||||
- "ADR 0302"
|
||||
- "ADR 0354"
|
||||
- "ADR 0458"
|
||||
---
|
||||
|
||||
# 49 — The mesh in domains
|
||||
|
||||
**Every concept of the mesh belongs to one of eleven domains, which owns its one word. The glossary is
|
||||
**Every concept of the mesh belongs to one of thirteen domains, which owns its one word. The glossary is
|
||||
organised by them and is the authority; a word it retires is named in the entry that replaced it, with
|
||||
where it is retired; and two checks hold the documents and the tools' descriptions to it.**
|
||||
(ADR 0244; the eleventh, Media, ADR 0302.)
|
||||
(ADR 0244; the eleventh, Media, ADR 0302; the twelfth, Config, ADR 0354; the thirteenth, Mail, ADR 0458.)
|
||||
|
||||
A **domain** is an area of the mesh that owns a set of concepts: inside it each concept has one word,
|
||||
and the domain decides what that word means. The glossary
|
||||
@@ -38,6 +40,8 @@ shape — what each is for, where its records live, and how they depend on one a
|
||||
| **Connectivity** | to make every node and module reachable by name where it should be, and unreachable where it should not | the controller |
|
||||
| **Operator and conversation** | to let the mesh and its operator tell, ask and answer, and act only on an answer it can trust | the router, and the controller for authorising asks |
|
||||
| **Media** | to find, fetch and file copies of the works a person watches, listens to and reads, each in the library its kind names | the `media-importer` module's settings and memory, and the servarr apps' own libraries |
|
||||
| **Config** | to hold, check and resolve every value a module reads that someone may change, and say where each resolved value came from | the `mesh-config` module, in its buckets on the bus, with its store as the history behind them |
|
||||
| **Mail** | to hold the operator's mail accounts, say each mail on the bus, note each mail for the operator and tell them of the mail that matters, and send a mail only on the operator's Approve | `mesh-mail` (its index database, attachment bucket and account buckets) and `mesh-mail-reader` (its database of mail entries, mail groups and reading lessons) |
|
||||
|
||||
Beside them, **the record** is this repository's own vocabulary — research, decisions, designs,
|
||||
issues, playbooks, checks — listed because its words meet the mesh's.
|
||||
@@ -71,6 +75,11 @@ a change of meaning upstream ripples down, never up. Arrows point downstream.
|
||||
Media stands beside the diagram, below Module alone: its words are about what a person watches, not
|
||||
about the mesh's machinery, and no other domain reads them.
|
||||
|
||||
Mail stands below the diagram's foot: it is downstream of Identity and access (the operator grants each mail
|
||||
account to a caller) and of Operator and conversation (a mail send is an ask, a mail signal is a notice through
|
||||
the operator channel), and upstream of nothing. It is the operator's own correspondence, which the mesh holds and
|
||||
reads for them, not the mesh talking about itself, so it is not part of Operator and conversation (ADR 0458).
|
||||
|
||||
Delivery sits low because it reads health and data; in time it runs first, and asks Placement
|
||||
to send. An authorising answer acts in whichever domain asked, through that domain's own verb: the
|
||||
conversation owns the asking, never the act.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
layer: to-be
|
||||
status: in-progress
|
||||
code: [mesh-catalog]
|
||||
updated: 2026-10-19
|
||||
updated: 2026-10-20
|
||||
decisions:
|
||||
- "ADR 0440"
|
||||
- "ADR 0378"
|
||||
@@ -14,6 +14,12 @@ decisions:
|
||||
- "ADR 0439"
|
||||
- "ADR 0201"
|
||||
- "ADR 0436"
|
||||
- "ADR 0458"
|
||||
- "ADR 0459"
|
||||
- "ADR 0460"
|
||||
- "ADR 0461"
|
||||
- "ADR 0462"
|
||||
- "ADR 0278"
|
||||
---
|
||||
|
||||
# 59 — The mail web client
|
||||
@@ -22,12 +28,23 @@ decisions:
|
||||
`mesh-mail-web`, holds the seat `mail-webclient`; it renders pages on the server in Go and reaches mail only through
|
||||
`mail-store`'s verbs, under a caller the operator grants account by account. Its route reaches the private network
|
||||
only, under its internal name, and the operator signs in with Keycloak. A mail written there goes out only on the
|
||||
operator's Approve, as every mail the mesh sends does. Once it works on the laptop and the workstation, Betterbird is removed.**
|
||||
operator's Approve, as every mail the mesh sends does.**
|
||||
(ADR 0440, building on ADR 0378 §5 and ADR 0379 §2.)
|
||||
|
||||
**Then the model reads the mail for the operator.** A module of its own, `mesh-mail-reader`, holds the seat
|
||||
`mail-reading`: it reads each new mail in batches, keeps a mail entry for it (its mail group, one line, its mark),
|
||||
tells the operator on Telegram of the mail that matters in a mail signal, shows a scam warning on the page only, and
|
||||
learns from the operator's corrections as reading lessons; it never changes the mailbox and keeps no mail text.
|
||||
Reading and asking to send are granted apart first, and the pop-up for every new mail retires once mail signals
|
||||
work. Later, once the mesh's threads exist, the operator asks questions about their mail in a mail conversation, a
|
||||
thread with a mail context. Betterbird is removed once mail reading works on the laptop and the workstation.
|
||||
(Research 066; ADR 0458 to 0462. The words are the glossary's Mail domain.)
|
||||
|
||||
**Acceptance.** In a browser on the laptop and on the workstation, the operator signs in, browses, searches and reads the mail of
|
||||
every account `mesh-mail` holds, opens an attachment, and writes a mail that goes out on their Approve on Telegram;
|
||||
the same page is not reachable from a machine outside the private network.
|
||||
the same page is not reachable from a machine outside the private network. A new mail that matters reaches the
|
||||
operator's phone as one mail signal and stands at the top of the mail page in its mail group; a mail that does not
|
||||
matter gives no pop-up and no mail signal anywhere.
|
||||
|
||||
## 1. The parts
|
||||
|
||||
@@ -70,7 +87,7 @@ outside. Two things hold it:
|
||||
Measured on 2026-10-19: the laptop and the workstation hold the mesh's authority (`mesh-internal-ca.crt`) as a trust anchor, and
|
||||
Firefox on both reads the system's trust through p11-kit, so the page opens there without a warning. Away from the
|
||||
private network (the laptop travelling without its tunnel) the page is unreachable; Betterbird stays the offline client
|
||||
until it is removed (§6).
|
||||
until it is removed (milestone 3, §11).
|
||||
|
||||
## 3. Signing in (ADR 0440 §3)
|
||||
|
||||
@@ -102,16 +119,108 @@ account through the page and get around `grants`.
|
||||
- **The seat's verbs** (ADR 0378 §5): `open` answers the page's address, and with an account and a mail that mail's
|
||||
page; `status` answers whether it serves and which accounts it is granted.
|
||||
|
||||
## 5. What the first version leaves out
|
||||
## 5. Reading and asking to send, granted apart (ADR 0460)
|
||||
|
||||
Each is an issue with an owner (ADR 0440 §8):
|
||||
`mesh-mail`'s trusted setting `grants` gives a caller, per account, **reading** (that account's `MAIL` events,
|
||||
`mail_accounts`, `mail_search`, `mail_read`) and **asking to send** (`mail_send`, `mail_send_status`), each on its own,
|
||||
set as `grants` is today. A caller granted reading only is refused by both send tools, with the missing grant named;
|
||||
one granted asking to send only is refused every read. When the split is delivered every caller in today's `grants`
|
||||
keeps both for each account it has, so nothing stops; narrowing one afterwards is the operator's choice.
|
||||
`mesh-mail-reader` is granted reading only, for every account, and nothing before the split is delivered. This is
|
||||
issue 1227.
|
||||
|
||||
## 6. Mail reading (ADR 0459)
|
||||
|
||||
```
|
||||
mail-store (mesh-mail) ── MAIL: mail.<account>.message.added ──▶ mesh-mail-reader (seat mail-reading, once for the mesh)
|
||||
▲ │ its own database: mail entries, mail groups,
|
||||
└──────────── mail_read (reading grant only) ─────────────┤ reading lessons; never a body
|
||||
│ batches of ≤ 10 mails ──▶ claude_code_judge (within ≤ 40 s)
|
||||
│ claude_code_judged
|
||||
├──▶ operator-channel.tell (a mail signal, §7)
|
||||
▼
|
||||
mesh-mail-web ── entries · groups · correct · lessons · undo · status ──▶ the mail page
|
||||
```
|
||||
|
||||
- **One module, one seat.** `mesh-mail-reader`, built from `mesh-mail`'s source like `mesh-mail-web`, claims
|
||||
`mail-reading` (declared in `mesh-mail`'s manifest beside the three seats of ADR 0379 §4) and runs once, on the
|
||||
machine that runs `mesh-mail`. It hears `added` events under its own `runs-as` account and the operator's reading
|
||||
grant (ADR 0378 §13), and moves, flags, deletes and sends nothing.
|
||||
- **A mail entry per mail, never the body.** Its own database (`postgres-database`) keeps each mail's mail group,
|
||||
a one-line summary, its mark (*matters*, *scam warning* or neither) and why, and a due date where the mail gives
|
||||
one, beside the mail groups and the reading lessons.
|
||||
- **Batches.** One judgement reads at most 10 mails, and every part of its question has a bound, so it never
|
||||
passes 55 KiB of the judgement's 64 KiB: the framing that a mail is data and never an instruction, at most 4 KiB;
|
||||
the mail groups, at most 4 KiB, the largest first; the reading lessons that apply, at most 40 within 12 KiB,
|
||||
sender and mail group first, then the newest, under the framing that a reading lesson outranks anything a mail
|
||||
says; then each mail, at most 3.5 KiB (its headers at most 512 bytes, its text cut to its first 3 KiB), a mail in
|
||||
a Junk folder said to be so. A batch asks for up to 40 s with `within` and collects with
|
||||
`claude_code_judged` (built under issue 508, recorded by ADR 0459 §14). Research 066 measured 1.9 to 3.1 s per
|
||||
mail, so a batch of 10 takes about 19 to 31 s. A batch starts at least 160 s after the previous one started, so
|
||||
an issue tracker's check that waits behind a batch on the same machine ends within 115 s, inside its two minutes
|
||||
(ADR 0278 §2), which research 066's 15 mails and 120 s back to back would not; mail reading then reads up to 225
|
||||
mails an hour (ADR 0459 §15).
|
||||
Batches stay judgements; whether they become threads is issue 1417.
|
||||
- **Reading lessons.** When the operator changes a mail's mark or mail group on the page, `mesh-mail-web` calls
|
||||
`correct` and the correction is kept at once as a reading lesson (headers, the change, when; never body text),
|
||||
with no further Approve: it is the signed-in operator's own act. The page lists the reading lessons, undoes one
|
||||
(later mail reading only), and shows reading lessons per 100 read mails per week, which answers whether mail
|
||||
reading learns the operator's way.
|
||||
- **The page.** Above the classical list it shows the mail that matters at the top, the mail groups, and the scam
|
||||
warnings in a place of their own, each with why; the classical list (accounts, folders, search, one mail) stays
|
||||
and always opens. `mesh-mail-web` reads these through `mail-reading`'s verbs and still keeps no mail state
|
||||
(ADR 0440 §4 as ADR 0459 §13 changes it).
|
||||
- **It fails loudly.** Its own health check is unhealthy when a judgement is refused, times out or answers out of
|
||||
shape, with the cause and since when; the controller raises its condition, the page shows the cause above the
|
||||
classical list instead of mail groups, and no mail signal is sent. On recovery the mail that arrived meanwhile is
|
||||
read in arrival order from its durable consumer on `MAIL` (kept 7 days). A warning before a licence runs out is
|
||||
issue 1409.
|
||||
|
||||
## 7. Mail signals, and the pop-up retired (ADR 0461)
|
||||
|
||||
- **One tell per batch.** A batch that marks mail as mattering sends one `operator-channel.tell`: the headline
|
||||
"1 mail matters" or "N mails matter", a first line naming the mail with the nearest due date (sender's name,
|
||||
summary, due date), a second naming the next and, with more than two, ending "and N-2 more on the mail page".
|
||||
When the hourly cap of 10 refuses one, its mails stay at the top of the page and the next mail signal counts
|
||||
them.
|
||||
- **Words only.** No link, mail address, host name or path: the router refuses a message holding any, and the mail
|
||||
page opens only on the mesh's own machines. The reader checks its words with `messenger_check` first and, refused,
|
||||
sends the safe form "N mails matter: open the mail page".
|
||||
- **At once, at any hour**; the phone's own quiet hours decide. **Never** for a scam warning, and never while mail
|
||||
reading is unhealthy.
|
||||
- **The pop-up retires.** Once mail signals pass acceptance test 13 on the real accounts, `mesh-mail-notifier` is
|
||||
unassigned from the laptop and the workstation on the operator's Approve and leaves `grants`; `mail-notifier`
|
||||
stays declared and unheld, and nothing takes it over (ADR 0379 §3, §7). Betterbird's own pop-ups stay off by its
|
||||
setting until it is removed (ADR 0379 §6). Issue 1418; issue 801 closes as replaced.
|
||||
|
||||
## 8. The mail conversation (ADR 0462)
|
||||
|
||||
A mail conversation is a thread (ADR 0383), run by the thread handler (ADR 0384), with a mail context: the
|
||||
framing that a mail is data, the tools `mail_search` and `mail_read` only under a caller granted reading only (a caller of the thread's own,
|
||||
issue 1419), the
|
||||
operator's real senders and folder names, and the reading lessons. The operator writes a mail question on the mail
|
||||
page; each answer names the mails it found, and a question with no answer says so. `mesh-mail-web` creates and
|
||||
follows the thread over the bus on its server side; the page loads one script from its own origin and talks only to
|
||||
it (content security policy: script from that origin, `connect-src 'self'`), so the browser never reaches the bus.
|
||||
The thread keeps the text of each mail it read for good, as every thread is kept (ADR 0383 §3), which the operator
|
||||
accepted; mail reading keeps none. In the same milestone `mail_search` matches folder names without regard to case
|
||||
and describes its three `-any` switches as true or false only. It is built after design 58's milestone 3 (threads,
|
||||
issue 880).
|
||||
|
||||
## 9. What stays outside
|
||||
|
||||
Each is an issue with an owner:
|
||||
|
||||
- a reply, cc, bcc and attachments on a sent mail: issue 1257 (it needs `mail_send` to take them first);
|
||||
- a page that shows new mail without a reload, from ADR 0439's buckets: issue 1258, after issue 1255;
|
||||
- the agent that searches, triages and drafts (ADR 0378 §5): issue 1259, which needs a decision first;
|
||||
- a page that shows new mail without a reload, from ADR 0439's buckets: issue 1258;
|
||||
- drafting a mail, the rest of issue 1259 (its triage is mail reading, its search the mail conversation), and writing
|
||||
to the mailbox: issue 730;
|
||||
- a task list for the operator: issue 1396; the search faults found by research 066: issues 1400 and 1401;
|
||||
- the work account: a later decision of its own (ADR 0359 §7).
|
||||
|
||||
## 6. The build's acceptance tests
|
||||
## 10. The build's acceptance tests
|
||||
|
||||
Tests 1 to 9 are milestone 1's; tests 10 to 17 are research 066's eight, in its order.
|
||||
|
||||
1. A request without a session, for a page, an attachment or a send, is redirected to sign-in; an identity not in
|
||||
`operators` is answered 403; a send form without its token is answered 403; the session cookie is `Secure`,
|
||||
@@ -131,22 +240,55 @@ Each is an issue with an owner (ADR 0440 §8):
|
||||
answers whether it serves and the accounts it is granted (a unit test of `mesh-mail-web`, issue 1262).
|
||||
9. The acceptance sentence at the top, live: in a browser on the laptop and on the workstation, for every account.
|
||||
|
||||
10. A new mail on each account has a mail entry, in a mail group, within 5 minutes of its mail event; a test searches
|
||||
`mesh-mail-reader`'s database for a known body line and finds none.
|
||||
11. The reader's caller is refused by `mail_send` for every account, and no mail is moved, flagged or deleted by it.
|
||||
12. (Milestone 4.) On the mail page, a mail question by a person, by a time range and by "what needs a reply" finds
|
||||
its target mails, research 066's three failed kinds included; a question with no answer says so; the conversation
|
||||
is a thread readable through the thread seat; and the browser makes no request but to the mail page's own origin.
|
||||
13. A batch with one mail that matters sends exactly one `tell` naming it, with no URL, mail address or host name in
|
||||
its words, and the mail is at the top of the page; a sender whose name carries a host name still gives a
|
||||
mail signal, in the safe form.
|
||||
14. Research 066's 20 steering mails, read again, mark no injected words as mattering, and every phishing decoy that
|
||||
is marked is a scam warning, which sends no `tell`.
|
||||
15. A reading lesson given on a real mail changes how the next mail of that sender is noted; undone, it no longer
|
||||
does; the page lists it.
|
||||
16. With the judgement refused (the reader's licence binding removed in the integration test), the condition is
|
||||
raised with its cause, the page shows it over the classical list, no `tell` is sent, and after recovery the mail
|
||||
that arrived meanwhile is read in arrival order.
|
||||
17. With `mesh-mail-notifier` unassigned, a new mail that does not matter shows nothing on the laptop or the
|
||||
workstation, and one that matters gives one mail signal.
|
||||
|
||||
Tests 1 to 4 are one integration test that starts the module whole against the real bus (playbook 07 step 3 item 4);
|
||||
tests 5 and 7 are `mesh-mail`'s own and test 8 `mesh-mail-web`'s, unit tests; test 6 is read before the module is
|
||||
assigned; test 9 is proven live after the delivery.
|
||||
|
||||
## 7. Milestones
|
||||
Tests 11, 13 (with a stand-in router), 16 and the grant split's refusals are one integration test that starts
|
||||
`mesh-mail` and `mesh-mail-reader` whole against the real bus and store; the batch's budget, the seat's verbs and the
|
||||
mail signal's words are unit tests; tests 10, 13, 14, 15 and 17 are proven live after milestone 2's delivery, test 13
|
||||
before `mesh-mail-notifier` is unassigned; test 12 with milestone 4.
|
||||
|
||||
## 11. Milestones
|
||||
|
||||
| # | Outcome, in one sentence | Proves | Repositories and their parts | Depends on |
|
||||
|---|---|---|---|---|
|
||||
| 1 | In a browser on the laptop and the workstation, the operator signs in and browses, searches and reads every account's mail with its attachments, and writes a mail that goes out on their Approve | tests 1 to 9 | mesh-catalog: `mesh-mail`'s account bucket (issue 1255, ADR 0439 §2); the module `mesh-mail-web` (manifest, sign-in, the pages, the send, the seat's verbs, the integration test) | — |
|
||||
| 2 | Betterbird is gone from the laptop and the workstation, its profile and mail kept in the home | ADR 0379 §2 | mesh-catalog: Betterbird unassigned on the operator's Approve, then the `betterbird` module removed from the catalogue (issue 806) | 1 |
|
||||
| 2 | Each new mail is read into a mail group on the mail page; the mail that matters reaches the operator's phone as one mail signal, a scam warning shows on the page only, the operator's corrections become reading lessons, and the pop-up for every new mail is gone | tests 10, 11, 13 to 17 | mesh-catalog: `mesh-mail`'s grants split (issue 1227) and the seat `mail-reading` declared; the module `mesh-mail-reader` (batches, mail entries, reading lessons, mail signals, health, the integration test); `mesh-mail-web`'s mail groups, mail signals, scam warnings and reading lessons; `mesh-mail-notifier` unassigned (issue 1418) | 1 |
|
||||
| 3 | Betterbird is gone from the laptop and the workstation, its profile and mail kept in the home | ADR 0379 §2 | mesh-catalog: Betterbird unassigned on the operator's Approve, then the `betterbird` module removed from the catalogue (issue 806) | 2 |
|
||||
| 4 | On the mail page the operator asks questions about their mail and gets the mails that answer them, in a mail conversation kept as a thread | test 12 | mesh-catalog: `mesh-mail-web`'s mail conversation as a client of the thread seat; the thread's mail tools under a caller of their own granted reading only (issue 1419); `mesh-mail`'s folder case and `-any` switches | 2 (the grant split and the reading lessons); design 58's milestone 3 (issue 880) |
|
||||
|
||||
**Confirmed by the operator on 2026-10-19.** Milestone 1's issues, one repository part each, in their order:
|
||||
1255 (`mesh-mail`'s account bucket), 1261 (`mail_send_status` answers only its caller), 1262 (the module), 1263
|
||||
(sign-in), 1264 (accounts, folders and mails), 1265 (search), 1266 (a mail and its attachments), 1267 (writing a
|
||||
mail), 1268 (the integration test). Milestone 2 is issue 806.
|
||||
**Milestone 1, confirmed by the operator on 2026-10-19, is delivered;** its live proof on the laptop and the
|
||||
workstation (a search, an attachment, one send on the Approve) is still the operator's. Its issues, one repository
|
||||
part each, in their order: 1255 (`mesh-mail`'s account bucket), 1261 (`mail_send_status` answers only its caller),
|
||||
1262 (the module), 1263 (sign-in), 1264 (accounts, folders and mails), 1265 (search), 1266 (a mail and its
|
||||
attachments), 1267 (writing a mail), 1268 (the integration test). After its delivery four values were set, each on
|
||||
the operator's Approve: `mesh-mail-web`'s `reach` on its machine (`internal`), its assignment there, its
|
||||
`operators`, and its caller in `mesh-mail`'s `grants` for every account.
|
||||
|
||||
After milestone 1's delivery and before its live proof, four values are set, each on the operator's Approve:
|
||||
`mesh-mail-web`'s `reach` on its machine (`internal`), then its assignment there, its `operators`, and its caller in
|
||||
`mesh-mail`'s `grants` for every account.
|
||||
Milestones 2 to 4 are written by research 066's graduation and wait for the operator's confirmation and their issues
|
||||
(playbook 04, steps 5 and 6). 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,
|
||||
and not until the mail conversation, is the lead's proposal, for the operator to confirm with the milestones
|
||||
(playbook 04, step 5). Milestone 4 waits for threads and for the decision that names its thread's reading-only caller (issue 1419, which needs a decision first).
|
||||
|
||||
Reference in New Issue
Block a user