Repository navigation
feat: add the emails capability spec - #159
Merged
Merged
Conversation
Adds the canonical contract for server-side transactional email: send from a template and read an email's status. Derived from posthog-node and posthog-python. Includes the archived add-emails change, an acceptance feature, and the README index row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be
Contributor
PostHog Review · Deep · reviewed
|
| Step | Status | Result |
|---|---|---|
| Prepare the diff | done | 9 files, 3 chunks |
| Pick perspectives | done | 3 perspectives |
| Run review passes | done | 8 issues (+2 blind-spot) |
| Merge overlapping findings | done | 10 → 8 |
| Validate findings | done | 7 kept, 1 dismissed |
| Publish | done | 7 posted (view review) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be
mayteio
marked this pull request as ready for review
October 29, 2026 12:24
Contributor
There was a problem hiding this comment.
See this review and its findings in PostHog Review.
- Name a local invalid_* argument error validation_error. - Keep native argument exceptions alongside the single raised email error type. - Bound email draining by the remaining shutdown timeout. - Treat a 2xx without a message ID as api_error, without a retry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be
dustinbyrne
approved these changes
Oct 29, 2026
dustinbyrne
left a comment
Contributor
There was a problem hiding this comment.
The template-send and status contract is coherent, and the previous review concerns are addressed. Two non-blocking documentation accuracy suggestions are inline.
AI-assisted review.
- The purpose says one key per call lets PostHog deduplicate retries, instead of promising a send never goes out twice. The design records the pending-reservation gap. - The conformance table pins the assessed revisions, marks Python's per-send max_retries as passing from 5abcf29, and records synchronous Python shutdown draining as a gap. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be
This was referenced Oct 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Transactional email ships in posthog-node (PostHog/posthog-js#5418) and posthog-python (PostHog/posthog-python#1093), but the shared contract lives only in a comment on PostHog/posthog#120921. Other server SDKs have nothing to implement against, and the compliance audit does not track email.
Changes
openspec/specs/emails/spec.md, for server SDKs only, with 20 requirements:send,get) and the email options;acceptance/public/emails.feature: server scenarios for the request, the host refusal, the missing key, idempotency across retries, which responses retry,Retry-After, error names, the status read, and a disabled client. They carry the legacy@servertag and are not opted into the integration suite, because no harness binding exists yet.openspec/changes/archive/2026-10-29-add-emails/(proposal, design, tasks, delta), and the capability added to the README index andproject.md.Decisions where the two SDKs differ (details in the archived
design.md):{ data, error }, and posthog-python raises.max_retries: canonical, because the shared contract named it. posthog-python does not have it yet.Not covered: the code-content form and
capture_engagement, which the send API does not accept yet.Validation
openspec validate --specs --strict --no-interactivewith 1.4.1, the CI version: 68 passed, 0 failed.openspec validate add-emails --strictwith 1.15.0 before archive: valid.Agent context
Autonomy: Human-driven (agent-assisted)
Tools: PostHog Desktop (Claude Code, Claude Opus 5.5), OpenSpec CLI, Git
🤖 Generated with Claude Code
Created with PostHog Desktop