Skip to content

docs(ci): stop lint.yml's header comment hand-counting the object-ui error rules - #3273

Merged
xuyushun441-sys merged 1 commit into
mainfrom
claude/issue-3261-lint-yml-comment-drift
Aug 3, 2026
Merged

docs(ci): stop lint.yml's header comment hand-counting the object-ui error rules#3273
xuyushun441-sys merged 1 commit into
mainfrom
claude/issue-3261-lint-yml-comment-drift

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

Fixes#3261

.github/workflows/lint.yml 的头部注释写着 eslint.config.js三条object-ui/* 规则设成 error,实际是四条;括号里点名的三个来源(ADR-0054 Phase 5、#2879、objectql.ts ratchet)同样漏了一个(no-dynamic-import-in-test-hook / #3010#3021)。

复核结果(origin/main @ e0f23ca,直接读求值后的 flat config,而不是扫文本):

eslint.config.js 行规则files 作用域
59no-synthetic-event-trigger**/*.{ts,tsx}
65no-try-catch-around-hook**/*.{ts,tsx}
98no-dynamic-import-in-test-hook**/*.test.{ts,tsx}**/__tests__/**
111no-inline-spec-configpackages/types/src/objectql.ts

为什么不是把「三」改成「四」

数错一个数是症状,不是缺陷。这条注释是 lint.yml 存在理由的唯一书面说明 —— 它记录着「这些 error ratchet 曾因 workflow 是 workflow_dispatch-only 而全部空转,直到 #2923」。下一个要加 error 级规则的人照它判断这道门禁管到哪儿,而过期的枚举读起来和新鲜的一样权威:它会同样自信地告诉那个人「你的新规则不在覆盖范围内」(或者反过来),然后是错的。

#3212 在同一天量过同一页:工作流数量文档写 11、issue 写 12、实际 13 —— 手工维护的枚举按构造必然漂移。三改四只是把下一次漂移推迟到第五条规则落地那天。

所以注释改成既不点数也不点名,与 content/docs/guide/ci-cd-pipeline.md 已经采用的写法(「the rules eslint.config.js sets to error」)对齐,不再维护第二份副本。

但清单确实有价值 —— 所以加了守卫

本单和 PM 都要求先评估「加断言把清单钉在 eslint.config.js 上」。评估结论:把清单钉住可行,但清单本身不该保留

eslint.config.js 已经是那份清单,而且每条规则在自己旁边写了 ADR/issue 出处;在 workflow YAML 里再抄一份,只是制造一个必须与配置同步、却没有任何机制强迫谁去同步的第二副本。真正值得机器守住的不是「有几条」,而是这条注释还在做的那几个断言。于是 scripts/__tests__/lint-workflow.test.ts(与 #3212 的反向断言、#3207 的 peer-edge 守卫、#3257 的样例守卫同一路数)钉住:

  1. 枚举不会回来 —— 注释里不得再出现数量词或规则名(lint.yml 的头部注释说「三条 object-ui/* 规则设成 error」,实际已经是四条 #3261 本身的回归守卫);
  2. eslint.config.js 确实还有 object-ui/* 规则设成 error —— 否则注释描述的是一道背后空无一物的门禁,该重写了;
  3. 这个 workflow 确实还在 pull_request 上跑,且没把 .ts/.tsx 放进 paths-ignore —— 否则那些规则就空转了,和 lint never ran on PRs, and turbo skipped 7 packages — three error ratchets were inert #2923 修掉的状态一模一样,而注释还在把它当历史讲。

规则集合是 import 求值后的 flat config 读出来的,不是正则扫文本:severity 有 'error' / 2 / ['error', {…}] 等多种写法,四条规则又分散在四个 files 作用域不同的 config 对象里,只有读求值结果才能得到和 ESLint 一致的答案。

破坏性验证(每例改完即还原)

用例结果
基线5 passed
A1 数量词写回注释(同一行)× never hand-counts the object-ui/* rules again
A2 数量词跨注释换行(#3261 原始形态)× never hand-counts the object-ui/* rules again
B 注释里点名规则× never enumerates them by name either
C 四条规则全降为 warn× eslint.config.js really does set object-ui/* rules to `error`
D 去掉 pull_request 触发器× still runs on pull requests, so those rules are not inert again (#2923)
E paths-ignore'**/*.tsx'× does not paths-ignore the TypeScript sources those rules lint
F 新增第五条 error 规则5 passed —— 保持绿灯

F 是这套设计的关键性质,不是遗漏:加规则不该要求任何人再去改一句 workflow 散文。如果走「保留枚举 + 断言钉住」那条路,F 会变红,把「编辑注释」变成每个加规则的人都要做的杂务 —— 而一个只能靠改散文来修的失败断言,教会大家的是把守卫当噪音。

A2 值得单说:第一版正则用 [^.\n] 连接数量词与 object-ui,漏掉了 #3261 的原始形态 —— 原注释里 "sets three" 结束一行、"object-ui/* rules" 开始下一行。破坏性验证抓到了这一点,现已改为先把注释去掉 # 前缀、展平换行再匹配。

未加 changeset

改动是一条 CI workflow 注释 + 一个仓库内部守卫测试,不触及任何已发布包的行为或 API,没有用户可见的东西发出去。按 AGENTS.md「纯 bug 修复不需要 changeset」,这里连发布代码都不是;加了只会在 release notes 里多一行无意义条目。

边界

只改了 .github/workflows/lint.yml 的注释,新增一个测试文件。未改任何 workflow 的实际行为,未改eslint.config.js 的规则等级。

npx eslint scripts/__tests__/lint-workflow.test.ts 干净退出;vitest run --project unit scripts/ eslint-rules/ 9 个文件 / 85 个测试全绿。

🤖 Generated with Claude Code

https://claude.ai/code/session_01NVPjPzmmAJ2Ngtvgg5MSRa


Generated by Claude Code

…error rules
The comment said `eslint.config.js` sets three `object-ui/*` rules to `error`;
it sets four. The parenthesised source list was short by one for the same
reason. Rewritten to name neither a count nor a rule, matching how
`content/docs/guide/ci-cd-pipeline.md` already phrases it, and pinned by
`scripts/__tests__/lint-workflow.test.ts` so the enumeration cannot come back
and the comment's remaining claims cannot become fiction.
Fixes#3261
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NVPjPzmmAJ2Ngtvgg5MSRa
@vercel

vercelBot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectuiIgnoredIgnoredAug 3, 2026 9:57am

Request Review

@xuyushun441-sys
xuyushun441-sys marked this pull request as ready for review August 3, 2026 10:03
@xuyushun441-sys
xuyushun441-sys added this pull request to the merge queueAug 3, 2026
Merged via the queue into main with commit 7d20309Aug 3, 2026
15 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the claude/issue-3261-lint-yml-comment-drift branch August 3, 2026 10:03
akarma-synetal pushed a commit to akarma-synetal/objectui that referenced this pull request Aug 10, 2026
…bjectstack-ai#3279) (objectstack-ai#3784)
`scripts/check-lint-coverage.mjs` 的文件头 docblock 说 `eslint.config.js` 把
**three** 条 `object-ui/*` 规则设成了 `error`,并在括号里手工列举来源(ADR-0054
Phase 5、objectstack-ai#2879、objectql.ts ratchet)。这是 objectstack-ai#3261 从 `.github/workflows/lint.yml`
里删掉的那句话的逐字副本,连漏掉的规则都是同一条:配置里设成 `error` 的
`object-ui/*` 规则实际有四条 —— L59 no-synthetic-event-trigger、L65
no-try-catch-around-hook、L98 no-dynamic-import-in-test-hook、L111
no-inline-spec-config,漏的是第三条。objectstack-ai#3261 只改了 workflow,这份副本原样留着,
所以它今天就是错的,而不是"将来会错"。
## 头注改法
按 objectstack-ai#3261 / PR objectstack-ai#3273 在 `lint.yml` 里确立的写法去数字化:不点数、不在括号里列
来源,改成「every `object-ui/*` rule that `eslint.config.js` sets to `error`」
这种永真表述。这段话本身正确的主张一字未动 —— 没有 `lint` script 的包不是干净
而是没被 lint 过,ratchet 在那里一文不值。同时按 `lint.yml` 的同构做法补一段,
说明为什么这里刻意不点数也不列举,以及唯一诚实的清单是 `eslint.config.js`
本身(每条规则自己的 ADR/issue 就写在它旁边的注释里)。
## 守卫扩面
`scripts/__tests__/lint-workflow.test.ts`(objectstack-ai#3273 新增)的两条断言 —— 不得点数、
不得按名列举 —— 此前只扫 `lint.yml`,看不见这第二份副本,所以它是被人顺手读到
(objectstack-ai#3274)而不是被门禁挡下来的。现在把扫描面参数化成一个 prose surface 列表,
`lint.yml` 与 `check-lint-coverage.mjs` 各出一项,判定逻辑(点数正则、规则名
比对)原样复用,只是按 surface 取注释:
- 注释块提取按标记参数化 —— YAML 的 `#` 行首标记与 docblock 的星号行首标记共用
一个 `unwrap(block, marker)`,`\s+` 折行还原照旧,因为 objectstack-ai#3261 那句话正是断在
"sets three" 与 "`object-ui/*` rules" 之间的。
- 点数正则只读各文件的解释性注释,不读整个文件。对这个脚本这条限定是必需的而
非洁癖:它的 `Known gaps` 注释合法地在数**包**(「the last two …, 14 errors」),
整文件扫描会把它当成规则条数报出来。
- 规则名比对仍读整个文件 —— 规则名出现在这两个文件的任何位置,都是
`eslint.config.js` 的第二份拷贝。
原来那条「eslint.config.js 确实还有 `object-ui/*` 规则设成 error」的前提断言
现在被两份注释共用,单独提成一个 describe;`lint.yml` 专属的两条触发器断言
(仍跑 pull_request、ignore 列表不吞 .ts/.tsx)留在原处不动。
## 验证
- `grep -n 'object-ui/' eslint.config.js` 确认四条 error 规则现状。
- 仓库根 `pnpm vitest run scripts/__tests__/lint-workflow.test.ts`:7 passed
(扩面前 5:2 条守卫 × 2 个 surface + 1 前提 + 2 触发器)。
- `pnpm type-check:scripts` 干净通过。
- `node scripts/check-control-bytes.mjs` OK;改动文件另做一次
`grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]'` 自扫,零控制字节。
- 变异自证:把原来那句点数写回 mjs 头注,`check-lint-coverage.mjs` 的
never-hand-counts 一条变红(counted 报出 "three `object-ui"),其余六条仍绿;
变异不入 commit。
不带 changeset:`scripts/**` 不在 `check-changeset-presence.mjs` 的守卫面
(`<pkg>/src/**`,取自 `.changeset/config.json` 的 fixed 组)之内,且先例
PR objectstack-ai#3273 / objectstack-ai#3278 改的正是这两个文件、均未带 changeset。
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lint.yml 的头部注释说「三条 object-ui/* 规则设成 error」,实际已经是四条

2 participants

@xuyushun441-sys@claude