fix(lint): promote build output to the global ESLint ignore, and level the per-object lists - #13679
Merged
os-project-manager merged 1 commit intoAug 31, 2026
Conversation
…r-object lists `**/build/**`, `**/.next/**` and `**/.turbo/**` join the global `ignores` object alongside `**/node_modules/**` and `**/dist/**`, and every per-object `ignores` list is levelled onto one shared `NEVER_LINTED` array so no config object can match build output on its own. NAMED CORRECTION, not a neutral change: three rules (`slot-lookup/no-any-assignment`, `no-restricted-syntax`, `query-options/no-any-erasure`) are enabled on TypeScript under those directories today and this deliberately turns them off on build output. That repairs the config's own stated intent — never lint build output — rather than cutting coverage: nobody authors the code there. Maintainer ruling 2026-08-26 (option C), verbatim 「同意」. Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
This was referenced Aug 31, 2026
os-project-manager
marked this pull request as ready for review
August 31, 2026 06:34
os-project-manager
deleted the
claude/issue-12334-eslint-global-ignores
branch
August 31, 2026 06:55
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #12334
Adopts option C from the maintainer ruling on that card (2026-08-26, verbatim 「同意」). Both halves ship.
This is a NAMED CORRECTION, not a neutral change
Three rules are enabled on TypeScript under
build/,.next/and.turbo/today, and this PR deliberately turns them off on build output:It is written up in those words rather than as "semantics-neutral" or "changes nothing", because switching a rule off on generated code and switching it off on source are the same line in a diff. What it repairs is this config's own stated intent — never lint build output. Nobody authors the code under those directories, so linting generated code is the defect being removed, not coverage being cut.
The two halves
**/build/**,**/.next/**and**/.turbo/**join the globalignoresobject that PR fix(lint): take build output out of the linted population with a global ignore #12332 landed (merged 2026-08-25), which carried**/node_modules/**and**/dist/**only.ignoreslist is levelled onto one sharedNEVER_LINTEDarray, so no config object can match build output on its own. The invariant becomes a property of that array instead of seven lists that happen to agree, and it survives a future edit to the global object by someone who has never read this card.Why this is live, not latent
Measured on the card's thread, 2026-08-25 20:23Z:
**/.next/**is live today.apps/docs/.nextis 3.9 GB afterpnpm --filter @objectstack/docs build, and linting it is a hard OOM rather than a slowdown:exit 134with no eslint output reads as a crashed gate, not as 3.9 GB of chunks being parsed. A tracked-file census cannot see this one, because.nextis untracked output.build/and.turbo/remain latent on that census —git ls-filesmatches 0 files under any of the five patterns (control: 4,776 under/src/).Neutrality measurement — source coverage is unchanged
Repo-wide
pnpm lintbefore and after, same tree, ESLint v10.8.1 on Node 22.22.2. Wall figures are shared-box seconds (parallel agents on the same cores), so read them as "no regression", not as a benchmark.Stronger than the count: the two
--format jsonfile lists are set-identical — 0 files dropped, 0 added. Per-path confirmation over 14 probes throughESLint#calculateConfigForFile: all 8 build-output probes go from linted to not-linted, and every source control keeps exactly the rules it had.The structural half is verified independently of the global object: with the global ignore object removed from the array, all 12 build-output probes still resolve to 0 rules, while the 6 source controls keep theirs (6, 6, 4, 2, 6, 5 rules).
The required review step
Option C's own price is one review step: confirm nothing depends on the per-object configs still matching
build/output before levelling them. What was checked:git grepfor the three glob literals — they occur only ineslint.config.mjs(now once, inNEVER_LINTED). No workflow, script or test names them.check:slot-lookup,check:query-options-erasure,check:verify-stand-in. The first two assert on the rule block'sfilesscope and never on itsignores; themeasuringConfighelper that rewritesignoresonly ever removes baselined file paths from it.scripts/slot-lookup-baseline.json, 25 files;scripts/query-options-erasure-baseline.json, 3 keys; 0 matches forbuild/,.next,.turbo).scripts/check-verify-stand-in-erasure.mjsalready runs its own census withSKIP_DIRScontainingbuild,.nextand.turbo. A sibling gate was already assuming build output is out of the population; this levelling brings the ESLint config into agreement with it.One correction to the card's arithmetic: it is four objects, not three
The card and the ruling both say three per-object
ignoreslists need levelling. Measured on currentmain, it is four. The fourth is thepackages/cli/src/**object, whoseignoreslist isnode_modules,dist,**/*.test.ts— the card's phrase "list only node_modules and dist" excluded it by wording, but it matches build output exactly as the other three do (packages/cli/src/build/x.tsmeasured as LINTED with 3 rules enabled before this change). All four are levelled here, and the three objects that already carried the globs read from the same array, so all seven now share one list. The operative clause of the ruling — "so no config object can match build output" — is what is implemented.Gates
Run on
e39276b31, the head of this branch, after the final commit:pnpm lint— exit 0, 5557 files, 0 errors, 0 warningspnpm check:slot-lookup— "slot-lookup ratchet holds: 107 unswept site(s) in 25 file(s), none new, and every file in the population parsed"pnpm check:query-options-erasure— "query-options-erasure ratchet holds: 67 unswept non-test site(s) in 17 file(s), none new, and every file measured parsed"pnpm check:verify-stand-in— "2 stand-in check(s) guarded, 7 candidate(s) explicitly exempt, 10 call site(s) reached, 0 asserted driver arguments"pnpm check:nul-bytes— "OK (scanned 7555 text file(s) ... no raw ASCII control bytes)"node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstacknames no check family for this path; the four gates above are the ones that import this config, pluspnpm lint, which CI runs on every PR.No changeset, and the PR carries
skip-changeset: the diff is one root config file, it publishes nothing from any package, and it is the same disposition as PR #12332, which changed the same file.Draft on purpose — the dispatching PM seat arms it after review.
Generated by Claude Code
Generated by Claude Code