48 KiB
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:
- SMS
- RSS / Atom / WebSub
- XMPP
- Hybrid Mail
The main changes are:
- Added
AdapterCapabilityProfile. - Added
EvidenceCeiling. - Added
NativeStatusMapping/NativeEventSemantics. - Added universal weakest-safe-mapping rule.
- Added
AdapterEvidenceAssessment. - Added
EndpointQuality. - Added
LateEventPolicy. - Added
EventObservation. - Added
FeatureDependency. - Added
AssuranceCapability. - Added adapter conformance levels.
- Added golden test requirements.
- Strengthened semantic underclaiming requirements.
- 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-connectsms-connectrss-connectxmpp-connecthybridmail-connectpush-connectportal-connectpayment-connectsignature-connectdocument-connectidentity-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:
- Declaring capabilities.
- Declaring evidence ceilings.
- Accepting action requests.
- Returning action results.
- Preserving native events.
- Mapping native events conservatively.
- Emitting normalized evidence events.
- Providing advisory evidence assessments.
- Exposing endpoint quality and adapter health.
- 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:
CoordinationCaseParticipantIntendedResult- 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:
AdapterDescriptorAdapterCapabilityProfileAdapterActionCapabilityAdapterActionRequestAdapterActionResultAdapterEventEvidenceEventAdapterEvidenceAssessmentEvidenceGradeEvidenceCeilingNativeStatusMappingNativeEventSemanticsEndpointQualityAdapterHealthCorrelationContextErrorDescriptorLateEventPolicyFeatureDependencyAssuranceCapabilityAdapterGoldenTest
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?
9.14 ActionLink
ActionLink:
link_id: string
purpose: string
url: string
expires_at: timestamp?
tokenized: boolean?
requires_authentication: boolean?
9.15 AdapterActionResult
An AdapterActionResult is the adapter’s 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-connectSHOULD NOT mark a click as authenticated unless backed by trusted identity or portal evidence.sms-connectSHOULD NOT assume phone possession equals intended participant identity.rss-connectSHOULD NOT assume feed fetch equals participant identity.xmpp-connectMAY provide medium/high identity evidence if JID mapping and authentication are reliable.hybridmail-connectSHOULD 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 |
|---|---|
| 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
*-connectcomponents - 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-connectmay exposedelivered_to_mx, but MUST NOT expose it as business-level awareness.sms-connectmay exposedelivered_to_device, but MUST NOT expose it as human-read proof.rss-connectmay exposepublished, but MUST NOT expose it as participant awareness.xmpp-connectmay exposedisplayed, but MUST NOT expose it as comprehension.hybridmail-connectmay exposehanded_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:
- Exposes an
AdapterDescriptor. - Exposes an
AdapterCapabilityProfile. - Declares supported actions.
- Declares emitted event types.
- Declares an
EvidenceCeiling. - Declares
AssuranceCapability. - Accepts
AdapterActionRequestobjects for supported actions. - Returns
AdapterActionResultobjects. - Supports idempotency keys.
- Emits or maps to
EvidenceEventobjects. - Provides
EvidenceGradeandConfidenceGrade. - Preserves
CorrelationContext. - Exposes
AdapterHealth. - Documents known limitations.
- Does not overclaim result success.
- Clearly separates provider-native events from normalized evidence.
- Applies weakest safe mapping to ambiguous native events.
- Preserves raw native event references where possible.
- Declares late-event behavior.
- Provides advisory
AdapterEvidenceAssessmentor 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.