# DevOS Notification / Communication Runtime > 文档版本:v1.0 > 文档编号:31 > 状态:Architecture Specification > 适用范围:DevOS Core / Event / Task / Agent / Workflow / Plugin / MCP / API / SDK / UI > 项目根目录:`/home/dev/bun/devos` --- # 1. 文档目标 DevOS 必须提供统一的: > **Notification / Communication Runtime** 用于处理: - Notification - Message - Communication - Delivery - Channel - Provider - Template - Subscription - Preference - Recipient - Audience - Routing - Delivery Policy - Retry - Rate Limit - Deduplication - Scheduling - Batch Sending - Webhook - Email - Push - SMS - In-App Notification - Provider Failover - Delivery Tracking - Bounce / Complaint - Unsubscribe - Digest - Notification Center - Agent Notification - Task Notification - Workflow Notification - System Alert 核心目标: > **业务系统只产生“应该通知什么”,Communication Runtime 决定“发给谁、通过什么渠道、什么时候发、如何发送、失败后怎么办”。** --- # 2. 核心原则 必须严格区分: ```text Event Notification Message Delivery Provider Channel ``` 它们不是同一个东西。 --- # 3. Event Event 表示: > 系统发生了什么。 例如: ```text task.completed plugin.installed agent.failed server.offline article.published ``` Event 不负责发送。 --- # 4. Notification Notification 表示: > 某个事件/条件是否需要通知某个受众。 例如: ```text Task 完成 → 通知项目负责人 ``` Notification 是语义层。 --- # 5. Message Message 表示: > 实际准备发送的内容。 例如: ```text Title: 任务已完成 Body: SEO 批量生成任务已完成,共生成 100 篇。 ``` --- # 6. Delivery Delivery 表示: > 一条 Message 通过某个 Channel 向某个 Recipient 进行的一次发送尝试。 例如: ```text Message ↓ Email ↓ user@example.com ``` 这是一次 Delivery。 --- # 7. Provider Provider 是实际的外部发送实现。 例如: ```text SMTP SendGrid Resend AWS SES Twilio FCM APNs Discord Slack Generic Webhook ``` Provider 是实现。 --- # 8. Channel Channel 表示通信方式: ```text in_app email webhook push sms chat ``` Channel 不等于 Provider。 例如: ```text email ├── SMTP ├── SES ├── Resend └── SendGrid ``` --- # 9. 总体架构 ```text Event │ ↓ Notification Rules │ ↓ Notification │ ┌────────┴────────┐ ↓ ↓ Recipient Template │ │ └────────┬────────┘ ↓ Message │ ↓ Delivery Planner │ ┌────────────┼────────────┐ ↓ ↓ ↓ In-App Email Webhook ↓ ↓ ↓ Provider Provider Provider │ │ │ └────────────┼────────────┘ ↓ Delivery │ ┌────────┴────────┐ ↓ ↓ Event Observability ``` --- # 10. Runtime 边界 Communication Runtime 负责: ```text Recipient Resolution Template Rendering Channel Selection Provider Selection Delivery Retry Scheduling Deduplication Rate Limit Status Tracking ``` 不负责: ```text Business Logic Agent Planning Task Execution Authorization Secret Storage Event Bus ``` 这些由其他 Runtime 提供。 --- # 11. 与 Event Runtime 的关系 Event Runtime: ```text Action ↓ Execution ↓ Event ``` Communication Runtime: ```text Event ↓ Notification Rule ↓ Message ↓ Delivery ``` 因此: ```text Event ≠ Notification ``` 一个 Event 可以: ```text 不通知 ``` 也可以: ```text 通知一个人 通知 1000 人 发送 Email 发送 Push 发送 Webhook 生成 Digest ``` --- # 12. 与 Task Runtime 的关系 发送大量消息: ```text Notification ↓ Task ↓ Jobs ↓ Queue ↓ Worker ↓ Delivery ``` Communication Runtime 不创建自己的 Queue。 --- # 13. 与 Security Runtime 的关系 Communication Runtime 必须使用: ```text Security Context Authorization Scope Policy ``` 但是不实现自己的 Authorization。 例如: ```text Agent ↓ Notification ↓ Recipient ``` Agent 不能因为拥有 Notification Capability 就读取所有用户邮箱。 --- # 14. Recipient Recipient 是通知目标。 类型: ```ts type RecipientType = | 'user' | 'organization' | 'project' | 'team' | 'role' | 'email' | 'phone' | 'webhook' | 'external'; ``` --- # 15. Recipient Resolution 通知可以声明: ```text project.owner project.members organization.admins task.requester agent.owner ``` Runtime 负责解析: ```text Recipient Selector ↓ Security Scope ↓ Recipient Resolver ↓ Concrete Recipients ``` --- # 16. Recipient Selector 推荐: ```ts interface RecipientSelector { type: | 'user' | 'role' | 'team' | 'project' | 'organization' | 'expression'; id?: string; role?: string; filters?: Record; } ``` 不允许业务代码自己查询用户表发送消息。 --- # 17. Recipient Address 最终 Delivery 需要: ```ts interface RecipientAddress { type: 'email' | 'phone' | 'push' | 'webhook' | 'in_app'; valueRef: string; verified?: boolean; metadata?: Record; } ``` 敏感地址必须遵循 Credential / Identity / Security Policy。 --- # 18. 不直接暴露 Recipient 敏感信息 UI、Agent、Plugin 不应该任意读取: ```text 所有用户 Email 所有电话号码 所有 Webhook URL ``` 而应该请求: ```text Notification Capability ``` 得到允许使用的 Recipient。 --- # 19. Audience Audience 表示通知受众。 例如: ```text Task Owner Project Admin SEO Team Organization Admin ``` Audience 可以是动态计算的。 --- # 20. Audience 与 Recipient ```text Audience ↓ Recipient Resolver ↓ Recipients ``` 例如: ```text "项目管理员" ``` 最终解析为: ```text User A User B User C ``` --- # 21. Notification 统一定义: ```ts interface Notification { id: string; type: string; sourceEventId?: string; organizationId?: string; projectId?: string; environmentId?: string; recipients: RecipientSelector[]; channels?: NotificationChannel[]; templateId?: string; data: Record; priority?: 'low' | 'normal' | 'high' | 'critical'; scheduledAt?: Date; expiresAt?: Date; } ``` --- # 22. Notification Type 使用稳定的语义 ID。 例如: ```text task.completed task.failed agent.completed agent.failed plugin.updated security.alert deployment.failed server.offline ``` 插件可以注册: ```text seo.article.published seo.scan.completed ``` --- # 23. Notification Type Registry DevOS 维护统一 Registry。 定义: ```ts interface NotificationTypeDefinition { id: string; description: string; defaultChannels: NotificationChannel[]; defaultPriority: NotificationPriority; templateSchema?: unknown; sensitive?: boolean; } ``` --- # 24. Notification 不直接发送 禁止: ```ts sendEmail(...) ``` 出现在业务 Service 中。 必须: ```text Business Event ↓ Notification Runtime ↓ Communication Runtime ``` --- # 25. Message Message 是渲染后的通信内容。 ```ts interface Message { id: string; notificationId: string; channel: NotificationChannel; subject?: string; body: string; format?: 'text' | 'html' | 'markdown' | 'json'; metadata?: Record; } ``` --- # 26. Template Runtime 模板必须独立。 支持: ```text Email Template In-App Template Webhook Template Push Template SMS Template ``` --- # 27. Template Version 模板必须版本化: ```text task.completed@1 task.completed@2 ``` Delivery 必须记录: ```text templateId templateVersion ``` 这样历史消息可以追溯。 --- # 28. Template Rendering 流程: ```text Template ↓ Variables ↓ Validation ↓ Render ↓ Message ``` 禁止模板执行任意代码。 --- # 29. Template Variables 例如: ```text {{task.name}} {{task.status}} {{project.name}} {{execution.id}} ``` 变量来源必须来自: ```text Notification Context ``` 不能直接执行任意 JavaScript。 --- # 30. Template Security 禁止: ```text eval() new Function() arbitrary template code ``` 模板只能使用: ```text approved variables approved helpers ``` --- # 31. HTML Email HTML 邮件必须经过: ```text Template ↓ Render ↓ Sanitize ↓ Message ``` 防止: ```text XSS unsafe HTML external injection ``` --- # 32. Markdown Markdown 只允许在明确支持 Markdown 的 Channel。 例如: ```text in_app chat ``` Email 是否转换 HTML 由 Template/Channel Policy 决定。 --- # 33. Channel Registry 统一注册: ```text in_app email webhook push sms chat ``` 插件可以贡献新的 Channel Adapter。 --- # 34. In-App Notification In-App 不需要外部 Provider。 流程: ```text Notification ↓ Message ↓ In-App Delivery ↓ Notification Store ↓ Realtime ↓ UI ``` --- # 35. Notification Center UI: ```text Notifications ├── All ├── Unread ├── Important ├── System ├── Tasks ├── Agents └── Security ``` --- # 36. Read State 每个用户需要: ```text readAt seenAt archivedAt ``` Notification 内容本身可以共享。 Delivery/User State 单独存储。 --- # 37. Realtime 新通知: ```text Notification ↓ Event Runtime ↓ Realtime Runtime ↓ SSE / WebSocket ↓ UI ``` 不要创建第二套 WebSocket Runtime。 --- # 38. Email Channel Email Channel 负责: ```text Message ↓ Email Provider ``` Provider 可以: ```text SMTP SES Resend SendGrid ``` --- # 39. Email Provider Provider Adapter: ```ts interface EmailProvider { send( message: EmailMessage, context: DeliveryContext, ): Promise; } ``` --- # 40. SMTP SMTP Provider 可以使用: ```text host port username credential ``` Credential 通过: ```text Credential Runtime ``` 管理。 --- # 41. Email 不直接读取 Secret 禁止: ```ts process.env.SMTP_PASSWORD ``` 业务代码直接使用。 必须: ```text Communication Runtime ↓ Provider Resolver ↓ Credential Runtime ↓ Secret Runtime ``` --- # 42. Webhook Channel Webhook 是: ```text Notification ↓ JSON Message ↓ Webhook Delivery ``` --- # 43. Webhook Security 必须支持: ```text HMAC Signature Timestamp Nonce Replay Protection Timeout Retry ``` --- # 44. SSRF Protection Webhook URL 必须经过: ```text Network Policy ``` 禁止访问: ```text 127.0.0.1 localhost 169.254.169.254 internal network private CIDR ``` 除非明确允许。 --- # 45. Webhook Payload 统一: ```json { "id": "delivery-id", "type": "task.completed", "timestamp": "2026-09-12T00:00:00Z", "data": {} } ``` --- # 46. Webhook Version Webhook Schema 必须版本化: ```text v1 v2 ``` Event Type: ```text task.completed ``` Schema: ```text eventVersion: 1 ``` --- # 47. Push Push Channel 可以支持: ```text FCM APNs Web Push ``` Provider Adapter 统一: ```text Push Runtime ↓ Provider ``` --- # 48. SMS SMS 也作为 Channel: ```text sms ``` Provider: ```text Twilio Vonage Custom ``` SMS 必须受到: ```text cost rate limit country policy user preference ``` 约束。 --- # 49. Chat Channel 未来支持: ```text Slack Discord Teams Telegram ``` 但都统一为: ```text chat ``` 然后 Provider Adapter。 --- # 50. Channel Policy 用户可能: ```text Email = enabled Push = enabled SMS = disabled ``` 项目可能: ```text SMS = forbidden ``` Organization 可能: ```text External Webhook = disabled ``` 最终: ```text Global Policy ↓ Organization Policy ↓ Project Policy ↓ User Preference ↓ Notification Policy ``` --- # 51. Notification Preference 用户可以设置: ```text Task Completed In-App ✓ Email ✓ Push ✓ Task Failed In-App ✓ Email ✓ Push ✓ Marketing Email ✗ ``` --- # 52. Preference 不等于 Security Preference: > 用户想不想收到? Security: > 系统允不允许发送? 所以: ```text Security Policy ↓ Preference ↓ Delivery Policy ``` --- # 53. Critical Notification 某些通知: ```text security.alert production.down critical.failure ``` 可能: ```text 不能被普通偏好完全关闭 ``` 但必须明确由: ```text Notification Policy ``` 决定。 --- # 54. Notification Routing 例如: ```text task.failed ``` Routing: ```text In-App Email ``` 而: ```text task.completed ``` 可能只有: ```text In-App ``` --- # 55. Routing Policy ```ts interface NotificationPolicy { notificationType: string; channels: NotificationChannel[]; priority?: NotificationPriority; quietHours?: boolean; dedupeWindowSeconds?: number; digest?: boolean; } ``` --- # 56. Quiet Hours 支持: ```text 22:00 - 08:00 ``` 普通通知: ```text delay ``` Critical: ```text send immediately ``` 由 Policy 决定。 --- # 57. Digest 大量通知可以合并: ```text 100 Task Completed ``` 变成: ```text 今日任务摘要 完成 100 个任务 失败 3 个任务 ``` --- # 58. Digest Runtime 流程: ```text Notifications ↓ Group ↓ Aggregate ↓ Digest Template ↓ Message ↓ Delivery ``` Digest 不需要第二套 Queue。 --- # 59. Deduplication 例如: ```text server.offline ``` 短时间内连续产生: ```text 100 Events ``` 不能发送: ```text 100 Email ``` 支持: ```text dedupeKey dedupeWindow ``` --- # 60. Dedup Key 例如: ```text server.offline:{serverId} ``` 或者: ```text task.failed:{taskId} ``` --- # 61. Delivery ```ts interface Delivery { id: string; notificationId: string; messageId: string; channel: NotificationChannel; providerId?: string; recipientId?: string; status: | 'pending' | 'scheduled' | 'sending' | 'sent' | 'delivered' | 'failed' | 'retrying' | 'cancelled'; attempts: number; scheduledAt?: Date; sentAt?: Date; deliveredAt?: Date; failedAt?: Date; providerMessageId?: string; } ``` --- # 62. Delivery Attempt 一次 Delivery 可以: ```text Attempt 1 ↓ fail Attempt 2 ↓ fail Attempt 3 ↓ success ``` 必须记录每次 Attempt。 --- # 63. Delivery Attempt Schema ```ts interface DeliveryAttempt { id: string; deliveryId: string; attempt: number; providerId: string; startedAt: Date; completedAt?: Date; status: 'success' | 'failed'; providerStatus?: string; providerRequestId?: string; errorCode?: string; latencyMs?: number; } ``` --- # 64. Retry 支持: ```text fixed linear exponential jitter ``` 例如: ```text 1 min 5 min 15 min 1 hour ``` --- # 65. Retryable Error 通常: ```text timeout 429 5xx temporary network error provider unavailable ``` 可以 Retry。 通常不能: ```text invalid recipient invalid credentials invalid template permission denied unsubscribed ``` --- # 66. Dead Letter Queue 多次失败: ```text Delivery ↓ Retry ↓ Retry ↓ DLQ ``` DLQ 使用: ```text Task / Job Runtime ``` 已有 Queue Runtime。 --- # 67. Manual Replay 管理员可以: ```text Replay Delivery ``` 但必须: ```text permission audit idempotency ``` --- # 68. Idempotency 发送通信也必须考虑: ```text network timeout provider accepted response lost ``` 因此: ```text Idempotency-Key ``` 非常重要。 --- # 69. Provider Message ID Provider 返回: ```text providerMessageId ``` 必须保存。 用于: ```text delivery tracking provider webhook debugging dedupe ``` --- # 70. Delivery Status 标准状态: ```text pending scheduled sending sent delivered failed retrying cancelled ``` Email 可能额外: ```text bounced complained ``` --- # 71. Bounce Email Provider 可能通知: ```text bounce ``` Event: ```text communication.email.bounced ``` 进入: ```text Event Runtime ``` --- # 72. Complaint 同样: ```text communication.email.complained ``` 可更新: ```text Recipient Preference ``` 防止继续发送。 --- # 73. Unsubscribe 必须支持: ```text global unsubscribe channel unsubscribe notification-type unsubscribe ``` 但系统安全通知可以由 Policy 决定是否可关闭。 --- # 74. Consent 营销/商业通信如果涉及用户同意: ```text Consent ``` 应该独立建模。 不要简单用: ```text notification_preferences ``` 替代所有法律/合规语义。 --- # 75. Consent Runtime 如果产品需要: ```text consent withdrawal proof timestamp source policyVersion ``` 建议独立: ```text Consent Runtime ``` Communication Runtime 消费 Consent 状态。 --- # 76. Communication Provider 统一 Provider: ```ts interface CommunicationProvider { id: string; channel: NotificationChannel; capabilities: string[]; send( message: Message, context: DeliveryContext, ): Promise; } ``` --- # 77. Provider Health Provider 必须支持: ```text healthy degraded down disabled ``` Communication Router 根据健康状态选择。 --- # 78. Provider Failover 例如: ```text Email ↓ Provider A ↓ timeout Provider B ``` 但要特别注意: > Provider A 可能已经接受消息但响应丢失。 因此 Failover 必须依赖: ```text idempotency provider semantics delivery state ``` 不能简单地认为 timeout = 未发送。 --- # 79. Communication Router 流程: ```text Delivery ↓ Allowed Channels ↓ Provider Candidates ↓ Credential Check ↓ Health ↓ Rate Limit ↓ Cost ↓ Policy ↓ Selected Provider ``` --- # 80. Cost Routing SMS/Email/Push 可能有不同成本。 Router 可以考虑: ```text cost latency reliability region ``` 但: ```text security consent policy ``` 仍然是 Hard Filter。 --- # 81. Region Provider 可以声明: ```text region dataResidency supportedCountries ``` Policy 可以要求: ```text Japan EU US ``` Router 过滤不符合要求的 Provider。 --- # 82. Communication Rate Limit 支持: ```text global organization project user recipient provider channel notificationType ``` 例如: ```text 每用户每小时最多 10 条 SMS。 ``` --- # 83. Anti-Spam 批量 Agent 自动化特别容易产生: ```text 10000 Email ``` 因此必须支持: ```text quota rate limit daily limit per-recipient limit per-notification-type limit ``` --- # 84. Batch Sending 批量发送: ```text Notification ↓ Task ↓ Jobs ↓ Queue ↓ Workers ``` 每个 Job 可以处理: ```text 100 recipients ``` 具体 batch size 由 Provider Capability 决定。 --- # 85. Parallel Sending 可以并发: ```text Worker 1 Worker 2 Worker 3 ``` 但必须遵守: ```text provider concurrency channel rate limit organization quota ``` --- # 86. Scheduling Notification 可以: ```text send now send at time delay digest ``` 例如: ```text Task 完成 ↓ Delay 5 min ↓ Email ``` Schedule 交给: ```text Scheduler Runtime ``` --- # 87. Event Trigger Event 可以触发: ```text Notification Rule ``` 例如: ```text deployment.failed ``` 触发: ```text security/admin notification ``` --- # 88. Workflow Trigger Workflow 可以执行: ```text notification.send ``` 例如: ```text Webhook ↓ Process ↓ Approval ↓ Notification ``` 但发送仍然走: ```text Communication Runtime ``` --- # 89. Agent Notification Agent 可以请求: ```text notify user ``` 但 Agent 只能提出: ```text Notification Request ``` 最终: ```text Security ↓ Preference ↓ Policy ↓ Communication Runtime ``` --- # 90. Agent 不直接 Email 禁止: ```text Agent ↓ SMTP ``` 禁止: ```text Agent ↓ SendGrid API ``` 必须: ```text Agent ↓ Capability ↓ Action ↓ Communication Runtime ``` --- # 91. Plugin Notification Plugin 可以注册: ```text notification types templates channels providers ``` 但不能建立: ```text Plugin-owned Notification Runtime ``` --- # 92. MCP Notification MCP 可以暴露: ```text notification.send ``` 但: ```text MCP ↓ Action Runtime ↓ Communication Runtime ``` 不能绕过权限。 --- # 93. API 推荐: ```text POST /v1/actions/notification.send GET /v1/notifications GET /v1/notifications/:id POST /v1/notifications/:id/read POST /v1/notifications/:id/archive GET /v1/notification-preferences PUT /v1/notification-preferences GET /v1/deliveries GET /v1/deliveries/:id ``` --- # 94. SDK ```ts sdk.notifications.list(); sdk.notifications.markRead(); sdk.notifications.send(); sdk.notifications.preferences.get(); sdk.notifications.preferences.update(); ``` SDK 不负责发送 Provider API。 --- # 95. CLI 建议: ```bash devos notification list devos notification inspect devos notification send-test devos notification preferences devos delivery list devos delivery inspect devos delivery retry devos communication provider list devos communication provider health devos communication doctor ``` --- # 96. Notification UI 建议: ```text System └── Notifications ├── Notification Center ├── Preferences ├── Templates ├── Channels ├── Providers ├── Deliveries └── Failed / DLQ ``` --- # 97. Delivery Inspector 显示: ```text Delivery ID Notification ID Recipient Channel Provider Status Attempts Created Scheduled Sent Delivered Error Provider Message ID ``` --- # 98. 不默认显示敏感信息 例如: ```text Webhook URL Email Address Phone Provider Credential ``` 需要根据权限脱敏。 --- # 99. Template UI 管理员可以: ```text Create Edit Preview Validate Publish Deprecate ``` Template 发布后版本固定。 --- # 100. Template Preview 支持: ```text Preview Email Preview Push Preview In-App Preview Webhook JSON ``` 使用: ```text sample context ``` 不能真实发送。 --- # 101. Test Delivery 提供: ```text Send Test ``` 必须明确: ```text permission audit rate limit ``` 防止管理员误发送大量消息。 --- # 102. Notification Search Global Search 可以搜索: ```text notification delivery template provider ``` 但必须应用: ```text Security Scope ``` --- # 103. Notification Data Model 建议: ```text notifications notification_recipients notification_messages notification_templates notification_template_versions notification_preferences notification_policies deliveries delivery_attempts communication_providers communication_provider_credentials communication_provider_health notification_digests notification_subscriptions ``` --- # 104. In-App 数据 可以额外: ```text notification_user_state ``` 保存: ```text readAt seenAt archivedAt ``` 避免修改共享 Notification。 --- # 105. Provider Credentials 数据库只保存: ```text credentialId ``` 而不是: ```text smtpPassword apiKey webhookSecret ``` 实际 Secret: ```text Secret Runtime ``` --- # 106. Outbox Event → Notification 的可靠性建议使用: ```text Transactional Outbox ``` 例如: ```text Business Transaction ├── Resource Update └── Outbox Event ↓ Event Runtime ↓ Notification Runtime ``` 避免: ```text DB 成功 Email 逻辑失败 ``` 导致状态不一致。 --- # 107. Notification Event 推荐: ```text notification.created notification.scheduled notification.sent notification.failed notification.cancelled notification.deduplicated ``` --- # 108. Delivery Event 推荐: ```text delivery.created delivery.started delivery.sent delivery.delivered delivery.failed delivery.retrying delivery.cancelled delivery.bounced delivery.complained ``` --- # 109. Event Runtime Integration 这些 Event 全部进入: ```text Event Runtime ``` 不能: ```text Notification Event Bus ``` 另起一套。 --- # 110. Observability 所有 Delivery 必须有: ```text requestId correlationId notificationId deliveryId attemptId providerId ``` --- # 111. Metrics 至少: ```text notifications_created_total deliveries_total deliveries_success_total deliveries_failed_total deliveries_retry_total delivery_latency_ms provider_failures_total provider_rate_limit_total email_bounce_total email_complaint_total notification_deduplicated_total ``` --- # 112. Cost Communication Cost 可以计入: ```text organization project agent task job notification delivery provider channel ``` 例如: ```text SMS: $0.01 × 1000 ``` 最终可以归因到: ```text Agent Task ``` --- # 113. Usage 统一 Usage: ```text emails sent SMS sent push sent webhooks sent in-app notifications ``` 并可以和: ```text Model Usage Storage Usage Network Usage ``` 统一进入: ```text Usage Runtime ``` --- # 114. Budget 通信也应该支持: ```text daily budget monthly budget per-task budget per-project budget ``` 例如: ```text Agent Task: Max communication cost = $2 ``` 达到预算: ```text COMMUNICATION_BUDGET_EXCEEDED ``` --- # 115. Priority 支持: ```text low normal high critical ``` Queue 优先级由 Task/Job Runtime 处理。 --- # 116. Cancellation 尚未发送: ```text pending scheduled ``` 可以取消。 已经发送: ```text sent ``` 不能假装取消。 因此: ```text cancel() ``` 只影响尚未执行的 Delivery。 --- # 117. Expiration Notification 可以设置: ```text expiresAt ``` 例如: ```text Task Approval ``` 过期后: ```text 不要继续发送 ``` --- # 118. Approval Notification Approval Runtime 可以产生: ```text approval.requested approval.approved approval.rejected approval.expired ``` Communication Runtime 负责通知。 但: ```text Communication Runtime ``` 不负责 Approval Decision。 --- # 119. Security Alert Security Runtime 可以产生: ```text security.alert ``` Communication Runtime 负责: ```text In-App Email Push ``` Security Runtime 不直接操作 SMTP。 --- # 120. Task Notification Task Runtime 可以产生: ```text task.started task.completed task.failed task.cancelled ``` Communication Runtime 负责通知。 --- # 121. Agent Notification Agent Runtime 可以产生: ```text agent.started agent.waiting agent.completed agent.failed agent.approval_required ``` Communication Runtime 负责发送。 --- # 122. Workflow Notification Workflow 可以声明: ```text notify: type: workflow.failed recipients: - project.owner ``` Workflow Engine 不直接发送。 --- # 123. Communication Context 模板渲染使用: ```ts interface CommunicationContext { notification: Notification; event?: EventReference; actor?: ActorReference; organization?: ResourceReference; project?: ResourceReference; task?: ResourceReference; job?: ResourceReference; execution?: ResourceReference; data: Record; } ``` --- # 124. Context Security Communication Context 必须经过: ```text Authorization Scope Field Permission Redaction ``` 防止模板意外输出敏感字段。 --- # 125. Template Field Permission 例如模板想使用: ```text {{user.email}} ``` 必须判断: ```text communication context + recipient visibility ``` 不能因为模板管理员可以编辑模板,就自动获得所有用户字段。 --- # 126. External Recipient 如果 Recipient 是: ```text external email ``` 必须确认: ```text data policy external sharing policy ``` 否则可能产生数据泄露。 --- # 127. External Webhook Webhook 更加敏感。 需要: ```text allowed domains network policy payload policy signature ``` --- # 128. Webhook Secret Webhook Secret: ```text Secret Runtime ``` 签名: ```text HMAC ``` Secret 不能进入: ```text logs events audit delivery payload ``` --- # 129. Email Security 支持: ```text SPF DKIM DMARC ``` 但这些属于: ```text Provider / Domain Configuration ``` 不是 Notification Runtime 自己实现邮件服务器。 --- # 130. Email Tracking 如果业务需要: ```text open click bounce complaint ``` 可以接入 Provider Webhook。 但需要注意: ```text privacy consent regional policy ``` --- # 131. Provider Webhook Provider 状态回调: ```text Provider ↓ Webhook Endpoint ↓ Authentication ↓ Event Runtime ↓ Delivery Update ``` 不能直接修改业务表。 --- # 132. Provider Webhook Idempotency Provider 可能重复发送: ```text delivered delivered delivered ``` 必须: ```text eventId / providerEventId ``` 去重。 --- # 133. Communication Provider Plugin 未来可以安装: ```text @devos/provider-resend @devos/provider-twilio @devos/provider-slack ``` 但它们只能提供: ```text Provider Adapter ``` 不能拥有: ```text Notification Runtime Queue Audit Permission Secret Runtime ``` --- # 134. Plugin Notification Extension 插件可以贡献: ```text Notification Type Template Recipient Resolver Channel Provider ``` 例如 SEO Plugin: ```text seo.scan.completed seo.keyword.alert seo.article.published ``` --- # 135. Plugin UI 插件可以贡献: ```text Notification Settings Template Settings Provider Settings Dashboard Widget ``` 但使用: ```text DevOS UI Shell ``` 不能创建第二套 Notification Center。 --- # 136. MCP MCP 可以暴露: ```text notification.send notification.list notification.mark_read ``` 但全部进入: ```text Security ↓ Action Runtime ↓ Communication Runtime ``` --- # 137. Agent Capability Agent 可看到: ```text notification.send ``` 但 Capability Discovery 必须根据: ```text permission scope channel recipient policy ``` 过滤。 --- # 138. Agent Notification Example Agent: ```text 任务已经完成。 ``` 请求: ```json { "type": "task.completed", "recipient": "task.requester", "channels": ["in_app", "email"] } ``` Runtime: ```text Security ↓ Resolve Recipient ↓ Check Preference ↓ Check Policy ↓ Render Template ↓ Create Delivery ↓ Queue ↓ Provider ``` --- # 139. Batch Agent Example 例如: ```text 生成 100 篇文章 ``` 完成后不要: ```text Agent → 100 Email ``` 而: ```text Task ↓ Event ↓ Notification ↓ Digest ↓ Email ``` 可以最终只发: ```text 任务完成: 100 篇文章 97 成功 3 失败 ``` --- # 140. Communication Runtime 不做业务摘要 “100 篇文章,97 成功,3 失败”应该由: ```text Task / Agent / Workflow ``` 提供结构化数据。 Communication Runtime 只负责: ```text Render Deliver Track ``` --- # 141. Digest 可以聚合,但不理解业务 Digest Runtime 可以: ```text count group sum ``` 例如: ```text 100 task.completed ``` 但不应该理解: ```text SEO CRM DevOps ``` --- # 142. Message Localization 支持: ```text en-US zh-CN ja-JP ``` 模板: ```text task.completed.en task.completed.zh task.completed.ja ``` --- # 143. Locale Resolution 优先级: ```text Recipient Preference ↓ Project ↓ Organization ↓ System Default ``` --- # 144. Timezone Notification Scheduler 必须考虑: ```text recipient timezone project timezone organization timezone ``` 例如: ```text 每日 09:00 ``` 不是服务器 UTC 09:00。 --- # 145. Internationalization Notification Type 不应该直接存: ```text 任务完成 ``` 而存: ```text task.completed ``` 模板负责本地化。 --- # 146. Accessibility In-App Notification 必须支持: ```text ARIA keyboard navigation screen reader contrast notification grouping ``` --- # 147. Notification Center Performance 不要一次加载: ```text 100000 notifications ``` 必须: ```text cursor pagination ``` 推荐: ```text createdAt + id ``` 作为稳定排序。 --- # 148. Notification Read Optimization 未读数: ```text unread_count ``` 可以使用缓存/计数,但 PostgreSQL 作为最终一致性 Source of Truth。 --- # 149. Redis Redis 可以用于: ```text unread count cache rate limit dedupe lock delivery concurrency provider health cache ``` 不能成为: ```text notification source of truth ``` --- # 150. Storage 如果消息包含附件: ```text Message ↓ Attachment ↓ Storage Runtime ``` Communication Runtime 不自己管理 Blob。 --- # 151. Large Attachments Email 附件不应该直接把: ```text 100MB ``` 塞进数据库。 使用: ```text Storage Reference ``` Provider 根据能力: ```text signed URL stream attachment ``` 发送。 --- # 152. Artifact Task 生成: ```text report.pdf ``` 应该: ```text Artifact ↓ Storage ``` Notification 只引用: ```text artifactId ``` --- # 153. Communication 与 Artifact 正确: ```text Artifact ↓ Message Attachment Reference ↓ Provider ``` 错误: ```text Notification DB ↓ 复制整个 PDF Blob ``` --- # 154. Data Retention 不同数据可以有不同 retention: ```text Notification Delivery Delivery Attempt Provider Response Message Content Audit ``` --- # 155. Message Content Retention 敏感通信内容不能无限保存。 支持: ```text retention policy redaction deletion archive ``` --- # 156. Audit Retention Audit 按: ```text Audit Runtime ``` 的规则保存。 Communication Runtime 不自己定义完整 Audit System。 --- # 157. Privacy Communication Runtime 必须支持: ```text data minimization purpose limitation retention redaction access control export deletion ``` --- # 158. User Data Export 如果平台需要用户数据导出: ```text Notification Delivery Preferences ``` 可以通过: ```text Export Runtime ``` 统一导出。 --- # 159. Deletion 删除用户时: ```text Identity ↓ Data Lifecycle ↓ Notification References ``` 按照平台 Data Retention Policy 处理。 --- # 160. Tenant Isolation 必须保证: ```text Organization A ``` 无法读取: ```text Organization B ``` 的: ```text Notification Delivery Template Provider Recipient ``` --- # 161. Project Isolation 同一个 Organization 内: ```text Project A ``` 默认不能读取: ```text Project B ``` 的项目级 Notification。 --- # 162. Environment Isolation 例如: ```text production ``` 不能错误发送: ```text staging recipient ``` 必须通过: ```text Environment Scope ``` 隔离。 --- # 163. Production Guard Production 可以要求: ```text approved provider verified sender verified domain ``` 防止测试配置向真实用户发消息。 --- # 164. Development Safety Development 环境建议: ```text Email → Mailpit SMS → Mock Push → Mock Webhook → Local Receiver ``` 防止开发环境误发真实消息。 --- # 165. Test Provider 必须提供: ```text MockCommunicationProvider ``` 支持: ```text success failure timeout rate limit bounce duplicate provider accepted but response lost ``` --- # 166. Contract Tests 必须测试: ```text Provider Adapter Notification Routing Template Rendering Recipient Resolution Preference Deduplication Retry Rate Limit Scheduling Delivery Webhook ``` --- # 167. Security Tests 必须测试: ```text Tenant isolation Recipient authorization Template injection SSRF Webhook signature Secret leakage External sharing Unsubscribe Agent authorization Plugin authorization MCP authorization ``` --- # 168. Delivery Tests 必须覆盖: ```text success failure retry DLQ manual replay timeout provider failover idempotency duplicate provider webhook ``` --- # 169. Notification Tests 必须覆盖: ```text event → notification notification → recipients preferences quiet hours critical notifications digest dedupe expiration localization ``` --- # 170. Performance Tests 测试: ```text 10k notifications 100k deliveries large recipient list high concurrency provider rate limit large digest ``` 重点不是单纯吞吐,而是: ```text 不会重复发送 不会跨租户 不会突破 Provider Rate Limit 不会突破预算 ``` --- # 171. Failure Recovery Worker Crash: ```text Delivery ↓ Lease ↓ Worker crash ↓ Lease expire ↓ Retry ``` 继续使用: ```text Task/Job/Queue/Worker Runtime ``` --- # 172. Provider Down ```text Provider A ↓ down ``` Router: ```text Provider B ``` 如果没有备用: ```text Delivery → retry ``` 最终: ```text DLQ ``` --- # 173. Network Timeout 如果: ```text request timeout ``` 不能直接假设: ```text provider did not receive ``` 必须使用: ```text idempotency provider status providerMessageId ``` 尽可能判断。 --- # 174. Communication State Machine ```text pending ↓ scheduled ↓ sending ├──→ sent │ ↓ │ delivered │ └──→ retrying ↓ sending ↓ failed ↓ DLQ ``` --- # 175. Notification State Notification: ```text created scheduled processing partially_sent completed failed cancelled expired ``` --- # 176. Partial Completion 例如: ```text 100 recipients 97 delivered 3 failed ``` Notification: ```text partially_completed ``` 而不是: ```text failed ``` --- # 177. Aggregated Delivery Status 可以计算: ```text total pending sending sent delivered failed ``` 用于: ```text Notification Detail ``` --- # 178. Communication Doctor CLI: ```bash devos communication doctor ``` 检查: ```text Provider Credential DNS SMTP Webhook Rate Limit Templates Scheduler Queue Worker Event Realtime ``` --- # 179. Provider Test ```bash devos communication provider test ``` 应该执行: ```text credential check connectivity test message provider response ``` 测试消息必须明确标记: ```text TEST ``` --- # 180. Architecture Package 推荐: ```text packages/ ├── notification/ │ ├── domain/ │ ├── runtime/ │ ├── policy/ │ ├── template/ │ ├── recipient/ │ ├── routing/ │ ├── preference/ │ ├── digest/ │ └── testing/ │ ├── communication/ │ ├── runtime/ │ ├── provider/ │ ├── delivery/ │ ├── email/ │ ├── webhook/ │ ├── push/ │ ├── sms/ │ └── chat/ ``` 如果项目当前规模较小: ```text packages/notification/ ``` 内部模块化即可。 --- # 181. Provider Package 未来: ```text packages/communication/providers/ ├── mock/ ├── smtp/ ├── ses/ ├── resend/ ├── twilio/ ├── fcm/ ├── apns/ ├── slack/ └── generic-webhook/ ``` 不要求一次全部实现。 --- # 182. Recommended Initial Providers 第一阶段只需要: ```text Mock In-App SMTP Generic Webhook ``` 之后再增加: ```text Push SMS Chat ``` --- # 183. 为什么不一开始实现所有 Channel 因为 DevOS 的目标是: > 建立统一 Runtime,而不是第一天实现几十个 Provider。 先保证: ```text Notification ↓ Delivery ↓ Provider ``` 架构稳定,再增加 Provider。 --- # 184. 与 API / Integration Runtime 的关系 26 号文档定义: ```text Integration / Provider Runtime ``` Communication Runtime 应复用: ```text Credential Network Provider Webhook Rate Limit ``` 不要重新实现。 --- # 185. 与 Event Runtime 的关系 16 号: ```text Event Runtime ``` 负责: ```text Event Event Store Event Bus Replay Subscription Webhook Realtime ``` 31 号: ```text Notification Runtime ``` 消费 Event。 --- # 186. 与 Observability Runtime 的关系 17 号: ```text Observability ``` 负责: ```text Log Metric Trace Audit Alert ``` 31 号只产生 telemetry。 --- # 187. 与 Configuration Runtime 的关系 18 号: ```text Configuration Runtime ``` 负责: ```text SMTP host Provider configuration Channel configuration ``` Secret: ```text Secret Runtime ``` --- # 188. 与 Storage Runtime 的关系 15 号: ```text Storage Runtime ``` 负责: ```text attachments artifacts large files ``` Communication Runtime 只引用。 --- # 189. 与 Model Runtime 的关系 30 号: ```text Model Runtime ``` 可以用于: ```text AI-generated notification translation summarization classification ``` 例如: ```text Notification Data ↓ Model Runtime ↓ Localized Summary ↓ Communication Runtime ``` 但这不是 Communication Runtime 自己调用 Provider。 --- # 190. AI Notification 如果需要: ```text “帮我把这 20 个任务失败信息总结成一封邮件” ``` 正确: ```text Agent ↓ Model Runtime ↓ Structured Result ↓ Notification ↓ Communication Runtime ``` --- # 191. Model Failure 如果 AI Summary 失败: ```text Communication Runtime ``` 应该可以使用: ```text fallback template ``` 而不是让整个通知系统失败。 --- # 192. Agent + Communication 最终: ```text Agent ↓ Goal ↓ Task ↓ Action ↓ Event ↓ Notification ↓ Communication ``` 这样 Agent 不需要理解: ```text SMTP FCM Twilio ``` --- # 193. Project Factory Project Manifest 可以声明: ```yaml capabilities: - notification - email - webhook ``` Factory 根据 Capability 安装: ```text Notification Runtime Provider Modules UI API ``` --- # 194. Plugin Manifest 插件可以声明: ```yaml notifications: - type: seo.scan.completed - type: seo.article.published templates: - seo.scan.completed ``` --- # 195. Plugin Permission 例如: ```yaml permissions: - notification.create - notification.read ``` 如果插件需要: ```text external email ``` 还应该明确: ```text communication.email.send ``` --- # 196. Agent Capability Agent 默认只获得: ```text notification.send ``` 如果需要外部渠道: ```text notification.send.email notification.send.webhook ``` 需要额外授权。 --- # 197. MCP Capability MCP Capability: ```text notification.send ``` 实际: ```text MCP ↓ Security Context ↓ Action Runtime ↓ Notification Runtime ``` --- # 198. No Second Communication Runtime 绝对禁止: ```text Plugin EmailService Agent EmailService Workflow EmailService SEO EmailService ``` 最终全部应该使用: ```text Communication Runtime ``` --- # 199. Architecture Contract 任何发送行为必须满足: ```text Security ↓ Authorization ↓ Scope ↓ Notification ↓ Delivery ↓ Communication Provider ``` --- # 200. Zcode Forbidden Patterns 禁止: ```ts await transporter.sendMail(...) ``` 出现在: ```text business service agent plugin workflow controller mcp ``` 禁止: ```ts fetch(webhookUrl) ``` 直接出现在业务逻辑。 禁止: ```ts twilio.messages.create(...) ``` 直接出现在 Agent/Plugin。 --- # 201. Zcode Correct Pattern ```ts await actionRuntime.execute( 'notification.send', { type: 'task.completed', recipients: [ { type: 'user', id: userId, }, ], data: { taskId, }, }, context, ); ``` 之后: ```text Action Runtime ↓ Notification Runtime ↓ Communication Runtime ↓ Provider ``` --- # 202. Implementation Phase 1 实现: ```text Notification Domain Notification Type Registry Recipient Message Delivery ``` 先使用: ```text Mock Provider ``` --- # 203. Implementation Phase 2 实现: ```text Template Runtime Preference Routing Deduplication Retry ``` --- # 204. Implementation Phase 3 实现: ```text In-App Realtime Notification Center ``` --- # 205. Implementation Phase 4 实现: ```text SMTP Generic Webhook ``` --- # 206. Implementation Phase 5 实现: ```text Provider Health Failover Rate Limit Budget Cost Usage ``` --- # 207. Implementation Phase 6 实现: ```text Push SMS Chat ``` 按真实业务需要逐步添加。 --- # 208. Implementation Phase 7 实现: ```text Digest Quiet Hours Scheduling Localization Advanced Preferences ``` --- # 209. Implementation Phase 8 接入: ```text Agent Workflow Plugin MCP Task Event ``` --- # 210. Definition of Done Notification / Communication Runtime 完成必须至少满足: ```text [ ] Notification Domain [ ] Message [ ] Recipient [ ] Audience [ ] Template [ ] Template Version [ ] Channel [ ] Provider [ ] Delivery [ ] Delivery Attempt [ ] Retry [ ] DLQ [ ] Deduplication [ ] Preference [ ] Routing Policy [ ] Quiet Hours [ ] Scheduling [ ] Digest [ ] In-App [ ] Email [ ] Webhook [ ] Provider Health [ ] Provider Failover [ ] Rate Limit [ ] Budget [ ] Usage [ ] Cost [ ] Realtime [ ] Event Integration [ ] Task Integration [ ] Agent Integration [ ] Plugin Integration [ ] MCP Integration [ ] Security [ ] Audit [ ] Observability [ ] Localization [ ] Contract Tests [ ] Security Tests [ ] Mock Provider ``` --- # 211. Security Definition of Done 必须证明: ```text [ ] No cross-tenant notification access [ ] No unauthorized recipient access [ ] No secret leakage [ ] No webhook SSRF [ ] No template code execution [ ] No unauthorized external communication [ ] No preference bypass [ ] No Agent privilege escalation [ ] No Plugin privilege escalation [ ] No MCP privilege escalation [ ] No duplicate delivery after retry ``` --- # 212. Performance Definition of Done 必须证明: ```text [ ] Async batch delivery [ ] Provider rate limiting [ ] Worker concurrency control [ ] Delivery lease recovery [ ] Notification pagination [ ] Deduplication [ ] Backpressure [ ] Provider failover ``` --- # 213. 最终 Runtime 关系 ```text EVENT │ ↓ Notification Rule │ ↓ NOTIFICATION │ ┌───────────┴───────────┐ ↓ ↓ RECIPIENT TEMPLATE │ │ └───────────┬───────────┘ ↓ MESSAGE │ ↓ DELIVERY PLANNER │ ↓ COMMUNICATION RUNTIME │ ┌───────────┼───────────┐ ↓ ↓ ↓ In-App Email Webhook ↓ ↓ ↓ Provider Provider Provider │ │ │ └───────────┼───────────┘ ↓ DELIVERY │ ┌───────────┴───────────┐ ↓ ↓ EVENT OBSERVABILITY ``` --- # 214. DevOS 完整通信链 ```text User / Agent / Workflow / Plugin │ ↓ Action Runtime │ ↓ Event │ ↓ Notification Runtime │ ┌───────┼────────┐ ↓ ↓ ↓ Policy Recipient Template │ │ │ └───────┼────────┘ ↓ Message │ ↓ Communication Runtime │ Provider Router │ ┌───────┼────────┐ ↓ ↓ ↓ Email Push Webhook │ │ │ └───────┼────────┘ ↓ Delivery │ ┌─────┴─────┐ ↓ ↓ Event Metrics ↓ ↓ Realtime Observability ``` --- # 215. 最终 Golden Rules ## Golden Rule 1 > **Event 表示发生了什么,Notification 表示需要通知什么。** ## Golden Rule 2 > **Notification 不直接发送,Delivery 才代表一次实际发送。** ## Golden Rule 3 > **Channel 是通信方式,Provider 是通信实现。** ## Golden Rule 4 > **所有 Email / SMS / Push / Webhook / Chat 都必须进入统一 Communication Runtime。** ## Golden Rule 5 > **业务代码不能直接调用 SMTP、Twilio、SendGrid、FCM 等 Provider SDK。** ## Golden Rule 6 > **Provider Credential 永远通过 Credential / Secret Runtime。** ## Golden Rule 7 > **所有批量发送必须使用 Task → Job → Queue → Worker Runtime。** ## Golden Rule 8 > **Communication Runtime 不重新实现 Queue、Event、Security、Audit、Storage。** ## Golden Rule 9 > **Security / Consent / Scope 是发送前的硬性约束。** ## Golden Rule 10 > **Preference 决定用户偏好,但不能覆盖 Security Policy。** ## Golden Rule 11 > **所有 Delivery 必须支持状态、Attempt、Retry、Idempotency 和 Observability。** ## Golden Rule 12 > **Provider 可以替换,但 Notification API 不应该变化。** --- # 216. 最终结论 DevOS 最终不应该出现: ```text SEOEmailService AgentEmailService WorkflowEmailService PluginEmailService CRMEmailService ``` 而应该只有: ```text Notification Runtime ↓ Communication Runtime ↓ Provider Runtime ``` 业务只需要说: ```text “任务完成,请通知项目负责人。” ``` DevOS 自己负责: ```text 找谁 ↓ 是否允许通知 ↓ 用户喜欢什么渠道 ↓ 选择什么 Channel ↓ 选择什么 Provider ↓ 使用什么 Credential ↓ 什么时候发送 ↓ 是否需要 Digest ↓ 是否重复 ↓ 是否超过 Rate Limit ↓ 是否超过 Budget ↓ 发送 ↓ 失败 Retry ↓ Provider Failover ↓ 记录 Delivery ↓ 产生 Event ↓ Realtime / Audit / Metrics ``` 最终形成: ```text EVENT ↓ NOTIFICATION ↓ RECIPIENT + POLICY + TEMPLATE ↓ MESSAGE ↓ DELIVERY ↓ COMMUNICATION RUNTIME ↓ PROVIDER ↓ EXTERNAL CHANNEL ``` **最终 Golden Rule:** > **业务系统只描述“通知什么”;Notification Runtime 决定“通知谁”;Communication Runtime 决定“怎么发送”;Provider 只负责“实际通信”。任何 Agent、Plugin、Workflow、MCP 或业务模块都不能创建第二套发送系统。**