Handoff: document the digest send path; trim Current state
- docs/guides/email.md: new "Outbound mail — the daily digest" section (Gmail-DWD primary → SMTP fallback; gmail.compose send capability; the internal-digest exemption from the agents-draft rule). - AGENTS.md: add digest env names (CRM_DIGEST_SENDER, SMTP_*); consolidate the v75/v76 deploy bullets into one current bullet; drop finished v74 narrative.
This commit is contained in:
@@ -16,6 +16,31 @@ Read this before editing Gmail capture or draft creation.
|
||||
|
||||
- **Agents draft; humans send.** Never let an agent send email, post, or contact an LP autonomously. Tier-B `compose.py` only *creates* a Gmail draft for human review.
|
||||
|
||||
## Outbound mail — the daily digest (internal; exempt from "agents draft")
|
||||
|
||||
The CRM sends an internal **daily activity digest** to the fund's own admins. This is the
|
||||
ONE automated send path, and it does **not** violate the hard rule above: that rule governs
|
||||
outward **LP/prospect** contact. An internal ops email to the team's own inboxes is a
|
||||
different category. **Never extend this path to send to LPs/prospects.**
|
||||
|
||||
- **Transport selector: `backend/digest_mailer.py`** (top-level, not in this package) —
|
||||
`send_digest(conn, to_addrs, subject, body)` picks **Gmail-DWD (preferred) → SMTP (fallback)**.
|
||||
DWD-impersonation sender = `CRM_DIGEST_SENDER` env, else the first active admin.
|
||||
- **Gmail-DWD path: `gmail_send.py`** (this package) — reuses `credentials.py`'s
|
||||
`DWDCredentialProvider` with the **`gmail.compose`** scope to call `users.messages.send`
|
||||
(REST, mirrors `compose.py`; body is `{raw}` not the draft's `{message:{raw}}`). The
|
||||
deployment's DWD grant includes `gmail.compose` (which authorizes send) but **not** the
|
||||
narrow `gmail.send` — so request `gmail.compose`. Verified live 2026-06-15 (token mint +
|
||||
a real `messages.send`).
|
||||
- **SMTP fallback: `backend/smtp_send.py`** (top-level) — stdlib smtplib reading `SMTP_*` env,
|
||||
populated on the box by the **Configure Digest SMTP** Start9 action (writes
|
||||
`/data/secrets/smtp/*`; entrypoint exports `SMTP_*`). A dedicated per-package account,
|
||||
independent of any StartOS system-wide SMTP.
|
||||
- The admin **`POST /api/admin/digest/test-email`** restricts recipients to the active-admin
|
||||
set (not an open relay), and logs send failures rather than echoing them (an auth error can
|
||||
carry a token/credential). Digest *content* generation (Phase B) runs on **Spark, never
|
||||
Claude** — the digest is deliberately un-anonymized.
|
||||
|
||||
## Known gap
|
||||
|
||||
- Tier-B drafts currently reply to the **LP only**; reply-all is the next change (see AGENTS.md → Current state).
|
||||
|
||||
Reference in New Issue
Block a user