Skip to content

fix(scripts): check-single-authz-resolver 的扫描语料补下限断言 —— 根解析成功但零文件不再判绿 (#5916) - #6056

Open
hotlong wants to merge 1 commit into
mainfrom
claude/issue-5916-authz-resolver-scan-floor
Open

fix(scripts): check-single-authz-resolver 的扫描语料补下限断言 —— 根解析成功但零文件不再判绿 (#5916)#6056
hotlong wants to merge 1 commit into
mainfrom
claude/issue-5916-authz-resolver-scan-floor

Conversation

@hotlong

@hotlong hotlong commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Fixes #5916

#4932 同族的第三个门禁。scripts/check-single-authz-resolver.mjs 已经补过 #4930 那一半(每个 SCAN_ROOTS 先解析,死根按名报错),缺的是另一半:根解析成功、可读,但走完一个文件都没收到。此时 collectScanFiles 返回空数组,检查 (1) 遍历空集合、零 error,"不存在重复解析器" 这个结论就这样从零文件里得了出来 —— assertRootsResolvable 全程满意,目录就在那儿,离开的是语料。

前提复核(照 Prime Directive #6,实测而非照抄正文)

origin/main@efedd28 上对未修改的脚本跑了两个探针:

场景 origin/main 现状
(a) packages/ 可解析、零个 .ts(语料整体迁走) exit 1,但报的是 Delegator missing: packages/rest/src/rest-server.ts ×2
(b) packages/ 可解析、只剩两个 delegator 是 .ts,真实重复解析器写成 .mts exit 0,绿

场景 (a) 值得如实记一笔:今天它是红的,但红错了理由 —— 操作者被告知两个文件不见了,而实际事件是重复解析器扫描一个文件都没读。这恰好就是脚本模块头自称的 "luck, not coverage"(两个 DELEGATOR 碰巧在同一根下),而不是正文字面说的"整体绿";正文的核心断言 —— out 长度从不断言、检查 (1) 的结论来自空集合 —— 逐字成立。场景 (b) 则显示同族的静默收窄本身已经能判绿。修法要买的正是"这道门能诚实地告诉你它跑没跑"。

修法

#4932 落地在 check-doc-authoring.mjsEmptyRootError 复用形状,未重新设计:

  • collectScanFiles 按根统计 out.length 增量,任一声明的根产出 0 个文件即抛 EmptyRootError,按名报红,并带上本次总数;
  • 下限由本次 walk 现算(「每个声明的根至少 1 个文件」),⛔ 不引入需要维护的高水位棘轮 —— 棘轮要在每次合法搬迁时维护,而它多买到的那个失败(语料缩水但非空)并不是让这道门变空转的那个;
  • 按根、绝不按总数:多根时一个有货的根会替所有蒸发掉的兄弟根打掩护,那正是这条断言要拦的静默收窄;
  • main() 分出 reportEmptyRoots,把"根解析了但没贡献文件"和死根分开报,并指向真正的两种成因(语料搬家 / walk 过滤器不再匹配)。

未新增第二个真实 SCAN_ROOTS 条目 —— 那是改这道门扫什么,不在本 issue 的申报面内。

self-test 三向钉死

SCAN_ROOTS 今天只有一个条目,所以"只点名该根"这一向用 collectScanFiles(root, roots) 已有的参数注入一个两根列表来驱动,不动生产常量:

  1. 单根为空 → 红且只点名该根:tools/ 可解析但无 .tsroots === ['tools']、不牵连 packages,且 total 等于 packages 仍扫到的基线数(证明这一轮没有被整体中止,也证明按根下限不是总数下限);
  2. 全空 → 红且报总数 0:每个声明根都存在但为空 ⇒ roots 等于 SCAN_ROOTStotal === 0,并断言 audit 抛的是空扫描而不是那对误导性的 Delegator missing;
  3. 恢复 → 绿:空根下放回一个 .ts ⇒ 回到 baseline + 1;整棵树未动时 audit 仍为 0 error。

反向验证(方向在跑之前先定:去掉断言必须红)

collectScanFiles 还原成 main 的四行写法后跑 self-test,7 条新断言全红,其中最后一条正好钉住旧的误诊:

✗ a root that resolves but yields nothing is red: expected true, got false
✗ the failure names the empty root: expected "tools", got "(none)"
✗ a scan that finds nothing at all is red, not a vacuous "no duplicates": expected true, got false
✗ the zero total is reported: expected 0, got -1
✗ the empty scan is reported instead of a misleading delegator verdict:
    expected null, got ["Delegator missing: packages/rest/src/rest-server.ts", ...]

验证

pnpm check:authz-resolver          # CI 用的正是这条(lint.yml:178)
✓ check-single-authz-resolver self-test: ... 全部成立
✓ check:authz-resolver: single shared authorization resolver intact; both entry points delegate.

npx eslint scripts/check-single-authz-resolver.mjs   # 干净
node scripts/check-nul-bytes.mjs                     # OK,5780 个文件无裸控制字节

现状实跑绿 —— 新下限对真实语料不误报。

备注

  • 改动面仅 scripts/check-single-authz-resolver.mjs 一个文件;scripts/*.mjs 不在任何 tsconfig 的 include 内、也没有对应 vitest 套件,该脚本的 --self-test 模式就是它的测试载体,且 CI 已在跑(pnpm check:authz-resolver 同时跑 self-test 和实检),故本 PR 没有独立的 pnpm test / pnpm typecheck 产出可报。
  • scripts-only、不发版,故打 skip-changeset、不提交空 changeset。

Generated by Claude Code

…#5916)

`collectScanFiles` 先 `assertRootsResolvable`(#4930),但 `out` 长度从不断言:
根还在、可读、走完一个 `.ts` 都没收到时,检查 (1) 遍历空集合、零 error,
"不存在重复解析器" 就这样从零文件里得出。

照 #4932 给 `check-doc-authoring.mjs` 的 `EmptyRootError` 体例复用形状:
按根统计,任一声明的根产出 0 个文件即抛错并按名报红;下限由本次 walk 现算,
不引入需要维护的高水位棘轮;按根而非按总数,避免一个有货的根替蒸发掉的兄弟根打掩护。

self-test 三向钉死:单根为空(红且只点名该根、并报出另一根仍扫到的总数)、
全空(红且总数 0、且报的是空扫描而非误导性的 "Delegator missing")、恢复(绿)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BDmDsu2575gDxeMCxXhDE3
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 6, 2026 3:50pm

Request Review

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

Labels

skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

check-single-authz-resolver 的扫描语料没有下限断言:根解析成功但一个文件都没扫到仍然绿(observation)

2 participants