Skip to content

feat: dependency hygiene engine - stale floors, phantom dependencies, and maintenance risk #733

Description

@sonukapoor

Three new audits that extend CVE Lite CLI from a vulnerability scanner into a full dependency health platform for JavaScript and TypeScript projects.

The problem

Vulnerability scanning catches CVEs. Override hygiene (OA001-OA008) catches broken security pins. But two more classes of dependency risk sit in the gaps:

  • A package that is unmaintained and drags a transitive dep below its latest safe version - invisible to CVE scanners because no advisory exists yet
  • A package imported in source code but not properly declared - present only via an override pin or by hoisting accident, a silent deploy-breaker under pnpm strict mode

And one gap in the existing override hygiene rules: a >= security floor that has become redundant because the ecosystem has moved on, but nobody dares remove it because there is no record of why it was added.

The three audits

Audit Rule What it catches
Stale override floors OA009 >= floors where the un-overridden resolution already satisfies the constraint
Phantom dependencies PD001/PD002 Packages imported in source but not declared - only present via an override pin (PD001) or transitive hoisting (PD002)
Maintenance risk DM001 Unmaintained packages that constrain transitive deps below their latest safe version

Why they belong together

They are three stages in the lifecycle of one bad dependency. The worked example is gray-matter:

  1. gray-matter is added - DM001 would flag it as unmaintained (last release 2018)
  2. It pins js-yaml ^3.x - DM001 drag term; a latent version constraint
  3. A js-yaml CVE appears - team adds js-yaml: ">=4.2.0" override floor
  4. js-yaml is imported in source - resolves only via that override pin = PD001 phantom
  5. Ecosystem moves past the CVE - the floor is now redundant = OA009 stale floor

One replace action (swap gray-matter) retires the override, the phantom, and the stale floor in a single move. That is why all three audits share one engine and one shared context (lockfile graph, import map, OSV advisories, registry packuments).

Sub-issues

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions