Skip to content

madr/required-sections

Enforces that an ADR Markdown file contains every heading listed in the sections option.

The rule walks the Markdown AST, collects the text of every heading (any level, with inline markup stripped via mdast-util-to-string, so ## **Status** matches Status), and reports one diagnostic for each required heading that is not present.

  • missingSection — a required heading is not found among the file’s headings. One diagnostic is emitted per missing section. The message is Missing required section: "<section>". The diagnostic carries data.section (the missing heading) and data.found (every heading text seen in the file, for debugging). It is a file-level diagnostic — there is no node to point at.

Heading matching is controlled by matchMode: exact requires the full trimmed heading to equal the required text; startsWith matches any heading that begins with the required text (e.g. Decision Outcome matches Decision Outcome (Architectural)).

A file with the three default required sections:

# ADR-0001: Use mise for runtime management
## Context and Problem Statement
...
## Decision Outcome
Adopted: ...
## Consequences
...
# ADR-0001: Missing context
## Decision Outcome
...
## Consequences
...

Emits 1 diagnostic: Missing required section: "Context and Problem Statement".

OptionTypeDefaultDescription
sectionsstring[]['Context and Problem Statement', 'Decision Outcome', 'Consequences']Required heading texts. Order does not matter.
matchMode'exact' | 'startsWith''exact'How each required entry is compared against a heading. startsWith lets Decision Outcome (Architectural) satisfy Decision Outcome.
import { defineConfig } from 'madr-lint';
export default defineConfig({
rules: {
'madr/required-sections': ['error', {
sections: ['Context', 'Decision', 'Consequences'],
matchMode: 'startsWith',
}],
},
});
VersionApplies
v2yes
v3yes
v4yes

The default sections appear in every MADR version’s template, so heading names are consistent across v2/v3/v4.

Set madr/required-sections to off only when migrating an ADR collection that uses different section names. Prefer overriding sections (and/or switching to startsWith) to preserve some level of validation.

Like all rules, this rule can be suppressed inline — see Suppressing rules.