Skip to content

ci(dx): TEST_DEBT 的隐藏测试文件数改由闸门实时导出,删掉手写 tests 字段 (#5826) - #6196

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-5826-test-debt-tests-derived
Aug 7, 2026
Merged

ci(dx): TEST_DEBT 的隐藏测试文件数改由闸门实时导出,删掉手写 tests 字段 (#5826)#6196
os-zhuang merged 1 commit into
mainfrom
claude/issue-5826-test-debt-tests-derived

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #5826

做了什么

TEST_DEBT 每条条目有两个手写数字。#5278 / PR #5827errors 装上了真棘轮(每次 --re-measure 重跑 tsc --noEmit,实测 > 记录即红),tests 没有——而 tests(被 tsconfig 排除、因而对 tsc 隐形的测试文件数)恰恰是这个脚本每次运行都已经算出来的量testCoverage() 返回的 pkg.testFiles,亚秒级、不需要编译器,evaluate() 里就在用它判 TESTS_COVERED。

两个数字需要相反的修法,这也是它们是两单的原因:errors 不跑编译器就不可知,所以「冻结 + 重测」是它唯一可用的形状;文件数是免费的,所以正确的修法是删掉副本、直接读活数(issue 的选项 1,也是本文件自己在 #5286 毕业 packages/spec 时就写下过的结论)。

  • 19 条 TEST_DEBT 条目的 tests 字段全部删除。 errors 值与 note 一律未动,包括 ci(dx): DEBT/TEST_DEBT 台账数字改为每次重测的真棘轮 —— 实测 > 记录即红 (#5278) #5827 新增的五条 Option A 记档余量(objectql 355 / rest 163 / lint 42 / service-storage 52 / mcp 63)及其 note。
  • 摘要行改为实时导出:新增纯函数 hiddenTestFiles(packages, TEST_DEBT),按包求和本次扫描得到的 pkg.testFiles。输出从「N files」变为「N files hidden as counted by this run」。
  • RECONCILED 增一条:TEST_DEBT 条目再带 tests 字段即红。这是结构性拒绝,哪怕今天的数值恰好正确——见下。
  • note 散文同样去重:四条 note 复述了闸门现在实时导出的文件总数(plugin-security「across 35 test files rather than 34」、service-sms「across 5 test files rather than 3」、mcp「file count moved 8 -> 9」、objectql「file count went 87 -> 127」)。这是同一个「两个事实源」缺陷下沉一层,改成保留事件(哪个 PR 加了哪个文件、文件数动了而错误数没动)、不再留数字副本。
  • 台账顶部注释重写:说明为什么 errors 记、文件数不记,以及这两者需要相反的修法。

为什么不是「加一条对账」

新增的检查在数值一致时也拒绝(self-test 里那条 fixture 写的就是 tests: 7testFiles: 7)。理由是:一致只是「写下那一刻」的属性,不是这个字段的属性;改成「不一致才红」会把「新增一个干净的测试文件」变成一次记账费,而 #5278 的裁决明确排除了这个方向(改善不得制造记账 churn)。删字段 + 结构性拒绝,是唯一按构造消除漂移、且代码比现状更少的选项。

漂移实测(issue 正文的表已过期,这里是本分支上重量的)

#5827 昨夜(约 03:5xZ)刚把 12 个漂移的 tests 刷成实测值。今天在 origin/main @ 80f7dc6a3 上重量,19 条里已有 3 条重新漂移

#5827 记录 本次实算
@objectstack/objectql 130 135 +5
@objectstack/runtime 102 105 +3
@objectstack/formula 16 17 +1
合计(19 条) 534 543 +9

(三个数字都用 find packages/formula/src packages/runtime/src packages/objectql/src -name '*.test.ts' -o -name '*.spec.ts' | wc -l(逐包)独立复核过:17 / 105 / 135,与闸门实算一致。objectql 的 +5 来自 #6158 / #6165 / #6171 等本窗口新增的测试文件。)

也就是说:一次「刷新副本」的有效期,就是到下一个测试文件落地为止——这正是本单的论点,与今天差值是不是 0 无关。

反向验证(方向为先声明后运行:应当变红)

把删掉的字段原样放回一条条目(objectql tests: 130),闸门必须红;这是新检查不是幽灵检查的证明。

$ node scripts/check-type-check-coverage.mjs        # 放回 tests: 130 之后
check-type-check-coverage: 1 problem(s)

  • @objectstack/objectql: TEST_DEBT entry carries a hand-written `tests` count -- that number is
    DERIVED from this run's own scan ... Delete the field; the summary reports the live count (#5826).
exit=1

移除后立刻恢复绿。摘要总数在两种状态下都是 543——即恢复的副本不再参与任何计算,这是「删掉副本」而非「换个地方读副本」的证据。

验证

$ node scripts/check-type-check-coverage.mjs --self-test
✓ check:type-check-coverage --self-test — 23 semantic case(s) + 16 observation case(s) + 11 re-measure case(s) hold.

$ node scripts/check-type-check-coverage.mjs
check-type-check-coverage: OK — 62/77 workspace packages type-checked (plus the root), 15 in the DEBT
ledger (457 frozen raw errors, ...), 1 exempt.
  test layer: 19 package(s) still exclude their own tests (543 files hidden as counted by this run,
  1648 frozen raw errors in TEST_DEBT).

$ flock /tmp/os-heavy-verify.lock -c 'pnpm exec turbo run build --filter=./packages/* --filter=./packages/*/*'
 Tasks:    70 successful, 70 total

$ flock /tmp/os-heavy-verify.lock -c 'pnpm check:type-check-debt'     # 完整 --re-measure
  ℹ @objectstack/service-storage: DEBT records 52, tsc now reports 42 (-10) -- the entry can be lowered.
  ℹ @objectstack/objectql: TEST_DEBT records 355, tsc now reports 344 (-11) -- ...
  ℹ @objectstack/rest: TEST_DEBT records 163, tsc now reports 153 (-10) -- ...
  ℹ @objectstack/mcp: TEST_DEBT records 63, tsc now reports 53 (-10) -- ...
  ℹ @objectstack/lint: TEST_DEBT records 42, tsc now reports 32 (-10) -- ...
check-type-check-coverage --re-measure: OK — 34 ledger entr(ies) re-measured in 223.3s, 2054 raw tsc
error(s) total, none above its recorded number.

$ pnpm exec eslint scripts/check-type-check-coverage.mjs        # 无输出
$ node scripts/check-nul-bytes.mjs
check-nul-bytes: OK (scanned 5920 tracked text file(s); ... no raw ASCII control bytes).

五条 ℹ ... can be lowered#5827 记档余量的既有输出(本 PR 未动那些 errors 与 note),不是本 PR 引入的。

新增/更新的 self-test 用例

语义层 1 条:

  • a TEST_DEBT entry that writes the derived file count down fails, even when it is right today —— 副本与实算相等(7 对 7)仍拒绝,钉死「结构性拒绝,不是对账」。

observation 层 5 条(hiddenTestFiles):总数取自活扫描;台账外的包不计入;同一份台账、多一个测试文件、总数自动跟随(本单要消除的漂移,钉成正向断言);条目指向不存在的包时计 0 而不抛;未扫描到的包读作 0 而不是 NaN。

另有 3 条既有 fixture 去掉了 tests 键。

发布面

scripts/ 只在仓库根,根 package 是 private: true,不在任何包的 files 白名单里——本 PR 不发布任何东西,故走 skip-changeset 标签而非 changeset(#6059 已禁止空 frontmatter changeset,所以只能二选一)。

范围

只改 scripts/check-type-check-coverage.mjs。未碰任何包的源码 / tsconfig / typecheck 脚本(不做毕业),未碰 packages/spec/scripts/**,未碰 content/docs/releases/,未改动任何 errors 数值或其 note。

🤖 Generated with Claude Code

https://claude.ai/code/session_014wsZeReNTqiceBfLb5Pyf5


Generated by Claude Code

TEST_DEBT 每条有两个手写数字。#5278 / PR #5827 给 `errors` 装上了真棘轮
(每次 --re-measure 重跑 tsc,实测 > 记录即红),`tests` 没有——而
`tests`(被 tsconfig 排除、因而对 tsc 隐形的测试文件数)恰恰是这个脚本
每次运行都已经算出来的量:`testCoverage()` 返回的 `pkg.testFiles`,
亚秒级、无需编译器,`evaluate()` 里就在用它判 TESTS_COVERED。

两个数字需要相反的修法,所以是两单:`errors` 不跑编译器就不可知,冻结 +
重测是唯一形状;文件数是免费的,所以删掉副本、直接读活数。

- 19 条 TEST_DEBT 条目的 `tests` 字段全部删除;`errors` 值与 note 一律未动
  (含 #5827 的五条 Option A 记档余量)。
- 摘要行的「隐藏了多少文件」改读新函数 `hiddenTestFiles(packages, TEST_DEBT)`,
  按包求和 `pkg.testFiles`,本次运行实算。
- RECONCILED 增一条:TEST_DEBT 条目再带 `tests` 字段即红——**结构性拒绝**,
  哪怕今天数值恰好对。改成「不一致才红」会把「新增一个干净的测试文件」变成
  记账费,正是 #5278 裁决里排除的方向。
- note 里复述文件总数的散文同样去重(plugin-security / service-sms / mcp /
  objectql):闸门实时导出的数字不再在散文里留第二份副本,事件(哪个 PR 加了
  哪个文件)保留。
- --self-test 新增 1 条语义用例 + 5 条 observation 用例,共 23 + 16 + 11。

漂移实测(本 PR 分支,origin/main @ 80f7dc6):#5827 昨夜刚把 12 个 `tests`
刷成实测值,今天已有 3 条重新漂移——objectql 130→135、runtime 102→105、
formula 16→17,合计 534 vs 实算 543。机制未变时,刷新只在下一个测试文件落地
前有效。

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

vercel Bot commented Aug 7, 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 7, 2026 10:30am

Request Review

@os-zhuang os-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 7, 2026 — with Claude
@github-actions github-actions Bot added the size/m label Aug 7, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review August 7, 2026 10:39
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit a38ba08 Aug 7, 2026
24 of 25 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-5826-test-debt-tests-derived branch August 7, 2026 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

2 participants