Skip to main content

ADR-0025: Docusaurus documentation site and documentation with every change

StatusAccepted
Date2026-10-09
Issue#48
Pull requestThe pull request that introduced website/ and .github/workflows/docs.yml
RelatedADR-0021

Context and problem statement​

Until this decision the documentation was README.md, PRD.md, VERSIONS.md and four loose Markdown files in docs/ (deployment.md, security.md, storage.md, webhooks.md). The v2.5 hardening work (#57) changed delivery semantics, the security model, configuration and the API in about twenty pull requests, and the reasons behind those changes lived only in issue and PR descriptions. Upcoming work (Converger Protocol v1, SDKs, new adapters) needs a place for a protocol specification, JSON Schemas with resolvable $id URLs, API references and operator guides.

#48 proposed ExDoc (mix docs) published to GitHub Pages. Two more requirements came from the project owner: the site should look and work like the documentation of the sibling project chativa (chativa.aimtune.dev, Docusaurus), and the documentation must be updated with every change, including a record of each architectural decision.

Decision drivers​

  • One source of truth: documentation is reviewed in the same pull request as the code, and code and other docs keep linking to docs/*.md by path.
  • Narrative documentation (guides, concepts, architecture with diagrams, ADRs, a wire protocol) matters more than generated API reference for an application (Converger is not a library consumed via Hex).
  • Static hosting on GitHub Pages under converger.aimtune.dev, the same setup as chativa, plus static JSON Schemas under /schemas/.
  • Documentation drift must be caught mechanically, not by reviewer memory.
  • Must not slow down or destabilise the Elixir CI.

Considered options​

  1. ExDoc (mix docs) with extras - the Elixir-native generator, as #48 proposed.
  2. Docusaurus site in website/ reading the repository's docs/ - same stack and conventions as chativa.
  3. Docusaurus with its own website/docs/ copy - chativa's exact layout.
  4. GitHub wiki / Markdown in the repository only - no site.

Pros and cons of the options​

ExDoc​

  • Good, because it is the standard for Elixir and renders module docs and typespecs.
  • Bad, because the value for an application is in narrative pages; ExDoc extras have no sidebar categories, versioned navigation, Mermaid by default, landing page or custom pages, and would look nothing like the sibling project's site.
  • Bad, because publishing extra static assets (protocol JSON Schemas) and a custom domain needs hand-written workflow glue anyway.

Docusaurus reading docs/​

  • Good, because it matches chativa (navbar, footer, colour mode, Mermaid, edit links, GitHub Pages deployment), so both projects share conventions.
  • Good, because docs/ stays the single source of truth: existing paths keep working and other pull requests can add pages (for example docs/protocol/) that appear automatically through autogenerated sidebars.
  • Good, because the production build fails on broken links.
  • Bad, because it adds a Node toolchain and an npm lockfile to an Elixir repository (isolated in website/ and its own workflow).

Docusaurus with website/docs/​

  • Good, because it is exactly chativa's layout.
  • Bad, because existing docs/*.md would have to move or be duplicated, breaking links from code, error messages and other docs.

Wiki or plain Markdown​

  • Good, because there is nothing to build.
  • Bad, because wikis are not reviewed with the code, and plain Markdown gives no navigation, search, diagrams or hosting for schemas.

Decision​

Chosen option: "Docusaurus site in website/ reading the repository's docs/", because it keeps documentation next to the code in the same review, matches the sibling project's site, and supports the protocol specification and schema hosting the v3.0 work needs.

Together with the site, documentation becomes part of the definition of done:

  • Every pull request updates the affected docs/ pages. Architectural decisions are recorded as ADRs in docs/adr/ (MADR format, see How we write ADRs). The rule is written in AGENTS.md and the contributing guide.
  • The pull request template has a documentation checklist.
  • The "Docs required" CI job fails when lib/, config/ or priv/repo/migrations/ change without any change under docs/. The no-docs label is the explicit, visible escape hatch for changes with no documentation impact; the reason goes in the PR description.

ExDoc module documentation can still be added later for the internal API; it does not replace the site.

Consequences​

Positive​

  • Decisions from #1-#20 and #54-#56 are recorded with their context and rejected options (ADR-0001 to ADR-0024).
  • Broken internal links fail the build (onBrokenLinks: "throw").
  • Protocol JSON Schemas are published at https://converger.aimtune.dev/schemas/protocol/v1/ when priv/protocol/v1/ exists, so their $id URLs resolve.

Negative and trade-offs​

  • A Node toolchain (Docusaurus 3.10, React 19) and website/package-lock.json must be kept up to date; Dependabot covers /website.
  • The "Docs required" check is a heuristic: it checks that some file under docs/ changed, not that the right page did. Review still matters.
  • Small code fixes without documentation impact need the no-docs label, which adds a step.

Follow-ups​

  • Remaining parts of #48: LICENSE, SECURITY.md, CODE_OF_CONDUCT.md, issue templates, folding VERSIONS.md into CHANGELOG.md.
  • OpenAPI specification and Swagger UI (#45) can be embedded in the site.

Implementation​

  • website/: Docusaurus 3.10.1 with TypeScript config (docusaurus.config.ts): docs plugin path: "../docs", routeBasePath: "/", edit links to docs/, Mermaid theme, future.v4 and faster, markdown.format: "detect" (.md is CommonMark, .mdx is MDX), numberPrefixParser: false so ADR URLs keep their number. The sidebar is autogenerated from sidebar_position and _category_.json; a sidebarItemsGenerator moves the root-level deployment.md, security.md, storage.md and webhooks.md into their sections without moving the files.
  • .github/workflows/docs.yml: "Docs required" and "Build site" on pull requests; build plus actions/deploy-pages on pushes to main and manual runs. website/static/CNAME sets converger.aimtune.dev.
  • .github/pull_request_template.md: documentation checklist.