Engineering portal — handoff for another engineer or AI¶
Read this before touching https://engineering.embeddedera.com. Paths are on the shop server
Plex (Ubuntu 24.04, user angel). No secret values are written here; only where they live.
What it is¶
A static site listing every KiCad board in the EmbeddedEra GitHub org: schematic and board
viewers (KiCanvas), an interactive 3D model, an InteractiveHtmlBom, four renders, ERC/DRC
counts, manufacturing specs and the fab-pack releases. Nothing is hand-edited; it is rebuilt
from the repos. Design and log: engineering-portal.
The pieces and where they are¶
| Piece | Where | Notes |
|---|---|---|
| Build script | ~/.local/bin/engineering-build (python3) |
lists repos with gh, clones to ~/engineering/repos/, writes ~/engineering/site/docs/ |
| Deploy script | ~/.local/bin/engineering-deploy (bash) |
runs the build, MkDocs, wrangler pages deploy; skips deploy when the tree hash is unchanged |
| Schedule | crontab -l → 20 * * * * under flock |
log ~/.local/state/engineering-deploy.log, lock ~/.local/state/engineering-deploy.lock |
| Site source | ~/engineering/site/mkdocs.yml, docs/assets/ |
Material theme copied from the SOP site; vendored kicanvas.js, model-viewer.min.js, meshopt_decoder.js, mv-init.js; navigation.instant must stay OFF |
| Per-commit cache | ~/engineering/cache/<repo>/<board>/<sha>/ |
renders, board.glb, ibom, _check-<sha>.json; delete a file to force a rebuild of that piece |
| 3D models | ~/engineering/3dmodels/ (KiCad packages3D subsets) and ~/kicad-lib/3dmodels/ (Git LFS) |
~/.local/bin/kicad-3dmodels fetches missing .3dshapes; git lfs pull in ~/kicad-lib after cloning |
| GLB material fix | ~/.local/share/glbfix/fix-materials.mjs |
gltf-transform; makes the viewer match the raytraced renders |
| Helpers | ~/.local/bin/kicad-check, kicad-ibom, gltfpack (symlink into nvm) |
all run the pinned container kicad/kicad:10.0.5 |
| Hosting | Cloudflare Pages project embeddedera-engineering, custom domain engineering.embeddedera.com |
token in ~/.config/cloudflare/env (CLOUDFLARE_API_TOKEN, account id) |
| Login gate | Cloudflare Access app "EmbeddedEra Engineering" (+ "(pages.dev previews)") | Google login; allowed departments engineering + admin from ~/Notes/roles/departments.yml; managed by ~/.local/bin/onboard access-sync |
| Home tile | ~/assistant/home.py TILES["engineering"], departments.yml tiles: |
restart systemctl --user restart assistant.service after editing |
GitHub: what is configured where¶
| Thing | Where | Purpose |
|---|---|---|
gh CLI login |
~/.config/gh/hosts.yml (account angelEmbeddedEra, org owner) |
the build lists repos, reads releases, triggers workflows |
KICAD_LIB_TOKEN |
fine-grained PAT, value in ~/.config/github/env; set as a repo secret on every product repo (gh secret set KICAD_LIB_TOKEN -R EmbeddedEra/<repo>) |
lets CI clone the private library EmbeddedEra/KiCad (contents: read only) |
| CI workflow | .github/workflows/kicad-checks.yml, master copy in EmbeddedEra/Project_Template; verbatim copies in Dashcam_Drive, Cow_Robot_Board, Cow_Remote |
job erc-drc on every push under hardware/**; job fab-outputs on tags hw/<board dir with _ for spaces>/<rev> |
| Fab pack | release asset <board>-<rev>-fab.zip |
gerbers, drill, BOM, CPL, schematic PDF, assembly PDFs, renders, pnp/ YY1 files, REQUIREMENTS.md from hardware/<board>/fab.yml |
Library repo EmbeddedEra/KiCad (~/kicad-lib) |
.gitattributes tracks *.step *.STEP *.stp *.wrl in LFS; scripting/neoden/ holds kicad_to_yy1.py + neoden_yy1_machine_setup.toml (bench feeder state) |
CI checks it out with lfs: true after installing git-lfs in the container |
| Product manifest | product.yml at each repo root, schema in Project_Template/docs/product-yml.md |
boards[].status: shipping / prototype / retired drives the Production / In development / Archive sections |
| Excluded repos | EXCLUDE_REPOS near the top of engineering-build |
KiCad, Project_Template, EmbeddedEra-products/modules, DIY-Multiprotocol-TX-Module |
Other secrets an agent may need (values never in the vault)¶
~/.config/cloudflare/env— Cloudflare API token (Pages, DNS, Access).~/.config/github/env—KICAD_LIB_TOKEN.~/.config/inventree/env— ERP URL + owner token (portal links to parts by IPN only).- Everything is also in the Vaultwarden vault; SOP-020 lists the credentials register.
Rules that apply¶
- Never
sudo apt; user-space only (nvm, uv,~/.local/bin). See~/CLAUDE.md. - Try changes with a local build (
engineering-build, thenmkdocs serveon 127.0.0.1) before deploying; a deploy is one command and the CDN caches by file name, so renders and models carry the commit hash in their names. - Procedures: SOP-021 New PCB Design (tags, fab.yml, fab pack), SOP-008 KiCad Library (IPNs, LFS), SOP-019 Cloudflare Changes, all at https://sop.embeddedera.com.
Verified deployment and recovery — 2026-09-18¶
- Versioned source is now
~/assistant/scripts/{engineering-build,engineering-deploy,kicad-check}and~/assistant/static/engineering/{mkdocs.yml,portal.v1.css}. Installed tools must match the reviewed main branch. Use the sandbox first;tests/test_engineering_portal.pyandtests/test_kicad_check_reports.pyare the offline regressions. Run provider fixtures undersystemd-run --user --wait --pipe --collect -p RestrictAddressFamilies=AF_UNIX. engineering-deploy [main|preview]builds in a private temporary copy, regeneratingdocs/boards. Failed discovery, pull, build or upload does not replace the previous successful docs or hash. Use this entrypoint; a standalone build into live docs is not atomic.- Cron's outer lock remains
engineering-deploy.lock; the script's shared main/preview lock is engineering-deploy-internal.lock. Never make these the same file. Branch hashes are~/.local/state/engineering-deploy.<branch>.hash, written only after successful upload and (main only) local docs promotion. The old unqualified hash is not used. - Main success promotes generated docs to
~/engineering/site/docsand retains the previous successful tree asdocs.prev. Preview never promotes into main docs. A post-upload local promotion failure exits nonzero, states that the upload already happened, and leaves the hash unwritten so recovery retries honestly. Pre-change tools, config and superseded check caches are retained at~/.local/state/engineering-backups/task148/. - Test overrides:
ENGINEERING_SITE_DIR,ENGINEERING_DOCS_DIR(builder),ENGINEERING_REPOS_DIR,ENGINEERING_CACHE_DIR,ENGINEERING_KICAD_CHECK, and deployENGINEERING_STATE_DIR,ENGINEERING_BUILD,ENGINEERING_MKDOCS,ENGINEERING_WRANGLER,ENGINEERING_CF_ENV,ENGINEERING_TMPDIR. Keep isolated roots and empty fixture credentials for failure tests; never rely on an environment flag alone to prevent live mutations. - Check caches actually live at
~/engineering/cache/<repo>/_check-<sha>.json. Schema 2 records SHA, checker/library fingerprint, exit code and validated report. Old reports cannot prove tool execution and are regenerated. Existing environment-noise/fragment filtering inkicad-checkremains; these counts are not unfiltered manufacturing sign-off. CI status is separately matched to the same commit and is unknown when no matching run exists. - Board identity uses exact normalized
boards[].path. Canonical project filenames win over old sibling project files; missing metadata is not borrowed. Unclassified does not mean Archive. Source layouts with no outline/components have a visible BOM failure, not a fabricated output. Angel explicitly excluded the three empty drafts from #148 on 2026-09-18; #148 is closed and their hardware follow-up remains under #149 (see engineering-portal). - Browser smoke check: serve a sandbox MkDocs output on loopback, then run
~/.local/share/shots-venv/bin/python ~/assistant/scripts/engineering-browser-check.py http://127.0.0.1:<port>/ --artifacts <evidence-dir>. It checks phone/desktop overflow, Home links, both KiCanvas canvases, source-commit text and BOM highlighting. Keepassets/portal.v1.cssinextra_cssto prevent the Home/Feedback controls overflowing a phone.
Log¶
-
2026-09-16: written for handing the portal to another engineer or AI.
-
2026-09-16: Production correction confirmed by Angel: Robot-Cow-004B is shipping; Robot Cow 4.0.1 is retired (Cow_Robot_Board commit 6a43367). The existing 4.0.1 fab pack is historical, not a pack for the production 004B board. See engineering-portal Open items for 004B fab.yml, release, and unverified IPN/firmware mappings.
-
2026-09-16: User prioritized a usage collector/dashboard and revenue-oriented operating plan during workflow implementation. Collector shipped at EmbeddedEra/ai-capacity and Home; see ai-capacity. Hardware workflow changes are preserved, not rolled out: resume
implementation/STATUS.mdin/home/angel/Documents/Codex/2026-09-16/home-angel-notes-projects-engineering-portal. The old phase2 process ended without a report; restart its bounded brief after reviewing partial diffs.
September 17: business operations automation direction¶
Current plan and task assignments: business-operations-automation. Tasks240–243 cover inventory valuation/build capacity, deterministic employee-scoped ERP actions, actual receivables/payables reporting, and private Chase/supplier imports. Reuse existing assistant actions and department agents. Prefer tested functions with schemas and receipts over repeated model reasoning; preserve existing Claude memory/routing and per-user permissions.