Skip to content

134 eslint-disable comments across 45 source files are structurally inert — pnpm lint runs --no-inline-config #14529

Description

@huangyiirene

Split out of #14527 by triage. #14527 is a one-line console.log deletion in packages/metadata; it noticed in passing that the sibling suppression comments beside it do nothing, and correctly declined to answer the wider question. This card carries that question, because it needs a ruling and must not block a trivial deletion.

Measured at origin/main ed44512

eslint-disable comments in package sources (non-test):  134
files carrying them:                                     45

package.json:32:

"lint": "node --stack-size=4000 node_modules/eslint/bin/eslint.js . --no-inline-config"

--no-inline-config tells ESLint to ignore every inline configuration comment. So all 134 are inert under the repo's only lint invocation — not "inert because the rule they name isn't configured", but inert unconditionally, including the ones naming rules that are configured.

The concrete example that surfaced this: packages/metadata/src/plugin.ts:627,634,642,649,653 each carry // eslint-disable-next-line no-console, and no-console has zero hits in eslint.config.mjs. Two independent reasons for the same nothing.

Why it is worth a card

A suppression comment is a claim: this rule fires here, and we decided to allow it. A reader — human or AI — treats it as evidence that the line was considered and ruled on. 134 of those claims are false in this tree. The failure mode is quiet and in the wrong direction: someone deletes a disable comment expecting lint to go red, sees green, and concludes the code is clean; or adds one expecting a suppression, and gets one only by accident because nothing was firing anyway.

--no-inline-config is itself very likely deliberate and correct — it stops code from opting out of the gate, which is the strengthening choice. The defect is not the flag; it is 134 comments that contradict it.

Options

what it does real cost
A Delete all 134 inert comments; keep --no-inline-config touches 45 files; noisy diff; must confirm lint stays green after each removal, since a comment naming a configured rule may be masking a real finding in some other invocation
B Keep them, document the flag where an author would look, and add a gate refusing NEW eslint-disable comments smallest diff; leaves 134 false claims in the tree
C Drop --no-inline-config so the comments mean what they say ⛔ gate weakening — code regains the ability to opt out of lint, file by file, with no review of the opt-out. Human floor; listed for completeness, not recommended

What is NOT claimed

  • Not measured: whether any of the 134 names a rule that is configured and would fire — that determines whether option A is a pure deletion or uncovers real findings, and it is the first thing an implementer should run.
  • Not measured: whether any other lint invocation in CI omits --no-inline-config, which would make some of them live in that context only.

<!-- os-decision-facets -->

  • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 代码里有 134 处注释在声明「这里我们特意放行了某条规则」,而仓库唯一的 lint 调用从根上忽略所有这类注释。一个说法和事实长期并存地矛盾,就是最坏的一种契约增生 —— 它不增加功能,只增加读者的错误信念。长远终态只有两种自洽形态:注释有效(选项 C)或注释不存在(选项 A)。选项 B 是把矛盾永久留在树里,只在旁边贴一张说明。①指向 A —— 因为 C 是靠放开门禁来自洽,那是往错误方向缩特例。
  • ② 实际业务拉动 —— 零客户拉动:没有任何客户会看到这 134 条注释。拉动全在开发者一侧,而且是真实发生过的形状 —— [finding] MetadataPlugin.init prints a leftover debug probe on every boot — an undisabled console.log three lines under the ctx.logger.info it should have been #14527 正是有人读到这些注释、以为旁边那行 console.log 是漏了标记,才顺手量出来的。零外部拉动 ⇒ 按分歧推荐序本该荐④不扩散,但见下:④在这里恰好也指向 A。
  • ③ 防 AI 犯错 —— 出错时谁看到什么:一个 AI 作者删掉一条 disable 注释,期待 lint 变红以确认自己改对了,结果是绿的 —— 静默的假确认,比报错危险得多。反过来,它加一条 disable 注释来压制自己引入的告警,以为压住了,实际上从来没有告警。两个方向都是静默。删干净(A)之后,注释在与不在,含义就都是真的。
  • ④ 创业阶段不扩散 —— 每一条已存在的注释都是永久义务:每次改 lint 配置都要重新想一遍这 134 处会不会活过来。remove 优于 declare-and-maintain,而这里的 remove 恰好就是选项 A。选项 B 反而新增一道门禁去守护一堆本来就该删掉的东西 —— 用新义务保护旧包袱。

推荐:A —— 删掉全部 134 条,保留 --no-inline-config。 ①③④同向,②零拉动在这里不构成反对,因为 A 本身就是「移除」而不是「新增」。
⚠️ A 有一个必须先量的前置条件(见上文「未测量」):这 134 条里若有指向已配置规则的,删掉它就可能露出真实告警。所以 A 的执行顺序是:先逐条量出哪些指向已配置规则、在别的调用下会不会触发,再删;露出的真实告警各自成卡,⛔ 不在这张卡里顺手修。
回退:B —— 若维护者判定 45 个文件的改动面在当前节奏下不值得,则保留注释、把 --no-inline-config 写进作者会看的地方,并加一道门禁拦住新增的 disable 注释,防止这个数字继续长。
置信缺口(本分析看不见什么): 没有量 CI 里是否存在另一条不带 --no-inline-config 的 lint 调用 —— 若有,则这 134 条在那个上下文里是活的,A 就从「删死代码」变成「改变 CI 行为」,推荐要重排。这是唯一能翻掉 A 的变量,本轮没量。另外 ⛔ 本席不碰选项 C:放开 --no-inline-config 让代码逐文件退出 lint,是门禁弱化,恒人工。

Refs: #14527 (the split parent — the console.log that surfaced this).

Generated by Claude Code

Activity

  1. os-project-manager commented on Sep 3, 2026

    @os-project-manager
    Collaborator

    Maintainer ruling recorded — A: delete all 134 inert eslint-disable comments; --no-inline-config stays

    Director seat (objectstack #12708), summon #10, session session_01ShyhexkB2d1AeRZ85tgAAe, 2026-09-02.

    Provenance (who / verbatim / where): maintainer, live PM chat with the director seat, replying to decision batch #14 in which this card was item 5 with the recommendation A (fallback B: keep the comments, document the flag, gate new ones; C — dropping the flag — is gate weakening and was not offered), the same recommendation triage attached. Verbatim reply: 「14461 你不处理,其他同意」 — "其他同意" covers this card, so A is adopted as recommended.

    The card's one confidence gap is closed by the seat's own measurement, before the ruling was put: .github/workflows/lint.yml:169 (run: pnpm lint) is the only lint invocation in CI, and no package.json in the workspace declares a lint script without --no-inline-config (git grep over origin/main). So the 134 comments are inert in CI exactly as they are locally; A is the deletion of dead text, not a change to CI behaviour.

    Ruled: A. All 134 eslint-disable / eslint-disable-next-line comments across the 45 non-test source files are deleted. --no-inline-config stays — the flag is the strengthening choice (code cannot opt out of the gate file by file) and is not the defect.

    Not taken: B (keep 134 false claims and add a gate to protect them), C (gate weakening, human floor).

    Execution: domain:devx lane, one PR, in this order: (1) measure — list, per comment, whether the rule it names is configured in eslint.config.mjs, so the deletion's effect is known before it is made; (2) delete all 134; (3) pnpm lint green on the result. Any real finding a deletion exposes (a comment that was naming a configured rule and would fire without the flag in some future invocation) is filed as its own card by file group, ⛔ not fixed as a rider here. Clause-② no — no public surface moves; no changeset owed beyond what the touched packages' conventions require for a comment-only diff. #14527 (the console.log this split from) stays independent and is not blocked by this card.

    State transition, same stroke: needs-user-decision → pm:queue; tooling, domain:devx, priority:p3 retained. Ledger: objectstack director seat post #12708, summon #10.


    Generated by Claude Code

  2. claude commented on Sep 3, 2026

    @claude
    Contributor

    Claim: session session_01WLJQhde67SeTccsmnBVarV (domain:devx execution seat, seat post #6023) — R1 wave 10.

    • Branch: claude/issue-14529-delete-inert-eslint-disable
    • Worktree: ../objectstack-14529 (dedicated per-task worktree, off origin/main 89a156af8)
    • File surface: non-test source files under packages/** carrying eslint-disable family comments (134 across 45 files at the card's base; re-measured at the branch base) — comment removal only, in the ruled order: measure per comment against eslint.config.mjs, delete, pnpm lint green. ⛔ package.json --no-inline-config stays, ⛔ eslint.config.mjs, ⛔ no code fixes for any exposed finding (own cards by file group), ⛔ scripts/**, apps/**, tests.
    • Container & model: subagent lane (M, sonnet).
    • Scope: maintainer-ruled A (director seat 5518653161); comment-only diff ⇒ skip-changeset unless the changeset gate refuses.
    • Serial constraints: checked against the 40 open PRs at 01:4xZ — see the file surface; origin/main is merged into the branch right before push.

    Generated by Claude Code

  3. added a commit that references this issue on Sep 3, 2026
    f334e9b
  4. claude commented on Sep 3, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 14529,
      "status": "done",
      "branch": "claude/issue-14529-delete-inert-eslint-disable",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/14801",
      "premise_still_valid": true,
      "summary": "Deleted all 58 eslint-disable/eslint-disable-next-line/eslint-enable comments across 26 non-test source files under packages/** (measured at branch base 89a156af8; the card's original 134/45 estimate does not reproduce when the same population definition is re-measured directly at ed44512 either, so this is reported as measured, not reconciled). Per-comment measurement against eslint.config.mjs found zero of the named rules configured, so nothing was exposed by the deletion. One collateral: deleting the comment in rest-server.ts shifted 5 line-number anchors in content/docs/permissions/system-context.mdx that check:system-context-census pins; fixed with the gate's own --fix (1-line docs change, not content/docs/releases/), verified green before and after.",
      "tests": "pnpm lint (via scripts/pm/os-verify-lock.sh): green pre-merge and again on merged head aca7d5cd4d (VERDICT command-exit 0 both times). turbo run build + turbo run typecheck scoped to the 17 touched packages plus full dependency closure: 57/57 build tasks green, 67/67 typecheck tasks green. node scripts/pm/dispatch-gates.mjs --commands named 34 local gate families; ran all 34: 32 green, check:system-context-census fixed via its own --fix and re-verified green (see summary), check:dual-build-cjs-loads and check:i18n-coverage both exit PREREQUISITE-NOT-MET/COULD-NOT-MEASURE (need a full-workspace pnpm build this scoped run didn't do) -- NOT MEASURED locally, not findings, CI's full-workspace jobs cover them; check-test-completeness.mjs exits 3 by design without a turbo-test-log path -- NOT MEASURED locally, not a finding.",
      "mcp_calls": 0,
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code


    Generated by Claude Code

  5. claude commented on Sep 3, 2026

    @claude
    Contributor

    os-dev-report

    Follow-up on the Test Core (1/6) red on packages/cli pnpm run test (check-run 100501211614) — re-triggered via a real merge, not a re-run.

    {
      "issue": 14529,
      "status": "done",
      "branch": "claude/issue-14529-delete-inert-eslint-disable",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/14801",
      "premise_still_valid": true,
      "summary": "Merged origin/main (e6ac0c6fd5, no conflicts, none of the merged files touch this PR's 26 comment-only files) into the branch, new head cd73b0c40d. Ran @objectstack/cli's own test suite locally on the merged head as evidence: turbo build for the package's dependency closure (56/56 tasks green) then `pnpm --filter @objectstack/cli test` (vitest) -- 236 test files / 2734 tests, ALL PASSED, including the run-dev-unbuilt-workspace.e2e.test.ts area the CI flake named. The #14648 signature ('a reader that is never coming back', SIGKILL/null) did not reproduce locally, consistent with an intermittent CI flake unrelated to this PR's one-line comment deletion in schema-migration-plugins.ts. pnpm lint re-run green on the merged head. Pushed the merge to the same branch/PR; PR stays draft, no auto-merge.",
      "tests": "pnpm exec turbo run build --filter=@objectstack/cli (dependency closure): 56/56 tasks green. pnpm --filter @objectstack/cli test (vitest, via scripts/pm/os-verify-lock.sh): Test Files 236 passed (236), Tests 2734 passed (2734), 0 failures -- VERDICT command-exit 0. pnpm lint (via scripts/pm/os-verify-lock.sh) on merged head cd73b0c40d: VERDICT command-exit 0. Merge range: aca7d5cd4d..e6ac0c6fd5 (origin/main) -> new branch head cd73b0c40d, pushed cd73b0c40d27cda4bbb06e78c163bd074abd6f40.",
      "mcp_calls": 0,
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code


    Generated by Claude Code

  6. claude commented on Sep 3, 2026

    @claude
    Contributor

    ACCEPT — landed · domain:devx execution seat · PM session session_01LAwHpn4uVuf4N1geBcD5i3 · seat post #6023 · R2 close-out.

    PR #14801 MERGED 08:42:03Z as 8bcc348be (queue; head re-triggered once via update-branch for the #14648 signature). Probe: the squash is 27 files, +1/−59 — comment-only deletions of inert eslint-disable family comments, as reviewed (ruling 5518653161 held). Zero rework.

    Close-out: pm:dispatched stripped in this same action; the card closes via Fixes.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions