README: mail is content - mail: on a state, mail: in site.yaml, gdo
Lint and reload / lint (push) Successful in 3s
Lint and reload / reload (push) Successful in 0s

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4jrCgLiKKHAEFuZUJjckH
This commit is contained in:
Bendik Aagaard Lynghaug
2026-09-23 19:50:22 +02:00
co-authored by Claude Fable 5.1
parent 58225386b0
commit 9917b07312
+31
View File
@@ -289,6 +289,37 @@ it>` naming the automation that does. A bucket nothing reads fails
lint, so no publicly collected answer can land where no one will ever
see it.
**Mail is content** (portal 0.3.43, delivered by
[gdo](https://project.uhhm.no/uhhm/gdo)). A state in `aggregates.yaml`
may carry the mail its arrival sends:
```yaml
states:
open: { event: received, mail: { to: submitter, subject: "Got it, {name}", body: "We read every one. Withdraw it here: {site}/decide/brief?chain={chain}&email={email}" } }
fixed: { event: fixed, mail: { to: board@example.no, subject: "Fixed: {where}", body: "..." } }
```
`to` is `submitter` (the record's `email` field; lint then requires
every form recording into that bucket to collect a required `email`)
or one fixed address. Subject and body are templates over the
record's fields, plus `{site}` (the instance's public URL), `{chain}`
(the record id), `{email}`, `{bucket}`, `{state}`; the body is
markdown, sent as plain text with an HTML alternative. An invite
(`invite:` on an alternative) mails its one-time link built in, in the
site's `lang`. None of it is sent unless `site.yaml` says who it comes
from:
```yaml
mail:
from: UHHM <portal@uhhm.no>
reply_to: bl@uhhm.no # optional
invite: { subject: "...", body: "..." } # optional rewording; {name} {username} {email} {group} {link} {site} {site_name} {expires}
```
Portal renders each mail the moment the record enters the state and
publishes it on `portal.mail.send` in the `WORMHOLE` JetStream stream;
gdo, one per host, hands it to the host's SMTP. A transition that
fires twice sends once.
## Routing: the tree is the router
The `questions/` directory tree is the URL tree — `index.yaml` names