---
name: hardware-pipeline
description: End-to-end workflow for publishing a hardware/workcell Component page with a live 3D viewer from Fusion CAD. Fusion export via the adom-desktop bridge, STEP to draco GLB via step2glb, page publish via adom-wiki with the current viewer/hero/size contracts. Use when the user says "publish a workcell page", "fusion to wiki", "component page from CAD", "export this machine to the wiki", "hardware page 3D viewer", or names a machine (Essemtec, workcell, kiosk) they want on the wiki.
---

# hardware-pipeline: Fusion CAD to a live Component page

Publishes a machine or workcell as a wiki Component page with the interactive
3D viewer, from a Fusion cloud design to a live page. This is the hardware
sibling of `molecule-pipeline`: same stage-1 export, same conversion
dependency, but the publish stage is plain hardware (no molecule invariants,
no MP markers, no machine pins). For chips/molecules use `molecule-pipeline`
instead.

Reference pages built with this flow: `adom/essemtec-puma`, `adom/kiosk-workcell`.

## Stage 1: Fusion export (adom-desktop bridge)

```bash
# Find the design (Fusion must be running on the connected desktop):
adom-desktop fusion_aps_search '{"query": "Essemtec Puma"}'
adom-desktop fusion_open_cloud_file '{"id": "<urn from search>"}'
# Export STEP and pull it into the container:
adom-desktop fusion_export_cloud_file '{"format": "step"}'
adom-desktop pull_file '{"path": "<export path>", "dest": "./export/machine.step"}'
```

STEP exports of machines run large (40MB+ is normal). That is fine for the
next stage, but never push the STEP through a JSON file push (10MB cap);
repo pushes of binaries go multipart (`adom-wiki repo push`), which handles
large files.

## Stage 2: STEP to web-grade GLB (step2glb)

```bash
step2glb convert machine.step --compress draco -o models/<slug>.glb
step2glb thumbnail models/<slug>.glb -o docs/hero.png   # optional, see Hero below
```

- Always `--compress draco`. Fusion geometry uncompressed will blow the page
  budget (below).
- The service answers big jobs with HTTP 202 and a job URL; the CLI polls it.
  If you drive the HTTP API directly, poll the job URL yourself; a 202 is not
  an error.
- Size budget: models over 8 MB or 4M vertices render CLICK-TO-LOAD on the
  page instead of inline (a deliberate crash guard). Do not tune to prose:
  run `adom-wiki pkg lint` and decimate or recompress until its HEAVY_GLB
  warning stops firing. `adom/essemtec-puma` at about 1 MB renders instantly
  and is the reference for what good looks like.

## Stage 3: the Component page (adom-wiki)

```bash
adom-wiki page create <slug> --type component --title "..." --brief "..." \
  --mpn "<MPN or model number>" --manufacturer "..." --category "..."
adom-wiki repo push adom/<slug> models/<slug>.glb models/<slug>.step docs/hero.png
```

Layout convention: `models/<slug>.glb` plus `models/<slug>.step`, hero (if
any) at `docs/hero.png`.

- 3D viewer activation is AUTOMATIC: the indexer detects any `.glb` in the
  repo and the page renders the viewer headline. `component.model_3d_path`
  in page.json only needs setting when several GLBs exist and the default
  pick is wrong. No undocumented metadata dance.
- Viewer behavior knobs live in page.json `component.viewer_3d` and are
  validated by `pkg lint`. Current semantics (changed 2026-07-24): platform
  default is LAND-ONCE (play the placement once, then hold); `repeat: 0..10`
  with `0` meaning loop forever; `loop: true` is shorthand for `repeat: 0`;
  `shadows: false` disables cast shadows independently of `ground`. Query
  params beat page.json beats platform default. Viewer URLs are
  owner-qualified: `/viewer/3d/<owner>/component/<slug>`.
- A page that wants its README HTML as the whole canvas below the viewer can
  set `component.page_layout: "canvas"`. Viewer slots can also reference a
  shared custom viewer on another page: `"<owner>/<slug>:<path>.html"`.

## Durability: commit the source, not just the render

Push the STEP (and any native CAD you can) into the page repo alongside the
GLB. The surviving workcell board pages do exactly this (KiCad project plus
STEP committed), which is why they are regenerable; a page that holds only a
converted GLB is one deletion away from being unrecoverable, since page repos
and release tarballs are NOT in the database backups. adom/kiosk-workcell was
lost that way (adom/wiki#74): the model existed only as a published artifact,
so when the page was hard-deleted the machine had to be re-exported from
whoever still had the Fusion design.

Corollary: prefer transfer or soft delete over hard delete on any page whose
source lives only there.

## Hero (optional for components)

Component pages do NOT require a hero: the registry composes page visuals
from part files, and a `step2glb thumbnail` at `docs/hero.png` is a choice,
not a requirement. If the page deserves a real hero, generate it in Hero
Studio (`hero-studio pose <owner>/<slug>`, component mode); it blocks until
a human clicks Generate, and the exported PNG carries the provenance stamp
the registry checks for app/skill pages. Never hand-compose billboard-era
heroes; that path is retired.

## Schematics (boards only)

If the hardware page carries schematic sheets: `render/manifest.json` with a
`sheets[]` name array plus `render/sheet-NNN.svg` in index order. The page
renders a native Schematics section from it, and `pkg lint` validates both
directions (SHEETS_MANIFEST_MISMATCH).

## Rules that save a bad afternoon

- STAGE FROM SOURCE. Never build a new version by downloading the previous
  tarball and overlaying files: it silently resurrects anything cleaned
  since (the lints warn via STALE_PAGE_JSON and NONCANONICAL_HOST, but the
  workflow itself is the bug).
- Run `adom-wiki pkg lint` before publishing; it encodes the size, sheets,
  hero, and manifest contracts so you do not have to remember them.
- Internal hostnames in shipped files trigger a publish warning
  (INTERNAL_HOSTS_IN_TARBALL); keep personal container hosts out of docs.

## Related

`molecule-pipeline` (chips/molecules), `adom-step2glb` (conversion service),
`adom-wiki` (registry mechanics), `hero-studio` (real heroes).