Appearance
Building these docs
This site is VitePress. The content is ordinary markdown under documentation/, so if the toolchain is ever swapped out, the pages survive it.
Commands
bash
cd documentation && npm installbash
npm run dev # local preview with hot reload
npm run build # static site into .vitepress/dist
npm run preview # serve the built outputThe build output is plain HTML, CSS and JS with no runtime service behind it — search is a client-side index built at compile time, so nothing phones home.
Why VitePress
The app uses importmap and Propshaft and has no Node build pipeline; this is deliberately self-contained in its own directory with its own package.json, and touches nothing in the Rails asset path. Python packaging was not available on the target machine, which ruled out MkDocs.
Dev-server advisory
vitepress@1.6.4 depends on an esbuild version with a known advisory (GHSA-67mh-4wv8-2f99): the development server allows any website to send it requests and read the response.
It affects npm run dev only — never the built static output — and there is no fix available within VitePress 1.x. VitePress 2 is still alpha and not appropriate here. Do not run the dev server on an untrusted network; the built site carries no such exposure.
Screenshots
The screen-by-screen pages use real captures from the design-audit harness, so they cannot drift into showing a UI that never existed.
bash
DESIGN_AUDIT=1 mise exec -- bin/rails test test/design_audit/design_audit_capture_test.rb
documentation/screenshots.shThe audit writes 2x full-page PNGs (~800KB each) into tmp/design_audit/. The script copies the subset the docs reference into public/screens/, downscaled to 1400px wide and converted to WebP — about a quarter of the bytes, and still sharp on a retina display.
To add one, append its name to SCREENS in the script and reference it from a page:
markdown
Screenshots are wrapped in a link to the full-size image at build time — write a plain image and the wrapping happens for you, so a screenshot added later cannot silently miss it.
For a detail like a form, add a crop instead. A form inside a full-page capture scaled to a 690px column is unreadable, so screenshots.sh has a CROPS list taking a region of an existing capture:
name|source screen|WIDTHxHEIGHT+X+YGeometry is in the 2x capture's own pixels.
Re-run both commands after a visual change. A screenshot showing a UI that no longer exists is worse than none, because it is trusted.
Checking links
bash
python3 documentation/check_links.pyVerifies every internal link, every image reference, and that every page is reachable from the sidebar. VitePress will happily build an orphaned page or a missing image; this will not.
Structure
| Directory | Content |
|---|---|
guide/ | What Verity is, concepts, the principle it runs on |
operators/ | Day-to-day use |
risk/ | The risk model in detail |
providers/ | Checks, provider lifecycle, calendars |
api/ | API reference and webhooks |
admin/ | Account configuration |
screens/ | Screen-by-screen anatomy, with captures |
development/ | Setup, architecture, testing, extending |
Navigation is defined in .vitepress/config.mjs — a new page must be added to the sidebar there, or it builds but is unreachable.
Writing rules
Match the product's own standard. In particular:
- Do not describe behaviour you have not read in the code. Docs that invent behaviour are worse than no docs, because they are trusted.
- Where the product deliberately refuses to answer — not assessed, could not be read, no rule configured — say why. Those are the parts users misread as bugs.
- Prefer a table to a list of sentences when the content is genuinely tabular.
- State known limitations plainly. There is no pagination on the entities endpoint, no automatic webhook retry, and a flaky design-audit suite; all three are documented rather than omitted.
Relationship to docs/
The repository's docs/ directory holds internal design notes, provider API specifications and the operability runbook. Those are working documents for the team.
This site is the product documentation. Where it needs a detail from docs/, it restates it rather than linking, because the published site should be readable without the repository.