返回 TraceWise 项目总览 · 交互图:审核 · 决定 · 证据 · 血缘 / 审核 · 决定 · 治理 · 工作流 / 审核 · 决定 · 生命周期
很多 AI 系统已经加上了“人工审核”:模型先给出建议,人点击批准,系统再执行。问题是,如果这个批准只被保存成一个布尔值,那么它很快就会失去含义。
审核之后,底层 Graph 可能增加了节点,Evidence 可能被补充或撤回,Proposal 可能被重新生成,Policy 也可能已经升级。此时继续沿用旧的 approved=true,看起来尊重了人审,实际上执行的却已经不是审核者看到的那件事。
TraceWise 对这个问题的回答不是“多加一次确认弹窗”,而是把一次审核建模为一个有明确适用范围的不可变 ReviewDecision。它绑定 Proposal、Graph 基线、Evidence 集合、Policy、Reviewer、Project 与 Scope。任一关键依据发生变化,旧决定仍作为历史记录保留,但不再拥有对当前状态的授权效力;系统必须基于新依据重新形成 Proposal,并重新进入审阅。
这篇文章只回答一个问题:为什么分析依据发生变化后,旧结论不能继续有效,以及系统如何在不伪造原子回滚的前提下恢复。
人审批准的不是一句结论,而是一组被冻结的前提
可以把一次决定的有效范围写成下面这个约束:
有效决定 = f( Proposal@fingerprint, Graph@revision+fingerprint, Evidence@ids+fingerprint, Policy@revision, Reviewer@identity, Project, Scope )
这里没有任何一项只是为了“审计看起来完整”。它们共同回答三个问题:
- 审核者当时看到了什么;
- 审核者凭什么作出这个判断;
- 这次判断被允许作用到哪里。
Proposal 指纹防止提案内容被换掉;Graph revision 与 fingerprint 固定变更发生前的权威状态;Evidence IDs 与 fingerprint 固定审核依据;Policy revision 防止旧规则下的批准穿透到新规则;Reviewer、Project 和 Scope 则限制决定的主体和作用域。
因此,ReviewDecision 不是“批准按钮的日志”,而是一个不可变的审阅信封。信封中的任一绑定对不上当前权威状态,执行就必须失败关闭。
同一个治理不变量,两种权威执行路径
当前 TraceWise 保留两种执行路径,分别有不同的存储归属与生效步骤。
| 路径 | 适用项目 | 决定与执行方式 |
|---|---|---|
| 产品权威路径 | 尚未显式切换到 AF-X01 的项目 | GraphChangeService 形成不可变 tracewise.review-decision.v1,校验后应用产品 Graph,再把同一个决定同步给 Foundation Memory 生命周期 |
| AF-X01 权威路径 | 已显式 opt-in 的项目 | TraceWise 把 Registration、Graph baseline、Evidence bindings、operations 和 principals 编译成 Foundation Proposal;Reviewer 只形成决定,不直接写 Graph,独立 Executor 消费 approved outbox |
两条路径的存储和故障恢复不同,但共享同一条治理原则:审核只对被冻结的 Proposal、Graph、Evidence、Policy 和身份绑定有效。 产品权威路径把这个原则直接编码在 ReviewDecision 及执行前重验中;AF-X01 路径则把它编码在 Foundation Proposal、expected state version、Evidence binding 与独立 Executor 中。
技术解释图:Proposal 先绑定 Evidence 与权威身份,再进入人审;批准后由独立执行器消费,失效、冲突和恢复都有显式出口。该图解释关系,不是产品运行截图。
两次重验:作出决定前一次,真正写入前再一次
只在审核页面打开时检查一次并不够。用户可能在页面停留数分钟,另一个操作已经改变了 Graph 或 Evidence;也可能 ReviewDecision 已经持久化,但执行任务稍后才启动。
在产品权威路径中,TraceWise 明确设置了两个检查点。
第一个检查点:形成 ReviewDecision 之前
审核请求到达后,服务端不会直接相信前端携带的 Proposal。它会重新读取已存 Proposal、当前 Graph 和当前 Evidence,然后检查:
- Proposal 的当前内容是否仍与存储时的 fingerprint 一致;
- Graph fingerprint 和 revision 是否仍等于提案形成时的基线;
- Evidence IDs 和 Evidence fingerprint 是否仍是同一组依据;
- Project 与 Scope 是否仍匹配;
- 审阅理由是否非空,审核身份是否由当前认证上下文派生。
通过之后,系统才会构造冻结的 tracewise.review-decision.v1,写入 decision、reason、replay identity 与 decision fingerprint。
第二个检查点:执行 ReviewDecision 之前
执行阶段重新读取 ReviewDecision、Proposal、Graph 与 Evidence。除了再次校验 Proposal、Graph、Evidence,它还会检查:
- Policy revision 是否仍是当前规则;
- ReviewDecision 中的 Project、Graph、Scope、Proposal 是否与存储信封一致;
- Reviewer subject 与 credential actor 是否仍匹配;
- 同一 Proposal 是否已经存在冲突的终态决定。
只有这些约束全部成立,批准才可以写入 Graph;驳回路径则记录终态而不写入提案目标。直接绕过审阅调用 apply 会收到 review_decision_required,而不是隐式补一个默认审核者。
这两次重验解决的是不同时间窗口:第一次防止“基于过期页面作出新决定”,第二次防止“用已经过期的决定执行新状态”。
AF-X01 路径采用对应但不同的实现:记录 Proposal 时固定 Registration、Graph baseline、排序后的 Evidence revision bindings、operations 与 proposer fingerprint;人审命令必须携带 expected state version;真正执行由独立 Executor 再次消费当前权威状态。Reviewer 不直接写 Graph,TraceWise 也不能在切换后退回旧 apply 路径。
漂移不是普通报错,而是决定适用范围被打破
产品权威路径没有把所有失败都压成一个 409 Conflict。不同错误码表达不同的权威不变量:
| 变化 | 拒绝码 | 含义 |
|---|---|---|
| 已存 Proposal 内容被改变 | stale_proposal | 审阅对象已经不是原对象 |
| 当前 Graph 不再等于提案基线 | graph_drift | 变更目标的前置状态已经变化 |
| Evidence 集合或内容发生变化 | evidence_drift | 审核依据已经变化 |
| Policy revision 变化 | review_policy_revision_mismatch | 旧规则下的决定不能穿透新规则 |
| Reviewer 身份不匹配 | reviewer_identity_mismatch | 当前执行主体无权代表原审核者 |
| 对同一 Proposal 提交相反终态 | review_decision_conflict | 不允许覆盖不可变终态 |
受控本地验收分别制造了 Graph 漂移和 Evidence 漂移,两种漂移都在到达 Foundation 权威写入前失败,记录的 Foundation writes 为 0。源码回归还覆盖了 Proposal 篡改、陈旧 Policy、错误 Reviewer、Project/Scope 不匹配和直接 apply 绕过。
AF-X01 路径使用自己的 typed contract 表达同一件事。保留的 installed-workflow 验收中,superseded 或 revoked Evidence revision 在 submit 或 executor 阶段返回 evidence_lineage_stale,并保持 Graph 零写入;执行结果如果发现当前 authority 与冻结绑定不再一致,则进入 stale,而不是回退到旧权威继续写。
这就是“失效”的精确定义:旧 ReviewDecision 记录仍然存在,也没有被改写成另一个决定;只是当前状态已经不满足它的绑定条件,所以它不能继续授权执行。
前端承担的是把这个事实讲清楚,而不是掩盖它。在产品权威审阅面板中,收到 stale_proposal、graph_drift、evidence_drift 或 review_policy_revision_mismatch 后,界面把提案标记为“已失效”,禁用批准和驳回按钮,并要求刷新 Proposal、Graph 与 Evidence 后重新形成提案。AF-X01 项目则显示 Foundation Proposal 的 pending、approved、applied、stale 或 recovery 状态,但仍只保留一个业务人审入口。
技术解释图:Graph 与 Evidence 的 revision/fingerprint 进入不可变审阅信封,批准后的 receipt 再把执行结果带回历史与恢复路径。
为什么不能自动把新 Evidence 拼进旧决定
一种看似友好的实现是:执行时总读取最新 Evidence,只要“比原来更多”就继续执行。这个做法的问题是,它偷偷改变了人审对象。
新增 Evidence 不一定加强旧结论,也可能直接推翻它;Evidence 被撤回更不能被当成无关变化。即使新增内容与结论一致,也只有新的审核动作才能确认审核者确实看过它。
因此 TraceWise 比较的不是 Evidence 数量,而是排序后的 IDs 与内容 fingerprint。只要集合或内容不同,就进入 evidence_drift。系统不替审核者推断“这次变化应该没关系”。
同样,Graph 变化也不能只检查目标节点是否还存在。Graph 是变更计划的前置状态,任何会改变提案语义的权威变化都应该让旧基线失效。使用 revision 与 fingerprint 的组合,目的就是把“看起来还能执行”与“仍是原来审核过的执行”区分开。
重新审阅与重试不是一回事
证据漂移后,正确恢复路径是:
- 读取当前 Graph 和当前 Evidence;
- 重新生成或重新存储 Proposal;
- 让 Reviewer 基于新差异和新依据作出新的 ReviewDecision;
- 用新的 lineage 执行。
这里不能重放旧决定,因为它的 Proposal、Graph 或 Evidence 绑定已经失效。
但并不是所有失败都要求第二次人审。在产品权威路径中,如果 TraceWise 已经成功应用 Graph,而 Foundation 暂时不可用,业务决定本身没有变化,失败的是跨存储交付。受控验收中,系统明确记录 applied_with_foundation_pending,保留同一个 ReviewDecision 和 sync record;恢复数据库后,人工触发同一决定的重试,状态变为 applied,再次重试得到 deduplicated。
AF-X01 路径不采用“先产品 Graph、后同步 Foundation”的顺序。批准只推进 approved outbox,由独立 Executor 写权威 Graph;执行被中断时进入 recovery_required,并通过显式 recover/replay 恢复。两种路径都拒绝把暂时失败伪装成成功,但恢复动作必须遵守各自的权威所有权。
这条边界很重要:
- 依据变化破坏了决定的适用范围,需要重新审阅;
- 交付暂时失败没有改变决定内容,可以重试同一冻结决定;
- 相同 replay identity 已完成只返回去重 receipt,不重复 Graph 或 Memory 转换;
- 相反终态决定是冲突,不能用“重试”覆盖。
技术解释图:批准、驳回、执行中断、显式恢复和去重回执是不同状态;恢复不是把 503/423 伪装成成功。
为什么不伪造跨存储原子回滚
在产品权威路径中,TraceWise 拥有产品 Graph、Evidence、审核工作流和 ReviewDecision;Foundation 通过公共接口消费同一个决定,独立验证 Registration、Scope、资源、Evidence 与 Policy,并推进 Foundation 所有的 Memory 生命周期。
这两个权威存储之间没有统一数据库事务。Graph 已经成功而 Foundation 失败时,系统保留 TraceWise 的成功事实,把 Foundation 状态标为 pending/degraded,并提供有次数上限的显式重试。
AF-X01 项目已经把 Graph 与 Evidence 权威显式切换给 Foundation,因此采用 proposal/outbox/executor/recovery 状态机,并且切换后的旧产品写入口失败关闭。这里同样不存在“Foundation 不可用就静默回到 legacy”的安全退路。
运营人员可以分别检查业务决定是否已生效、下游生命周期是否已同步,再决定重新审阅还是重试交付。
被否决的几种更简单设计
只保存 approved=true
它无法回答批准的是哪个 Proposal、哪版 Graph、哪组 Evidence,也无法区分幂等重放和相反决定。随着状态变化,这个布尔值只剩下“某人曾经点过按钮”。
执行时自动使用最新依据
它会让实际执行对象脱离人工审阅对象,把“人审门”退化为一次与当前状态无关的历史确认。
Graph 与 Foundation 任一失败就宣称全部回滚
跨存储没有真实事务时,这种说法会抹去已经发生的权威写入。正确做法是记录部分成功、保留恢复依据,并把重试与重新审阅分开。
在 Foundation 再增加一次人工批准
这会制造两个业务决定来源。TraceWise 保持唯一的人审入口,Foundation 独立验证同一决定的权威绑定,但不要求用户再次批准。
证据边界
本文描述的是当前 TraceWise 正式源码和保留的本地受控验收结果。产品权威 ReviewDecision 验收覆盖真实 ASGI 路由、TraceWise SQLite/Graph 读取、Foundation PostgreSQL Memory 生命周期、Graph/Evidence 漂移、回放冲突、数据库不可用与手工恢复;AF-X01 验收覆盖 Registration、Evidence revision binding、独立 Reviewer/Executor、stale fail-closed、outbox 和恢复。它们都不等于生产运行证明。
以下能力没有因为这套 ReviewDecision 机制而自动成立:
graph_id仍只是逻辑分区,不能据此声称租户级安全隔离;- Foundation Relation 生命周期在该验收中没有合法 Relation candidate,因此没有被证明;
- 跨存储原子回滚、生产 IAM/TLS/Secrets、HA/DR、生产流量与长期 soak 都没有被认证;
- 这套机制证明的是决定与证据的可追溯性和失效边界,不证明模型结论更准确。
最后:保留历史,撤销授权效力
治理系统最危险的不是没有日志,而是日志存在,却无法说明一次批准究竟批准了什么。
TraceWise 的核心设计原则可以收敛成一句话:历史决定必须不可变,当前授权必须可失效。
前者让系统能解释“当时为什么这样做”;后者确保“现在的事实已经变化”时,旧批准不会继续穿透到新状态。把这两件事分开,人工审核才不是装饰性的按钮,而是可以被验证、被拒绝、被恢复,也能被追责的权威边界。


