Note: this is an in-house item already being handled by the maintainer - not open for contribution. Filed for tracking only.
Follow-up to #1079, which fixed SBOM dependency-graph completeness for npm only. Sibling of #1107 (pnpm) and #1108 (Bun).
Do this one last. It is the largest of the three and carries most of the risk. The estimate below is the least reliable of the set.
Problem
Yarn still derives SBOM dependency edges by prefix-matching PackageRef.paths, capped at MAX_PATHS_PER_PACKAGE = 5 (src/parsers/yarn-lock.ts:8). Same consequence as #1107 and #1108: lost edges on large trees, orphaned packages when the surviving routes traverse excluded packages, and a weaker answer on the NTIA dependency-relationship element.
Why this is harder than the other two
Two incompatible lockfile formats. yarn-lock.ts detects Berry via __metadata (line 158, and again at 309 and 335). Classic v1 and Berry differ enough that edge extraction likely needs separate handling for each.
Classic keys entries by range, not by version. A v1 lockfile keys entries as name@range, so building name@version edges means resolving ranges to the concrete versions actually installed. That is real work, not plumbing, and it is the main reason this is a one-to-two day job rather than half a day.
No existing children map to reuse. Unlike pnpm (which has graph at pnpm-lock.ts:108) and Bun (childDepsByPackageName), the Yarn parser has its own bespoke path-recording logic at line 200 and does not build a reusable adjacency structure. This one is built from scratch.
Important: do not record edges during the path traversal
yarn-lock.ts:35 and :200 both cap while walking, so edges recorded there inherit the incompleteness. Separate edge-only pass, as with the others.
Scope
- Build a child-to-parents edge map keyed by
name@version, covering both classic and Berry.
- Extend
resolveDependencyEdges (src/output/sbom-dependency-edges.ts) for yarn-lock.
- Handle workspace members (linked, no version) and parents filtered out of the scanned set by anchoring to the root rather than orphaning. Never emit a reference to a package absent from the document.
- Update
website/docs/spdx.md, which currently lists Yarn among the affected ecosystems. Once this lands, that per-package-manager split can be removed entirely.
Keep MAX_PATHS_PER_PACKAGE at 5.
Verification
examples/yarn-berry for Berry and examples/twenty for classic. Both formats need checking; a fix verified on only one is not done. Confirm packages with no parent edge drop to the root project alone, and zero dangling references.
Estimate
One to two days, and less certain than the other two. I have read the parser but not traced the range-resolution path in detail, so if that turns out to need more than a lookup against already-resolved entries, this grows. Re-estimate after an hour of reading rather than committing to the number up front.
Follow-up to #1079, which fixed SBOM dependency-graph completeness for npm only. Sibling of #1107 (pnpm) and #1108 (Bun).
Do this one last. It is the largest of the three and carries most of the risk. The estimate below is the least reliable of the set.
Problem
Yarn still derives SBOM dependency edges by prefix-matching
PackageRef.paths, capped atMAX_PATHS_PER_PACKAGE = 5(src/parsers/yarn-lock.ts:8). Same consequence as #1107 and #1108: lost edges on large trees, orphaned packages when the surviving routes traverse excluded packages, and a weaker answer on the NTIA dependency-relationship element.Why this is harder than the other two
Two incompatible lockfile formats.
yarn-lock.tsdetects Berry via__metadata(line 158, and again at 309 and 335). Classic v1 and Berry differ enough that edge extraction likely needs separate handling for each.Classic keys entries by range, not by version. A v1 lockfile keys entries as
name@range, so buildingname@versionedges means resolving ranges to the concrete versions actually installed. That is real work, not plumbing, and it is the main reason this is a one-to-two day job rather than half a day.No existing children map to reuse. Unlike pnpm (which has
graphatpnpm-lock.ts:108) and Bun (childDepsByPackageName), the Yarn parser has its own bespoke path-recording logic at line 200 and does not build a reusable adjacency structure. This one is built from scratch.Important: do not record edges during the path traversal
yarn-lock.ts:35and:200both cap while walking, so edges recorded there inherit the incompleteness. Separate edge-only pass, as with the others.Scope
name@version, covering both classic and Berry.resolveDependencyEdges(src/output/sbom-dependency-edges.ts) foryarn-lock.website/docs/spdx.md, which currently lists Yarn among the affected ecosystems. Once this lands, that per-package-manager split can be removed entirely.Keep
MAX_PATHS_PER_PACKAGEat 5.Verification
examples/yarn-berryfor Berry andexamples/twentyfor classic. Both formats need checking; a fix verified on only one is not done. Confirm packages with no parent edge drop to the root project alone, and zero dangling references.Estimate
One to two days, and less certain than the other two. I have read the parser but not traced the range-resolution path in detail, so if that turns out to need more than a lookup against already-resolved entries, this grows. Re-estimate after an hour of reading rather than committing to the number up front.