← 返回文章列表

Evidence 为什么不能直接“更新掉”:撤销、继任与物理处置的三条边界

从不可变 revision、下游依赖保护和物理内容处置出发,解释为什么‘停止使用’与‘彻底删除’必须由两条独立权威链完成。

设计 Evidence 系统时,一个很自然的问题是:发现内容错误、过期,或者用户要求删除时,为什么不直接执行一次 UPDATEDELETE

因为这一个动作其实混合了三个不同问题:

  1. 这条内容是否仍可被业务使用;
  2. 新事实如何替代旧事实,同时保留可解释的历史;
  3. 原始 payload 是否应当从数据库、副本、导出和备份中物理消失。

Agent Foundation 已经实现了前两类能力:Evidence 使用稳定 lineage 与不可变 revision,支持 successor、supersede、revoke,以及对下游 Memory、Relation、Graph 状态的依赖保护和重新验证。第三类——物理内容处置——目前只有边界设计,还没有实现为公共产品能力。

这篇文章刻意把“已经验证的机制”与“尚未实现的设计”分开。

查看 Agent Foundation 项目总览 · 打开本文交互图

为什么 Evidence revision 不原地更新

假设一条 Evidence 证明“学生已经掌握分数通分”,Memory 据此形成了教学支架,Graph Proposal 又据此准备更新掌握关系。如果我们把原 Evidence 原地改成“学生尚未掌握”,系统会立刻失去三个关键答案:

  • 当时的 Memory 到底基于哪一版来源形成;
  • 当时审批人看到的内容是什么;
  • 后续 Graph 状态为何与现在的 Evidence 文本不一致。

不可变 revision 的价值不是“多存几份 JSON”,而是让每个下游结论都能绑定到一个精确来源。事实变化时,系统创建同 lineage 的 successor;旧 revision 可以被 supersede 或 revoke,但历史身份不会被改写。

因此,“更新 Evidence”在 Foundation 中表达为:追加新 revision,并改变旧 revision 的生命周期

撤销首先解决使用安全

Evidence 被撤销后,最紧迫的动作不是清理磁盘,而是阻止下游继续把旧内容当作当前权威。

Foundation 的依赖收敛链会在 Evidence 控制面事务中形成 lifecycle event、dependency fence 与 durable outbox。读取路径不再返回不满足支持条件的 Memory 或 Relation;执行路径在无法确认权威时 fail closed;独立 revalidator 再根据 successor 或当前支持状态恢复可用投影。

这条链路的目标是“现在不要继续使用错误内容”,而不是“现在所有物理副本都已删除”。

Evidence 撤销与物理处置边界

技术解释图:左侧是已经实现的使用安全;右侧是尚未实现的物理处置控制面。图中的处置执行链是设计合同,不代表当前产品已有删除 API。

为什么 revoke 不等于 delete

revoke 是语义权威动作。它回答:“这条 revision 还能否支持新的投影或副作用?”

delete 是物理处置动作。它需要回答更难的问题:

  • payload 存在哪些 provider;
  • 是否存在搜索索引、对象存储副本、导出、缓存或备份;
  • 是否有法律保留、审计保留或争议冻结;
  • 删除后如何证明目标不可读,又不在回执中重新泄漏被删除内容;
  • 混合来源生成的 summary 是否仍间接持有不允许继续保留的内容。

如果系统只删除主表中的一行,却仍保留对象存储、向量索引或导出副本,就不能宣称“彻底删除”。反过来,如果为了删除内容而抹掉 lifecycle、ReviewDecision 和依赖回执,又会破坏系统的可审计性。

所以两条链必须正交:撤销先保证使用安全;物理处置再在独立授权下处理内容副本。

一个安全的处置控制面至少需要什么

当前设计把物理处置限制为一条显式的不可逆工作流。

1. 认证的 controller

普通 Agent、模型输出或 adopter 请求体不能直接触发删除。controller 必须重读实际 principal、项目 Registration、处置目的与保留策略。

2. 精确 target inventory

系统需要冻结本次要处理的 provider 与对象身份,而不是执行“删除所有相关内容”这样的模糊命令。目标可能包括主 payload、派生副本、索引、导出与可识别备份。

3. 零写 dry-run

dry-run 计算覆盖范围、阻塞原因、provider 能力和目标指纹,但不删除任何内容。未知副本、法律保留或身份漂移都必须在越过不可逆边界前暴露。

4. 显式授权

授权绑定冻结的 target set 与 dry-run fingerprint。任何目标变化都使旧授权失效,而不是让 controller 悄悄扩大删除范围。

5. provider 执行与验证

执行器只能处理 manifest 中的 exact targets。执行结束后还要验证 active store 和声明覆盖的副本不可读;部分 provider 失败应当形成可重放的 partial disposition,而不是把整个请求标成成功。

6. 有界回执

回执证明谁、在什么合同下、对哪些不透明目标执行了什么结果,但不能保存原始 payload、敏感 locator、自由文本或可猜测的明文摘要。否则“删除完成”的回执会成为新的敏感副本。

混合来源 summary 是最容易漏掉的难点

一段 summary 可能同时来自三条 Evidence,其中只有一条被要求处置。简单删除原始 revision 并不能证明 summary 不再携带该内容。

安全策略不能依赖全局语义扫描去猜“哪段文字受影响”。更可靠的做法是要求派生对象记录精确 dependency:

  • 能够从剩余来源安全重建时,先保护旧投影,再创建不含该来源的 successor;
  • 无法证明安全重建时,保持 protected,不继续投影;
  • 处置回执只记录依赖收敛结果,不复制被处置内容。

这也是为什么 dependency/revalidation 先于物理删除实现:没有来源映射,就无法找到并处理依赖已删除来源的派生内容。

“完全擦除”应当是一项很难获得的结论

只有所有声明范围内的 provider 都完成处置并通过不可读验证,系统才有资格报告 complete disposition。以下任一情况都应降低结论:

  • 未知 export 或 backup;
  • provider 不支持精确目标删除;
  • 部分目标失败;
  • legal hold 阻止执行;
  • 派生 summary 尚未形成安全 successor;
  • 目标 inventory 在授权后发生漂移。

这不是保守措辞游戏,而是在区分“我停止使用它”“我删除了主副本”和“我能证明声明范围内已不可读”三个不同承诺。

当前边界

截至这篇文章对应的本地基线:

  • Evidence revision、successor、supersede、revoke 已有实现与回归证据;
  • Memory、Relation 与 Graph 的 Evidence dependency protection/revalidation 已有实现与 SQLite、PostgreSQL/Neo4j 验证;
  • 物理 content disposition controller、target inventory、执行器和回执尚未实现;
  • 不存在可以对外宣称的“完整擦除 API”;
  • 备份治理、法务保留、生产 IAM 与跨区域副本处置仍属于生产系统问题。

我的最终判断是:不可变 Evidence 不是拒绝修正,而是把修正、失效和删除拆成可证明的动作。 先让旧内容立即停止产生影响,再讨论如何安全地、可验证地物理处置,才能同时保住使用安全、历史解释和隐私边界。

← 返回文章列表