The person is identified by an email address. A handle may be chosen later and does not replace it: the handle is a display name, the address is the id. Excluded from input_id and build_id. input_id answers whether two records describe the same part as specified, so two people specifying the same part must collide there; hashing the author would make identical parts claim to be different designs. The guarantee is structural rather than careful -- the ids are computed from the resolved parameter set and the author never enters it. That exclusion narrows the one-way door it was scheduled against but does not close it. A record regenerated later with the author filled in keeps its input_id, but build_id covers the code revision and the Shapely and GEOS versions, and boolean results on near-degenerate geometry can shift between GEOS releases -- the F-034 mechanism. Regenerate after a GEOS bump and you have attribution under a different build identity beside a printed part nobody can tie to either. Recoverable, not free. Priority order in HANDOFF section 4 is reversed accordingly: this before STL export, so the first coupon off the printer carries its author. The rendered line carries its own limit -- "(self-declared, unverified)". Nothing checks that the address belongs to whoever typed it, and a bare email in a field called author reads as identity to someone finding the file in five years. The record is meant to outlive everyone present, so it states what it knows. When an authenticated identity exists the qualifier changes and the distinction stays legible. Same discipline as Provenance.describe(), a separate type: provenance is about measurement, and design_record imports nothing from mechcomp, which is what keeps a failure in the record off the build path. parse() gets its own branch because authorship is neither input nor output and inherits neither rule. It recovers the address and never the verification: a text file cannot attest to its own verification, so reading a verified record back as self-declared understates the claim, which is the only safe direction. REVISION stays 8.0.0. The field reaches no geometry. 547 passed. The 529 are unchanged and no oracle case moved. The eighteen new assertions were mutation-tested with PYTHONDONTWRITEBYTECODE=1 and caches cleared between runs: leaking the author into input_canonical, deafening the parser, trusting the adjective, dropping the qualifier, and turning an empty author into an empty claim each fail the suite.
Mechanical Compiler
Build the capacity to construct real structures from reclaimed and commodity materials, using whatever fabrication is actually to hand — 3D printing, tabletop CNC, welding, cement casting, COTS stock.
The reference case is a faceted timber shell: planar panels meeting along straight fold lines, converging on nodes, sitting on a platform. Buildable without a factory, provided someone has worked out what the pieces are and how they meet. That last clause is the project. The Mechanical Compiler exists to make the pieces computable, qualifiable, and reproducible by someone who was not present when they were designed.
Scope
In scope: geometry, qualification, and reproducibility of structural members and their interfaces.
Not in scope: building codes, permitting, jurisdictional approval. Qualification and compliance are different things. A qualification says this member is what it claims to be, made this way, from this stock. Compliance is a jurisdiction-specific argument someone else may build on top.
The project records physical claims, never verdicts — section modulus, moment of inertia, material provenance, process parameters. Those are what any future argument would need. A pass/fail verdict would bake in a jurisdiction we do not want to be bound to. Measure and attest; never adjudicate.
Repository layout
docs/ specification, state, failure log, roadmap
legacy/openscad/ rev 8.0.0 generators — reference, not a live target
fixtures/ frozen acceptance oracles
tools/reference-toolchain/ pinned OpenSCAD + BOSL2, build-time only
src/mechcomp/ the application
tests/ acceptance against the oracle
Read docs/ROADMAP.md first for what this is, then docs/ENVIRONMENT.md for
how an instance is built. If you are writing provisioning automation, read
docs/FAILURES.md before the specification — every entry is something a
script written from the specification alone would have got wrong.
Getting started
make deps # virtualenv, base + CAD requirements
make verify-oracle # confirm the frozen oracle is intact
make test # pytest -n auto
make verify-oracle needs nothing but Python. It should pass on any machine at
any time; if it does not, stop.
The oracle
fixtures/strap-beam-8.0.0/ holds 123 frozen cases — 113 accepted, 10
rejected — produced by OpenSCAD 2021.01 with BOSL2 at 92d697c2. It is the
acceptance criterion for any reimplementation of the generators.
The ten rejected cases are part of the contract. A port that accepts them is wrong, however good its numbers look elsewhere. It is easy to reproduce the geometry and quietly lose the constraint that made it trustworthy.
The generators under legacy/openscad/ are the reference implementation, kept
so the oracle can be regenerated. They are not a live target and the running
application has no OpenSCAD dependency.
Provenance
This project's documents, code and roadmap are LLM-generated under human direction. That is stated plainly here and in any downstream submission. We do not obscure it.
The maintainer reviews and owns every line. Anything that could not be defended in a review thread does not ship.
Licence
AGPL-3.0-or-later. See LICENSE.
Section 13 obliges us to offer source to users interacting over a network, so any deployed web tier carries a visible link back to this repository. That is a licence obligation, not a courtesy.