Skip to content

chore: add markdown linting to pre-commit hooks and CI - #223

Merged
SkyeAv merged 1 commit into
mainfrom
chore/markdown-lint-gates
Oct 19, 2026
Merged

SkyeAv merged 1 commit into
mainfrom
chore/markdown-lint-gates

Conversation

@SkyeAv

@SkyeAv SkyeAv commented Oct 19, 2026

Copy link
Copy Markdown
Owner

Summary

Adds markdown linting as solid gates at both levels, following the repo's existing pattern (fast auto-fixing pre-commit hooks; CI re-runs the same tools with identical pins so local and CI cannot drift).

  • markdownlint-cli2 v0.23.3 — structure rules; scope lives in .markdownlint-cli2.jsonc (globs/ignores exclude machine-generated trees: .ralph/, plans/, PLAN.md, tests/, site/, target/, .tablassert/)
  • Custom rule (.markdownlint/no-unicode-chars.cjs) — bans em/en dashes, unicode arrows (→ ⇒ ⟶ ➜ ➔ ⇨ ←) and unicode bullets (• ‣ ◦), auto-fixed to ASCII (-, ->, <-)
  • html-validate 11.16.4 + html-validate-markdown 6.0.0 — validates ```html code fences inside markdown
  • pre-commit: markdownlint-cli2 mirror hook (--fix, pre-commit stage) + local node html-validate hook
  • CI: new markdown-lint job in ci.yml, standalone like python-lint (node is preinstalled on runners), pins cross-referenced with the pre-commit config
  • One-time remediation: ~740 auto-fixed violations (table pipe padding, blank lines around headings/lists, fence languages) + manual tail (MD036 emphasis → real headings, MD040 languages, preserved a semantically-significant trailing space in docs/configuration/advanced-example.md)

Rule decisions

Rule Setting Why
MD013 line-length off no wrapping convention exists (CHANGELOG prose to 2500+ chars)
MD033 inline HTML off HTML is deliberate (mkdocs docs); well-formedness enforced by html-validate instead
MD046 code style off mkdocs admonitions require 4-space indent; multi-paragraph admonitions are indistinguishable from indented code under plain GFM, and tests/test_docs_style.py bans HTML comments, so inline disables are impossible
MD024 duplicates siblings_only CHANGELOG repeats ### Added per release
MD060 table style compact dominant existing style, measured least-churn

HTML linting design note

html-validate's built-in markdown transformer does not escape < inside inline code spans — prose like `(?<=...)` or `<name>_<version>` (this repo's placeholder convention) parses as start tags with non-suppressible parser-error (rule config, --rule, and disable comments all verified ineffective). The third-party html-validate-markdown transformer is fence-scoped instead: zero false positives, and real HTML blocks are still gated.

Verification

  • npx markdownlint-cli2@0.23.3 → 0 issues in 24 files (exact CI command)
  • npx -y -p html-validate@11.16.4 -p html-validate-markdown@6.0.0 html-validate "**/*.md" → clean (exact CI command)
  • pre-commit run markdownlint-cli2 --all-files / html-validate --all-files → pass
  • uv run --no-sync mkdocs build --strict → green
  • tests/test_docs_style.py → 4/4 (custom rule documented against its prose-arrow ban)
  • negative test: probe with missing blank lines + unicode trio + unclosed <span> in a ```html fence failed both tools; --fix rewrote the unicode
  • tests/ and plans/ untouched

Adds markdownlint-cli2 (structure rules + custom unicode ban) and html-validate
(validates html code fences inside markdown) as pre-commit hooks and a
markdown-lint CI job, following the existing pattern of local hooks re-run
standalone with identical pins in CI.

- .markdownlint-cli2.jsonc: scope source of truth (globs/ignores exclude
  machine-generated trees: .ralph, plans, tests, site, target, .tablassert);
  MD013/MD033/MD046 off with rationale, MD024 siblings_only, MD060 compact
- .markdownlint/no-unicode-chars.cjs: custom auto-fixable rule banning
  em/en dashes, unicode arrows, and unicode bullets (ASCII replacements)
- .htmlvalidate.json: recommended preset + html-validate-markdown transform
  (fence-scoped: the built-in markdown transformer false-positives on '<'
  inside inline code spans, e.g. (?<=..., <name>_<version>)
- .pre-commit-config.yaml: markdownlint-cli2 v0.23.3 mirror hook (--fix) and
  local node html-validate hook; pins cross-referenced with CI
- .github/workflows/ci.yml: markdown-lint job, pinned npx commands
- bulk: one-time --fix remediation (table pipe padding, blank lines around
  headings/lists, code fence languages) plus manual fixes: MD036 emphasis
  promoted to real headings (docs/index.md, docs/configuration/table.md),
  preserved the semantically-significant trailing space in
  docs/configuration/advanced-example.md

Verified: markdownlint 0 issues across 24 files, html-validate clean,
pre-commit hooks pass, mkdocs build --strict green, tests/test_docs_style.py
4/4, tests/ and plans/ untouched.
@coderabbitai

coderabbitai Bot commented Oct 19, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e0855b77-ab0b-4edb-8c84-8da6277ce9b9
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@SkyeAv
SkyeAv merged commit 45fe329 into main Oct 19, 2026
6 checks passed
@SkyeAv
SkyeAv deleted the chore/markdown-lint-gates branch October 19, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant