ci(typecheck): every package type-checks or is ledgered — the tsup hole becomes a ratchet (#4311) - #4324
Conversation
…le becomes a ratchet (#4311) 66 of 77 workspace packages build with tsup (esbuild transpile, no type check), vitest never type-checks, and the CI typecheck job covered four targets — so for most packages nothing read src/ or the tests with tsc at all. #4311 measured the hole: 380 code-tier errors across 18 packages, 241 of them driver-sql tests feeding authored-shape literals into the freshly narrowed QueryAST. Re-measured per-package `tsc --noEmit` on main @ e5a4d26; aggregates match the issue exactly (48 clean / 29 failing / 1 no-tsconfig): - The 48 clean packages (42 new scripts + 6 pre-existing) now declare `typecheck`, run by a new `turbo run typecheck` task (dependsOn ^build) wired into lint.yml's typecheck job after the workspace build. The clean set is locked against regression from today. - The 29 failing ones (858 raw errors) are frozen in a DEBT ledger in scripts/check-type-check-coverage.mjs, each entry carrying its measured count and the issue's code/config/noise triage so a config-tier pile (types: 107, core: 91-with-3-real) is never mistaken for real breakage or the reverse (driver-sql: 241, all real). @objectstack/console is EXEMPT: no TypeScript sources. - The coverage gate (self-tested, reconciled in both directions) fails when a package is neither covered nor ledgered, when a ledger entry goes stale, or when the turbo task / root aggregator / CI step is deleted — the ledger can only shrink. Root `pnpm typecheck` aggregates the task locally; AGENTS.md documents the ratchet. Empty changeset: dev scripts and CI only, releases nothing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011m13wbaZziPveBdtQthrXd
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 41 package(s): 130 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…ackages were hiding their tests (#4311) (#4348) #4324 counted a package covered the moment it declared a `typecheck` script. But `tsc --noEmit` reads the package's own tsconfig.json, and 27 of the 48 packages that gate waved through `exclude` `**/*.test.ts` from exactly that file — so COVERED and REAL both passed while nothing read the test layer, which is the source #4311 is actually about. Measured by lifting each exclusion and re-running the package's own config: 568 test files, 1451 errors, behind a green check. `spec` alone hid 902 across 272 files; `plugin-approvals` hid 467, more than driver-sql's 241, with a clean src. What changed: 1. New TESTS_COVERED invariant + TEST_DEBT ledger in scripts/check-type-check-coverage.mjs. A package that excludes its own tests must carry a measured entry; RECONCILED runs both ways, so dropping the exclusion without deleting the entry fails, and so does the reverse. Test files are counted under the tsconfig's `include` roots — `exclude` only subtracts from what `include` selected, and several packages keep a sibling `test/` tree that `include` never mentions. Six new self-test cases (18 total). The summary line now prints both layers: reporting only the src figure is how 48/77 read as green over 568 unchecked files. 2. Nine packages that were already clean with tests included had the exclusion deleted outright: sdui-parser, plugin-audit, plugin-email, plugin-hono-server, plugin-pinyin-search, plugin-reports, trigger-api, trigger-schedule, connector-slack. 3. 44 relative imports repaired to carry the `.js` extension NodeNext requires. This was filed as config-tier noise and is not: an unresolved import degrades every symbol it names to `any`, and the callbacks over those symbols then report TS7006 "implicitly any". The 44 fixes closed 110 errors across eight packages — and exposed 12 real defects in service-settings (manifest action handlers called without `namespace`/`actionId`) that the broken imports had been masking. Its ledger entry said "no code-tier finding"; it was wrong in both directions, and now says so. 4. Nine packages graduate out of DEBT (types, create-objectstack, service-cache, service-i18n, service-job, service-messaging, service-queue, service-realtime, plugin-approvals). Three tsconfig repairs: `types:["node"]` for types (107 errors, one line), `exclude: src/templates` for create-objectstack (scaffolding copied verbatim by tsup, whose imports resolve in the generated project, not this one), `lib: ES2021` for plugin-approvals (String.replaceAll). plugin-approvals graduates on src only and carries a TEST_DEBT entry — its 13 test files are still excluded. Coverage: 48/77 -> 57/77 src-covered; DEBT 29 -> 20 entries (679 raw errors); TEST_DEBT 21 entries (652 files, 2243 raw errors) newly visible. No non-test source file changes. Verified: self-test 18/18, coverage gate, `turbo run typecheck` 119/119, `pnpm test` 132/132, eslint, check:published-files. Claude-Session: https://claude.ai/code/session_011m13wbaZziPveBdtQthrXd Co-authored-by: Claude <noreply@anthropic.com>
落地 #4311 的建议 1(覆盖率棘轮,先接入已干净的包)。不动任何 src——纯管线改动,零修复成本,立刻锁死回归。
实测(main @ e5a4d26,即 issue 审计后一个 commit)
逐包
cd && tsc --noEmit(与 issue 同方法),聚合结果与 issue 完全一致:48 干净 / 29 失败 / 1 无 tsconfig(console)。issue 指认的 18 个含 code-tier 错误的包全部在 29 之内;另 11 个仅 config-tier/noise。原始错误合计 858。改了什么
scripts/check-type-check-coverage.mjs(新,进 CI) —— 声明式覆盖棘轮,对齐 objectui 侧同名 gate 的治理形态(声明式、带理由、只减不增),结构仿check-published-files.mjs:typecheckscript,要么在脚本内置的 DEBT(实测错误数 + note)/ EXEMPT(理由)台账里。新包必须以覆盖状态进场,台账只能变短。typecheckscript 必须真的调 tsc。typecheck任务、根typecheck必须聚合它、lint.yml 必须执行它(check:generated 台账缺check:variant-docs分类——#4177 落地后本地 wrapper 在 main 上直接红 #4203 的教训:只在本地跑的 gate 会烂掉)。--self-test(12 个语义用例),先自测后运行(仓库惯例)。"typecheck": "tsc --noEmit"(加上已有的 6 个 = 48 覆盖);turbo run typecheck任务(dependsOn: ^build,tsc 经各依赖的dist/*.d.ts解析 workspace 导入)。turbo run typecheck --filter='./packages/*' --filter='./packages/*/*' --filter='./apps/*'(裸./packages/*只匹配直接子目录,见 build 步注释;examples 与 downstream-contract 保留各自的专用步骤——它们是语义不同的 gate)。本地已全量验证:105 tasks successful。types(107,全 config)/core(91,仅 3 真错)误读成重灾区、或把driver-sql(241,全真错)误读成配置问题。pnpm typecheck与棘轮说明;空 changeset(仿 fix(dx): per-package lint scripts stop existing where they can only mislead (#4276) #4304:dev scripts + CI,不发版)。没做什么(仍归 #4311)
driver-sql241 独占 63%,单一 playbook,适合单独集中修)。tsconfig.test.json统一消 288 处)。noImplicitAny决策(issue 明确要求单独拍板)。包毕业路径:修完错 → 加
typecheckscript → 同一 PR 删台账条目(删漏/删多都会被 gate 拦下)。本地验证:覆盖 gate + self-test ✅;
turbo run typecheck(CI 同命令)105/105 ✅;lint.yml YAML ✅;check:generated --reconcile-only✅;changeset gates ✅;eslint(新脚本)✅。Closes 部分不写——本 PR 不关闭 #4311(code-tier 修复与 config 模板仍开放),只落地其建议 1。
🤖 Generated with Claude Code
https://claude.ai/code/session_011m13wbaZziPveBdtQthrXd
Generated by Claude Code