Skip to content

feat(cdp): deliver and charge a repeated sandbox address once - #636

Draft
Silthus wants to merge 2 commits into
sbx-api/integration-nodefrom
sbx-api/sa1a-envelope
Draft

Silthus wants to merge 2 commits into
sbx-api/integration-nodefrom
sbx-api/sa1a-envelope

Conversation

@Silthus

@Silthus Silthus commented Nov 1, 2026 •

Copy link
Copy Markdown
Owner

Part of map #461 (sandbox sender for API sends). SA1 part 1 of 3, split from #632: the sandbox envelope and the api source. Sits on sbx-api/integration-node, a merge of #584 and #587. Part 2 is #637, part 3 is #638, and #633 sits on top.

Problem

  • A sandbox email that repeats an address across To, CC and BCC lists it once per copy in the SES envelope and charges the project allowance once per copy.
  • So the code-send check in part 2 can't predict what the worker charges, and sandbox events can't tell an API send from a workflow send.

Merge Danger

Warning

🔴 Merge risk: high · two-way door: a revert brings back the per-copy envelope and charge

  • Email delivery path. The worker's sandbox SES envelope lists a repeated address once, and the allowance charges it once.
  • Only a sandbox integration takes this path, and one exists only behind workflows-sandbox-sender.

Changes

  • The sandbox worker sends a repeated address once. It builds one envelope from To, CC and BCC that keeps the first sighting of each address, ignoring case. SES gets that list, and the daily allowance charges each address once.
  • Sandbox sent and blocked events from the send API carry source: api, with their own blocked-event window.
  • The address parsing moves unchanged from email.service.ts to sandbox-envelope.ts (mechanical).

How did you test this code?

Test seams: the worker's executeSendEmail (email.service.test.ts).

Test rationale: a repeated address across To, CC and BCC reaches SES once and is charged once, and an API send records source: api.

Proofs: the live run, cross-version run and shadow diff ran on #632, whose code equals this stack's top (part 3). Prod shape is a gap until read-only production access exists on 2026-11-02.

CI: this PR sits on an integration base until the sandbox stack (through #587) and the send stacks (through #584 and #585) reach master.

Release status

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

Docs update

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Opus 5.5 (claude-opus-5-5)

Skills: /tdd, /writing-tests, /qa-swarm, /pr-description, /writing-pr-descriptions

Question Answer Who Where
How is SA1 split for review? Three stacked PRs: envelope and source, the admission gate, delivery_mode 👍 Accepted default map #461 lane handoff, 2026-11-01

Involvement: the SA1 review carries over from #632, whose code these three parts hold: one design pass, a 7-lens security swarm, a 4-lens fix round and one clean final read (GPT-6.1 Sol and Claude Opus 5.5). One GPT-6.1 Sol read of this part came back clean. A GPT-6.1 Sol read of the merge that took the newer base came back clean.

More context for AI agents

🤖 Generated with Claude Code

The sandbox worker builds one envelope from to, cc and bcc that lists each address once, case-insensitively, so SES delivers a repeated address once and the daily allowance charges it once. A send from the transactional email API records `source: api` on the sandbox sent and blocked events, with its own blocked-event window.

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

This branch has not been deployed

No deployments
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