Repository navigation
Conversation
5e7f579 to
86b2ad7
Compare
Coherence4 spec problems · 0 failing chokepoints · 2 spec gaps · 0 guard failures 44 components, 7 bullets (5 invariants, 2 requirements), 4 problems Spec problems (spec --check)
Chokepoints: none declared. Spec gaps: 2 entrances with outside or unknown trust and no traced control, and 10 more held by the adoption baseline
Close one with |
Node SDK compliance v2Commit: 8384b8c Capture v0 — acceptance✅ 28 passed / ❌ 3 non-passing / Drill-down: run artifacts → ❌ server_snapshot_payload_false — failed_assertionExpected native data result Code: Failed step: acceptance/public/evaluate-flags.feature:868 the public snapshot outcomes should have these semantics: ❌ server_snapshot_payload_zero — failed_assertionExpected native data result Code: Failed step: acceptance/public/evaluate-flags.feature:868 the public snapshot outcomes should have these semantics: ❌ server_snapshot_payload_null — failed_assertionExpected native data result Code: Failed step: acceptance/public/evaluate-flags.feature:868 the public snapshot outcomes should have these semantics: Harness exit: 1; report validation exit: 1. Capture v1 — acceptance✅ 28 passed / ❌ 3 non-passing / Drill-down: run artifacts → ❌ server_snapshot_payload_false — failed_assertionExpected native data result Code: Failed step: acceptance/public/evaluate-flags.feature:868 the public snapshot outcomes should have these semantics: ❌ server_snapshot_payload_zero — failed_assertionExpected native data result Code: Failed step: acceptance/public/evaluate-flags.feature:868 the public snapshot outcomes should have these semantics: ❌ server_snapshot_payload_null — failed_assertionExpected native data result Code: Failed step: acceptance/public/evaluate-flags.feature:868 the public snapshot outcomes should have these semantics: Harness exit: 1; report validation exit: 1. Capture v0 — migration✅ 55 passed / ❌ 1 non-passing / Drill-down: run artifacts → ❌ migration/yaml-parity-v1/remote-flags-v1.feature::Omitted GeoIP settings default to enabled in flag requests — failed_assertionFlags field differs Code: Failed step: migration/yaml-parity-v1/remote-flags-v1.feature:134 the first flags request field "geoip_disable" should equal JSON false Operation: Field: Expected: false Actual value: true Harness exit: 1; report validation exit: 1. Capture v1 — migration✅ 120 passed / ❌ 1 non-passing / Drill-down: run artifacts → ❌ migration/yaml-parity-v1/remote-flags-v1.feature::Omitted GeoIP settings default to enabled in flag requests — failed_assertionFlags field differs Code: Failed step: migration/yaml-parity-v1/remote-flags-v1.feature:134 the first flags request field "geoip_disable" should equal JSON false Operation: Field: Expected: false Actual value: true Harness exit: 1; report validation exit: 1. |
|
Note 🤖 Claude Opus 5.5 responding on behalf of Michael Decisions made in the agent session:
|
86b2ad7 to
db5ac2d
Compare
The template form posts template: { id } to /messaging/send/email/ instead of
the template's own send route, once the server takes it there. Callers change
nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fake email API no longer invents a template_not_found code, and the changeset states the route change only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed second argument Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
db5ac2d to
8384b8c
Compare
Part of the code-first rebuild of posthog-node's email API; replaces parts of PostHog#5371.
Problem
After #5, a template made in PostHog still sends on its own route,
messaging_templates/{id}/send/, which ignorescaptureEngagementand the newer send checks. This PR sends it onsend/email/like code content, astemplate: { id }. No caller change.Stacks on #5. Needs the server's
template: { id }arm ofsend/email/.Impact
Same as the stack: Grow Workflows, billed
workflows_emailsfrom API sends. This PR makes both forms behave the same, socaptureEngagement: falseworks on a template send.Merge Danger
Warning
🟠 Merge risk: medium · two-way door (merge-risk rubric)
template: { id }arm, every template send fails with400namingtemplate, so this must ship with or after that server change.Changes
POST /api/projects/@current/messaging/send/email/as{ template: { id }, to, identifiers?, message_data?, capture_engagement }.captureEngagementnote that the template route follows the project setting is gone.Evidence
posthog.emails.send()on a real client withFakeEmailsApiat thefetchboundary.capture_engagement.86b2ad76: nodevitest(1322 passed), edge (1322 passed),tsc,oxlint,oxfmt, build, references committed; corevitest.db5ac2dais the same change rebased onto feat(node): send transactional email from code with emails.send #5's references commit, andpnpm check:public-apipasses on it.Live run, done on 2026-10-26 at
8384b8ce, against Django at feat(messaging): send each email once per idempotency key posthog#578c4c5ff05d2f(slice 09, with 05e20426aa1e5, 066730e409b4band 08d0eeb308f962below it) and cdp-api at feat(cdp): replay a keyed send after its workflow or default sender changes posthog#5801a43bdda327, on a local stack with a dev mail catcher:templateData: { link }templateDatareplyToinvalid_formonreplyTo, withwhyandfix; no request sentEarlier live run, on the template-send slice (feat(messaging): send a stored template by key on send/email posthog#574 at
bf2e702c864)templateKey,subject,htmltemplateId,templateData: { link },captureEngagement: false; the body is{ template: { id }, message_data, capture_engagement: false, ... }onsend/email/templateDatareplyTotemplateId,templateData,replyTo{ data: null, error }withinvalid_formonreplyTo,whyandfix; no request sentIn the template case, the link still goes through the click-tracking redirect although the send passes
captureEngagement: false. That redirect comes from the server.Cross-version (this SDK against a server without the arm): gap; expected
400ontemplate, see Merge Danger.Production shape: gap until read-only production access is available.
Decisions
Open: release order, see #5 (this PR ships with or after the server's
template: { id }arm).Involvement: review round 1 (GPT-6.1 Sol: Correctness, Risk, Design, Anti-Overengineering, two Team perspectives; Opus 5.5: Fresh eyes; 2 fixed, 1 for Michael), two final reads (clean), live run captured.
Release info Sub-libraries affected
Libraries affected
Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
claude-opus-5-5) in Claude Code, as build lane js2 of map Map: send code-managed email templates with one PostHog call posthog#461, directed by Michael. The code comes from the reviewed stack feat(node): send transactional email with the flat SDK contract PostHog/posthog-js#5312, feat(node): send email content from code, uploading local templates by hash PostHog/posthog-js#5371, feat(node): send cc, bcc, headers, tags and attachments with a code send PostHog/posthog-js#5373 and feat(node): read an email's status with emails.get PostHog/posthog-js#5372 (closed; fork copies feat(node): send transactional email with the flat SDK contract #1–feat(node): read an email's status with emails.get #4), restacked code-first. The equality with each reviewed head is checked by diff and listed in the lane ledger.🤖 Generated with Claude Code