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

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions