Skip to content

bug(objectql): 扫描得来的 ADR-0104 证书在 lax 开关下会变陈旧 —— 数据回退了,闸却还开着 #4797

Description

@os-zhuang

现象

recordDataMigrationRun 的文档写得很清楚:

verified_at is set on a passing run and CLEARED on a failing one — a deployment whose data has regressed since it last verified closes its own gate.

「数据自上次验证后回退,部署自己关闸」—— 但今天这只发生在重新跑一次迁移的时候。没有任何东西在数据真的回退时通知账本。

正常情况下这不成问题:证书一旦成立,写路径就是 strict,不合形状的值会被拒,根本落不了库,所以证书不会变假。但操作员的逃生开关(OS_ALLOW_MEDIA_VALUES 系列 —— OS_ALLOW_LAX_MEDIA_VALUES / OS_ALLOW_LAX_VALUE_SHAPES)恰恰是为「已验证部署临时放宽」准备的。开着它写入不合形状的值:

  1. 值被放行、落库;
  2. sys_migration 仍然记着 verified_at 非空、blocking: 0;
  3. 操作员关掉开关(或换个进程 / 换台机器)→ strict 回来 → 同一份数据开始被拒;
  4. 而且 adr-0104-file-references 那道闸同时管着已释放字段文件的回收,一张陈旧证书意味着在数据已不合规的前提下继续删字节。

这与 #4769 是同一个病:账本声称的事实,被它自己所在的部署推翻了,而账本不知道。

#4794 为什么刻意没覆盖这一类

#4769 的修复给引擎加了「证书被本次启动推翻就撤销」的能力,但范围收窄到本次启动亲手从空创建的库上的自证行:

  • 自证是「因为空,所以干净」的推断,一次写入的反例足以推翻它;
  • 而扫描得来的证据是走遍全库得出的,让一次写入的观察去推翻一次全库扫描,量级不对;而且开了 lax 开关的操作员并没有要求我们吊销他的迁移记录。

所以这一半留作独立决定。

需要定夺

  • 方案 A:任何被放行的违规值都撤销当前证书(无论证据来源)。最诚实,但会让 lax 开关变成「用一次就得重跑迁移」,可能不是操作员想要的。
  • 方案 B:不撤销证书,但在账本上加一条「已观测到偏离」的标记(不动 verified_at),让下一次迁移运行 / 回收扫描能看到,并在日志里持续告警。
  • 方案 C:维持现状,把它写进 lax 开关的文档 —— 「开着它写入的数据,关掉后可能被拒;关掉前请重跑迁移」。

倾向 B:它保住了「declared = enforced」的信息(偏离被记录、可发现、可告警),又不会把一个显式的临时开关变成不可逆操作。但 A 与文档里已经写下的语义最一致,值得维护者权衡。

关联


#4769 的实现过程中发现并记录(AGENTS.md Prime Directive #10),未认领。

Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions