mail-events-log
Keep what happened to each email, and carlos email events to read it. First of two platform changes toward telling an app when its email was delivered or bounced (the second, mail-events-push, is stacked on this).
SES already publishes Send, Delivery, Bounce, Complaint, Reject and DeliveryDelay to the deployment's SNS topic and the console already verifies each one, but all it kept was a daily count.
What this adds
- Parsing, in two reads. The fields the counts and cap depend on are read on their own, exactly as before, and only that read can refuse a notification. Everything the log adds — destination,
ses:caller-identity, each type's recipient block and own timestamp — is read separately; a part in an unexpected shape is left empty and logged (Event.Incomplete), and the event is still counted. Kept strings lose control, C1 and invisible formatting characters and are bounded. mail_events: one row per recipient per notification, keyed on SNS's MessageId, 30-day window, pruned hourly (a failed prune retries).- Attribution by sender.
AppOfCallerreads a bare name or IAM user ARN. A CARLOS-minted identity is the sender: its app gets the row if live, nobody otherwise. Only a non-CARLOS caller falls back to every app on a verified matching domain (by_sender=false). A per-recipient event naming nobody is not widened to every addressee. - The log belongs to the app, not its name. Trashed app: nothing new kept. Purge and account reap forget. Rename carries everything; a move to another account carries only the app's own rows, leaving domain-attributed ones behind.
- Counts and enforcement unchanged: still bucketed by the send time.
GET .../email/events(Admin) andcarlos email eventswith--since,--message,--to,-n,--json; documented.
Reviews
Two Opus rounds and one Fable round. Opus: name-reuse leak, named-sender fallback, role-session ARN, C1/bidi, send-time dating (88a71415); a regression from that dating counting late events against the wrong day (71343dad). Fable: move carrying sibling apps' recipients across accounts, log-only fields able to drop a count, bounce widened to all addressees, prune stamp, reap, unverified domain fallback, plus an end-to-end SNS→log test (a03088f6). Each new test was checked to fail with its fix undone.
Not yet verified
ses:caller-identity hasn't been seen on a live event from this deployment; if absent, events fall back to verified-domain attribution.
Gate
make test green locally under umask 022. CI: gate and cross green; minio-contract fails on the upstream 410 (discussion 152). Two tests fail under a 0077 umask here and on main (discussion 151).
Discussions 1 open
Tasks 8/9 done
- Parse recipients, diagnostics and the sender identity from SES events Done
- Keep a 30-day per-message log in the console, attributed by sender Done
- GET .../email/events door, Admin-only Done
- carlos email events, and its docs Done
- CI: gate + cross green; minio-contract blocked upstream (152) Done
Activity
- claude-code agent, operated by bill@keymail.dev replied to CI: minio-contract fails — dl.min.io answers 410 for the pinned release
- claude-code agent, operated by bill@keymail.dev replied to CI: minio-contract fails — dl.min.io answers 410 for the pinned release
- task updated: Fable review findings fixed (a03088f6)
- claude-code agent, operated by bill@keymail.dev added task Fable review findings fixed (a03088f6)
- task updated: Push events to the app — on branch mail-events-push
- task updated: Booking app records ids and shows delivery — billhorsman/bunkhouse#54
- task updated: Opus review findings fixed (88a71415)
- task updated: CI: gate + cross green; minio-contract blocked upstream (152)
- claude-code agent, operated by bill@keymail.dev added task Opus review findings fixed (88a71415)
- claude-code agent, operated by bill@keymail.dev opened CI: minio-contract fails — dl.min.io answers 410 for the pinned release
- claude-code agent, operated by bill@keymail.dev opened Two file-mode tests fail under a 0077 umask
- task updated: carlos email events, and its docs
- task updated: Parse recipients, diagnostics and the sender identity from SES events
- task updated: Keep a 30-day per-message log in the console, attributed by sender
- task updated: GET .../email/events door, Admin-only
- claude-code agent, operated by bill@keymail.dev added task Parse recipients, diagnostics and the sender identity from SES events
- claude-code agent, operated by bill@keymail.dev added task Keep a 30-day per-message log in the console, attributed by sender
- claude-code agent, operated by bill@keymail.dev added task GET .../email/events door, Admin-only
- claude-code agent, operated by bill@keymail.dev added task carlos email events, and its docs
- claude-code agent, operated by bill@keymail.dev added task CI: gate + cross green; minio-contract blocked upstream (152)
- claude-code agent, operated by bill@keymail.dev added task Push events to the app — on branch mail-events-push
- claude-code agent, operated by bill@keymail.dev added task Booking app records ids and shows delivery — billhorsman/bunkhouse#54