Release assurance
Bomly CLI v0.28.1
Everything we check for this release was verified: 37 claims, all confirmed.
- Released
- 4 October 2026
- Commit
- 1c5079c745f8
How to read this
A claim
One specific statement about what this version of Bomly does — for example, that it reads an npm lockfile correctly, or that the files you download are the ones we signed.
Verified
Something ran against this exact release and confirmed the claim. Every result links to the record of it running, so nothing here has to be taken on trust.
What a verified claim does not mean. It covers what is listed on this page and nothing more. Software can still fail in ways nobody has written a check for. Claims that depend on outside services record what those services said on the day, and timing figures are measurements from one test machine rather than promises.
Nothing here is written by hand. The page is generated from the checks themselves and published automatically with each release, including any claim that was not confirmed. How this is produced.
At a glance
What this release was checked for. Each card opens the section behind it.
Scanning real projects
VerifiedRunning the real command line against pinned example projects and comparing the entire result with a recorded one.
2 claims verified
Dependency graphs
VerifiedWorking out which packages a project depends on, and how each one got there.
8 claims verified
Policy decisions
VerifiedDeciding what counts as a problem: licences, vulnerabilities, baselines, and packages that change where they come from.
4 claims verified
Reachability
VerifiedJudging whether a vulnerable package is actually used by the code that depends on it.
4 claims verified
Upgrade guidance
VerifiedThe fixes Bomly recommends, worked out without changing anything in your project.
1 claim verified
Comparing two scans
VerifiedTelling what genuinely changed between two scans, and what only looks new.
1 claim verified
Other scan targets
VerifiedScanning things that are not a local source tree, such as container images.
1 claim verified
SBOM compatibility
VerifiedReading SBOM documents other tools produce, and writing ones they accept.
3 claims verified
Running everywhere
VerifiedBehaving the same on Linux, macOS, and Windows, and building for every processor a release supports.
3 claims verified
Handling broken input
VerifiedReading damaged or hostile project, configuration, and SBOM files without crashing.
1 claim verified
Speed and repeatability
VerifiedHow long a repeated scan takes, and whether it returns the same answer every time.
1 claim verified
What you download
VerifiedWhether the published files are complete, unaltered, and signed by this project's release pipeline.
6 claims verified
Installing it
VerifiedWhether the documented ways of installing this release actually work.
1 claim verified
This report itself
VerifiedThe catalog and contracts the report is built from, and the check that keeps them honest.
1 claim verified
Ecosystems covered
The languages and package formats this release was scanned against. Each was exercised by at least one claim above.
Scanning real projects
VerifiedRunning the real command line against pinned example projects and comparing the entire result with a recorded one.
2 claims verified
VerifiedThe released binary scans real projects
Runs scan, diff, and explain with the binary from the published release against pinned example repositories and checks the results against the same golden files the source-tree smoke tests use.
What this shows
- The binary users actually download produces the same dependency graphs as the source tree it was built from.
What it does not
- A representative subset of ecosystems runs against the released binary; the full ecosystem matrix runs on the source tree before the release is tagged.
3 instances passed.
- packages
- 3
- tests failed
- 0
- tests passed
- 11
- tests skipped
- 0
- tests total
- 11
Check it yourself
sh -c BOMLY_SMOKE_BINARY=$PWD/bin/bomly go test -tags smoke ./test/smoke/ -run 'TestScan$/scan-go$'
VerifiedEnd-to-end scans of real projects
Runs scan, diff, and explain against pinned public repositories, one slice per ecosystem, and compares the whole result with checked-in golden files.
What this shows
- For every supported ecosystem, the command line produces exactly the dependency graph, policy result, and output shape recorded in the golden files.
What it does not
- Golden files pin one revision of one example project per ecosystem. They do not cover every project layout or every version of a package manager.
- Cases that reach live advisory services can change when upstream data changes.
22 instances passed.
- packages
- 22
- tests failed
- 0
- tests passed
- 107
- tests skipped
- 0
- tests total
- 107
Check it yourself
make smoke
Dependency graphs
VerifiedWorking out which packages a project depends on, and how each one got there.
8 claims verified
VerifiedVisible detector fallback
Forces a detector to fall back to a second technique and checks that the result says so instead of hiding it.
What this shows
- A detector fallback preserves its origin and produces a typed degraded-coverage warning.
What it does not
- The synthetic detector case proves orchestration behavior, not the fidelity of every concrete fallback.
Checked against
Confirmed for this release by
Check it yourself
go test ./internal/engine -run TestPipeline_RunRecordsFallbackWarning|TestPipeline_Run_TypesFallbackWarningsAsDegradedCoverage -count=1
VerifiedBun lockfile graph
Scans a pinned Bun example project and compares the whole dependency graph with a recorded one.
What this shows
- The native Bun detector preserves the package inventory and dependency placement represented by the pinned lockfile.
What it does not
- This is one Bun lockfile shape and does not prove behavior for every historical Bun format.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-bun$
VerifiedGo module graph
Scans a pinned Go example project and compares the whole dependency graph with a recorded one.
What this shows
- The Go detector resolves a build-tool-backed module graph for the pinned repository.
What it does not
- The result depends on a compatible Go toolchain and the evidence available from that toolchain.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-go$
VerifiedMaven dependency graph
Scans a pinned Maven example project and compares the whole dependency graph with a recorded one.
What this shows
- The Maven detector resolves a build-tool-backed dependency graph for the pinned repository.
What it does not
- Artifact resolution depends on Maven repositories and a compatible Java and Maven installation.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-maven$
Verifiednpm lockfile graph
Scans a pinned npm example project and compares the whole dependency graph with a recorded one.
What this shows
- The npm detector preserves lockfile package inventory, versions, scopes, and dependency placement.
What it does not
- This case covers the lockfile versions present in one pinned repository.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-npm$
Verifiedpnpm lockfile graph
Scans a pinned pnpm example project and compares the whole dependency graph with a recorded one.
What this shows
- The pnpm detector preserves lockfile package inventory and dependency placement.
What it does not
- This case does not cover every pnpm lockfile generation.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-pnpm$
VerifiedPython requirements graph
Scans a pinned Python example project and compares the whole dependency graph with a recorded one.
What this shows
- The pip detector reads the pinned requirements lock and preserves the resolved Python package graph.
What it does not
- Unpinned requirements and environment inspection have different fidelity and are not proven by this case.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-python-pip$
VerifiedYarn lockfile graph
Scans a pinned Yarn example project and compares the whole dependency graph with a recorded one.
What this shows
- The Yarn detector preserves package inventory and dependency placement represented by the pinned lockfile.
What it does not
- This case covers one Yarn lockfile family; fallback behavior is documented separately.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-yarn$
Policy decisions
VerifiedDeciding what counts as a problem: licences, vulnerabilities, baselines, and packages that change where they come from.
4 claims verified
VerifiedFinding baseline lifecycle
Records a package finding in a project baseline, then scans again and compares the whole result with a recorded one.
What this shows
- A project baseline can keep a denied package finding visible with suppressed policy status.
What it does not
- The local matcher fixture is deterministic but does not measure advisory freshness.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestFindingBaselineWorkflow$
VerifiedComplex and invalid SPDX policy
Evaluates licence policy against a matrix of SPDX expressions, including combined, nested, exception, custom, and invalid ones.
What this shows
- The license auditor evaluates AND, OR, nested, exception, custom-reference, and invalid SPDX expressions under allow and deny policy.
What it does not
- The tests prove policy evaluation after license data is present; they do not prove the accuracy of every upstream license source.
Checked against
Confirmed for this release by
Check it yourself
go test ./internal/auditors/license -run TestLicenseAuditorComplexSPDX|TestLicenseAuditorInvalidSPDXExpressionMatrix -count=1
VerifiedRegistry-to-Git source-change review
Compares two scans of the same project where one package moved from a registry to a Git source, and checks how that is flagged.
What this shows
- Diff marks a same-version registry-to-Git move for review and the package auditor can fail it when source-change policy is enabled.
What it does not
- A source change is a review signal, not proof of malicious intent, and unknown source evidence cannot be classified.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestDependencyDetailRiskPolicy$
VerifiedVulnerability policy constraints
Evaluates vulnerability policy against a matrix of severities, reachability tiers, known exploitation, and advisory allowlists.
What this shows
- The vulnerability auditor composes severity, reachability, known exploitation, and advisory allowlists with the documented repeated-constraint behavior.
What it does not
- Policy can only evaluate vulnerability, reachability, and exploitation evidence that is present in the registry.
Checked against
Confirmed for this release by
Check it yourself
go test ./internal/auditors/vulnerability -run TestAuditorSeverityReachabilityExploitabilityAndAllowlistMatrix -count=1
Reachability
VerifiedJudging whether a vulnerable package is actually used by the code that depends on it.
4 claims verified
VerifiedGo vulnerability reachability
Analyses a pinned Go project and checks the reachability evidence attached to each matched vulnerability.
What this shows
- The Go analyzer attaches named analyzer, tier, status, and reason evidence to matched vulnerabilities.
What it does not
- Advisories come from live services and may change; an unreachable result is not proof that a package is safe.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-go-reachability$
VerifiedJava package reachability
Analyses a pinned Java project and checks the reachability evidence attached to each matched vulnerability.
What this shows
- The Java analyzer separates package-reachable and package-unreachable vulnerability evidence.
What it does not
- This is package-tier evidence, not symbol-level proof, and live advisory results may change.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-java-maven-reachability$
VerifiedJavaScript package reachability
Analyses a pinned JavaScript project and checks the reachability evidence attached to each matched vulnerability.
What this shows
- The JavaScript analyzer separates package-reachable and package-unreachable vulnerability evidence.
What it does not
- This is package-tier evidence, dynamic loading can reduce confidence, and live advisory results may change.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-npm-reachability$
VerifiedPython package reachability
Analyses a pinned Python project and checks the reachability evidence attached to each matched vulnerability.
What this shows
- The Python analyzer separates package-reachable and package-unreachable vulnerability evidence.
What it does not
- This is package-tier evidence, reflective imports can reduce confidence, and live advisory results may change.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-python-pip-reachability$
Upgrade guidance
VerifiedThe fixes Bomly recommends, worked out without changing anything in your project.
1 claim verified
VerifiedCanonical read-only remediation guidance
Derives upgrade guidance for a set of findings and checks the fix status, versions, and per-occurrence advice it produces.
What this shows
- One central component derives fix status, recommended versions, occurrence actions, and detector advice without applying changes.
What it does not
- Suggestions are read-only evidence and are not guaranteed to work in every checkout.
Checked against
Confirmed for this release by
Check it yourself
go test ./internal/remediation -run TestDerivePackageRemediation|TestDeriveBuildsCanonicalOccurrenceSuggestions -count=1
Comparing two scans
VerifiedTelling what genuinely changed between two scans, and what only looks new.
1 claim verified
VerifiedRisk that persists across a version change
Compares two scans across a package version change and checks how a finding that survives the change is classified.
What this shows
- A vulnerability or license finding that remains across a package version change is classified as persisted instead of one resolved and one introduced finding.
What it does not
- Persistence uses the canonical package-finding identity; a genuinely different advisory or rule remains a distinct finding.
Checked against
Confirmed for this release by
Check it yourself
go test ./internal/engine/diff -run TestRun_SameVulnerabilityAcrossVersionBumpPersists|TestRun_SameLicenseIssueAcrossVersionBumpPersists -count=1
Other scan targets
VerifiedScanning things that are not a local source tree, such as container images.
1 claim verified
VerifiedContainer package inventory
Scans a public container image and compares the operating-system packages found with a recorded inventory.
What this shows
- Bomly can inventory the operating-system packages in the checked Alpine image.
What it does not
- The upstream image tag can move; the checked-in golden is a snapshot, not an immutable image claim.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestContainerScan/container-scan-alpine$
SBOM compatibility
VerifiedReading SBOM documents other tools produce, and writing ones they accept.
3 claims verified
VerifiedOfficial validators accept our SBOMs
Generates SPDX 2.3 and CycloneDX 1.7 documents from the code about to be released — one pair from a single input and one pair merged from two source documents — and validates all four with checksum-pinned official SPDX and CycloneDX tools.
What this shows
- The SBOM documents this release writes are accepted by the official SPDX and CycloneDX validators, at the exact validator versions recorded in the result.
- A document merged from two sources states its own identity and links both sources, rather than adopting one of them.
What it does not
- Validators check that a document is well formed against its specification. They do not check that every receiving tool interprets it the same way.
- The merge case uses two checked-in fixtures; it does not cover every combination of source formats.
- The documents are generated by a binary built from the release commit, before it is tagged, not by the published archive. The published files are verified separately.
4 generated SBOM documents passed spdx-tools-java 2.0.7 and cyclonedx-cli 0.32.0, and 1 document check(s) held.
- checks
- 1
- documents
- 4
- validators
- 2
Where it ran
Check it yourself
go run ./internal/assurance/sbominterop -bomly ./bin/bomly
VerifiedCycloneDX 1.6 ingestion
Reads a checked-in CycloneDX document and compares the dependency graph it produces with a recorded one.
What this shows
- Bomly ingests the checked CycloneDX 1.6 dependency graph.
What it does not
- The fixture covers one document shape and does not imply lossless conversion from every producer.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-sbom-cyclonedx$
VerifiedSPDX 2.3 ingestion
Reads a checked-in SPDX document and compares the dependency graph it produces with a recorded one.
What this shows
- Bomly ingests the checked SPDX 2.3 dependency graph.
What it does not
- The fixture covers one document shape and does not imply lossless conversion from every producer.
Checked against
Confirmed for this release by
Check it yourself
go test -tags smoke ./test/smoke/ -v -count=1 -timeout 15m -run TestScan$/scan-sbom-spdx$
Running everywhere
VerifiedBehaving the same on Linux, macOS, and Windows, and building for every processor a release supports.
3 claims verified
VerifiedRelease binaries build for every target
Cross-compiles the full and lite binaries for every supported operating system and processor from the same source tree.
What this shows
- The source tree compiles into both binaries for every Linux, macOS, and Windows target a release ships.
What it does not
- A successful build is not a test: it does not run the binary or check what it produces.
All 12 release binaries built: full and lite for Linux, macOS, and Windows on amd64 and arm64.
- builds completed
- 12
- builds planned
- 12
Where it ran
Check it yourself
gh workflow run assurance-prerequisites.yml -f ref=main
VerifiedUnit tests pass on every platform
Runs the full Go unit test suite twice on Linux, macOS, and Windows, so a pass is never a single lucky run.
What this shows
- Every unit test passes on all three supported operating systems, twice in a row, so a pass is not a one-off.
What it does not
- Unit tests run in process against fixtures. They do not download repositories or call external services.
3 instances passed.
- completed runs
- 6
- planned runs
- 6
Where it ran — 3 of 3 verified
Check it yourself
go test ./... -count=1
VerifiedJava detector tests are stable
Runs the Gradle, Maven, and sbt detector test suites ten times, because build-tool-backed detectors are where intermittent failures have actually appeared.
What this shows
- The build-tool-backed Java detector suites passed ten consecutive times.
What it does not
- This exercises the detectors against local fixtures with the toolchain installed on the runner.
The Gradle, Maven, and sbt detector suites passed ten times in a row.
- completed runs
- 10
- planned runs
- 10
Where it ran
Check it yourself
go test ./internal/detectors/gradle ./internal/detectors/maven ./internal/detectors/sbt -count=10
Handling broken input
VerifiedReading damaged or hostile project, configuration, and SBOM files without crashing.
1 claim verified
VerifiedParsers survive malformed input
Runs every registered Go fuzz target against the parsers that read untrusted project, configuration, baseline, SBOM, and plugin data.
What this shows
- Each registered parser handled its seed corpus and newly generated inputs without crashing during the time budget of this run.
What it does not
- Fuzzing explores a limited time budget. A clean run is evidence of robustness, not proof that no malformed input can cause a failure.
- Parsers that are command-backed or handled entirely by the standard library are excluded and listed in test/assurance/PARSER_FUZZING.md.
30 fuzz targets ran for 30s each against their seed corpus without finding a crash.
- targets
- 30
- targets failed
- 0
Where it ran
Check it yourself
make fuzz FUZZTIME=60s
Speed and repeatability
VerifiedHow long a repeated scan takes, and whether it returns the same answer every time.
1 claim verified
VerifiedRepeated scan speed and stability
Runs the same offline scan with the released binary several times with a cold cache and several times with a warm cache, and records timing, memory, and output stability.
What this shows
- Repeated runs of the same scan produced identical normalized output, and the recorded timings show how long that scan took on this machine.
What it does not
- Timing and memory are observations from one CI machine, not limits. Comparing them across releases is only meaningful because the case and the machine class stay the same.
canonical-sbom-scan completed 5 samples per cache mode with identical normalized output (cold median 37 ms, warm median 36 ms).
- cold ci95 upper (ms)
- 37 ms
- cold mean (ms)
- 37 ms
- cold median (ms)
- 37 ms
- peak memory bytes
- 41 MiB
- samples per mode
- 5
- warm ci95 upper (ms)
- 37 ms
- warm mean (ms)
- 36 ms
- warm median (ms)
- 36 ms
Where it ran
Check it yourself
make benchmark-samples
What you download
VerifiedWhether the published files are complete, unaltered, and signed by this project's release pipeline.
6 claims verified
VerifiedPublished files download and match
Downloads every published file from its public URL, without credentials, verifies the signature on the published checksum list, and checks each file against it.
What this shows
- Every file a user downloads from the public release page is present, reachable without credentials, and matches a checksum list signed by this repository's release workflow.
What it does not
- This checks availability and integrity at one moment from one network location.
- It confirms the published files match the signed list; it does not re-check the provenance attestation, which is verified before publication.
- Whether each archive contains a working binary is checked separately, against the draft release and by the install scripts.
All 23 published files downloaded from their public URLs without credentials and match the signed checksum list.
- files
- 23
Where it ran
Check it yourself
gh release download <tag> --repo bomly-dev/bomly-cli
VerifiedEvery release file is attached
Compares the files attached to the draft release against the full list a release is required to ship.
What this shows
- The release carries an archive for every supported platform, both binaries, every Linux package format, the checksum list, its signature, and the provenance file.
What it does not
- This counts files. Whether each archive contains a working binary is checked separately.
23 of 23 expected release assets are attached.
- assets
- 23
- assets missing
- 0
Where it ran
Check it yourself
go run ./internal/assurance/cmd verify-release --dir assets --version <version>
VerifiedReleased binaries report this version
Extracts the archives built for each operating system and runs the binaries inside them.
What this shows
- Both the full and lite binaries start on Linux, macOS, and Windows and report the version that is being released.
What it does not
- Only the architecture of the CI runner is executed for each operating system; other architectures are verified by checksum and build only.
3 instances passed.
Where it ran — 3 of 3 verified
Check it yourself
go run ./internal/assurance/cmd verify-release --dir assets --version <version> --scope native
VerifiedRelease files match their checksums
Hashes every release file each platform downloads and compares it with the published SHA256SUMS list.
What this shows
- Every file the release ships hashes to exactly the value recorded in the checksum list, and the list covers every file.
What it does not
- Checksums prove the files were not altered after they were built; the signature and provenance checks prove who built them.
3 instances passed.
Where it ran — 3 of 3 verified
Check it yourself
sha256sum --check SHA256SUMS
VerifiedBuild provenance verifies
Verifies the SLSA build provenance attached to the release with slsa-verifier.
What this shows
- The release archives were produced by this repository's tagged release workflow, as recorded in signed build provenance.
What it does not
- Provenance describes how and where the files were built. It does not review what the source code does.
SLSA build provenance verifies the linux/amd64 archives against this repository and tag.
Where it ran
Check it yourself
slsa-verifier verify-artifact <archive> --provenance-path multiple.intoto.jsonl --source-uri github.com/bomly-dev/bomly-cli
VerifiedChecksum list is signed
Verifies the Sigstore signature over the release checksum list with cosign.
What this shows
- The checksum list carries a valid Sigstore signature issued to this repository's release workflow, so the checksums themselves can be trusted.
What it does not
- The signature covers the checksum list. Individual files are tied to it through their checksums.
The checksum list carries a valid Sigstore signature issued to this repository's release workflow.
Where it ran
Check it yourself
cosign verify-blob SHA256SUMS --bundle SHA256SUMS.sigstore.json --certificate-oidc-issuer https://token.actions.githubusercontent.com --certificate-identity-regexp ^https://github.com/bomly-dev/bomly-cli/
Installing it
VerifiedWhether the documented ways of installing this release actually work.
1 claim verified
VerifiedInstall scripts install the release
Runs the published install script on each operating system against this release and asks the installed binary for its version.
What this shows
- The documented one-line install works on Linux, macOS, and Windows for this exact release, and the installed binary reports this version.
What it does not
- This installs into a temporary directory on a clean runner. It does not cover every shell, proxy, or locked-down corporate environment.
Check it yourself
sh -c BOMLY_VERSION=<tag> BOMLY_INSTALL_DIR=$PWD/bin sh scripts/install.sh
This report itself
VerifiedThe catalog and contracts the report is built from, and the check that keeps them honest.
1 claim verified
VerifiedAssurance catalog is valid
Validates this catalog and confirms every fixture and expected-result file it points at exists.
What this shows
- Every claim in this report points at a real check and at files that are present in this release's source.
What it does not
- A valid catalog says the paperwork is consistent; the checks themselves decide whether the software works.
The assurance catalog is valid and every fixture and expected-result file it names exists.
- checks
- 16
Where it ran
Check it yourself
make assurance-catalog
Compared with v0.28.0
What changed since the previous release.
- Every release file is attached: Failed → Verified
- Build provenance verifies: Failed → Verified
- Official validators accept our SBOMs: Failed → Verified