Skip to content

ADR-0008 — Pin MkDocs 1.x, reevaluate docs engine in October 2026

Status

accepted

Context

ADR-0007 committed the project to MkDocs + Material for MkDocs as the category choice. That ADR was written against a stable upstream assumption: MkDocs 1.x is maintained, Material for MkDocs is maintained, they work together.

During Phase 1 of the docs reorganization the first mkdocs build --strict run printed two unexpected banners into its stderr. Investigation turned up a 2026-Q1 ecosystem split that ADR-0007 did not account for:

  • MkDocs 1.x has had no commits for ~18 months. Its original author/sole maintainer is pursuing an incompatible ground-up rewrite ("MkDocs 2.0") that removes the plugin system entirely, has no migration path, uses a closed contribution model, and as of the research date lacks an explicit license.
  • Material for MkDocs responded in November 2025 by entering maintenance mode: version 9.7.0 was the last feature release on 2026-02-18, with critical bug fixes and security updates committed only until November 2026. The Material team is building a replacement engine ("Zensical") from scratch rather than fork MkDocs.
  • ProperDocs is a third-party drop-in fork of MkDocs 1.x published 2026-03-15 by a former MkDocs maintainer (@oprypin). Several of its author's plugins (which we depend on transitively) print a promotional banner into mkdocs build's stderr advocating for ProperDocs. The banner is not malicious, but the practice of injecting promotional output into other projects' build pipelines is a trust signal about maintainership style.

The upshot: ADR-0007's category choice (MkDocs + Material) is correct today but has a known end-of-life date that was not visible when ADR-0007 was written. Acting on ADR-0007 without acknowledging this risk would be inconsistent with ADR-0006 — we would be planning around a stable-upstream assumption we have direct evidence against.

The options on the table once this context was clear:

  • (A) Pin MkDocs 1.x and Material at known-good versions, build an explicit reevaluation point into the plan. No code migration now; accept the EOL date as a known risk and commit to revisit before it hits.
  • (B) Switch to ProperDocs. Drop-in, active maintainer. But the maintainer's malvertising practice is a trust signal, the Material team is not supporting ProperDocs, and the project would inherit a "bus factor 1" dependency.
  • (C) Wait for Zensical. Not yet released.
  • (D) Switch to a different engine entirely (Sphinx, Docusaurus, etc). Throws away the reorganization plan and restarts authoring under a different generator.

Decision

Pin MkDocs 1.x + Material for MkDocs at known-good versions, lock the full transitive dependency tree, and schedule a formal reevaluation of the docs engine for October 2026.

Concretely:

  • docs/requirements.txt uses == exact pins for every direct dependency. No >= ranges anywhere.
  • docs/requirements-lock.txt is a full pip freeze of the docs venv, regenerated by wiping the venv and reinstalling from requirements.txt. It is the authoritative source for reproducible installs.
  • scripts/docs-build.sh and scripts/docs-serve.sh set DISABLE_MKDOCS_2_WARNING=true to silence the ProperDocs promotional banner. This does not change any package behavior; it only suppresses the stderr output. The separate Material team's MkDocs-2.0 EOL notice remains visible because it is load-bearing information, not an ad.
  • mkdocs-macros-plugin has been removed from the dependency list. It was the transitive source of the ProperDocs banner (confirmed empirically during Phase 1) and we were not using its templating features anyway.

Reevaluation trigger: October 2026, chosen as one month before Material for MkDocs's stated end of security-fix window. At that point the project has three plausible paths:

  • Zensical is released and works — migrate to it. Material team is the natural successor.
  • Zensical is still not released — freeze the pinned state, accept no security updates, and revisit again in Q1-2027.
  • Zensical is abandoned and Material's EOL holds — pick a fresh generator. Sphinx and Docusaurus are the most likely candidates at that point.

The choice at reevaluation time is a new ADR that supersedes this one. This ADR does not predict the choice.

Consequences

Wanted:

  • We ship the reorganization now without waiting on an unpredictable ecosystem. The content work (topic hierarchy, ADR framework, research index) is valuable regardless of which engine ultimately renders it.
  • Pinned dependencies mean the build is reproducible across machines and across time — an old checkout from 2026-Q2 still builds in 2027 because every package is version-locked.
  • The October 2026 reevaluation point is written down in a first-class document (this ADR) instead of living as a session note.

Accepted as cost:

  • We inherit the risk of a security CVE in an unmaintained dependency between now and the reevaluation. The blast radius is limited to a static-site-generator toolchain that runs on developer machines and in CI — not on production servers — so the practical risk is low.
  • Possible future rewrite if Zensical or a successor is incompatible. We accept this because the authoring layer is pure Markdown + YAML frontmatter, and the migration cost of moving Markdown files between generators is bounded.
  • We are using a pinned version of the mkdocs-git-revision-date-localized-plugin and mkdocs-redirects packages, which are maintained by the same person who authored ProperDocs. We accept this because the packages themselves are functional and the promotional behavior is cosmetic once silenced.

Evidence

References

  • ADR-0006 — the discipline that required this ADR to exist at all, since ADR-0007 was written without the ecosystem context.
  • ADR-0007 — the category decision this ADR ratifies under current risk conditions.