ADR-0025: Docusaurus documentation site and documentation with every change
| Status | Accepted |
| Date | 2026-10-09 |
| Issue | #48 |
| Pull request | The pull request that introduced website/ and .github/workflows/docs.yml |
| Related | ADR-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/*.mdby 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
- ExDoc (
mix docs) with extras - the Elixir-native generator, as #48 proposed. - Docusaurus site in
website/reading the repository'sdocs/- same stack and conventions as chativa. - Docusaurus with its own
website/docs/copy - chativa's exact layout. - 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 exampledocs/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/*.mdwould 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 indocs/adr/(MADR format, see How we write ADRs). The rule is written inAGENTS.mdand the contributing guide. - The pull request template has a documentation checklist.
- The "Docs required" CI job fails when
lib/,config/orpriv/repo/migrations/change without any change underdocs/. Theno-docslabel 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/whenpriv/protocol/v1/exists, so their$idURLs resolve.
Negative and trade-offs
- A Node toolchain (Docusaurus 3.10, React 19) and
website/package-lock.jsonmust 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-docslabel, which adds a step.
Follow-ups
- Remaining parts of #48:
LICENSE,
SECURITY.md,CODE_OF_CONDUCT.md, issue templates, foldingVERSIONS.mdintoCHANGELOG.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 pluginpath: "../docs",routeBasePath: "/", edit links todocs/, Mermaid theme,future.v4andfaster,markdown.format: "detect"(.mdis CommonMark,.mdxis MDX),numberPrefixParser: falseso ADR URLs keep their number. The sidebar is autogenerated fromsidebar_positionand_category_.json; asidebarItemsGeneratormoves the root-leveldeployment.md,security.md,storage.mdandwebhooks.mdinto their sections without moving the files..github/workflows/docs.yml: "Docs required" and "Build site" on pull requests; build plusactions/deploy-pageson pushes tomainand manual runs.website/static/CNAMEsetsconverger.aimtune.dev..github/pull_request_template.md: documentation checklist.