执行协议
状态:已准入,正在构建中 (Admitted, in build-out)
五阶段执行协议已在内核层准入 (P-ALMI-011)。状态机、幂等性规则、补偿规则、故障关闭规则和执行级别矩阵均已确定。审计账本的持久化功能正在积极构建中,以交付形式提供。
五个阶段
Nimi AI 执行协议具有固定的规范顺序:
discover → dry-run → verify → commit → audit| 阶段 | 目的 |
|---|---|
discover | 查找请求主体(Principal)作用域下可用的类型化操作动词 |
dry-run | 在模拟提交下执行操作;无副作用 |
verify | 验证试运行输出是否与调用方的意图和策略匹配 |
commit | 执行实际操作;修改状态 |
audit | 在执行账本中记录结果(成功或失败) |
此顺序是规范的。文档和操作指南必须按此顺序呈现阶段;颠倒或跳过任何阶段均视为契约违规,而非风格选择。
幂等性要求
写操作必须支持 idempotencyKey。重试时必须携带相同的 idempotencyKey。运行时必须识别并去重。
这是一项硬性规定,因为没有幂等性的重试会将瞬时网络故障转化为重复的副作用。协议的正确性取决于此键是否得到遵守。
补偿 (SAGA)
多操作编排必须支持补偿。如果在早期的 commit 成功后,后续的 commit 失败,协议将触发对在其操作契约中声明了 compensation 处理器的操作进行补偿。
| 属性 | 值 |
|---|---|
| 补偿声明于 | 操作契约(compensation 字段) |
| 触发条件 | 部分多操作成功后提交失败 |
| 补偿类型 | 根据操作声明进行撤销 / 退款 / 回滚 |
| 补偿失败 | 记录到审计中;不会静默空操作 |
如果某个操作未声明补偿,则包含该操作的多操作编排不能依赖回滚——这是编排器必须遵守的契约级别属性。
验证必须先于提交
verify 始终在 commit 之前运行。协议不接受“先提交后验证”的模式。如果 verify 失败,协议将在不提交的情况下终止。
提交必须持久化审计账本
commit 必须持久化到执行账本中。如果持久化不确定(例如,账本后端不可达),协议将故障关闭——它不会继续执行未持久化的提交。
故障转换
| 失败位置 | 发生情况 |
|---|---|
dry-run | 无副作用;协议进入 audit 阶段并记录失败原因 |
verify | 协议终止,不进行提交;audit 记录失败 |
commit | 如果操作声明了补偿,则触发补偿;audit 记录失败(以及任何补偿结果) |
audit 持久化不确定 | 故障关闭;先前的 commit 被视为可疑并报告 |
任何阶段的失败都会直接路由到 audit。不存在静默跳过。
执行级别矩阵
操作注册时需指定三个执行级别之一。每个级别绑定不同的协议保证:
| 级别 | 试运行要求 | 审计要求 | 允许高风险? |
|---|---|---|---|
full | 必需 | 标准 | 是 |
guarded | 预检可替代 | 强审计要求 | 是 |
opaque | supportsDryRun=false (固定) | 持久化审计要求 | 否 — 不透明模式下禁止高风险 |
opaque 模式适用于无法暴露其提交前状态的操作(例如,不支持试运行的提供方)。其权衡在于,不透明操作不能是高风险的。
操作契约最低要求
操作注册表条目最低声明以下内容:
| 字段 | 目的 |
|---|---|
actionId | 稳定标识 |
inputSchema | 类型化输入 |
outputSchema | 类型化输出 |
riskLevel | low / medium / high (低 / 中 / 高) |
executionMode | full / guarded / opaque (完全 / 受控 / 不透明) |
idempotent | 操作是否幂等(无键) |
supportsDryRun | 是否支持试运行(opaque 模式下强制为 false) |
auditEventMap | 操作事件到审计事件类型的映射 |
compensation | 可选;SAGA参与必需 |
opaque + high risk 的组合不可准入。应用不能注册此类组合。
读者场景:标准写操作
应用通过其已准入的主体(Principal)发起类型化写操作。
- 发现 (Discover)。 主体(Principal)的作用域授予操作动词;发现返回类型化操作契约。
- 试运行 (Dry-run)。 操作在模拟提交下运行;输出Schema验证通过;无状态修改。
- 验证 (Verify)。 验证检查试运行输出是否符合调用方意图和策略;通过。
- 提交 (Commit)。 实际提交执行;状态修改;审计账本持久化。
- 审计 (Audit)。 结果记录;血缘链接发现 → 试运行 → 验证 → 提交 → 审计。
使用相同的 idempotencyKey 重试将返回原始提交结果,而非重复副作用。
读者场景:带补偿的多操作编排
一个编排工作流调用三个提交:A、B、C。C失败。
- A 执行发现 + 试运行 + 验证 + 提交 + 审计。 A的补偿处理器已声明。
- B 执行发现 + 试运行 + 验证 + 提交 + 审计。 B的补偿处理器已声明。
- C 执行发现 + 试运行 + 验证 + 提交。 提交失败。
- 补偿触发。 运行时调用B的补偿;然后调用A的补偿。
- 审计链。 审计记录原始提交尝试以及每个补偿结果;血缘完整。
如果A或B未声明补偿,编排器将无法回滚它们;这是操作契约的属性,而非协议的属性。
读者场景:验证失败
一个类型化写提案到达。发现 + 试运行通过。
- 验证运行。 验证交叉检查:在当前策略快照下,试运行输出是否与调用方意图实际匹配?
- 验证失败。 输出表明策略现在禁止的写操作(例如,自试运行以来敏感度阈值已更改)。
- 协议终止。 无提交。无重试挽救。契约级别规则是“验证必须先于提交,且验证失败终止流程”。
- 审计。 失败原因记录;调用方看到类型化拒绝。
更改输入和键的重试可能在新的流程下成功。使用相同键的重试将获得原始审计结果。
读者场景:补偿路径本身失败
编排器触发B的补偿。B的补偿处理器引发错误。
- 尝试补偿。 运行时调用B的补偿。
- 补偿失败。 运行时不会静默空操作;它将失败记录到审计中。
- 运维人员可见性。 审计账本现在显示:原始提交、失败的C提交、B的补偿尝试及失败、A的补偿尝试。
- 无静默挽救。 系统不会假装补偿成功。审计显示真相。
重试/传输不做什么
重试和认证刷新仅是传输/认证机制。它们不挽救以下情况:
- 解码失败
- 内容类型失败
- Schema失败
- 契约级别失败(例如,验证失败、没有准入重试语义的提交失败)
验证失败不会通过重试变为验证通过。Schema无效的响应不会通过重试变为有效。协议将这些失败视为故障关闭。
性能/可用性红线
| 约束 | 规则 |
|---|---|
| 控制平面/数据平面分离 | 必需 |
| 策略 + 授权决策 | 尽可能本地缓存 |
| 审计写入 | 默认异步 |
| 操作控制平面开销 | p95 ≤ 20毫秒 |
| 策略异常时的只读低风险操作 | 受控故障开放准入 |
| 策略异常时的高风险写操作 | 默认故障关闭 |
这些规则管理生产环境中执行协议的操作属性。它们不是可选的默认值。
边界摘要
| 关注点 | 所有者 |
|---|---|
| 五阶段状态机 | 平台 (P-ALMI-011) |
| 操作契约最低要求 | 平台 (P-ALMI-010) |
| Hook操作架构(存在哪些操作) | 平台 (P-ALMI-002) |
| 主体模型(谁在调用) | 平台 (P-ALMI-003) |
| 外部代理准入规则 | 平台 (P-ALMI-004) |
| 运行时侧委托网关/防火墙 | 运行时 (K-DELEG-*) |