Files
coordination-engine/spec/EmailAdapterSpecification.md

55 KiB
Raw Blame History

EmailAdapterSpecification.md

1. Document Status

Document: EmailAdapterSpecification.md Project: email-connect Target Integration: coordination-engine Adapter Contract: AdapterInterfaceSpecification.md v1.0 Status: Draft v1.0 Primary Scope: Email protocol and provider integration as a coordination-engine adapter

2. Purpose

This document specifies how email-connect models email as a communication protocol and how it integrates with coordination-engine.

email-connect is the reference adapter for the coordination-engine adapter layer. It provides email-specific sending, event ingestion, event normalization, evidence classification, message timelines, endpoint state, and provider abstraction.

The central design objective is to make email useful as a notification and communication channel without overclaiming what email can prove.

Email can often provide evidence that:

  • a message was accepted by an outbound provider
  • a message was accepted by a recipient mail server
  • a message was rejected, bounced, deferred, delayed, dropped, or suppressed
  • a user agent, proxy, scanner, or recipient-like actor interacted with tracking mechanisms
  • a recipient or mailbox system replied, complained, unsubscribed, or emitted an out-of-office response

Email usually cannot prove by itself that:

  • the message reached the recipients inbox
  • the intended human recipient saw the message
  • the recipient understood the message
  • the intended recipient clicked a link
  • the recipient accessed the primary payload
  • the coordination case result was achieved

Therefore, email-connect reports email evidence. coordination-engine decides what that evidence means for a coordination case.

3. Core Principle

Email is a weak-to-medium evidence channel for awareness. It is not a reliable proof channel for payload delivery or intended-recipient action.

The adapter MUST distinguish:

technical email transport evidence
mailbox or endpoint inference
engagement evidence
identity-bound interaction evidence from other systems
coordination result evidence

In the coordination model, most email events map to undef or weak evidence unless paired with stronger evidence from another adapter such as portal-connect, identity-connect, signature-connect, or payment-connect.

4. Architectural Role

4.1 Standalone Role

As a standalone component, email-connect provides:

  • provider-neutral email sending
  • transactional email dispatch
  • provider event ingestion
  • bounce classification
  • complaint and unsubscribe handling
  • suppression list management
  • open and click tracking interpretation
  • recipient endpoint diagnostics
  • email message timelines
  • deliverability diagnostics
  • normalized email event stream
  • evidence-oriented message assessment

4.2 coordination-engine Adapter Role

As a coordination-engine adapter, email-connect provides:

Actions

  • notification.send
  • notification.send_reminder
  • notification.register_tracking_context
  • recipient.suppress
  • recipient.unsuppress
  • optionally notification.cancel where supported by queue state
  • optionally notification.schedule where supported

Signals

  • notification.attempt.accepted_by_adapter
  • notification.attempt.rejected_by_adapter
  • notification.attempt.accepted_by_provider
  • notification.attempt.rejected_by_provider
  • notification.attempt.queued
  • notification.attempt.delayed
  • notification.endpoint.accepted
  • notification.endpoint.deferred
  • notification.endpoint.rejected_temporary
  • notification.endpoint.rejected_permanent
  • notification.endpoint.unreachable
  • notification.channel.complaint_received
  • notification.channel.unsubscribe_received
  • notification.channel.suppression_added
  • notification.channel.reputation_warning
  • interaction.notification.opened
  • interaction.proxy_or_privacy_interaction
  • interaction.link.clicked
  • interaction.scanner_or_bot_interaction
  • interaction.unverified_actor_interaction
  • interaction.reply_received
  • interaction.out_of_office_received

5. Relationship to coordination-engine

email-connect does not own:

  • CoordinationCase
  • intended result evaluation
  • participant-level success
  • case-level success
  • legal delivery interpretation
  • portal access
  • payload retrieval
  • contract acceptance
  • payment settlement
  • signature completion
  • multi-channel escalation policy

email-connect owns:

  • email send requests
  • email provider abstraction
  • email provider identifiers
  • email event ingestion
  • email event classification
  • email-native status timeline
  • email endpoint diagnostics
  • email evidence mapping
  • suppression and complaint handling
  • email-specific uncertainty classification

The boundary rule is:

email-connect reports what happened in the email channel and what that may indicate. coordination-engine decides what that means for the coordination case.

6. Email as Notification, Not Delivery

Within coordination-engine, email is primarily a notification channel.

Email may contain small inline payloads, but in the primary architecture it usually points participants toward an action surface such as:

  • a portal page
  • a secure document download
  • a payment page
  • a contract signing flow
  • an approval screen
  • a form submission page

The actual payload delivery or result-relevant interaction should usually be observed by another adapter.

Example:

email-connect:
  notification.endpoint.accepted
  interaction.link.clicked

portal-connect:
  identity.actor_authenticated
  delivery.payload.downloaded

coordination-engine:
  participant result satisfied

Email acceptance by the recipient mail server is not payload delivery. It is technical notification evidence.

7. Email Message Lifecycle Model

email-connect models an email notification as a lifecycle with multiple observable phases.

message.created
message.rendered
message.render_failed
message.suppression_checked
message.send_requested
message.accepted_by_adapter
message.rejected_by_adapter
message.accepted_by_provider
message.rejected_by_provider
message.queued
message.provider_dropped
message.provider_suppressed
message.deferred
message.endpoint_accepted
message.soft_bounced
message.hard_bounced
message.async_bounced
message.delayed
message.expired_without_delivery
message.opened
message.opened_proxy_like
message.clicked
message.clicked_scanner_like
message.clicked_unverified
message.replied
message.out_of_office_received
message.complaint_received
message.unsubscribe_received
message.suppression_added

The lifecycle is not strictly linear. Events may arrive late, out of order, duplicated, or in conflict.

Example:

provider accepted
endpoint accepted
later async bounce received

The adapter MUST preserve all meaningful events and avoid collapsing the message into a single final status too early.

8. Email Attempt vs Email Message vs Recipient

The adapter MUST distinguish at least three layers.

8.1 EmailMessage

The logical message created by a client or coordination case.

EmailMessage:
  email_message_id: string
  coordination_case_id: string?
  participant_id: string?
  purpose: string?
  subject: string?
  template_ref: string?
  content_ref: string?
  tracking_context: TrackingContext
  created_at: timestamp

8.2 EmailAttempt

One send attempt for one message through one provider/configuration.

EmailAttempt:
  email_attempt_id: string
  email_message_id: string
  provider_name: string
  provider_account_ref: string?
  from_endpoint: EmailEndpoint
  to_endpoint: EmailEndpoint
  cc_endpoints:
    - EmailEndpoint
  bcc_endpoints:
    - EmailEndpoint
  provider_message_id: string?
  adapter_operation_id: string?
  state: EmailAttemptState
  created_at: timestamp
  updated_at: timestamp

8.3 EmailEndpoint

The target email endpoint.

EmailEndpoint:
  endpoint_id: string?
  email_address: string
  display_name: string?
  endpoint_role: from | to | cc | bcc | reply_to | return_path
  verification_state: unknown | syntax_validated | verified | suspected_invalid | invalid
  suppression_state: active | suppressed | complaint_suppressed | bounce_suppressed | unsubscribed | unknown
  metadata: object?

Per-recipient modeling is required because one email message may have multiple recipients and different outcomes per recipient.

For coordination-engine integration, the preferred mode is one logical notification per participant endpoint.

9. Email Attempt States

The adapter SHOULD support these attempt states:

created
rendered
render_failed
suppressed
send_requested
accepted_by_adapter
rejected_by_adapter
accepted_by_provider
rejected_by_provider
queued
scheduled
provider_dropped
provider_suppressed
deferred
endpoint_accepted
soft_bounced
hard_bounced
async_bounced
delayed
expired_without_delivery
complaint_received
unsubscribe_received
unknown

These states are email-native. They are not coordination result states.

10. Email Evidence Assessment

email-connect should provide an email-native assessment separate from coordination-engine state.

EmailEvidenceAssessment:
  email_message_id: string
  participant_id: string?
  category: success | fail | undef
  subclass: string
  confidence: low | medium | high
  strongest_signal: string?
  evidence_summary:
    - string
  recommended_coordination_interpretation: string?

The assessment categories are adapter-level hints.

10.1 Email Adapter Success

Email-level success means only that the email channel produced strong email-channel evidence.

Possible subclasses:

success.endpoint_accepted
success.reply_received
success.human_like_open
success.human_like_click

Important: These are not automatically coordination success.

success.endpoint_accepted is technical success for the email transport, but usually maps to coordination undef.technical_acceptance_only.

10.2 Email Adapter Fail

Email-level fail indicates strong evidence that the email channel failed or should not be used.

Subclasses:

fail.invalid_address
fail.missing_address
fail.render_failed
fail.template_invalid
fail.provider_rejected
fail.provider_dropped
fail.provider_suppressed
fail.hard_bounce
fail.domain_not_found
fail.mailbox_not_found
fail.authentication_rejected
fail.policy_rejected
fail.content_rejected
fail.message_too_large
fail.complaint_received
fail.unsubscribed
fail.suppressed
fail.expired_without_delivery

10.3 Email Adapter Undef

Email-level undef is the normal state when the adapter cannot infer reliable human awareness.

Subclasses:

undef.pending
undef.provider_accepted_only
undef.queued
undef.deferred
undef.delayed
undef.endpoint_accepted_only
undef.no_signal
undef.weak_positive
undef.proxy_open
undef.scanner_click
undef.unverified_click
undef.identity_uncertain
undef.mailbox_possibly_reached
undef.possibly_spam_or_quarantine
undef.possibly_silent_drop
undef.forwarding_unknown
undef.catch_all_domain
undef.conflicting_evidence
undef.channel_degraded
undef.recipient_reported_missing
undef.out_of_office

The undef category must not be empty because email does not provide guaranteed delivery or awareness evidence.

11. Detailed Email Scenario Classification

11.1 Pre-Send Scenarios

Scenario Email assessment Normalized event Notes
Missing address fail.missing_address notification.attempt.rejected_by_adapter No send possible
Invalid address syntax fail.invalid_address notification.attempt.rejected_by_adapter Strong local failure
Template rendering failure fail.render_failed notification.attempt.rejected_by_adapter or payload.validation_failed Notification unusable
Invalid generated link fail.template_invalid notification.attempt.rejected_by_adapter Especially relevant for portal links
Suppression hit fail.suppressed notification.channel.suppression_added or action rejected May be due to bounce, complaint, unsubscribe
Adapter config missing fail.provider_rejected system.adapter.health_changed + action error Operational failure
Provider unavailable before acceptance undef.pending or fail.provider_rejected action result error Depends on retryability
Submission timeout undef.pending action result unknown Could have been accepted despite timeout

11.2 Provider-Side Scenarios

Scenario Email assessment Normalized event Notes
Adapter accepted request undef.pending notification.attempt.accepted_by_adapter Adapter accepted work
Provider accepted message undef.provider_accepted_only notification.attempt.accepted_by_provider Sending began
Provider rejected message fail.provider_rejected notification.attempt.rejected_by_provider Strong failure
Provider queued message undef.queued notification.attempt.queued Pending
Provider delayed message undef.delayed notification.attempt.delayed Pending, may degrade
Provider dropped message fail.provider_dropped notification.attempt.rejected_by_provider or dropped-specific metadata Message may never leave provider
Provider suppressed recipient fail.provider_suppressed notification.channel.suppression_added Channel blocked
Provider rate-limited undef.pending notification.attempt.delayed Retry or wait
Provider quota exceeded fail.provider_rejected or undef.pending action error Policy-dependent

11.3 Recipient Mail Server Scenarios

Scenario Email assessment Normalized event Notes
MX accepted undef.endpoint_accepted_only notification.endpoint.accepted Does not prove inbox placement
Temporary SMTP deferral undef.deferred notification.endpoint.deferred Retry window active
Soft bounce undef.deferred or fail.expired_without_delivery notification.endpoint.rejected_temporary Becomes failure after retry policy
Hard bounce unknown user fail.mailbox_not_found notification.endpoint.rejected_permanent Strong endpoint failure
Domain not found fail.domain_not_found notification.endpoint.unreachable Strong failure
SPF/DKIM/DMARC rejection fail.authentication_rejected notification.endpoint.rejected_permanent Strong sender config/channel failure
Content policy rejection fail.content_rejected notification.endpoint.rejected_permanent Strong failure
Recipient mailbox full undef.deferred notification.endpoint.rejected_temporary May later succeed
Greylisting undef.deferred notification.endpoint.deferred Usually retryable
Async bounce after acceptance fail.async_bounced notification.endpoint.rejected_permanent or temporary Important late failure
Catch-all domain acceptance undef.catch_all_domain notification.endpoint.accepted + metadata Acceptance is especially weak
Forwarding unknown undef.forwarding_unknown notification.endpoint.accepted + metadata if known Intended recipient awareness uncertain

11.4 Mailbox and Inbox Inference Scenarios

Scenario Email assessment Notes
Delivered to inbox Usually not directly observable
Delivered to spam/junk Usually not directly observable
Delivered to promotions/other tab Usually not directly observable
Delivered then moved by user rule Usually not directly observable
Delivered then silently dropped Usually not directly observable
Quarantined by enterprise gateway Usually not directly observable unless feedback received
Accepted by shared mailbox Awareness of intended person uncertain
Accepted by inactive mailbox Endpoint works, awareness uncertain
Out-of-office reply Mailbox likely reached, but action uncertain
User reports missing email Conflicting evidence; treat as suspicious
User reports spam-folder location Useful diagnostic; still not initial success

These cases should usually map to undef.* because email lacks reliable inbox placement proof.

11.5 Open Tracking Scenarios

Scenario Email assessment Normalized event Notes
No open undef.no_signal none Absence of open proves nothing
Pixel loaded normally undef.weak_positive or success.human_like_open interaction.notification.opened Weak-to-medium
Apple/privacy proxy-like open undef.proxy_open interaction.proxy_or_privacy_interaction Not human proof
Gmail/image proxy open undef.proxy_open or weak positive interaction.proxy_or_privacy_interaction Ambiguous
Security scanner image load undef.proxy_open interaction.proxy_or_privacy_interaction Automated
Multiple human-like opens success.human_like_open interaction.notification.opened Still not payload delivery
Open from unusual geography undef.identity_uncertain interaction.notification.opened + metadata May be proxy, forwarding, or risk

Open tracking MUST NOT be treated as strong coordination success.

11.6 Click Tracking Scenarios

Scenario Email assessment Normalized event Notes
No click undef.no_signal none No evidence of interaction
Scanner-like click undef.scanner_click interaction.scanner_or_bot_interaction Do not count as recipient action
Link prefetch undef.scanner_click interaction.scanner_or_bot_interaction Common in enterprise security
Unverified click undef.unverified_click interaction.unverified_actor_interaction Identity uncertain
Human-like click success.human_like_click interaction.link.clicked Medium, still not identity-bound
Click followed by authenticated portal login email event remains weak; portal event is strong Portal adapter provides identity evidence
Click followed by payload download email contributed path evidence; delivery evidence is decisive Delivery/portal event closes case
Token invalid after click fail.template_invalid or undef.identity_uncertain Depends on cause
Expired link clicked undef.weak_positive Awareness possible, action path failed
Forwarded link clicked undef.identity_uncertain Intended recipient unknown

The adapter SHOULD classify likely scanner clicks using timing, user-agent, IP ranges, known security vendors, HEAD/GET patterns, link fan-out, and immediate multi-link access where available.

11.7 Reply and Auto-Reply Scenarios

Scenario Email assessment Normalized event Notes
Human reply received success.reply_received interaction.reply_received Strong awareness signal, identity still may require validation
Out-of-office reply undef.out_of_office interaction.out_of_office_received Mailbox reached, action uncertain
Auto-reply from ticket system undef.identity_uncertain interaction.reply_received + metadata System interaction
Bounce-like auto-response classify as bounce if parseable notification endpoint event Must parse carefully
Reply from delegated/shared mailbox undef.identity_uncertain or medium awareness depends on participant model

11.8 Complaint, Unsubscribe, and Suppression

Scenario Email assessment Normalized event Notes
Spam complaint fail.complaint_received notification.channel.complaint_received Negative channel evidence
Unsubscribe fail.unsubscribed notification.channel.unsubscribe_received Future email use constrained
Bounce suppression added fail.suppressed notification.channel.suppression_added Channel blocked
Complaint suppression added fail.suppressed notification.channel.suppression_added Channel blocked
Manual suppression fail.suppressed notification.channel.suppression_added Operator action
Suppression removed active/unknown notification.channel.suppression_removed Channel may become available again

For legally or operationally required notifications, unsubscribe semantics must be scenario-specific. email-connect records the event; coordination-engine decides whether email remains permissible.

12. Adapter-to-Coordination Mapping

12.1 Core Mapping Table

Email-native event Email assessment coordination-engine event Coordination interpretation
message created undef.pending notification.attempt.created Attempt exists
render failed fail.render_failed notification.attempt.rejected_by_adapter Notification failed before send
adapter accepted undef.pending notification.attempt.accepted_by_adapter Work accepted
adapter rejected fail.provider_rejected or validation fail notification.attempt.rejected_by_adapter Attempt failed
provider accepted undef.provider_accepted_only notification.attempt.accepted_by_provider Weak send evidence
provider rejected fail.provider_rejected notification.attempt.rejected_by_provider Strong attempt failure
provider queued undef.queued notification.attempt.queued Pending
provider delayed undef.delayed notification.attempt.delayed Pending/degraded
provider dropped fail.provider_dropped notification.attempt.rejected_by_provider Strong failure
MX accepted undef.endpoint_accepted_only notification.endpoint.accepted Technical delivery only
temporary deferral undef.deferred notification.endpoint.deferred Pending
soft bounce undef.deferred notification.endpoint.rejected_temporary Retryable/pending
hard bounce fail.hard_bounce notification.endpoint.rejected_permanent Strong failure
async bounce fail.async_bounced notification.endpoint.rejected_permanent or temporary Late failure
open human-like success.human_like_open interaction.notification.opened Weak-to-medium awareness
open proxy-like undef.proxy_open interaction.proxy_or_privacy_interaction Ambiguous
click scanner-like undef.scanner_click interaction.scanner_or_bot_interaction Ambiguous/automated
click unverified undef.unverified_click interaction.unverified_actor_interaction Identity uncertain
reply received success.reply_received interaction.reply_received Medium-to-strong awareness
OOO received undef.out_of_office interaction.out_of_office_received Mailbox reached, action uncertain
complaint fail.complaint_received notification.channel.complaint_received Strong negative channel signal
unsubscribe fail.unsubscribed notification.channel.unsubscribe_received Future channel constraint
suppression added fail.suppressed notification.channel.suppression_added Channel blocked

12.2 Coordination Undef Subclasses

coordination-engine may derive these participant uncertainty classes from email evidence:

undef.pending
undef.technical_acceptance_only
undef.no_signal
undef.weak_positive
undef.identity_uncertain
undef.channel_suspicious
undef.conflicting_evidence
undef.delivery_pending
undef.escalation_required

Email evidence should commonly produce:

undef.pending
undef.technical_acceptance_only
undef.weak_positive
undef.identity_uncertain
undef.channel_suspicious
undef.conflicting_evidence

13. Evidence Grading Rules

13.1 Provider Acceptance

event_type: notification.attempt.accepted_by_provider
evidence_grade:
  strength: weak
  actor_certainty: none
  authority_certainty: none
  payload_certainty: low
  interaction_certainty: none
  timing_certainty: medium
  channel_certainty: medium
  non_repudiation_strength: none
notes:
  - Provider accepted message for processing.
  - Does not prove recipient endpoint acceptance.

13.2 Recipient MX Acceptance

event_type: notification.endpoint.accepted
evidence_grade:
  strength: weak
  actor_certainty: none
  authority_certainty: none
  payload_certainty: low
  interaction_certainty: none
  timing_certainty: medium
  channel_certainty: medium
  non_repudiation_strength: none
notes:
  - Recipient mail server accepted the message.
  - Does not prove inbox placement or human awareness.

13.3 Hard Bounce

event_type: notification.endpoint.rejected_permanent
evidence_grade:
  strength: negative
  actor_certainty: none
  authority_certainty: none
  payload_certainty: none
  interaction_certainty: none
  timing_certainty: medium
  channel_certainty: high
  non_repudiation_strength: low
notes:
  - Strong evidence the email endpoint is not usable for this attempt.

13.4 Soft Bounce / Deferral

event_type: notification.endpoint.rejected_temporary
evidence_grade:
  strength: ambiguous
  actor_certainty: none
  authority_certainty: none
  payload_certainty: none
  interaction_certainty: none
  timing_certainty: medium
  channel_certainty: medium
  non_repudiation_strength: none
notes:
  - Temporary failure or deferral.
  - May later resolve or expire.

13.5 Proxy Open

event_type: interaction.proxy_or_privacy_interaction
evidence_grade:
  strength: ambiguous
  actor_certainty: low
  authority_certainty: none
  payload_certainty: low
  interaction_certainty: low
  timing_certainty: low
  channel_certainty: medium
  non_repudiation_strength: none
notes:
  - Open may be caused by privacy proxy, image proxy, or automated prefetch.
  - Should not be treated as human awareness in high-assurance scenarios.

13.6 Scanner-Like Click

event_type: interaction.scanner_or_bot_interaction
evidence_grade:
  strength: ambiguous
  actor_certainty: low
  authority_certainty: none
  payload_certainty: low
  interaction_certainty: low
  timing_certainty: medium
  channel_certainty: medium
  non_repudiation_strength: none
notes:
  - Click appears automated.
  - Should not be treated as recipient engagement.

13.7 Unverified Click

event_type: interaction.unverified_actor_interaction
evidence_grade:
  strength: medium
  actor_certainty: low
  authority_certainty: none
  payload_certainty: medium
  interaction_certainty: medium
  timing_certainty: medium
  channel_certainty: medium
  non_repudiation_strength: none
notes:
  - Link was clicked, but actor identity is not proven.
  - May indicate awareness but should be confirmed by portal or identity evidence.

13.8 Human Reply

event_type: interaction.reply_received
evidence_grade:
  strength: strong
  actor_certainty: medium
  authority_certainty: low
  payload_certainty: medium
  interaction_certainty: high
  timing_certainty: high
  channel_certainty: high
  non_repudiation_strength: low
notes:
  - Reply indicates mailbox-level interaction.
  - Identity and authority may still require validation.

13.9 Complaint

event_type: notification.channel.complaint_received
evidence_grade:
  strength: negative
  actor_certainty: medium
  authority_certainty: none
  payload_certainty: low
  interaction_certainty: high
  timing_certainty: high
  channel_certainty: high
  non_repudiation_strength: low
notes:
  - Complaint is strong negative channel evidence.
  - Future use of the channel may be constrained.

14. Message Timeline API

email-connect SHOULD expose a message timeline suitable for standalone diagnostics and coordination audit.

EmailMessageTimeline:
  email_message_id: string
  email_attempts:
    - email_attempt_id: string
      provider_name: string
      provider_message_id: string?
      events:
        - EmailTimelineEvent
  current_assessment: EmailEvidenceAssessment
EmailTimelineEvent:
  event_id: string
  event_type: string
  occurred_at: timestamp
  source: adapter | provider | inbound_mail | tracking | operator
  native_event_type: string?
  normalized_event_type: string?
  summary: string
  evidence_grade: EvidenceGrade
  raw_event_ref: string?

15. Adapter Descriptor

email-connect MUST expose an AdapterDescriptor compatible with AdapterInterfaceSpecification.md v1.0.

adapter_id: email-connect.default
adapter_name: email-connect
adapter_version: 1.0.0
adapter_contract_version: 1.0
adapter_types:
  - notification
  - communication
  - interaction
provider_family: email
provider_name: configurable
deployment_mode: external
supported_channels:
  - email
supported_endpoint_types:
  - email_address
supported_actions:
  - action_type: notification.send
    mode: async
    idempotency_required: true
  - action_type: notification.send_reminder
    mode: async
    idempotency_required: true
  - action_type: notification.register_tracking_context
    mode: sync
    idempotency_required: true
  - action_type: recipient.suppress
    mode: sync
    idempotency_required: true
  - action_type: recipient.unsuppress
    mode: sync
    idempotency_required: true
emitted_event_types:
  - notification.attempt.created
  - notification.attempt.accepted_by_adapter
  - notification.attempt.rejected_by_adapter
  - notification.attempt.accepted_by_provider
  - notification.attempt.rejected_by_provider
  - notification.attempt.queued
  - notification.attempt.delayed
  - notification.endpoint.accepted
  - notification.endpoint.deferred
  - notification.endpoint.rejected_temporary
  - notification.endpoint.rejected_permanent
  - notification.endpoint.unreachable
  - notification.channel.complaint_received
  - notification.channel.unsubscribe_received
  - notification.channel.suppression_added
  - notification.channel.suppression_removed
  - notification.channel.reputation_warning
  - interaction.notification.opened
  - interaction.proxy_or_privacy_interaction
  - interaction.link.clicked
  - interaction.scanner_or_bot_interaction
  - interaction.unverified_actor_interaction
  - interaction.reply_received
  - interaction.out_of_office_received
evidence_profile:
  strongest_evidence_level: weak_to_medium
  can_prove_human_awareness: false
  can_prove_payload_delivery: false
  can_prove_identity: false
identity_profile:
  identity_strength: none
  authority_strength: none
limitations:
  - Recipient mail server acceptance does not prove inbox delivery.
  - Absence of bounce does not prove delivery.
  - Open tracking is ambiguous.
  - Click tracking can be caused by security scanners.
  - Email events alone usually cannot prove intended-recipient awareness.
  - Email events do not prove payload access unless the payload is embedded and policy accepts that as sufficient.

16. Action Request Handling

16.1 notification.send

notification.send sends a new email notification.

Required fields:

request_id
action_type
coordination_case_id
participant_id
target_endpoint
content or template_ref
tracking_context
idempotency_key
requested_at

Example:

request_id: req_001
action_type: notification.send
coordination_case_id: case_123
participant_id: participant_456
channel: email
target_endpoint:
  endpoint_type: email_address
  value: recipient@example.com
template_ref: secure-document-available
variables:
  recipient_name: Example Recipient
  portal_link: https://portal.example.com/access/abc
tracking_context:
  correlation_id: corr_789
  coordination_case_id: case_123
  participant_id: participant_456
  notification_id: notif_001
  payload_id: payload_777
idempotency_key: case_123:participant_456:notif_001
requested_at: 2026-01-01T12:00:00Z

16.2 Action Result

The adapter returns:

request_id: req_001
adapter_id: email-connect.default
accepted: true
action_state: accepted
adapter_operation_id: emailop_001
provider_operation_id: providerop_001
initial_events:
  - event_type: notification.attempt.accepted_by_adapter
received_at: 2026-01-01T12:00:01Z

The result does not prove the email was delivered or seen.

17. Provider Abstraction

email-connect SHOULD support a provider abstraction layer.

Provider integration responsibilities:

  • send messages
  • store provider message IDs
  • verify webhooks
  • ingest provider events
  • normalize provider event names
  • parse bounce reasons
  • parse complaints and unsubscribes
  • handle provider-specific suppression events
  • expose provider health

Provider model:

EmailProvider:
  provider_name: string
  provider_account_ref: string
  supported_features:
    - sending
    - webhooks
    - bounce_events
    - open_tracking
    - click_tracking
    - suppression_api
    - template_rendering
  event_mapping_ref: string
  configuration_ref: string

The first implementation MAY use a simulated provider. Real providers SHOULD be added behind this abstraction.

18. Native Provider Event Mapping

The adapter MUST support provider-specific mapping files or code modules.

Examples of provider-native event groups:

accepted
processed
queued
delivered
deferred
delayed
bounce
dropped
failed
rejected
open
click
spam_report
unsubscribe
suppressed
rendering_failed

Important mapping rule:

Provider delivered events MUST be interpreted carefully.

For many providers, delivered means the receiving mail server accepted the email. It MUST map to:

notification.endpoint.accepted

not to coordination success.

19. Bounce Classification

email-connect SHOULD classify bounces into structured reasons.

EmailBounce:
  bounce_type: hard | soft | transient | unknown
  reason_code: string
  enhanced_status_code: string?
  smtp_status_code: string?
  diagnostic_text: string?
  retryable: boolean
  classification:
    - mailbox_not_found
    - domain_not_found
    - mailbox_full
    - message_too_large
    - authentication_failed
    - policy_rejected
    - content_rejected
    - reputation_rejected
    - rate_limited
    - greylisted
    - temporary_server_failure
    - suppressed
    - unknown

Suggested mappings:

Bounce class Email assessment Normalized event
mailbox_not_found fail.mailbox_not_found notification.endpoint.rejected_permanent
domain_not_found fail.domain_not_found notification.endpoint.unreachable
mailbox_full undef.deferred notification.endpoint.rejected_temporary
authentication_failed fail.authentication_rejected notification.endpoint.rejected_permanent
policy_rejected fail.policy_rejected notification.endpoint.rejected_permanent
content_rejected fail.content_rejected notification.endpoint.rejected_permanent
reputation_rejected fail.policy_rejected notification.channel.reputation_warning plus rejection
greylisted undef.deferred notification.endpoint.deferred
temporary_server_failure undef.deferred notification.endpoint.rejected_temporary

20. Suppression Model

email-connect SHOULD maintain or integrate with a suppression model.

EmailSuppression:
  endpoint_ref: EndpointRef
  suppression_type: hard_bounce | complaint | unsubscribe | manual | provider_policy | unknown
  scope: global | tenant | sender_identity | campaign | coordination_case
  reason: string?
  source: provider | adapter | operator | participant
  created_at: timestamp
  expires_at: timestamp?

Suppression should produce evidence:

notification.channel.suppression_added
notification.channel.suppression_removed

coordination-engine decides whether suppression means participant failure, channel failure, alternate channel selection, or manual review.

21. Open and Click Tracking Model

email-connect MAY support open and click tracking, but MUST classify such evidence conservatively.

21.1 Open Tracking

EmailOpenEvent:
  email_message_id: string
  occurred_at: timestamp
  ip_address: string?
  user_agent: string?
  proxy_classification: none | suspected | likely | confirmed
  confidence: low | medium | high

Possible classifications:

human_like_open
proxy_open
privacy_proxy_open
image_proxy_open
security_scanner_open
unknown_open

21.2 Click Tracking

EmailClickEvent:
  email_message_id: string
  link_id: string
  occurred_at: timestamp
  url: string
  ip_address: string?
  user_agent: string?
  scanner_classification: none | suspected | likely | confirmed
  confidence: low | medium | high

Possible classifications:

human_like_click
scanner_click
link_prefetch
multi_link_scan
unverified_click
unknown_click

21.3 Scanner Detection Hints

The adapter SHOULD consider:

  • click occurs immediately after delivery
  • multiple links clicked within seconds
  • HEAD requests or unusual HTTP methods
  • known security user agents
  • known security vendor IP ranges
  • no browser-like behavior
  • link fetched but no subsequent portal session
  • repeated link checks from data center IPs
  • clicks before recipient likely had time to read

Scanner detection is heuristic and MUST be represented as confidence, not certainty, unless the adapter has strong provider-specific evidence.

22. Address and Endpoint Quality

email-connect SHOULD maintain email endpoint quality signals.

EmailEndpointQuality:
  endpoint_ref: EndpointRef
  syntax_valid: boolean?
  domain_exists: boolean?
  mx_exists: boolean?
  verified: boolean?
  catch_all_suspected: boolean?
  role_address_suspected: boolean?
  disposable_suspected: boolean?
  suppression_state: string?
  last_successful_endpoint_acceptance_at: timestamp?
  last_hard_bounce_at: timestamp?
  last_complaint_at: timestamp?
  last_engagement_at: timestamp?

Endpoint quality may be emitted as diagnostics but should not by itself create coordination success.

23. Channel Health

email-connect SHOULD expose channel health.

EmailChannelHealth:
  sender_identity: string
  domain: string?
  provider_account_ref: string?
  status: healthy | degraded | failing | unknown
  authentication_status:
    spf: pass | fail | unknown
    dkim: pass | fail | unknown
    dmarc: pass | fail | unknown
  reputation_status: good | warning | poor | unknown
  bounce_rate: number?
  complaint_rate: number?
  deferral_rate: number?
  provider_degradation:
    - string

Health-related normalized events:

notification.channel.reputation_warning
system.provider.degraded
system.provider.unavailable
system.adapter.health_changed

24. Security Requirements

email-connect MUST:

  • protect provider credentials
  • verify provider webhook signatures where available
  • validate inbound webhook source authenticity where possible
  • avoid logging sensitive message content by default
  • preserve idempotency
  • prevent duplicate sends for repeated idempotency keys
  • support tenant or sender separation where applicable
  • avoid leaking tracking tokens
  • protect suppression lists
  • sanitize inbound replies and auto-replies

25. Privacy Requirements

email-connect SHOULD:

  • store message content only when necessary
  • support metadata-only mode
  • support raw event redaction
  • support configurable retention of raw provider events
  • store endpoint references instead of endpoint values where possible
  • avoid storing unnecessary open/click details if not needed
  • allow tracking to be disabled
  • separate operational diagnostics from coordination evidence
  • support deletion or anonymization workflows where applicable

26. Reliability Requirements

email-connect MUST support:

  • idempotent send requests
  • duplicate webhook event detection
  • out-of-order event handling
  • late bounce handling
  • retryable provider failures
  • non-retryable provider failures
  • provider timeout handling
  • correlation preservation
  • dead-letter handling for unprocessable events

Late events MUST be preserved.

Example:

MX accepted at 10:00
participant unresolved at 14:00
hard bounce arrives at 18:00

The hard bounce must still be recorded and emitted as evidence.

27. Raw Event Preservation

email-connect SHOULD preserve raw provider events or references to them.

RawEmailEventRef:
  raw_event_id: string
  provider_name: string
  storage_ref: string?
  received_at: timestamp
  redacted: boolean

Normalized events should reference raw event data where available:

raw_event_ref: raw_email_event_123

28. Minimal API Surface

email-connect SHOULD expose a headless API.

28.1 Adapter Contract API

Required conceptual operations:

GET /adapter/descriptor
GET /adapter/health
POST /adapter/actions
POST /adapter/events/provider
GET /adapter/events
GET /adapter/messages/{id}/timeline
GET /adapter/messages/{id}/assessment

The actual transport may differ, but these conceptual operations should exist.

28.2 Standalone API

Useful standalone operations:

POST /email/send
GET /email/messages/{id}
GET /email/messages/{id}/timeline
GET /email/messages/{id}/assessment
GET /email/endpoints/{id}/quality
POST /email/suppressions
DELETE /email/suppressions/{id}
GET /email/channel-health

29. Example End-to-End Flow

29.1 Secure Document Notification

  1. coordination-engine creates a coordination case.
  2. portal-connect creates an authenticated document access link.
  3. coordination-engine sends notification.send to email-connect.
  4. email-connect renders and dispatches email.
  5. Provider accepts the message.
  6. email-connect emits notification.attempt.accepted_by_provider.
  7. Recipient MX accepts message.
  8. email-connect emits notification.endpoint.accepted.
  9. User clicks the link.
  10. email-connect emits interaction.unverified_actor_interaction.
  11. User logs into portal.
  12. portal-connect emits identity.actor_authenticated.
  13. User downloads document.
  14. portal-connect emits delivery.payload.downloaded.
  15. coordination-engine marks participant complete.

Email contributed useful path evidence but did not by itself prove the result.

29.2 Hard Bounce and Fallback

  1. email-connect sends email.
  2. Provider accepts the message.
  3. Recipient server returns hard bounce.
  4. email-connect emits notification.endpoint.rejected_permanent.
  5. coordination-engine marks email channel failed for that participant.
  6. Policy engine selects SMS fallback or manual review.

29.3 Scanner Click

  1. Email is accepted by MX.
  2. Link is clicked immediately by a known scanner pattern.
  3. email-connect emits interaction.scanner_or_bot_interaction.
  4. coordination-engine keeps participant in undef.identity_uncertain.
  5. No reminder is suppressed merely because of the scanner click.
  6. If no portal evidence appears after threshold, reminder or alternate channel is triggered.

30. Provider Implementation Guidance

The first real provider integration SHOULD be selected based on:

  • webhook support
  • bounce event quality
  • provider metadata/correlation support
  • suppression API
  • event reliability
  • local availability and cost
  • compatibility with transactional email
  • ability to separate message streams

The implementation SHOULD avoid hardcoding provider semantics into the core email model.

Provider-specific modules should map to the email-native model first, then to normalized coordination events.

Provider event
→ email-native event
→ EmailEvidenceAssessment
→ EvidenceEvent for coordination-engine

31. Message Steparation

email-connect SHOULD support sender identities or message streams.

Recommended streams:

transactional
notification
legal_or_high_assurance_notice
marketing
system_alert
test

High-assurance or legally relevant notifications SHOULD NOT share reputation-critical infrastructure with marketing traffic unless explicitly accepted by policy.

Stream separation may affect:

  • sender domain
  • return path
  • DKIM identity
  • provider account
  • suppression scope
  • complaint handling
  • deliverability diagnostics

email-connect does not by itself provide legal proof of delivery, legal notice, acceptance, signature, or contract closure.

It provides evidence from the email channel.

Scenario-specific applications and coordination-engine policies may combine email evidence with stronger evidence from portal, identity, signature, payment, archive, or manual processes.

The adapter MUST avoid naming technical email events in ways that imply legal success.

For example:

Use:

notification.endpoint.accepted

Avoid:

recipient_notified
legal_delivery_completed

33. MVP Scope

The first useful version of email-connect should implement:

  1. Adapter descriptor.
  2. Adapter health endpoint.
  3. notification.send.
  4. Idempotent send request handling.
  5. Simulated provider or one real provider.
  6. Email message and attempt records.
  7. Provider event ingestion.
  8. Basic bounce classification.
  9. Basic open/click classification.
  10. Evidence event generation.
  11. Message timeline.
  12. Message assessment.
  13. Suppression support.
  14. Mapping to AdapterInterfaceSpecification.md v1.0.

MVP Required Email Events

notification.attempt.accepted_by_adapter
notification.attempt.rejected_by_adapter
notification.attempt.accepted_by_provider
notification.attempt.rejected_by_provider
notification.endpoint.accepted
notification.endpoint.deferred
notification.endpoint.rejected_temporary
notification.endpoint.rejected_permanent
interaction.proxy_or_privacy_interaction
interaction.scanner_or_bot_interaction
interaction.unverified_actor_interaction
notification.channel.complaint_received
notification.channel.suppression_added

MVP Acceptance Criteria

The MVP is acceptable when it can:

  1. Accept a coordination-compatible send request.
  2. Dispatch or simulate an email.
  3. Preserve correlation and idempotency.
  4. Ingest or simulate provider events.
  5. Produce normalized evidence events.
  6. Classify MX acceptance as weak technical evidence.
  7. Classify hard bounce as strong failure evidence.
  8. Classify proxy opens and scanner clicks as ambiguous.
  9. Provide a message timeline.
  10. Provide an email evidence assessment.
  11. Integrate with coordination-engine without overclaiming success.

34. Future Extensions

Potential future capabilities:

  • multi-provider routing
  • provider failover
  • domain reputation monitoring
  • inbox placement seed testing
  • DMARC aggregate report ingestion
  • BIMI diagnostics
  • advanced bounce parsing
  • advanced scanner detection
  • inbound reply classification
  • natural-language reply intent extraction
  • tenant-specific suppression scopes
  • message stream isolation
  • deliverability analytics
  • adaptive sending policies
  • integration with archive systems
  • S/MIME or PGP support
  • signed email support
  • email authentication diagnostics
  • AI-assisted deliverability analysis

35. Non-Goals

email-connect is not:

  • a marketing automation platform
  • a newsletter campaign manager
  • a CRM
  • a full workflow engine
  • a legal delivery service by itself
  • a document portal
  • a payment system
  • a signature system
  • the owner of coordination case success

It may integrate with such systems or be used by them.

36. Summary

email-connect models email as a useful but uncertain communication and notification channel.

Its job is to:

  • send emails
  • ingest provider events
  • classify email outcomes
  • normalize email evidence
  • preserve message timelines
  • expose endpoint and channel diagnostics
  • integrate cleanly with coordination-engine

The key rule is:

Email events are evidence, not result satisfaction. email-connect reports email-channel facts and uncertainty. coordination-engine evaluates intended results.