feat: add rule severity, make parse diagnostics non-blocking - #34
Merged
Conversation
Introduce severity as a first-class concept: every rule carries a weight (error | warning), E110 and S900 become warnings (non-blocking by default because linti cannot tell syntax errors from parser gaps), and projects can override any rule's weight via `rules.<key>.severity` in linti.yaml. Two new flags and config keys control the whole run: - `--fail-on <severity>` / `fail_on:` (default: error) — lowest severity that makes the run fail. Warnings are reported but exit 0. - `--severity <severity>` / `severity:` (default: warning) — lowest severity that is reported; anything below is dropped before the report. Filtering happens before both rendering and the exit code, so a hidden finding cannot fail the run even with `--fail-on warning`. Assisted by: Claude Code
E110 was labeled a rule group named "Error" but defaults to warning severity — confusing now that "error" also names a severity level. Renamed the group/prefix to Parser/P (E110 → P110), kept E110 working via DEPRECATED_IDS, moved rules/errors/ → rules/parser/, and updated docs/tests. Assisted by: Claude Code
S900 (the parser-enforced nesting-depth diagnostic) had no rule class, so linti explain and ALL_RULES.md generation — both registry-only — never saw it. Renamed it into the P (Parser) group as P900, added a synthetic RuleMetadata merged manually into both consumers, kept S900 resolving via a one-cycle deprecation mapping, and documented that rules.nesting_depth.enabled: false only silences the report — the underlying nesting cap and dropped coverage still apply either way. Assisted by: Claude Code
Code-review pass on the severity feature: top-level fail_on/severity typos now warn-and-fallback instead of crashing (matching per-rule severity), lint_process_file rejects an ambiguous custom-linter-without-cfg call instead of silently using wrong defaults, the public API exports Severity and the exit-code/filter helpers, and P900's ID/metadata merge logic is consolidated into one synthetic_rules() helper instead of being duplicated (and partly hardcoded) across rule_explainer.py and generate_all_rules.py.
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.
Every rule now carries a severity (error, warning). E110 and S900 become warnings: linti cannot tell a real syntax error from a gap in its own parser, so those no longer fail a build — they are still reported, with a prominent count in the summary.
Severity is overridable per rule via
rules.<key>.severityin linti.yaml. New flags: --strict (fail on warnings too) and --min-severity (report only at or above a level, filtered before the exit code is decided).S900 also gains config for the first time via
rules.nesting_depth.