generated from coulomb/repo-seed
1413 lines
33 KiB
Markdown
1413 lines
33 KiB
Markdown
# Technical Specification Document: coordination-engine Architecture and Adapter Subsystem
|
|
|
|
## 1. Document Status
|
|
|
|
**Status:** Draft
|
|
**Project:** coordination-engine
|
|
**Document Type:** Technical Specification Document
|
|
**Scope:** Overall runtime architecture and adapter subsystem
|
|
**Primary Audience:** Developers, architects, integration partners, automation agents
|
|
|
|
## 2. Purpose
|
|
|
|
This document specifies the technical architecture of `coordination-engine` and describes how it uses adapters to integrate with external protocols, systems, providers, and technologies.
|
|
|
|
`coordination-engine` is a generalized, headless runtime for digital coordination. It coordinates participants around payloads and action surfaces through notifications, deliveries, access control, interactions, evidence, and policies to achieve intended results under uncertainty.
|
|
|
|
The adapter subsystem enables `coordination-engine` to remain protocol-neutral while integrating with concrete systems such as email, SMS, push notifications, RSS, XMPP, portals, payment providers, signature providers, document stores, identity providers, CRM systems, ERP systems, and webhooks.
|
|
|
|
## 3. Architectural Intent
|
|
|
|
The architecture is based on the following principles:
|
|
|
|
1. **Coordination is result-driven.**
|
|
A coordination case succeeds when its intended result is satisfied, not when messages are merely sent.
|
|
|
|
2. **Digital coordination is evidence-driven.**
|
|
The engine records observations from multiple systems and derives participant and case states from evidence.
|
|
|
|
3. **Adapters are capability providers.**
|
|
Adapters are not simple transport drivers. They expose actions and emit normalized evidence.
|
|
|
|
4. **External systems remain external.**
|
|
The engine should orchestrate and evaluate coordination, not replace email providers, portals, payment systems, signature systems, document stores, or identity systems.
|
|
|
|
5. **Uncertainty is first-class.**
|
|
Many digital signals are ambiguous. The architecture must represent weak, conflicting, late, missing, or uncertain evidence.
|
|
|
|
6. **Scenario-specific applications should compose concepts selectively.**
|
|
Simple use cases should not require payment, signature, or document-validation logic. Complex use cases should be able to add stronger identity, authority, payload, access, and evidence requirements.
|
|
|
|
## 4. System Overview
|
|
|
|
`coordination-engine` is a headless coordination runtime composed of a central coordination controller, specialized domain controllers, an evidence ledger, a policy engine, and an adapter layer.
|
|
|
|
```text
|
|
coordination-engine
|
|
coordination-controller
|
|
result-controller
|
|
participant-controller
|
|
payload-controller
|
|
access-controller
|
|
notification-controller
|
|
delivery-controller
|
|
interaction-controller
|
|
identity-authority-controller
|
|
evidence-ledger
|
|
policy-engine
|
|
adapter-layer
|
|
```
|
|
|
|
The engine manages `CoordinationCase` objects. Each case represents a goal-directed process initiated by one party to achieve an intended result involving one or more participants.
|
|
|
|
External systems connect through adapters. Adapters provide actions, such as sending an email or creating a payment request, and signals, such as delivery events, click events, payment settlement events, or signature completion events.
|
|
|
|
## 5. Core Runtime Model
|
|
|
|
### 5.1 CoordinationCase
|
|
|
|
A `CoordinationCase` is the primary aggregate.
|
|
|
|
It represents one goal-directed coordination process.
|
|
|
|
Example cases:
|
|
|
|
* deliver documents to recipients
|
|
* collect missing documents
|
|
* obtain AGB acceptance
|
|
* close contracts
|
|
* collect payments
|
|
* gather acknowledgements
|
|
* coordinate approvals
|
|
|
|
Minimal structure:
|
|
|
|
```yaml
|
|
CoordinationCase:
|
|
id: string
|
|
initiator: ActorRef
|
|
purpose: string
|
|
scenario_type: string
|
|
intended_result: IntendedResult
|
|
participants: ParticipantRef[]
|
|
payloads: PayloadRef[]
|
|
action_surfaces: ActionSurfaceRef[]
|
|
policies: PolicyRef[]
|
|
state: CoordinationCaseState
|
|
assessment: CoordinationAssessment
|
|
created_at: timestamp
|
|
updated_at: timestamp
|
|
```
|
|
|
|
### 5.2 Participant
|
|
|
|
A `Participant` is an actor involved in a coordination case.
|
|
|
|
Participants may be humans, organizations, systems, agents, delegates, signers, payers, approvers, respondents, recipients, or intermediaries.
|
|
|
|
```yaml
|
|
Participant:
|
|
id: string
|
|
actor_ref: ActorRef
|
|
roles: string[]
|
|
contact_endpoints: EndpointRef[]
|
|
authority_profile_ref: string?
|
|
required_outcomes: RequiredOutcome[]
|
|
state: ParticipantState
|
|
```
|
|
|
|
### 5.3 IntendedResult
|
|
|
|
An `IntendedResult` defines what the initiator wants to achieve.
|
|
|
|
```yaml
|
|
IntendedResult:
|
|
id: string
|
|
result_type: string
|
|
target_population: ParticipantSelector
|
|
required_outcome: string
|
|
required_evidence_level: EvidenceLevel
|
|
threshold: Threshold?
|
|
deadline: timestamp?
|
|
partial_success_rules: RuleRef[]
|
|
failure_rules: RuleRef[]
|
|
```
|
|
|
|
Examples:
|
|
|
|
```yaml
|
|
result_type: payload_access
|
|
required_outcome: pdf_downloaded
|
|
threshold:
|
|
type: percentage
|
|
value: 95
|
|
deadline: 2026-12-31T23:59:59Z
|
|
```
|
|
|
|
```yaml
|
|
result_type: payment_collection
|
|
required_outcome: payment_settled
|
|
threshold:
|
|
type: amount
|
|
value: 100000
|
|
currency: EUR
|
|
```
|
|
|
|
### 5.4 Payload
|
|
|
|
A `Payload` is a meaningful resource involved in the case.
|
|
|
|
Payloads are not limited to documents. They can include invoices, payment requests, contract drafts, signed contracts, submitted forms, data packages, receipts, terms versions, or structured messages.
|
|
|
|
```yaml
|
|
Payload:
|
|
id: string
|
|
semantic_role: string
|
|
payload_type: string
|
|
version: string?
|
|
representation_refs: RepresentationRef[]
|
|
integrity_hash: string?
|
|
sensitivity: string?
|
|
retention_policy_ref: string?
|
|
validation_policy_ref: string?
|
|
```
|
|
|
|
### 5.5 ActionSurface
|
|
|
|
An `ActionSurface` is the place where a participant can interact with a payload or perform a required action.
|
|
|
|
Examples:
|
|
|
|
* portal page
|
|
* mobile app screen
|
|
* payment page
|
|
* signature flow
|
|
* upload form
|
|
* approval screen
|
|
* chatbot flow
|
|
* API endpoint
|
|
* email reply parser
|
|
* XMPP bot
|
|
|
|
```yaml
|
|
ActionSurface:
|
|
id: string
|
|
type: string
|
|
adapter_ref: string
|
|
url: string?
|
|
endpoint_ref: string?
|
|
supported_interactions: string[]
|
|
access_policy_ref: string?
|
|
```
|
|
|
|
### 5.6 EvidenceEvent
|
|
|
|
An `EvidenceEvent` is a normalized observation used by the engine to derive state.
|
|
|
|
```yaml
|
|
EvidenceEvent:
|
|
id: string
|
|
event_type: string
|
|
source_adapter: string?
|
|
native_event_type: string?
|
|
coordination_case_id: string
|
|
participant_id: string?
|
|
payload_id: string?
|
|
action_surface_id: string?
|
|
actor_ref: ActorRef?
|
|
timestamp: timestamp
|
|
normalized_meaning: string
|
|
confidence: ConfidenceGrade
|
|
evidence_grade: EvidenceGrade
|
|
raw_event_ref: string?
|
|
correlation: CorrelationContext
|
|
```
|
|
|
|
Evidence events are the basis for assessment, policy evaluation, auditability, and explainability.
|
|
|
|
## 6. Runtime Components
|
|
|
|
### 6.1 Coordination Controller
|
|
|
|
The `coordination-controller` is the central runtime component.
|
|
|
|
Responsibilities:
|
|
|
|
* Create and manage `CoordinationCase` objects.
|
|
* Coordinate specialized controllers.
|
|
* Maintain case lifecycle state.
|
|
* Request policy evaluations.
|
|
* Apply derived state transitions.
|
|
* Trigger adapter actions through the adapter layer.
|
|
* Close, fail, expire, pause, or escalate cases.
|
|
|
|
The coordination controller does not directly speak to email, SMS, payment, signature, portal, or other external systems. It uses adapters.
|
|
|
|
### 6.2 Result Controller
|
|
|
|
The `result-controller` evaluates whether an intended result has been satisfied.
|
|
|
|
Responsibilities:
|
|
|
|
* Evaluate case-level success predicates.
|
|
* Evaluate participant-level completion.
|
|
* Handle thresholds, deadlines, partial success, failure, expiry, and manual override.
|
|
* Produce result assessment events.
|
|
|
|
Example derived states:
|
|
|
|
```text
|
|
active
|
|
partially_completed
|
|
completed_successfully
|
|
completed_partially
|
|
failed
|
|
expired
|
|
manually_closed
|
|
```
|
|
|
|
### 6.3 Participant Controller
|
|
|
|
The `participant-controller` manages participant state within a case.
|
|
|
|
Responsibilities:
|
|
|
|
* Maintain participant roles and required outcomes.
|
|
* Link participants to payloads, action surfaces, endpoints, and evidence.
|
|
* Derive participant progress states.
|
|
* Support delegates, organizations, systems, and agents.
|
|
|
|
Example participant states:
|
|
|
|
```text
|
|
not_started
|
|
notification_pending
|
|
notified
|
|
awareness_uncertain
|
|
access_granted
|
|
accessed
|
|
interaction_started
|
|
required_action_completed
|
|
failed
|
|
expired
|
|
escalated
|
|
completed
|
|
```
|
|
|
|
### 6.4 Payload Controller
|
|
|
|
The `payload-controller` manages payload identity, versioning, representation, integrity, validation, and lifecycle references.
|
|
|
|
Responsibilities:
|
|
|
|
* Register payloads.
|
|
* Link payloads to participants and intended results.
|
|
* Track payload availability.
|
|
* Track inbound and outbound payload references.
|
|
* Integrate with document stores, archives, or payload providers through adapters.
|
|
|
|
The payload controller does not need to store the payload itself. It may only store metadata and references.
|
|
|
|
### 6.5 Access Controller
|
|
|
|
The `access-controller` manages access to payloads and action surfaces.
|
|
|
|
Responsibilities:
|
|
|
|
* Create access grants.
|
|
* Revoke access.
|
|
* Track access usage, denial, expiry, delegation, and abuse.
|
|
* Coordinate with identity and authority systems.
|
|
* Emit access-related evidence events.
|
|
|
|
Example access states:
|
|
|
|
```text
|
|
not_granted
|
|
granted
|
|
used
|
|
denied
|
|
expired
|
|
revoked
|
|
delegated
|
|
suspicious
|
|
```
|
|
|
|
### 6.6 Notification Controller
|
|
|
|
The `notification-controller` manages awareness-oriented signals.
|
|
|
|
Responsibilities:
|
|
|
|
* Create notification attempts.
|
|
* Select channels according to policy.
|
|
* Trigger notification adapters.
|
|
* Record notification evidence.
|
|
* Distinguish technical delivery from awareness evidence.
|
|
* Support reminders, retries, and escalation.
|
|
|
|
Notification does not equal delivery. A notification may point to an action surface or payload but does not necessarily carry the payload.
|
|
|
|
### 6.7 Delivery Controller
|
|
|
|
The `delivery-controller` manages payload availability, retrieval, submission, transfer, consumption, and completion.
|
|
|
|
Responsibilities:
|
|
|
|
* Track outbound delivery evidence.
|
|
* Track inbound delivery evidence.
|
|
* Track payload submission and validation results.
|
|
* Interpret delivery-side events as possible evidence for notification or result success.
|
|
|
|
Delivery is generalized as controlled payload access, transfer, retrieval, submission, or consumption.
|
|
|
|
### 6.8 Interaction Controller
|
|
|
|
The `interaction-controller` classifies meaningful participant actions.
|
|
|
|
Responsibilities:
|
|
|
|
* Record interaction events.
|
|
* Distinguish anonymous, suspected, authenticated, delegated, authorized, bot, scanner, and proxy interactions.
|
|
* Determine whether interactions are result-relevant.
|
|
* Feed interaction evidence into participant and result assessment.
|
|
|
|
Example interactions:
|
|
|
|
```text
|
|
notification_opened
|
|
link_clicked
|
|
portal_opened
|
|
document_viewed
|
|
pdf_downloaded
|
|
form_started
|
|
form_submitted
|
|
payment_started
|
|
payment_settled
|
|
contract_viewed
|
|
signature_completed
|
|
acknowledgement_recorded
|
|
```
|
|
|
|
### 6.9 Identity & Authority Controller
|
|
|
|
The `identity-authority-controller` evaluates actor identity and authority.
|
|
|
|
Responsibilities:
|
|
|
|
* Link actors to participants.
|
|
* Evaluate authentication strength.
|
|
* Evaluate authorization, delegation, and representation.
|
|
* Provide evidence grades for identity and authority.
|
|
* Integrate with IAM, SSO, MFA, signature providers, or authorization systems.
|
|
|
|
Example identity grades:
|
|
|
|
```text
|
|
unknown
|
|
device_known
|
|
session_authenticated
|
|
mfa_verified
|
|
identity_provider_verified
|
|
qualified_identity_verified
|
|
```
|
|
|
|
Example authority grades:
|
|
|
|
```text
|
|
unknown
|
|
self_authorized
|
|
delegated
|
|
organizational_representative
|
|
authorized_signer
|
|
payment_authorized
|
|
admin_override
|
|
```
|
|
|
|
### 6.10 Evidence Ledger
|
|
|
|
The `evidence-ledger` stores normalized observations.
|
|
|
|
Responsibilities:
|
|
|
|
* Persist evidence events.
|
|
* Preserve raw event references.
|
|
* Support idempotency and deduplication.
|
|
* Maintain correlation across adapters.
|
|
* Support audit reconstruction.
|
|
* Support state derivation and explainability.
|
|
|
|
The evidence ledger should be append-oriented. Derived state may be updated, but original evidence events should remain traceable.
|
|
|
|
### 6.11 Policy Engine
|
|
|
|
The `policy-engine` interprets state and evidence to determine next actions.
|
|
|
|
Responsibilities:
|
|
|
|
* Evaluate result policies.
|
|
* Evaluate follow-up policies.
|
|
* Evaluate escalation rules.
|
|
* Evaluate retry and timeout rules.
|
|
* Generate next-action recommendations or commands.
|
|
* Explain why actions were generated.
|
|
|
|
Example next actions:
|
|
|
|
```text
|
|
wait
|
|
send_notification
|
|
send_reminder
|
|
retry
|
|
switch_channel
|
|
escalate
|
|
request_correction
|
|
revoke_access
|
|
extend_deadline
|
|
manual_review
|
|
close_success
|
|
close_failure
|
|
expire_case
|
|
```
|
|
|
|
### 6.12 Adapter Layer
|
|
|
|
The `adapter-layer` connects `coordination-engine` to external systems.
|
|
|
|
Responsibilities:
|
|
|
|
* Register adapter capabilities.
|
|
* Dispatch adapter actions.
|
|
* Receive adapter events.
|
|
* Normalize events into evidence.
|
|
* Monitor adapter health.
|
|
* Enforce idempotency and correlation.
|
|
* Isolate provider-specific logic from the core engine.
|
|
|
|
Adapters may be implemented as separate services or libraries. The preferred architectural direction is separate `*-connect` repositories.
|
|
|
|
Examples:
|
|
|
|
```text
|
|
email-connect
|
|
rss-connect
|
|
sms-connect
|
|
push-connect
|
|
xmpp-connect
|
|
portal-connect
|
|
payment-connect
|
|
signature-connect
|
|
document-connect
|
|
identity-connect
|
|
crm-connect
|
|
erp-connect
|
|
```
|
|
|
|
## 7. Adapter Architecture
|
|
|
|
### 7.1 Adapter Definition
|
|
|
|
An adapter is a component that connects `coordination-engine` with an external protocol, provider, system, or technology.
|
|
|
|
An adapter has three roles:
|
|
|
|
```text
|
|
Adapter = Action Provider + Signal Provider + Capability Descriptor
|
|
```
|
|
|
|
### 7.2 Action Provider
|
|
|
|
As an action provider, the adapter performs operations requested by `coordination-engine`.
|
|
|
|
Examples:
|
|
|
|
* send email
|
|
* send SMS
|
|
* publish RSS item
|
|
* create push notification
|
|
* grant portal access
|
|
* create payment request
|
|
* create signature envelope
|
|
* revoke access token
|
|
* archive document
|
|
* request identity verification
|
|
|
|
### 7.3 Signal Provider
|
|
|
|
As a signal provider, the adapter emits observations.
|
|
|
|
Examples:
|
|
|
|
* email provider accepted message
|
|
* email hard bounce received
|
|
* SMS delivery receipt received
|
|
* push notification tapped
|
|
* portal login completed
|
|
* document downloaded
|
|
* payment settled
|
|
* signature completed
|
|
* form submitted
|
|
* identity verified
|
|
|
|
### 7.4 Capability Descriptor
|
|
|
|
As a capability descriptor, the adapter declares what it can do and what evidence it can provide.
|
|
|
|
This allows `coordination-engine` to reason about which adapters are suitable for a scenario.
|
|
|
|
## 8. Adapter Contract
|
|
|
|
### 8.1 AdapterDescriptor
|
|
|
|
Each adapter shall expose an `AdapterDescriptor`.
|
|
|
|
```yaml
|
|
AdapterDescriptor:
|
|
adapter_id: string
|
|
adapter_type: string
|
|
adapter_name: string
|
|
adapter_version: string
|
|
contract_version: string
|
|
supported_actions:
|
|
- AdapterActionCapability
|
|
emitted_event_types:
|
|
- string
|
|
supported_channels:
|
|
- string
|
|
evidence_strength_profile: EvidenceStrengthProfile
|
|
identity_strength_profile: IdentityStrengthProfile
|
|
latency_profile: LatencyProfile
|
|
cost_profile: CostProfile
|
|
failure_modes:
|
|
- string
|
|
configuration_schema_ref: string?
|
|
health_endpoint: string?
|
|
```
|
|
|
|
Example:
|
|
|
|
```yaml
|
|
adapter_id: email-connect.default
|
|
adapter_type: email
|
|
adapter_name: email-connect
|
|
adapter_version: 0.1.0
|
|
contract_version: 0.1.0
|
|
supported_channels:
|
|
- email
|
|
supported_actions:
|
|
- action_type: notification.send
|
|
- action_type: notification.send_reminder
|
|
emitted_event_types:
|
|
- notification.attempt.accepted_by_provider
|
|
- notification.endpoint.accepted
|
|
- notification.endpoint.rejected_permanent
|
|
- interaction.proxy_or_privacy_interaction
|
|
- interaction.scanner_or_bot_interaction
|
|
- interaction.unverified_actor_interaction
|
|
failure_modes:
|
|
- provider_rejected
|
|
- endpoint_rejected
|
|
- deferred
|
|
- hard_bounce
|
|
- soft_bounce
|
|
- complaint
|
|
- suppressed
|
|
```
|
|
|
|
### 8.2 AdapterActionRequest
|
|
|
|
An `AdapterActionRequest` is sent by the engine to an adapter.
|
|
|
|
```yaml
|
|
AdapterActionRequest:
|
|
request_id: string
|
|
action_type: string
|
|
coordination_case_id: string
|
|
participant_id: string?
|
|
payload_ref: string?
|
|
action_surface_ref: string?
|
|
channel: string?
|
|
target_endpoint: EndpointRef?
|
|
content_ref: string?
|
|
template_ref: string?
|
|
variables: object?
|
|
tracking_context: TrackingContext
|
|
policy_context: PolicyContext?
|
|
idempotency_key: string
|
|
requested_at: timestamp
|
|
```
|
|
|
|
Example for email:
|
|
|
|
```yaml
|
|
request_id: req_123
|
|
action_type: notification.send
|
|
coordination_case_id: case_456
|
|
participant_id: participant_789
|
|
channel: email
|
|
target_endpoint:
|
|
type: email
|
|
value: recipient@example.com
|
|
template_ref: secure-document-available
|
|
variables:
|
|
recipient_name: Example Recipient
|
|
portal_link: https://portal.example.com/access/abc
|
|
tracking_context:
|
|
correlation_id: corr_001
|
|
notification_id: notif_001
|
|
idempotency_key: case_456:participant_789:notif_001
|
|
```
|
|
|
|
### 8.3 AdapterActionResult
|
|
|
|
An `AdapterActionResult` is returned by the adapter after receiving an action request.
|
|
|
|
```yaml
|
|
AdapterActionResult:
|
|
request_id: string
|
|
adapter_id: string
|
|
accepted: boolean
|
|
adapter_operation_id: string?
|
|
provider_operation_id: string?
|
|
initial_status: string
|
|
raw_response_ref: string?
|
|
normalized_events:
|
|
- EvidenceEvent
|
|
error:
|
|
code: string?
|
|
message: string?
|
|
retryable: boolean?
|
|
```
|
|
|
|
The action result is not final proof of outcome. It only records whether the adapter accepted or rejected the requested action and may emit initial evidence events.
|
|
|
|
### 8.4 AdapterEvent
|
|
|
|
An `AdapterEvent` is an incoming event from an adapter.
|
|
|
|
```yaml
|
|
AdapterEvent:
|
|
event_id: string
|
|
adapter_id: string
|
|
event_type: string
|
|
native_event_type: string?
|
|
timestamp: timestamp
|
|
coordination_case_id: string?
|
|
participant_id: string?
|
|
payload_id: string?
|
|
action_surface_id: string?
|
|
message_ref: string?
|
|
endpoint_ref: EndpointRef?
|
|
actor_ref: ActorRef?
|
|
raw_event_ref: string?
|
|
normalized_meaning: string
|
|
confidence: ConfidenceGrade
|
|
evidence_grade: EvidenceGrade
|
|
correlation: CorrelationContext
|
|
```
|
|
|
|
Adapter events are usually converted into `EvidenceEvent` records in the evidence ledger.
|
|
|
|
### 8.5 AdapterHealth
|
|
|
|
Adapters should expose health information.
|
|
|
|
```yaml
|
|
AdapterHealth:
|
|
adapter_id: string
|
|
status: healthy | degraded | unavailable | misconfigured
|
|
last_action_success_at: timestamp?
|
|
last_event_received_at: timestamp?
|
|
provider_connectivity: string?
|
|
configuration_validity: string?
|
|
known_degradation:
|
|
- string
|
|
```
|
|
|
|
## 9. Event Normalization
|
|
|
|
### 9.1 Native Events vs Normalized Events
|
|
|
|
External systems use different event vocabularies. The adapter layer is responsible for normalizing them.
|
|
|
|
Example:
|
|
|
|
```text
|
|
SendGrid delivered
|
|
Mailgun delivered
|
|
SES Delivery
|
|
Postmark Delivery
|
|
```
|
|
|
|
These may all map to:
|
|
|
|
```text
|
|
notification.endpoint.accepted
|
|
```
|
|
|
|
with meaning:
|
|
|
|
```text
|
|
recipient email server accepted the message
|
|
```
|
|
|
|
They should not map directly to business-level success.
|
|
|
|
### 9.2 Normalized Event Families
|
|
|
|
The engine should define canonical event families.
|
|
|
|
```text
|
|
coordination.*
|
|
participant.*
|
|
payload.*
|
|
access.*
|
|
notification.*
|
|
delivery.*
|
|
interaction.*
|
|
identity.*
|
|
authority.*
|
|
payment.*
|
|
signature.*
|
|
policy.*
|
|
result.*
|
|
system.*
|
|
manual.*
|
|
```
|
|
|
|
### 9.3 Example Email Normalization
|
|
|
|
```text
|
|
email.provider.accepted
|
|
→ notification.attempt.accepted_by_provider
|
|
|
|
email.transport.mx_accepted
|
|
→ notification.endpoint.accepted
|
|
|
|
email.transport.hard_bounce
|
|
→ notification.endpoint.rejected_permanent
|
|
|
|
email.transport.soft_bounce
|
|
→ notification.endpoint.deferred
|
|
|
|
email.open.proxy_like
|
|
→ interaction.proxy_or_privacy_interaction
|
|
|
|
email.click.scanner_like
|
|
→ interaction.scanner_or_bot_interaction
|
|
|
|
email.click.unverified
|
|
→ interaction.unverified_actor_interaction
|
|
|
|
email.complaint
|
|
→ notification.channel.complaint_received
|
|
```
|
|
|
|
### 9.4 Example Portal Normalization
|
|
|
|
```text
|
|
portal.login_success
|
|
→ identity.actor_authenticated
|
|
|
|
portal.document_viewed
|
|
→ delivery.payload_viewed
|
|
|
|
portal.pdf_downloaded
|
|
→ delivery.payload_retrieved
|
|
|
|
portal.acknowledgement_submitted
|
|
→ interaction.acknowledgement_recorded
|
|
```
|
|
|
|
### 9.5 Example Payment Normalization
|
|
|
|
```text
|
|
payment.request_created
|
|
→ delivery.payment_request_available
|
|
|
|
payment.link_clicked
|
|
→ interaction.payment_surface_opened
|
|
|
|
payment.started
|
|
→ interaction.payment_started
|
|
|
|
payment.succeeded
|
|
→ payment.succeeded
|
|
|
|
payment.settled
|
|
→ result.payment_settled
|
|
|
|
payment.failed
|
|
→ payment.failed
|
|
|
|
payment.disputed
|
|
→ payment.disputed
|
|
```
|
|
|
|
## 10. Evidence Grading
|
|
|
|
Not all evidence is equally strong. The architecture must avoid treating weak technical signals as business success.
|
|
|
|
### 10.1 EvidenceGrade
|
|
|
|
A generic evidence grade may contain:
|
|
|
|
```yaml
|
|
EvidenceGrade:
|
|
category: weak | medium | strong | conclusive | ambiguous | negative
|
|
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
|
|
non_repudiation_strength: none | low | medium | high
|
|
```
|
|
|
|
### 10.2 Examples
|
|
|
|
Email MX acceptance:
|
|
|
|
```yaml
|
|
category: weak
|
|
actor_certainty: none
|
|
payload_certainty: low
|
|
interaction_certainty: none
|
|
```
|
|
|
|
Anonymous link click:
|
|
|
|
```yaml
|
|
category: ambiguous
|
|
actor_certainty: low
|
|
interaction_certainty: medium
|
|
```
|
|
|
|
Authenticated portal login:
|
|
|
|
```yaml
|
|
category: strong
|
|
actor_certainty: high
|
|
interaction_certainty: medium
|
|
```
|
|
|
|
PDF downloaded by authenticated participant:
|
|
|
|
```yaml
|
|
category: strong
|
|
actor_certainty: high
|
|
payload_certainty: high
|
|
interaction_certainty: high
|
|
```
|
|
|
|
Qualified signature completed:
|
|
|
|
```yaml
|
|
category: conclusive
|
|
actor_certainty: high
|
|
authority_certainty: high
|
|
payload_certainty: high
|
|
interaction_certainty: high
|
|
non_repudiation_strength: high
|
|
```
|
|
|
|
## 11. Case State Derivation
|
|
|
|
The engine derives state from evidence and policy.
|
|
|
|
### 11.1 Participant Assessment
|
|
|
|
A participant assessment may include:
|
|
|
|
```yaml
|
|
ParticipantAssessment:
|
|
participant_id: string
|
|
state: string
|
|
notification_state: string?
|
|
access_state: string?
|
|
delivery_state: string?
|
|
interaction_state: string?
|
|
result_state: string?
|
|
evidence_level: EvidenceLevel
|
|
uncertainty_class: string?
|
|
risk_level: string?
|
|
next_actions:
|
|
- NextAction
|
|
```
|
|
|
|
Example uncertainty classes:
|
|
|
|
```text
|
|
undef.pending
|
|
undef.technical_acceptance_only
|
|
undef.no_signal
|
|
undef.weak_positive
|
|
undef.identity_uncertain
|
|
undef.channel_suspicious
|
|
undef.conflicting_evidence
|
|
undef.delivery_pending
|
|
undef.escalation_required
|
|
```
|
|
|
|
### 11.2 Case Assessment
|
|
|
|
A case assessment may include:
|
|
|
|
```yaml
|
|
CoordinationAssessment:
|
|
case_id: string
|
|
state: string
|
|
result_satisfied: boolean
|
|
participants_total: integer
|
|
participants_completed: integer
|
|
participants_pending: integer
|
|
participants_failed: integer
|
|
participants_escalated: integer
|
|
progress_percentage: number
|
|
deadline_risk: string?
|
|
channel_risk: string?
|
|
compliance_risk: string?
|
|
next_actions:
|
|
- NextAction
|
|
```
|
|
|
|
## 12. Policy Engine
|
|
|
|
### 12.1 Policy Inputs
|
|
|
|
The policy engine evaluates:
|
|
|
|
* case state
|
|
* participant states
|
|
* evidence events
|
|
* evidence grades
|
|
* deadlines
|
|
* result predicates
|
|
* adapter health
|
|
* channel availability
|
|
* failure modes
|
|
* scenario-specific configuration
|
|
|
|
### 12.2 Policy Outputs
|
|
|
|
The policy engine produces:
|
|
|
|
```yaml
|
|
NextAction:
|
|
id: string
|
|
action_type: string
|
|
target: string
|
|
priority: string
|
|
due_at: timestamp?
|
|
adapter_action_request: AdapterActionRequest?
|
|
explanation: string
|
|
```
|
|
|
|
Examples:
|
|
|
|
```text
|
|
send_email_notification
|
|
send_sms_reminder
|
|
switch_to_push
|
|
grant_portal_access
|
|
request_manual_review
|
|
close_participant_success
|
|
close_case_partial
|
|
expire_case
|
|
```
|
|
|
|
### 12.3 Policy Example
|
|
|
|
```yaml
|
|
if:
|
|
participant.notification_state: notification.endpoint.accepted
|
|
participant.delivery_state: none
|
|
age_since_notification: ">72h"
|
|
then:
|
|
action_type: send_reminder
|
|
channel_preference: sms
|
|
explanation: "Email was technically accepted but no access or interaction evidence was observed within 72 hours."
|
|
```
|
|
|
|
## 13. Adapter Integration Modes
|
|
|
|
### 13.1 Embedded Library Mode
|
|
|
|
An adapter may be included as a library in the same deployment.
|
|
|
|
Suitable for:
|
|
|
|
* simple simulations
|
|
* testing
|
|
* local development
|
|
* low-volume integrations
|
|
|
|
### 13.2 Sidecar Service Mode
|
|
|
|
An adapter may run as a service alongside the engine.
|
|
|
|
Suitable for:
|
|
|
|
* provider credentials isolation
|
|
* webhook ingestion
|
|
* retry handling
|
|
* operational separation
|
|
|
|
### 13.3 External Service Mode
|
|
|
|
An adapter may run as an independently deployed service.
|
|
|
|
Suitable for:
|
|
|
|
* reusable connectors like `email-connect`
|
|
* multi-tenant environments
|
|
* shared provider integrations
|
|
* separate scaling and security boundaries
|
|
|
|
Preferred direction:
|
|
|
|
```text
|
|
coordination-engine owns the contract.
|
|
*-connect repos implement the contract.
|
|
```
|
|
|
|
## 14. Adapter Repository Pattern
|
|
|
|
Adapters should preferably live in separate repositories.
|
|
|
|
Example:
|
|
|
|
```text
|
|
email-connect
|
|
rss-connect
|
|
sms-connect
|
|
push-connect
|
|
portal-connect
|
|
payment-connect
|
|
signature-connect
|
|
document-connect
|
|
identity-connect
|
|
```
|
|
|
|
Each adapter repository should provide:
|
|
|
|
```text
|
|
INTENT.md
|
|
docs/AdapterArchitecture.md
|
|
docs/EventMapping.md
|
|
docs/ProviderModel.md
|
|
docs/EvidenceClassification.md
|
|
schemas/
|
|
src/
|
|
tests/
|
|
```
|
|
|
|
Each adapter should include a compatibility declaration:
|
|
|
|
```yaml
|
|
coordination_engine_compatibility:
|
|
adapter_contract_version: 0.1.0
|
|
supported_actions:
|
|
- notification.send
|
|
emitted_events:
|
|
- notification.attempt.accepted_by_provider
|
|
- notification.endpoint.accepted
|
|
known_limitations:
|
|
- does_not_prove_inbox_delivery
|
|
- open_tracking_is_ambiguous
|
|
```
|
|
|
|
## 15. email-connect as Reference Adapter
|
|
|
|
`email-connect` should be the first reference adapter.
|
|
|
|
### 15.1 Standalone Role
|
|
|
|
`email-connect` should be useful independently as a headless email communication and evidence service.
|
|
|
|
Standalone capabilities:
|
|
|
|
* send transactional emails
|
|
* ingest provider events
|
|
* track message timelines
|
|
* classify bounces
|
|
* handle suppression
|
|
* classify opens and clicks
|
|
* expose normalized email evidence
|
|
* debug delivery uncertainty
|
|
|
|
### 15.2 coordination-engine Role
|
|
|
|
As an adapter, `email-connect` provides:
|
|
|
|
Actions:
|
|
|
|
```text
|
|
notification.send
|
|
notification.send_reminder
|
|
notification.register_tracking_context
|
|
recipient.suppress
|
|
recipient.unsuppress
|
|
```
|
|
|
|
Signals:
|
|
|
|
```text
|
|
notification.attempt.accepted_by_provider
|
|
notification.attempt.rejected_by_provider
|
|
notification.endpoint.accepted
|
|
notification.endpoint.deferred
|
|
notification.endpoint.rejected_permanent
|
|
interaction.proxy_or_privacy_interaction
|
|
interaction.scanner_or_bot_interaction
|
|
interaction.unverified_actor_interaction
|
|
notification.channel.complaint_received
|
|
notification.channel.unsubscribe_received
|
|
interaction.reply_received
|
|
```
|
|
|
|
### 15.3 Email-Specific Boundary
|
|
|
|
`email-connect` may classify email events, but it does not decide case-level success.
|
|
|
|
It may say:
|
|
|
|
```text
|
|
MX accepted
|
|
hard bounce received
|
|
open appears privacy-proxy-like
|
|
click appears scanner-like
|
|
```
|
|
|
|
`coordination-engine` decides:
|
|
|
|
```text
|
|
participant remains unresolved
|
|
send reminder
|
|
switch channel
|
|
close success
|
|
escalate
|
|
fail participant
|
|
```
|
|
|
|
## 16. Data Flow Examples
|
|
|
|
### 16.1 Notification and Access Flow
|
|
|
|
```text
|
|
1. Client creates CoordinationCase.
|
|
2. Client adds participants and payload.
|
|
3. Access Controller creates access grants.
|
|
4. Policy Engine requests notification.
|
|
5. Notification Controller creates AdapterActionRequest.
|
|
6. email-connect sends email.
|
|
7. email-connect emits provider accepted event.
|
|
8. Evidence Ledger records normalized event.
|
|
9. Later, portal-connect emits authenticated download event.
|
|
10. Evidence Ledger records delivery evidence.
|
|
11. Result Controller marks participant complete.
|
|
12. Coordination Controller updates case progress.
|
|
```
|
|
|
|
### 16.2 Payment Collection Flow
|
|
|
|
```text
|
|
1. Client creates payment collection case.
|
|
2. Payload Controller registers invoices.
|
|
3. payment-connect creates payment requests.
|
|
4. email-connect sends payment notifications.
|
|
5. payment-connect emits payment_started and payment_settled events.
|
|
6. Evidence Ledger records events.
|
|
7. Result Controller marks paid participants complete.
|
|
8. Policy Engine triggers reminders for unpaid participants.
|
|
```
|
|
|
|
### 16.3 Contract Signing Flow
|
|
|
|
```text
|
|
1. Client creates contract closure case.
|
|
2. Payload Controller registers contract draft.
|
|
3. Access Controller grants contract access.
|
|
4. signature-connect creates signature flow.
|
|
5. email-connect sends notification.
|
|
6. signature-connect emits viewed, signed, declined, expired events.
|
|
7. Identity & Authority Controller evaluates signer authority.
|
|
8. Result Controller closes participant on valid signature.
|
|
9. Coordination Controller closes case when required signatures are complete.
|
|
```
|
|
|
|
## 17. Reliability Requirements
|
|
|
|
The architecture shall support:
|
|
|
|
* idempotent action requests
|
|
* duplicate event detection
|
|
* late event handling
|
|
* retryable and non-retryable errors
|
|
* provider outages
|
|
* adapter degradation
|
|
* correlation across systems
|
|
* partial failure
|
|
* conflicting evidence
|
|
* manual correction or override
|
|
|
|
## 18. Security Requirements
|
|
|
|
The architecture shall support:
|
|
|
|
* adapter credential isolation
|
|
* least-privilege adapter access
|
|
* secure webhook verification
|
|
* event authenticity validation where possible
|
|
* sensitive metadata minimization
|
|
* secure access grant handling
|
|
* audit logs for policy-driven and manual actions
|
|
* separation between payload storage and coordination metadata
|
|
|
|
## 19. Privacy Requirements
|
|
|
|
The engine should avoid storing unnecessary personal data.
|
|
|
|
Recommended practices:
|
|
|
|
* store participant references instead of full profiles where possible
|
|
* store payload references instead of payload content
|
|
* support retention policies
|
|
* support evidence minimization
|
|
* support redaction of raw event data
|
|
* separate audit requirements from operational tracking requirements
|
|
|
|
## 20. Observability Requirements
|
|
|
|
The system should expose metrics for:
|
|
|
|
* active cases
|
|
* completed cases
|
|
* failed cases
|
|
* expired cases
|
|
* unresolved participants
|
|
* generated next actions
|
|
* adapter action success/failure
|
|
* adapter event ingestion latency
|
|
* evidence event volume
|
|
* policy evaluation results
|
|
* channel-level failure rates
|
|
* case-level progress
|
|
* deadline risk
|
|
|
|
## 21. MVP Architecture
|
|
|
|
The MVP should implement a minimal but coherent version of the architecture.
|
|
|
|
### 21.1 MVP Components
|
|
|
|
Required:
|
|
|
|
* Coordination Controller
|
|
* Result Controller
|
|
* Participant Controller
|
|
* Payload Controller
|
|
* Access Controller
|
|
* Notification Controller
|
|
* Interaction Controller
|
|
* Evidence Ledger
|
|
* Policy Engine
|
|
* Adapter Contract
|
|
* Simulated Adapter
|
|
|
|
Recommended:
|
|
|
|
* email-connect reference adapter
|
|
* portal/action-surface simulated adapter
|
|
* webhook event ingestion
|
|
|
|
### 21.2 MVP Scenario
|
|
|
|
The recommended MVP scenario is **Digital Payload Notification and Access**.
|
|
|
|
Flow:
|
|
|
|
```text
|
|
create case
|
|
add participants
|
|
register payload
|
|
grant access
|
|
send notification
|
|
record provider acceptance
|
|
record ambiguous/no signal cases
|
|
record authenticated payload access
|
|
derive participant states
|
|
generate reminders
|
|
close completed participants
|
|
close case when result predicate is satisfied
|
|
```
|
|
|
|
### 21.3 MVP Acceptance Criteria
|
|
|
|
The MVP shall demonstrate:
|
|
|
|
1. Creation of a multi-participant coordination case.
|
|
2. Registration of one outbound payload.
|
|
3. Definition of an intended result.
|
|
4. Dispatch of notification actions through an adapter.
|
|
5. Recording of normalized evidence events.
|
|
6. Participant-level state derivation.
|
|
7. Case-level progress assessment.
|
|
8. Ambiguous evidence handling.
|
|
9. Policy-generated reminder or escalation.
|
|
10. Closure based on sufficient delivery or interaction evidence.
|
|
11. Traceability from final state to evidence events.
|
|
|
|
## 22. Open Technical Questions
|
|
|
|
1. Should policy rules be expressed as JSON/YAML, a DSL, embedded code, or an external rule engine?
|
|
2. Should the evidence ledger be strictly append-only from the first implementation?
|
|
3. Should adapter events be pushed, pulled, or both?
|
|
4. Should adapters call the engine directly or publish to an event bus?
|
|
5. How should raw event payloads be stored, redacted, and retained?
|
|
6. Should the engine own scheduling, or should it emit next actions to an external scheduler?
|
|
7. Should result predicates be evaluated synchronously on every event or asynchronously by a worker?
|
|
8. What is the minimal adapter contract version needed for `email-connect`?
|
|
9. Which provider should be used first for a real email adapter implementation?
|
|
10. How should manual override events be represented and audited?
|
|
|
|
## 23. Non-Goals
|
|
|
|
The architecture does not attempt to make `coordination-engine`:
|
|
|
|
* a general-purpose BPMN engine
|
|
* an email provider
|
|
* a payment provider
|
|
* a signature provider
|
|
* a document store
|
|
* a CRM
|
|
* an ERP
|
|
* a legal proof system by default
|
|
* a complete UI application
|
|
|
|
The engine coordinates across such systems through adapters.
|
|
|
|
## 24. Strategic Implementation Guidance
|
|
|
|
The recommended implementation path is:
|
|
|
|
1. Define the core schemas.
|
|
2. Implement evidence ledger and case state derivation.
|
|
3. Implement adapter contract.
|
|
4. Implement simulated adapter.
|
|
5. Implement minimal notification-and-access scenario.
|
|
6. Create `email-connect` as reference adapter.
|
|
7. Add portal/action-surface adapter or simulation.
|
|
8. Validate policy-driven follow-up.
|
|
9. Extend toward request/collect, acceptance, signature, and payment patterns.
|
|
|
|
## 25. Summary
|
|
|
|
`coordination-engine` provides a digital-first coordination runtime. It manages goal-directed coordination cases by combining participants, payloads, action surfaces, access, notifications, deliveries, interactions, evidence, and policies.
|
|
|
|
Adapters are the bridge between the engine and the outside world. They provide actions and signals, normalize provider-specific events, and declare their capabilities. The engine remains responsible for result evaluation, uncertainty handling, follow-up decisions, and coordination state.
|
|
|
|
The core architectural idea is:
|
|
|
|
> Adapters translate external capabilities and observations into coordination actions and evidence events. coordination-engine uses those events to evaluate intended results and control follow-up under uncertainty.
|
|
|