Files
coordination-engine/spec/AdapterInterfaceSpecification.md

48 KiB
Raw Blame History

AdapterInterfaceSpecification.md

1. Document Status

Document: AdapterInterfaceSpecification.md Project: coordination-engine Version: 1.1 Status: Updated Draft Scope: Contract between coordination-engine and external adapters Primary Reference Adapters: email-connect, sms-connect, rss-connect, xmpp-connect, hybridmail-connect

2. Version 1.1 Change Summary

Version 1.1 extends the original adapter interface based on concrete adapter design work for:

  • Email
  • SMS
  • RSS / Atom / WebSub
  • XMPP
  • Hybrid Mail

The main changes are:

  1. Added AdapterCapabilityProfile.
  2. Added EvidenceCeiling.
  3. Added NativeStatusMapping / NativeEventSemantics.
  4. Added universal weakest-safe-mapping rule.
  5. Added AdapterEvidenceAssessment.
  6. Added EndpointQuality.
  7. Added LateEventPolicy.
  8. Added EventObservation.
  9. Added FeatureDependency.
  10. Added AssuranceCapability.
  11. Added adapter conformance levels.
  12. Added golden test requirements.
  13. Strengthened semantic underclaiming requirements.
  14. Clarified that adapters provide evidence, not coordination-result truth.

3. Purpose

This document defines the adapter interface contract between coordination-engine and external adapter components such as:

  • email-connect
  • sms-connect
  • rss-connect
  • xmpp-connect
  • hybridmail-connect
  • push-connect
  • portal-connect
  • payment-connect
  • signature-connect
  • document-connect
  • identity-connect
  • future adapters

The adapter interface allows coordination-engine to remain protocol-neutral while integrating with concrete technologies, providers, systems, and communication channels.

Adapters translate between external systems and the internal coordination model by:

  1. Declaring capabilities.
  2. Declaring evidence ceilings.
  3. Accepting action requests.
  4. Returning action results.
  5. Preserving native events.
  6. Mapping native events conservatively.
  7. Emitting normalized evidence events.
  8. Providing advisory evidence assessments.
  9. Exposing endpoint quality and adapter health.
  10. Preserving correlation between coordination cases and external provider events.

The goal of this specification is to ensure that adapters are independently useful components while still being compatible with coordination-engine.

4. Core Design Principle

Adapters are not merely transport drivers.

An adapter is a capability component that can perform actions, observe signals, preserve native events, classify evidence, and expose its own limitations.

Adapter =
  Capability Descriptor
  + Action Provider
  + Signal Provider
  + Evidence Normalizer
  + Evidence Ceiling Declaration
  + Health / Diagnostics Provider

The coordination engine remains responsible for:

  • coordination case lifecycle
  • result evaluation
  • participant state derivation
  • policy decisions
  • follow-up decisions
  • uncertainty handling
  • case-level success/failure/expiry/escalation
  • final interpretation of adapter evidence

The adapter remains responsible for:

  • provider-specific integration
  • protocol-specific action execution
  • native event ingestion
  • native event preservation
  • native-to-normalized event mapping
  • adapter-level evidence assessment
  • adapter-specific diagnostics
  • provider-level correlation
  • adapter health reporting
  • explicit limitation reporting

5. Semantic Underclaiming Rule

Adapters MUST underclaim rather than overclaim.

If a native event or provider status is ambiguous, the adapter MUST map it to the weakest semantically safe normalized event and preserve the raw native event or status in metadata.

Examples:

Email provider "delivered"
→ notification.endpoint.accepted
→ not recipient awareness

SMS provider "delivered"
→ notification.endpoint.accepted with delivery-receipt metadata
→ not human read confirmation

RSS item "published"
→ feed.item.published
→ not participant awareness

XMPP stream acknowledgement
→ notification.attempt.accepted_by_provider
→ not client delivery

Hybrid mail "sent"
→ delivery.payload.submitted or delivery.postal.handed_over only if semantics prove handover
→ not delivery confirmation

The central rule is:

Adapters report what happened and what it may mean. coordination-engine decides what it means for the coordination case.

6. Boundary Between coordination-engine and Adapters

6.1 coordination-engine Owns

coordination-engine owns:

  • CoordinationCase
  • Participant
  • IntendedResult
  • case-level state
  • participant-level state
  • result predicates
  • policy evaluation
  • next-action selection
  • evidence ledger
  • adapter selection
  • scenario-specific orchestration
  • closure, failure, expiry, escalation, and manual override

6.2 Adapters Own

Adapters own:

  • provider communication
  • protocol-specific execution
  • provider credentials and configuration
  • native event ingestion
  • provider-native identifiers
  • native status interpretation
  • native-to-normalized event mapping
  • adapter-specific retries where appropriate
  • adapter-specific diagnostics
  • adapter health
  • adapter-native evidence assessment

6.3 Shared Contract

The shared contract consists of:

  • AdapterDescriptor
  • AdapterCapabilityProfile
  • AdapterActionCapability
  • AdapterActionRequest
  • AdapterActionResult
  • AdapterEvent
  • EvidenceEvent
  • AdapterEvidenceAssessment
  • EvidenceGrade
  • EvidenceCeiling
  • NativeStatusMapping
  • NativeEventSemantics
  • EndpointQuality
  • AdapterHealth
  • CorrelationContext
  • ErrorDescriptor
  • LateEventPolicy
  • FeatureDependency
  • AssuranceCapability
  • AdapterGoldenTest

7. Adapter Types

An adapter may belong to one or more adapter types.

Recommended canonical adapter types:

notification
communication
publication
access
delivery
interaction
identity
authority
payment
signature
document
archive
crm
erp
webhook
feed
system
manual

Examples:

Adapter repo Likely adapter types
email-connect notification, communication, interaction
sms-connect notification, communication, interaction
rss-connect publication, feed, notification
xmpp-connect notification, communication, interaction, feed
hybridmail-connect delivery, communication, document, archive
portal-connect access, delivery, interaction, identity
payment-connect payment, interaction, delivery
signature-connect signature, identity, authority, delivery
identity-connect identity, authority
webhook-connect system, delivery, interaction

Adapter type is descriptive, not exclusive.

8. Normative Language

The following terms are used in this specification:

  • MUST means required for contract compliance.
  • SHOULD means recommended unless a documented reason exists.
  • MAY means optional.
  • MUST NOT means prohibited for contract compliance.

9. Core Interface Objects

9.1 AdapterDescriptor

An AdapterDescriptor declares the identity, version, capabilities, event support, evidence profile, and operational characteristics of an adapter.

Adapters MUST expose a descriptor.

AdapterDescriptor:
  adapter_id: string
  adapter_name: string
  adapter_version: string
  adapter_contract_version: string
  adapter_types:
    - string
  provider_family: string?
  provider_name: string?
  deployment_mode: embedded | sidecar | external | unknown
  capability_profile: AdapterCapabilityProfile
  supported_actions:
    - AdapterActionCapability
  emitted_event_types:
    - string
  supported_channels:
    - string
  supported_endpoint_types:
    - string
  evidence_profile: AdapterEvidenceProfile
  evidence_ceiling: EvidenceCeiling
  assurance_capability: AssuranceCapability
  identity_profile: AdapterIdentityProfile
  late_event_policy: LateEventPolicy
  feature_dependencies:
    - FeatureDependency
  latency_profile: AdapterLatencyProfile?
  cost_profile: AdapterCostProfile?
  reliability_profile: AdapterReliabilityProfile?
  configuration_schema_ref: string?
  native_status_mapping_ref: string?
  golden_tests_ref: string?
  health_endpoint_ref: string?
  documentation_ref: string?
  limitations:
    - string

Required Fields

The following fields are REQUIRED:

adapter_id
adapter_name
adapter_version
adapter_contract_version
adapter_types
capability_profile
supported_actions
emitted_event_types
supported_channels
supported_endpoint_types
evidence_profile
evidence_ceiling
assurance_capability
identity_profile
late_event_policy
limitations

9.2 AdapterCapabilityProfile

An AdapterCapabilityProfile declares what the adapter can do, observe, and never prove.

AdapterCapabilityProfile:
  can_notify: boolean
  can_publish: boolean
  can_deliver_payload: boolean
  can_collect_payload: boolean
  can_grant_access: boolean
  can_revoke_access: boolean
  can_observe_interaction: boolean
  can_observe_identity: boolean
  can_observe_authority: boolean
  can_emit_delivery_receipts: boolean
  can_emit_display_or_read_receipts: boolean
  can_emit_return_or_failure_events: boolean
  can_emit_late_events: boolean
  can_cancel_after_dispatch: boolean
  supports_webhooks: boolean
  supports_polling: boolean
  supports_idempotency: native | adapter_managed | none | unknown
  supports_endpoint_quality: boolean
  supports_native_status_mapping: boolean
  supports_golden_tests: boolean
  limitations:
    - string

Example: email-connect

AdapterCapabilityProfile:
  can_notify: true
  can_publish: false
  can_deliver_payload: false
  can_collect_payload: false
  can_grant_access: false
  can_revoke_access: false
  can_observe_interaction: true
  can_observe_identity: false
  can_observe_authority: false
  can_emit_delivery_receipts: false
  can_emit_display_or_read_receipts: false
  can_emit_return_or_failure_events: true
  can_emit_late_events: true
  can_cancel_after_dispatch: false
  supports_webhooks: true
  supports_polling: false
  supports_idempotency: adapter_managed
  supports_endpoint_quality: true
  supports_native_status_mapping: true
  supports_golden_tests: true
  limitations:
    - Recipient mail server acceptance does not prove inbox placement.
    - Open and click tracking are ambiguous.

Example: hybridmail-connect

AdapterCapabilityProfile:
  can_notify: false
  can_publish: false
  can_deliver_payload: true
  can_collect_payload: false
  can_grant_access: false
  can_revoke_access: false
  can_observe_interaction: false
  can_observe_identity: false
  can_observe_authority: false
  can_emit_delivery_receipts: true
  can_emit_display_or_read_receipts: false
  can_emit_return_or_failure_events: true
  can_emit_late_events: true
  can_cancel_after_dispatch: false
  supports_webhooks: true
  supports_polling: true
  supports_idempotency: adapter_managed
  supports_endpoint_quality: true
  supports_native_status_mapping: true
  supports_golden_tests: true
  limitations:
    - Postal handover does not prove recipient reading.
    - Ordinary letters often do not provide final delivery confirmation.

9.3 EvidenceCeiling

An EvidenceCeiling declares the strongest evidence the adapter can provide under its configured capabilities.

EvidenceCeiling:
  max_positive_event: string
  max_positive_strength: none | weak | medium | strong | conclusive | unknown
  can_prove_human_awareness: boolean | partially
  can_prove_payload_access: boolean | partially
  can_prove_payload_delivery: boolean | partially
  can_prove_identity: boolean | partially
  can_prove_authority: boolean | partially
  can_prove_non_repudiation: boolean | partially
  conditions:
    - string
  limitations:
    - string

Examples

email:
  max_positive_event: interaction.unverified_actor_interaction
  max_positive_strength: medium
  can_prove_human_awareness: false
  can_prove_payload_access: false
  can_prove_payload_delivery: false
  can_prove_identity: false
  can_prove_authority: false
  can_prove_non_repudiation: false
  limitations:
    - Email tracking cannot reliably prove intended-recipient awareness.
sms:
  max_positive_event: notification.endpoint.accepted
  max_positive_strength: strong
  can_prove_human_awareness: false
  can_prove_payload_access: false
  can_prove_payload_delivery: false
  can_prove_identity: false
  can_prove_authority: false
  can_prove_non_repudiation: false
  conditions:
    - Strongest evidence depends on carrier delivery receipts.
xmpp_with_display_markers:
  max_positive_event: interaction.notification.opened
  max_positive_strength: strong
  can_prove_human_awareness: partially
  can_prove_payload_access: false
  can_prove_payload_delivery: false
  can_prove_identity: partially
  can_prove_authority: false
  can_prove_non_repudiation: false
  conditions:
    - Requires client support for displayed markers.
hybridmail_registered:
  max_positive_event: delivery.postal.delivery_confirmed
  max_positive_strength: strong
  can_prove_human_awareness: false
  can_prove_payload_access: partially
  can_prove_payload_delivery: partially
  can_prove_identity: false
  can_prove_authority: false
  can_prove_non_repudiation: partially
  conditions:
    - Requires registered or delivery-confirmation postal product.

9.4 AssuranceCapability

AssuranceCapability allows coordination-engine to compare adapter capabilities against scenario assurance requirements.

AssuranceCapability:
  awareness_assurance: none | weak | medium | strong | conclusive | conditional | unknown
  delivery_assurance: none | weak | medium | strong | conclusive | conditional | unknown
  identity_assurance: none | weak | medium | strong | conclusive | conditional | unknown
  authority_assurance: none | weak | medium | strong | conclusive | conditional | unknown
  non_repudiation_assurance: none | weak | medium | strong | conclusive | conditional | unknown
  conditions:
    - string
  limitations:
    - string

Example:

email:
  awareness_assurance: weak
  delivery_assurance: none
  identity_assurance: none
  authority_assurance: none
  non_repudiation_assurance: none
portal:
  awareness_assurance: strong
  delivery_assurance: strong
  identity_assurance: strong
  authority_assurance: conditional
  non_repudiation_assurance: medium

9.5 AdapterActionCapability

An AdapterActionCapability declares one action an adapter can perform.

AdapterActionCapability:
  action_type: string
  description: string?
  mode: sync | async | scheduled
  idempotency_required: boolean
  required_fields:
    - string
  optional_fields:
    - string
  supported_channels:
    - string
  supported_endpoint_types:
    - string
  preconditions:
    - string
  postconditions:
    - string
  capability_dependencies:
    - string
  unsupported_when:
    - string
  expected_initial_events:
    - string
  possible_later_events:
    - string
  known_failure_modes:
    - string

Action Type Naming

Action types SHOULD use dotted semantic names.

Recommended families:

notification.*
publication.*
access.*
delivery.*
interaction.*
identity.*
authority.*
payment.*
signature.*
document.*
archive.*
feed.*
webhook.*
recipient.*
system.*

Examples:

notification.send
notification.send_reminder
publication.publish
access.grant
access.revoke
delivery.submit_payload
delivery.submit_letter
delivery.request_submission
payment.create_request
payment.cancel_request
signature.create_envelope
signature.cancel_envelope
feed.publish_item
recipient.suppress
recipient.unsuppress

9.6 AdapterActionRequest

An AdapterActionRequest is a command from coordination-engine to an adapter.

Adapters MUST accept action requests in this conceptual shape, even if transport-specific serialization differs.

AdapterActionRequest:
  request_id: string
  action_type: string
  coordination_case_id: string
  participant_id: string?
  payload_ref: ResourceRef?
  action_surface_ref: ActionSurfaceRef?
  channel: string?
  target_endpoint: EndpointRef?
  actor_context: ActorContext?
  content: ActionContent?
  template_ref: string?
  variables: object?
  tracking_context: TrackingContext
  policy_context: PolicyContext?
  security_context: SecurityContext?
  idempotency_key: string
  requested_at: timestamp
  expires_at: timestamp?
  metadata: object?

Required Fields

The following fields are REQUIRED:

request_id
action_type
coordination_case_id
tracking_context
idempotency_key
requested_at

Fields such as participant_id, payload_ref, target_endpoint, or action_surface_ref may be optional for system-level, broadcast, or publication actions, but adapters MAY require them for specific action types.

9.7 Idempotency

idempotency_key MUST be provided for all externally visible actions.

Adapters MUST treat repeated action requests with the same idempotency_key as duplicates of the same logical request.

Adapters SHOULD return the original or current action result for duplicate requests.

For irreversible or expensive side-effect actions, such as hybrid-mail physical dispatch or payment creation, adapters MUST implement strict duplicate prevention.

If the same idempotency key is used with conflicting request content, the adapter MUST return an idempotency conflict.

IdempotencyConflict:
  idempotency_key: string
  original_request_ref: string
  conflicting_request_ref: string
  conflict_fields:
    - string

9.8 TrackingContext

tracking_context MUST contain enough information to correlate later adapter events back to the coordination case.

TrackingContext:
  correlation_id: string
  coordination_case_id: string
  participant_id: string?
  notification_id: string?
  delivery_id: string?
  interaction_id: string?
  payload_id: string?
  action_surface_id: string?
  external_context:
    - key: string
      value: string

Adapters MUST preserve correlation identifiers where technically possible.

Adapters SHOULD include correlation identifiers in outbound provider metadata, message headers, webhook metadata, URLs, tokens, provider custom arguments, or provider-specific reference fields when supported.

9.9 EndpointRef

EndpointRef:
  endpoint_id: string?
  endpoint_type: string
  value: string?
  display_name: string?
  verified: boolean?
  metadata: object?

Examples of endpoint_type:

email_address
phone_number
push_token
xmpp_jid
rss_feed
atom_feed
webhook_url
portal_account
payment_account
signature_recipient
api_client
postal_address
physical_address
muc_room_jid
pubsub_node

9.10 EndpointQuality

Adapters SHOULD expose endpoint quality where meaningful.

EndpointQuality:
  endpoint_ref: EndpointRef
  endpoint_type: string
  validity: valid | invalid | suspected_invalid | unknown
  reachability: reachable | unreachable | degraded | unknown
  verification_state: unverified | syntax_validated | provider_verified | recently_successful | failed | unknown
  suppression_state: active | suppressed | blocked | opted_out | unknown
  last_success_at: timestamp?
  last_failure_at: timestamp?
  quality_signals:
    - string
  confidence: low | medium | high
  adapter_specific:
    email: object?
    sms: object?
    rss: object?
    xmpp: object?
    hybridmail: object?
    other: object?

Examples of adapter-specific quality signals:

email: mx_exists, hard_bounce_history, catch_all_suspected
sms: e164_valid, number_type, carrier, opt_out_state
rss: feed_valid, last_fetch_observed, cache_status
xmpp: presence_state, roster_state, resource_known
hybridmail: address_valid, address_position_valid, return_history

9.11 ActionSurfaceRef

Adapters often point participants toward action surfaces rather than completing results themselves.

ActionSurfaceRef:
  action_surface_id: string
  action_surface_type: portal | payment_page | signature_flow | upload_form | api_endpoint | physical_letter | chat_command | feed_item | other
  uri: string?
  requires_authentication: boolean?
  expected_interactions:
    - string
  metadata: object?

Adapters SHOULD include action_surface_ref when the action contains a link, command, form, payment flow, signature flow, or physical action prompt.

9.12 ActionContent

ActionContent represents content or content references.

Adapters SHOULD prefer references over large inline content where possible.

ActionContent:
  content_ref: string?
  subject: string?
  body_text: string?
  body_html: string?
  payload_refs:
    - ResourceRef
  action_links:
    - ActionLink
  attachments:
    - ResourceRef
  inline_data: object?

9.13 ResourceRef

ResourceRef:
  ref_type: string
  ref_id: string
  uri: string?
  version: string?
  integrity_hash: string?
  metadata: object?
ActionLink:
  link_id: string
  purpose: string
  url: string
  expires_at: timestamp?
  tokenized: boolean?
  requires_authentication: boolean?

9.15 AdapterActionResult

An AdapterActionResult is the adapters response to an action request.

AdapterActionResult:
  request_id: string
  adapter_id: string
  accepted: boolean
  action_state: AdapterActionState
  adapter_operation_id: string?
  provider_operation_id: string?
  initial_events:
    - EvidenceEvent
  raw_response_ref: string?
  error: ErrorDescriptor?
  received_at: timestamp
  completed_at: timestamp?
  metadata: object?

AdapterActionState

accepted
rejected
queued
scheduled
in_progress
completed
failed
cancelled
duplicate
idempotency_conflict
unknown

Important Rule

An accepted action result is not proof that the intended result was achieved.

Example:

For email, accepted: true means the email adapter accepted the send request. It does not prove that the recipient received, saw, understood, or acted on the notification.

For hybrid mail, accepted: true means the adapter accepted the request. It does not prove that the letter was validated, printed, handed over, delivered, or read.

9.16 AdapterEvent

An AdapterEvent is an incoming event from an adapter before or during evidence normalization.

Adapters MAY expose native-like adapter events, but MUST provide a mapping to EvidenceEvent.

AdapterEvent:
  event_id: string
  adapter_id: string
  adapter_event_type: string
  native_event_type: string?
  native_status: string?
  occurred_at: timestamp?
  received_at: timestamp
  observation: EventObservation
  correlation: CorrelationContext
  participant_id: string?
  payload_ref: ResourceRef?
  action_surface_ref: ActionSurfaceRef?
  endpoint_ref: EndpointRef?
  actor_context: ActorContext?
  provider_refs:
    - ProviderRef
  raw_event_ref: string?
  normalization_status: normalized | ignored | failed | pending
  normalized_events:
    - EvidenceEvent
  metadata: object?

9.17 EventObservation

EventObservation distinguishes the event source from the event meaning.

EventObservation:
  source_type: adapter | provider_api | provider_webhook | endpoint | carrier | recipient_client | postal_carrier | feed_server | action_surface | manual | system | unknown
  observed_at: timestamp
  occurred_at: timestamp?
  source_confidence: low | medium | high
  observer_ref: string?
  transport_ref: string?
  notes:
    - string

This is useful because provider events may be delayed, forwarded, batched, inferred, or partially observed.

9.18 EvidenceEvent

An EvidenceEvent is the normalized event format consumed by the evidence-ledger.

Adapters MUST produce or enable production of EvidenceEvent records.

EvidenceEvent:
  evidence_event_id: string
  event_type: string
  event_family: string
  occurred_at: timestamp?
  observed_at: timestamp
  source_adapter_id: string?
  source_adapter_event_id: string?
  coordination_case_id: string
  participant_id: string?
  payload_ref: ResourceRef?
  action_surface_ref: ActionSurfaceRef?
  endpoint_ref: EndpointRef?
  actor_context: ActorContext?
  observation: EventObservation?
  provider_refs:
    - ProviderRef
  normalized_meaning: string
  evidence_grade: EvidenceGrade
  confidence: ConfidenceGrade
  raw_event_ref: string?
  correlation: CorrelationContext
  native_status_mapping_ref: string?
  metadata: object?

Required Fields

The following fields are REQUIRED:

evidence_event_id
event_type
event_family
observed_at
coordination_case_id
normalized_meaning
evidence_grade
confidence
correlation

occurred_at SHOULD be included when the source provides it.

10. Canonical Event Families

The following event families are canonical for adapter-generated evidence.

notification
publication
access
delivery
interaction
identity
authority
payload
payment
signature
feed
webhook
system
manual
result
policy

Adapters SHOULD map native events into these families.

11. Canonical Event Types

This version defines a starter vocabulary. It is not exhaustive.

11.1 Notification Events

notification.attempt.created
notification.attempt.accepted_by_adapter
notification.attempt.rejected_by_adapter
notification.attempt.accepted_by_provider
notification.attempt.rejected_by_provider
notification.attempt.queued
notification.attempt.scheduled
notification.attempt.delayed
notification.attempt.cancelled
notification.endpoint.accepted
notification.endpoint.deferred
notification.endpoint.rejected_temporary
notification.endpoint.rejected_permanent
notification.endpoint.unreachable
notification.endpoint.unknown
notification.channel.complaint_received
notification.channel.unsubscribe_received
notification.channel.suppression_added
notification.channel.suppression_removed
notification.channel.reputation_warning

11.2 Publication and Feed Events

publication.item.published
publication.item.updated
publication.item.removed
feed.item.published
feed.item.updated
feed.item.removed
feed.item.expired
feed.item.fetched
feed.feed.fetched
feed.feed.validated
feed.feed.validation_failed
feed.hub.notified
feed.hub.notification_failed

11.3 Access Events

access.grant.created
access.grant.issued
access.grant.used
access.grant.denied
access.grant.expired
access.grant.revoked
access.grant.delegated
access.grant.suspicious_use_detected

11.4 Delivery Events

delivery.payload.available
delivery.payload.presented
delivery.payload.viewed
delivery.payload.retrieved
delivery.payload.downloaded
delivery.payload.submitted
delivery.payload.received
delivery.payload.validated
delivery.payload.validation_failed
delivery.payload.accepted
delivery.payload.rejected
delivery.payload.archived
delivery.payload.failed
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

The event delivery.postal.delivered SHOULD be avoided because it is ambiguous. Use delivery.postal.delivery_confirmed where actual confirmation semantics exist.

11.5 Interaction Events

interaction.surface.opened
interaction.notification.opened
interaction.link.clicked
interaction.proxy_or_privacy_interaction
interaction.scanner_or_bot_interaction
interaction.unverified_actor_interaction
interaction.authenticated_actor_interaction
interaction.authorized_actor_interaction
interaction.reply_received
interaction.out_of_office_received
interaction.acknowledgement_recorded
interaction.decline_recorded
interaction.dispute_opened

11.6 Identity Events

identity.actor_unknown
identity.actor_suspected
identity.actor_authenticated
identity.actor_mfa_verified
identity.actor_verified_by_provider
identity.actor_mismatch_detected

11.7 Authority Events

authority.unknown
authority.self_asserted
authority.delegate_authorized
authority.organizational_representative_verified
authority.signer_authorized
authority.payment_authorized
authority.authorization_failed

11.8 Payment Events

payment.request.created
payment.request.presented
payment.started
payment.failed
payment.cancelled
payment.succeeded
payment.settled
payment.partially_settled
payment.refunded
payment.disputed
payment.promise_to_pay_recorded

11.9 Signature Events

signature.envelope.created
signature.envelope.sent
signature.document.viewed
signature.signing.started
signature.signing.completed
signature.signing.declined
signature.signing.expired
signature.signing.cancelled
signature.document.finalized
signature.document.archived

11.10 Webhook/System Events

webhook.request.sent
webhook.response.accepted
webhook.response.rejected
webhook.delivery.failed
system.adapter.health_changed
system.provider.degraded
system.provider.unavailable

12. Acceptance-Level Metadata

Some generic event names, especially notification.endpoint.accepted, may represent different strengths depending on protocol.

Adapters SHOULD include acceptance-level metadata.

AcceptanceSemantics:
  acceptance_level: provider | relay | carrier | server | endpoint | client | device | mailbox | physical_handover | unknown
  finality: preliminary | intermediate | final | unknown
  does_not_mean:
    - string

Examples:

email_mx_accepted:
  acceptance_level: server
  finality: intermediate
  does_not_mean:
    - inbox placement
    - human awareness
sms_delivered:
  acceptance_level: device
  finality: final
  does_not_mean:
    - human read
    - intended-recipient identity
xmpp_delivery_receipt:
  acceptance_level: client
  finality: intermediate
  does_not_mean:
    - displayed
    - understood
hybridmail_postal_handover:
  acceptance_level: physical_handover
  finality: intermediate
  does_not_mean:
    - final delivery confirmation
    - human reading

13. EvidenceGrade

An EvidenceGrade describes what an event can reasonably support.

Adapters MUST assign an evidence grade to normalized evidence events.

EvidenceGrade:
  strength: none | weak | medium | strong | conclusive | negative | ambiguous
  actor_certainty: none | low | medium | high
  authority_certainty: none | low | medium | high
  payload_certainty: none | low | medium | high
  interaction_certainty: none | low | medium | high
  timing_certainty: none | low | medium | high
  channel_certainty: none | low | medium | high
  non_repudiation_strength: none | low | medium | high
  notes:
    - string

14. ConfidenceGrade

ConfidenceGrade expresses how confident the adapter is in the normalized interpretation.

ConfidenceGrade:
  level: low | medium | high
  basis:
    - string

Example:

level: medium
basis:
  - Provider event type is known.
  - Native event contains provider message ID.
  - Event was correlated to known action request.

15. NativeStatusMapping

Adapters MUST define native-to-normalized mappings for provider statuses or native events where applicable.

NativeStatusMapping:
  native_status: string
  native_event_type: string?
  native_status_scope: provider | endpoint | transport | interaction | delivery | production | postal | payment | signature | publication | feed | system | unknown
  normalized_event: string
  normalized_state: string?
  evidence_grade: EvidenceGrade
  confidence: low | medium | high
  terminal: boolean
  retryable: boolean?
  ambiguous: boolean
  product_or_feature_dependent: boolean
  required_features:
    - string
  warning: string?
  examples:
    - string

16. NativeEventSemantics

Adapters SHOULD document native event semantics for agent-friendly implementation.

NativeEventSemantics:
  native_event_type: string
  source_system: string
  plain_meaning: string
  does_not_mean:
    - string
  normalized_mapping: string
  evidence_grade: EvidenceGrade
  examples:
    - string

Example:

native_event_type: delivered
source_system: email_provider
plain_meaning: Recipient mail server accepted the message.
does_not_mean:
  - Message reached inbox.
  - Human recipient saw the message.
  - Payload was accessed.
normalized_mapping: notification.endpoint.accepted

17. AdapterEvidenceAssessment

Adapters SHOULD provide a native evidence assessment for standalone use and diagnostics.

AdapterEvidenceAssessment:
  subject_ref: string
  coordination_case_id: string?
  participant_id: string?
  adapter_id: string
  category: success | fail | undef
  subclass: string
  confidence: low | medium | high
  strongest_signal: string?
  evidence_summary:
    - string
  recommended_coordination_interpretation: string?
  limitations:
    - string

Adapter assessment is advisory.

coordination-engine remains authoritative for participant and case state.

Examples:

email:
  category: undef
  subclass: endpoint_accepted_only

sms:
  category: success
  subclass: delivered

hybridmail:
  category: success
  subclass: handed_to_postal_service

These adapter-native classifications do not automatically become coordination-case success.

18. ActorContext

ActorContext describes the actor associated with an event, if known.

ActorContext:
  actor_ref: string?
  actor_type: human | organization | system | agent | bot | unknown
  identity_strength: none | low | medium | high
  authority_strength: none | low | medium | high
  authenticated: boolean?
  delegated: boolean?
  provider_identity_ref: string?
  metadata: object?

Adapters SHOULD avoid overclaiming identity.

For example:

  • email-connect SHOULD NOT mark a click as authenticated unless backed by trusted identity or portal evidence.
  • sms-connect SHOULD NOT assume phone possession equals intended participant identity.
  • rss-connect SHOULD NOT assume feed fetch equals participant identity.
  • xmpp-connect MAY provide medium/high identity evidence if JID mapping and authentication are reliable.
  • hybridmail-connect SHOULD NOT infer recipient identity merely from postal dispatch.

19. CorrelationContext

Correlation is mandatory for useful adapter integration.

CorrelationContext:
  correlation_id: string
  request_id: string?
  coordination_case_id: string
  participant_id: string?
  notification_id: string?
  delivery_id: string?
  interaction_id: string?
  payload_id: string?
  action_surface_id: string?
  adapter_operation_id: string?
  provider_operation_id: string?
  provider_message_id: string?
  external_refs:
    - ProviderRef

Adapters MUST preserve correlation identifiers where technically possible.

20. ProviderRef

ProviderRef:
  provider_name: string
  ref_type: string
  ref_value: string

Examples:

provider_name: sendgrid
ref_type: message_id
ref_value: abc123
provider_name: stripe
ref_type: payment_intent_id
ref_value: pi_123
provider_name: pingen
ref_type: letter_id
ref_value: letter_123

21. FeatureDependency

FeatureDependency describes provider-, route-, product-, or configuration-specific requirements.

FeatureDependency:
  feature_name: string
  dependency_type: provider | product | route | country | endpoint | recipient_client | configuration | policy | account | unknown
  required_for_events:
    - string
  fallback_behavior: string
  limitation: string

Examples:

feature_name: email_click_tracking
dependency_type: configuration
required_for_events:
  - interaction.link.clicked
fallback_behavior: no click events emitted
limitation: Link clicks cannot be observed without tracking links.
feature_name: xmpp_displayed_markers
dependency_type: recipient_client
required_for_events:
  - interaction.notification.opened
fallback_behavior: delivery receipts only
limitation: Displayed markers depend on client support.
feature_name: hybridmail_delivery_confirmation
dependency_type: product
required_for_events:
  - delivery.postal.delivery_confirmed
fallback_behavior: postal handover is maximum positive evidence
limitation: Ordinary letters do not provide delivery confirmation.

22. LateEventPolicy

Adapters frequently produce late events.

Examples:

Adapter Late event example
Email async bounce
SMS late delivery receipt
RSS delayed feed fetch log
XMPP delayed delivery receipt
Hybrid mail return mail weeks later

Adapters MUST declare their late-event policy.

LateEventPolicy:
  accepts_late_events: boolean
  late_events_can_revise_assessment: boolean
  late_events_can_reopen_case: boolean
  default_late_event_window: string?
  expected_late_event_types:
    - string
  notes:
    - string

Normative rule:

Adapters MUST emit late events if they are relevant.
coordination-engine decides whether to revise, annotate, reopen, or ignore case state.

23. ErrorDescriptor

ErrorDescriptor:
  code: string
  message: string
  retryable: boolean
  category: validation | authentication | authorization | configuration | provider | network | rate_limit | timeout | conflict | idempotency_conflict | unsupported_capability | unknown
  native_error_code: string?
  native_error_message: string?
  details: object?

Adapters MUST return an ErrorDescriptor when an action request is rejected or fails before acceptance.

24. AdapterHealth

Adapters MUST expose health state.

AdapterHealth:
  adapter_id: string
  status: healthy | degraded | unavailable | misconfigured | unknown
  checked_at: timestamp
  provider_connectivity: healthy | degraded | unavailable | unknown
  configuration_validity: valid | invalid | partial | unknown
  credential_status: valid | expired | missing | insufficient | unknown
  webhook_status: healthy | degraded | unavailable | not_supported | unknown
  polling_status: healthy | degraded | unavailable | not_supported | unknown
  last_action_success_at: timestamp?
  last_event_received_at: timestamp?
  known_degradations:
    - string
  metrics:
    actions_accepted_last_24h: integer?
    actions_failed_last_24h: integer?
    events_received_last_24h: integer?
    average_action_latency_ms: integer?

25. Transport Patterns

This specification does not mandate one technical transport.

Adapters MAY integrate through:

REST API
event bus
message queue
webhook
gRPC
embedded library
CLI
file drop
polling

However, any transport MUST preserve the semantic contract defined here.

26. Adapter Integration Modes

26.1 Embedded Mode

Adapter code runs in the same process as coordination-engine.

Suitable for:

  • local development
  • test adapters
  • simulated adapters
  • simple deployments

26.2 Sidecar Mode

Adapter runs next to the engine but is deployed separately.

Suitable for:

  • credential isolation
  • provider-specific webhook handling
  • protocol-specific runtime dependencies

26.3 External Service Mode

Adapter is an independently deployed service.

Suitable for:

  • reusable *-connect components
  • multi-tenant installations
  • independent scaling
  • provider abstraction
  • operational separation

Preferred direction for production adapters:

*-connect repositories SHOULD implement external service mode first,
while optionally also offering embedded or sidecar modes.

27. Adapter Lifecycle

Adapters SHOULD support the following lifecycle:

registered
configured
healthy
degraded
disabled
retired

27.1 Registration

During registration, the adapter provides its AdapterDescriptor.

27.2 Configuration

Configuration may include credentials, provider selection, endpoint settings, webhook secrets, templates, routing policies, tenant-specific settings, product settings, or feature flags.

27.3 Health Monitoring

The engine or platform periodically checks AdapterHealth.

27.4 Action Dispatch

The engine dispatches AdapterActionRequest objects to the adapter.

27.5 Event Ingestion

The adapter emits AdapterEvent or EvidenceEvent objects.

27.6 Degradation Handling

If an adapter is degraded, the policy engine may switch channel, delay actions, retry later, or escalate.

28. Event Ordering, Idempotency, and Late Events

28.1 Event Ordering

Adapters MUST NOT assume events arrive in causal order.

The engine MUST be able to process late events.

Adapters SHOULD include accurate occurred_at and observed_at timestamps.

28.2 Duplicate Events

Adapters SHOULD provide stable event identifiers where possible.

The engine MUST deduplicate events using:

evidence_event_id
adapter_event_id
provider event id
correlation context
event type
timestamp

28.3 Late Events

Late events MUST still be accepted and recorded if they are relevant.

Examples:

Email: late hard bounce
SMS: late delivery receipt
RSS: delayed fetch log
XMPP: delayed receipt after offline delivery
Hybrid mail: return mail event after postal handover

28.4 Idempotent Actions

All externally visible actions MUST include idempotency_key.

Adapters MUST avoid duplicate external side effects for repeated action requests with the same key.

29. Adapter Conformance Levels

Adapters MAY implement different maturity levels.

Level 0: Descriptor only / simulated
Level 1: Action execution + basic evidence events
Level 2: Native status mapping + health + idempotency
Level 3: Evidence grading + endpoint quality + late events
Level 4: Full provider flavor / product semantics / golden tests

Level 0

The adapter exposes a descriptor and may simulate actions/events.

Level 1

The adapter can execute at least one supported action and emit basic normalized evidence events.

Level 2

The adapter supports health, idempotency, native status mapping, and error handling.

Level 3

The adapter supports evidence grading, endpoint quality, late events, and advisory assessments.

Level 4

The adapter includes provider/product semantics, capability profiles, native status mapping registry, golden tests, and conformance documentation.

Production adapters SHOULD target Level 3 or higher.

Provider-flavor-heavy adapters, such as hybridmail-connect, SHOULD target Level 4.

30. Golden Test Requirements

Every adapter SHOULD define golden test scenarios.

AdapterGoldenTest:
  test_id: string
  scenario: string
  adapter_id: string
  native_events:
    - object
  expected_evidence_events:
    - EvidenceEvent
  expected_assessment: AdapterEvidenceAssessment
  must_not_emit:
    - string
  notes:
    - string

Recommended test categories:

duplicate action request
idempotency conflict
provider acceptance
provider rejection
ambiguous native event
late event
out-of-order event
unsupported capability
endpoint failure
strongest supported positive event
status overclaim prevention
raw event preservation

Example:

test_id: hybridmail_ordinary_handover_not_delivery_confirmation
scenario: Ordinary letter handed over to postal service.
expected_evidence_events:
  - event_type: delivery.postal.handed_over
must_not_emit:
  - delivery.postal.delivery_confirmed

Example:

test_id: email_provider_delivered_not_awareness
scenario: Email provider reports delivered.
expected_evidence_events:
  - event_type: notification.endpoint.accepted
must_not_emit:
  - interaction.notification.opened
  - delivery.payload.downloaded

31. Security Requirements

Adapters MUST:

  • protect provider credentials
  • verify incoming provider webhooks where possible
  • validate action request authenticity
  • avoid leaking sensitive payloads in logs
  • support least-privilege configuration
  • preserve correlation without exposing unnecessary personal data
  • avoid storing raw sensitive data unless explicitly configured
  • distinguish test/sandbox from production where relevant

Adapters SHOULD:

  • support tenant separation
  • support secret rotation
  • support signed callbacks or event signatures
  • support audit logging of action execution

32. Privacy Requirements

Adapters SHOULD minimize personal data.

Adapters SHOULD support:

  • endpoint references instead of full endpoint values where possible
  • redaction of raw provider events
  • retention limits for raw event data
  • configurable storage of message content
  • metadata-only mode
  • data deletion or anonymization workflows where applicable

The adapter interface MUST allow references to external payloads rather than requiring payload content to be copied into the adapter.

33. Standalone Adapter Requirements

Adapters are encouraged to be useful outside coordination-engine.

A standalone adapter MAY provide:

  • provider abstraction
  • operational dashboard
  • message or delivery timeline API
  • diagnostic API
  • native event archive
  • normalized event stream
  • suppression management
  • provider health checks
  • local policy hints
  • endpoint quality diagnostics
  • adapter-native evidence assessment

However, standalone features MUST NOT contradict the coordination-engine contract.

For example:

  • email-connect may expose delivered_to_mx, but MUST NOT expose it as business-level awareness.
  • sms-connect may expose delivered_to_device, but MUST NOT expose it as human-read proof.
  • rss-connect may expose published, but MUST NOT expose it as participant awareness.
  • xmpp-connect may expose displayed, but MUST NOT expose it as comprehension.
  • hybridmail-connect may expose handed_to_postal_service, but MUST NOT expose it as final delivery confirmation.

34. Compatibility Requirements for Adapter Repositories

Every *-connect repository SHOULD contain:

INTENT.md
docs/AdapterImplementation.md
docs/EventMapping.md
docs/ProviderModel.md
docs/EvidenceClassification.md
docs/GoldenTests.md
schemas/
src/
tests/

Every adapter repository MUST document:

Implemented adapter contract version
Conformance level
Supported actions
Emitted normalized events
Native event mappings
Evidence grading rules
Evidence ceiling
Endpoint quality model
Late event policy
Known limitations
Provider-specific assumptions
Security model
Privacy model
Standalone usage
coordination-engine integration mode

35. Versioning

35.1 Contract Version

Adapters MUST declare adapter_contract_version.

This document defines:

adapter_contract_version: 1.1

35.2 Backward Compatibility

Minor extensions MAY add:

  • optional fields
  • new event types
  • new action types
  • new adapter types
  • new evidence metadata
  • new capability flags

Breaking changes include:

  • removing required fields
  • changing meaning of existing fields
  • changing event semantics
  • changing idempotency requirements
  • changing evidence grade semantics
  • changing weakest-safe-mapping requirements

Breaking changes require a new major version.

36. Minimal Compliance Checklist

An adapter is minimally compliant with AdapterInterfaceSpecification 1.1 if it:

  1. Exposes an AdapterDescriptor.
  2. Exposes an AdapterCapabilityProfile.
  3. Declares supported actions.
  4. Declares emitted event types.
  5. Declares an EvidenceCeiling.
  6. Declares AssuranceCapability.
  7. Accepts AdapterActionRequest objects for supported actions.
  8. Returns AdapterActionResult objects.
  9. Supports idempotency keys.
  10. Emits or maps to EvidenceEvent objects.
  11. Provides EvidenceGrade and ConfidenceGrade.
  12. Preserves CorrelationContext.
  13. Exposes AdapterHealth.
  14. Documents known limitations.
  15. Does not overclaim result success.
  16. Clearly separates provider-native events from normalized evidence.
  17. Applies weakest safe mapping to ambiguous native events.
  18. Preserves raw native event references where possible.
  19. Declares late-event behavior.
  20. Provides advisory AdapterEvidenceAssessment or explains why not.

37. Non-Goals

This adapter specification does not define:

  • the internal storage model of adapters
  • the provider-specific API shape
  • the transport protocol used between engine and adapter
  • legal validity of evidence
  • UI requirements
  • billing models
  • tenant management model
  • full workflow semantics
  • complete event vocabulary for every possible domain

Those concerns may be defined in separate documents or scenario-specific specifications.

38. Strategic Summary

The adapter interface allows coordination-engine to remain a generalized coordination runtime while integrating with many concrete systems.

Adapters perform actions and emit evidence. They translate external provider realities into a normalized coordination vocabulary without deciding overall business success.

Version 1.1 strengthens the interface by requiring adapters to declare what they can prove, what they cannot prove, how native statuses map to normalized evidence, and how ambiguity is handled.

The central rule is:

Adapters must preserve facts, underclaim semantics, expose limitations, and let coordination-engine decide result meaning.

This distinction is essential for reliable, extensible, evidence-driven digital coordination.