Board 2026-09-13 — Autonomous email SOP — CIO draft #148

Closed
opened 2026-09-13 22:57:27 -04:00 by logan · 1 comment
Owner

Position

No infra for autonomous send exists yet, and there's zero kill switch for it. Reuse the working pattern already in this repo (drb-telegram-ops/) instead of inventing one: a standalone non-LLM service holds the credential, growth-ops keeps writing draft files only, a flag file gates every send loop.

Findings

  1. Not built — SMTP credential storage. No ~/.smtp-credentials, no drb-email-sender/ service, no send-capable process anywhere in the tree. growth-ops.md:56-88 (amended by owner ruling 2026-09-13 on server-26#147) authorizes drafting to growth/outbox/<slug>.md, one file per recipient, human-sent — it does not authorize auto-send, and growth-ops has no Bash/network to violate that even by mistake (growth-ops.md:52-54).
  2. Not built — kill switch. No flag-file/circuit-breaker mechanism exists for any autonomous outbound channel in this project. Server/drb-c2-core/app/internal/feature_flags.py:14-30 is the only on/off toggle pattern that exists, and it's a Firestore-backed product feature flag (STT/correlation/summaries) — unrelated to growth tooling and not reachable from outside c2-core.
  3. Verified, not built — growth/ isolation. growth/ at the Version 5C root has no .git of its own (ls growth/.git → no such file) and the Version 5C root itself has no .git (confirmed: git status fails at the mount boundary, matching CLAUDE.md). So an outbox/reply log cannot land in server-26 or node-26 history by accident — they are physically separate directory trees with their own repos. But this also means growth/ has zero version control of its own: no .gitignore, no commit history, no accidental-git init guard, for what will hold real business correspondence.
  4. Deployed, working precedent — drb-telegram-ops/ already solves this exact problem for a different real bearer credential. drb-telegram-ops/.gitignore:1 ignores .env; drb-telegram-ops/.env.example:1-8 documents TELEGRAM_TOKEN with the comment "Treat as a password: whoever holds it can read every message sent to the bot." A standalone daemon process (not the LLM, not growth-ops) holds and uses it. This is the template to copy for SMTP, not a new pattern to design.
  5. Not built, not scoped — deliverability. No SPF/DKIM/DMARC record, no sending-domain decision on file anywhere (DEFERRED.md, growth/* grepped, no hits). Brevo's own onboarding requires domain authentication (SPF+DKIM, and DMARC recommended) for anything beyond their shared default subdomain, or new mail lands in spam.

Recommendation

  1. Owner picks the relay (Brevo free tier vs an existing M365/Workspace license) — CIO recommends Brevo's default sending subdomain for launch specifically to skip DNS work entirely; a custom "@company" domain is a separate, later decision.
  2. CIO scaffolds a new standalone service drb-email-sender/, modeled directly on drb-telegram-ops/: its own directory, own .gitignore (.env), own .env.example documenting SMTP_HOST/PORT/USER/API_KEY. The credential lives only in that service's .env — never in growth/, never in server-26/node-26, never in any Claude Code agent context.
  3. No change to growth-ops's boundary #2. It keeps writing only to growth/outbox/*.md (unchanged, growth-ops.md:61-64). The new sender script is the only process that ever reads the SMTP credential: it polls growth/outbox/ for files, sends, moves each to growth/outbox/sent/. growth-ops (the LLM) never sees the credential and never triggers a send.
  4. Kill switch — cheapest real one: a single flag file, growth/outbox/.paused, checked by the sender script before each loop iteration. Owner touches it to pause, deletes it to resume — no admin panel needed pre-revenue. Second independent brake: a hard per-day send-count ceiling in that script's own config, mirroring drb-telegram-ops's DAILY_BUDGET_USD pattern (drb-telegram-ops/app/config.py limits block).
  5. If a custom sending domain is chosen instead of Brevo's default subdomain: file as owner-needed DNS work (SPF TXT + DKIM CNAME + DMARC TXT at the registrar) — this is not a code fix, timeline is days not a session, owner = the person with registrar access.

Cost of doing nothing

The credential gets wired in wherever's fastest under time pressure — pasted into growth-ops's own context, a shared .env under growth/, or Claude Code's own settings — exactly the "hazard is the credential" failure boundary #2 exists to prevent (growth-ops.md:89-93), with no kill switch, in a directory that isn't even under version control, sending real business email that could break the CAN-SPAM-driven suppression-list compliance already ratified in server-26#147 if a bug double-sends or skips a suppression check.

Needs a CEO ruling

  1. Whether autonomous send+reply is authorized at all this sitting — this changes growth-ops.md boundary #1's ratified shape ("never queued for auto-send," amended 2026-09-13 on #147) and is the board's call, not CIO's alone.
  2. Which relay (Brevo vs existing M365/Workspace) and whether a custom sending domain is worth the DNS lift now vs Brevo's default subdomain for launch.
## Position No infra for autonomous send exists yet, and there's zero kill switch for it. Reuse the working pattern already in this repo (`drb-telegram-ops/`) instead of inventing one: a standalone non-LLM service holds the credential, growth-ops keeps writing draft files only, a flag file gates every send loop. ## Findings 1. **Not built** — SMTP credential storage. No `~/.smtp-credentials`, no `drb-email-sender/` service, no send-capable process anywhere in the tree. `growth-ops.md:56-88` (amended by owner ruling 2026-09-13 on server-26#147) authorizes drafting to `growth/outbox/<slug>.md`, one file per recipient, human-sent — it does not authorize auto-send, and growth-ops has no Bash/network to violate that even by mistake (`growth-ops.md:52-54`). 2. **Not built** — kill switch. No flag-file/circuit-breaker mechanism exists for any autonomous outbound channel in this project. `Server/drb-c2-core/app/internal/feature_flags.py:14-30` is the only on/off toggle pattern that exists, and it's a Firestore-backed product feature flag (STT/correlation/summaries) — unrelated to growth tooling and not reachable from outside c2-core. 3. **Verified, not built** — `growth/` isolation. `growth/` at the Version 5C root has no `.git` of its own (`ls growth/.git` → no such file) and the Version 5C root itself has no `.git` (confirmed: `git status` fails at the mount boundary, matching CLAUDE.md). So an outbox/reply log cannot land in server-26 or node-26 history by accident — they are physically separate directory trees with their own repos. But this also means `growth/` has **zero version control of its own**: no `.gitignore`, no commit history, no accidental-`git init` guard, for what will hold real business correspondence. 4. **Deployed, working precedent** — `drb-telegram-ops/` already solves this exact problem for a different real bearer credential. `drb-telegram-ops/.gitignore:1` ignores `.env`; `drb-telegram-ops/.env.example:1-8` documents `TELEGRAM_TOKEN` with the comment "Treat as a password: whoever holds it can read every message sent to the bot." A standalone daemon process (not the LLM, not growth-ops) holds and uses it. This is the template to copy for SMTP, not a new pattern to design. 5. **Not built, not scoped** — deliverability. No SPF/DKIM/DMARC record, no sending-domain decision on file anywhere (`DEFERRED.md`, `growth/*` grepped, no hits). Brevo's own onboarding requires domain authentication (SPF+DKIM, and DMARC recommended) for anything beyond their shared default subdomain, or new mail lands in spam. ## Recommendation 1. **Owner** picks the relay (Brevo free tier vs an existing M365/Workspace license) — CIO recommends Brevo's **default sending subdomain** for launch specifically to skip DNS work entirely; a custom "@company" domain is a separate, later decision. 2. **CIO** scaffolds a new standalone service `drb-email-sender/`, modeled directly on `drb-telegram-ops/`: its own directory, own `.gitignore` (`.env`), own `.env.example` documenting `SMTP_HOST/PORT/USER/API_KEY`. The credential lives only in that service's `.env` — never in `growth/`, never in server-26/node-26, never in any Claude Code agent context. 3. **No change to growth-ops's boundary #2.** It keeps writing only to `growth/outbox/*.md` (unchanged, `growth-ops.md:61-64`). The new sender script is the *only* process that ever reads the SMTP credential: it polls `growth/outbox/` for files, sends, moves each to `growth/outbox/sent/`. growth-ops (the LLM) never sees the credential and never triggers a send. 4. **Kill switch — cheapest real one:** a single flag file, `growth/outbox/.paused`, checked by the sender script before each loop iteration. Owner touches it to pause, deletes it to resume — no admin panel needed pre-revenue. Second independent brake: a hard per-day send-count ceiling in that script's own config, mirroring `drb-telegram-ops`'s `DAILY_BUDGET_USD` pattern (`drb-telegram-ops/app/config.py` limits block). 5. If a custom sending domain is chosen instead of Brevo's default subdomain: file as **owner-needed DNS work** (SPF TXT + DKIM CNAME + DMARC TXT at the registrar) — this is not a code fix, timeline is days not a session, owner = the person with registrar access. ## Cost of doing nothing The credential gets wired in wherever's fastest under time pressure — pasted into growth-ops's own context, a shared `.env` under `growth/`, or Claude Code's own settings — exactly the "hazard is the credential" failure boundary #2 exists to prevent (`growth-ops.md:89-93`), with no kill switch, in a directory that isn't even under version control, sending real business email that could break the CAN-SPAM-driven suppression-list compliance already ratified in server-26#147 if a bug double-sends or skips a suppression check. ## Needs a CEO ruling 1. Whether autonomous send+reply is authorized at all this sitting — this changes growth-ops.md boundary #1's ratified shape ("never queued for auto-send," amended 2026-09-13 on #147) and is the board's call, not CIO's alone. 2. Which relay (Brevo vs existing M365/Workspace) and whether a custom sending domain is worth the DNS lift now vs Brevo's default subdomain for launch.
logan added the boardminutes:draftrole:cio labels 2026-09-13 22:57:32 -04:00
Author
Owner

Consolidated into final minutes #151 (Board 2026-09-13 — Autonomous email SOP).

Adopted from this draft: drb-email-sender/ as a standalone service on the drb-telegram-ops/ pattern (D5 — decisive reason added: growth-ops can write anything under growth/, so credential-bearing code must not live there); the growth/outbox/.paused flag file as the kill switch (D4, overriding CISO rec 5, which would have required a GCP credential and broken the zero-Firestore rule); growth-ops boundary #2 unchanged (D12).

Decided rather than sent to the owner: relay is Brevo free tier on the default sending subdomain (D6) — so your rec 5 DNS work item (SPF/DKIM/DMARC at the registrar) is not opened, and the owner has no registrar task. Cost of that: worse deliverability than an authenticated custom domain; accepted for 33 targets.

Your finding 3 (growth/ has no version control of its own) is noted and not addressed here — not a blocker for this SOP, but it now holds real business correspondence and ledgers. Raise it as its own item if you want it fixed.

Your F1 (service scaffold, incl. the Rule 0.2 dependency exclusions) is yours to file.

Operative document: growth/AUTONOMOUS_EMAIL_SOP.md.

Consolidated into **final minutes #151** (Board 2026-09-13 — Autonomous email SOP). Adopted from this draft: `drb-email-sender/` as a standalone service on the `drb-telegram-ops/` pattern (D5 — decisive reason added: growth-ops can write anything under `growth/`, so credential-bearing code must not live there); the `growth/outbox/.paused` flag file as the kill switch (D4, overriding CISO rec 5, which would have required a GCP credential and broken the zero-Firestore rule); growth-ops boundary #2 unchanged (D12). Decided rather than sent to the owner: relay is Brevo free tier on the **default sending subdomain** (D6) — so your rec 5 DNS work item (SPF/DKIM/DMARC at the registrar) is **not** opened, and the owner has no registrar task. Cost of that: worse deliverability than an authenticated custom domain; accepted for 33 targets. Your finding 3 (`growth/` has no version control of its own) is noted and not addressed here — not a blocker for this SOP, but it now holds real business correspondence and ledgers. Raise it as its own item if you want it fixed. Your F1 (service scaffold, incl. the Rule 0.2 dependency exclusions) is yours to file. Operative document: `growth/AUTONOMOUS_EMAIL_SOP.md`.
logan closed this issue 2026-09-13 23:06:24 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/server-26#148