Configuration
lucid-lint is configured via a lucid-lint.toml file at the project root (optional) and CLI flags (overrides the file).
File layout
# lucid-lint.toml
[default]
profile = "public"
[rules.sentence-too-long]
max_words = 22
[rules.passive-voice]
max_per_paragraph = 2
Sections
[default]
Top-level defaults applied to the whole run.
| Field | Type | Default | Description |
|---|---|---|---|
profile | string | "public" | One of dev-doc, public, falc |
conditions | array of strings | [] | Active condition tags. See Conditions. |
exclude | array of glob strings | [] | Paths to skip during directory recursion. See Excluding paths. |
[rules.<rule-id>]
Per-rule configuration. The fields available depend on the rule. See the rule pages in Rules reference.
[scoring]
Tunables for the hybrid scoring model. All fields are
optional; missing fields fall back to the shipped defaults
(category_max = 20, category_cap = 15).
[scoring]
category_max = 20
category_cap = 15
[scoring.weights]
sentence-too-long = 3
weasel-words = 2
The [scoring.weights] sub-table is keyed by rule id. Unknown ids are
ignored, so removing a rule in a future version does not break older
configs.
Precedence
From lowest to highest:
- Profile preset (e.g.,
public) lucid-lint.tomloverrides- CLI flags
An unset CLI flag defers to the TOML value; an unset TOML field defers to the profile preset.
Discovery
lucid-lint walks up from the current working directory to the first lucid-lint.toml it finds, stopping at the nearest .git repo boundary. Passing --config <path> skips auto-discovery and loads the given file directly; a missing explicit path is an error, but a missing auto-discovered file is not.
Excluding paths
Large documentation repositories routinely contain generated output,
vendored text, and snapshots that would drown the linter in noise. Use
the exclude field in [default] — or the --exclude <GLOB> CLI flag
— to skip them at discovery time, before parsing.
[default]
exclude = [
"vendor/**",
"**/fixtures/**",
"CHANGELOG.md",
]
Equivalently on the command line:
lucid-lint check --exclude 'vendor/**,**/fixtures/**,CHANGELOG.md' docs
Notes:
- Matching. Globs are matched against the path relative to the
walked root. Passing
lucid-lint check docswithexclude = ["drafts/**"]skipsdocs/drafts/.... - Prune, don’t visit. A matching directory is not descended into — large excluded trees cost nothing to walk.
- Explicit files bypass. If you pass
docs/CHANGELOG.mddirectly on the command line, it is linted even whenCHANGELOG.mdis in the exclude list. If you named the path, you meant it. - Additive. CLI
--excludeand TOMLexcludeare unioned, not overridden. Comma-separate multiple patterns in a single flag, or repeat--exclude.
Silencing rules globally
Markdown documents support
inline-disable directives for local silencing, but
plain text and stdin have no such escape hatch. [[ignore]] fills
that gap — and works uniformly across all input formats.
[[ignore]]
rule_id = "unexplained-abbreviation"
[[ignore]]
rule_id = "weasel-words"
Each [[ignore]] entry removes every diagnostic whose rule_id
matches, across Markdown files, plain text, and stdin. The filter is
applied after all rules have run but before scoring, so the score
reflects the post-filter view too.
Notes:
- Global scope. The filter is not per-file. Inline directives
remain the recommended escape hatch for spot silencing in Markdown
— reach for
[[ignore]]only when a rule is genuinely noisy project-wide. - Unknown ids tolerated. Entries referencing rules that no longer exist are dropped silently, so removing a rule in a future release does not break older configs.
- Future fields. A
reason = "..."field on each entry is tracked as F-suppression-reason-field — when it lands it will be surfaced in reports and optionally required via config.
Per-rule overrides
TOML-driven config is wired rule-by-rule as each Config gains a dedicated accessor. Two rules honour it today:
[rules.readability-score]
[rules.readability-score]
formula = "kandel-moles" # or "flesch-kincaid", "auto"
Pins the readability formula regardless of detected language. auto (default) preserves the F-readability-formulas-extra per-language selection.
[rules.unexplained-abbreviation]
[rules.unexplained-abbreviation]
whitelist = ["WCAG", "ARIA", "ADHD", "LLM"]
Entries are additive over the profile baseline (F31). Use this to restore project-specific acronyms — accessibility standards, domain initialisms, engineering-practice terms — that the v0.2 baseline no longer ships. Each entry is silenced globally across the document, same as if it had been defined inline via Expansion (ACRONYM).
[rules."structure.excessive-commas"]
[rules."structure.excessive-commas"]
max_commas = 2
Overrides the per-sentence comma ceiling (default: 4 / 3 / 2 for dev-doc / public / falc). Must be a positive integer — 0 or negative values are rejected at load time. The override replaces the profile preset; it is not additive.
Tables for other rules parse without error but have no runtime effect. Extending this list is a mechanical per-rule change and will continue through the v0.2.x cycle.
Narrowing the audit with --severity-floor
--severity-floor is a CLI flag (not a config key) that drops
diagnostics below a chosen severity from every output surface —
tty, json, and sarif — and from the score. It accepts info
(default), warning, or error. The filter runs after all rules but
before scoring, so dropped diagnostics do not count toward the score
and the --min-score gate sees the same filtered set.
lucid-lint check --severity-floor=warning path/to/docs
info(default) — keep everything. Identical to the pre-flag behaviour; the flag is a no-op when unset.warning— dropinfodiagnostics (observability signals likereadability.score), keepwarningand above.error— keep onlyerrordiagnostics.
Worked example — a narrow audit on someone else’s repo. You are
reviewing a repository you do not own and want a high-signal pass:
only the diagnostics worth acting on, nothing that would look like
noise in your review notes. Raise the floor to warning and emit
JSON for tooling:
lucid-lint check --severity-floor=warning --format=json path/to/their-repo/docs
Because the floor is applied before scoring, the score you report
reflects only the warning-and-above findings — the info-level
readability.score line never inflates or deflates it. Pair it with
--min-score to gate the review on that same narrowed view. Unlike
[[ignore]], the floor needs no config file, so it is well suited to
a one-off audit of a repo whose lucid-lint.toml you would rather not
touch.
Category subscores follow the active floor. A category subscore
counts only the diagnostics at or above the active floor. Under a
raised floor a category can show a perfect subscore — for example
20/20 — simply because its info-tier diagnostics were filtered out,
not because the prose is clean. A high subscore under a raised floor
therefore does not imply the category is issue-free; drop back to the
default info floor when you want the full picture.
Known limitation — --severity-floor=error currently silences
everything. No rule in this release emits error-tier diagnostics,
so --severity-floor=error filters out every finding and always
reports score 100. The error tier is a legitimate severity reserved
for future rules; until one emits at that tier, error is not a useful
floor.