Overview

Burr / Overview

Burr

CAD linter.

Burr checks CAD intent and writes receipts.

For the full CAD source, CLI, receipt, and agent-loop explanation, see How Burr Works.

build123d source
-> generated STEP
-> burr-design-data.json
-> burr check
-> burr-receipt.json
-> fix the CAD or the declared rule

Install

Install the Rust CLI:

cargo install burr --version 0.29.0

Install the optional build123d helper in a CAD project:

uv add burr-build123d==0.10.0

The helper is only a way to emit burr-design-data.json while writing build123d. Burr core still checks JSON receipts, so other CAD tools can adopt the same contract later.

Quickstart

Create a starter part:

burr init my-part
cd my-part
uv sync
uv run python design.py
burr check .
burr explain .

Expected files:

my-part/
design.py
pyproject.toml
actuator.step
burr-design-data.json
burr-receipt.json

The STEP and receipt are generated artifacts. Commit the source and design intent. Ignore bulky generated CAD outputs unless a release artifact needs them.

Annotate CAD

In build123d, the useful pattern is one call that both cuts the geometry and records the mechanical feature:

from burr_build123d import BurrDesignData, DESIGN_DATA_FILE, m3_clearance_hole
design = BurrDesignData(
artifact_id="starter-actuator",
artifact_version="0.1.0",
artifact_type="actuator_mount",
units="mm",
)
m3_clearance_hole(
design,
part=plate,
feature_id="m3_loaded_mount_left",
center=(-18, 0),
edge_distance_mm=3.2,
intent="mechanical_interface",
role="loaded_mount",
)
design.write(DESIGN_DATA_FILE)

Target metadata is small on purpose:

{
"schema_version": "burr.design-data.v1",
"artifact_id": "starter-actuator",
"artifact_type": "actuator_mount",
"units": "mm",
"features": [
{
"id": "m3_loaded_mount_left",
"kind": "m3_clearance_hole",
"intent": "mechanical_interface",
"edge_distance_mm": 3.2,
"role": "loaded_mount"
}
]
}

Burr does not judge every random hole. It judges declared features selected by the active rulepack. Cosmetic holes, routing holes, labels, and relief cuts should be declared as cosmetic or left out of the mechanical rulepack.

Read The Receipt

Run:

burr check .

Passing output means Burr wrote a receipt:

PASS burr-design-data.json -> burr-receipt.json

The receipt contains measured facts and rule outcomes:

Receipt schema: burr.receipt.v1.

{
"status": "pass",
"checks": [
{
"status": "pass",
"rule_id": "m3_loaded_mount_edge_distance",
"feature_id": "m3_loaded_mount_left",
"measured": { "edge_distance_mm": 3.2 },
"required": { "min_edge_distance_mm": 2.7 }
}
]
}

Failing output is the useful part:

FAIL burr-design-data.json -> burr-receipt.json

Then ask Burr for the fix context:

burr explain .

Example failure:

Problem: an M3 loaded mount is too close to the part edge.
Measured: edge distance 1.8 mm
Required: at least 2.7 mm
Fix: move the hole inward, grow the local boss, or lower the declared load class.

That is the loop. The image tells you what it looks like. The receipt tells you what Burr actually checked.

Failure To Fix

Burr should be learned from a failure first.

In the starter part, the good M3 mount is safely away from the side edge. Move it too close by changing:

m3_hole_y = 20.0

Then rerun:

uv run python design.py
burr check .
burr explain .

Expected shape:

FAIL burr-design-data.json -> burr-receipt.json
Problem: the loaded M3 hole is too close to a free edge.
Evidence: Measured center-to-edge = 4 mm.
Evidence: Required center-to-edge = 10.2 mm.
Fix: move the hole inward or make the surrounding part larger.

Restore the original hole offset:

m3_hole_y = 12.0

Then rerun:

uv run python design.py
burr check .

Expected shape:

PASS burr-design-data.json -> burr-receipt.json

Website Proof

Fray displays Burr release artifacts at the Burr gallery.

The website does not regenerate CAD. It downloads a Burr release zip, validates the manifest, and renders PNG previews beside receipts and design data.

For a Fray website update, run:

cd fray-repos/fray-web
npm run burr-release:check
npm run build

The release guard checks:

  • burr exists on crates.io at the documented version;
  • burr-build123d exists on PyPI at the documented version;
  • the configured GitHub gallery zip downloads and validates;
  • the Fray site page points at the same release asset.

Fray consumes Burr repair action source hints from the configured gallery release. Each repair_actions[] entry includes a source_hint with exact before_text and after_text, plus edit_kind, selector, source_file_path, value_path, confidence, and before/after values. Fray validates and renders those fields; Burr owns the source-repair proof.

The slower clean-user proof belongs in the Burr repo:

cd repos/burr
npm run check:fresh-install

That Burr-owned gate proves the published install path plus the failure-to-fix loop:

cargo install
-> burr init
-> uv sync
-> uv run python design.py
-> burr check passes
-> move the M3 hole toward the side edge
-> burr check fails
-> burr explain gives the fix
-> restore the hole
-> burr check passes

Boundary

Burr is a linter, not a guarantee that a part is good.

It can catch declared CAD mistakes such as bad edge distance, missing seats, missing capture, or out-of-range measured clearances. It does not replace engineering judgment, assembly checks, collision checks, FEA, slicer review, or real bench testing.