Skip to content

feat(sbom): add the sbom-pipeline contract - #1900

Merged
potiuk merged 3 commits into
apache:mainfrom
ppkarwasz:sbom-pipeline-contract
Nov 14, 2026
Merged

potiuk merged 3 commits into
apache:mainfrom
ppkarwasz:sbom-pipeline-contract

Conversation

@ppkarwasz

Copy link
Copy Markdown
Member

Summary

  • Adds tools/sbom-pipeline/, the contract:sbom-pipeline interface for integrating SBOM generation into a project's build, once, rather than as a per-release step.
  • The value of an SBOM is ecosystem collaboration and independence, so the contract fixes what every SBOM says whatever ecosystem and generator produced it: one CycloneDX 1.7 JSON SBOM per distributable artifact; bundled content (above all content from another ecosystem, such as a JavaScript UI inside a WAR) described in the artifact's own SBOM, nested as an assembly, with everything the environment must provide listed once at the top level with isExternal: true; reproducible SBOMs, published next to their artifact through the ecosystem's own channel.
  • The source release gets an SBOM too: every file whose license or copyright attribution differs from the project's own, produced from the release's LICENSE and NOTICE files.
  • The contract takes no position on which SBOM generator a project uses. The planned Maven, Gradle, JS, Python, Go and Rust adapters describe what any generator in their ecosystem has to produce; the generators they name are existing examples only. Adapters and the consuming skills (sbom-pipeline-integrate, sbom-pipeline-verify, in a new sbom family) follow in separate PRs once the contract settles.

This PR is meant to start the discussion of the contract itself.

Type of change

  • Tool / bridge contract (tools/<system>/*.md)
  • CI / dev loop (prek, workflows, validators): registers contract:sbom-pipeline in skill-and-tool-validator, vendor-neutrality-score and the generated labeler config
  • Documentation (docs/, README.md, CONTRIBUTING.md): docs/labels-and-capabilities.md, regenerated docs/vendor-neutrality.md

Test plan

  • prek run --all-files --skip workspace-pytest passes, except two hooks that cannot run in the isolated agent and touch nothing in this PR:
    skill-token-count (tokenizer cache not prepared) and skill-script-tests (isolated-setup-doctor tests need Unix sockets).
    Every hook, including lychee, markdownlint, skill-and-tool-validate and pytest (workspace), passed on the commit itself.
  • Field names checked against the CycloneDX 1.7 JSON schema (bom-1.7.schema.json): nested components, isExternal, versionRange, metadata.lifecycles phases, supplier, the serialNumber pattern.
  • No spec-loop update: the PR adds a contract document only, with no adapter or skill; the adapters spec is updated with the first adapter.

RFC-AI-0004 compliance

  • Vendor neutrality: the contract is generator-agnostic and classed agnostic in vendor-neutrality-score (vendor-neutral by construction): ecosystems are not interchangeable backends, and within each ecosystem the generator is the project's choice.

Linked issues

None.

Notes for reviewers (optional)

  • Serial number. The contract derives serialNumber from the subject's purl (UUID v5) for reproducibility, departing from the specification's recommendation that every SBOM have a unique serial number; a corrected SBOM keeps the serial number and increments version.
  • Open questions are listed at the end of the README: the purl type that identifies a source release, the configuration key naming the supplier, and whether generator versions are recorded in a registry.json.
  • The contract:sbom-pipeline label does not exist on the repository yet; the labeler rule expects it.

Was generative AI tooling used to co-author this PR?
  • Yes: Claude Code (Opus 5.5)

Generated-by: Claude Code (Opus 5.5) following the guidelines

🤖 Generated with Claude Code

@github-actions github-actions Bot added family:tools tools/* family:docs Docs, MISSION.md, READMEs family:ci .github workflows, prek, validators substrate:analytics Tool substrate: read-only metrics / dashboards / renderers substrate:framework-dev Tool substrate: build / validate / eval the framework itself labels Oct 29, 2026

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A clear contract that fixes exactly the points where generators disagree; a few questions on artifact identity, the source SBOM inputs and how embed treats requirements the container already satisfies, before it settles.

Smaller observations

  • See inline comments on tools/vendor-neutrality-score/src/vendor_neutrality_score/__init__.py:125, tools/sbom-pipeline/README.md:28, tools/sbom-pipeline/README.md:194, tools/sbom-pipeline/README.md:244, tools/sbom-pipeline/README.md:264.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The findings
below are observations, not blockers; an Apache Magpie
maintainer — a real person — will take the next look at the
PR. If you think a finding is mis-applied, please reply on
the PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
Contributing guide.

Comment thread tools/sbom-pipeline/README.md Resolved
Comment thread tools/sbom-pipeline/README.md Resolved
Comment thread tools/sbom-pipeline/README.md Resolved
Comment thread tools/sbom-pipeline/README.md Resolved

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as changes requested so the queue shows it is waiting on the branch: the five threads from the 2026-10-29 review are still open, and four of them need a change or a decision in the contract before it can merge.

  • Neutrality class (vendor_neutrality_score/__init__.py:125): with every adapter still planned, agnostic turns the contract green and lifts the score before anything ships. vendor-backed, like contract:hook-manager, matches its shape.
  • Serial number (README.md:194): two artifacts can share a purl (platform wheels, classified Maven JARs), so their SBOMs collide. Either require the distinguishing qualifiers in the subject purl, or derive the UUID from something that includes them.
  • Source SBOM inputs (README.md:244): rule 7's per-file components cannot always come from LICENSE and NOTICE alone. Say the inventory comes from the tree with those two files as the cross-check, or require LICENSE to list paths.
  • embed (README.md:264): resolve a part's external requirements against the container's embedded components before hoisting them, and let C8 allow that edge.
  • The duplicate SPDX header (README.md:28) is a one-line removal.

A reply on each thread, or a push that addresses it, and I will take another look.

The branch currently conflicts with main and needs a rebase before this can merge.


This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. After you've
addressed the points above and pushed an update, an Apache Magpie
maintainer — a real person — will take the next look
at the PR. The findings cite the project's review criteria;
if you think one of them is mis-applied, please reply on the
PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
Contributing guide.

Define the contract for integrating SBOM generation into a project's
build, independently of the build ecosystem: one CycloneDX 1.7 JSON
SBOM per distributable artifact, with the artifact, its components and
their licenses described the same way whatever generator produced them.

Content bundled into an artifact, above all content from another
ecosystem (a JavaScript UI inside a WAR), is described in the
artifact's own SBOM, so a consumer never has to resolve an SBOM in an
ecosystem it does not use: what a bundled component embeds is nested
under it as an assembly, while everything the environment must provide
is listed once, at the top level, with isExternal set. SBOMs are
reproducible, and published next to their artifact through the
ecosystem's own channel.

The source release gets an SBOM too, listing every file whose license
or copyright attribution differs from the project's own: the
machine-readable counterpart of the release's LICENSE and NOTICE
files, and produced from them.

The contract takes no position on which SBOM generator a project uses:
the planned Maven, Gradle, JS, Python, Go and Rust adapters describe
what any generator in their ecosystem has to produce, and name existing
generators only as examples. The adapters and the consuming skills
follow separately.

Generated-by: Claude Code (Opus 5.5)
@potiuk
potiuk force-pushed the sbom-pipeline-contract branch from 7ff2ee0 to c6b6719 Compare November 4, 2026 23:39
@potiuk

potiuk commented Nov 4, 2026

Copy link
Copy Markdown
Member

I rebased this onto main and force-pushed, so please pull before pushing again. The only conflict was in docs/labels-and-capabilities.md, where I kept the updated hook-manager row and your sbom-pipeline row. No other changes, and my review comments still stand.

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A gentle nudge to keep the discussion going — the five design threads (neutrality class, the duplicate SPDX header, serial numbers from the purl, source-SBOM inputs, and embed / C8 hoisting) are still open, and a second-read pass by other models raised two more points for the contract, inline below; happy for this to stay a discussion draft while those settle.

GitHub has not yet computed whether this branch merges cleanly with its base.

Smaller observations

  • See inline comments on tools/sbom-pipeline/README.md:124, tools/sbom-pipeline/README.md:355.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The findings
below are observations, not blockers; an Apache Magpie
maintainer — a real person — will take the next look at the
PR. If you think a finding is mis-applied, please reply on
the PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
Contributing guide.

Comment thread tools/sbom-pipeline/README.md Resolved
Comment thread tools/sbom-pipeline/README.md Resolved

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The head is unchanged since my last look, so the six design threads on the contract (neutrality class, purl-derived serial, LICENSE/NOTICE inventory, embed/C8 hoisting, bom-ref determinism, source-release purl) still stand, and my earlier change request with them. This pass adds two smaller spec gaps (array ordering beyond bom-ref, merging conflicting external version ranges) and two wording nits. I am withdrawing my duplicate-SPDX-header thread: 53 tool READMEs carry the same doubled header (doctoc stamps one above the TOC), so it is house style rather than a defect here.

Smaller observations

  • See inline comments on tools/sbom-pipeline/README.md:198, tools/sbom-pipeline/README.md:264, tools/sbom-pipeline/README.md:196, tools/sbom-pipeline/README.md:211.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The findings
below are observations, not blockers; an Apache Magpie
maintainer — a real person — will take the next look at the
PR. If you think a finding is mis-applied, please reply on
the PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
Contributing guide.

Comment thread tools/sbom-pipeline/README.md Resolved
Comment thread tools/sbom-pipeline/README.md Resolved
Comment thread tools/sbom-pipeline/README.md Resolved
Comment thread tools/sbom-pipeline/README.md Resolved

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The head has not moved since my last review (still c6b6719), so the ten open threads from that pass still apply; this pass adds one consistency gap between rule 3 and conformance check C6, inline below.

Smaller observations

  • See inline comments on tools/sbom-pipeline/README.md:135.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The findings
below are observations, not blockers; an Apache Magpie
maintainer — a real person — will take the next look at the
PR. If you think a finding is mis-applied, please reply on
the PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
Contributing guide.

Comment thread tools/sbom-pipeline/README.md Resolved
- Rule 2: the subject purl carries the qualifiers that tell a release's
  artifacts apart, so no two share a serial number.
- Rule 3: bom-refs are derived deterministically; normalize removes
  scope: excluded components, so C6 holds.
- Rule 4: a requirement the artifact embeds is met inside it; distinct
  external requirements keep their own top-level entries.
- Rule 5: a build-produced SBOM has version 1; every array has a canonical
  sort key, applied by normalize and checked by C7.
- Rule 6: next to or inside the artifact, as its channel dictates.
- Rule 7: the inventory comes from the source tree, cross-checked against
  LICENSE and NOTICE; provisional until the source purl type is settled.
- C8 allows an edge to a top-level embedded component; new C11.
- vendor-neutrality: VENDOR_BACKED until adapters ship (regenerated).
- New spec tools/spec-loop/specs/sbom-pipeline.md, indexed.

Generated-by: Claude Opus 5
@github-actions github-actions Bot added the family:dev Repo dev: .asf.yaml, spec-loop specs, Node manifests, .claude/settings.json label Nov 14, 2026
@potiuk potiuk added the contract:sbom-pipeline Tool capability: SBOM generation in the build (one CycloneDX SBOM per artifact) label Nov 14, 2026

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the patience on this one. I merged main into the branch and pushed one fixup commit, 963a3ca, that settles all eleven threads in tools/sbom-pipeline/README.md:

  • Rule 2: the subject purl carries the qualifiers that tell a release's artifacts apart (classifier/type, a wheel's file_name), so no two artifacts share a serial number.
  • Rule 3: bom-refs are derived from the component (its purl, else name@version, prefixed by the parent when nested); normalize removes scope: excluded components, so C6 holds.
  • Rule 4 / embed: a requirement the artifact itself embeds is met inside it rather than hoisted as external; distinct external requirements keep their own top-level entries instead of being merged.
  • Rule 5: a build-produced SBOM has version 1; every array has a canonical sort key, applied by normalize and checked by C7.
  • Rule 6: next to or inside the artifact, as its channel dictates (PEP 770 included).
  • Rule 7 / generate-source: the inventory comes from the source tree, cross-checked against LICENSE and NOTICE; the rule is marked provisional until the source-release purl type is settled.
  • Checks: C8 allows an edge to a top-level embedded component, and a new C11 checks bom-ref derivation and the absence of scope: excluded.
  • Vendor neutrality: the contract is VENDOR_BACKED until two adapters ship, like contract:hook-manager (regenerated: 16/19).
  • Spec: new tools/spec-loop/specs/sbom-pipeline.md (proposed), indexed; and the contract:sbom-pipeline label now exists and is applied.

If any of those choices goes against what you intended, a follow-up PR is welcome.


This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The maintainer
approving this PR has read the findings and signed off. If
something feels off, please reply on the PR and a maintainer
will follow up.

More on how Apache Magpie handles maintainer review:
Contributing guide.

@potiuk
potiuk merged commit a7d543e into apache:main Nov 14, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contract:sbom-pipeline Tool capability: SBOM generation in the build (one CycloneDX SBOM per artifact) family:ci .github workflows, prek, validators family:dev Repo dev: .asf.yaml, spec-loop specs, Node manifests, .claude/settings.json family:docs Docs, MISSION.md, READMEs family:tools tools/* substrate:analytics Tool substrate: read-only metrics / dashboards / renderers substrate:framework-dev Tool substrate: build / validate / eval the framework itself

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants