ADR-016 — License the project under MPL-2.0, without Exhibit B¶
Status: Accepted
Date: 2026-09-06
Closes: PRD 19
[OPEN-11](License choice), open since PRD v1Deciders: stakeholder
Evidence: Autodesk App Store Publisher Agreement, retrieved 2026-09-06, sections 4.3, 7(e), 14.3, 20.11, 20.12, 20.18, 20.19; a license audit of every dependency, hand-written component and asset in the repository
Context¶
The repository is going public. [OPEN-11] framed the choice narrowly — as a constraint
imposed by FreeCAD’s LGPL on a future shared core (G6) — but two other constraints turned
out to matter more, and one widely believed constraint turned out not to exist.
What the audit found: nothing blocks any license¶
Zero runtime dependencies, enforced by
tools/check_no_third_party.pyand by the CIpackagejob importing the bundle underpython -S(ADR-013). There is no third-party code in the shipped artifact to be compatible with.Dev-only dependencies are permissive or MPL-2.0 (pytest, ruff, mypy, sphinx, furo, myst-parser: MIT; numpy, pypdf, babel: BSD; coverage, requests: Apache-2.0; hypothesis, pathspec: MPL-2.0). None is distributed and none is linked.
Every hand-written component is original. The PDF writer implements ISO 32000-1, a spec Adobe publishes with a royalty-free grant for conforming implementations, and embeds no font — base-14 Helvetica is referenced by name only. The icons are generated by
tools/make_icon.py. No Autodesk stubs are committed and no third-party fixture data exists: PRD 11 records measurements of a model, not the model.One provenance risk existed and was removed.
core/linalg.pycited Numerical Recipes, whose code is not redistributable under any license. The routine is an independent 3x3 implementation — nob/zcorrection vectors, notreshschedule, a Frobenius-scaled convergence test, the three index pairs enumerated rather than looped — so the exposure was the citation’s wording, not the code. Golub & Van Loan is now the primary reference and the independence is stated in the docstring.
Constraint 1 — the Autodesk App Store, measured rather than assumed¶
The belief that copyleft bars an app from the Autodesk App Store is wrong as stated, and the way it is wrong changes the decision.
Clause |
What it actually says |
|---|---|
7(e) |
warrants no Open Source Software is included “in a manner that could cause any Autodesk Assets to be subject to any Open Source License”, then adds: “In the event that Your App includes Open Source Software, You will comply with all licensing terms for such Open Source Software.” |
20.18 |
“Open Source License” = any Copyleft License plus any OSI- or FSF-approved license |
20.12 |
“Copyleft License” names GPL, LGPL, Artistic, the Mozilla Public License, NPL, SCSL, SISL, CPL, SSPL |
20.5 |
“Autodesk Assets” = the Marketplace, Autodesk Confidential Information, Trademark Materials, Autodesk websites, and other Autodesk products or services |
4.3 |
the publisher may furnish a Custom End User Agreement; six minimum terms are mandated |
20.11 |
commission is currently 0.0 %; paid distribution is supported |
Three consequences follow. Open source is permitted — 7(e) forbids infecting Autodesk’s assets, not shipping OSS, and the next sentence says so. No license escapes the clause by category, because 20.18 sweeps in MIT and BSD as well; picking a permissive license to “be safe” is a misreading. And MPL is named as a Copyleft License in 20.12 exactly as GPL is, so MPL is not chosen here to dodge that clause — the advice that MPL clears app stores comes from Apple’s terms and does not transfer.
What does differ between GPL and MPL under this agreement is 4.3. Of the six mandatory Custom EULA terms, five (relationship acknowledgement, warranty disclaimer, liability for claims, third-party beneficiary, publisher contact) sit inside what GPLv3 §7(a)–(f) already permits a licensor to add. The 18+ representation does not, and GPLv3 §10 forbids imposing further restrictions. MPL has no equivalent of §10 and explicitly contemplates distributing the Executable Form under terms of the distributor’s choice (§3.2), so the same EULA raises no question at all.
Constraint 2 — the proprietary host¶
core/ never imports adsk (ADR-002), but adapter/ and ui/ must, and the add-in runs
inside Fusion’s process. Under the GPL this invites the long-running argument about whether
a plugin sharing an address space with a proprietary program forms a single combined work.
Nobody distributes that combination — the user assembles it, and the GPL does not reach
private use — but a redistributor would have to make the argument, and an App Store reviewer
reading 7(e) would have to be persuaded by it. Answering that argument needs a GPLv3 §7
additional permission for the Fusion API.
Under MPL the question does not arise: §3.3 permits the Covered Software to be part of a Larger Work under other terms, so no exception has to be drafted, granted or defended.
Constraint 3 — the one [OPEN-11] actually named¶
FreeCAD is LGPL-2.0-or-later. MPL-2.0 §1.12 defines GPL, LGPL and AGPL as Secondary
Licenses, and §3.3 lets a recipient distribute Covered Software under one of them —
unless the file carries the Exhibit B notice. Omitting Exhibit B therefore satisfies
[OPEN-11]’s requirement directly.
Decision¶
The project is licensed under the Mozilla Public License 2.0. Exhibit B (“Incompatible With Secondary Licenses”) is not applied to any file, now or later.
LICENSEholds the canonical MPL-2.0 text, unmodified.Every file of the shipped tree —
src/**/*.pyandMightyMiter.py— carries the Exhibit A notice plus a copyright line. These are the files whose covered status has legal consequence, because MPL copyleft is per-file.tests/,tools/,docs/andprd/are covered by the repository-levelLICENSEunder MPL’s own Exhibit A allowance for a notice “in a location … where a recipient would be likely to look”. They are not distributed (PRD 14.2) and headering ~70 further files would add noise without changing anything.The CI
packagejob copiesLICENSEinto the bundle and asserts it is non-empty. MPL §3.1 requires the license to travel with the Source Code Form; the job’s comment had claimed this copy since the job was written, and it was not happening.
Consequences¶
Modifications to these files stay open. Anyone distributing a changed
core/unroll/cylinder.pymust make that file’s source available under the MPL. The geometry — the part that is hard and the part that must be checkable — cannot be taken closed.The larger work may be proprietary. Someone can wrap this core in closed code and ship it, republishing only their changes to MPL-covered files. This is a real concession relative to the GPL and it was made deliberately, in exchange for removing two arguments (the App Store’s 4.3, the combined-work question) rather than managing them.
App Store distribution stays open, including paid. Charging a fee was never the obstacle; the GPL permits selling copies too. 7(e) still has to be answered honestly if Autodesk asks — the answer is that the MPL covers only the files in this repository and cannot reach Fusion — but that answer is now underwritten by §3.3 rather than by argument.
A future FreeCAD addon may absorb
core/into GPL/LGPL code via §3.3. Adding Exhibit B to any file at any point would silently revoke this, which is why it is prohibited here rather than merely omitted.Contributions need no CLA. MPL §5.1’s patent-defense termination and the per-file scope make inbound=outbound sufficient. This is the concrete cost avoided by not choosing the GPL dual-licensing route below.
Every new file under
src/starts with the Exhibit A header, no file anywhere carries Exhibit B, and the bundle containsLICENSE. All three are asserted intests/unit/test_license_notices.py, because a constraint that only lives in prose is not enforced — the lesson of ADR-015, and thecpline above is the proof.
Alternatives rejected¶
GPLv3 with a §7 additional permission for the Fusion API. The strongest copyleft, and it does work: the exception answers the combined-work argument in writing. Rejected on 4.3 — the mandatory 18+ representation is outside the §7(a)–(f) list that GPLv3 §10 otherwise forbids adding — and on the reviewer risk that 7(e) presents to a license naming itself in 20.12 while also being the one the clause’s drafters plainly had in mind.
GPLv3 plus dual licensing under the sole copyright. Also works: a sole copyright holder is not bound by their own license and may ship the identical code to the App Store under Autodesk’s Standard EULA. Rejected because it only keeps working while the copyright stays consolidated, which means a CLA on every outside contribution. For a tool whose value depends on fabricators and other CAD developers contributing corrections, that friction costs more than the copyleft strength it buys.
LGPLv3. Worse than both: named in 20.12 anyway, inherits GPLv3 §10, and its relink requirement is meaningless for a plain Python source tree that ships as source.
MIT or Apache-2.0. Would end every question above, and gives up the one guarantee worth keeping — that a corrected unroller stays public. 20.18 makes them “Open Source Licenses” under the Publisher Agreement regardless, so they do not even simplify 7(e).
MPL-2.0 with Exhibit B. Rejected explicitly: it would close the FreeCAD path that
[OPEN-11]was raised to protect, in exchange for nothing this project wants.