molecule-pipeline
Public Made by Adomby adom
Top-level router for moving molecules between EDA tools, the wiki, and Hydrogen: one entry point that routes publish/import intents to the right skill chain and enforces the pipeline invariants.
82dd16c
1d ago
The molecule pipeline, step by step
How a board leaves your EDA tool, becomes a molecule on the wiki, and lands in a Hydrogen account wireable in the 3D editor. Every tool in the chain, in the order it runs, with the command each step actually issues and the gate that has to pass before the next step starts.
This page is the process; the README is the one-sentence front door.
The chain at a glance
YOUR LAPTOP YOUR CONTAINER ADOM CLOUD
─────────── ────────────── ──────────
KiCad 10 ──kicad bridge──┐
Fusion 360 ──fusion bridge─┼─▶ EDA export skill ─▶ step2glb (CLI) ──▶ OCCT service ─▶ anchored GLB
Altium ──altium bridge─┘ │ ▲ (adom-step2glb) + footprint/symbol JSON
│ │ │
▼ │ ▼
molecule-publish ────────┘ package.json + gates ──▶ adom-wiki ──▶ wiki page
│ (pkg publish + repo push)
▼ │
adom-nucleus --render-board (APM render/ archive) │
▼
adom-molecule import <owner>/<slug> ─────────▶ Hydrogen /api/molecules/import
│
▼
3D Editor V2: load, place, wire
Every arrow is a real package. Versions this page was verified against (2026-09-03):
| Layer | Package | Version | Runs where |
|---|---|---|---|
| Router (this page) | adom/molecule-pipeline |
1.1.2 | container skill |
| Laptop bridge | adom/adom-bridge (adom-bridge CLI, formerly adom-desktop) |
2.1.15 | laptop app, driven from the container |
| KiCad bridge | adom/kicad-bridge |
1.0.111 | inside Adom Bridge |
| Fusion bridge | adom/fusion-bridge |
1.9.352 | inside Adom Bridge |
| EDA export skills | adom/kicad-export-molecule · adom/fusion-export-molecule · adom/altium-export-molecule |
1.1.2 · 1.2.2 · 2.3.1 | container skills |
| Convert | adom/adom-step2glb (step2glb CLI) + shared OCCT service |
1.2.2 CLI / service 1.3.0 | container CLI, cloud service |
| Package + publish | adom/molecule-publish |
2.10.0 | container skill (+ scripts) |
| Wiki CLI | adom/adom-wiki-cli (adom-wiki) |
1.7.26 | container |
| Render archive | adom/adom-project-manager (adom-nucleus, alias adom-project-manager) |
0.14.0 | container |
| Import | adom/adom-molecule (adom-molecule CLI, ships adom-molecule-import skill) |
1.1.10 | container |
| Destination | Hydrogen (hydrogen.adom.inc) |
1.0.185 | cloud |
Install the container side in one go:
adom-wiki pkg install adom/molecule-pipeline # router; pulls molecule-publish + adom-molecule
adom-wiki pkg install adom/adom-step2glb # step2glb CLI
adom-wiki pkg install adom/kicad-export-molecule # or fusion-export-molecule / altium-export-molecule
adom-wiki pkg install adom/adom-project-manager # adom-nucleus --render-board
Stage 0 — Before you export: the board must be a molecule
A molecule is a board that carries the Adom furniture: MP1–MP4 marker footprints (the anchoring references) and the corner machine pins / contacts from the Adom library. OCCT anchors on the markers; without at least three of them the conversion still runs but the GLB imports unanchored and unwireable.
- KiCad:
kicad-to-moleculeadds wings + machine pins to a plain board; footprints come fromadom/kicad-library-manager. - Altium:
barrett-land/adom-altium-library-importerputs the machine-pin libraries inside Altium. - Fusion/EAGLE: use the Adom library parts (
MACH_PIN_LRG_SHORT, etc.); the marker names carry the pin size, which the converter reads (pin_size_source: markers).
Gate: the 3D models for the pins, contacts and markers resolve in your EDA's 3D viewer on the machine that will export. A STEP only contains what resolved at export time; a model referenced by a path that only exists on someone else's machine is silently dropped, and anchoring fails downstream.
Stage 1 — Export on the laptop (EDA export skill + Adom Bridge)
The STEP is always exported on the design machine, driven from the container through Adom Bridge. Everything below is what the export skill does for you when you say "export molecule ABC".
KiCad (kicad-export-molecule)
- Preflight:
adom-bridge ping;adom-bridge commands | grep kicad_; kicad-cli is KiCad 10 (C:\Program Files\KiCad\10.0\bin\kicad-cli.exe version). - Export the STEP with the laptop CLI (models substituted from the laptop's libraries):
Read the output: everykicad-cli pcb export step --subst-models --force -o ABC.step ABC.kicad_pcbCould not add 3D model for MPnline means a marker did not bake in. Fix the model path (KiCad resolves relative model paths against the board's directory,${KICAD10_3DMODEL_DIR}against the install) and export again. - Optional silk PNGs (top/bottom, white art on transparent).
- Pull the bundle to the container:
adom-bridge pull_file {"filePaths":[...], "saveTo":"..."}—ABC.step,ABC.kicad_pcb,ABC.kicad_sch,ABC.kicad_pro, silks.
Never use KiCad's own GLB export for a molecule: it bypasses anchoring, gold pins, normalization and the footprint emit. STEP in, OCCT makes the GLB.
Fusion 360 Electronics (fusion-export-molecule)
adom-bridge fusion_startif Fusion is closed (blocks until the add-in is ready; the firstfusion_get_app_stateafter that can take a minute).- Open the board file directly so the multi-design picker never appears:
Find the design first withadom-bridge fusion_open_cloud_file {"projectName":"Main","folderPath":"COSMIIC","fileName":"PM COIL Molecule","fileExtension":"fbrd","recovery":"discard"}fusion_mcp_call {"tool":"fusion_mcp_read","arguments":{"queryType":"document","operation":"search","name":"..."}}(APS search needs a fresh sign-in; MCP search works with any open document). - Export sources:
fusion_export_eagle_sourcefor the.brd, switch withfusion_electron_run {"command":"EDIT .s1"}, export the.sch, switch back withEDIT .brd. fusion_show_3d_board, thenfusion_export_step(andfusion_export_f3d/fusion_export_usdz/ silkscreen screenshots if you want the kitchen sink).pull_filethe bundle:.brd,.sch,.step(+ extras).
Altium (altium-export-molecule)
Native STEP export with the machine-pin models baked in, board metadata derived for OCCT, then the same converter call as everyone else. The skill ends when the OCCT artifacts are on the container; it never packages or publishes.
Gate for all three: the bundle on the container has STEP + board + schematic + <slug>-fab.zip + export.json (a molecule without its schematic is not reproducible and molecule-publish refuses it).
For each EDA, collect fabrication layers on every export and verify them with molecule-publish's scripts/fab_bundle.py before handing off. Preserve native board sources and mark imported backfills honestly.
Stage 2 — Convert: STEP → anchored GLB + footprint/symbol (step2glb)
One command, run on the container, does the whole OCCT molecule pipeline server-side:
step2glb convert ABC.step --board ABC.kicad_pcb --pin large -o <slug>.glb # .brd boards work too
The CLI uploads to the shared OCCT service (https://step2glb-gmdoncpxdwx0.adom.cloud, async POST /convert → GET /jobs/{id} → /jobs/{id}/result), and downloads <slug>.glb, <slug>_footprint.json and <slug>_symbol.json beside it. What the service does: MP-marker anchoring (Z-up, front-left machine pin at the origin, board-surface Z), canonical gold machine-pin material, optional silkscreen overlay, meter normalization, Draco compression, and footprint + symbol JSON with the per-pad wire-attach Z — the numbers Hydrogen's wire tool snaps to.
Gate on the printed stats before going any further:
| Stat | Must be | Otherwise |
|---|---|---|
molecule_anchored |
true |
markers missing from the STEP; go back to Stage 1 |
footprint_applied / footprint_pins |
true / 4 |
board parse failed; read the warnings |
contact_z |
2.8–8.4 mm | wrong pin size or wrong marker models |
pin_size_source |
markers |
param means the size fell back to --pin |
warnings |
none | every entry is actionable |
The GLB carries asset.extras.adomMolecule — durable provenance you can check on any downloaded copy (do not look for a molecule_anchor node; the optimizer flattens it by design).
Stage 3 — Package (molecule-publish)
<slug>/
package.json type "component", component.mpn, hero block, dependencies {}
<slug>.glb the OCCT GLB, named EXACTLY <slug>.glb
ABC.kicad_pcb | .brd board source
ABC.kicad_sch | .sch schematic source
ABC.step STEP (reproducibility)
<slug>-fab.zip Gerbers and drill
export.json exporter versions and source/member hashes
<slug>_footprint.json OCCT artifact (wire-attach Z)
<slug>_symbol.json OCCT artifact
README.md, screenshots/hero.png, [silk PNGs, .f3d, .usdz, bom, cpl]
Rules that bite:
- Name the GLB
<slug>.glb. The wiki auto-converts the STEP to a plain<slug>.glbat publish time and pointsmodel_3d_pathat it; an anchored GLB with any other name is shadowed by the plain one and every import gets an unanchored model. - The
componentblock is what creates the page's component-metadata row; without itmodel_3d_pathis never set and import fails with "no published GLB". - Key the page by MPN, never by value. Do not ship a hand-made
page.json. - Component dependencies are enforced before publish:
python3 scripts/component_graph.py plan <board> --out component-plan.jsonthengate package.json --plan component-plan.json --expect-board <board> --resolve(declared coverage + every dependency resolves to a real page). Missing component pages: Stage 2.6 auto-creates them. - Stamp what you tested on:
python3 scripts/tested_with.py stamp package.json --family <model>. - Hero camera:
python3 scripts/hero_camera.py pose <slug>.glb --page page.json.
Stage 4 — Publish + verify (adom-wiki)
adom-wiki pkg publish [--org adom] # registry version
adom-wiki repo push <owner>/<slug> --files <every file above> -m "<name> molecule"
Two layers, both required: pkg publish registers the version (and generates page.json), repo push puts the files on the page. Verify before calling it done:
metadata.model_3d_pathon the page ==<slug>.glb;- the page's GLB is byte-identical to your gated conversion (
curlit with your token,cmpagainst the local file) — this is the anchoring proof; - the full set is present: GLB + STEP + schematic + board + footprint/symbol JSON.
Private pages are fine end to end; nothing in the chain needs the page public.
Stage 5 — Render archive (adom-nucleus --render-board)
Run after the publish, every time (it stamps the archive with the version it reads from the published package.json):
adom-nucleus --render-board <owner>/<slug> # alias: adom-project-manager --render-board
It renders render/pcb.svg, render/sheet-*.svg, render/board.glb, content-hashes them and archives render/<version>/ + render/manifest.json only when the content changed. Check manifest.current == <version> and python3 scripts/render_parity.py render/board.glb <slug>.glb (same mesh count, else the render dropped geometry). EAGLE/Fusion sources report "nothing rendered" and skip gracefully today.
Stage 6 — Import into Hydrogen (adom-molecule)
adom-molecule import <owner>/<slug> --owner <your-user-or-org> [--name <name>]
What it does (1.1.10): reads the page owner-qualified with your container credential (private pages included), checks model_3d_path and that a footprint JSON or board file exists, downloads the GLB as a preflight, then POSTs {wikiRef:"<owner>/<slug>", owner, name, includeSource:true} to https://hydrogen.adom.inc/api/molecules/import. Hydrogen re-reads the page with the same credential, reuses the wiki GLB verbatim (no re-optimization, no silkscreen, no Blender), carries the sources, and attaches the footprint so the molecule lands with wire-attach points. Re-importing creates a new version of the same molecule.
Same thing from any script:
curl -X POST https://hydrogen.adom.inc/api/molecules/import \
-H "X-Api-Key: $(cat /var/run/adom/api-key)" -H "Content-Type: application/json" \
-d '{"wikiRef":"<owner>/<slug>","owner":"<you>","includeSource":true}'
Gate: the reply carries a version and no warnings; adom-molecule list shows the name under your owner; https://hydrogen.adom.inc/<owner>/molecules/<name> renders it.
Stage 7 — Use it in Hydrogen
Open a repo's editor (https://hydrogen.adom.inc/<owner>/<repo>/edit), add a 3D Editor V2 tab, then:
- Browse and Load Molecule → pick the owner → the molecule → Load → set the placement position → OK.
- More Objects tools → Add Wires (tick Draw Multiple Wires) → hover a machine pin until the "Machine Pin: FL/BL/FR/BR" tooltip shows → click → click the second molecule's pin. The console logs
New contact-based wire created from <a> - Pin: X to <b> - Pin: Y. - Save the layout.
The in-app Optimize / Regenerate 3D model button is retired (it pointed at a worker that no longer exists); optimization happens in Stage 2 and import reuses it.
Regression: the e2e harness
project/molecule-e2e/run-e2e.sh on gallia republishes two private test molecules — drew2/e2e-kicad-solonoid (KiCad) and drew2/e2e-fusion-pmcoil (Fusion/EAGLE) — through the current stack every time a molecule-family package changes (cron, every 30 minutes, check-and-run.sh). Stages it gates: EDA export on the laptop (kicad-cli 10 / Fusion bridge), OCCT conversion stats, provenance stamp, pkg publish + repo push, wiki GLB checksum, APM render archive + manifest, and the private import into Hydrogen through adom-molecule import. last-status.json is the verdict; e2e.log is the trail.
The one-sentence versions
- "Move molecule ABC from KiCad on my computer up to the wiki." → Stages 1–5.
- "Get molecule ABC into my Hydrogen account." → Stage 6.
- "Publish my molecule ABC and import it into my Hydrogen account." → Stages 1–6, each gated before the next.
- "Wire ABC to DEF in the 3D editor." → Stage 7.
# The molecule pipeline, step by step
How a board leaves your EDA tool, becomes a molecule on the wiki, and lands in a Hydrogen account wireable in the 3D editor. Every tool in the chain, in the order it runs, with the command each step actually issues and the gate that has to pass before the next step starts.
This page is the process; the [README](../README.md) is the one-sentence front door.
## The chain at a glance
```
YOUR LAPTOP YOUR CONTAINER ADOM CLOUD
─────────── ────────────── ──────────
KiCad 10 ──kicad bridge──┐
Fusion 360 ──fusion bridge─┼─▶ EDA export skill ─▶ step2glb (CLI) ──▶ OCCT service ─▶ anchored GLB
Altium ──altium bridge─┘ │ ▲ (adom-step2glb) + footprint/symbol JSON
│ │ │
▼ │ ▼
molecule-publish ────────┘ package.json + gates ──▶ adom-wiki ──▶ wiki page
│ (pkg publish + repo push)
▼ │
adom-nucleus --render-board (APM render/ archive) │
▼
adom-molecule import <owner>/<slug> ─────────▶ Hydrogen /api/molecules/import
│
▼
3D Editor V2: load, place, wire
```
Every arrow is a real package. Versions this page was verified against (2026-09-03):
| Layer | Package | Version | Runs where |
|---|---|---|---|
| Router (this page) | `adom/molecule-pipeline` | 1.1.2 | container skill |
| Laptop bridge | `adom/adom-bridge` (`adom-bridge` CLI, formerly adom-desktop) | 2.1.15 | laptop app, driven from the container |
| KiCad bridge | `adom/kicad-bridge` | 1.0.111 | inside Adom Bridge |
| Fusion bridge | `adom/fusion-bridge` | 1.9.352 | inside Adom Bridge |
| EDA export skills | `adom/kicad-export-molecule` · `adom/fusion-export-molecule` · `adom/altium-export-molecule` | 1.1.2 · 1.2.2 · 2.3.1 | container skills |
| Convert | `adom/adom-step2glb` (`step2glb` CLI) + shared OCCT service | 1.2.2 CLI / service 1.3.0 | container CLI, cloud service |
| Package + publish | `adom/molecule-publish` | 2.10.0 | container skill (+ scripts) |
| Wiki CLI | `adom/adom-wiki-cli` (`adom-wiki`) | 1.7.26 | container |
| Render archive | `adom/adom-project-manager` (`adom-nucleus`, alias `adom-project-manager`) | 0.14.0 | container |
| Import | `adom/adom-molecule` (`adom-molecule` CLI, ships `adom-molecule-import` skill) | 1.1.10 | container |
| Destination | Hydrogen (`hydrogen.adom.inc`) | 1.0.185 | cloud |
Install the container side in one go:
```bash
adom-wiki pkg install adom/molecule-pipeline # router; pulls molecule-publish + adom-molecule
adom-wiki pkg install adom/adom-step2glb # step2glb CLI
adom-wiki pkg install adom/kicad-export-molecule # or fusion-export-molecule / altium-export-molecule
adom-wiki pkg install adom/adom-project-manager # adom-nucleus --render-board
```
## Stage 0 — Before you export: the board must be a molecule
A molecule is a board that carries the Adom furniture: **MP1–MP4 marker footprints** (the anchoring references) and the corner **machine pins / contacts** from the Adom library. OCCT anchors on the markers; without at least three of them the conversion still runs but the GLB imports unanchored and unwireable.
- KiCad: `kicad-to-molecule` adds wings + machine pins to a plain board; footprints come from `adom/kicad-library-manager`.
- Altium: `barrett-land/adom-altium-library-importer` puts the machine-pin libraries inside Altium.
- Fusion/EAGLE: use the Adom library parts (`MACH_PIN_LRG_SHORT`, etc.); the marker names carry the pin size, which the converter reads (`pin_size_source: markers`).
Gate: the 3D models for the pins, contacts and markers **resolve in your EDA's 3D viewer on the machine that will export**. A STEP only contains what resolved at export time; a model referenced by a path that only exists on someone else's machine is silently dropped, and anchoring fails downstream.
## Stage 1 — Export on the laptop (EDA export skill + Adom Bridge)
The STEP is always exported **on the design machine**, driven from the container through Adom Bridge. Everything below is what the export skill does for you when you say "export molecule ABC".
### KiCad (`kicad-export-molecule`)
1. Preflight: `adom-bridge ping`; `adom-bridge commands | grep kicad_`; kicad-cli is KiCad 10 (`C:\Program Files\KiCad\10.0\bin\kicad-cli.exe version`).
2. Export the STEP with the laptop CLI (models substituted from the laptop's libraries):
```
kicad-cli pcb export step --subst-models --force -o ABC.step ABC.kicad_pcb
```
Read the output: every `Could not add 3D model for MPn` line means a marker did not bake in. Fix the model path (KiCad resolves relative model paths against the board's directory, `${KICAD10_3DMODEL_DIR}` against the install) and export again.
3. Optional silk PNGs (top/bottom, white art on transparent).
4. Pull the bundle to the container: `adom-bridge pull_file {"filePaths":[...], "saveTo":"..."}` — `ABC.step`, `ABC.kicad_pcb`, `ABC.kicad_sch`, `ABC.kicad_pro`, silks.
Never use KiCad's own GLB export for a molecule: it bypasses anchoring, gold pins, normalization and the footprint emit. STEP in, OCCT makes the GLB.
### Fusion 360 Electronics (`fusion-export-molecule`)
1. `adom-bridge fusion_start` if Fusion is closed (blocks until the add-in is ready; the first `fusion_get_app_state` after that can take a minute).
2. Open the **board file directly** so the multi-design picker never appears:
```
adom-bridge fusion_open_cloud_file {"projectName":"Main","folderPath":"COSMIIC","fileName":"PM COIL Molecule","fileExtension":"fbrd","recovery":"discard"}
```
Find the design first with `fusion_mcp_call {"tool":"fusion_mcp_read","arguments":{"queryType":"document","operation":"search","name":"..."}}` (APS search needs a fresh sign-in; MCP search works with any open document).
3. Export sources: `fusion_export_eagle_source` for the `.brd`, switch with `fusion_electron_run {"command":"EDIT .s1"}`, export the `.sch`, switch back with `EDIT .brd`.
4. `fusion_show_3d_board`, then `fusion_export_step` (and `fusion_export_f3d` / `fusion_export_usdz` / silkscreen screenshots if you want the kitchen sink).
5. `pull_file` the bundle: `.brd`, `.sch`, `.step` (+ extras).
### Altium (`altium-export-molecule`)
Native STEP export with the machine-pin models baked in, board metadata derived for OCCT, then the same converter call as everyone else. The skill ends when the OCCT artifacts are on the container; it never packages or publishes.
Gate for all three: the bundle on the container has **STEP + board + schematic + `<slug>-fab.zip` + `export.json`** (a molecule without its schematic is not reproducible and `molecule-publish` refuses it).
For each EDA, collect fabrication layers on every export and verify them with molecule-publish's `scripts/fab_bundle.py` before handing off. Preserve native board sources and mark imported backfills honestly.
## Stage 2 — Convert: STEP → anchored GLB + footprint/symbol (`step2glb`)
One command, run on the container, does the whole OCCT molecule pipeline server-side:
```bash
step2glb convert ABC.step --board ABC.kicad_pcb --pin large -o <slug>.glb # .brd boards work too
```
The CLI uploads to the shared OCCT service (`https://step2glb-gmdoncpxdwx0.adom.cloud`, async `POST /convert` → `GET /jobs/{id}` → `/jobs/{id}/result`), and downloads `<slug>.glb`, `<slug>_footprint.json` and `<slug>_symbol.json` beside it. What the service does: MP-marker anchoring (Z-up, front-left machine pin at the origin, board-surface Z), canonical gold machine-pin material, optional silkscreen overlay, meter normalization, Draco compression, and footprint + symbol JSON with the **per-pad wire-attach Z** — the numbers Hydrogen's wire tool snaps to.
Gate on the printed stats before going any further:
| Stat | Must be | Otherwise |
|---|---|---|
| `molecule_anchored` | `true` | markers missing from the STEP; go back to Stage 1 |
| `footprint_applied` / `footprint_pins` | `true` / 4 | board parse failed; read the warnings |
| `contact_z` | 2.8–8.4 mm | wrong pin size or wrong marker models |
| `pin_size_source` | `markers` | `param` means the size fell back to `--pin` |
| `warnings` | none | every entry is actionable |
The GLB carries `asset.extras.adomMolecule` — durable provenance you can check on any downloaded copy (do not look for a `molecule_anchor` node; the optimizer flattens it by design).
## Stage 3 — Package (`molecule-publish`)
```
<slug>/
package.json type "component", component.mpn, hero block, dependencies {}
<slug>.glb the OCCT GLB, named EXACTLY <slug>.glb
ABC.kicad_pcb | .brd board source
ABC.kicad_sch | .sch schematic source
ABC.step STEP (reproducibility)
<slug>-fab.zip Gerbers and drill
export.json exporter versions and source/member hashes
<slug>_footprint.json OCCT artifact (wire-attach Z)
<slug>_symbol.json OCCT artifact
README.md, screenshots/hero.png, [silk PNGs, .f3d, .usdz, bom, cpl]
```
Rules that bite:
- **Name the GLB `<slug>.glb`.** The wiki auto-converts the STEP to a plain `<slug>.glb` at publish time and points `model_3d_path` at it; an anchored GLB with any other name is shadowed by the plain one and every import gets an unanchored model.
- The `component` block is what creates the page's component-metadata row; without it `model_3d_path` is never set and import fails with "no published GLB".
- Key the page by MPN, never by value. Do not ship a hand-made `page.json`.
- Component dependencies are enforced before publish: `python3 scripts/component_graph.py plan <board> --out component-plan.json` then `gate package.json --plan component-plan.json --expect-board <board> --resolve` (declared coverage + every dependency resolves to a real page). Missing component pages: Stage 2.6 auto-creates them.
- Stamp what you tested on: `python3 scripts/tested_with.py stamp package.json --family <model>`.
- Hero camera: `python3 scripts/hero_camera.py pose <slug>.glb --page page.json`.
## Stage 4 — Publish + verify (`adom-wiki`)
```bash
adom-wiki pkg publish [--org adom] # registry version
adom-wiki repo push <owner>/<slug> --files <every file above> -m "<name> molecule"
```
Two layers, both required: `pkg publish` registers the version (and generates `page.json`), `repo push` puts the files on the page. Verify before calling it done:
- `metadata.model_3d_path` on the page == `<slug>.glb`;
- the page's GLB is byte-identical to your gated conversion (`curl` it with your token, `cmp` against the local file) — this is the anchoring proof;
- the full set is present: GLB + STEP + schematic + board + footprint/symbol JSON.
Private pages are fine end to end; nothing in the chain needs the page public.
## Stage 5 — Render archive (`adom-nucleus --render-board`)
Run **after** the publish, every time (it stamps the archive with the version it reads from the published `package.json`):
```bash
adom-nucleus --render-board <owner>/<slug> # alias: adom-project-manager --render-board
```
It renders `render/pcb.svg`, `render/sheet-*.svg`, `render/board.glb`, content-hashes them and archives `render/<version>/` + `render/manifest.json` only when the content changed. Check `manifest.current == <version>` and `python3 scripts/render_parity.py render/board.glb <slug>.glb` (same mesh count, else the render dropped geometry). EAGLE/Fusion sources report "nothing rendered" and skip gracefully today.
## Stage 6 — Import into Hydrogen (`adom-molecule`)
```bash
adom-molecule import <owner>/<slug> --owner <your-user-or-org> [--name <name>]
```
What it does (1.1.10): reads the page owner-qualified with your container credential (private pages included), checks `model_3d_path` and that a footprint JSON or board file exists, downloads the GLB as a preflight, then POSTs `{wikiRef:"<owner>/<slug>", owner, name, includeSource:true}` to `https://hydrogen.adom.inc/api/molecules/import`. Hydrogen re-reads the page with the same credential, **reuses the wiki GLB verbatim** (no re-optimization, no silkscreen, no Blender), carries the sources, and attaches the footprint so the molecule lands with wire-attach points. Re-importing creates a new version of the same molecule.
Same thing from any script:
```bash
curl -X POST https://hydrogen.adom.inc/api/molecules/import \
-H "X-Api-Key: $(cat /var/run/adom/api-key)" -H "Content-Type: application/json" \
-d '{"wikiRef":"<owner>/<slug>","owner":"<you>","includeSource":true}'
```
Gate: the reply carries a `version` and no `warnings`; `adom-molecule list` shows the name under your owner; `https://hydrogen.adom.inc/<owner>/molecules/<name>` renders it.
## Stage 7 — Use it in Hydrogen
Open a repo's editor (`https://hydrogen.adom.inc/<owner>/<repo>/edit`), add a **3D Editor V2** tab, then:
1. **Browse and Load Molecule** → pick the owner → the molecule → Load → set the placement position → OK.
2. **More Objects tools → Add Wires** (tick *Draw Multiple Wires*) → hover a machine pin until the "Machine Pin: FL/BL/FR/BR" tooltip shows → click → click the second molecule's pin. The console logs `New contact-based wire created from <a> - Pin: X to <b> - Pin: Y`.
3. Save the layout.
The in-app **Optimize / Regenerate 3D model** button is retired (it pointed at a worker that no longer exists); optimization happens in Stage 2 and import reuses it.
## Regression: the e2e harness
`project/molecule-e2e/run-e2e.sh` on gallia republishes two private test molecules — `drew2/e2e-kicad-solonoid` (KiCad) and `drew2/e2e-fusion-pmcoil` (Fusion/EAGLE) — through the current stack every time a molecule-family package changes (cron, every 30 minutes, `check-and-run.sh`). Stages it gates: EDA export on the laptop (kicad-cli 10 / Fusion bridge), OCCT conversion stats, provenance stamp, `pkg publish` + `repo push`, wiki GLB checksum, APM render archive + manifest, and the private import into Hydrogen through `adom-molecule import`. `last-status.json` is the verdict; `e2e.log` is the trail.
## The one-sentence versions
- "Move molecule ABC from KiCad on my computer up to the wiki." → Stages 1–5.
- "Get molecule ABC into my Hydrogen account." → Stage 6.
- "Publish my molecule ABC and import it into my Hydrogen account." → Stages 1–6, each gated before the next.
- "Wire ABC to DEF in the 3D editor." → Stage 7.