OHAI Docs

How This Site Works

Historical reference for the retired MkDocs assembly pipeline.

Historical pipeline

This page preserves the previous MkDocs assembly pipeline for migration reference. Fumadocs in rad-app and the reviewed bidirectional content sync now own publication.

This site is an aggregator. Product teams maintain assembly documentation in each product repository, and this repository assembles those packages into one MkDocs Material site.

The important rule is that product assembly content is owned by the product repos. This repo owns the site shell, the build scripts, shared styling, and the automation that turns product docs into the published site.

Source layout

Each Ohai-eligible product repository contributes:

  • assembly-docs/: Markdown pages for the product assembly guide.
  • assembly-docs/assets/: Product images and other page assets.
  • assembly-docs/site.yml: Product slug, title, license, and nav order.
  • assembly-docs/nav.yml: Product-local page order and section title.
  • hardware/bom.csv: The human-owned bill of materials source data.
  • Hardware source folders under hardware/cad/, hardware/pcb/, and hardware/cables/.
  • GitHub topic ohai-assembly-docs after placeholders are replaced and local assembly/build checks pass.

This repository contributes:

  • mkdocs.yml: MkDocs Material configuration for the unified site.
  • docs/index.md: The site homepage.
  • docs/how-this-site-works.md: Cross-product site documentation.
  • scripts/assemble-docs.sh: The main assembler.
  • scripts/render_bom.py: BOM renderer.
  • scripts/bom_categories.py: Shared BOM category label and color map.
  • docs/stylesheets/assembly.css: Shared assembly-site styles.
  • .github/workflows/deploy.yml: Site assembly, build, and publish workflow.
  • .github/workflows/bom-release.yml: Reusable standalone BOM release workflow.
  • templates/: Workflows copied into product repos.

Build flow

The assembler stages each product first, then replaces docs/{product}/ only after that product assembles successfully. Those product folders are assembled output, so avoid hand-editing them. Change product docs in the source product repo instead.

Locally, you can run the same assembly process against nearby checkouts:

pip install -r requirements.txt
ASSEMBLE_LOCAL="$HOME/Github" ./scripts/assemble-docs.sh
mkdocs serve

Without ASSEMBLE_LOCAL, the assembler discovers non-archived researchanddesire/* repos with the ohai-assembly-docs topic. In CI it uses ASSEMBLE_GITHUB_TOKEN for private discovery/cloning when set, prefers per-repo read-only deploy keys when present, then falls back to anonymous HTTPS for public repos.

CI triggers

The main deploy workflow lives at .github/workflows/deploy.yml.

Product repos should copy templates/trigger-assembly-docs.yml to .github/workflows/trigger-assembly-docs.yml and replace <PRODUCT_REPO> with their repository name. That workflow watches assembly-docs/**, BOM CSVs, hardware/pcb/**, and hardware/cables/**. It needs a DOCS_DISPATCH_TOKEN secret with permission to send a repository dispatch to this repo.

The deploy workflow:

  1. Checks out this repo.
  2. Writes any configured read-only deploy keys into the runner temp directory.
  3. Runs scripts/assemble-docs.sh, which discovers topic-tagged products and stages each product before replacing published output.
  4. Installs the MkDocs dependencies from requirements.txt.
  5. Runs mkdocs build.
  6. Uploads the generated site/ directory as a Pages artifact.
  7. Deploys the artifact to GitHub Pages.

BOM rendering

The BOM source of truth is always the product repo's hardware/bom.csv. Rendering is read-only on that CSV.

scripts/render_bom.py validates the canonical 12-column BOM header before it renders. It replaces only the content between these markers in the copied page:

{/* BEGIN GENERATED BOM */} {/* END GENERATED BOM */}

If a product's assembly-docs/bom.md does not contain those markers, the page is left untouched. If hardware/bom.csv has only a header row and no data rows, the renderer skips it rather than blanking the page.

The rendered BOM belongs only on this assembly-docs site. Developer docs may document the BOM workflow, but should not embed the rendered BOM table.

Cable harnesses

Cable harness source files belong under product repo hardware/cables/. Wireviz-generated child BOMs belong to release/build artifacts such as .bom.tsv files.

Product-level hardware/bom.csv lists cable harnesses as top-level assemblies. When a harness has Wireviz source, the product BOM Source should point to the source path relative to hardware/, for example cables/OSSM-Motor-Control-Harness.yml. Assembly cable pages link to generated diagrams and child BOM artifacts instead of copying cable child rows into the product-level BOM.

Release BOM artifacts

Tagged product releases can also generate a standalone bom.html artifact.

Product repos should copy templates/generate-bom-release.yml to .github/workflows/generate-bom-release.yml and set the product name, repo URL, and license string. The product repo is checked out by the reusable workflow; only the BOM rendering scripts are pulled from this repo.

Contributing properly

Use this rule of thumb: edit content where it is owned.

ChangeEdit here
Product assembly steps, product images, product BOM page text, PCB overview, cable pagesProduct repo assembly-docs/
Product BOM dataProduct repo hardware/bom.csv
Product assembly nav orderProduct repo assembly-docs/nav.yml
Product metadata for Ohai discoveryProduct repo assembly-docs/site.yml
CAD, PCB, cable source artifactsProduct repo hardware/cad/, hardware/pcb/, hardware/cables/
Site homepage or cross-product site docsThis repo docs/ outside product folders
Assembly pipeline behaviorThis repo scripts/
Shared site stylingThis repo docs/stylesheets/assembly.css
GitHub Pages deploymentThis repo .github/workflows/deploy.yml
Product rebuild trigger templateThis repo templates/trigger-assembly-docs.yml
Release BOM generation templateThis repo templates/generate-bom-release.yml

Do:

  • Make product content changes in the product repo first.
  • Keep hardware/bom.csv human-owned and schema-compliant.
  • Include {/* BEGIN GENERATED BOM */} and {/* END GENERATED BOM */} in a product assembly-docs/bom.md when that page is ready for generated content.
  • Keep assembly-docs/site.yml real and placeholder-free before adding the ohai-assembly-docs topic.
  • Test site changes locally with ASSEMBLE_LOCAL="$HOME/Github" ./scripts/assemble-docs.sh and mkdocs serve.
  • Treat scripts/bom_categories.py as the single source for BOM category labels and colors.
  • Keep output deterministic: no timestamps or unstable ordering in generated docs.

Do not:

  • Hand-edit docs/dtt/, docs/lockbox/, docs/radr/, docs/ossm/, or other assembled product folders.
  • Add ohai-assembly-docs to template repos or repos with PRODUCT_* placeholders.
  • Commit generated BOM blocks back to product repos.
  • Copy Wireviz child cable BOM rows into the product-level BOM.
  • Change the BOM schema in this repo.
  • Duplicate the BOM category color map in CSS.
  • Add rendered assembly BOM tables to developer docs.
  • Depend on local-only assets or absolute local paths in product docs.

Adding a new product

  1. Add an assembly-docs/ folder to the product repo.
  2. Add assembly-docs/site.yml with real slug, title, license, and integer nav_order.
  3. Add assembly-docs/nav.yml with site_name and the standard page order.
  4. Include index.md, pcb-overview.md, cable-harnesses.md, bom.md, and assembly-guide.md.
  5. Put page images and supporting files under assembly-docs/assets/.
  6. Add or validate hardware/bom.csv against the canonical BOM schema.
  7. Keep hardware/cad/, hardware/pcb/, and hardware/cables/ present.
  8. Copy the trigger workflow template into the product repo.
  9. Confirm local assembly and mkdocs build --strict pass.
  10. Add the ohai-assembly-docs topic to opt into the site.

For private repos, configure ASSEMBLE_GITHUB_TOKEN with read access to the product repos. Per-repo read-only deploy keys remain supported during transition. Once repos are public, anonymous HTTPS cloning is enough.

Troubleshooting

SymptomCheck
Product page did not updateDid the source product repo change under assembly-docs/**, and did the trigger workflow dispatch successfully?
BOM did not renderDoes assembly-docs/bom.md contain both generated BOM markers? Does hardware/bom.csv have data rows?
BOM render failedDoes hardware/bom.csv match the canonical 12-column header exactly?
Images are missingAre assets under assembly-docs/assets/, and are page links relative to the product docs package?
Product-relative source links are brokenCheck scripts/rewrite_product_links.py and the product repo/branch configuration in scripts/assemble-docs.sh.
KiCanvas did not appearConfirm a *.kicad_pcb file exists under the product repo's hardware/pcb/.
Product was skipped by discoveryConfirm ohai-assembly-docs topic, non-placeholder assembly-docs/site.yml, and required assembly/hardware paths.

On this page