ADR-0007: Single Source of Truth for Documentation
This ADR is automatically copied from docs/adr/0007-single-source-documentation.md in the repository.
Edit the source file to update this page.
Status
Accepted
Context
This project has two categories of documentation:
1. Hybrid documentation (GitHub + Docusaurus)
Files that must render correctly in both contexts:
README.md- First thing visitors see on the repositoryCONTRIBUTING.md- Guide for contributorsdocs/adr/*.md- Architecture Decision Records
These files contain plain Markdown without embedded PlantUML/Mermaid diagrams. They are the primary source on GitHub and should also appear in the Docusaurus site.
2. Docusaurus-first documentation
Files in test-docusaurus-site/docs/examples/ that contain PlantUML/Mermaid diagrams:
- Example pages (e.g., Little Red Riding Hood sequence diagrams)
- Plugin architecture diagrams
- Domain model examples
These are Docusaurus-only because GitHub does not render PlantUML (only limited Mermaid support). They require the remark-kroki-a11y plugin and Kroki service to generate images.
This ADR addresses the first category: hybrid documentation.
The challenge
For hybrid documentation, GitHub and Docusaurus have conflicting requirements:
- GitHub renders plain Markdown files directly
- Docusaurus requires front-matter (YAML header with
id,title, etc.) for proper navigation - Docusaurus uses different link resolution (relative paths within the docs folder)
Maintaining two copies leads to:
- Inconsistencies when one copy is updated but not the other
- Double maintenance effort
- Risk of outdated information
Options
Option 1: Duplicate documentation
Maintain separate files for GitHub and Docusaurus.
Pros:
- Each context gets optimized content
- No build-time processing needed
Cons:
- Double maintenance
- Inevitable inconsistencies
- Violates DRY principle
Option 2: Docusaurus as source, symlinks for GitHub
Use Docusaurus docs as the source and symlink from root.
Pros:
- Single source
Cons:
- Front-matter visible on GitHub (ugly)
- Symlinks don't work well on all platforms
- Links in Docusaurus format don't work on GitHub
Option 3: GitHub as source, copy with transformation at build time
Maintain files in GitHub-friendly locations (root README.md, CONTRIBUTING.md, docs/adr/) and copy them to Docusaurus with transformations.
Pros:
- Single source of truth
- GitHub renders files natively (no front-matter clutter)
- Docusaurus gets proper front-matter and navigation
- Links can be transformed for each context
Cons:
- Requires build-time script
- Generated files must be gitignored
- Slightly more complex setup
Option 4: Use Docusaurus plugin for external docs
Use a Docusaurus plugin that can import external Markdown files.
Pros:
- No custom scripts needed
Cons:
- Plugin dependency
- Less control over transformations
- May not handle all edge cases (links, front-matter)
Decision
We choose Option 3: GitHub as source, copy with transformation at build time.
The start-docs.sh script (and equivalent logic in the GitHub Actions workflow) copies:
README.md→test-docusaurus-site/docs/readme.mdCONTRIBUTING.md→test-docusaurus-site/docs/contributing.mddocs/adr/*.md→test-docusaurus-site/docs/adr/*.md
During copy, the script:
- Prepends Docusaurus front-matter (id, title, sidebar_label, description)
- Adds an info admonition noting the file is auto-copied
- Transforms links:
docs/adr/README.md→./adr/(index page)docs/adr/...→./adr/...(relative Docusaurus paths)CONTRIBUTING.md→./contributing
The generated files are listed in .gitignore to prevent committing duplicates.
Consequences
Positive
- Single source of truth for all documentation
- GitHub users see clean Markdown without Docusaurus artifacts
- Docusaurus site has proper navigation and styling
- ADRs automatically appear in sidebar (using
autogenerateddirective) - New ADRs only need to be added to
docs/adr/, no sidebar updates needed
Negative
- Developers must run
start-docs.shto see documentation locally in Docusaurus - CI/CD pipeline must include the copy logic
- Links in source files must use GitHub-relative paths (transformed at build time)
Neutral
- The pattern is documented in README.md under "Single Source of Truth"
- Info admonitions in Docusaurus pages indicate the source location
Actions
- ✅ Create
start-docs.shscript with copy and transformation logic - ✅ Update
.github/workflows/deploy-docs.ymlwith same logic - ✅ Add generated files to
.gitignore - ✅ Use
autogeneratedsidebar directive for ADRs - ✅ Document the pattern in README.md
References
- Docusaurus documentation on front-matter
- Docusaurus autogenerated sidebars
- DRY principle: Hunt, A., & Thomas, D. (1999). The Pragmatic Programmer. Addison-Wesley.