The direct answer

Drive explicit SMTP envelope addresses and controlled visible headers from the same approved message record. Interpret the documented submission outcome for each intended recipient, including partial refusal and uncertainty. A visible To field, recipient-command acceptance or successful relay submission does not prove mailbox delivery.

Review the transport destination as well as the message display

An AI application reviews a plain-text maintenance note for two known recipients, R-A and R-B. Its preview looks correct, but the sending adapter obtains transport recipients from a different object. An unchanged preview cannot establish where that adapter will submit the note.

This original worksheet selects Python’s smtplib reference and EmailMessage reference, both identifying Python 3.15.2, with RFC 5321 for SMTP outcome meaning. No installed Python, relay or account was inspected.

Current authorization and exact message approval remain prerequisites. This guide adds the adapter’s routing-field and submission-evidence decision. It does not authorize contacting anyone, and every worksheet case is PROPOSED_UNRUN.

Choose explicit envelope arguments instead of inference

The smtplib documentation distinguishes transport-envelope arguments from headers: sendmail uses from_addr and to_addrs for the envelope without modifying message headers. send_message delegates to sendmail. When envelope arguments are omitted, send_message extracts Sender/From and To/Cc/Bcc, with documented Resent handling. It suppresses Bcc and Resent-Bcc in transmitted headers.

Our stricter profile always supplies both from_addr and to_addrs explicitly. It excludes Cc, Bcc, Sender and every Resent field entirely. Bcc suppression is not an approval control: removing a visible field does not establish that the envelope contains only reviewed recipients. Adding R-C to an explicit list would still be an unauthorized expansion.

Keep message routing independent of model output. Resolve sender S-A and recipient records R-A/R-B through a trusted approved registry. Their separately validated, already suitable ASCII mailbox values are prerequisites; this article supplies no address parser, normalization rule or recipient-identity assurance.

Declare a complete controlled construction contract

Invent immutable action A-A binding configured sender record S-A, exactly R-A and R-B, reviewed subject revision H-2, plain-text body revision T-4 and trusted date value D-1. Approval covers those associations. The positive path uses a newly constructed standard EmailMessage owned only by the adapter, not a model-provided instance, subclass, raw MIME message or callable object.

Original A-A field-source contract; symbolic labels only
Field or componentExclusive trusted source
Explicit from_addrS-A’s approved envelope mailbox
Explicit to_addrs listExactly R-A and R-B mailbox values
Single From and To headersThe same sender and two recipient records, rendered by the trusted fixed template
Single Subject and Date headersReviewed single-line H-2 and fixed D-1 values
Payload and content metadataOnly approved ASCII plain text T-4 and the trusted template’s fixed plain-text MIME/encoding configuration
All other caller-supplied headers, parts and optionsNot admitted; no Cc/Bcc/Resent/Reply-To, attachments, HTML or model-selected ESMTP options

This is a construction contract, not a runnable factory or proof of safe serialization. The actual policy/content manager, encoding and generated header inventory need independent implementation verification before use. Python documents set_content as delegation to a content manager; do not infer that this call sanitizes arbitrary objects or preserves a desired policy automatically.

The EmailMessage reference also documents duplicate headers and undefined single-field lookup when duplicates exist; assignment does not simply overwrite. Do not approve a message by reading one To value from arbitrary input. The narrow profile prevents unreviewed fields from entering construction rather than repairing unknown MIME with a few accessor calls.

Separate recipient acceptance from message acceptance

RFC 5321 sections 3.3 and 4.2.5 distinguish recipient commands from the final response after message data. Positive final completion transfers responsibility to the receiving SMTP server; it does not establish completed mailbox delivery. A preliminary recipient acceptance or permission to start data is insufficient.

Python documents a normal sendmail return when at least one recipient is accepted, with a dictionary of refused recipients; all-recipient refusal raises SMTPRecipientsRefused. Interpret that through send_message’s documented delegation and the complete submission outcome. Under the stated relay prerequisites, a normal return with R-B refused supports R-A submitted-to-relay and R-B refused. An empty refusal map supports all intended recipients submitted, not delivered.

If recipient commands were accepted but the message data is refused, do not promote those earlier acceptances to submitted status. Keep refusal phases and actual evidence distinct. A disconnect or unavailable final result can leave submission unknown. RFC 5321 section 4.5.3.2.6 explains duplicate risk around final-response timeouts; this application must not blindly replay the whole approved set.

Review eight inert routing and outcome cards

Original recipient-specific submission worksheet — PROPOSED_UNRUN
Inert caseProposed disposition
A-A unchanged; explicit envelope and controlled headers contain exactly R-A/R-BEligible for the specifically authorized submission plan only after every prerequisite
Model observation proposes R-C or another senderReject expansion; retain approved registry associations
Envelope argument omitted or sourced from another objectHold under this explicit-envelope profile
Hidden, Resent or duplicate routing-related header appearsReject outside controlled construction; no silent repair
Normal complete submission return identifies only R-B refusedRecord R-A submitted-to-relay, R-B refused and partial overall status
Documented all-recipient refusalRecord that refusal; no accepted-submission claim from the visible To list
Connection or final outcome evidence is lostKeep affected submission unknown; reconcile before any separately authorized retry
Relay submission accepted without downstream evidenceDelivery, mailbox presence, reading and later forwarding remain unknown

Keep the evidence claim at the boundary actually observed

A useful status names recipients separately: “R-A submitted to relay; R-B refused.” Preserve the attempted recipient set and supported refusal categories in protected records without copying raw message contents or credentials into ordinary logs. Do not repeat the accepted subset merely to recover a refused or unknown entry; any later attempt needs its own supported recovery and current authority decision.

Configured relay trust, authentication, TLS, mailbox validation and aliases or list expansion are unverified prerequisites or exclusions here. Neither explicit arguments nor matching visible From establishes universal sender authentication, confidentiality, consent or ultimate destination behavior. This guide supplies no Message-ID deduplication or exactly-once guarantee.

No Python email/smtplib import, message/header construction, serialization, SMTP connection, send, account access, API/model or runtime fixture occurred for these cases. Boundary is prelaunch and does not claim a shipped mail sender. Its synthetic demo checks concern separate policy, JSON-export and approval-status behavior.

Primary sources

Official references supporting the guidance. Examples in this guide are synthetic and are not reports of a production incident.

  1. Python 3.15.2: smtplib SMTP client reference
  2. Python 3.15.2: EmailMessage reference
  3. RFC 5321: Simple Mail Transfer Protocol