Skip to content

feat(cyclonedx): emit CycloneDX 1.7 with license acknowledgement and evidence - #1331

Merged
mstykow merged 2 commits into
mainfrom
feat/cyclonedx-1.7
Jul 24, 2026
Merged

feat(cyclonedx): emit CycloneDX 1.7 with license acknowledgement and evidence#1331
mstykow merged 2 commits into
mainfrom
feat/cyclonedx-1.7

Conversation

@mstykow

@mstykow mstykow commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Bump the CycloneDX renderer from spec 1.3 to 1.7.
  • Populate licenses[].acknowledgement (declared vs concluded) — the declared-vs-concluded distinction Provenant already expresses in SPDX (PackageLicenseDeclared / PackageLicenseConcluded), mapped from the same package fields. A parser-declared expression is declared; a license concluded from source/file detection is concluded.
  • Populate component.evidence — the file-content license detections of the files each component owns become evidence.licenses (distinct observed SPDX expressions) + evidence.occurrences (file + line), using the file.for_packages ownership assembly already computes. Only detected packages own scanned files, so promoted resolved dependencies carry no evidence.
  • CycloneDX renderer only: JSON specVersion/$schema and the XML bom namespace move to 1.7. SPDX and the native ScanCode-compatible JSON are byte-unchanged.

Issues

Scope and exclusions

  • Included: spec-version bump (JSON specVersion + $schema, XML namespace), licenses[].acknowledgement, component.evidence (licenses + occurrences), validator switch to SchemaVersion.V1_7, regenerated CycloneDX goldens + a dedicated evidence golden + the four examples/sbom, ADR 0012 amendment.
  • Explicit exclusions: 1.7 crypto/CBOM/formulation additions (not Provenant's use case); SPDX and native ScanCode-compatible JSON (unchanged).

How to verify

  • Beyond CI: set up a venv from scripts/requirements-output-format-validators.txt, then run python scripts/validate_output_format_fixtures.py (with the venv bin on PATH so pyspdxtools resolves). All CycloneDX goldens — including the new cyclonedx-evidence-expected.{json,xml} — validate against the official 1.7 JSON schema + XSD, and SPDX tag-value still validates. The four examples/sbom/*/sbom.cdx.json (now carrying evidence) also validate against 1.7 and their sbom.spdx against pyspdxtools.

Intentional differences from Python

  • N/A — this is CycloneDX spec-conformance work, not a ScanCode-parity surface.

Follow-up work

  • None. Component license evidence, originally floated as a possible split, landed here.

Expected-output fixture changes

  • Files changed: testdata/output-formats/cyclonedx-expected.{json,xml}, cyclonedx-dependencies-expected.{json,xml}, cyclonedx-expected-without-packages.json; new cyclonedx-evidence-expected.{json,xml}; regenerated examples/sbom/*/sbom.cdx.json (and sbom.spdx re-stamped, version/timestamp-only).
  • Why the new expected output is correct: the CycloneDX fixtures gain $schema, specVersion: 1.7 / the 1.7 XML namespace, acknowledgement on each license, and (for components that own detected files) evidence; all validate clean against the official CycloneDX 1.7 schema + XSD. The examples/sbom sbom.spdx files differ only in the Creator/Created version+timestamp lines, confirming SPDX output is substantively unchanged. Examples are stamped for the upcoming release (the version that first ships this output), per the generator's convention.

Before / after — component license

// before (1.3)
"licenses": [{ "expression": "MIT" }]

// after (1.7): acknowledgement + source-observed evidence
"licenses": [{ "expression": "MIT", "acknowledgement": "declared" }],
"evidence": {
  "occurrences": [
    { "location": "scan/LICENSE", "line": 1 },
    { "location": "scan/src/main.js", "line": 5 }
  ],
  "licenses": [{ "expression": "Apache-2.0" }, { "expression": "MIT" }]
}

🤖 Generated with Claude Code

Bump the CycloneDX renderer from spec 1.3 to 1.7 and populate
licenses[].acknowledgement (declared vs concluded), the distinction
Provenant already expresses in SPDX. A parser-declared license expression
is `declared`; a license concluded from source/file detection is
`concluded`, mapped from the same package fields the SPDX writer uses.

Only the CycloneDX renderer changes: JSON specVersion, $schema, and the XML
bom namespace move to 1.7, and every licenses[] entry carries an
acknowledgement. SPDX and the native ScanCode-compatible JSON are unchanged.

Component license evidence (evidence.licenses / evidence.occurrences) is
split to a documented follow-up: a clean component-level file->license
mapping is more than a moderate change in a renderer that does not otherwise
consume output.files.

- Switch the external validator to CycloneDX SchemaVersion.V1_7 (the pinned
  cyclonedx-python-lib already exposes it) and CYCLONEDX_SPEC_VERSION to 1.7.
- Regenerate CycloneDX goldens and the four examples/sbom; all validate
  clean against the official 1.7 JSON schema + XSD, and SPDX still validates.
- Document the bump + acknowledgement as an amendment to ADR 0012.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Maxim Stykow <maxim.stykow@gmail.com>
@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Greptile Summary

Updates CycloneDX output to version 1.7.

  • Adds declared/concluded license acknowledgement metadata and component-level license evidence.
  • Updates JSON schema identifiers, XML namespaces, validation tooling, tests, fixtures, examples, and ADR documentation.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failures remain.

Important Files Changed

Filename Overview
src/output/cyclonedx.rs Upgrades CycloneDX serialization to 1.7 and adds license acknowledgement and component evidence generation.
scripts/validate_output_format_fixtures.py Switches fixture validation to CycloneDX 1.7 and includes the new evidence fixtures.
tests/output_format_golden.rs Extends golden coverage for the revised CycloneDX output and license evidence.
docs/adr/0012-sbom-resolved-dependency-components.md Documents the CycloneDX license acknowledgement and evidence behavior.

Reviews (2): Last reviewed commit: "feat(cyclonedx): add component license e..." | Re-trigger Greptile

Populate CycloneDX component.evidence from the file-content license
detections of the files each component owns (file->package ownership via
file.for_packages): the distinct observed SPDX expressions as
evidence.licenses and the file+line of each detection as
evidence.occurrences. Only detected packages own scanned files, so promoted
resolved dependencies carry no evidence.

This completes the second license feature of the CycloneDX 1.7 work
alongside licenses[].acknowledgement, rather than deferring it. SPDX and the
native ScanCode-compatible JSON remain unchanged.

- Add a dedicated cyclonedx-evidence golden (JSON + XML) and wire it into the
  external 1.7 schema/XSD validator; add unit coverage for the file->package
  evidence mapping.
- Regenerate the four examples/sbom (now carrying evidence) stamped for the
  release that first ships this output; all validate clean against the
  official CycloneDX 1.7 schema + XSD, and SPDX still validates.
- Fold the evidence contract into the ADR 0012 amendment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Maxim Stykow <maxim.stykow@gmail.com>
@mstykow mstykow changed the title feat(cyclonedx): emit CycloneDX 1.7 with license acknowledgement feat(cyclonedx): emit CycloneDX 1.7 with license acknowledgement and evidence Jul 24, 2026
@mstykow
mstykow merged commit 8420dc1 into main Jul 24, 2026
13 checks passed
@mstykow
mstykow deleted the feat/cyclonedx-1.7 branch July 24, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SBOM: emit CycloneDX 1.7 with license acknowledgement (declared/concluded) + evidence

1 participant