Skip to content

feat: add rule severity, make parse diagnostics non-blocking - #34

Merged
onefloid merged 4 commits into
mainfrom
feat/severity
Aug 9, 2026
Merged

feat: add rule severity, make parse diagnostics non-blocking#34
onefloid merged 4 commits into
mainfrom
feat/severity

Conversation

@onefloid

@onefloid onefloid commented Aug 8, 2026

Copy link
Copy Markdown
Member

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>.severity in 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.

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.
@onefloid
onefloid merged commit ac15aea into main Aug 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant