Skip to content

fix(cdp): skip email sends through the sandbox sender in the worker - #611

Closed
Silthus wants to merge 1 commit into
masterfrom
workflows-sandbox-product/worker-skip
Closed

Silthus wants to merge 1 commit into
masterfrom
workflows-sandbox-product/worker-skip

Conversation

@Silthus

@Silthus Silthus commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Problem

Impact

Pays into Workflows activation (first billed action after a team creates its first workflow), through the sandbox funnel step. This PR alone moves nothing a user sees. It makes a send through the sandbox sender fail safe.

Merge Danger

Caution

🔴 Merge risk: high · two-way door (merge-risk rubric)

  • The change sits on the email send path of the CDP worker. A bug there could skip or fail sends for every project.
  • Limited by: the skip matches only provider: sandbox, which no sender row has until feat(workflows): provision a managed sandbox email sender #601 lands behind the workflows-sandbox-sender flag. The rest of the email service suite runs unchanged on base and head.

Changes

  • A workflow email step or test send through a sandbox sender now skips. The invocation log reads "Skipping send: the sandbox sender can't send email yet. Choose a sender on your own verified domain in this email step."
  • The send result is skipped with that reason, and the step pushes success: false, so the workflow does not treat it as delivered.
  • The worker never calls SES for it.
  • When the sandbox delivery stack lands, its sandbox provider case replaces this skip.

Production lines (tests excluded): 12, from git diff --numstat.

How did you test this code?

  • Worker: email.service.test.ts on this head: 142 passed. The two sandbox cases failed on base, where the send reported success.
  • Typecheck: worker pnpm typescript:check reports no errors on the stack head.
  • CI: not run. Fork CI cannot run because the fork lacks the GitHub App secret. The mix-lanes check on the fork compares each layer with master, so it flags the upper layers until the lower ones land.

Test rationale:

  • email.service.test.ts "sandbox sender": a workflow send and a test send through the sandbox row skip with the reason and never call SES. Both failed on base, where the send reported success. The nearest test, the suspension block, covers a different gate.

Proof (fleet proof, on a preview of the stack head, which carries this worker change unchanged):

  • Live run: each email step ran for real through the CDP worker. A sandbox send to a domain with mail servers now logs the warning "Skipping send: the sandbox sender can't send email yet…" and moves on. An own-sender step and a recipient domain without mail servers still skip at the bounce check, as before.
  • Shadow diff, master against the stack head: the one worker change is the sandbox send. Master logs "Email sent to … from Hogflix via PostHog" and reports it as accepted, though nothing went out. The head skips it. The other changed cases belong to feat(workflows): provision a managed sandbox email sender #601 and feat(workflows): validate sandbox sender use at save time #603.
  • Prod shape: gap, accepted under a standing rule until read-only production access is available.
  • Review: one round by GPT-6.1 Sol, no findings.

Release status

  • This change is behind a feature flag and is not available to users

Docs update

None here. #601 updates docs/internal/workflows-email-sending-tiers.md with the skip.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Opus 5.5; review by GPT-6.1 Sol

Decisions

Question Answer Who Where
Sends through the sandbox row before its delivery route exists The worker skips them with a logged reason and success: false, instead of falling through the provider switch as a success 🤖 Agent Silthus/personal#200 (resolution)
Where the worker skip lands Its own PR at the bottom of the stack, because the merge queue rejects PRs that mix Node with Python or frontend changes, and the skip must deploy before the API that creates the row 🤖 Agent Silthus/personal#200 (resolution)

Involvement: no grilling rounds; one design pass and two review rounds on the combined change, then one review round on this PR (GPT-6.1 Sol); proof captured.

🤖 Generated with Claude Code

The sandbox sender has no delivery route in the worker yet. A send through it
now skips with a reason in the logs instead of passing the provider switch as
a success. This lands before any API can create a sandbox sender row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Silthus

Silthus commented Oct 28, 2026

Copy link
Copy Markdown
Owner Author

Closed in the sandbox sender restack (Silthus/personal#71). The worker's own sandbox case in #594 replaces this guard, and #601 no longer carries a Node change.

@Silthus Silthus closed this Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant