Skip to content

Adopting on an existing repo

The first time you run madr-lint on a repo with dozens of legacy ADRs, you get hundreds of errors. Fixing them all before your first green build is a non-starter — so madr-lint lets you baseline the existing violations and enforce the rules only on new ones. This is the same pattern as tsc-baseline, ESLint bulk suppressions, and Betterer.

Terminal window
madr-lint
# → 342 errors, 17 warnings
Terminal window
madr-lint --update-baseline
# → Wrote 359 violations across 53 files to .madr-lint/baseline.json

This writes .madr-lint/baseline.json and exits 0. Commit that file.

Terminal window
madr-lint
# → 17 problems hidden by baseline (.madr-lint/baseline.json)
# exit code 0

Every violation already in the baseline is subtracted. Add a brand-new one — a new ADR with a missing section, or a fresh mistake in an old file — and it fails the build as normal:

docs/adr/0060-new-decision.md
madr-lint
# error madr/required-sections Missing required section: "Consequences"
#
# 1 error
# exit code 1

Wire step 3 into CI and you get “no new debt” enforcement from day one, while the legacy debt waits to be paid down on your schedule.

A baselined violation is identified by (file path, rule, messageId) mapped to a count — not by line number or message text. That is deliberate: it means the baseline survives unrelated edits. Insert a paragraph at the top of an ADR and every downstream violation shifts down a few lines, but the baseline still absorbs them because the fingerprint never looked at lines in the first place.

The count is what catches new debt. If a file was baselined with two missingSection violations and a later edit introduces a third, two are absorbed and the third is reported.

See ADR-0007 for the full design and the alternatives we rejected.

Fix some violations, then re-snapshot:

Terminal window
madr-lint --update-baseline

The rewrite prunes anything you have fixed, so the baseline file shrinks by exactly the lines you resolved — a clean, reviewable git diff. Keys are sorted and the file uses a stable 2-space indent, so re-running --update-baseline never produces spurious churn.

To audit everything the baseline is hiding, run without it:

Terminal window
madr-lint --no-baseline
FlagEffect
--update-baselineRun a full lint (ignoring any existing baseline), rewrite .madr-lint/baseline.json, print a one-line summary, exit 0.
--no-baselineIgnore the baseline file entirely; report every violation.
(default)Subtract .madr-lint/baseline.json when it exists; no-op when it does not.
  • The baseline lives at .madr-lint/baseline.json, alongside the cache directory (.madr-lint/cache). Commit the baseline; the cache is safe to gitignore.
  • Paths in the baseline are relative to the project root with forward slashes, so the same file works across macOS, Linux, and Windows CI.
  • Subtraction applies to both errors and warnings, and runs after inline suppression. Use inline madr-lint-disable comments for the handful of legitimate, permanent exceptions; use the baseline for bulk legacy debt you intend to pay down.
  • Editing or deleting the baseline takes effect immediately — it is independent of the content-hash cache, which always stores pre-baseline results.
  • A baseline file that exists but cannot be parsed is ignored with a one-line stderr warning (run --update-baseline to regenerate it). A missing file stays silent.
  • --format json reports how many diagnostics were absorbed via summary.baselineHidden (always present; 0 when no baseline is active). SARIF output is unaffected.
  • core/internal-error (emitted when a rule itself crashes) is never baselined — it signals a bug, not debt.