You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The union grows to what the CLI actually models, in reviewer-directed
vocabulary: manifest, module (the project's own root and workspace
artifacts — first-party ownership becomes the kind, not a boolean), and
dependency nodes, with both project shapes (manifest→module→dependencies
and nested workspace manifests) as plain edge patterns. Dependency-node
validity delegates entirely to the PURL specification via packageurl-go —
scheme+type+name plus each type's own rules — with missing versions warned
as the one Bomly policy. The identity relation is now kind-scoped with the
ADR-0033 three-way origin rule (equal folds, gap fills, different
coexists), which also makes cross-kind folds impossible by construction.
Specified: the identity-form qualifier gate for published IDs, ordinal
start/scope/order, and the wire kind discriminator (authoritative when
present, deterministic legacy inference, unknown = decode error, four
frozen fixtures). Every remaining ADR-0036 identity reference in
SDK_MATURITY_PLAN.md is rescoped.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| 1.2 |`spdxkit`: absorb `internal/licenseexpr` semantics (panic guards, `Valid`/`ValidateAll`/`Identifier`/`Compose`/`Satisfies`/`Extract`); deprecated-ID canonicalization via the audited replacement map relocated from `internal/sbom/transform.go` (the list marks deprecation; the map owns replacements); classification-by-validation; deterministic `LicenseRef-*` minting + extracted-text pairing; fix `matcherkit.NormalizeLicenseSet` to classify on write | v0.5.0 |
143
-
| 1.3 | Identity (ADR-0041, superseding ADR-0036): typed`GraphNode` union (`PackageNode` requires a valid canonical PURL — type+name mandatory, missing version warned; `ManifestNode` is structural, path-identified, never matched); identity equals/key comparison over (canonical PURL, normalized origin); PURL-based readable IDs with deterministic run-local ordinals for contradicting occurrences; single insertion + finalization entry points; wire flat-node shape kept with an additive kind discriminator; no content address | v0.6.0 |
147
+
| 1.3 | Identity (ADR-0041, superseding ADR-0036): sealed`GraphNode` union — manifest / module / dependency nodes (dependency nodes require a spec-valid canonical PURL, missing version warned; modules are the project's own artifacts; manifests structural, path-identified, never matched); kind-scoped identity equals/key over (canonical PURL, normalized origin) with ADR-0033 gap-filling; PURL identity-form readable IDs with per-PURL deterministic ordinals from 1 for coexisting occurrences; single insertion + finalization entry points; wire flat-node shape plus additive `kind` discriminator with frozen explicit/legacy/conflicting/unknown fixtures; no content address | v0.6.0 |
144
148
| 1.4 | Model fields (ADR-0037): supplier/originator/description/homepage; `ExternalReference`; `PackageLicense` declared/concluded + extracted text; digest-algorithm registry; set-aware scope ↔ CycloneDX mapping with its scalar projection rule; typed `DependencyEdge.Kind` with a kind-preserving edge-copy/rename primitive for graph reconstruction sites; usage attribution (`PackageLocation` carries per-site scopes and relationship so the node-level union becomes derived; reachability becomes repeatable per-module-root evidence with the vulnerability annotation as derived summary, and evidence may carry optional `DependencyRefs` to the exact occurrence nodes where the analyzer can attribute — a conjunctive filter such as reachable ∧ runtime ∧ direct then joins evidence to locations within one module root, selecting one usage); a derived package → nodes reverse-index helper (the stored truth stays `Dependency.PackageRef`; the registry remains position-free); per-`GraphEntry` document assertions; per-field-class merge helpers; boundary validation codecs + fuzz targets for every new parser | v0.7.0 |
145
149
| 1.5 | Metadata policy: document reserved `bomly.` prefix; deprecate `MetadataKeyDetectionLicenses` in favor of the typed license field | v0.7.0 |
146
150
@@ -157,7 +161,7 @@ the golden refresh happens **once**:
157
161
|---|---|---|
158
162
| 2.1 | Adopt `purlkit`: delete `internal/sbom/identity.go` table, `benchmark/summary.go` table, `render/explain.go` string surgery; detectors derive purl types (guard test forbids literals); one canonical-ID rewrite in consolidation, reused by SBOM ingest paths | Findings §2 duplication items |
159
163
| 2.2 | Adopt `spdxkit`: delete `internal/licenseexpr`; the deprecated-ID replacement map relocates into the kit; export/import use kit classification | ADR-0035 stays behavioral truth, now SDK-enforced |
160
-
| 2.3 | Adopt identity: node IDs SDK-derived end to end; regenerate schemas, goldens, smoke; release-notes callout for the one-time ID change | ADR-0036|
164
+
| 2.3 | Adopt identity: the typed node union and SDK-derived IDs end to end; regenerate schemas, goldens, smoke; release-notes callout for the one-time ID change | ADR-0041|
161
165
| 2.4 |**Close #410**: `LicenseRef-*` + `hasExtractedLicensingInfos` emission, mixed-validity composition, canonical ingest coordinates via `SplitEcosystemName`; round-trip asserts `Org`+`Name`+`EcosystemName()` together | Also removes ADR-0035's recorded limitation |
162
166
| 2.5 |**Close #396** on the typed model: ingest populates typed fields through their gates; the export surface takes the prepared entries rather than the bare merged graph, so per-entry document assertions reach the codec; export projects them; merge follows the declared classes; fixed-point test (single-source export → ingest → export byte-stable for preserved fields; a merged export links source identities per ADR-0037, with merged fixtures for both formats validated through the codecs and the official format validators); hostile-document fuzz coverage | Deferred #391 items stay deferred per ADR-0037 |
163
167
| 2.6 | Export full scope sets (fixes survey defect 2) and adopt json/v2 strict ingest with documented rejection behavior, and pin the v1 plugin wire's lenient decode with SDK wire fixtures so the migration cannot tighten it by accident | ADR-0039 |
@@ -201,8 +205,8 @@ the golden refresh happens **once**:
201
205
`packageurl-go`/`go-spdx` imports outside the kits, zero PURL string
202
206
concatenation outside `purlkit` — each enforced by a guard test, not a
203
207
review habit.
204
-
4. One identity authority: every node ID and content address in the pipeline
205
-
is produced by an SDK entry point, and `left-pad@1.0.0` from two
208
+
4. One identity authority: every node ID in the pipeline is produced by an
209
+
SDK entry point on the typed node union, and `left-pad@1.0.0` from two
206
210
ecosystems are two nodes in one merged graph, proven by test.
207
211
5. Both modules on Go 1.27; untrusted SBOM ingest rejects documents with
208
212
duplicate object names or invalid UTF-8, each with an actionable error.
0 commit comments