Files
coordination-engine/spec/HybridmailAdapterSpecification.md

2077 lines
65 KiB
Markdown

# HybridmailAdapterSpecification.md
## 1. Document Status
**Document:** HybridmailAdapterSpecification.md
**Project:** hybridmail-connect
**Target Integration:** coordination-engine
**Adapter Contract:** AdapterInterfaceSpecification.md v1.0
**Specification Version:** 1.1
**Status:** Updated Draft
**Primary Scope:** Provider-neutral hybrid-mail adapter baseline, provider flavor contract, lifecycle semantics, evidence model, and conformance requirements.
## 2. Version 1.1 Change Summary
This version strengthens the original hybrid-mail adapter specification based on provider flavor analysis for:
* Binect
* Pingen
* Deutsche Post / E-POSTBUSINESS API
The main changes are:
1. Added mandatory provider flavor contract.
2. Added machine-readable capability profile.
3. Added layered lifecycle model.
4. Added provider status mapping registry.
5. Added postal product evidence semantics.
6. Strengthened distinction between ordinary dispatch and delivery confirmation.
7. Strengthened idempotency and duplicate physical dispatch prevention.
8. Expanded validation issue taxonomy.
9. Added batch and child-letter semantics.
10. Added polling, webhook, and late-event ingestion model.
11. Added evidence ceiling model.
12. Added coding-agent implementation and conformance requirements.
## 3. Purpose
This document specifies the provider-neutral hybrid-mail adapter baseline for `hybridmail-connect`.
Hybrid mail means that a digital payload, usually a PDF or print-ready document, is submitted to a provider that organizes physical production and postal dispatch. The provider may validate the document, print it, fold it, insert it into an envelope, frank it, hand it over to a postal carrier, and optionally provide tracking, return-mail information, registered-mail evidence, delivery-confirmation evidence, or address-correction information.
This specification defines the common model that provider-specific flavors MUST map into.
Known provider flavors include:
* `HybridmailBinectSpecification.md`
* `HybridmailPingenSpecification.md`
* `HybridmailDpagSpecification.md`
Future provider flavors SHOULD use the same baseline.
## 4. Core Principle
Hybrid mail is a controlled physical-delivery channel initiated through digital submission.
The adapter MUST distinguish:
```text
digital submission
provider acceptance
document validation
production readiness
print production
enveloping
franking
handover to postal carrier
postal delivery evidence
registered or tracked delivery evidence
undeliverable / return-mail evidence
physical delivery uncertainty
coordination result evidence
```
Normal physical letter dispatch usually cannot prove that the intended recipient personally received, opened, read, understood, or acted on the payload.
The adapter reports hybrid-mail evidence. `coordination-engine` decides whether that evidence satisfies the coordination case.
## 5. Relationship to coordination-engine
`hybridmail-connect` does not own:
* `CoordinationCase`
* intended result evaluation
* participant-level success
* case-level success
* legal notice interpretation
* proof that the recipient opened or read the letter
* contract acceptance
* payment settlement
* signature completion
* follow-up and escalation policy
`hybridmail-connect` owns:
* hybrid-mail provider abstraction
* provider flavor capability declaration
* document submission
* provider identifiers
* document validation result mapping
* print/shipping option mapping
* production status mapping
* postal handover status mapping
* status polling and webhook ingestion
* return-mail / undeliverable status normalization
* registered-letter or delivery-confirmation evidence normalization
* hybrid-mail-native message timeline
* hybrid-mail evidence assessment
The boundary rule is:
> hybridmail-connect reports what happened in the hybrid-mail channel and what that may indicate. coordination-engine decides what that means for the coordination case.
## 6. Hybrid Mail as Delivery Channel
Within `coordination-engine`, hybrid mail is primarily a **delivery channel**.
It is used when the communication payload itself is physically delivered as a paper letter.
Examples:
```text
PDF letter submitted for physical mailing
invoice printed and posted
contract notice sent by post
dunning letter sent as registered mail
mass mailing sent as bulk/serial letters
confidential employee payroll letter mailed physically
```
Hybrid mail may also produce notification-like evidence, because physical payload dispatch can be a strong delivery attempt. However, even physical delivery normally does not prove that the intended human personally read or understood the letter.
For high-assurance scenarios, hybrid-mail evidence may be combined with:
* registered-mail evidence
* delivery confirmation
* return-mail processing
* manual evidence
* recipient response
* payment event
* signature event
* portal access
* acknowledgement
## 7. Normative Provider Flavor Contract
Every provider-specific implementation MUST define a provider flavor specification.
A provider flavor specification MUST declare:
```text
provider identity
capability profile
supported file types
supported postal products
native lifecycle model
native status model
validation issue model
option model
idempotency model
webhook model
polling model
delivery confirmation model
return-mail model
batch/child-letter model
evidence mapping
known limitations
test requirements
```
A provider flavor MUST NOT claim support for any lifecycle event, postal product, webhook, delivery confirmation, return-mail process, idempotency behavior, or production-status mapping unless it explicitly declares the capability.
## 8. Provider Flavor Descriptor
Each provider flavor MUST expose a machine-readable descriptor.
```yaml
HybridmailProviderFlavorDescriptor:
provider_name: string
provider_label: string
provider_family: hybridmail
provider_version: string?
adapter_contract_version: string
parent_specification: HybridmailAdapterSpecification.md
deployment_mode: embedded | sidecar | external | unknown
capability_profile: HybridmailCapabilityProfile
supported_file_types:
- string
supported_attachment_file_types:
- string
supported_postal_products:
- HybridmailPostalProduct
status_mapping_ref: string
validation_issue_catalog_ref: string
product_evidence_matrix_ref: string
known_limitations:
- string
```
## 9. HybridmailCapabilityProfile
Provider capabilities MUST be represented explicitly.
```yaml
HybridmailCapabilityProfile:
supports_document_upload: boolean
supports_validation: boolean
supports_attachments: boolean
supports_preview: boolean
supports_single_letter: boolean
supports_bulk: boolean
supports_serial_letters: boolean
supports_status_polling: boolean
supports_webhooks: boolean
supports_track_and_trace: boolean
supports_production_status: boolean
supports_postal_handover_status: boolean
supports_delivery_confirmation: none | product_dependent | full | unknown
supports_registered_mail: boolean
supports_return_mail: boolean
supports_address_correction: boolean
supports_international_mail: boolean
supports_scheduled_dispatch: boolean
supports_cover_sheet: boolean
supports_address_positioning: boolean
supports_automatic_positioning: boolean
supports_idempotency: native | adapter_managed | none | unknown
supports_staging: boolean
supports_rate_limits: boolean
supports_send_limits: boolean
supports_cost_calculation: boolean
supports_sustainability_options: boolean
supports_cancellation: none | before_submission | before_production | provider_specific | unknown
```
A provider flavor MAY add provider-specific capabilities, but these MUST be namespaced or clearly marked as provider-specific.
## 10. Provider Flavor Examples
### 10.1 Binect Flavor Center
Binect is modeled as a document-centric hybrid-mail provider.
Important capabilities include:
```text
document upload
attachments
preview
print and shipping options
document status
shipping status
address-position validation
address-format validation
restricted-area validation
serial/child document status
```
### 10.2 Pingen Flavor Center
Pingen is modeled as a developer-friendly letter API with strong operational status features.
Important capabilities include:
```text
letter creation
idempotency-key support
webhooks
Track & Trace
rate limits
send limits
staging/simulation
return-mail processing
undeliverable and delivered webhook categories
auto-send
address-position configuration
```
### 10.3 DPAG / E-POSTBUSINESS Flavor Center
DPAG is modeled as a postal-infrastructure-native shipment API.
Important capabilities include:
```text
PDF/PDF-A shipment submission
single and bulk upload
bulk status requests
production data
shipment tracking
registered-mail products
address-window positioning
automatic positioning
cover sheets
scheduled dispatch
```
These provider centers are informative only. The authoritative behavior must be captured in each provider flavor descriptor and status mapping.
## 11. Layered Hybrid-Mail Lifecycle
Hybrid mail MUST be modeled as a layered lifecycle, not as a single flat status.
## 11.1 Digital Submission Layer
```text
created
upload_requested
uploaded
accepted_by_provider
rejected_by_provider
upload_failed
```
## 11.2 Validation Layer
```text
validation_pending
validation_passed
validation_failed
action_required
```
## 11.3 Preparation Layer
```text
options_set
preview_available
address_positioning_applied
cover_sheet_generated
ready_for_sending
scheduled
```
## 11.4 Production Layer
```text
submitted_for_sending
production_pending
production_started
production_completed
production_failed
cancelled_before_production
```
## 11.5 Postal Layer
```text
handed_to_postal_service
in_transit
delivery_confirmed
undeliverable
return_received
forwarded
address_corrected
status_unknown
expired_without_final_status
```
## 11.6 Critical Lifecycle Rule
The following transitions MUST NOT be collapsed:
```text
uploaded ≠ validation_passed
validation_passed ≠ submitted_for_sending
submitted_for_sending ≠ production_completed
production_completed ≠ handed_to_postal_service
handed_to_postal_service ≠ delivery_confirmed
delivery_confirmed ≠ human_read_confirmed
```
## 12. Hybrid Mail Lifecycle Model
The adapter SHOULD support the following lifecycle events where provider capabilities allow them.
```text
letter.created
letter.payload_received
letter.rendered
letter.render_failed
letter.upload_requested
letter.accepted_by_adapter
letter.rejected_by_adapter
letter.uploaded_to_provider
letter.accepted_by_provider
letter.rejected_by_provider
letter.validation_started
letter.validation_passed
letter.validation_failed
letter.action_required
letter.preview_available
letter.options_set
letter.ready_for_sending
letter.scheduled
letter.submitted_for_sending
letter.cancelled_before_production
letter.processing_started
letter.transferred_for_printing
letter.printed
letter.enveloped
letter.franked
letter.production_completed
letter.handed_to_postal_service
letter.in_postal_delivery
letter.delivery_confirmed
letter.registered_delivery_event
letter.undeliverable_reported
letter.return_mail_received
letter.address_corrected
letter.forwarded
letter.finalized
letter.status_unknown
letter.expired_without_final_status
```
Provider flavors MAY expose fewer lifecycle events, but they MUST map their native states conservatively.
## 13. Weakest Safe Mapping Rule
If a provider-native status is ambiguous, the adapter MUST map it to the weakest semantically safe normalized event and preserve the raw provider status in metadata.
Example:
```text
Native provider status: "sent"
```
Possible meanings:
```text
submitted_for_sending
production_completed
handed_to_postal_service
```
Unless provider documentation confirms that `sent` means postal handover, the adapter MUST NOT map it to `delivery.postal.handed_over`.
Where ambiguity remains, the adapter SHOULD map to:
```text
delivery.payload.submitted
```
or another weaker event and add a warning.
## 14. Provider Status Mapping Registry
Every provider flavor MUST define a status mapping registry.
```yaml
HybridmailStatusMapping:
provider_status: string
provider_status_scope: upload | validation | preparation | production | postal | tracking | return | bulk | child | unknown
normalized_event: string
normalized_state: string
evidence_grade: EvidenceGrade
confidence: low | medium | high
terminal: boolean
retryable: boolean?
product_dependent: boolean
required_product_types:
- string
warning: string?
raw_status_preserved: true
```
Example:
```yaml
- provider_status: SENT
provider_status_scope: postal
normalized_event: delivery.postal.handed_over
normalized_state: handed_to_postal_service
confidence: medium
terminal: false
product_dependent: true
warning: Verify that SENT means postal handover for this provider/product.
```
Example conservative mapping:
```yaml
- provider_status: SENT
provider_status_scope: unknown
normalized_event: delivery.payload.submitted
normalized_state: submitted_for_sending
confidence: low
terminal: false
product_dependent: true
warning: Native SENT status is ambiguous; mapped conservatively.
```
## 15. Postal Product Evidence Semantics
Every provider flavor MUST define postal product semantics.
```yaml
HybridmailPostalProduct:
product_code: string
provider_product_code: string?
normalized_product_type: standard | priority | registered | registered_return_receipt | delivery_confirmation | international | dialogpost | provider_specific | unknown
supports_tracking: boolean
supports_delivery_confirmation: boolean
supports_recipient_signature: boolean
supports_return_info: boolean
supports_address_correction: boolean
supports_international_delivery: boolean
evidence_ceiling: dispatch_only | in_transit | delivery_confirmed | return_only | product_dependent | unknown
limitations:
- string
```
Product semantics constrain evidence mapping.
If a product does not support delivery confirmation, the adapter MUST NOT emit:
```text
delivery.postal.delivery_confirmed
```
for that product unless another explicit source provides delivery-confirmation evidence.
## 16. Evidence Ceiling Model
Each provider/product/status combination has a maximum evidence strength.
```yaml
HybridmailEvidenceCeiling:
provider_name: string
product_type: string
max_positive_event: delivery.payload.submitted | delivery.production.completed | delivery.postal.handed_over | delivery.postal.in_transit | delivery.postal.delivery_confirmed | unknown
max_positive_strength: weak | medium | strong | conclusive | unknown
can_prove_human_awareness: boolean
can_prove_payload_reading: boolean
can_prove_recipient_identity: boolean
notes:
- string
```
Typical examples:
```yaml
ordinary_letter:
max_positive_event: delivery.postal.handed_over
max_positive_strength: strong
can_prove_human_awareness: false
can_prove_payload_reading: false
can_prove_recipient_identity: false
```
```yaml
registered_delivery_confirmation:
max_positive_event: delivery.postal.delivery_confirmed
max_positive_strength: strong
can_prove_human_awareness: false
can_prove_payload_reading: false
can_prove_recipient_identity: product_dependent
```
This prevents the coordination policy from demanding evidence a product cannot produce.
## 17. Ordinary Postal Dispatch vs Delivery Confirmation
The adapter MUST explicitly distinguish ordinary dispatch from delivery confirmation.
Normative rules:
```text
Postal handover is strong dispatch evidence.
Postal handover is not final delivery confirmation.
Absence of return mail is not proof of delivery.
Ordinary letters often do not produce final delivery status.
Delivery confirmation requires product/status evidence that explicitly supports delivery confirmation.
Registered-mail events are product-specific and must not be generalized.
Return mail or undeliverable events may arrive late and must still be recorded.
```
Recommended normalized events:
```text
delivery.postal.handed_over
delivery.postal.in_transit
delivery.postal.delivery_confirmed
delivery.postal.undeliverable
delivery.postal.return_received
delivery.postal.status_unknown
delivery.postal.expired_without_final_status
```
Avoid using the ambiguous normalized event:
```text
delivery.postal.delivered
```
If a provider-native status is called `delivered`, it MUST be mapped to `delivery.postal.delivery_confirmed` only if the product/status semantics support delivery confirmation.
## 18. Letter, Document, Attempt, Batch, and Recipient Model
The adapter MUST distinguish at least six layers.
## 18.1 HybridmailLetter
The logical letter delivery created by a client or coordination case.
```yaml
HybridmailLetter:
hybridmail_letter_id: string
coordination_case_id: string?
participant_id: string?
purpose: string?
payload_ref: ResourceRef
document_ref: HybridmailDocumentRef?
recipient: PostalRecipient
sender: PostalSender?
options: HybridmailOptions?
tracking_context: TrackingContext
created_at: timestamp
```
## 18.2 HybridmailDocumentRef
The submitted document or generated print artifact.
```yaml
HybridmailDocumentRef:
document_id: string
provider_document_id: string?
document_type: pdf | pdfa | postscript | image | other
version: string?
page_count: integer?
sheet_count: integer?
color_pages: integer?
grayscale_pages: integer?
simplex_pages: integer?
duplex_pages: integer?
integrity_hash: string?
validation_state: unknown | pending | passed | action_required | failed
metadata: object?
```
## 18.3 HybridmailAttempt
One submission attempt through one provider/configuration.
```yaml
HybridmailAttempt:
hybridmail_attempt_id: string
hybridmail_letter_id: string
provider_name: string
provider_account_ref: string?
provider_document_id: string?
provider_letter_id: string?
provider_sending_id: string?
provider_tracking_id: string?
state: HybridmailAttemptState
idempotency_key: string
created_at: timestamp
updated_at: timestamp
```
## 18.4 HybridmailBatch
A batch or serial-letter group.
```yaml
HybridmailBatch:
batch_id: string
provider_batch_id: string?
coordination_case_id: string?
batch_type: bulk | serial | campaign | mixed | unknown
letters:
- hybridmail_letter_id
state: pending | partial | completed | failed | unknown
created_at: timestamp
updated_at: timestamp?
```
## 18.5 HybridmailChildLetterStatus
```yaml
HybridmailChildLetterStatus:
batch_id: string
child_letter_id: string
provider_child_id: string?
hybridmail_letter_id: string?
participant_id: string?
provider_status: string?
normalized_status: string
evidence_event_refs:
- string
updated_at: timestamp?
metadata: object?
```
## 18.6 PostalRecipient
```yaml
PostalRecipient:
recipient_id: string?
name_lines:
- string
organization: string?
street: string?
house_number: string?
address_addition: string?
postal_code: string?
city: string?
region: string?
country_code: string?
country_name: string?
address_source: extracted_from_document | provided_metadata | provider_detected | cover_sheet | manual | unknown
address_quality: PostalAddressQuality?
```
## 18.7 PostalSender
```yaml
PostalSender:
sender_id: string?
name_lines:
- string
organization: string?
return_address: PostalRecipient?
billing_account_ref: string?
sender_identity_ref: string?
```
## 19. Batch and Child-Letter Rules
Batch and serial-letter processing MUST be handled conservatively.
Normative rules:
```text
Batch acceptance MUST NOT imply child-letter success.
Batch submission MUST NOT imply child-letter postal handover.
Batch completion MUST NOT imply every participant completed unless child statuses prove it or policy explicitly accepts batch evidence.
Provider flavors MUST emit per-child evidence whenever provider data allows it.
Case-level aggregation belongs to coordination-engine, not hybridmail-connect.
```
Batch events should be treated as operational evidence unless linked to child-letter status.
## 20. Hybrid Mail Options Model
The adapter MUST support a provider-neutral print and postal option model.
```yaml
HybridmailOptions:
color_mode: color | grayscale | provider_default | unknown
print_sides: simplex | duplex | provider_default | unknown
envelope_type: c5 | c4 | window_left | window_right | no_window | provider_default | unknown
address_position: left | right | metadata | extracted | automatic | cover_sheet | provider_default | unknown
postage_product: standard | priority | economy | registered | registered_return_receipt | delivery_confirmation | international | dialogpost | provider_specific
country_scope: domestic | international | mixed | unknown
dispatch_mode: manual_review | auto_send | submit_later | scheduled
desired_dispatch_date: date?
cutoff_policy_ref: string?
return_mail_handling: none | provider_processed | scan_return | digital_return_info | physical_return | unknown
address_correction_requested: boolean?
cover_sheet: boolean?
automatic_positioning: boolean?
sustainability_option: none | carbon_reduced | gogreen_plus | provider_default | provider_specific
metadata: object?
```
Provider-native option names MUST be preserved in metadata.
## 21. Postal Address Quality Model
```yaml
PostalAddressQuality:
validation_state: unknown | valid | action_required | invalid | corrected
country_supported: boolean?
address_position_valid: boolean?
address_format_valid: boolean?
postal_code_valid: boolean?
street_known: boolean?
recipient_known: boolean?
correction_available: boolean?
correction_source: provider | postal_carrier | manual | unknown
issues:
- string
```
Address quality may update a contact registry, but it MUST NOT create coordination result success by itself.
## 22. Document Validation Model
Document validation is central to hybrid mail.
```yaml
HybridmailValidationResult:
document_id: string
validation_state: pending | passed | action_required | failed | unknown
issues:
- HybridmailValidationIssue
validated_at: timestamp?
provider_validation_ref: string?
```
```yaml
HybridmailValidationIssue:
issue_code: string
provider_issue_code: string?
severity: info | warning | action_required | fatal
category: format | pdf | pdfa | page_size | address | address_position | address_format | restricted_area | margins | cover_sheet | file_size | page_count | attachment | postage | country | scheduled_dispatch | credit_or_account | provider_policy | unknown
message: string
page_number: integer?
bounding_box: object?
fixable: boolean?
machine_recommendation: string?
```
## 23. Validation Issue Taxonomy
Provider flavors SHOULD map native validation issues into this taxonomy.
```text
invalid_pdf
invalid_pdfa
unsupported_file_type
not_a4_portrait
invalid_page_size
file_too_large
too_many_pages
address_not_detected
address_invalid
address_format_invalid
address_position_invalid
automatic_positioning_failed
restricted_area_violation
barcode_area_violation
margin_violation
cover_sheet_failed
unsupported_country
unsupported_product
attachment_invalid
scheduled_dispatch_invalid
insufficient_credit
account_blocked
provider_policy_rejected
unknown_validation_issue
```
Validation failure usually maps to strong failure of the hybrid-mail attempt, but not necessarily failure of the coordination case if another channel or corrected document can be used.
## 24. Preview and Review Semantics
Some providers support preview retrieval before dispatch.
```yaml
HybridmailPreview:
preview_id: string
document_id: string
provider_preview_id: string?
preview_type: pdf | png | image | metadata | unknown
preview_uri: string?
generated_at: timestamp
expires_at: timestamp?
metadata: object?
```
Normative rules:
```text
Preview availability is operational readiness evidence.
Preview availability is not postal dispatch evidence.
Preview approval may be required by scenario policy before sending.
Preview artifacts may contain full sensitive document content and require retention/security rules.
```
Preview evidence usually maps to:
```text
delivery.payload.available
```
with metadata.
## 25. Status Ingestion Model: Polling, Webhooks, and Late Events
Provider flavors MUST define how status is ingested.
```yaml
HybridmailStatusIngestionModel:
supports_polling: boolean
supports_webhooks: boolean
polling_required: boolean
webhook_required: boolean
fallback_polling_enabled: boolean
polling_interval_seconds: integer?
max_polling_duration_seconds: integer?
late_event_policy: accept_and_record
terminal_statuses:
- string
```
Normative rules:
```text
Late return-mail events MUST be accepted and recorded.
Late delivery-confirmation events MUST be accepted and recorded.
Late undeliverable events MUST be accepted and recorded.
Polling and webhook events may arrive out of order.
Raw provider status MUST be preserved.
Derived state may be revised or annotated after late events.
```
## 26. Hybrid-Mail Event Vocabulary
This spec defines the following recommended normalized event vocabulary.
## 26.1 Payload and Validation Events
```text
delivery.payload.submitted
delivery.payload.accepted
delivery.payload.rejected
delivery.payload.available
delivery.payload.failed
payload.validation_started
payload.validation_passed
payload.validation_failed
```
## 26.2 Production Events
```text
delivery.production.pending
delivery.production.started
delivery.production.completed
delivery.production.failed
```
## 26.3 Postal Events
```text
delivery.postal.handed_over
delivery.postal.in_transit
delivery.postal.delivery_confirmed
delivery.postal.undeliverable
delivery.postal.return_received
delivery.postal.forwarded
delivery.postal.address_corrected
delivery.postal.status_unknown
delivery.postal.expired_without_final_status
```
## 26.4 System Events
```text
system.provider.degraded
system.provider.unavailable
system.adapter.health_changed
```
The event `delivery.postal.delivered` SHOULD be avoided as a normalized event because it is ambiguous. Use `delivery.postal.delivery_confirmed` instead.
## 27. Provider-to-Generic Event Mapping
Provider flavors MUST provide mapping tables from native events to generic events.
Example:
| Provider-native event | Generic event | Evidence interpretation |
| --------------------- | ------------------------------------ | -------------------------------------------- |
| Upload accepted | `delivery.payload.accepted` | Digital submission accepted |
| Validation passed | `payload.validation_passed` | Provider-processable |
| Validation failed | `payload.validation_failed` | Correction/fallback needed |
| Submitted for sending | `delivery.payload.submitted` | Provider instructed to send |
| Production started | `delivery.production.started` | Physical production started |
| Production completed | `delivery.production.completed` | Production completed, not postal delivery |
| Handover to post | `delivery.postal.handed_over` | Strong dispatch evidence |
| In transit | `delivery.postal.in_transit` | Tracking evidence |
| Delivery confirmed | `delivery.postal.delivery_confirmed` | Product-dependent physical-delivery evidence |
| Undeliverable | `delivery.postal.undeliverable` | Strong negative delivery evidence |
| Return received | `delivery.postal.return_received` | Strong negative delivery evidence |
## 28. Hybrid Mail Evidence Assessment
`hybridmail-connect` should provide a hybrid-mail-native assessment separate from coordination-engine state.
```yaml
HybridmailEvidenceAssessment:
hybridmail_letter_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.
## 29. Hybrid-Mail Adapter Success Subclasses
Hybrid-mail-level `success` means the channel produced meaningful hybrid-mail evidence.
Possible subclasses:
```text
success.provider_accepted
success.validation_passed
success.preview_available
success.submitted_for_sending
success.production_started
success.production_completed
success.handed_to_postal_service
success.in_transit
success.registered_tracking_event
success.delivery_confirmed
success.return_info_processed
```
Important: These are not automatically coordination success.
For ordinary letters, `success.handed_to_postal_service` is strong dispatch evidence but not proof of physical delivery or human awareness.
## 30. Hybrid-Mail Adapter Fail Subclasses
Hybrid-mail-level `fail` indicates strong evidence that the hybrid-mail attempt failed.
Subclasses:
```text
fail.missing_payload
fail.invalid_document
fail.validation_failed
fail.action_required_unresolved
fail.invalid_address
fail.address_position_invalid
fail.address_format_invalid
fail.restricted_area_violation
fail.unsupported_country
fail.unsupported_product
fail.insufficient_credit
fail.account_blocked
fail.provider_rejected
fail.upload_failed
fail.production_failed
fail.cancelled
fail.postal_undeliverable
fail.return_mail_received
fail.expired_before_handover
```
## 31. Hybrid-Mail Adapter Undef Subclasses
Hybrid-mail-level `undef` is used when the adapter cannot determine physical delivery, recipient awareness, or final postal outcome.
Subclasses:
```text
undef.pending
undef.uploaded_only
undef.provider_accepted_only
undef.validation_pending
undef.action_required
undef.ready_but_not_sent
undef.scheduled_for_future_dispatch
undef.submitted_for_sending
undef.processing
undef.production_status_unknown
undef.production_completed_but_handover_unproven
undef.transferred_for_printing
undef.handed_to_postal_service_but_delivery_unproven
undef.postal_delivery_unknown
undef.registered_tracking_pending
undef.return_mail_pending
undef.no_final_status_expected
undef.bulk_status_partial
undef.conflicting_evidence
undef.channel_degraded
```
For ordinary physical letters, the adapter should expect `undef.handed_to_postal_service_but_delivery_unproven` to be common.
## 32. Detailed Scenario Classification
## 32.1 Pre-Submission Scenarios
| Scenario | Hybridmail assessment | Normalized event | Notes |
| -------------------------------------- | --------------------------------------------- | --------------------------- | ----------------------------- |
| Missing payload | `fail.missing_payload` | `delivery.payload.failed` | No delivery possible |
| Unsupported document format | `fail.invalid_document` | `payload.validation_failed` | Provider may reject |
| Invalid PDF/PDF-A | `fail.validation_failed` | `payload.validation_failed` | Provider-specific |
| Unsupported page size | `fail.validation_failed` | `payload.validation_failed` | Common hybrid-mail constraint |
| Address not detected | `fail.invalid_address` or `action_required` | `payload.validation_failed` | May be fixable |
| Address in wrong window position | `fail.validation_failed` or `action_required` | `payload.validation_failed` | Provider-specific |
| Restricted area violation | `fail.validation_failed` or `action_required` | `payload.validation_failed` | Print/postal layout issue |
| Unsupported destination country | `fail.unsupported_country` | `delivery.payload.rejected` | Route unavailable |
| Unsupported postal product | `fail.unsupported_product` | `delivery.payload.rejected` | Option mismatch |
| Insufficient credit/account problem | `fail.insufficient_credit` | `delivery.payload.rejected` | Operational/account failure |
| Provider unavailable before acceptance | `undef.pending` or provider fail | action error | Retry-dependent |
## 32.2 Upload and Validation Scenarios
| Scenario | Hybridmail assessment | Normalized event | Notes |
| ------------------------ | ------------------------------------------ | ---------------------------------------------------- | --------------------------- |
| Adapter accepted request | `undef.pending` | `delivery.payload.submitted` | Adapter accepted work |
| Provider accepted upload | `undef.provider_accepted_only` | `delivery.payload.accepted` | Digital submission accepted |
| Provider rejected upload | `fail.provider_rejected` | `delivery.payload.rejected` | Strong attempt failure |
| Validation started | `undef.validation_pending` | `payload.validation_started` | Operational status |
| Validation passed | `success.validation_passed` | `payload.validation_passed` | Ready for options/send |
| Action required | `fail.action_required_unresolved` or undef | `payload.validation_failed` with severity | May be fixable |
| Validation failed fatal | `fail.validation_failed` | `payload.validation_failed` | Cannot send |
| Preview available | operational success | `delivery.payload.available` | Review evidence only |
| Attachment accepted | operational success | `delivery.payload.accepted` with attachment metadata | Not final delivery |
| Attachment failed | `fail.validation_failed` | `payload.validation_failed` | Must be corrected |
## 32.3 Sending and Production Scenarios
| Scenario | Hybridmail assessment | Normalized event | Notes |
| ----------------------------- | ------------------------------------- | ------------------------------------------------ | --------------------------- |
| Options set | operational success | metadata event | Not delivery |
| Ready for sending | `undef.ready_but_not_sent` | `delivery.payload.available` | Awaiting dispatch approval |
| Scheduled for future dispatch | `undef.scheduled_for_future_dispatch` | `delivery.payload.available` | Dispatch pending |
| Submitted for sending | `success.submitted_for_sending` | `delivery.payload.submitted` | Provider instructed to send |
| Cancelled before production | `fail.cancelled` or cancelled | `delivery.payload.failed` or manual cancellation | Depends on policy |
| Processing started | `undef.processing` | `delivery.production.started` | Production chain began |
| Transferred for printing | `success.production_started` | `delivery.production.started` | Strong production evidence |
| Printed | production success | `delivery.production.completed` | Not postal handover |
| Enveloped/franked | production success | `delivery.production.completed` | Not postal delivery |
| Production failed | `fail.production_failed` | `delivery.production.failed` | Strong channel failure |
| Handover to postal service | `success.handed_to_postal_service` | `delivery.postal.handed_over` | Strong dispatch evidence |
| Cutoff missed | `undef.processing` or delayed | metadata/channel warning | Adjust expected timing |
## 32.4 Postal Delivery Scenarios
| Scenario | Hybridmail assessment | Normalized event | Notes |
| ------------------------------ | ------------------------------------------------------ | ----------------------------------------- | ---------------------------------- |
| Ordinary letter handed over | `undef.handed_to_postal_service_but_delivery_unproven` | `delivery.postal.handed_over` | Strong dispatch, delivery unproven |
| Postal tracking ID received | `undef.postal_delivery_unknown` | `delivery.postal.in_transit` | Stronger traceability |
| Registered tracking event | `success.registered_tracking_event` | `delivery.postal.in_transit` or confirmed | Depends event |
| Delivery confirmed | `success.delivery_confirmed` | `delivery.postal.delivery_confirmed` | Strong physical delivery evidence |
| Return receipt received | `success.delivery_confirmed` | `delivery.postal.delivery_confirmed` | Stronger evidence |
| Undeliverable reported | `fail.postal_undeliverable` | `delivery.postal.undeliverable` | Strong negative evidence |
| Return mail received | `fail.return_mail_received` | `delivery.postal.return_received` | Strong negative evidence |
| Address corrected | address signal | `delivery.postal.address_corrected` | Useful for contact registry |
| Forwarded due to moving | `undef.forwarded` or success-ish | `delivery.postal.forwarded` | Delivery path changed |
| No final status expected | `undef.no_final_status_expected` | metadata | Common for ordinary letters |
| No return after waiting period | still `undef` unless policy accepts | timeout metadata | Absence of return is not proof |
## 33. Evidence Grading Rules
## 33.1 Provider Upload Accepted
```yaml
event_type: delivery.payload.accepted
evidence_grade:
strength: weak
actor_certainty: none
authority_certainty: none
payload_certainty: medium
interaction_certainty: none
timing_certainty: medium
channel_certainty: medium
non_repudiation_strength: low
notes:
- Provider accepted the digital submission.
- Does not prove validation, production, postal handover, or delivery.
```
## 33.2 Validation Passed
```yaml
event_type: payload.validation_passed
evidence_grade:
strength: medium
actor_certainty: none
authority_certainty: none
payload_certainty: high
interaction_certainty: none
timing_certainty: high
channel_certainty: high
non_repudiation_strength: low
notes:
- Document passed provider validation for print/postal processing.
- Does not prove dispatch or delivery.
```
## 33.3 Validation Failed
```yaml
event_type: payload.validation_failed
evidence_grade:
strength: negative
actor_certainty: none
authority_certainty: none
payload_certainty: high
interaction_certainty: none
timing_certainty: high
channel_certainty: high
non_repudiation_strength: low
notes:
- Document cannot be processed until corrected or replaced.
```
## 33.4 Submitted for Sending
```yaml
event_type: delivery.payload.submitted
evidence_grade:
strength: medium
actor_certainty: none
authority_certainty: none
payload_certainty: high
interaction_certainty: none
timing_certainty: high
channel_certainty: high
non_repudiation_strength: low
notes:
- Letter was submitted into the provider sending process.
- Does not prove print production or postal handover.
```
## 33.5 Production Started
```yaml
event_type: delivery.production.started
evidence_grade:
strength: medium
actor_certainty: none
authority_certainty: none
payload_certainty: high
interaction_certainty: none
timing_certainty: medium
channel_certainty: high
non_repudiation_strength: low
notes:
- Letter entered production or printing process.
- Does not prove postal handover.
```
## 33.6 Production Completed
```yaml
event_type: delivery.production.completed
evidence_grade:
strength: medium
actor_certainty: none
authority_certainty: none
payload_certainty: high
interaction_certainty: none
timing_certainty: high
channel_certainty: high
non_repudiation_strength: low
notes:
- Letter production was completed.
- Does not prove postal handover unless provider status explicitly says so.
```
## 33.7 Handed to Postal Service
```yaml
event_type: delivery.postal.handed_over
evidence_grade:
strength: strong
actor_certainty: none
authority_certainty: none
payload_certainty: high
interaction_certainty: none
timing_certainty: high
channel_certainty: high
non_repudiation_strength: medium
notes:
- Letter was handed over to the postal delivery chain.
- Strong dispatch evidence.
- Does not prove recipient receipt or reading.
```
## 33.8 In Transit
```yaml
event_type: delivery.postal.in_transit
evidence_grade:
strength: strong
actor_certainty: none
authority_certainty: none
payload_certainty: high
interaction_certainty: none
timing_certainty: high
channel_certainty: high
non_repudiation_strength: medium
notes:
- Postal tracking indicates the letter is in the postal chain.
- Does not necessarily prove final delivery.
```
## 33.9 Delivery Confirmed
```yaml
event_type: delivery.postal.delivery_confirmed
evidence_grade:
strength: strong
actor_certainty: low
authority_certainty: none
payload_certainty: high
interaction_certainty: low
timing_certainty: high
channel_certainty: high
non_repudiation_strength: medium
notes:
- Postal delivery confirmation or registered-mail event was received.
- This is strong physical-delivery evidence.
- It may still not prove that the intended human personally read the payload.
```
## 33.10 Return Mail / Undeliverable
```yaml
event_type: delivery.postal.return_received
evidence_grade:
strength: negative
actor_certainty: none
authority_certainty: none
payload_certainty: high
interaction_certainty: none
timing_certainty: high
channel_certainty: high
non_repudiation_strength: medium
notes:
- Letter was returned or reported undeliverable.
- Strong evidence that physical delivery failed for this attempt.
```
## 34. Status Timeline API
`hybridmail-connect` SHOULD expose a delivery timeline suitable for standalone diagnostics and coordination audit.
```yaml
HybridmailTimeline:
hybridmail_letter_id: string
provider_name: string
provider_document_id: string?
provider_letter_id: string?
provider_sending_id: string?
provider_tracking_id: string?
events:
- HybridmailTimelineEvent
current_assessment: HybridmailEvidenceAssessment
```
```yaml
HybridmailTimelineEvent:
event_id: string
event_type: string
occurred_at: timestamp
source: adapter | provider | print_center | postal_carrier | return_mail | webhook | polling | operator
native_event_type: string?
normalized_event_type: string?
provider_status: string?
summary: string
evidence_grade: EvidenceGrade
raw_event_ref: string?
```
## 35. Adapter Descriptor
`hybridmail-connect` MUST expose an `AdapterDescriptor` compatible with AdapterInterfaceSpecification.md v1.0.
```yaml
adapter_id: hybridmail-connect.default
adapter_name: hybridmail-connect
adapter_version: 1.1.0
adapter_contract_version: 1.0
adapter_types:
- delivery
- communication
- document
- archive
provider_family: hybridmail
provider_name: configurable
deployment_mode: external
supported_channels:
- hybridmail
- postal_mail
supported_endpoint_types:
- postal_address
supported_actions:
- action_type: delivery.submit_letter
mode: async
idempotency_required: true
- action_type: delivery.submit_bulk
mode: async
idempotency_required: true
- action_type: delivery.validate_payload
mode: async
idempotency_required: true
- action_type: delivery.add_attachment
mode: async
idempotency_required: true
- action_type: delivery.set_options
mode: sync
idempotency_required: true
- action_type: delivery.request_preview
mode: async
idempotency_required: true
- action_type: delivery.approve_for_sending
mode: async
idempotency_required: true
- action_type: delivery.cancel
mode: async
idempotency_required: true
- action_type: delivery.request_status
mode: sync
idempotency_required: true
emitted_event_types:
- delivery.payload.submitted
- delivery.payload.accepted
- delivery.payload.rejected
- payload.validation_started
- payload.validation_passed
- payload.validation_failed
- delivery.payload.available
- delivery.production.pending
- delivery.production.started
- delivery.production.completed
- delivery.production.failed
- delivery.postal.handed_over
- delivery.postal.in_transit
- delivery.postal.delivery_confirmed
- delivery.postal.undeliverable
- delivery.postal.return_received
- delivery.postal.forwarded
- delivery.postal.address_corrected
- delivery.postal.status_unknown
- delivery.postal.expired_without_final_status
- system.provider.degraded
- system.provider.unavailable
evidence_profile:
strongest_evidence_level: strong
can_prove_human_awareness: false
can_prove_payload_delivery: partially
can_prove_identity: false
identity_profile:
identity_strength: none_to_low
authority_strength: none
limitations:
- Ordinary postal handover does not prove recipient receipt.
- Ordinary physical letters often do not provide final delivery confirmation.
- Delivery confirmation depends on postal product and provider support.
- Return-mail information may arrive late.
- Address extraction and validation differ by provider.
- Cancellation may only be possible before production starts.
- Batch-level status does not imply child-letter success.
```
## 36. Action Request Handling
## 36.1 `delivery.submit_letter`
`delivery.submit_letter` submits a letter payload to a hybrid-mail provider.
Required fields:
```text
request_id
action_type
coordination_case_id
participant_id
payload_ref
target_endpoint
tracking_context
idempotency_key
requested_at
```
Example:
```yaml
request_id: req_001
action_type: delivery.submit_letter
coordination_case_id: case_123
participant_id: participant_456
channel: hybridmail
target_endpoint:
endpoint_type: postal_address
value: postal_recipient_ref_456
payload_ref:
ref_type: coordination_payload
ref_id: payload_777
uri: s3://bucket/document.pdf
integrity_hash: sha256:...
tracking_context:
correlation_id: corr_789
coordination_case_id: case_123
participant_id: participant_456
delivery_id: delivery_001
payload_id: payload_777
idempotency_key: case_123:participant_456:hybridmail:delivery_001
requested_at: 2026-01-01T12:00:00Z
metadata:
hybridmail_options:
color_mode: grayscale
print_sides: duplex
envelope_type: window_left
postage_product: standard
```
## 36.2 Action Result
The adapter returns:
```yaml
request_id: req_001
adapter_id: hybridmail-connect.default
accepted: true
action_state: accepted
adapter_operation_id: hmop_001
provider_operation_id: providerop_001
initial_events:
- event_type: delivery.payload.submitted
received_at: 2026-01-01T12:00:01Z
```
This result does not prove validation, production, postal handover, or delivery.
## 37. Idempotency and Duplicate Physical Dispatch Prevention
Duplicate physical dispatch prevention is safety-critical.
Normative rules:
```text
Hybrid-mail submit/send actions MUST be idempotent.
If the provider lacks native idempotency, the adapter MUST implement adapter-managed idempotency.
Duplicate physical dispatch prevention is mandatory.
A repeated request with the same idempotency key MUST NOT create a second physical send.
```
Recommended idempotency scope:
```text
coordination_case_id
participant_id
delivery_id
payload_id
payload_integrity_hash
provider_flavor
postal recipient
postal product
shipment options
scheduled dispatch date
```
Idempotency conflict rule:
```text
Same idempotency key + different payload hash/address/options/product/schedule = conflict.
```
The adapter MUST reject idempotency conflicts unless scenario policy explicitly allows a new delivery attempt with a new key.
## 38. Provider Abstraction
`hybridmail-connect` SHOULD support a provider abstraction layer.
Provider integration responsibilities:
* authenticate
* upload document
* create letter/document record
* add attachments
* configure options
* request preview
* submit for sending
* cancel where possible
* poll status
* ingest webhooks where supported
* normalize provider statuses
* parse validation issues
* parse production data
* parse tracking events
* parse return-mail information
* parse delivery-confirmation information
* expose provider health
Provider model:
```yaml
HybridmailProvider:
provider_name: string
provider_account_ref: string
flavor_descriptor_ref: string
supported_features:
- upload
- validation
- attachments
- options
- preview
- send
- cancel
- status_polling
- webhooks
- track_and_trace
- production_status
- return_mail
- registered_mail
- delivery_confirmation
- bulk
- staging
event_mapping_ref: string
configuration_ref: string
```
Provider-specific modules should map to the hybrid-mail-native model first, then to normalized coordination events.
```text
Provider event
→ hybridmail-native event
→ HybridmailEvidenceAssessment
→ EvidenceEvent for coordination-e```
## 39. Return Mail and Undeliverable Model
```yaml
HybridmailReturnEvent:
return_event_id: string
hybridmail_letter_id: string
provider_return_id: string?
postal_tracking_id: string?
return_type: undeliverable | address_unknown | recipient_moved | refused | deceased | insufficient_address | mailbox_inaccessible | other | unknown
address_correction: PostalRecipient?
return_document_ref: ResourceRef?
occurred_at: timestamp?
observed_at: timestamp
raw_event_ref: string?
```
Return events usually create strong negative delivery evidence but may also provide address-correction information useful for future attempts.
## 40. Registered / Delivery Confirmation Model
```yaml
HybridmailDeliveryConfirmation:
confirmation_id: string
hybridmail_letter_id: string
provider_tracking_id: string?
postal_tracking_id: string?
product_type: registered | registered_return_receipt | delivery_confirmation | provider_specific
status: in_transit | attempted | delivered | refused | undeliverable | returned | unknown
recipient_signature_ref: ResourceRef?
confirmation_document_ref: ResourceRef?
occurred_at: timestamp?
observed_at: timestamp
raw_event_ref: string?
```
Delivery confirmation is stronger than ordinary handover evidence, but the exact legal and business meaning remains scenario-specific.
## 41. Channel Health
`hybridmail-connect` SHOULD expose hybrid-mail channel health.
```yaml
HybridmailChannelHealth:
provider_name: string
provider_account_ref: string?
provider_flavor: string?
status: healthy | degraded | failing | unknown
authentication_status: valid | expired | missing | insufficient | unknown
upload_status: healthy | degraded | unavailable | unknown
validation_status: healthy | degraded | unavailable | unknown
preview_status: healthy | degraded | unavailable | not_supported | unknown
production_status: healthy | delayed | unavailable | unknown
postal_handover_status: healthy | delayed | unavailable | unknown
webhook_status: healthy | degraded | unavailable | not_supported | unknown
polling_status: healthy | degraded | unavailable | unknown
cutoff_status: before_cutoff | after_cutoff | no_production_day | unknown
rate_limit_status: available | limited | exhausted | not_supported | unknown
send_limit_status: available | limited | exhausted | not_supported | unknown
known_degradations:
- string
```
Health-related normalized events:
```text
system.provider.degraded
system.provider.unavailable
system.adapter.health_changed
```
## 42. Security Requirements
`hybridmail-connect` MUST:
* protect provider credentials.
* protect uploaded payloads and document references.
* support secure transport to providers.
* preserve idempotency.
* avoid duplicate physical sends.
* validate provider webhooks where supported.
* avoid logging sensitive document content.
* protect postal recipient data.
* protect previews and generated artifacts.
* support tenant/account separation where applicable.
* support secure deletion or retention rules for raw payloads and previews.
* clearly separate test/staging and production modes.
Duplicate-send prevention is especially critical because physical mail sends cost money and may have legal/business consequences.
## 43. Privacy Requirements
`hybridmail-connect` SHOULD:
* store payload references instead of payload content where possible.
* support metadata-only mode.
* support masking of postal addresses.
* support raw event redaction.
* support configurable retention of documents, previews, generated cover sheets, and raw events.
* avoid unnecessary storage of print payloads after submission.
* separate operational diagnostics from coordination evidence.
* support deletion or anonymization workflows where legally possible.
* document provider-side retention limitations.
## 44. Reliability Requirements
`hybridmail-connect` MUST support:
* idempotent submit requests.
* duplicate webhook event detection.
* out-of-order event handling.
* late return-mail events.
* late undeliverable events.
* late delivery-confirmation events.
* retryable upload failures.
* non-retryable validation failures.
* provider timeout handling.
* provider polling fallback where webhooks are unavailable.
* correlation preservation.
* dead-letter handling for unprocessable events.
* batch partial-failure handling.
* status revision or annotation after late events.
Late events MUST be preserved.
Example:
```text
Letter handed to postal service on Monday.
Coordination case moves to waiting state.
Return mail event arrives two weeks later.
The return event must still be recorded and emitted as negative evidence.
```
## 45. Raw Event Preservation
`hybridmail-connect` SHOULD preserve raw provider events or references to them.
```yaml
RawHybridmailEventRef:
raw_event_id: string
provider_name: string
source: api_response | webhook | polling | print_center | postal_carrier | return_mail | tracking | operator
storage_ref: string?
received_at: timestamp
redacted: boolean
```
Normalized events should reference raw event data where available:
```yaml
raw_event_ref: raw_hybridmail_event_123
```
## 46. Minimal API Surface
`hybridmail-connect` SHOULD expose a headless API.
## 46.1 Adapter Contract API
Required conceptual operations:
```text
GET /adapter/descriptor
GET /adapter/health
POST /adapter/actions
POST /adapter/events/provider
GET /adapter/events
GET /adapter/letters/{id}/timeline
GET /adapter/letters/{id}/assessment
```
The actual transport may differ, but these conceptual operations should exist.
## 46.2 Standalone API
Useful standalone operations:
```text
POST /hybridmail/letters
POST /hybridmail/batches
POST /hybridmail/letters/{id}/attachments
PUT /hybridmail/letters/{id}/options
POST /hybridmail/letters/{id}/preview
POST /hybridmail/letters/{id}/send
POST /hybridmail/letters/{id}/cancel
GET /hybridmail/letters/{id}
GET /hybridmail/letters/{id}/timeline
GET /hybridmail/letters/{id}/assessment
GET /hybridmail/letters/{id}/return-info
GET /hybridmail/letters/{id}/delivery-confirmation
GET /hybridmail/channel-health
GET /hybridmail/providers/{provider}/capabilities
GET /hybridmail/providers/{provider}/status-mapping
```
## 47. Coding-Agent Implementation Requirements
Every provider flavor repository or provider-flavor module SHOULD include:
```text
ProviderFlavorDescriptor.yaml
ProviderCapabilityProfile.yaml
ProviderStatusMapping.yaml
ProviderValidationIssueCatalog.yaml
ProviderProductEvidenceMatrix.yaml
ProviderExampleFlows.md
ProviderGoldenTests.md
```
## 47.1 ProviderStatusMapping.yaml
Each provider flavor SHOULD provide an agent-readable status mapping.
```yaml
- provider_status: SENT
provider_status_scope: postal
normalized_event: delivery.postal.handed_over
normalized_state: handed_to_postal_service
evidence_strength: strong
confidence: medium
product_dependent: true
warning: Verify that SENT means postal handover for this provider/product.
- provider_status: DELIVERED
provider_status_scope: postal
normalized_event: delivery.postal.delivery_confirmed
normalized_state: delivery_confirmed
evidence_strength: strong
confidence: product_dependent
product_dependent: true
warning: Only valid for delivery-confirmation-capable products.
```
## 47.2 ProviderGoldenTests.md
Every provider flavor SHOULD define test cases for:
```text
valid single letter
invalid PDF
address-position failure
restricted-area violation
unsupported country
duplicate idempotency key
idempotency conflict
successful validation
sending submission
production status
postal handover
late return-mail event
delivery-confirmation product event
bulk partial failure
provider timeout
ambiguous provider status
```
## 48. Conformance Checklist for Provider Flavors
A provider flavor conforms to this specification if it:
1. Provides a `HybridmailProviderFlavorDescriptor`.
2. Provides a `HybridmailCapabilityProfile`.
3. Declares supported file types.
4. Declares supported postal products.
5. Declares product evidence ceilings.
6. Defines a provider status mapping registry.
7. Defines validation issue mapping.
8. Defines idempotency behavior.
9. Prevents duplicate physical dispatch.
10. Preserves raw provider status.
11. Uses weakest safe mapping for ambiguous statuses.
12. Separates upload, validation, sending, production, postal handover, and delivery confirmation.
13. Represents ordinary handover as dispatch evidence, not final delivery proof.
14. Accepts and records late return/undeliverable/delivery-confirmation events.
15. Handles batch and child-letter evidence separately.
16. Provides a timeline API.
17. Provides a provider-specific evidence assessment.
18. Integrates with AdapterInterfaceSpecification.md v1.0.
19. Documents known limitations.
20. Avoids overclaiming coordination result success.
## 49. Example End-to-End Flows
## 49.1 Ordinary Physical Letter
1. `coordination-engine` creates a coordination case.
2. A PDF payload is registered.
3. Policy selects hybrid mail as the delivery channel.
4. `coordination-engine` sends `delivery.submit_letter` to `hybridmail-connect`.
5. `hybridmail-connect` uploads the document to the provider.
6. Provider validates the document.
7. `hybridmail-connect` emits `payload.validation_passed`.
8. The letter is submitted for sending.
9. Provider transfers the letter for printing.
10. Print center hands the letter to the postal service.
11. `hybridmail-connect` emits `delivery.postal.handed_over`.
12. `coordination-engine` treats the participant as physically dispatched, but not necessarily as confirmed delivered unless policy accepts handover as sufficient.
## 49.2 Validation Failure and Correction
1. A PDF is uploaded.
2. Provider detects address-position or restricted-area issue.
3. `hybridmail-connect` emits `payload.validation_failed` with issue details.
4. `coordination-engine` marks the participant delivery attempt failed or action-required.
5. Policy requests correction, alternate document generation, or alternate channel.
6. Corrected payload is submitted with a new idempotency key or corrected version reference.
## 49.3 Registered Letter
1. A dunning letter is submitted with registered-mail option.
2. Provider validates and submits it.
3. Letter is handed to postal service.
4. Postal tracking events are received.
5. Delivery confirmation or return receipt event arrives.
6. `hybridmail-connect` emits `delivery.postal.delivery_confirmed`.
7. `coordination-engine` evaluates whether this satisfies the intended result.
## 49.4 Return Mail
1. Ordinary letter is handed to postal service.
2. No ordinary delivery confirmation is expected.
3. After several days or weeks, return mail is processed.
4. `hybridmail-connect` emits `delivery.postal.return_received`.
5. `coordination-engine` reopens, annotates, or fails the participant delivery state depending on policy.
## 49.5 Bulk Mailing
1. `coordination-engine` creates a batch delivery case.
2. `hybridmail-connect` submits a bulk/serial set of letters.
3. Some letters pass validation, others fail.
4. Per-letter evidence events are emitted.
5. `coordination-engine` aggregates participant states and avoids treating batch acceptance as universal success.
## 50. MVP Scope
The first useful version of `hybridmail-connect` should implement:
1. Adapter descriptor.
2. Provider flavor descriptor.
3. Capability profile.
4. Provider status mapping registry.
5. Adapter health endpoint.
6. `delivery.submit_letter`.
7. Idempotent submit request handling.
8. Simulated provider or one real provider flavor.
9. Letter, document, attempt, and recipient records.
10. Basic validation result mapping.
11. Basic print/shipping option mapping.
12. Basic status polling or webhook ingestion.
13. Evidence event generation.
14. Letter timeline.
15. Hybrid-mail evidence assessment.
16. Weakest safe mapping for ambiguous statuses.
17. Duplicate physical send prevention.
## 51. MVP Required Hybrid-Mail Events
```text
delivery.payload.submitted
delivery.payload.accepted
delivery.payload.rejected
payload.validation_started
payload.validation_passed
payload.validation_failed
delivery.payload.available
delivery.production.started
delivery.production.completed
delivery.postal.handed_over
delivery.postal.undeliverable
delivery.postal.return_received
delivery.postal.status_unknown
system.provider.degraded
system.provider.unavailable
```
## 52. MVP Acceptance Criteria
The MVP is acceptable when it can:
1. Accept a coordination-compatible hybrid-mail submit request.
2. Dispatch or simulate a PDF letter submission.
3. Preserve correlation and idempotency.
4. Prevent duplicate physical sends for duplicate idempotency keys.
5. Record provider acceptance separately from validation.
6. Classify validation failure as strong negative payload evidence.
7. Classify postal handover as strong dispatch evidence but not proof of human awareness.
8. Classify ordinary no-final-status cases as unresolved rather than success.
9. Record return mail as strong negative evidence.
10. Provide a letter timeline.
11. Provide a hybrid-mail evidence assessment.
12. Expose a provider capability profile.
13. Expose a provider status mapping registry.
14. Integrate with coordination-engine without overclaiming success.
## 53. Future Extensions
Potential future capabilities:
* multi-provider routing
* provider failover
* cost optimization by product/provider
* print-preview comparison
* PDF/A conversion support
* advanced address extraction
* address correction feedback loop
* return-mail scan ingestion
* registered-mail evidence archive
* delivery-confirmation document archive
* production SLA monitoring
* cutoff-aware scheduling
* country-specific postal product model
* automated correction workflows
* physical plus digital fallback patterns
* duplicate-content detection
* batch campaign analytics
* monthly journal / billing export integration
* print layout linting
* DIN 5008 address-window validation
* provider certification test suites
* coding-agent generated provider flavor tests
## 54. Non-Goals
`hybridmail-connect` is not:
* a document authoring system
* a PDF renderer by default
* a postal carrier
* a legal notice system by itself
* a signature system
* a payment system
* a CRM
* a full workflow engine
* the owner of coordination case success
It may integrate with such systems or be used by them.
## 55. Summary
`hybridmail-connect` models hybrid mail as a physical delivery channel initiated through digital submission.
Its job is to:
* submit PDF or print-ready documents
* validate hybrid-mail payloads
* map provider-specific print and shipping options
* track production and postal handover
* process return-mail and undeliverable evidence
* normalize registered or delivery-confirmation evidence
* expose document, letter, batch, provider, and channel diagnostics
* expose provider flavor capabilities and status mappings
* integrate cleanly with `coordination-engine`
The key rule is:
> Hybrid-mail events are physical production and postal-chain evidence, not automatic coordination result satisfaction. hybridmail-connect reports hybrid-mail facts and uncertainty. coordination-engine evaluates intended results.