Skip to content

check:durability-log-level 结构性看不见「读接缝把故障答成空值」这一类 —— #4825 / #5108 全家都在闸门盲区里 #5186

Closed

Description

@os-zhuang

发现于 #5108(DatabaseLoader 读故障吞成空结果)实现期,不在该单范围内,故单独立卡。未认领 —— 只是记录。观察类,今天没有用户会撞到。

现象

scripts/check-durability-degradation-log-level.mjs 是 #4632 那条规则的机械执行者。它的判据是:

catch 块里调了 DURABILITY_CRITICAL_CALLEES 词表里的操作,而日志级别低于 error 且没有 rethrow → 红。

这个模型对写/DDL 接缝是合身的,对读接缝则结构性地表达不了。两条都不成立:

  1. 词表是按 callee 名字匹配的,而读接缝的 callee 是 find / findOne / count 这种彻底通用的名字 —— 加进词表会把全仓库每一处数据读取都拖进来,不可行。词表现有 9 项(syncSchema、initObjects、writeRecord、dropPromotedDraftRow…)清一色是写/DDL 语义的专名。
  2. 更根本的:读接缝的错误形态不是「日志太轻」,而是「编了一个返回值,且一行都不记」。 catch { return []; } 在闸门眼里连一个可判级别的日志调用都没有 —— 它检查的那个维度在这里是空的。DatabaseLoader 把存储读故障吞成空结果 —— ADR-0110 D3 的 miss/outage 之分在复数读路径上不成立 #5108 修掉的那五处正是这个形状:catch {} → [] / false / null,零日志。[metadata] nextEventSeq() 把驱动读失败也当成「表还没建」,静默从 1 重新发号 —— #4632 同形,机械检查覆盖不到 #4825(nextEventSeq 的 catch { return 1 })是同一族,而且是最贵的那半(写进去的数是错的)。

也就是说:这个族已经在这一个包里出现过三次(#4728 → #4825 → #5108),每次都是人读出来的,闸门一次都没有帮上忙,而且照现在的模型也帮不上。

这一类的可判据形状

三次实例长得一模一样,可以描述:

  • 一个 catch 包着一次读(driver/engine 的 find / findOne / count,或它们的薄封装);
  • catch 体里没有任何日志,也没有 rethrow;
  • 而是 return 一个该方法的空值/零值([] / false / null / 0 / 1)。

判据的关键不在「调了什么」,而在「没读到,却编了一个答案出来」。良性豁免也已经有现成词汇:isMissingTableError()(packages/metadata/src/errors.ts 专门为跨包导出它而存在)—— 一个 catch 只要按错误类型区分过、且只在良性分支返回空值,就应当放行。#4825 和 #5108 修完之后的代码正好就是这个形状,可以直接当 fixture。

为什么不该塞进别的单

建议方向(裁决留给维护者)

  1. 给现有脚本加一条独立规则(不走 DURABILITY_CRITICAL_CALLEES):catch 无日志无 rethrow + return 空值 + 块内含读调用 → 红,除非 catch 里出现按错误类型的区分(isMissingTableError 之类)。必然需要一份 baseline —— 全仓库这个形状的 catch 大概率不少,而且相当一部分是合法的功能性降级;
  2. 或者判定这一族不适合机械判(误报率过高),转而只在 AGENTS.md 里把「读接缝不得编造答案」写成明文规则,靠 review 兜 —— 但那样就要接受它会再犯,并且明说这个取舍;
  3. 或者收窄到只扫元数据/持久化层的读接缝(packages/metadata、packages/metadata-protocol、packages/objectql 的存储缝),把误报面压到可管的范围,再逐步放开。

两条不是本卡要定的;要定的是「这一族目前完全没有机械保护,而它已经复发三次」这一点。

复现

# 现状:五处 `catch {} → 空值` 的读接缝(#5108 修复前的 database-loader.ts)
# 对闸门完全透明 ——
node scripts/check-durability-degradation-log-level.mjs
# → OK,12 durability-critical catch seam(s), all loud or rethrowing

关联

#4632(立规矩)、#4728 / #4825 / #5108(同一族的三次复发)、#4754(词表覆盖的另一半:写接缝)、AGENTS.md「Degradation log levels — warn vs error」「Absence must be loud」、packages/metadata/src/errors.ts(良性判据的现成词汇)。

Activity

  1. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    发现分诊轮:转 needs-user-decision,并按落点改 domain:engine → domain:devx(摘 finding)。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. claude commented on Aug 6, 2026

    @claude
    Contributor

    处置(2026-08-06):退回派发队列,定向方向 3。

    复核结论:三次真实复发(#4728/#4825/#5108),「Absence must be loud」是 AGENTS.md 已明文的不变量,机械化它不是新决策。

    范围:读接缝规则收窄到 metadata / metadata-protocol / objectql 存储缝 + shrink-only baseline;防误报方法论照本脚本自己的先例(#4754/#5241:显式词表、非启发式)。不取方向 2(只写文档=明示接受第四次复发)。量级 M。

    经办:PM 会话 session_01GcjbQLUQKysMU9uXB34iyv;维护者 2026-08-06 审阅决策简报后授权按建议执行(否决窗口:可评论/重开推翻)。


    Generated by Claude Code

  3. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    【裁决落地】维护者 2026-08-06 批复全舰队决策箱评估报告(批复「同意」),本单裁定:

    裁 3——收窄先行:新规则(catch 无日志无 rethrow + return 空值 + 含读调用 → 红,isMissingTableError 豁免)先只扫元数据/持久化层,带 baseline 落地;误报面/成本可控验证后再评估放开全仓(届时由 devx 座位自提,不必回决策箱)。⛔ 不选 2(纯 AGENTS.md 靠 review = 接受 #4728→#4825→#5108 第四次复发)。

    流转:摘 needs-user-decision → pm:queue,归 devx 车道(落点 scripts/)。

    评估与落地会话:session_01N3uGFF8teXbpgtbEJ1aYXu


    Generated by Claude Code

  4. self-assigned this
    on Aug 6, 2026
  5. hotlong commented on Aug 6, 2026

    @hotlong
    Contributor

    认领:PM 循环第 1 轮(devx 车道)
    会话:session_01BDmDsu2575gDxeMCxXhDE3
    分支:claude/issue-5186-durability-read-seam-gate
    Worktree:objectstack-issue-5186
    域:domain:devx
    文件面:scripts/check-durability-degradation-log-level.mjs、scripts/ 下新增 baseline/fixture、.changeset/(越界即停,报告说明)

    按 10:44Z 已落地的裁 3 执行:新读接缝规则收窄到 metadata / metadata-protocol / objectql 存储缝 + shrink-only baseline,isMissingTableError 类型区分豁免;⛔ 不做方向 2。


    Generated by Claude Code

  6. hotlong commented on Aug 6, 2026

    @hotlong
    Contributor

    验收(devx 车道,会话 session_01BDmDsu2575gDxeMCxXhDE3):ACCEPT → PR #5986,已转 ready 并挂入合并队列。

    交付摘要(按维护者 10:44Z「裁 3 —— 收窄先行」):


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions