Repository navigation
Conversation
LICENSE has held the Unlicense since the repository was created (df6e5dd), but pyproject.toml declared MIT from the first code scaffold (d1a6630) and docs/myst.yml (2e0aa0d) repeated it, so a built wheel said License-Expression: MIT while bundling the Unlicense text. Set the package metadata and the MyST docs license to Unlicense, add a README License section that names it and exempts the vendored third-party files, and add tests/test_license.py, which finds every tracked license-bearing manifest and checks that each names the Unlicense, that pyproject carries no License classifier, and that the README names no other license. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The mismatch
GitHub detects
LICENSEas the Unlicense (gh api repos/PolicyEngine/policybench/license --jq .license.spdx_idreturnsUnlicense), butpyproject.tomldeclaredlicense = "MIT"anddocs/myst.ymldeclaredlicense: MIT. A wheel built from main carries both at once: its metadata saysLicense-Expression: MITwhile theLICENSEfile bundled with it is the Unlicense text.This PR declares the Unlicense everywhere.
Why the Unlicense
The history shows the Unlicense was selected when the repository was created, and MIT arrived with the first code scaffold:
df6e5dd"Initial commit"GitHub <noreply@github.com>, adds onlyLICENSE, a.gitignoreand a two-lineREADME.md.d1a6630"Initial version"license = {text = "MIT"}and the classifierLicense :: OSI Approved :: MIT Licensetopyproject.toml. The same commit also checked in stray renders (tmp9wmiy2qk.html,output.html).87fb46a"PolicyBench v2: complete rewrite"licenseline carried over unchanged.2e0aa0ddocs/myst.ymlwas added withlicense: MIT.4d96c18"Address review findings"{text = "MIT"}as the SPDX string"MIT". The value did not change.No commit on any branch changed
LICENSE, and no commit message, PR or issue discusses choosing MIT. The Unlicense also matches how Max set up repositories at the time: 12 of the 15 public repositories he created under his own account from October 2024 to April 2025 use it (two use MIT, one AGPL-3.0).It also imposes fewer conditions. The Unlicense dedicates the authors' copyright to the public domain where the law allows it and lets anyone use the code for any purpose, with no conditions on reuse. MIT requires that its copyright and permission notice be included in all copies or substantial portions. Both disclaim warranties.
Relation to the September 2026 MIT work. In September Max chose MIT over Apache-2.0 for Axiom's public code because it is the more permissive of the two (TheAxiomFoundation/axiom-mcp#25). In the same month, a license pass across PolicyEngine repositories added MIT to unlicensed code repositories. That pass left the repositories already under the Unlicense, this one included, as they were. The more-permissive reasoning points to keeping the Unlicense here. Moving to MIT later would mean replacing
LICENSEand the three declarations;tests/test_license.pywould point at each one.Dependencies. PolicyBench imports
policyengine,policyengine-usandpolicyengine-uk, which are AGPL-3.0. The FSF's license list lists both the Unlicense and Expat/MIT as compatible with the GNU GPL, so this change does not alter how those dependencies apply.Contributors. On main, every commit is authored by Max except Pavel Makarchuk's Google Analytics tag (#79). The squash-merged #5 and #47 include commits by Daphne Hansell, and #82 includes one by Pavel; each is credited in a
Co-authored-bytrailer. All of it landed whileLICENSEheld the Unlicense (andpyproject.tomlsaid MIT).The tradeoff
isOsiApproved: true, and OSI's page https://opensource.org/license/unlicense lists its approval. CC0, by contrast, is not OSI-approved; Creative Commons withdrew it from OSI review.Unlicense OR MITas ripgrep is. The dual option needs an MIT license file with a copyright line. Whether a dual offer satisfies an exclusive allowlist is the rule-setter's call.https://pypi.org/pypi/policybench/jsonreturns 404), so no released distribution carries the MIT metadata.Changes
pyproject.toml:license = "Unlicense". The wheel and sdist built withuv buildnow carryLicense-Expression: UnlicenseandLicense-File: LICENSE(Metadata-Version 2.4).docs/myst.yml:license: Unlicense. MyST reads a single string as the docs site's license, and its license table knows theUnlicenseid (myst-frontmatter 1.10.1, and the copy bundled with jupyter-book 2.1.2, whichuv.lockpins). No CI workflow builds the MyST site, so the new test is what checks this file.README.md: new "License" section naming the Unlicense. It also says that third-party files keep their own licenses and terms: the vendored Quarto web libraries inapp/public/paper/web/site_libs/and the captured Vals.ai leaderboard inpaper/external/. The README had no license badge or section before.tests/test_license.py: new; described under Invariant.LICENSE(GitHub already detects it correctly);app/package.json("private": true, nolicensefield);paper/_quarto.yml(nolicensefield);MANIFEST.in(already includesLICENSE);uv.lock(uv lock --checkpasses; the lock does not record the project's license). The site and the data-release notes declare no license.Invariant
Every license declaration in the repository names the license in
LICENSE, SPDX idUnlicense.tests/test_license.pychecks it three ways:LICENSEis the Unlicense text.licensekey, at any depth. Those formats arepyproject.toml,setup.cfg,package.json,myst.yml,_quarto.yml,CITATION.cff,codemeta.json,.zenodo.jsonandCargo.toml. Files are found withgit ls-files, and the vendoredsite_libsare excluded. The test also requirespyproject.tomlanddocs/myst.ymlto be among the files found, andpyproject.tomlto carry noLicense ::classifier.Mutation checks, run in a scratch worktree:
LICENSEitself is unchanged)CITATION.cffwithlicense: MITCITATION.cffwithlicense: Unlicenseapp/package.jsongains"license": "MIT"pyproject.tomlpyproject.tomllicenseUnlicense OR MITpyproject.tomllegacy{text = "Unlicense"}license-files = ["LICEN[CS]E*"]license: "Unlicense"(quoted){content: Unlicense, code: Unlicense}{content: CC-BY-4.0, code: Unlicense}No computed output changes, so property-based tests do not apply.
Verification
uv run ruff check .anduv run ruff format --check .pass.uv run pytest -m "not slow"on Python 3.12 at head89f16e0: 1566 passed, 8 skipped, 15 deselected.uv build: the wheel and sdist metadata are as stated above. On main, the same build givesLicense-Expression: MITwith the Unlicense text as the bundledLICENSE.pyproject.tomlchanged; the license value does not enter the render.🤖 Generated with Claude Code