Skip to content

Yui's mailbox: mail in and out at yuigui.com, run by Yui herself - #4

Open
CJohnDesign wants to merge 3 commits into
mainfrom
claude/dev-email-setup-def891
Open

CJohnDesign wants to merge 3 commits into
mainfrom
claude/dev-email-setup-def891

Conversation

@CJohnDesign

Copy link
Copy Markdown
Contributor

Yui gets her own mailbox at yuigui.com and runs it herself.

What it does

  • supabase/functions/yui-mail: every email goes through one function and SendGrid.
    • The site sends confirmation links, the app anything it needs, and Yui her own mail.
    • Every email for any address at yuigui.com is stored and threaded, and the hosted Yui answers it, emails the owner, or leaves it. There's no approval step.
  • Automatic limits:
    • mail_enabled switch that stops all sending
    • daily caps
    • at most 6 answers per thread per day, against auto-responder loops
    • no mail to addresses that bounced, reported spam or unsubscribed
    • one-click unsubscribe on promos
  • An email is data to Yui. From an incoming email she can only answer its sender or email the owner. Promos start only from her tools.
  • Hermes Yui gets a yui_mail tool and hermes yui mail inbox|thread|reply|rules, using Yui's mail key in ~/.hermes/yui/mail.json.
  • Migration 20260928100000_yui_mail: threads, messages, contacts, delivery events, the rules (first draft seeded), the private yui-mail bucket, limits, and a daily sweep. It was applied to yuigui through the Supabase tool, so the live database records it under that day's timestamp, not the file's version.

Already live on yuigui

  • The function is deployed with its secrets.
  • SendGrid's signed delivery webhook and its inbound forwarding for yuigui.com both point at the function.
  • Still to do: switch yuigui.com's MX record to mx.sendgrid.net.

Tests

  • deno test supabase/tests/mail_unit_test.ts: 11 pass
  • python3 hermes-plugin/tests/test_mail.py: 7 pass
  • test_controls.py and test_talk.py fail on main too; this PR doesn't touch them.

The site half (confirm, unsubscribe, the news opt-in, privacy) is in postscarcityai/yuigui on branch claude/yui-mail.

🤖 Generated with Claude Code

CJohnDesign and others added 3 commits September 27, 2026 23:42
- yui-mail: every email goes through one function and SendGrid. The site
  sends confirmation links, the app anything it needs, Yui her own mail.
  Inbound Parse posts every email for yuigui.com; it is stored, threaded,
  and the hosted Yui answers, tells the owner, or lets it be, with no human
  approval. Limits stay automatic: mail_enabled, daily caps, a per-thread
  reply cap against auto-responder loops, suppressions on bounce, spam
  report and unsubscribe, one-click unsubscribe on promos.
- An email is data to her: from an inbound email she can only answer its
  sender and write to the owner. Promos start only from her tools.
- Hermes Yui: yui_mail tool and `hermes yui mail` with Yui's mail key.
- Migration 20260928100000_yui_mail: threads, messages, contacts, events,
  rules (the first rules seeded), the yui-mail bucket, limits, daily sweep.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test for a missing key found the real ~/.hermes/yui/mail.json through a
second lookup path; one path, beside the connector file, as the token is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The mailbox brain is a tool loop now. Every email: brand_search over the
  site's brand kit (/brand.json: posts, releases, shipped, building, backlog,
  features, pages, logos), read_page on yuigui.com and the repos, attach a
  file from yuigui.com, tell_owner, then send_reply or no_reply.
- Mail from the owner, proven by his domain's DKIM pass, also gets the
  super-user tools: send_email to anyone, inbox, read_thread, contacts,
  campaign (dry run first), get_rules, set_rules. A forged From gets none.
- Replies carry attachments; no em dashes leave Yui (plainDashes).
- ops.ts: the mailbox operations the API and the brain now share.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant