Skip to content

packages/spec/scripts/** 在任何 tsconfig 的 include 之外:9 个 vitest 测试文件 + 全部构建/gate 脚本无类型检查覆盖 #5475

Closed

Description

@os-zhuang

在 #5286(spec 测试层进 tsc)的实施中发现,记录备查,未认领。基线 origin/main @ 01c0baef9。

事实

packages/spec/tsconfig.json 的 include 是 ["src/**/*"],tsconfig.test.json(#5286 新增)同样只到 src。于是整个 packages/spec/scripts/** 不在该包任何 tsconfig 的 program 里——既不是「被 exclude 排除」,而是压根没被 include 选进来,所以连 check:type-check-coverage 的 TESTS_COVERED 都数不到它(该不变式只统计 include 根之下的测试文件)。

这批文件不是死代码:

  • vitest.config.ts 的 include 含 scripts/**/*.test.ts,共 9 个测试文件在 pnpm test 里真的跑;
  • 其余是 gen:schema / gen:openapi / check:liveness / check:strictness-ledger 等 20 多个 CI gate 脚本本体。

也就是说:这些脚本决定 spec 的生成物和多条 gate 的判定,却没有任何类型检查器读过它们。这正是 #4311 的缺陷类别,只是下沉了一层(#4311 关心「包级 tsc 覆盖」,#5286 关心「测试层被 exclude」,本单是第三种形态:根本不在 include 里)。

实测

把 scripts/**/* 并进 #5286 的 tsconfig.test.json(需同时把继承来的 rootDir: "./src" 放宽到 ".",因为 scripts/ 在 src/ 之外)后:

16 个文件 / 33 条错误

分层:

层 数量 说明
config-tier TS5097 x13 .mts 后缀 import,需要 allowImportingTsExtensions
config-tier TS2593/TS2304 x2 scripts/build-schemas-check-mode.test.ts 用了全局 beforeEach/afterEach,需 vitest 类型
config-tier TS7016 x1 check-generated.ts import 仓库根的 .mjs 无声明文件
code-tier TS2339 x5 + TS7006 x1 scripts/build-schemas.ts:1208-1228 —— 一串 Property 'keys'/'rev' does not exist on type 'never',某个值被推成 never 后仍在被取属性
noise TS6133 x7 未使用的局部/导入(build-docs.ts x4、build-openapi.ts、generate-sbom.ts)
code-tier? TS7006 x1 check-liveness.mts:618 隐式 any 参数

按 AGENTS.md 已写下的纪律:先修 config 层再读残差,build-schemas.ts 那堆 never 才是真正要看的东西——而 build-schemas.ts 是 gen:schema 的本体,spec 全部 JSON Schema 由它产出。

与 #5286 的边界

#5286 的 PR 明确把这块排除在外并在 tsconfig.test.json 的注释里写明了理由(不夹带 riders)。同时确认:scripts/** 里没有任何 @ts-expect-error,所以 #5286 新增的 PINS_CHECKED 不变式不受影响——这里藏的不是幽灵 pin,是没被检查的生成器。

建议方向(未定,交 triage)

  1. 把 scripts/**/* 并入 tsconfig.test.json(rootDir 放宽 + allowImportingTsExtensions + types 补 vitest),把 config-tier 一次修掉,code-tier 的 6 条按 @ts-expect-error 退役 pin 在 packages/spec 里是幽灵检查:tsconfig 把 **/*.test.ts 排除出唯一的 tsc --noEmit #5286 的每文件台账 packages/spec/test-typecheck-debt.json 收口或直接修完;或
  2. 给 scripts/ 单开一份 tsconfig,由 typecheck 脚本链一并指名(@ts-expect-error 退役 pin 在 packages/spec 里是幽灵检查:tsconfig 把 **/*.test.ts 排除出唯一的 tsc --noEmit #5286 改造后的 TESTS_COVERED 已经支持 sibling 配置被指名即算覆盖)。

两条路都会让 check:type-check-coverage 继续通过;差别只在 program 边界怎么切。

关联:#5286、#4311、AGENTS.md「Build & Test」段的 typecheck 覆盖纪律。

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 5, 2026
  2. added
    domain:specDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 6, 2026
  3. claude commented on Aug 6, 2026

    @claude
    Contributor

    发现分诊轮判级(#4949 纪律):晋级 pm:queue,并补域标签 domain:spec(原单无 domain:*,落点在 packages/spec 自己的 tsconfig 与 scripts,按「共享契约面单一所有者」归 spec 座位)。

    过时前提检查:origin/main 889ae47 上 packages/spec/tsconfig.test.json 仍在,且该文件自己的注释就是本单的确证 —— 原文写着 "include deliberately stops at src, matching the build config's root. scripts/ holds nine more test files vitest runs and is in no tsconfig at all — a second, differently-shaped hole (measured at 16 files / 33 errors…)"。前提不仅成立,还已被 #5286 的作者在代码里明写为已知待补的第二个洞。

    晋级理由:落点唯一(packages/spec/tsconfig.test.json 的 include / rootDir)、工作量已实测量化(16 文件 / 33 错误,并已按 config-tier / 真实类型错误分层)、且它守的是门禁自身的正确性 —— gen:schema / gen:openapi / check:liveness / check:strictness-ledger 等 20 多个决定 spec 生成物与多条 gate 判定的脚本,今天没有任何类型检查器读过。同一失效类的前两种形态(#4311 包级、#5286 测试层)都已收口,本单是第三种(根本不在 include 里),没有理由停在观察态。

    ⚠️ 派发提示:放宽 rootDir 到 "." 是本单的必要动作(scripts/ 在 src/ 之外),但 ⛔ 不得放松任何 strictness 选项 —— 按 tsconfig.test.json 现有注释的原则,「若某个文件编不过,那本身就是发现」。33 条错误里若有需要单独立单的真实类型缺陷,照 PD #10 拆单,不要用 any 抹平。

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


    Generated by Claude Code

  4. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    疑似域误标:本单落点是 packages/spec/scripts/** 的 tsconfig 覆盖(C 包 #5163 文件面即为该目录),不触 packages/spec/src/**/*.zod.ts,建议改标 domain:spec-tooling ——交分诊座位定夺。背景:维护者 2026-08-06 拍板 spec 车道缩盘方案,见 #5837。


    Generated by Claude Code

  5. added and removed
    domain:specDomain lane — seat card indexed by label:pm:seat
    on Aug 6, 2026
  6. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    标签落实(维护者 2026-08-06 指示,session_01LeEfA7CFwbJb7JJmXm2KM3):按 08-06 转席建议执行 domain:spec → domain:spec-tooling(落点 packages/spec/scripts/** tsconfig 覆盖,即 C 包文件面本体)。


    Generated by Claude Code

  7. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    又一个当场付费的实例(#5943 / PR #6049,今天):本单给 packages/spec/scripts/check-skill-examples.ts 加了约 300 行新代码(含 TypeScript compiler API 的 AST 遍历、ts.isSatisfiesExpression / ts.isTypeAssertionExpression 这类版本敏感的窄化判定),而本单没有任何一步能类型检查它 —— pnpm --filter @objectstack/spec typecheck 全绿,因为它跑的 tsc --noEmit 只 include src/**/*;vitest 里那 9 个 scripts/**/*.test.ts 也不覆盖这个文件。tsx 只转译。

    我只能在流程外手动补一趟单文件校验才敢推:

    pnpm exec tsc --ignoreConfig --noEmit --strict --target ES2020 --module commonjs \
      --moduleResolution bundler --esModuleInterop --skipLibCheck --types node --lib ES2020 \
      scripts/check-skill-examples.ts     # 0 error
    

    这一步是我自己想起来做的,不是任何 gate 要求的——本单的下一个人不会知道要做,而这类文件恰恰是判定别的 gate 红绿的本体。补两条对本单选项的观察:

    • --ignoreConfig 是必需的:直接给命令行传文件会先撞 TS5112(tsconfig 存在但因指定了 files 而不加载);
    • 走本单选项 2(给 scripts/ 单开 tsconfig)时注意 moduleResolution: node10 现在会硬报 TS5107(TS 6.0 弃用),得用 bundler 或显式 ignoreDeprecations。

    不改本单结论,只补一条「今天仍在发生、且发生在 gate 脚本本体上」的实测。


    Generated by Claude Code

  8. self-assigned this
    on Aug 7, 2026
  9. os-zhuang commented on Aug 7, 2026

    @os-zhuang
    ContributorAuthor

    认领(claim):os-dev agent,session session_014wsZeReNTqiceBfLb5Pyf5,分支 claude/issue-5475-scripts-typecheck-coverage。

    计划:先在当前 origin/main 上重测错误清单(原单基线 01c0baef9 已过时 —— build-schemas.ts 今天经 #6200 / #6256 / #6309 / #6360 四次改动,原单引用的 build-schemas.ts:1208-1228 行号必然失效),再按「先 config 层、后读残差」的纪律处置,并优先修掉 code-tier 的 never 簇而不是记台账。


    Generated by Claude Code

  10. added a commit that references this issue on Aug 8, 2026
    c24b313
  11. added a commit that references this issue on Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

pm:queueReady for the PM dispatch loop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions