Skip to content

test(objectql): save-meta-response-conformance 删除悬空调试助手并补齐 registerObject 实参 (#5924) - #6431

Merged
baozhoutao merged 2 commits into
mainfrom
claude/issue-5924-test-debug-helper-fix
Aug 7, 2026
Merged

test(objectql): save-meta-response-conformance 删除悬空调试助手并补齐 registerObject 实参 (#5924)#6431
baozhoutao merged 2 commits into
mainfrom
claude/issue-5924-test-debug-helper-fix

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #5924

前提重验(先做,结论:完全成立,四条错误逐字复现)

按「issue 正文是线索不是规格」,先在 origin/main 上把正文三条主张各自证一遍:

主张 复核结果
:119LOG 助手原样仍在 ✅ 一字不差
全文件无 node:fs import、无 OUT 定义、无 LOG( 调用点 grep -n 'LOG|OUT|appendFileSync|node:fs' 只命中 119 行声明本身,零其他命中
该文件在 tsc 排除面上,四条错误对闸门隐形 ✅ 见下

把该包 tsconfig 的 test 排除项抬掉后实测,正文列的四条逐字复现:

packages/objectql/src/save-meta-response-conformance.test.ts(115,21): error TS2554: Expected 2-5 arguments, but got 1.
packages/objectql/src/save-meta-response-conformance.test.ts(119,7): error TS6133: 'LOG' is declared but its value is never read.
packages/objectql/src/save-meta-response-conformance.test.ts(119,30): error TS2304: Cannot find name 'appendFileSync'.
packages/objectql/src/save-meta-response-conformance.test.ts(119,45): error TS2304: Cannot find name 'OUT'.

一处正文笔误更正:正文与分诊都写 packages/objectql/src/tsconfig.json,该路径不存在;真正声明排除项的是 packages/objectql/tsconfig.json(第 4 行)。不影响结论,但下一个照路径去找的人会扑空,所以记一笔。

改动(两处,同一个文件,共 1 加 3 删)

1. 删掉 :119 整行 —— 正文选项 1、分诊背书的修法。它是提交时把 import 和 OUT 常量删了、助手本身留下的残骸:LOG 从未被调用,所以运行时不会抛,该文件的 conformance 断言一直照常执行。它值得修的理由不是「今天红了」,而是它会怎么变成故障 —— 下一个想调试这个用例、顺手取消注释一句 LOG(...) 的人,拿到的是 ReferenceError: appendFileSync is not defined 而不是日志。一个「看起来能用的调试助手」比没有助手更费时间。

2. 补齐 :115registerObject 实参 —— 分诊建议「一并修」的那条独立 TS2554。签名是 registerObject(schema, packageId, namespace?, ownership?, priority?),packageId必填的第二个形参,这里只传了一个实参,运行时实际是把 undefined 喂给一个 string 形参。按仓内既有约定补 'test-package'(protocol-unknown-query-param.test.ts / query-expression-conformance.test.ts 用的就是这个字面量;另有 '__test__' / 'pkg' 两种同类写法)。

为什么 :115 在范围内:派发令给的验收判据是「测试文件自身可被 tsc 检查时零错」。只删 :119 的话该文件还剩一条 TS2554,判据不成立,文件仍是排除面里的常住户,下一次尝试毕业照样绊在这里。两处都在同一个文件内,不越派发令「只动该测试文件」的边界。

验证

tsc 单点验证 —— 本单唯一有意义的类型证据

该文件在排除面上,常规 pnpm typecheck 结构性地看不见它(这正是本单存在的原因),所以类型侧的证据只能来自手工抬掉排除项的单点测量。用的是台账脚本自己的重测配方(同目录兄弟配置 extends 真配置、只去掉 test 排除项 —— tsconfig 的 include / outDir / rootDir 都相对声明它的那个文件解析,放别处会把它们统统改指):

该文件的错误数 @objectstack/objectql 全包
改动前 4 354
改动后 0 350

两次输出 diff 之后恰好只有那四行消失,全包其余诊断一行未动:

390,393d389
< …(115,21): error TS2554: Expected 2-5 arguments, but got 1.
< …(119,7): error TS6133: 'LOG' is declared but its value is never read.
< …(119,30): error TS2304: Cannot find name 'appendFileSync'.
< …(119,45): error TS2304: Cannot find name 'OUT'.

判据达成:该文件被 tsc 检查时零错

反向验证 —— 方向先定后验,且必须说清本单不适用常规方向

常规的「把删掉的肢体装回去,看新钉子转红」在本单不适用,如实写出来而不是硬套模板:本 PR 不新增任何钉子测试,删的是死代码,而死代码的定义就是「没有任何闸门能看见它」。所以预先写下的预期方向是两条,分别可证伪:

  1. tsc 诊断:少 4 条,且只少这 4 条(不是「转红」,是单向减少)—— 已证,见上表与 diff
  2. 测试行为:完全不变(不是「转红」也不是「转绿」)—— 因为 LOG 从未被调用,删它对运行时是恒等变换。

第 2 条用同一棵工作树跑了前后两趟全量(用 git diff 存补丁 + git checkout -- 回退再 git apply 复原,未用 git stash):

Test Files Tests exit
改动前(HEAD 原状) 140 passed (140) 2321 passed (2321) 0
改动后 140 passed (140) 2321 passed (2321) 0

逐字相同 —— 零行为变化落到了实测上,不是断言。

:115 那一处值得单说一句:传 packageId 严格讲一次运行时取值变化(undefined 变成 'test-package')。它在本用例里恒等的理由是可查的:packageId 只被三处读到 —— registerNamespace(namespace, packageId)(仅当 namespace 有值,此处未传)、owner 冲突判定(本用例全程只注册一个对象、只注册一次,冲突分支不可达)、以及 contributor 记录的索引键(本用例不调 unregisterObjectsByPackage)。加上上面前后两趟 2321 全等的实测,认定为行为中性。没有把它写成「零改动」,因为它不是。

其余

  • pnpm --filter @objectstack/objectql typecheckexit 0。但请按其真实含义读:它跑的是带排除项的那份 tsconfig,根本没读到本文件,所以它对本改动的证明力是零,列在这里只为说明没有把包搞坏。
  • pnpm check:type-check-coverageOK,exit 0
  • node scripts/check-nul-bytes.mjs → OK(6063 个跟踪文本文件,无裸控制字节);改动文件另做控制字符自查 grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]',无命中。
  • git merge origin/main(合并干净,零冲突;该窗口 main 未触碰 packages/objectql 一个字节),并在合并树上把上述 tsc 与全量测试各重跑一遍:该文件仍 0 错、全包 350、140 files / 2321 tests 全绿。

台账耦合面:分诊列的那条硬约束已经失效,本 PR 不动台账

分诊评论(8-06)写了一条硬约束:「若 #5827 先落地,本单的 PR 必须在同一提交里下调 scripts/check-type-check-coverage.mjsTEST_DEBT 条目」。#5827 确已先落地(已合并),但该约束的前提在 #5827 自己的落地形态里被取消了,理由两条,都可在 main 上复核:

  1. 棘轮是不对称的ci(dx): DEBT/TEST_DEBT 台账数字改为每次重测的真棘轮 —— 实测 > 记录即红 (#5278) #5827 最终按裁决走选项 A 落地,语义是「实测 大于 记录 → 红;实测 小于 记录 → 只打印一行 ℹ can be lowered,不红」。脚本里写得很直白:"an improvement must not have to pay a bookkeeping toll to land"。本 PR 让数字下降,因此不可能把闸门弄红。
  2. @objectstack/objectql 这条本来就带记档余量。它记 355,是 ci(dx): DEBT/TEST_DEBT 台账数字改为每次重测的真棘轮 —— 实测 > 记录即红 (#5278) #5827 明写的 bootstrap margin(在 77c7c884b 实测 345 之上 +10),而 ci(dx): DEBT/TEST_DEBT 台账数字改为每次重测的真棘轮 —— 实测 > 记录即红 (#5278) #5827 同时把「余量收紧」明确留作落地后的后续小单,不在飞行中做。

⇒ 在同一提交里改台账数字,既非必要(不会红)、也与 #5827 定下的收紧节奏相悖,更越出派发令「只动该测试文件」的边界。因此未碰 scripts/check-type-check-coverage.mjs

顺带留一个给 PM 的读数,它比本单本身更值得看一眼:改动前该条余量只剩 +1(记 355、实测 354),已经贴到红线;本 PR 把实测降到 350,余量回到 +5。也就是说这条余量在无人注意时几乎被吃光了。收紧仍按 #5827 的约定走后续小单,本 PR 不代做。

必答项:该文件为何在排除面、排除面还有多少同类文件

为何:packages/objectql/tsconfig.json:4 声明

"exclude": ["node_modules", "dist", "**/*.test.ts"]

而该包 typecheck 脚本就是裸 tsc --noEmit,读的正是这份配置 —— 于是 tsc 根本不读任何 *.test.ts。这就是 #4311 的缺陷本体(AGENTS.md 的说法:「a green gate over source nothing read」),也正是该包在 scripts/check-type-check-coverage.mjs 里带 TEST_DEBT 条目的原因。配套的另外两层同样看不见它:vitest 只执行不判类型,ESLint 不做跨符号解析。所以两条 TS2304#5861 落地那天起对每一道闸门隐形,直到 #5278 的重测棘轮把数字顶出来。

还有多少同类文件(闸门本次运行的实测口径):

  • 本包:packages/objectql/src140*.test.ts,全部被这一条排除项藏起来。
  • 全仓:check-type-check-coverage 本次运行报 19 个包仍排除自己的测试,共 558 个文件被藏,TEST_DEBT 冻结 1615 条 raw error

只测只报,未顺手修排除面 —— 那是 #4311 台账的事,不是本单的。本 PR 未改任何 tsconfig、未改任何 typecheck 脚本、未做任何包的毕业。

changeset

未写 changeset,判断依据:本 PR 的文件面只有一个 *.test.ts,不发布任何包、不改变任何用户可见行为(上面 2321 全等的前后两趟就是这一点的实测)。仓内现行门禁 scripts/check-empty-changeset.mjs(#5471 / PR #6059)明令新增空 frontmatter changeset 即违规,所以「写一份空的占位」这条路已被堵死,正确走法是 skip-changeset 标签(已在 PR 建好后立刻自行加上,读回确认;详见评论区)。

范围

文件面自始至终只有 packages/objectql/src/save-meta-response-conformance.test.ts 一个文件。未触任何源码、任何 tsconfig、任何 package.jsonscripts/check-type-check-coverage.mjscontent/docs/releases/。未 stash、未 rebase、未 force-push。

范围外发现

无新增。唯二两处偏离既有记录的事实都已就地写在上文,均不构成新缺陷:正文/分诊的 tsconfig 路径笔误(src/ 一级),以及分诊那条台账耦合约束的失效(#5827 落地形态所致)。


Generated by Claude Code

claude added 2 commits August 7, 2026 18:13
…conformance

The `LOG` helper declared at :119 referenced two names that exist nowhere in
the file: `appendFileSync` (never imported from `node:fs`) and `OUT` (never
defined). `LOG` itself was never called, so it never threw at runtime — it was
dead debug scaffolding left behind when its import and constant were dropped.
A debug helper that looks usable but raises `ReferenceError` the moment someone
uncomments a call is worse than no helper at all.

Also passes the required `packageId` argument to `registry.registerObject` at
:115, which was called with one argument against a `(schema, packageId, ...)`
signature. Both defects are invisible to every gate because
`packages/objectql/tsconfig.json` excludes `**/*.test.ts` (#4311), so `tsc`
never reads this file; vitest does not type-check and ESLint does no
cross-symbol resolution.

Fixes #5924

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Q7oc7ASjh8yxyS3Yz78We
@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 6:25pm

Request Review

@baozhoutao baozhoutao added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/xs labels Aug 7, 2026 — with Claude
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

@github-actions github-actions Bot added the tests label Aug 7, 2026
@baozhoutao baozhoutao added the size/xs label Aug 7, 2026 — with Claude

Copy link
Copy Markdown
Contributor Author

标签与 CI 记录(正文「详见评论区」的那一条)

最终标签(读回为准)

size/xs, tests, skip-changeset

Check Changeset 首跑判红 —— 已知竞态,且两侧都有实证

run 事件 Check Changeset
31206842664 opened @ 18:25:03 failure
31206871247 labeled @ 18:25:25 skipped

红的那一跑,其第 2 步「Re-read this PR's labels live」执行于 18:25:09,而我的 skip-changeset 落于 18:25:21 —— 标签比那次实时重读晚 12 秒。这正是 #5580 记下的形状(#5542 是「标签打对了、opened 跑仍判红」的同款先例)。标签之后的每一跑都豁免,labeled 那跑的 skipped 就是豁免生效的直接证据。未重跑 opened 那一跑,按约定把首跑颜色读作信息而非判据。

⚠️ 我自己撞进了 #5649 的开放半边,并已修复 —— 如实记一笔

.github/workflows/pr-automation.yml 顶栏明写了这半边没关上:「a writer OUTSIDE this workflow — an agent or a human labelling the PR seconds after gh pr create — can still land inside a PUT window and be erased」。本次方向是反的:被擦掉的是 bot 的标签,擦它的是我

时间线(全部可在 run 日志核对):

时刻 动作 结果
18:25:09–18:25:11 Add size label(whole-set PUT) 打上 size/xs
18:25:1x 我读回标签 读到空集(该读早于上面那次 PUT 可见)
18:25:21 我 PUT {skip-changeset} size/xs 被擦
18:26:00–18:26:03 Auto Label(whole-set PUT) 快照 {skip-changeset} 并入 tests,我的标签保住,但 size/xs 早已不在

也就是说:「先读回、再写并集」这条纪律我照做了,但读回本身赢了竞态却输了时序 —— 我算并集所依据的那份标签集,在我 PUT 时已经过期。等两个写标签的 job 全部结束(窗口关闭)后,已用并集写回 {tests, skip-changeset, size/xs} 并读回确认,现状即上面那三条。

留给 #5649 的一个可用读数:光靠「读回再写并集」并不能让外部写者安全,因为读与 PUT 之间同样有窗口;真正的修法仍是把写变成 additive 的 POST /issues/{n}/labels(该 issue 自己的结论),这一点本次又被实证了一遍。

其余 CI

CI success;Lint & Type Check 两个 job 全 success —— 其中与本 PR 直接耦合的第 27 步 Re-measure the type-check DEBT / TEST_DEBT ledger 判绿,印证了正文「本 PR 让台账数字下降、不对称棘轮不判红、因此不必也不应在本提交里改台账」的判断。Console Pin Freshness / Duplicate Fix Guard / Docs Drift Check / Check Links 均 success。


Generated by Claude Code

@baozhoutao
baozhoutao marked this pull request as ready for review August 7, 2026 18:45
@baozhoutao
baozhoutao added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit 1561479 Aug 7, 2026
33 of 34 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-5924-test-debug-helper-fix branch August 7, 2026 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

2 participants