Working on the docs
This documentation site (docsite/) is a separate project from the Cargo
workspace — its own build graph, its own gate, its own dependency stream. This
page covers how it is organized and how to change it without breaking the
gate. The governing contract is
.claude/rules/docsite.md;
the authoring mechanics live in the docsite, docsite-sync, and
mermaid-diagrams skills.
A separate project
Section titled “A separate project”docsite/ is Astro Starlight under bun. It has its own package.json,
bun.lock, node_modules, and dist/. It is not a member of the Cargo
workspace and not part of ui/control-plane’s bun project — it shares
zero dependencies with either by design. Workspace CI does not build it; a
path-filtered workflow does.
Two consequences follow from that isolation:
- It consumes outputs, never source. The site may ingest artifacts of
the other stacks — the workspace version from
apomesh-bump -- current, a committed OpenAPI snapshot — but never their source trees as build inputs. Documentation about code is written by reading HEAD, not by importing it. - It is never a contract-parity surface. A wire or closed-enum change does not sweep the docsite. Doc updates for code changes ride the sync loop below, not the parity gate.
The build gate
Section titled “The build gate”cd docsite && bun install && bun run buildA red build never lands. The gate catches broken sidebar slug:
references (a moved or missing page fails the build), invalid frontmatter,
Mermaid render errors, and the coverage check. It does not catch, so grep
for these by hand after moving pages:
- relative
../..links that 404 — use root-relative/section/page/links; - links that only resolve through a
redirectsentry — rewrite to canonical; - stale
#anchorfragments after a heading rename.
astro.config.mjs is not hot-reloaded — restart bun run dev after sidebar
edits.
The six-section topology
Section titled “The six-section topology”Pages are classified by Diátaxis type crossed with audience:
| Section | Type | Audience |
|---|---|---|
getting-started/ | Tutorial | any newcomer |
concepts/ | Explanation | anyone needing the “why” |
operate/ | How-to | operators running the stack + console |
build/ | How-to | SDK consumers + integrators |
contribute/ | How-to + explanation | developers building apomesh |
reference/ | Reference | look-up, all roles (autogenerated) |
Classify a page before writing it — the Diátaxis type decides its home. A
few IA rules keep the sidebar coherent: group by audience or concern, never by
crate (crate-shaped pages live only under reference/); no single-page groups;
keep journey depth to at most three (Section → Group → page, only the
collapsed reference/ trees go deeper); and one canonical home per concept —
every other page links there rather than re-explaining.
coverage.json and the sync loop
Section titled “coverage.json and the sync loop”Two tracked files keep the site honest against the moving codebase.
docsite/coverage.jsonis the semantic index: every workspace crate is classifieddocumented,planned, orinternal. Adocumentedentry must name a page slug that exists; aninternalentry gives a one-line reason;plannedis the visible documentation backlog.scripts/check-coverage.mjsruns as part of the build and discovers crates by globbing the workspace, so a new crate cannot land silently undocumented — the author classifies it or the build goes red.docsite/.sync-state.jsonanchors the last commit the docs were reconciled against (lastSyncedCommit) plus anypendingwork-list. Thedocsite-syncskill owns the loop: diff the range since the anchor, map changed paths to doc targets, update one target per iteration, and advance the anchor only after honest triage. A stale anchor is visible debt; an anchor advanced past unexamined commits is a defect.
Content vs. tooling — two rungs
Section titled “Content vs. tooling — two rungs”Changes land on one of two rungs, per
.claude/rules/docsite.md:
- Content edits — pages, sidebar entries, coverage or sync-state flips —
ride rung 1: commit direct to
main, but only after the local build gate passes. - Tooling / config / component edits —
package.json, the structure ofastro.config.mjs,scripts/,src/components/, the CI workflow — ride rung 2: a lean gated PR.
The site derives; the code wins
Section titled “The site derives; the code wins”docs/architecture.md
and the rest of docs/ remain the canonical in-repo sources. The docsite
derives from them and from the code, and never claims authority over
either. Where the docsite and the code disagree, the docsite is the bug. Rule
4’s “directional docs don’t inventory state” binds docsite prose too: no typed
version strings and no drift-prone counts — the version is injected at build
time from the bump tool.
Next steps
Section titled “Next steps”- Deep authoring mechanics (sidebar levers, redirects, the Mermaid component,
the
coverage.jsoncontract) live in thedocsiteskill. - Post-merge sync (“are the docs current?”) is the
docsite-syncskill.