tenant email spec: stop promising two things the code does not do
Final whole-branch review found two places this document claims behaviour the implementation cannot deliver, and recommended amending the spec rather than spending the code now. Section 11 said the CLI names which of DKIM / MAIL FROM / sending is still pending. VerifyDomain collapses SES's three-axis status into one string before persisting, so the axes are gone before any door sees them; the CLI names the candidate set. Section 9 said a pause surfaces with its reason. Provisioned carries only Active — the reason reaches the audit log and nothing else, so status shows the pause, the counts and the cap, and points at the audit log. Both closes are additive and small. Recording them honestly is what stops a future reader treating the spec as evidence the behaviour exists.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+15
−3
docs/superpowers/specs/2026-08-19-tenant-email-design.md+15 −3
diff --git a/docs/superpowers/specs/2026-08-19-tenant-email-design.md b/docs/superpowers/specs/2026-08-19-tenant-email-design.md| index 2c5d9ec8f..96b8941c8 100644 |
| --- a/docs/superpowers/specs/2026-08-19-tenant-email-design.md |
| +++ b/docs/superpowers/specs/2026-08-19-tenant-email-design.md |
| @@ -551,10 +551,16 @@ pause`. `resume` flips it back. |
| **A paused tenant fails loudly.** Its SMTP auth starts failing, which for |
| seapointish means sign-in links stop arriving — the cap working as |
| designed, and exactly the kind of failure that is invisible until someone |
| -complains. So a pause MUST surface in the console's app page and in the |
| -account's audit log at the moment it happens, with the reason and the |
| +complains. So a pause MUST surface at the moment it happens, with the |
| counts that caused it. A silent pause is a bug. |
| +**Amended 2026-08-20 on where the reason lives.** The reason string reaches |
| +the **audit log** and nothing else: `Provisioned` carries only `Active`, so |
| +`carlos email status` shows the pause, the counts and the cap, and points at |
| +the audit log for the reason rather than printing it. Adding |
| +`Provisioned.Reason` is additive and small; until it exists this document |
| +must not claim the status surface carries it. |
| + |
| **Suppression.** SES's account-level suppression list does the enforcing. |
| CARLOS ingests suppression events so a tenant can see and clear its own |
| suppressed destinations; it does not run a second suppression list. |
| @@ -590,7 +596,13 @@ AWS console visit — the CLI's standing rule. |
| which of DKIM / MAIL FROM / sending is not yet green. |
| - `carlos email domains add -app X <domain>` — the custom-domain path. |
| Prints the exact record set to publish, then polls (with `-wait`, on by |
| - default) until SES reports all three green. |
| + default) until SES reports all three green. **On timeout it names the |
| + CANDIDATE SET (DKIM, MAIL FROM, sending), not the specific axis** — |
| + amended 2026-08-20: `VerifyDomain` collapses SES's three-axis status into |
| + one string before persisting, so the individual axes are discarded before |
| + any door or CLI can see them. Re-widening `RegionState` to carry all three |
| + is additive and small; until someone does, this document must not claim |
| + precision the record does not hold. |
| - `carlos email status -app X` — domains and their per-region state, the |
| cap, today's counts, the pause state. |
| - `carlos email test -app X -to ADDR` — **sends a real message** and |