Skip to content

Commit 2cce3fd

Browse files
claude[bot]claude
andauthored
fix(lint): promote build output to the global ignore and level the per-object lists (#13679)
`**/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 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9a71af3 commit 2cce3fd

1 file changed

Lines changed: 57 additions & 25 deletions

File tree

‎eslint.config.mjs‎

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,32 @@ const commentSwallowPlugin = {
886886
},
887887
};
888888

889+
// ───────────────────────────────────────────────────────────────────────────
890+
// The trees nothing in this repo ever lints: installed dependencies and build
891+
// output. Named ONCE and spread into the global ignore below AND into every
892+
// per-object `ignores` beside it, so "no config object can match build output"
893+
// is a property of this one array instead of seven lists that happen to agree.
894+
//
895+
// They did not agree. Four of the seven `files` objects below omitted
896+
// `**/build/**`, `**/.next/**` and `**/.turbo/**`, so TypeScript under those
897+
// directories resolved to three ENABLED rules while the same generated file
898+
// under `dist/` resolved to none — the incidental-neutrality the levelling in
899+
// #12334 replaced.
900+
//
901+
// ⚠️ The global object alone already keeps these paths out of the linted
902+
// population, so the per-object copies change no behaviour today. They are not
903+
// redundancy: they are what makes the invariant survive a future edit to the
904+
// global object by someone who has never read this history — which is exactly
905+
// how a rule came to be enabled on generated code in the first place.
906+
// ───────────────────────────────────────────────────────────────────────────
907+
const NEVER_LINTED = Object.freeze([
908+
'**/node_modules/**',
909+
'**/dist/**',
910+
'**/build/**',
911+
'**/.next/**',
912+
'**/.turbo/**',
913+
]);
914+
889915
export default [
890916
// ───────────────────────────────────────────────────────────────────────────
891917
// GLOBAL ignore. This is the ONLY object in this array with no `files` key,
@@ -910,34 +936,41 @@ export default [
910936
// So the accept/reject semantics of `**/dist/**` do not move: nothing there
911937
// had a rule enabled to lose. The saving is pure enumeration + parse.
912938
//
913-
// ⚠️ SCOPE IS DELIBERATELY NARROWER THAN THE PER-OBJECT LISTS BELOW. Those
914-
// also carry `**/build/**`, `**/.next/**` and `**/.turbo/**`, and promoting
915-
// those three here would NOT be semantics-neutral. Three of the objects
916-
// below (the `packages/**` and `examples/**` ones) list only
917-
// `**/node_modules/**` and `**/dist/**` in their `ignores`, so they still
918-
// match TypeScript under the other three directories:
939+
// ⚠️ THE OTHER THREE PATTERNS ARE A NAMED CORRECTION, NOT A NEUTRAL ONE.
940+
// `**/build/**`, `**/.next/**` and `**/.turbo/**` join this object under a
941+
// maintainer ruling (2026-08-26, option C on #12334, verbatim 「同意」).
942+
// Three rules are enabled on TypeScript under those directories today, and
943+
// promoting the patterns DELIBERATELY TURNS THEM OFF on build output:
919944
//
920-
// packages/core/build/x.ts → LINTED, 3 rules ENABLED
945+
// packages/core/build/x.ts before → LINTED, 3 rules ENABLED
921946
// (slot-lookup/no-any-assignment, no-restricted-syntax,
922947
// query-options/no-any-erasure), parser @typescript-eslint/parser
948+
// after → no config object matches: not linted
949+
//
950+
// Recorded in those words rather than under a "changes nothing" banner,
951+
// because switching a rule off on generated code and switching it off on
952+
// source are the same line in a diff. It repairs this config's own stated
953+
// intent — never lint build output: nobody authors the code under those
954+
// directories, and linting generated code is the defect being removed, not
955+
// coverage being cut.
923956
//
924-
// No such path exists in this repo today — nothing emits to `build/`, and the
925-
// only Next.js app is `apps/docs`, which is outside `packages/**` — so this
926-
// is latent rather than live. It is still a real semantic change, and it is
927-
// left out of this object pending a maintainer ruling rather than taken
928-
// silently under a "changes nothing" banner. See #12304.
957+
// `**/.next/**` is LIVE, not latent (measured 2026-08-25 on #12334):
958+
// `apps/docs/.next` is 3.9 GB after `pnpm --filter @objectstack/docs build`,
959+
// and linting it is a hard OOM — `exit 134`, "Ineffective mark-compacts near
960+
// heap limit", 66 s, no eslint output — which reads as a crashed gate rather
961+
// than as 3.9 GB of chunks being parsed. A tracked-file census cannot see it:
962+
// `.next` is untracked output, and `git ls-files` matches 0 files under any
963+
// of the five patterns (control: 4,776 under `/src/`). `build/` and
964+
// `.turbo/` stay latent on that census; the levelling below is what stops
965+
// either of them becoming the next `.next`. See #12334 / #12304.
929966
// ───────────────────────────────────────────────────────────────────────────
930967
{
931-
ignores: ['**/node_modules/**', '**/dist/**'],
968+
ignores: [...NEVER_LINTED],
932969
},
933970
{
934971
files: ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}'],
935972
ignores: [
936-
'**/node_modules/**',
937-
'**/dist/**',
938-
'**/build/**',
939-
'**/.next/**',
940-
'**/.turbo/**',
973+
...NEVER_LINTED,
941974
'packages/spec/**',
942975
// CLI/scaffold templates contain `@objectstack/spec` strings that are
943976
// emitted to user projects, not actual imports in this repo.
@@ -980,7 +1013,7 @@ export default [
9801013
// reason to suspect it.
9811014
{
9821015
files: ['packages/cli/src/**/*.{ts,tsx,mts,cts}'],
983-
ignores: ['**/node_modules/**', '**/dist/**', '**/*.test.ts'],
1016+
ignores: [...NEVER_LINTED, '**/*.test.ts'],
9841017
languageOptions: {
9851018
parser: tsParser,
9861019
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
@@ -1019,7 +1052,7 @@ export default [
10191052
// backward-compat fixture (#2089) and are intentional.
10201053
{
10211054
files: ['examples/**/*.{ts,tsx,mts,cts}', 'packages/apps/**/*.{ts,tsx,mts,cts}'],
1022-
ignores: ['**/node_modules/**', '**/dist/**', 'packages/qa/downstream-contract/**'],
1055+
ignores: [...NEVER_LINTED, 'packages/qa/downstream-contract/**'],
10231056
languageOptions: {
10241057
parser: tsParser,
10251058
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
@@ -1068,7 +1101,7 @@ export default [
10681101
// needs type information, so it belongs to a typed-lint pass, not here.
10691102
{
10701103
files: ['packages/**/*.{ts,tsx,mts,cts}'],
1071-
ignores: ['**/node_modules/**', '**/dist/**', ...SLOT_LOOKUP_UNSWEPT],
1104+
ignores: [...NEVER_LINTED, ...SLOT_LOOKUP_UNSWEPT],
10721105
languageOptions: {
10731106
parser: tsParser,
10741107
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
@@ -1138,8 +1171,7 @@ export default [
11381171
{
11391172
files: ['packages/**/*.{ts,tsx,mts,cts}'],
11401173
ignores: [
1141-
'**/node_modules/**',
1142-
'**/dist/**',
1174+
...NEVER_LINTED,
11431175
// First cut is non-test code (08-03 triage). The ratchet lifts this and
11441176
// holds the test residual to a count instead.
11451177
...QUERY_OPTIONS_TEST_GLOBS,
@@ -1178,7 +1210,7 @@ export default [
11781210
// fakes — the arm the guard is worth the most on.
11791211
{
11801212
files: ['**/*.{ts,tsx,mts,cts}'],
1181-
ignores: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.next/**', '**/.turbo/**'],
1213+
ignores: [...NEVER_LINTED],
11821214
languageOptions: {
11831215
parser: tsParser,
11841216
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
@@ -1204,7 +1236,7 @@ export default [
12041236
// stopped being locked.
12051237
{
12061238
files: COMMENT_SWALLOW_FILES,
1207-
ignores: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.next/**', '**/.turbo/**'],
1239+
ignores: [...NEVER_LINTED],
12081240
languageOptions: {
12091241
parser: tsParser,
12101242
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },

0 commit comments

Comments
 (0)