A verified data factory for CAD
A text-to-CAD model is only as good as the data it learns from. So we stopped looking for CAD data and started manufacturing it — and we refuse to keep a single part we haven't proven correct.
The hard part of text-to-CAD is not the model. It's the data. There is very little clean, parametric CAD in the open, and most of what exists is dead geometry — meshes and STEP files with the design intent already stripped out. You can train a model to imitate the surface of a part from that. You cannot train it to reproduce the reasoning that built the part, because the reasoning was thrown away before the file was ever saved.
So we took the opposite position. Instead of harvesting whatever CAD we can find and hoping it teaches intent, we generate CAD we fully control and verify every piece of it before it earns a place in the corpus. A data factory, not a scraper. This note is about how we think about that factory — why it exists, why it runs on FreeCAD, and what "verified" actually buys us.
What we want the model to learn
We don't want a model that emits a shape. We want a model that reasons the way an engineer does: choose datums, express every dimension as a relationship, predict what the finished part should measure, and then check its own work. If that's the behaviour we want out, that's the behaviour the data has to carry in — the answer alone isn't enough.
So every record is built from a Blueprint: a part described entirely as expressions over named variables, with no magic numbers anywhere. A wall thickness is (od - id) / 2, never 3.0. The design intent lives in the relationships between dimensions, and those relationships are exactly what we want the weights to absorb.
A constant teaches a model to memorise one part. A relationship teaches it to design a family of them. Freezing every dimension as an expression is what turns a dataset of shapes into a dataset of reasoning.
Why we build it in FreeCAD
To manufacture data at scale, we needed a CAD engine that is five things at once: open and scriptable end to end, able to run headless across many workers, deterministic, backed by a real B-rep kernel, and free to run tens of thousands of times. Only one option is all five, and it's FreeCAD.
The alternatives each fail on at least one axis:
- Commercial and cloud CAD (Onshape and friends) have excellent kernels, but they're API-metered, license-gated, and cloud-bound. You can't cheaply build a solid a million times, and you can't ship the toolchain alongside the dataset so others can re-verify it.
- Code-CAD libraries like build123d are superb for code-native parts, and we compile to build123d as a second backend — but a library is not a full parametric document. It has no sketch-constraint history, no native feature tree, none of the editable structure an engineer actually manipulates.
FreeCAD gives us the OpenCASCADE kernel for free, a scriptable headless process we can fan out across workers, and a native PartDesign history with real sketches, constraints, and feature order. Crucially, it also gives us the same failure modes a real engineer hits — boolean failures, self-intersections, walls too thin for the kernel to resolve. Those failures aren't noise to be filtered out. They're some of the most valuable signal we have.
Our intermediate representation is kernel-independent — a FeatureGraph that compiles to FreeCAD and build123d alike. FreeCAD is the forge where we build and verify at scale, not the format we're locked into.
How the factory works
The loop is deliberately simple, and it runs the same way for every part: Blueprint → build → verify → keep or repair.
The build step turns the frozen Blueprint into a solid in FreeCAD. The verify step is where the discipline lives — a part is admitted only if it passes its own frozen assertions, checked at three tiers:
- Closed-form exact — volume and extents matched to the governing expression to within one part in a million.
- Mesh-converged — quantities that have no closed form, checked to a tight tolerance with demonstrated convergence, so the number is real and not an artefact of a coarse mesh.
- Measured-bounded — properties we can bound but not solve exactly, held inside a proven envelope.
When a part fails, we don't throw it away. We capture the whole episode — failure, diagnosis, fix, and re-verification — as a repair record. A model trained only on things that worked never learns to recover; a model trained on repairs learns to debug its own geometry.
Diversity is enforced by construction, too. Each part gets a topology signature, and a per-signature cap stops the factory from stamping out twenty-five thousand near-identical plates. A supervisor relaunches the run with fresh seeds to keep exploring the long tail of shapes rather than saturating the easy ones. The result is a Blueprint that reads less like a script and more like a specification with its own acceptance tests:
PARAM od, id, t
DERIVE wall = (od - id) / 2 # intent, not a constant
DERIVE V = pi*(od/2)**2*t - pi*(id/2)**2*t
BUILD tube from od, id, t
ASSERT wall > min_wall # precondition, tier 1
ASSERT volume == V rel 1e-6 # closed-form, exact
ASSERT extent_z == t rel 1e-6 # measured vs expression
Only if the built solid satisfies every assertion does the record — reasoning and all — enter the corpus.
What we have so far
Running that loop gives us a corpus where every row is either provably correct, or a provably-correct fix of something that wasn't:
CORPUS corpus_v3_scale.db (SQLite, source of truth)
42,723 verified records
25,000 clean synthetic parts
3,126 distinct verified topologies
700 real-CAD topologies preserved
~17,000 repair records (failure -> fix -> re-verified)
TRAIN rl_corpus_v3_scale.jsonl
85,342 packed rows
- reasoning traces (plan + derivation + check)
- stepwise sequences with per-assertion reward
- preference pairs (verified vs. faulted)
- repair pairs (natural failures weighted 3x)
frozen, checksummed, and backed up off-machine
It's not a large dataset by web-scraping standards, and it isn't meant to be. Every one of those rows was built, measured, and checked against its own definition of correct. That's the trade we're making: not the most CAD we can gather, but the most CAD we can trust.
What's next
The factory works and the corpus is frozen. The next step is the reason we built any of it — fine-tuning a model on this data, and then closing the loop: feeding the model's own failures back through the same verify-and-repair machinery, so the factory grows exactly where the model is weakest.
That's the subject of the next note in this series. We'll cover the training setup, what the verified data does to a model's behaviour, and the first results — once the model is trained.
To be continued — the fine-tuned model and its results will be added here as they land.
Related: A kernel-independent IR for editable CAD →
← All research