test(objectql): save-meta-response-conformance 删除悬空调试助手并补齐 registerObject 实参 (#5924) - #6431
Conversation
…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
…t-debug-helper-fix
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckNo hand-written docs reference the 0 changed package(s). ✅ |
标签与 CI 记录(正文「详见评论区」的那一条)最终标签(读回为准)
|
| 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
Fixes #5924
前提重验(先做,结论:完全成立,四条错误逐字复现)
按「issue 正文是线索不是规格」,先在
origin/main上把正文三条主张各自证一遍::119的LOG助手原样仍在node:fsimport、无OUT定义、无LOG(调用点grep -n 'LOG|OUT|appendFileSync|node:fs'只命中 119 行声明本身,零其他命中把该包 tsconfig 的 test 排除项抬掉后实测,正文列的四条逐字复现:
一处正文笔误更正:正文与分诊都写
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. 补齐
:115的registerObject实参 —— 分诊建议「一并修」的那条独立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全包两次输出
diff之后恰好只有那四行消失,全包其余诊断一行未动:判据达成:该文件被 tsc 检查时零错。
反向验证 —— 方向先定后验,且必须说清本单不适用常规方向
常规的「把删掉的肢体装回去,看新钉子转红」在本单不适用,如实写出来而不是硬套模板:本 PR 不新增任何钉子测试,删的是死代码,而死代码的定义就是「没有任何闸门能看见它」。所以预先写下的预期方向是两条,分别可证伪:
diff。LOG从未被调用,删它对运行时是恒等变换。第 2 条用同一棵工作树跑了前后两趟全量(用
git diff存补丁 +git checkout --回退再git apply复原,未用git stash):逐字相同 —— 零行为变化落到了实测上,不是断言。
:115那一处值得单说一句:传packageId严格讲是一次运行时取值变化(undefined变成'test-package')。它在本用例里恒等的理由是可查的:packageId只被三处读到 ——registerNamespace(namespace, packageId)(仅当namespace有值,此处未传)、owner 冲突判定(本用例全程只注册一个对象、只注册一次,冲突分支不可达)、以及 contributor 记录的索引键(本用例不调unregisterObjectsByPackage)。加上上面前后两趟 2321 全等的实测,认定为行为中性。没有把它写成「零改动」,因为它不是。其余
pnpm --filter @objectstack/objectql typecheck→ exit 0。但请按其真实含义读:它跑的是带排除项的那份 tsconfig,根本没读到本文件,所以它对本改动的证明力是零,列在这里只为说明没有把包搞坏。pnpm check:type-check-coverage→ OK,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.mjs的TEST_DEBT条目」。#5827 确已先落地(已合并),但该约束的前提在 #5827 自己的落地形态里被取消了,理由两条,都可在 main 上复核:ℹ can be lowered,不红」。脚本里写得很直白:"an improvement must not have to pay a bookkeeping toll to land"。本 PR 让数字下降,因此不可能把闸门弄红。@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声明而该包
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/src下 140 个*.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.json、scripts/check-type-check-coverage.mjs、content/docs/releases/。未 stash、未 rebase、未 force-push。范围外发现
无新增。唯二两处偏离既有记录的事实都已就地写在上文,均不构成新缺陷:正文/分诊的 tsconfig 路径笔误(
src/一级),以及分诊那条台账耦合约束的失效(#5827 落地形态所致)。Generated by Claude Code