fix(scripts): check-single-authz-resolver 的 walk 收 .mts/.cts,排除项同族扩展 (#6070) - #6282
Conversation
…6070) `'x.mts'.endsWith('.ts')` is false — the character before `ts` is `m`, not `.` — so the collector walked past every `.mts`/`.cts` source under the declared scan root `packages/`. Check (1) concluded "no duplicate request-context resolver exists" from a corpus that structurally excluded 12 files. Neither existing corpus assertion can see this: the root resolves (#4930) and yields well over a thousand `.ts` files, far above the per-root floor of one (#5916). A floor answers "did this root produce anything", never "did it produce everything it declares". - walk() now filters on an extension FAMILY: SCANNED_EXT /\.[mc]?ts$/ minus EXCLUDED_EXT /\.(?:test|d)\.[mc]?ts$/, so the test/declaration exclusions widen in the same step — widening only the collector would re-plant the same bug one level down (`x.test.mts` scannable while `x.test.ts` is not). The repo has none of those four shapes today; they are excluded anyway. - Corpus 1475 -> 1487 files (+12, all `packages/spec/scripts/**`). None trips check (1)'s heuristic, so the real run stays green — what changes is that the verdict is now drawn from what the gate says it reads. - Self-test pins both directions: the corpus must GROW by exactly the collectable fixtures, AND the duplicates written in `.mts`/`.cts` must be caught and named. Either alone is satisfiable by a filter that collects nothing. Also writes the `.d.ts` fixture that assertion's label has claimed since it was written. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BDmDsu2575gDxeMCxXhDE3
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
施工中量到一条范围外的发现,按 Prime Directive #10 已单独立案,不在本 PR 修: #6286 —— 本门禁检查 (1) 的判据词表已被 ADR-0090 D3 改名废掉: 两者的关系,一句话:#6070 / 本 PR 治的是「语料」(读了什么),#6286 治的是「判据」(拿什么判)。本 PR 把语料从 1475 补到 1487;判据词表在放宽前后都一样匹配不到东西,所以本 PR 的"现状仍绿"是真绿,只是这个绿现在有了第二重原因 —— 那重原因归 #6286。刻意不并单:改判据必然改裁决(直接换成 另:本 PR 首个( Generated by Claude Code |
Fixes #6070
'x.mts'.endsWith('.ts')为 false(ts前一个字符是m而非.),所以walk()从来没收过声明的扫描根packages/下的任何.mts/.cts。检查 (1)「不存在重复的请求上下文解析器」这个结论,是在一个结构性排除了 12 个文件的语料上得出的。按 issue 方向 1(声明即执行)修:门禁声称读遍
packages/,那就该真的读遍。过滤器 before / after
单文件改动
scripts/check-single-authz-resolver.mjs,walk()的收集条件:排除项与收集项同一步放宽,这是刻意的:只放宽收集器会把同一个 bug 原样种到下一层 ——
x.test.mts变成可扫描,而x.test.ts不是。仓内今天没有这四种形状(.test.mts/.test.cts/.d.mts/.d.cts实测各 0 个),仍然照排 —— 排除项陈述的是"一个测试/声明文件是什么",不是"现存哪些文件"的清单。语料 delta:1475 → 1487(+12)
用脚本自己的
collectScanFiles实测(把main();换成一行计数打印,分别跑改前/改后两版):新增的正是那 12 个文件,全部在
packages/spec/scripts/下(check-strictness-ledger.mts、liveness/*.mts等)。packages/下.ts文件的原始个数(本 PR 基点f6609e6实测:全量 3113、去掉dist/__tests__/后 3029),而 1475 是门禁真正推理的语料(再去掉.test.ts/.d.ts)。两个数都对,量的是不同集合;+12 这个差值两种口径一致,也是本单唯一实际变化的量。现状仍绿(复测,非沿用分诊结论)
12 个新入语料的文件对启发式(
sys_user_role且sys_user_permission_set)的命中数逐个复测 = 0/0,放宽后真实运行仍绿:语料变大不改变任何裁决;改变的是这个裁决从此出自门禁声称读的那个集合。
self-test delta:双向都钉,单向都不够
新增块(沿用 #6056 的 fixture idiom,真实临时目录 + 真实 walker):
.mts与.cts各写一个重复解析器形状 ⇒ 必须被抓出且按名报出(2 条,逐条断言文件名);x.test.mts/x.test.cts/x.d.mts/x.d.cts四个形状 ⇒ 不得进语料;collectScanFiles必须恰好beforeExt + 2,清理后必须回到beforeExt。第三条不是冗余:只断言"被抓出"的话,一个收不到任何文件的过滤器同样产生 0 条错误 —— 那正是原始漏判之所以静默的原因;只断言计数的话,又证不出抓出来的错误指向正确的文件。两条都要,才封得住。
顺带补齐一处既有断言的空头支票:
'tests, .d.ts and dist/ are out of scope'这个 label 从写下起就宣称覆盖.d.ts,但从来没写过.d.tsfixture —— 本 PR 把它补上(与本次扩到同族排除是同一件事)。反向验证(方向先声明后运行)
声明的预期方向 = 常规 red:把
walk()的过滤器还原成.ts-only、保留全部新断言,则 4 条新断言必须转红,且红必须指名漏掉了什么;既有断言(含新补的.d.ts)不受影响。实跑(在 scratchpad 的脚本副本上,不污染工作树):
与声明逐条相符:语料 7 → 5(两个模块扩展名文件根本没被收),诊断数 2 → 0。恢复过滤器 ⇒ self-test 与真实运行双绿(上一节输出)。红只出在 4 条新断言上,说明红确由过滤器本身引起,而非别的改动。
范围
严格按分诊钉死的范围:只改扩展名过滤 + 回归断言。未动
SCAN_ROOTS、未重写 #5916 的下限断言逻辑、未搭高水位棘轮(维护者在 #5916 已明确否掉)。#5475(那 12 个文件不在任何 tsconfig 的 include 内)是类型检查覆盖的另一套机制,仅交叉链接,不并单。改动仅
scripts/单文件,不发布任何东西 ⇒ 无 changeset,带skip-changeset。门禁pnpm check:authz-resolver在 CI 的 ESLint job(lint.yml的 "Single authz resolver guard" 步)内跑。相关:#5916 / PR #6056(按根下限)、#4930 / #4916(死根按名报错)、#4932(同族先例)、#4690(「提取失败必须红」出处)。
Generated by Claude Code