"""能力声明与证明协议。 定义能力声明、能力证明值对象与能力证明 Protocol。能力校验分为两层: 静态声明(``CapabilityDeclaration``)与运行时证明(``CapabilityProof``)。 出站中间件判断是否调用富消息渲染时,必须同时检查静态声明与运行时证明, 两者均为真才调用(FR-08 增强)。 """ from __future__ import annotations from dataclasses import dataclass from datetime import datetime from typing import Protocol, runtime_checkable from yuxi.channels.contract.dtos.capability import ChannelCapabilities from yuxi.channels.contract.errors import NotImplementedError @dataclass(frozen=True) class CapabilityDeclaration: """能力声明。 描述插件的静态能力声明,封装 ``ChannelCapabilities``,用于清单注册 与能力校验的声明层。 字段: capabilities: 渠道能力集合(静态声明)。 """ capabilities: ChannelCapabilities @dataclass(frozen=True) class CapabilityProof: """能力证明。 描述单项能力的运行时证明结果,包括能力名称、是否证明通过、证明时间戳 与缓存 TTL,用于能力校验的证明层。 字段: capability_name: 能力名称。 proven: 是否证明通过。 proof_timestamp: 证明时间戳。 cache_ttl: 缓存 TTL(秒,默认 300s)。 """ capability_name: str proven: bool proof_timestamp: datetime cache_ttl: int = 300 @runtime_checkable class CapabilityProver(Protocol): """能力证明 Protocol。 由插件实现,对单项能力进行运行时证明。证明为异步方法,以支持需要远程 调用的能力验证场景。 缓存约束(FR-08 增强): - 能力证明结果 **可以** 缓存,默认 TTL 300s(见 ``CapabilityProof.cache_ttl``)。 - 缓存失效时重新证明。 降级约束(FR-08 增强 / FR-21): - 静态声明支持但运行时证明不支持时,**必须** 记录告警日志并走降级路径。 - 契约测试 **必须** 强制清单声明的能力与运行时投递能力一致,不一致时 阻止合入主干。 """ async def proveCapability( self, capability_name: str, account_id: str | None = None, ) -> CapabilityProof: """证明单项能力。 参数: capability_name: 能力名称。 account_id: 目标账户 ID(多账户渠道使用);单账户渠道可忽略。 返回: 能力证明结果,包含是否通过、时间戳与缓存 TTL。 @consistency: 最终一致(eventual),证明结果可缓存(默认 TTL 300s),缓存失效后重新证明。 @idempotent: True — 相同能力名称的证明应产生等价结果,重复证明无累积副作用。 """ raise NotImplementedError(operation="proveCapability")