Repository navigation
Pitloom 0.20.0 fixes many cases where the same input gave a different SBOM depending on how Pitloom was run (CLI subcommand, library API, Hatchling build hook or GitHub Action). It also changes how wheel SBOMs are built: they now describe the wheel's payload only.
Major changes:
- Same output on every surface. Settings, AI model results, licences and IDs now come out the same whichever way Pitloom is run.
--configworks on every command, and a setting that does not apply to a target gives aWARNING:instead of being silently ignored. - Wheel SBOMs list payload only. The wheel's own
.dist-infometadata is no longer listed as a file in the SBOM, nor counted in the files' Merkle root, sowheel,embed-wheel,wheel --embedandgenerate <whl>record the same files. - Licences typed per SPDX 3. A valid SPDX licence is a canonical
LicenseExpression; anything else isSimpleLicensingText.NOASSERTIONandNONEuse the SPDX individuals, andLicense ::classifiers are read as a licence source. Licence detection from aLICENSEfile is more accurate: it no longer misses MIT after a copyright line, and no longer picks a near-variant (PixaroverApache-2.0). - ID registry only when declared. The registry is never searched for; a declared registry that is missing or broken is an error on every surface.
loom idsis renamedloom id,--registryis renamed--id-registry, and the registry file format is now v2. - AI models inside wheels.
wheelandembed-wheelnow find AI models packed in a wheel, with a size cap.--trust-wheel-modelcontrols whether their metadata is read. Recording which Python files use a model (--scan-model-usage) is now off by default. - Signed release SBOM. Pitloom's own release ships the SBOM its build hook embedded, attached to the release byte for byte, signed with Sigstore and attested.
Known issue: with -o -, a PITLOOM_SBOM_OUTPUT_PATH=- line follows the SBOM on stdout, so piping the JSON straight into a parser fails. The fix is planned for 0.20.1.
Note
Limitation notes: While Pitloom can work with any Python project, it currently gathers more information from Flit, Hatchling, PDM, Poetry, setuptools, and uv_build projects. Support for build with compiled artefacts (maturin, scikit-build-core, meson-python) is in the plan. See full limitation notes.
Install for CLI/Python API:
pip install -U pitloomInstall for AI coding assistant:
See the website on how to install Pitloom AI skills and the Claude Code plugin.
Try asking the AI agent to "generate SBOM for this project".
Report issues: https://github.com/bact/pitloom/issues
What's changed
- Add --build-timeout for --allow-build by @bact in #226
- Fix embed-wheel ignoring --content-type-method and --max-source-metadata-bytes by @bact in #227
- Fix type check for Hatchling 1.32.4 BuildHookInterface revert by @bact in #229
- Route every surface's settings through one config cascade by @bact in #228
- Fix flaky tests: pin SBOM created, drop is_alive-before-join by @bact in #230
- Read config only from the target or an explicit --config by @bact in #231
- sdist reads its own config; LF, UTC Z and sorted keys by @bact in #232
- Bump codecov/codecov-action from 7.0.0 to 7.1.1 by @dependabot[bot] in #233
- Fix spdxId collisions with registry-supplied ids by @bact in #234
- Explicit ID registry: declared-only, one error, stable ids by @bact in #235
- loom env: fix "unknown" packages (pipdeptree --json shape) by @bact in #236
- Roadmap: deferred items, AI-scan plan; release checklist by @bact in #237
- Network tests: skip with cause in CI, strict publish gate by @bact in #238
- Scanner: ModelCandidate refactor, stable model paths by @bact in #239
- Fix None doc and bandit findings in scripts by @bact in #241
- Close HTTPError in urllib handlers (3.14 ResourceWarning) by @bact in #242
- Scanner: deterministic AI model and usage order by @bact in #240
- embed-wheel: concluded licence + release SBOM gate by @bact in #243
- Warn and skip unreadable files in project file scan by @bact in #244
- Move embed SBOM generation into _embed_generate.py by @bact in #245
- Promote registered temp-dir helpers to core.temp_dirs by @bact in #246
- CI: check SBOM concluded licence on every PR by @bact in #248
- setup.cfg: read bool/int [tool:pitloom] keys as TOML does by @bact in #247
- Split config parsing: read primitives and file-scan keys by @bact in #249
- Name the guarded activity in termination messages by @bact in #250
- Normalise wheel and sdist member names on every OS by @bact in #251
- Add --scan-model-usage; usage pass off by default by @bact in #252
- ID registry v3 design by @bact in #255
- Warn and ignore wrong-typed [tool.poetry] values by @bact in #254
- Percent-encode names in SPDX ids and namespaces by @bact in #253
- Drop _project_doc_identity; test enrich_model directly by @bact in #256
- One-line WARNING for discovery and build failures by @bact in #258
- Break import cycles hidden by import order by @bact in #260
- Retry SBOM validation on network errors in build CI by @bact in #259
- Print one ERROR line on Ctrl-C instead of a traceback by @bact in #262
- Warn when file discovery cannot list a directory by @bact in #257
- Fix manual CLI checks importing the wrong Pitloom by @bact in #261
- Bump github/codeql-action/upload-sarif from 4.38.0 to 4.38.1 by @dependabot[bot] in #264
- Pitloom presentation ETSI Security Conference 2026 by @bact in #265
- Scan AI models in built wheels, with bounded readers by @bact in #263
- Record GGUF arrays as lengths; cap pickle decimals by @bact in #267
- Take wheel identity from its own .dist-info only by @bact in #266
- Add tests/extract to pylint by @bact in #268
- Give every confirmed AI model one entry on every surface by @bact in #270
- List payload only in wheel SBOMs; refuse signed wheels by @bact in #271
- Sort sdist file list before minting SPDX ids by @bact in #272
- Strip a given .spdx3.json from sbom-basename by @bact in #273
- Fix Windows flake in build-timeout e2e test by @bact in #274
- Ship the build hook's SBOM in the release, signed by @bact in #275
- Test re-embedding into a wheel that carries an SBOM by @bact in #277
- Pin the clock in the sdist member-order test by @bact in #279
- Refuse a wheel named .WHL on every surface by @bact in #278
- Reject bad max-source-metadata-bytes; warn on unknown keys by @bact in #280
- Print only KEY=VALUE data on CLI stdout by @bact in #281
- Read sdist PKG-INFO headers only; licence-file pick rules by @bact in #282
- Type licence elements; read classifiers on every surface by @bact in #276
- Detect licences in sdists as in project directories by @bact in #283
- Unify licences in fragment merges; envelope loom merge by @bact in #284
- Docs: licence rules, known bugs, test tiers, field notes by @bact in #285
- Fix licence detection on real files by @bact in #286
Full Changelog: v0.19.0...v0.20.0