# 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.