Skip to main content

Diagram Conventions

These rules keep the architecture diagrams consistent, reviewable in pull requests, and honest about what the code actually does.

The verification bar

Every node and every edge must be traceable to a file. If you cannot cite the import, call site, config entry, or schema line that proves a connection exists, the connection does not go on the diagram.
  • Diagrams describe what the code does, not what it should do.
  • When intended architecture and actual architecture differ, draw the actual one and add a callout naming the gap.
  • Aspirational or planned components are marked with a dashed border and an explicit “planned” label, or they are left out.

Which diagram type to use

Orientation: optimise for a narrow column

The docs content column is roughly 700 px. A diagram wider than that is scaled down, and past about 2× the labels stop being readable. Height is free — the page scrolls. So: tall and narrow renders well; wide and short renders badly. Mermaid lays siblings out across the flow direction, so orientation is the main lever: Getting this backwards is the most common cause of an unreadable diagram. A six-node chain in LR renders 2228 × 95 — a single unreadable ribbon. The same chain in TB is narrow and legible. Check before committing. Render the diagram and look at its viewBox width. Aim for under ~1200; treat anything over ~1400 as needing rework.

Readability limits

  • Maximum ~20 nodes per diagram. Past that, split it or move detail into a table underneath. A context diagram that needs more than 20 is really two diagrams.
  • Use subgraph for boundaries — a deployment boundary, a package, a trust boundary. Never use a subgraph purely for visual grouping.
  • Label every edge with its mechanism, not just its direction: HTTPS, gRPC, Prisma, activity, signal, webhook, OAuth redirect.
  • Line breaks inside node labels use <br/>.

Palette

Colours are semantic — a reader should be able to tell what kind of thing a node is without reading its label. Values derive from the CONA brand palette in docs.json. Applied with a classDef block so every diagram shares one definition:
classDef does not style subgraphs. Mermaid renders an unstyled subgraph in its default pale yellow, which collides with the external colour and makes a container look like a node. Every subgraph needs an explicit class <SubgraphId> boundary line.
The no-hardcoded-colors rule applies to application UI code, where semantic design tokens exist. Mermaid has no token layer and requires literal hex values, so these declarations are the intended exception rather than a violation.
An explicit color: is set on every class because Mermaid does not adapt label text to the fill when the docs site switches between light and dark appearance.

Naming

  • File names are kebab-case and match the page slug: core-domain-map.mdx.
  • Node identifiers are short PascalCase tokens (WebApp, TemporalCloud); the human-readable name lives in the label.
  • Node labels use the real name from the code — the package name, the workflow function, the route path — so readers can grep for it.

Page structure

Each diagram page follows the same shape:
  1. Frontmattertitle and description.
  2. One-paragraph summary of what the diagram covers and what it deliberately omits.
  3. The diagram.
  4. A key or component table listing each node with its source path.
  5. Notes — non-obvious behaviour, known gaps, drift callouts.

Keeping diagrams current

  • Architectural changes update the diagram in the same pull request.
  • The component tables carry source paths precisely so a reviewer can check whether a moved or deleted path invalidates a diagram.
  • Treat a diagram that cannot be verified as stale and fix or delete it.