MAS-WP-0012 finished: one outbound path and one send cap
mas_modes.mailer.Mailer is the only outbound path (own SQLite + lock), shared by the ticket service and both EmailMode roles. Over the cap mail is held and reported (send-cap-reached, held); held mail is purged after email-held-duration-max (7d) and not stored beyond emails-held-storage-max (100MB). The ticket service's legacy outbox is imported once so the live count carries over (checked on a copy of the live DB: 4 sent). Entrypoint passes the cap and both limits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 5787@bnt-lap001 Assistant-Session: 5db26b82-138b-40cc-9856-4d5eb0f752fd
This commit is contained in:
parent
bdf200a600
commit
8de8fddf37
10 changed files with 371 additions and 101 deletions
|
|
@ -4,7 +4,7 @@ type: workplan
|
|||
title: "One outbound path and one send cap"
|
||||
domain: communication
|
||||
repo: mail-address-semantics
|
||||
status: proposed
|
||||
status: finished
|
||||
owner: claude
|
||||
topic_slug: coulomb-social
|
||||
created: "2026-10-19"
|
||||
|
|
@ -28,7 +28,7 @@ total".
|
|||
|
||||
```task
|
||||
id: MAS-WP-0012-T01
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "5d9fefac-684d-5fe0-bead-f664952047e0"
|
||||
```
|
||||
|
|
@ -44,7 +44,7 @@ semantics.
|
|||
|
||||
```task
|
||||
id: MAS-WP-0012-T02
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "431cc528-cf9f-5991-8044-7cbab2ac0021"
|
||||
```
|
||||
|
|
@ -52,3 +52,32 @@ state_hub_task_id: "431cc528-cf9f-5991-8044-7cbab2ac0021"
|
|||
Add a test that a deployment with both roles stops at exactly N sends in
|
||||
total, and that the live entrypoint still passes `MAS_MAX_SENT` to the
|
||||
single cap.
|
||||
|
||||
## Outcome
|
||||
|
||||
- **Founder interview (2026-10-19).** Over the cap, mail is **held and
|
||||
reported**. Held mail is purged after `email-held-duration-max`
|
||||
(default 7d) and not stored beyond `emails-held-storage-max` (default
|
||||
100MB). The live counter is **migrated once at start**.
|
||||
- **`mas_modes.mailer.Mailer`** is the one outbound path: its own SQLite
|
||||
file and lock, principle 10, one lifetime cap, holding with a purge on
|
||||
every send and `purge_held()`, a storage limit, `import_legacy()` with a
|
||||
once-only marker, and `parse_duration` / `parse_size`.
|
||||
- **Ticket service.** It sends through a Mailer it is given, or builds one.
|
||||
`/outbox` shows the shared outbox (`ticket_id` = case ref). Its legacy
|
||||
`outbox` table is imported once and then left alone. New CLI options:
|
||||
`--outbox-db` (default `<db>-outbox.sqlite3`),
|
||||
`--email-held-duration-max` and `--emails-held-storage-max`. Over the
|
||||
cap the closed notice reports `notified: false`.
|
||||
- **EmailMode** takes the shared Mailer. `mail.send` over the cap answers
|
||||
`send-cap-reached` with `held`. CONTRACT.md §5 and §6 are updated.
|
||||
- **Deploy.** The entrypoint passes `MAS_MAX_SENT` (300) and the two
|
||||
hold limits (`MAS_EMAIL_HELD_DURATION_MAX`,
|
||||
`MAS_EMAILS_HELD_STORAGE_MAX`). The migration was checked on a copy of
|
||||
the live DB: 9 legacy rows, 4 sent, carried over; no second import on
|
||||
restart.
|
||||
- **Tests.** `tests/test_outbound.py` (15): exactly N sends across both
|
||||
roles, purge by age, storage limit, sent mail never purged, the legacy
|
||||
migration, parsers, entrypoint flags.
|
||||
- **Not deployed.** The live MX still runs `v0.2-a95f848`; this takes
|
||||
effect on the next redeploy.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue