Safeguard
Developer Tools•

When should you retire or rewrite a custom static analysis rule?

Retire a rule when the risky API is gone, a better check exists, or precision stays low. Rewrite when the idea is right but the matching is wrong.

Safeguard Security Team
4 min read

Retire a custom rule when the code it guards no longer exists, a maintained rule now covers the same ground, or its precision stays low after real tuning. Rewrite it when the intent is still valuable but the matching logic is wrong. Review every rule on a schedule so the decision is deliberate.

Why rules need an end date

Rules are written against the code and tools of one moment. The risky wrapper gets deleted. The framework adds a safe default. The language changes its syntax tree. A rule that nobody revisits keeps running, costing build time and developer attention for a risk that may no longer exist.

Signals to retire

  1. The target is gone. Search the repository for the API or pattern. If nothing uses it, the rule can go.
  2. A better check exists. A newer ruleset, a compiler option or a type system feature now prevents the problem outright. Prevention beats detection.
  3. Persistent low precision. After two rounds of tuning, most findings are still dismissed.
  4. No owner. Nobody can answer questions about it.
  5. Never fires. Check first that it still works with a test file, then ask whether the pattern is still possible.
  6. Constant suppression. If most findings are suppressed, the rule is functioning as noise.

Signals to rewrite

  • Dismissals cluster on one cause, such as test files or generated code.
  • The rule matches names where it should match types.
  • New language syntax is not covered, so it misses cases.
  • Its message is vague, and developers misread what to do.

Decision table

ObservationAction
Pattern no longer in the code, API removedRetire
Similar maintained check existsRetire after comparing results on your code
Real findings, but many false positives from one causeRewrite or scope
Rarely fires, still possibleKeep, add a test file to prove it works
Low precision across the boardMove to warn, then decide
Underlying library or language changedRewrite and retest

How to retire safely

  1. Move the rule to warn for a cycle and watch whether anything real appears.
  2. Run old and new checks side by side if you are replacing it.
  3. Remove it in a reviewed commit that links to the evidence.
  4. Delete its entries from any baseline or suppression file, so stale entries do not linger.
  5. Keep a short log: rule id, date, reason. It helps the next person who wants to add something similar.

ESLint's documentation shows a version of this thinking in its rule metadata, where a rule can be marked deprecated and can name its replacement. Even if your tool does not support that, you can copy the habit: leave a visible pointer from the old rule to what replaced it.

Review cadence

Put a review date in each rule's documentation. Quarterly is a common starting point. At review, answer three questions: is the target still present, what is the precision, and who owns it?

Quick check

Is a rule that never fires a good rule?

Not necessarily. It may be preventing the problem, or it may be broken. Run it against a file that should trigger it to find out which.

Can I just disable a noisy rule?

You can, and sometimes should. Record why and keep the decision visible, so the risk it covered is not forgotten.

Safeguard's scanning covers dependencies and SBOMs, and its reachability analysis helps show which findings your code can actually call. You can run a free scan on a repository.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.