Custom rule configuration

How a project wires custom rules into the scan: where the files live, how they load, and the surfaces their findings appear on. Writing the rules themselves is covered on Custom rules.

Setup

Point customRulesDir at a directory of rule files in nestjs-doctor.config.json:

{
  "customRulesDir": "./rules"
}

The path resolves against the scanned directory. Rule files export rule objects, one or several per file; other extensions and subdirectories are ignored. Rules load through jiti at scan time, so CI needs no build step, no ts-node, and no tsconfig for them.

Loading and ids

Rule ids are prefixed with custom/, so id: "no-todo-comments" reports as custom/no-todo-comments and can never collide with a built-in rule. A custom rule is toggled by that prefixed id through the same rules and ignore.rules keys built-in rules use, described on Configuration.

An invalid rule produces a warning and never crashes the scan. The warnings appear in CLI output, and the usual causes are:

  • Missing or non-function check export
  • Invalid category or severity values
  • Missing required meta fields
  • Syntax errors in the rule file

Fix the warning and re-run. The rest of the scan continues unaffected.

Surfaces

A rule appears on four surfaces by default:

SurfaceWhere
cliThe console report, the HTML report, and a shared report
prCommentThe pull request summary, its inline review comments, the GitHub annotations, --format sarif and --format gitlab
scoreThe 0-100 number
ciFailure--blocking

--format json is the exception: it carries every finding, with surfaces on each one, so a consumer filters however it wants.

Naming a subset in the rule's meta narrows it:

surfaces: ["cli"],

That rule still shows every finding and still says how to fix it. It never comments on a pull request, never moves the score, and never fails a build. Use it for a rule that encodes a preference rather than a defect, so a project that disagrees is not punished for it.

A project can decide otherwise. surfaces on a rule override replaces what the rule declares:

{
  "rules": {
    "correctness/prefer-readonly-injection": {
      "surfaces": ["cli", "prComment", "score", "ciFailure"]
    }
  }
}

That is how a team that does want a house style enforced puts it back on the score and the build.