Files
step-parse/PHASE0.md
T
Jason Stedwell c1abe36822 phase 0
2026-06-17 16:03:26 -05:00

4.7 KiB

Phase 0 — Containerize the CLI

Status: DONE (2026-06-17). step-parser:dev builds for linux/amd64 and all three sample assemblies (MR16/MR27/MR28) pass the full pipeline — load, BOM .xlsx, 6-view OSMesa thumbnails, geometry query, and dimensional-diagram SVG. Validated on a Mac (arm64) via QEMU emulation; image arch confirmed x86_64. Deps frozen in requirements.lock.txt. Two fixes were required (see Fixes applied below).

Goal: prove the heavy native stack runs on linux/amd64 (the Unraid target) before any web code is written. This is the highest-risk part of the step-parser roadmap; everything after it is conventional React-on-FastAPI.

What's being de-risked:

Path Library Container concern
STEP load + geometry build123d → cadquery-ocp (OpenCASCADE) manylinux x86_64 wheels; OCC needs GL/X11/OpenMP runtime libs
6-view thumbnails trimesh + pyrender offscreen GL with no GPU → forced onto OSMesa software rasterizer
Dimensional diagram cairosvg cairo / pango / gdk-pixbuf system libs
BOM pandas + openpyxl none
Translation anthropic (Claude API) network + ANTHROPIC_API_KEY (skipped in this phase)

Files (all in repo root, skill.src/ untouched)

  • Dockerfilepython:3.11-slim-bookworm, amd64-pinned, OSMesa + cairo system libs
  • requirements.txt — Python deps (floor pins; freeze to a lockfile after first green build)
  • .dockerignore — keeps .step samples, drops caches and pre-generated outputs
  • .env.exampleANTHROPIC_API_KEY (translation only)
  • build.sh — buildx build for linux/amd64 (+ registry push hints)
  • smoke-test.sh — runs MR16/MR27/MR28 through BOM + query + diagram; checks artifacts

Run it (on a Docker host)

Docker is not installed on the dev Mac this was authored on, and it's arm64. The build runs anywhere with Docker + buildx: Unraid itself, or a Mac/PC with Docker Desktop. From arm64 the amd64 build uses QEMU emulation (slow first time; the OpenCASCADE wheel is large).

./build.sh          # → step-parser:dev (linux/amd64)
./smoke-test.sh     # → _phase0_out/ with xlsx, pngs, svg per sample

Ad-hoc single file:

docker run --rm -v "$PWD/_phase0_out:/data" step-parser:dev "/data/MyPart.step" --no-translate

Pass criteria

For each of the three samples the smoke test must produce, with a clean exit:

  • *_bom.xlsx (kernel loaded + assembly traversed + Excel written)
  • at least one *_<view>.png (pyrender succeeded under OSMesa — the riskiest item)
  • *__external-diagram.svg (cairosvg succeeded)

All three green ⇒ Phase 0 done. Freeze the lockfile and move to Phase 1 (FastAPI wrapper).

Fixes applied during Phase 0

  1. PyOpenGL / OSMesa version clash (packaging). pyrender 0.1.45 hard-pins PyOpenGL==3.1.0, but the OSMesa offscreen backend needs OSMesaCreateContextAttribs (added in PyOpenGL ≥3.1.5). The Dockerfile installs pyrender's pin, then force-upgrades with pip install --no-deps --upgrade "PyOpenGL==3.1.7" (leaves pyrender untouched, avoids the resolver conflict). Without this, all 6 renders fail with an ImportError.
  2. external_diagram.py line 318 KeyError: 'position' (source bug). _arrange_views() returns view dicts keyed ox/oy, but the layout map read a non-existent position key — crashed the diagram on any platform. Fixed to {v["name"]: (v["ox"], v["oy"]) ...}.

Known follow-ups (deferred, out of Phase 0 scope)

  • Active-area detection is a no-op on Linux. external_diagram.py imports OCC.Core.* (pythonocc-core) for active-area detection, but the loader uses build123d's OCP kernel. The import fails and is caught (logged as a warning) — the diagram still renders, just without the auto-detected active-area dimension. Porting OCCOCP is a Phase 1 task.

  • Pin to the lockfile for reproducible Unraid builds. requirements.lock.txt is frozen; switch the Dockerfile's COPY requirements.txt / install line to it when convenient.

  • FreeCAD fallback is macOS-only right now. skill.src/modules/loader.py hardcodes /Applications/FreeCAD.app/..., so on Linux the fallback no-ops and returns None. build123d is the primary path and should handle the samples; wiring a Linux freecadcmd fallback means editing loader.py and is left for later.

  • Lockfile. Replace the floor pins with requirements.lock.txt once the build is green.

  • OSMesa is CPU rendering. Fine for correctness validation; thumbnail speed on the ~25 MB sample assemblies is a Phase 1+ concern. The roadmap's recommended pivot — export GLB and render client-side with three.js — sidesteps server GL for the live viewer.