fix(config): category severities no longer force-enable opt-out rules - #1020
Merged
Conversation
A config that only re-stamps category severities (e.g. `categories:
{ "Maintainability": "warn" }`) silently activated every
`defaultEnabled: false` rule in that category, because the opt-out
guard in createOxlintConfig accepted the category fallback from
resolveRuleSeverityOverride as an explicit enable. Opting a rule in
now requires pinning the rule itself (or a legacy alias) under
`rules` — the same principle as the app-only gate in
build-diagnostic-pipeline — and `react-doctor rules` previews the
same semantics.
Found via rule fire-rate telemetry: this force-enable explains the
two highest per-scan intensity outliers (forbid-component-props avg
871 findings/scan, react-in-jsx-scope avg 2,514/scan) plus
design-no-redundant-size-axes; validated on a real OSS repo whose
scan drops 13 -> 4 diagnostics with the fix.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
commit: |
rayhanadev
added a commit
that referenced
this pull request
Jul 2, 2026
…erministic-discovery-max-duration Clean auto-merge — main's CLI/rules/action audit fixes and the category-severity opt-out fix don't conflict with this branch. Verified: typecheck 14/14, core 1137 pass, react-doctor green (the lone json-out-flag e2e failure is the known parallel-load flake — passes in isolation). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rayhanadev
added a commit
that referenced
this pull request
Jul 2, 2026
The prior merge commit staged all 484 merged files, so lint-staged ran `vp check --fix` (oxlint --fix) across them and "fixed" test fixtures that carry intentional violations — e.g. state-issues.tsx's `no-mutable-in-deps` case (`[location.pathname]` → `[]`), which made that rule find nothing and failed tests/run-oxlint/state-effects.test.ts. Restore the affected files to origin/main (also pulling in #1020's category- severity config changes so the tree is consistent). Committed with --no-verify so the hook can't re-corrupt the fixtures; ran typecheck + the affected suites manually instead (all green). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Why
A config that only re-stamps category severities — e.g.
categories: { "Maintainability": "warn" }— silently activated everydefaultEnabled: falserule in those categories, because the opt-out guard increateOxlintConfigaccepted the category fallback fromresolveRuleSeverityOverrideas an explicit enable. Rule fire-rate telemetry traced the two highest per-scan intensity outliers in production to exactly this:forbid-component-props(avg 871 findings/scan, p90 2,965) andreact-in-jsx-scope(avg 2,514/scan), plusdesign-no-redundant-size-axes. Users are visibly being burned — two unrelated OSS repos carry hand-written"react-doctor/react-in-jsx-scope": "off"overrides for a rule they never enabled.Before (real repo,
Anchal789/Org-Drive— config sets category severities only, never names either rule):After:
What changed
createOxlintConfig(packages/core/src/runners/oxlint/config.ts): thedefaultEnabled: falseguard now requires a rule-level severity (per-rule key or legacy alias) — resolved with the same no-category lookup the app-only gate inbuild-diagnostic-pipelinealready uses. Category severities still re-stamp already-enabled rules.react-doctor rulespreview (resolve-effective-rule-severity.ts) mirrors the same semantics so the catalog matches scan behavior.categoriesdocstring + regenerated config schema state the contract explicitly.no-danger(itself an opt-out rule); consolidated a repeated test fixture literal.react-doctorpatch.For configs that never touch
categories, scan output is byte-identical — the change can only remove force-enabled rules, never add any.Test plan
packages/core: fullpnpm testsuite green;tests/oxlint-config-settings.test.tscovers category-can't-enable / category-still-restamps / rule-key-enables / alias-enables / off-by-defaultpackages/react-doctor: fullpnpm testsuite green (2,041 passed)turbo typecheck+vp fmtclean🤖 Generated with Claude Code
Note
Medium Risk
Changes which lint rules run for real-world configs that set category severities without per-rule pins; impact is limited to removing unintended rule activations, not adding new ones.
Overview
Fixes a bug where
categoriesseverities (e.g.Maintainability: "warn") were treated as explicit opt-in fordefaultEnabled: falserules, so scans could flood with rules likeforbid-component-propsandreact-in-jsx-scopeeven when those rules were never named underrules.createOxlintConfignow gates opt-out rules on a rule-only severity lookup (canonical key or legacy alias); category bumps still re-stamp severities for rules that are already on.react-doctor rulesuses the same logic viaresolveEffectiveRuleSeverity, and docs/schema state that category maps never activate opt-out rules.Configs that only touch
categoriesmay see fewer diagnostics; explicitrulesentries (or aliases) are still required to turn opt-out rules on.Reviewed by Cursor Bugbot for commit 1c89ea3. Bugbot is set up for automated code reviews on this repo. Configure here.