Docs with everything
Omniglass ships its documentation as part of the product. The docs are not an
afterthought in a separate wiki; they are Astro Starlight content under docs/, compiled
to a static site and published at docs.omniglass.hyperscaleav.com (and, in time, embedded
into the Go binary to serve at /docs). The architecture is
published ahead of the code, so the design is visible (and reviewable) before, or
alongside, the feature that implements it.
The rule
Section titled “The rule”A feature is not done until the docs that teach it ship in the same PR.
Concretely, a user-facing PR must do one of:
- change
docs/to add or update the page(s) that explain the new behavior, or - carry the
no-docslabel with a one-line justification (pure refactor, internal-only change, etc.).
CI enforces the docs-touched gate. The justification path exists so the gate never blocks a genuine internal change, not as a routine escape hatch.
What “the docs” means here
Section titled “What “the docs” means here”- Architecture pages (
/architecture/) hold the model: the spine plus leaf documents, and the current decisions. Each official term is defined once in the glossary and not redefined in the leaves. - Guides (
/guides/) are how-to pages for someone using the product, split by audience: the operator guide (running the estate from the console and the CLI), the admin guide (managing accounts, access, audit, and config), and deployment (standing the platform up). A slice that ships or changes a user-facing surface ships or updates its guide in the same PR, not just the architecture page, filed under the section that matches who does the task. The architecture page says how the surface is built; the guide says how to use it. - Concept and learning pages teach a concept interactively (see the learning-tool restriction). When a feature introduces a concept an operator must understand, the teaching surface ships with it.
- Contributor pages (
/contributing/) are this doctrine set.
So a feature that adds an operator surface usually touches two homes: the architecture
page (the model) and a guide (the how-to). A purely internal change touches neither and
takes the no-docs label.
Status moves with the code
Section titled “Status moves with the code”The architecture pages are written in the present tense as the target design, so build status is carried alongside the prose, not woven into it, and keeping it current is part of docs-with-everything. A slice that advances a page updates three surfaces in the same PR:
- the page’s status badge moves to its new floor (
DesigntoPartialtoBuilt), which the live grid on implementation status reads directly, so the grid never lies; - the build-progress note on
status.mdxgains the slice’s entry; and - if the shipped code diverges from a page’s design, the page carries an inline note and a decision-log entry (an ADR) lands in the same PR.
Forward-looking intent that is not yet a slice lives in a GitHub epic and is indexed on the
roadmap; it is not written into a page as if built. This is the contract that
keeps the published design describing what exists: a built capability never sits behind a Design badge,
and a divergence is never silent.
Screenshots are generated, not pasted
Section titled “Screenshots are generated, not pasted”Screenshots embedded on a docs page are a generated resource, treated like the OpenAPI
spec or the CLI reference, never a static image dropped in by hand. A page declares what it
needs in screenshots frontmatter (the shot’s id, the console path, its alt, and any
interaction steps), and embeds it in the prose with a directive:
---title: Secretsscreenshots: - id: secrets path: /web/secrets alt: "The Secrets directory: type badges, owner scope, and masked field previews."---
::screenshot{#secrets}That frontmatter is the single source: make docs-shots reads it from every page, drives
the real console (the same binary an operator runs, never a mock), and writes
public/screenshots/<id>.png; the directive renders the figure from the same entry. So the
capture list and the embed cannot drift, a #id with no frontmatter entry (or no captured
image) fails the build, and adding a screenshot is a frontmatter edit, not a code change.
Because the images track the live UI, they are refreshed like any generated artifact: a change
to an operator surface re-runs make docs-shots and commits the new PNGs, and
make docs-shots-check recaptures against the real console and fails if a shot drifts beyond a
small tolerance, the visual sibling of the make gen drift check. (Tolerance rather than an
exact hash because the dev seed’s random UUIDs move a fraction of a percent of pixels between
captures; a real UI change moves far more.)
- No em dashes. Use commas, colons, periods, or parentheses.
- No AI/assistant attribution.
- Write for someone learning the system, not someone who already built it. The same page serves the operator using the product and the contributor extending it.
Publishing
Section titled “Publishing”Docs build in CI on every PR (so a broken docs build fails the PR) and are embedded into the binary at release. The published site is docs.omniglass.hyperscaleav.com.