---
name: aieng-cad-authoring
description: Active MCP-first CAD authoring skill for AIENG Workbench. Use when the user asks to create, design, draft, model, or iteratively build CAD geometry through the active cad.* MCP tools. Do not use for solver/result review, schema/library implementation, or editing legacy IR plans.
---

# aieng-cad-authoring

MCP-first CAD authoring discipline for agents driving the active AIENG Workbench.
The recommended path is the live MCP toolchain and build123d runtime, not the older schema-plan CLI flow.

## Purpose

- Create or extend real CAD geometry through `cad.execute_build123d`.
- Keep generated geometry inspectable with named parts, colors, and editable constants.
- Use the UI as the live 3D viewer and spatial pointer surface.
- Preserve evidence honesty: CAD output is geometry evidence, not engineering validation.

## When to use

Use when the user asks to create, build, design, model, add, or substantially modify CAD geometry.
For pure dimensional tweaks on an existing editable model, prefer `cad.edit_parameter`.
For engineering audit only, use `cad.critique` without mutating geometry.
For solver workflows, use `aieng-cad-cae-copilot`.

## Required workflow

1. Call `aieng.agent_readme`, `aieng.list_projects`, and `aieng.agent_context { project_id }` when project state is not already known.
2. Call `cad.get_source { project_id }` before incremental edits; use `mode="append"` only when `has_base=true`.
3. For new/additive geometry, call `cad.execute_build123d` with build123d Python that:
   - binds the final model to `result`,
   - omits export calls,
   - sets `.label` on every meaningful part,
   - sets `.color = Color(r,g,b)` for readability,
   - declares editable dimensions as `UPPER_SNAKE_CASE` constants.
4. Inspect the returned thumbnail, `named_parts`, `parts_added`, `geometry_report_summary`, symmetry, and gaps before continuing.
5. For pure dimensional changes, use `cad.edit_parameter` and read `regression_diff` before trusting the result.
6. For mechanical parts, call `cad.critique` after creation and fix blocking manufacturability findings.

## Self-correction before presenting a result

Do not present a build as done just because it executed. Read the deterministic
signals every `cad.execute_build123d` / `edit_parameter` / `replace_part` /
`remove_part` returns and self-correct first:

- **`geometry_report_summary`** is always present (both `response_detail` modes):
  a one-line `part_count / size / proportions / floating=N / symmetry_issues=N`.
  Non-zero `floating` means a part is detached (usually a coordinate typo);
  non-zero `symmetry_issues` means a left/right pair is mismatched or missing.
- **When `floating` or `symmetry_issues` is non-zero, call `cad.design_review`**
  (read-only). It folds the critique + those structural signals into one
  severity-ranked `actions` list and binds each fixable finding to a concrete
  `cad.edit_parameter` target (`featureId` / `parameterName` / range). Fix the
  highest-severity targets, then re-run the review. It mutates nothing — applying
  a fix still goes through the approval-gated edit path.
- **Reference images.** When the user names a real product / character / vehicle
  but supplies no picture, call `cad.search_reference_image { project_id, query }`
  before iterating — it attaches a Wikimedia Commons match so every thumbnail is
  calibrated against the real proportions. Verify the returned `page_url`'s
  source/license; `status: "no_results"` just means proceed without one. If the
  user gives a URL/file, use `cad.set_reference_image` directly.
- **Reversibility.** Each successful CAD mutation is auto-snapshotted; if an edit
  goes wrong, `cad.list_snapshots` then `cad.restore_snapshot` rolls back
  (approval-gated). Iterate freely rather than over-planning a single build.
- **Category starters.** For a common shape (flange, plate, bracket, enclosure,
  bushing, aircraft, vehicle, wheel), `cad.plan_build123d_skill` returns a
  parameterized starting point with editable constants — review it, then execute.

## Standard parts (bd_warehouse)

For standard mechanical parts — fasteners, nuts, washers, bearings, gears, threads,
pipes, flanges — prefer the **bd_warehouse** library over approximating with
`Cylinder`/`Box`. It gives ISO/DIN/ANSI-compliant dimensions and semantically real
parts (a screw, not a cylinder). It is pre-installed and the modules are pre-bound
in the `cad.execute_build123d` namespace — no import line needed:

```python
# Pre-bound module aliases: fastener, bearing, gear, thread, pipe, flange, sprocket
screw = fastener.SocketHeadCapScrew("M6-1", length=12, simple=True)
screw.label = "mounting_bolt_M6"          # keep labels semantic + canonical
brg = bearing.SingleRowDeepGrooveBallBearing("608", bearing_type="SKT")
result = Compound(children=[screw, brg])
```

You may also `from bd_warehouse.fastener import SocketHeadCapScrew` explicitly.

**Clearance / tapped holes — pass a Fastener OBJECT, never a size string.**
`ClearanceHole` / `TapHole` / `InsertHole` take the actual fastener instance as
their `fastener=` argument (so they can look up the correct drill diameter), plus
a `fit` of `"Close"` / `"Normal"` / `"Loose"`. Passing a string like
`fastener="M6"` raises `AttributeError: 'str' object has no attribute
'clearance_hole_diameters'`. Build them inside the part so they cut the bolt
pattern:
```python
with BuildPart() as bp:
    Box(80, 60, 8, align=(Align.CENTER, Align.CENTER, Align.MIN))
    screw = fastener.SocketHeadCapScrew(size="M6-1", length=16, simple=True)
    with Locations((30, 20, 8), (-30, 20, 8), (30, -20, 8), (-30, -20, 8)):
        fastener.ClearanceHole(fastener=screw, fit="Normal")   # object, not "M6"
    result = bp.part
```
If you only need the hole (no fastener semantics), a plain `Hole(radius=...)` is
fine — but it will not carry `standard_part` ISO designation in the feature graph.

- Use `simple=True` on threaded fasteners unless real thread geometry is required
  (real threads add many faces → larger STEP/STL and slower viewer load).
- Label standard parts with semantic roles (`screw`, `bolt`, `washer`, `bearing`,
  `gear`, `flange`) even though the runner now records best-effort
  `bd_warehouse` provenance automatically. Recognized standard parts become
  `standard_part` feature-graph entries, remain available in `named_parts`, and
  carry source library, canonical type, designation, detection method, and
  confidence when known.
- Standard-part faces are pickable through the B-Rep pointer pipeline. A picked
  face may include conservative hints such as `head_top`, `head_side`,
  `shank_side`, `bearing_face`, or `washer_face`; do not treat those hints as
  preload, contact, thread engagement, or solver evidence.
- Gears: only spur gears are covered. Springs/cams/worms are not — hand-build those.

## Hard rules

- Respect `[APPROVAL REQUIRED]` tools; never bypass or hide approval boundaries.
- If `AIENG_MCP_BLOCK_APPROVAL_TOOLS=1` is active, gated CAD tools will be refused by the MCP server; report that and stop.
- Do not claim strength, safety factor, manufacturability, meshability, or simulation correctness from CAD generation alone.
- Do not read `aieng/src/` to infer live workbench capabilities; use MCP tool returns and `aieng.agent_readme`.
- For visible products/characters/vehicles, prefer loft/sweep/revolve/fillet helpers over primitive box stacking.
- For engineering parts, use canonical labels such as `base_plate`, `mounting_hole`, `rib`, `boss`, `flange`, and `interface_face`.

## Response contract

Report: tool sequence, key assumptions, parts created/changed, approval status, evidence inspected, and remaining limitations.
