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
Copy file name to clipboardExpand all lines: dev-docs/ARCHITECTURE.md
+15Lines changed: 15 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -385,6 +385,21 @@ Workspace/reactor detectors (npm and pnpm lockfile, cargo, maven) emit one `Grap
385
385
386
386
**First-party packages are inventory, not enrichment targets** (`sdk.NodeIsEnrichable`). Application-typed nodes — workspace members, reactor modules, the project's own package — are absent from public advisory/registry sources, so querying OSV / deps.dev / scorecard / grype for them wastes lookups and risks coincidental name matches (a workspace member named like a real npm package would adopt its advisories). The predicate mirrors `NodeIsDiffable` and gates the two selection chokepoints (`matchers.RegistryPackagesForGraph`, the OSV matcher's graph iteration) plus external grype's result mapping. External grype's SBOM *input* is deliberately not filtered: `sbom.FromDepGraph` is shared with user-facing SBOM generation, where first-party components must remain visible — so first-party matches are dropped when grype results map back into the registry. First-party entries stay in the `packages` collection and SBOMs, just unenriched; external plugin matchers (ClearlyDefined, EOL) are expected to adopt the same predicate.
387
387
388
+
**Dependency source classification belongs to detectors.** Source is an
389
+
occurrence fact, so the detector that reads the manifest, lockfile, or build
390
+
tool output owns it. The engine and package auditor consume the canonical
391
+
`sdk.Dependency.Source` value but never infer one from an ecosystem, package
392
+
name, PURL, or repository metadata. Detectors classify only explicit evidence:
393
+
for example Cargo `registry+` and `git+` sources, Bundler `GEM`/`GIT`/`PATH`
Python lock source tables. When a format does not retain the selected origin,
396
+
the source stays unknown. This trades some source-change coverage for avoiding
397
+
false provenance claims and keeps external protocol-v1 detectors compatible.
398
+
Source and matcher eligibility are related but not identical: SwiftPM remote
399
+
source control is classified as Git, while remaining eligible because the
400
+
repository URL is the canonical SwiftURL identity used for vulnerability
401
+
matching.
402
+
388
403
### Decision: Bun text lockfiles are native; binary lockfiles degrade explicitly
389
404
390
405
`bun-detector` parses JSONC `bun.lock` versions 0 and 1 directly in Go. The parser removes comments and trailing commas with a string-aware state machine, inventories package tuples before constructing edges, models workspace roots as application nodes, and runs the shared Node relationship finalizer before per-workspace graph partitioning. Bun workspace entries therefore use the same multi-entry `sdk.GraphContainer` contract described above. The lockfile path never invokes or installs Bun, so committed text lockfiles remain deterministic and offline.
Copy file name to clipboardExpand all lines: dev-docs/MODELS.md
+9-1Lines changed: 9 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -128,6 +128,14 @@ Key helpers:
128
128
-`sdk.RelationshipForPath(path)` — preserve an explicit relationship or derive direct/transitive from a root-to-target path.
129
129
-`dep.RegistryMatchEligible()` — classify whether this occurrence may be sent to external registry enrichment.
130
130
131
+
`Dependency.Source` is occurrence evidence, not a guess based on package name
132
+
or ecosystem. A detector sets it only when the manifest, lockfile, or build
133
+
tool output proves the origin. Cargo, Bundler, the JavaScript package managers,
134
+
pub, SwiftPM, and the pip, Pipenv, Poetry, and uv Python paths currently expose
135
+
that evidence. Formats that do not retain the selected feed or source leave the
136
+
field empty. An empty source remains eligible for matching for protocol-v1
137
+
compatibility, but it cannot create a source-change finding in a diff.
138
+
131
139
An `unknown` relationship means that the package was present in the owning
132
140
manifest but its parent could not be recovered. The component root is attached
133
141
beneath the manifest/application root so it continues through matching,
@@ -137,7 +145,7 @@ for protocol-v1 plugins and is derived from graph structure by consumers.
137
145
138
146
Dependencies **do not** carry `Licenses`, `Vulnerabilities`, or `Scorecard` fields. Detection-time licenses ride along in metadata; matching-stage data lives on the registry package.
139
147
140
-
Registry matching eligibility is occurrence-based. Ordinary registry releases are eligible even when their `ResolvedURL` points at a custom registry or mirror. First-party/manifest nodes and occurrences sourced from project, workspace, link/file, Git, or arbitrary URL references are ineligible but remain in the complete graph and package registry for analysis, auditing, diff, SBOM, and output. Application type alone is not an ownership signal: an application artifact imported from an SBOM remains eligible unless it is marked first-party or has a non-registry source. An omitted source remains eligible for protocol-v1 and legacy detector compatibility. Before any built-in or external matcher runs, the engine passes it a cloned graph containing only eligible occurrences and eligible-to-eligible edges; the original graph and full registry continue to later stages unchanged.
148
+
Registry matching eligibility is occurrence-based. Ordinary registry releases are eligible even when their `ResolvedURL` points at a custom registry or mirror. First-party/manifest nodes and occurrences sourced from project, workspace, link/file, Git, or arbitrary URL references are normally ineligible but remain in the complete graph and package registry for analysis, auditing, diff, SBOM, and output. Swift source-control packages are the exception: their repository URL is the canonical SwiftURL package identity, so Git-sourced Swift packages remain eligible for vulnerability matching. Application type alone is not an ownership signal: an application artifact imported from an SBOM remains eligible unless it is marked first-party or has a non-registry source. An omitted source remains eligible for protocol-v1 and legacy detector compatibility. Before any built-in or external matcher runs, the engine passes it a cloned graph containing only eligible occurrences and eligible-to-eligible edges; the original graph and full registry continue to later stages unchanged.
Copy file name to clipboardExpand all lines: docs/auditors/package.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -84,7 +84,7 @@ still downgrades a configured failure.
84
84
## Limitations
85
85
86
86
-**Names, not behavior.** This auditor cannot tell whether a package is malicious — only whether its name is denied or resembles a protected one. Pair it with the vulnerability auditor for content risk.
87
-
-**Source-change checks currently cover JavaScript package managers.** npm, pnpm, Yarn, and Bun detectors report the source details needed by this check. Other detectors do not yet provide enough source data, so this policy cannot report their source changes.
87
+
-**Source-change checks need detector evidence.**Cargo, Bundler, npm, pnpm, Yarn, Bun, pub, SwiftPM, and the pip, Pipenv, Poetry, and uv Python paths report source details when their lockfile or tool output proves the origin. Other detectors leave the source unknown when their input cannot distinguish a registry package from another origin.
88
88
-**Only Git and URL moves are review signals.** Moves to project, workspace, or file sources remain informational, even when registry matching eligibility changes.
89
89
-**Source-change policy is diff-only.**`--fail-on source-change` is accepted by other audited commands but cannot match because they do not produce dependency detail transitions.
90
90
-**Source changes need context.** Git and URL sources can be intentional. The warning asks a reviewer to confirm the new origin and pinned reference.
0 commit comments