Repository navigation
fix(sbom): a transformed export mints its own identity and links its source - #461
Conversation
…source applySourceAssertions adopted a single ingested document's identity -- SPDX namespace, CycloneDX serial and revision -- and its creation time, name and comment whenever exactly one document was read, whether or not the graph being exported still described that document. scan --sbom with --scope runtime or --enrich hands the exporter a transformed graph beside the original entry, so a filtered subset was published under the full document's identity: two documents with different content and one name, which is a correctness defect in the one field that exists to tell documents apart. The exporter cannot see the transformation; only the caller knows. So BuildOptions gains RestatesSource, the caller's declaration that nothing filtered, enriched, or degraded the graph between ingest and export. Only then does a conversion adopt its source's identity. The default is false, the safe side: the document mints its own identity and timestamp, keeps the default name and no comment, and links the source -- it behaves as a merge of one. The CLI derives the flag from the same predicate that decides compositions.aggregate, so a document that cannot claim to be complete cannot claim to be its source either; --analyze needs --enrich and writes nothing into the SBOM, so enrichment covers it. Visible change: a --scope or --enrich export of one SBOM now carries a fresh serial or namespace and this run's time, with an external reference of type bom (CycloneDX) or an externalDocumentRef with checksum (SPDX) naming the source. The fixed point still holds for restating exports and is pinned without pinning anything else. ADR-0042 is amended in place; ADR-0037 cross-references it. Closes #433. Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
Warning Review limit reachedNext included review available in 48 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (12)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bomly Diff SummaryCompared Overview
Dependency Changes✅ No dependency changes. Vulnerabilities✅ No vulnerability changes. License Changes✅ No license changes. Project Posture✅ No project posture changes ( Policy Findings✅ No policy differences were identified. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ac389f81a2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…wn its source Codex review on #461: the degraded argument was computed from any detector warning being present, while PipelineResult asks consumers concerned with coverage to filter on DetectorWarning.DegradesCoverage. A package-manager readiness notice therefore made an unfiltered scan declare its completeness unknown and mint a new identity for an unchanged source. coverageDegraded filters on the kind, and feeds both the aggregate claim and restatement. Co-Authored-By: Claude Fable 5.1 <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13cbb9fe0b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… whatever the caller declared Codex review on #461: a directory scan can hold one auto-detected SBOM entry beside native manifest entries; the source count skipped entries without a document, saw one source, and adopted its identity over a graph holding packages the document never named. FromGraphEntries now withdraws restatement when any entry carries a graph but no document -- decided at the model boundary, where the entries are visible, rather than by each caller. A lone document still restates. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Closes #433.
applySourceAssertionsadopted a single ingested document's identity (and creation time, name, comment) whenever exactly one document was read, even when--scopeor--enrichhad transformed the graph. A filtered subset was published under the full document's namespace or serial: two documents, one identity.The seam:
internal/sbomcannot see the transformation, only the caller can.BuildOptions.RestatesSourceis the caller's declaration that nothing filtered, enriched, or degraded the graph between ingest and export; only then does a conversion adopt its source's identity. Default false is the safe side: a transformed conversion behaves as a merge of one (own identity and timestamp, default name, no comment, source linked). Creators and tools still union.The CLI predicate (
sbomRestatesSourceinscan_cmd.go) issbomCompositionAggregate(...) == "complete" && !Enrich, so the completeness and restatement claims stay mechanically consistent.--analyzerequires--enrichand nothing underinternal/sbomreads reachability, so enrichment covers it. The registry is never nil at the CLI, so it cannot be the signal.Visible behaviour change:
bomly scan --sbom <one document> --scope runtime -f cyclonedx(or--enrich) now emits a fresh serial and this run's timestamp, plus an external reference of typebomwith a hash naming the source; SPDX gets anexternalDocumentRefwith the ingest checksum. Without--scope/--enrichthe source serial is kept as before. Verified end to end with the built binary on a self-scan export:Tests: every test asserting adoption now declares
RestatesSource: true(TestSingleSourceExportIsAFixedPointstill pins nothing else); the fuzz target gains a pass without the flag asserting the identity is never adopted and is linked whenever it clears the gate; newTestATransformedConversionMintsItsOwnIdentity,TestATransformedConversionLinksItsSource(both formats),TestRestatementFlagIsIgnoredByAMerge,TestSBOMRestatesSourceOnlyForAnUntransformedScan.Docs: ADR-0042 amended in place (dated blockquote), ADR-0037 cross-references it. A plugin-written source with no ingest checksum is neither adopted nor linked on a transformed SPDX export, which was already the merge behaviour and is now stated.
Gates:
make verifypasses; smokeTestScan/scan-sbom-spdx,TestScan/scan-sbom-cyclonedx,TestScanSBOMExportGolden,TestScanSBOMExportOriginpass with no golden change.Follow-up: bomly-dev/bomly-sdk#61 (source links are not yet read back on ingest), so a transformed export that links its source still loses that link on the next hop.
🤖 Generated with Claude Code