SBOM: make group the parent's name, as CycloneDX defines the field - #193
Merged
villelaitila merged 3 commits intoAug 28, 2026
Merged
Conversation
group carried the parent's full path so that two identically named groups under different roots stayed apart. That guarded a collision no measured estate has, at two costs every estate pays. CycloneDX defines group as "a shortened, single name of the company or project that produced the component" and asks that special characters be avoided. `/Estate/AccessManagement` is neither, and a consumer rendering group as a package coordinate shows a path. The heavier cost is stability. The first path segment is the estate root, the least stable part of the path, and group is an identity field for consumers such as Dependency-Track. Renaming an estate therefore re-identified every component beneath it at once -- observed in a live estate across 689 documents when its root was renamed. Against that, the disambiguation was not observed at all: across ten real estates every full-path group mapped one-to-one onto its bare name. Nor did it hold up in our own tests. The case documented as "the case the feature exists for", test_inlined_mirror_is_told_apart_from_its_host_by_its_ published_location, passes unchanged with bare names, because what separates its two 'shared' components is the parent names GroupA and GroupB, not the paths. The collision is now accepted knowingly and covered by a test that states it: two same-named groups under different roots share a group value, and softagram:elementPath and the document serial still tell them apart. The full path is not lost -- elementPath publishes it verbatim, and consumers who parsed it out of group should read it there. docs/data-formats.md carried both problems as caveats rather than fixes; those are replaced by a description of the trade actually made. The 2026-08-11 design spec is marked partly superseded rather than rewritten.
Softagram Impact Report for pull/193 (head commit: 098141c)TL;DR Arch. Impact: -3 | Changed code files: 2 | Directly impacted code files: 4⭐ Change Overview
⭐ Details of Dependency Changes (diagram)
🤖 AGENTS - machine-readable impact data (2 files changed, 4 impacted, +11/-0 deps)Change overviewHead Added dependencies (11)
Removed dependencies (0)None. Impacted files (4)Unchanged files that directly depend on files changed in this PR - check them for behavioral impact. Grouped by changed file; dependent paths starting with ./ are relative to the changed file's directory:
Complete data
[] 📄 Full report
Impact Report explained. Give feedback on this report to support@softagram.com |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Answers §7 of
sbom-export-feedback.txt, which round 3 kept as-is and flaggedas contested and worth a second opinion. On re-examination the reporter is
right, and the case for changing is stronger than the one they made.
What they reported
Three claims, tested rather than assumed
1. The disambiguation is not observed anywhere. Round 3 measured three
estates (73→73, 78→78, 11→11). Seven more were measured for this change —
CrossTranslate, google_workspace_mcp, aikeittiostudio ×2, google-search-console-mcp,
df-softagram — all single-root, zero collisions. Ten estates, no instance of
the case the path guards against.
2. Our own test does not support the behaviour. The docstring of
test_inlined_mirror_is_told_apart_from_its_host_by_its_published_locationcallsit "the case the feature exists for". Switching
groupto bare names andupdating only that test's expected strings, it passes: the two
sharedcomponents are separated by the parent names
GroupA/GroupB, not by the paths.3. The change is cheap. Full suite with the source change: 8 failures, every
one a string-representation assertion (
assert 'GroupA' == '/OrgName/GroupA').No behavioural break.
The argument the reporter did not make, which is the strongest one
CycloneDX defines
groupas "a shortened, single name of the company or projectthat produced the component" and says "whitespace and special characters should
be avoided". Examples:
apache,org.apache.commons,apache.org. Aleading-slash path is not that.
And
groupis an identity field. Putting the estate root — the least stablesegment of the path — inside it means an organisational rename re-identifies
every component beneath it at once. That is not hypothetical: it fired across 689
documents in a live estate. The absence of benefit is what they measured; this is
the active harm.
Notably
docs/data-formats.mdalready conceded both points as caveats — "thefirst path segment is the estate root and is not stable", "
groupholds a path,not a package namespace" — and kept the behaviour anyway. A caveat documenting a
known defect is a weaker position than removing the defect for eight string edits.
The cost, accepted knowingly
Two same-named groups under different roots now share a
groupvalue. That iscovered by a test which says so —
test_groups_sharing_a_name_under_different_roots_stay_distinguishable— andshows identity does not rest on it:
softagram:elementPathand the documentserial still separate them.
groupalso does not feed the purl (verified: 0 of2633 components on a real model), so purl-based identity is untouched.
Tests
Five new tests state why, not just what:
test_group_is_a_name_not_a_path/test_component_group_is_a_name_not_a_path— spec conformancetest_group_is_unchanged_by_an_estate_root_rename— the harm, failing before this changetest_the_estate_root_is_still_recoverable_after_the_change— nothing is losttest_groups_sharing_a_name_under_different_roots_stay_distinguishable— the accepted collision559 passed, 1 skipped. Verified on a real 77-document model: groups are now
softagram-engine/softagram-live/softagram-web-frontend, zero valuescontaining
/or whitespace,elementPathunchanged at/Softagram/softagram-engine/.github.Downstream
This is a breaking output change for anyone parsing the path out of
group; theyshould read
softagram:elementPath, which is unchanged. softagram-live#3993 isalready shipping a CycloneDX format change (specVersion 1.7 → 1.6), so landing
this in the same release costs consumers one migration instead of two.
Needs a release and a pin bump in softagram-live#3993 before it reaches anyone.
Migration note — one-time component re-keying
This change re-keys every internal component for consumers that identify
components by
group+name+version— Dependency-Track does exactlythis for components without a purl. On the first upload after the upgrade,
groupchanges from the full parent path (/Estate/GroupA) to the bareparent name (
GroupA): vulnerability-audit history detaches from the oldidentities and components may appear duplicated until the old entries are
cleaned up. This is a one-time cost, taken deliberately in the same customer
upgrade as the 1.16.0 SBOM fixes so integrations migrate once, not twice.
Consumers that parsed
groupfor the element path must read thesoftagram:elementPathproperty instead — it still carries the full pathverbatim and remains the identity-bearing field. Two same-named groups under
different roots now share a
groupvalue by design;softagram:elementPathtells them apart. Consumers indexing a multi-SBOM response by
groupalonemust switch to that property for the same reason.