How it works
PackageSafe is not an AI score. A risk score is the sum of three independent, individually inspectable signals - a deterministic rules engine, real published vulnerability data, and an LLM source review that only runs when the first layer already flagged something. Every result page shows you exactly which of these contributed points and why, so you're never just trusting a number.
Supply-chain heuristics
Deterministic. Free. Runs on every single scan.
A fixed set of rules against registry metadata and, where a repository is linked, GitHub activity. No model involved - the same input always produces the same output, and every rule is a plain function you can read the source of:
- Package age - published under 7 or 30 days ago is itself a risk signal for a brand-new dependency.
- Maintainer takeover (npm only - the only registry that exposes per-version maintainer history) - every maintainer replaced at once between two versions, a classic account-compromise pattern.
- Install scripts (npm only) - lifecycle scripts (
preinstall/install/postinstall) that run automatically the moment the package is installed. - Typosquatting - name within a short edit distance of a popular package in the same ecosystem, but not an exact match.
- Dependency count - an unusually large direct dependency count widens the attack surface.
- Repo/release activity mismatch - a recent release with no matching recent commit activity in the linked repository.
- Popularity anomaly - high download counts paired with a near-empty GitHub footprint (few stars, effectively one contributor).
A few of these are npm-specific because the signal they need genuinely doesn't exist in PyPI's or Maven Central's APIs - rather than fake a result, those checks are simply not run for those ecosystems, and the result page says so.
Known vulnerabilities
Real CVE/GHSA data from OSV.dev - a separate signal from #1.
Every scan is also checked against OSV.dev, the aggregated open-source vulnerability database, for the exact package and version being scanned. This answers a genuinely different question than layer 1: "does this package behave suspiciously" versus "does this exact version have a publicly disclosed vulnerability." A completely legitimate, well-maintained package can still carry a real CVE - that's not a contradiction, and the two are always shown as separate sections so one can't be mistaken for the other. Severity (critical/high/medium/low) is read directly from the advisory or computed from its CVSS vector when only a raw score is published.
For a full repo scan, every dependency's vulnerability check is batched into a handful of requests rather than one network round-trip per package, so checking hundreds of direct and transitive dependencies stays fast.
LLM deep-scan
Claude reading actual source code - only when layer 1 already flagged something.
The first two layers are metadata-only - fast, but they can't see what a package actually does. When the heuristics score crosses a threshold, or any single heuristic flags at danger severity, PackageSafe downloads the real package tarball, unpacks it, and selects a small high-signal subset of source files: anything referenced by an install script, the package's entry point, and any file that trips a suspicion filter (minified-looking code, unusually long lines, eval(), dynamic Function() construction, spawning child processes, decoding base64 payloads, reading process.env).
Those excerpts, plus the package's name and stated description, go to Claude with one job: does this code plausibly do what a package like this claims to do, or does it show obfuscation, unexplained network calls, or data-exfiltration patterns? The result is a bounded, structured classification, not free-form text - and it's deliberately gated behind layer 1 rather than run on every scan, since it's the slow, costly layer and most packages never need it.
If the download or the model call fails for any reason, the result says so explicitly ("deep scan did not complete") rather than silently reporting a clean result - a failed check must never look identical to a real one.
Beyond a single package
The same three-layer pipeline runs at every scope PackageSafe supports: a single package at latest or a pinned version, its full transitive dependency tree (so "this package is fine, but depends on X which has a CVE" is visible, not buried), or an entire repo's manifests scanned at once. It's the same auditable signals throughout - just applied to more packages at a time.