Files
coordination-engine/spec/AdapterInterfaceSpecification.md

1992 lines
48 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
```text
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:
```text
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:
```text
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.
```yaml
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:
```text
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.
```yaml
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
```yaml
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
```yaml
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.
```yaml
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
```yaml
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.
```
```yaml
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.
```
```yaml
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.
```
```yaml
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.
```yaml
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:
```yaml
email:
awareness_assurance: weak
delivery_assurance: none
identity_assurance: none
authority_assurance: none
non_repudiation_assurance: none
```
```yaml
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.
```yaml
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:
```text
notification.*
publication.*
access.*
delivery.*
interaction.*
identity.*
authority.*
payment.*
signature.*
document.*
archive.*
feed.*
webhook.*
recipient.*
system.*
```
Examples:
```text
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.
```yaml
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:
```text
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.
```yaml
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.
```yaml
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
```yaml
EndpointRef:
endpoint_id: string?
endpoint_type: string
value: string?
display_name: string?
verified: boolean?
metadata: object?
```
Examples of `endpoint_type`:
```text
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.
```yaml
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:
```text
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.
```yaml
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.
```yaml
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
```yaml
ResourceRef:
ref_type: string
ref_id: string
uri: string?
version: string?
integrity_hash: string?
metadata: object?
```
## 9.14 ActionLink
```yaml
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.
```yaml
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
```text
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`.
```yaml
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.
```yaml
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.
```yaml
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:
```text
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.
```text
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
```text
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
```text
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
```text
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
```text
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
```text
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
```text
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
```text
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
```text
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
```text
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
```text
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.
```yaml
AcceptanceSemantics:
acceptance_level: provider | relay | carrier | server | endpoint | client | device | mailbox | physical_handover | unknown
finality: preliminary | intermediate | final | unknown
does_not_mean:
- string
```
Examples:
```yaml
email_mx_accepted:
acceptance_level: server
finality: intermediate
does_not_mean:
- inbox placement
- human awareness
```
```yaml
sms_delivered:
acceptance_level: device
finality: final
does_not_mean:
- human read
- intended-recipient identity
```
```yaml
xmpp_delivery_receipt:
acceptance_level: client
finality: intermediate
does_not_mean:
- displayed
- understood
```
```yaml
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.
```yaml
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.
```yaml
ConfidenceGrade:
level: low | medium | high
basis:
- string
```
Example:
```yaml
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.
```yaml
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.
```yaml
NativeEventSemantics:
native_event_type: string
source_system: string
plain_meaning: string
does_not_mean:
- string
normalized_mapping: string
evidence_grade: EvidenceGrade
examples:
- string
```
Example:
```yaml
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.
```yaml
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:
```text
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.
```yaml
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.
```yaml
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
```yaml
ProviderRef:
provider_name: string
ref_type: string
ref_value: string
```
Examples:
```yaml
provider_name: sendgrid
ref_type: message_id
ref_value: abc123
```
```yaml
provider_name: stripe
ref_type: payment_intent_id
ref_value: pi_123
```
```yaml
provider_name: pingen
ref_type: letter_id
ref_value: letter_123
```
## 21. FeatureDependency
`FeatureDependency` describes provider-, route-, product-, or configuration-specific requirements.
```yaml
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:
```yaml
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.
```
```yaml
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.
```
```yaml
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.
```yaml
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:
```text
Adapters MUST emit late events if they are relevant.
coordination-engine decides whether to revise, annotate, reopen, or ignore case state.
```
## 23. ErrorDescriptor
```yaml
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.
```yaml
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:
```text
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:
```text
*-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:
```text
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:
```text
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:
```text
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.
```text
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.
```yaml
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:
```text
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:
```yaml
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:
```yaml
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:
```text
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:
```text
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:
```text
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.