Remove Mlinter Rule
Input
<rule id>: the rule to retire, e.g.TRF054. Accept a bare number (54) and normalise it toTRFXXX, zero-padded to three digits.- Optional: the reason for the removal. Ask for one if none is given — it becomes the CHANGELOG entry and the tombstone description, and it is the only record contributors will have of why the rule went away.
Why a tombstone and not a deletion
Rule ids are referenced from outside this repo: # trf-ignore: TRFXXX comments in the transformers
tree, CI configs, and copies of rules.toml passed via --rules-toml. So a removal keeps a tombstone
entry in rules.toml instead of deleting the table:
- The engine drops a deprecated id from
TRF_RULES,TRF_RULE_SPECS,TRF_RULE_CHECKS,DEFAULT_ENABLED_TRF_RULES, themlinter.TRFXXXpublic constants, and--list-rules. Projects that still suppress or configure the id are silently unaffected. - The docs site is the exception: it keeps publishing a page for the id, built from the tombstone and
listed under
Removed ruleson the rule index. A number that used to fire has to stay findable by whoever meets it in an old CI log. - Asking for it explicitly (
--enable-rules TRFXXX,--rule TRFXXX) fails with exit code 2. - A rules TOML that still lists the id as an active rule fails the whole run with exit code 2. The
bundled
rules.tomlis the authority here, so this holds for custom files too. - Leaving
trfXXX.pyon disk while the id is deprecated is also an error, which is what makes a half-finished removal impossible to ship.
Never reuse a retired number for a new rule: the tombstone stays forever, and add-mlinter-rule picks
the next number after the highest trf*.py.
Workflow
Confirm the rule exists and read it.
grep -n "\[rules.TRFXXX\]" mlinter/rules.tomland read the whole table plusmlinter/trfXXX.py.- If the id is already marked
deprecated = true, stop and report that it is already retired. - Summarise for the user what the rule checks and any
allowlist_models/cutoff_dateit carries, so they can confirm this is the rule they mean before anything is deleted.
Replace the TOML table with a tombstone in
mlinter/rules.toml.- Keep the table in place at its original position — ordering in this file is by rule id.
- Delete
default_enabled,allowlist_models,cutoff_date, and the whole[rules.TRFXXX.explanation]table. - Leave exactly:
[rules.TRFXXX] deprecated = true description = "Removed in <version>: <one-line reason>." <version>is the version under development inpyproject.toml. The description is published: it is the whole of the retired rule's docs page and its row in theRemoved rulestable, so write it for someone who just hit the id in a CI log, not as an internal note.
Delete the rule module.
git rm mlinter/trfXXX.pyDelete the tests.
- Delete the rule's own test file,
tests/test_trfXXX.py. - Remove the id from the public-API tests: the
assertEqual(public_api.TRFXXX, "TRFXXX")line and theassertIn("TRFXXX", public_api.__all__)line. grep -rn "TRFXXX" tests/ mlinter/must come back empty except for the tombstone inrules.toml. Watch for helper fixtures or shared source strings that only that rule used, and for any other rule's test that happened to reference it.- No new test is needed for the removal itself:
test_bundled_deprecated_rules_are_fully_retiredloops over every tombstone in the bundledrules.tomland asserts the module and the public constant are gone, so it starts covering the new id automatically.
- Delete the rule's own test file,
Update
CHANGELOG.md.- Under
## [Unreleased], in a### Removedsection (create it if absent), state the id, what it checked, and why it is gone. Add the migration note that projects need no change: mlinter ignores the id, existing# trf-ignore: TRFXXXcomments are harmless, but a rules TOML of their own must mark the ruledeprecated = trueor drop it. - If the removed rule was mentioned in
README.md,docs/index.md, or any other hand-written doc page, update those too.docs/rules/is generated and git-ignored — there is nothing to delete there.
- Under
Verify.
make lint make test make typecheck python -m mlinter --list-rules | grep TRFXXX # must print nothing python -m mlinter --rule TRFXXX # must exit 2 and say the rule is deprecated python -m mlinter --enable-all-trf-rules # must not error on the missing modulemake docs-rulesif the docs toolchain is available, to confirm the generator emits aRemovedpage for the id and lists it underRemoved ruleson the index — not a live rule page, and not nothing at all.
Report.
- The tombstone, the deleted files, the CHANGELOG entry, and what a consumer of mlinter has to do
(nothing, unless they ship their own
rules.toml).
- The tombstone, the deleted files, the CHANGELOG entry, and what a consumer of mlinter has to do
(nothing, unless they ship their own
Reference
- Rule metadata and tombstones:
mlinter/rules.toml - Deprecation handling:
_load_rule_specs,_build_rule_checks,_validate_rule_ids, andBUNDLED_DEPRECATED_TRF_RULESinmlinter/mlinter.py - Public API surface:
mlinter/__init__.py - Rule tests:
tests/test_trfXXX.py - General linter tests:
tests/test_mlinter.py(engine behaviour under "Deprecated rules") - The inverse skill:
.ai/skills/add-mlinter-rule/SKILL.md