Skip to content

saveMetaItem 是 #4632 词表覆盖不到的持久性接缝:8 处 catch 完全静默吞掉元数据写入失败 #4754

Description

@os-zhuang

发现于 #4669 的修复过程(PR 分支 claude/issue-4669-permission-backfill-strict-spec)。未认领 —— 只是记录。

背景

#4632 立的规则(AGENTS.md「Degradation log levels」)由 pnpm check:durability-log-level 机械执行,但闸门自己声明了局限:它只认 DURABILITY_CRITICAL_CALLEES 这张显式词表,发现不了词表以外的持久性接缝。

#4669 正是这个类:ADR-0094 D4 的 permission-set backfill 调 protocol.saveMetaItem(),失败被 catch 成一条 warn,计数器不动 —— 整条投影路径 100% 停摆,却一个红灯都没有,跨了一个发布周期才被人在无关的 bump 日志里偶然看见。修复(PR 见上)把那两处提到了 error + 计数,但 saveMetaItem 本身没有进词表,所以同类接缝仍然不受保护。

测量:如果把 saveMetaItem 加进词表会怎样

在本地把 ['saveMetaItem', …] 加进 DURABILITY_CRITICAL_CALLEES 跑一次(探针脚本,未提交),得到 8 处违规,分布在 3 个包 4 个文件,而且全部是最糟的形态 —— catch 里连日志都没有,完全静默:

文件 命中数 形态
packages/runtime/src/domains/packages.ts 3 catch swallows the failure with no log at all
packages/rest/src/rest-server.ts 2 同上
packages/metadata-protocol/src/protocol.ts 2 同上
packages/runtime/src/domains/meta.ts 1 同上

(plugin-security 的两处不在名单里 —— 它们已被 #4669 的 PR 修成 error。)

为什么单独立一条

建议做法

  1. 逐一读这 8 处,判定是持久性丢失还是功能性降级;
  2. 真丢失的:按范本(packages/services/service-automation/src/plugin.ts start())改成 error + 写清后果与修复动作,或直接 rethrow;
  3. 判定为可接受的:写进 scripts/durability-degradation.baseline.json,注明理由与关闭条件;
  4. 同一 PR 里把 ['saveMetaItem', '元数据定义没有写进权威存储 —— 运行时看起来一切正常,重新 provision 时定义凭空消失。'] 加进 DURABILITY_CRITICAL_CALLEES

复现

# 把 ['saveMetaItem', '…'] 插进 scripts/check-durability-degradation-log-level.mjs
# 的 DURABILITY_CRITICAL_CALLEES,然后:
node scripts/check-durability-degradation-log-level.mjs

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions