Here's a special kind of packaging bug: the project is properly licensed, the source tree has a LICENSE file, everyone agrees on the terms — and the thing your users actually download contains nothing a compliance tool can read.
Real case, reproducible today: protocolbuffers/protobuf#29440. The protobuf-7.36.0 wheel's METADATA says License: 3-Clause BSD License. That's free text, not an SPDX expression — and there is no License-Expression field at all. To be precise about what this means: the wheel does ship a dist-info/LICENSE file, so the license text is in there. What's missing is the machine-readable declaration (PEP 639). Any compliance pipeline that keys on SPDX expressions looks at this wheel and sees nothing it can evaluate. A previous fix attempt (#9441) didn't fully fix it; the issue is still open.
And it gets worse. ag-ui-protocol/ag-ui#1927: the ag_ui_strands-0.1.9 wheel has License: None, no License-Expression, no License-File, and zero license files anywhere in the archive. The monorepo root is MIT-licensed, but the published artifact inherits none of it — the hatch wheel config only includes src/. Scanners flag it "unknown license", and in enterprise procurement, "unknown license" is a polite way of saying "we can't use this."
The missing check
This is the seventh tool in my release-integrity series — the question each one asks is "the release passed, but what actually shipped?"
- readmeta: did your README render on PyPI, or are the images broken?
- wheeltruth: did your wheel ship complete, or are files missing?
- casecrash: will your filenames survive checkout on another OS?
- tagtruth: do your PyPI versions actually have matching Git tags?
- wheelreach: can your Python actually install what you declared it supports?
- entryprobe: does the installed CLI actually start?
- licenseproof: does the artifact say what license it's under?
licenseproof is a zero-dependency Python CLI. Point it at an artifact:
pip install licenseproof # PyPI upload pending rate limits; install from source meanwhile
licenseproof check --wheel dist/mypackage-1.0-py3-none-any.whl
source: dist/mypackage-1.0-py3-none-any.whl
verdict: LEGACY_LICENSE
detail: License: 'MIT' (free text, not SPDX); no License-Expression (PEP 639)
clean (legacy license info is a warning; use --require-spdx to fail)
It also checks sdists (--sdist) and installed distributions (--package).
Four verdicts, deliberately narrow
This is not a generic license scanner — pip-licenses and ScanCode already do that job. licenseproof answers one question: does this artifact contain license metadata and license text a compliance tool can use?
-
LICENSE_OK— an SPDXLicense-Expressionis present, and anyLicense-Filereferences actually exist in the dist. -
LEGACY_LICENSE— old-style info only: a free-textLicense:field, trove classifiers, or undeclared license text files. A warning by default — most of PyPI predates PEP 639, and failing all of it would be noise.--require-spdxturns it into a failure for projects that have decided to move. -
MISSING_LICENSE— no license metadata and no license text files. The ag_ui_strands case. A failure. -
LICENSE_FILE_MISSING— metadata references license files that aren't in the dist. A broken reference is worse than no reference, so this fails even when an SPDX expression is present.
Two deliberate strictness choices: a License: field containing UNKNOWN counts as absent (that's setuptools' default, not information), and an unparseable situation is never a silent pass.
What licenseproof does not verify
Presence and machine-readability — not meaning. A passing result confirms the expected license metadata fields and referenced files are present; License-Expression is checked for presence, but SPDX identifiers and expressions are not semantically validated. It doesn't interpret license compatibility or offer legal interpretation of any kind. For "what does this license obligate me to do", use a real compliance tool. licenseproof just makes sure the artifact gives that tool something to work with.
The release passed. Now check what actually shipped: github.com/hahahahahahahahah6/licenseproof
Top comments (0)