Documentation tooling and CI
Note
Project policy: accepted. The tools that build and check the documentation, how to run them locally, and what CI enforces.
The documentation is checked as strictly as code. Every tool used here is written in Rust (ADR-0002), and every check that runs in CI can be run locally with the same command.
Tools
| Tool | Version | Purpose | Configuration |
|---|---|---|---|
cargo xtask docs-check | in repository | Project-specific rules from the style guide | xtask/ |
| mdBook | 0.5.4 | Builds the documentation site from docs/ | docs/book.toml, docs/SUMMARY.md |
| mdbook-mermaid | 0.17.1 | Renders Mermaid diagrams in the built site | [preprocessor.mermaid] in docs/book.toml |
| lychee | 0.24.2 | Checks links and heading anchors | lychee.toml |
| typos | 1.50.1 | Finds spelling mistakes | typos.toml |
| rumdl | 0.2.73 | Lints Markdown structure | .rumdl.toml |
Versions are pinned in .github/workflows/docs.yml.
Upgrading a tool is a pull request that changes the pin and this table together.
Setting up locally
-
Install Rust with rustup. The repository’s
rust-toolchain.tomlselects the pinned toolchain automatically; see Toolchain and MSRV. -
Install the prebuilt tools:
$ cargo install cargo-binstall $ cargo binstall --locked mdbook@0.5.4 mdbook-mermaid@0.17.1 lychee@0.24.2 typos-cli@1.50.1 rumdl@0.2.73
Running the checks
Run these from the repository root. They are the same commands CI runs, in the same order.
$ cargo fmt --all --check
$ cargo clippy --workspace --all-targets -- -D warnings
$ cargo xtask docs-check
$ rumdl check .
$ typos
$ lychee --config lychee.toml './*.md' docs
$ mdbook build docs
The built site is written to target/book/.
To preview it with live reload, run mdbook serve docs.
What cargo xtask docs-check enforces
| Check | Rule |
|---|---|
| Metadata | Line 1 of every page is a valid shiin-doc comment with known values |
| Title and banner | Lines 3 to 6 hold the title and the banner that matches the metadata |
| Table of contents | SUMMARY.md and the pages on disk match in both directions, with no duplicates |
| Requirement IDs | Defined once, only in their owning kind=spec page; every mention refers to a defined ID |
| Threat IDs | Defined once, only in the threat model; every mention refers to a defined threat |
| ADRs | Unique numbers, ADR-NNNN: titles, listed in the index; every ADR-NNNN mention exists |
| Terminology | Requirement keywords only on specifications; deny as the decision value rather than the word it replaces; no exclusionary terms; no mischaracterization of Shiin; the former working name only where allowed |
| JSON Schemas | Draft 2020-12, urn:shiin:schema: identifiers matching file names, valid against the metaschema, and compilable with cross-schema references |
| Examples | JSON blocks after validate markers match their schema; blocks after validate-fail markers do not |
| Test vectors | Every file in spec/test-vectors/ matches the test-vector schema |
The implementation lives in xtask/src/docs_check/, with one module per group of checks.
What the other tools enforce
- rumdl applies its default Markdown rules, with line length disabled because pages use one sentence per line.
- typos checks spelling across the repository, excluding build output and vendored files.
- lychee runs offline on pull requests and checks that every relative link and heading anchor resolves.
- mdBook fails the build if
SUMMARY.mdreferences a missing page or a preprocessor fails.
Vendored files
docs/mermaid.min.js and docs/mermaid-init.js are the browser-side Mermaid renderer used by the built site.
They are generated by mdbook-mermaid install docs and are not edited by hand.
When mdbook-mermaid is upgraded, rerun that command and commit the regenerated files.
Linters exclude these files.
CI
The docs workflow in .github/workflows/docs.yml runs every check above on each pull request and on pushes to main.
- The workflow has read-only
contentspermission and does not persist checkout credentials. - Third-party actions are pinned by commit SHA, with the release tag in a comment.
- A failing check blocks merging once branch protection is configured; see the maintainer handbook.
Planned additions
The weekly external-link workflow, 180-day specification-review warning, and main book-publication workflow are now configured for the first alpha.
cargo xtask link-health checks public links; --report-issue explicitly enables the CI bot’s deduplicated issue report.
Pull-request link checks remain offline.
| Addition | When |
|---|---|
Validating TOML policy examples with shiin policy validate | v0.1 |
Comparing reference/cli.md with the CLI’s generated help | v0.1 |
| Versioned documentation per release | After 1.0 |
Adding a check
- Write the rule in the style guide and mark it (checked).
- Implement it in a module under
xtask/src/docs_check/, reporting problems with file and line. - Fix every existing page so the check passes.
- Update the table in What
cargo xtask docs-checkenforces.