fix(objectql): 悬空引用巡检为「预算没轮到」的对象建诚实桶 unscannedObjects (#5718) - #5760
Merged
Conversation
) 悬空引用巡检的主循环在 `report.scanned >= maxRows` 时直接 break,其后所有 对象既没被读、也没进任何桶 —— 它们的 `dangling: []` 与「真的读过且干净」的 表完全无法区分,而这正是本文件所有诚实桶存在的理由(`truncatedObjects` / `unreadableObjects` / `aborted` 已分别覆盖表内预算、数据源拒答、运行被叫停, 唯独「整张表没轮到」没有对应桶)。 新增 `unscannedObjects: string[]`:按扫描顺序(prioritise 三档)记下未轮到 的对象名,可直接回喂 `options.objects` 续跑。类型上 optional(同 `aborted` 与 #4743 的 `provenance`,手写 report 字面量仍可编译),运行时本模块产出的 每一份报告都显式赋值 —— 走到底就是 `[]`,永不缺席,`undefined` 只可能表示 「旧报告形状」。 不入桶的两类:无任何引用字段的对象(prioritise 已在循环前丢弃,其沉默是被 证明的而非假设的),以及调用方用 `options.objects` 排除的对象(那是调用方 自己的收窄,不是巡检漏看)。与 `truncatedObjects` 同族:不单独抬告警(大库 每次健康运行都会耗尽预算,常亮告警就是 #4747 的坏警报),只在告警载荷里逐项 带出,并始终留在返回的报告里。 被叫停的运行同样记录未轮到的对象,否则 `unscannedObjects: []` 与 `aborted: true` 并排会读成「早停了但什么都没漏」;唯一边界是在枚举注册表之前 就被叫停 —— 那时没有名单可给,由 `aborted` 承担,已用测试钉住。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V7WetGmnfoXNn8cLieKKmx
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 13 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This was referenced Aug 6, 2026
os-zhuang
marked this pull request as ready for review
August 6, 2026 04:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5718
问题
packages/objectql/src/integrity/dangling-reference-audit.ts主循环在report.scanned >= maxRows(默认DEFAULT_MAX_ROWS = 5_000)时直接break,其后所有对象既没被读、也没进任何桶。它们的
dangling: []与「真的读过且干净」的表在报告里完全无法区分 —— 而这正是本文件所有诚实桶存在的理由:
truncatedObjectsunreadableObjectsaborted(#4747)「整张表没轮到」是唯一没有对应桶的一条 —— 模块头注释原话:Together they are
what stops
0 danglingfrom ever being read aseverything is fine。改动
新增
unscannedObjects: string[],在主循环每一处提前退出前把未轮到的对象名记下:provenance(#4743 事实二) #5719 落地的prioritise三档:安全面 → 业务引用 → 仅溯源),所以调用方可以把它直接回喂
options.objects续跑,补齐画面。aborted、哨兵拆掉之后:#4441 的readonly收窄与 #4551 的巡检跳过还需要吗?——注释已过期,跳过范围值得收窄 #4743 的provenance同一契约:手写 report 字面量(测试替身)仍可编译;而本模块产出的每一份报告
都显式写入,走到底就是
[],永不缺席。因此undefined不需要被猜,它只可能意味着「旧报告形状」,绝不会意味着「完整」。
prioritise在循环前就丢弃了它们,它们不出现在
dangling里是被证明的而非假设的;②调用方用options.objects排除的对象 —— 那是调用方自己的收窄,把它报回去等于把调用方的选择说成巡检的漏看。
truncatedObjects同族:大库每次健康运行都会耗尽预算,常亮告警就是 每个
os migrate子命令关停时,悬空引用巡检都会把sys_metadata/sys_view_definition报成unreadableObjects(连接已关闭) #4747 的坏警报,会把读者训练得跳过那一行。它在告警载荷里逐项带出(对象量级而非行量级,读者要拿名字去续跑),并始终留在返回的报告里。
unscannedObjects: []与aborted: true并排会读成「早停了但什么都没漏」。唯一边界是在枚举注册表之前就被叫停 —— 那时
没有名单可给,由
aborted承担,已用一条测试把这个边界钉住而不是留给下一个人踩。与 #5719 的关系:#4743 不是成因,只是把这条路径抬到「容易踩到」—— 溯源族入巡检
后几乎每个对象都有可审计字段,同样的预算摊到多得多的表上,提前 break 的概率显著
上升。三档
prioritise决定谁拿到有限预算,本桶报告谁一点也没拿到,两件事独立:扫描顺序无法让有界运行变完整,只有说出漏了什么才能让它诚实。
反向验证(方向在跑之前就预测好了)
预测:删掉预算处的
fileUnscanned(i)→ 依赖预算停的用例转红;不依赖它的用例(显式
[]、被叫停、枚举前叫停)保持绿。实测完全一致:第二处限位单独验:只删 abort 分支的
fileUnscanned(i)→a called-off run names what it never reached too单独转红(
expected [] to deeply equal [ 'showcase_task', 'showcase_note' ]),其余保持绿。注意这里断言的选择是关键:只断言
dangling或scanned的测试在旧的静默break 下同样是绿的 —— 发现数一个都不变。名字本身才是被测行为。
测试证据
门禁:
改动面
packages/objectql/src/integrity/dangling-reference-audit.ts(主循环 + 报告类型)packages/objectql/src/integrity/dangling-reference-audit.test.ts(新增[#5718]块 10 例).changeset/dangling-audit-unscanned-bucket.md(patch)未碰
engine.ts/lifecycle-service.ts(有其他 dev 在飞),未碰content/docs/releases/。Generated by Claude Code