Skip to content

packages/qa/dogfood 的 tsconfig 没人跑 —— 14 个类型错误积在一个「声明了但未执行」的门后面 #4855

Closed

Description

@os-zhuang

发现于 #4700 的收尾验证(顺手跑了一次 tsc --noEmit),与那条 issue 无关,按 Prime Directive #10 单独归档,未在 #4700 的 PR 里修。

现象

packages/qa/dogfood/tsconfig.json 是一份认真的配置 —— strict: true、module/moduleResolution: NodeNext、include: ["src/**/*", "test/**/*"]。但 packages/qa/dogfood/package.json 的 scripts 只有 test:

包 scripts
packages/qa/dogfood test
packages/qa/downstream-contract typecheck, test
packages/qa/http-conformance test, typecheck

根 pnpm typecheck 是 turbo run typecheck,只会跑声明了该 script 的包。于是 dogfood 这份 tsconfig 从来没有被执行过 —— 三个 qa 包里唯一漏掉的一个。

积下来的量

$ cd packages/qa/dogfood && npx tsc --noEmit 2>&1 | grep -c "error TS"
14

分三类:

  1. NodeNext 缺扩展名(2 处) —— field-zoo-roundtrip.dogfood.test.ts:24 与 field-zoo-value-shape.test.ts:17 都写 from './field-zoo.matrix'。文件确实在(test/field-zoo.matrix.ts),但 moduleResolution: NodeNext 要求 './field-zoo.matrix.js',所以报 TS2307: Cannot find module。vitest 能跑,tsc 不认。
  2. fixture 里的 flow type 没收窄(多处) —— test/fixtures/flow-durable-suspend-fixture.ts:103、flow-function-effect-fixture.ts:71 等,对象字面量推成 type: string,赋给 flow 那个字面量联合(api | schedule | autolaunched | screen | record_change)时失败。加 as const 或显式标注即可。
  3. 条件展开出的 headers 类型(2 处) —— attachments-permission-matrix.dogfood.test.ts:67,81,token ? { Authorization } : {} 展开后与 HeadersInit 不兼容。

为什么值得记一笔

这就是「declared ≠ enforced」在构建配置层的形状:一份 strict 的 tsconfig 摆在那里,读代码的人(和写代码的 agent)会合理地假设它在 CI 里把关,于是照着它的严格度写;实际上没有任何一步跑它。dogfood 是这个仓最重的行为门,它的 fixture 类型漂移没有任何东西会挡。而且它是可修的:14 个错误都是机械性的,没有一个需要架构决定。

建议

  1. 先把这 14 个修掉(三类都是小改)。
  2. 给 packages/qa/dogfood/package.json 加 "typecheck": "tsc --noEmit",让它进 turbo run typecheck 的图 —— 与两个 sibling qa 包一致。
  3. 顺序不能反:先加 script 会直接把 typecheck 作业弄红。

如果结论是「dogfood 故意不做类型检查」,那么该删的是这份 tsconfig(或把它降到非 strict),而不是让一份没人执行的严格配置继续留在那里误导人。

Refs: #4700(发现处)、Prime Directive #10

Activity

  1. added
    bugSomething isn't working
    pm:queueReady for the PM dispatch loop
    on Aug 3, 2026
  2. added
    domain:devxDomain lane — seat card indexed by label:pm:seat
    on Aug 3, 2026
  3. xuyushun441-sys commented on Aug 3, 2026

    @xuyushun441-sys
    Collaborator

    认领(PM 分派)

    • session:session_018iARDqtrhQgz6fVHDeDkbQ
    • 分支:claude/issue-4855-dogfood-typecheck-wired
    • 车道:domain:devx(落点 packages/qa/dogfood)

    阻塞解除:#4719 的 PR #4999 已过审进队(动了同包的 enterprise-organizations 测试),从最新 main 开分支即可。本单形状与全会话主线一致:strict tsconfig 声明了、没有 typecheck script 执行它 —— declared ≠ enforced,14 个类型错误积在门外。


    Generated by Claude Code

  4. xuyushun441-sys commented on Aug 3, 2026

    @xuyushun441-sys
    Collaborator

    审核通过 — PR #5002 已取消草稿并挂上 auto-merge(SQUASH)

    议题前提被更正,而更正后的事实比原指控更有说服力:check-type-check-coverage 的门禁不是没看见这个包 —— 它把 dogfood 记成了 DEBT(12),COVERED 不变量被"有台账条目"这条分支满足。真实的发现是:台账在 3 天里从 12 漂到 14 —— 用一条记录顶替一次执行,记录就会漂,这正是毕业(修完 + 接线 + 同 PR 删台账条目)而非重测计数的论据。dev 走的正是台账自己文档写明的毕业路径,COVERED / RECONCILED 两条不变量都不违反。覆盖率 60/77 → 61/77。

    14 个错误里挖出一个真契约缺陷(议题的三类机械分类漏了它):测试用 handler!({}) 冒充引擎派发,而引擎总是传两个参数 —— 只因这个 MCP handler 恰好忽略 ctx 才一直没炸。修在调用点(补第二参)而不是把生产者的 ctx 放宽成可选 —— 方向对:contract-first,不为测试的便利松动生产契约。

    : Flow 优于议题建议的 as const,理由是本质性的:as const 只让报错闭嘴,类型标注让整个 fixture 对着 spec 的真实 schema 被检查 —— 反向验证的 sabotage(塞非法 type 字面量)之所以能被抓到,全靠这一点。而且标注后零额外报错,证明 fixtures 一直结构合法,只是 type 字面量此前不受约束。

    恢复证明用了 turbo 的缓存哈希:revert 后 cache hit, replaying logs 238d29ba02f83710,与注入前的绿运行哈希逐字相同 —— 精确态恢复,不是陈旧缓存的假绿。这个证法值得推广。

    共享文件:scripts/check-type-check-coverage.mjs 删 4 行台账(毕业要求),零冲突面。

    留给维护者的一条观察(dev 提出,不立单):DEBT 机制的固有漂移(3 天 +2)说明冻结数字的台账需要一个"重测对账"的节拍,否则每个 DEBT 条目都在静默过期 —— 若哪天有人想做,check-type-check-coverage 的 self-test 是现成的挂点。


    Generated by Claude Code

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

Metadata

Metadata

Labels

bugSomething isn't workingdomain:devxDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpm: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