Skip to main content

Package Dependency Governance

Use when governing package dependency support and migration.

Purpose​

Use this skill when dependency warnings, unsupported versions, transitive chains, lockfile policy, or packaging-tool migrations are part of the acceptance criteria. The goal is not merely a quiet installer: it is an auditable supported dependency graph that preserves product behavior and artifact contracts.

Required Distinction​

Treat deprecated and unsupported as separate classifications.

  • A deprecation notice can coexist with an active support window.
  • An unsupported exact version is unacceptable even when its parent package is maintained.
  • A clean warning count is useful evidence but does not establish support by itself.
  • Registry text is evidence, not the sole authority; confirm exact-version support from maintainer policy or release metadata.

When the user accepts deprecation but rejects unsupported modules, enforce support status rather than banning every deprecated field.

Workflow​

1. Inventory exact versions and ancestry​

For every suspect package:

npm explain <name>
npm ls <name> --all --json

Parse totals programmatically. Record the exact version, direct/transitive status, parent chain, runtime/dev/optional/peer role, and whether it reaches the shipped artifact.

2. Establish authoritative support status​

Use current registry and maintainer sources. Separate:

  • supported stable;
  • deprecated but supported;
  • unsupported/end-of-life;
  • prerelease;
  • abandoned or ownership-uncertain.

Do not substitute a fork based only on recency. Check ownership, release cadence, declaration quality, dependency graph, API compatibility, and release provenance.

3. Bound the product contract before editing​

Map all imports, calls, tests, build scripts, configured output targets, native-module rebuilds, and packaging resources. Define invariants such as:

  • serialization contents and styling;
  • streaming and error propagation;
  • retained file-descriptor/security behavior;
  • memory bounds;
  • installer formats and update behavior;
  • native ABI and resource inclusion.

A migration is incomplete until these behaviors are verified, not just type-compatible.

4. Choose the least risky supported path​

Preference order:

  1. Stable upstream parent release with supported transitives.
  2. Maintained API-compatible replacement with focused compatibility proof.
  3. Decomposed maintained tooling with full target parity.
  4. Exact transitive override only as a documented, tested bridge when the parent integration is proven.

Reject warning suppression, audit fix --force, prerelease substitution presented as stable, and overrides used only to make installation quiet.

5. Verify clean installation and actual installation​

Capture command status and warning count separately. Then inspect actual installed name/version pairs. Lock metadata alone is not enough: omitted peers can remain in a lockfile, and hoisting can place a different version at the same path.

For a lock record, treat it as installed only when the package found at that path has the same name and version. Never permit an unsupported installed package merely because its lock entry is marked peer.

6. Verify shipped artifacts independently​

Inspect the final archive or bundle and assert both:

  • required modules/resources are present;
  • unsupported exact versions are absent.

For Electron, inspect app.asar, separately copied resources, native modules, and each claimed installer target. A Linux artifact does not validate Windows or macOS packaging.

7. Enforce policy in CI​

The policy should fail on:

  • unsupported direct dependency ranges;
  • unsupported exact installed versions;
  • forbidden packages returning through new ancestry;
  • removal or drift of required exact compatibility pins;
  • configuration of a target whose peer/plugin is intentionally omitted.

Peer metadata may be allowed only when the package is absent, the omission is intentional, the target is not configured, and CI proves the supported targets.

8. Preserve exact-head evidence​

After the final mutation, rerun clean installation, policy, focused tests, full tests, typecheck, lint, build, security/audit policy, artifact inspection, and native target gates. Reviews and approvals bind to that exact commit; mutation invalidates them.

Override Standard​

An override is not automatically unsafe, but it carries the burden of proof. Require:

  • exact pinning;
  • inspection of the parent's API boundary and load behavior;
  • regression tests across that boundary;
  • successful builds for every claimed target;
  • a documented reason and removal trigger;
  • a policy that prevents fallback to the unsupported version.

If native targets cannot be exercised, keep them as explicit blockers and do not call the change merge-ready.

Common Failure Modes​

  • Counting lockfile deprecated records as proof that packages are installed.
  • Counting zero warning lines as proof that all modules are supported.
  • Checking only path existence and ignoring installed version identity.
  • Moving an unsupported tool to another workspace and claiming removal.
  • Omitting all peers without proving required peers are direct dependencies.
  • Rewriting an export path from streaming to buffering without memory/error tests.
  • Passing one platform's package build and generalizing to all platforms.
  • Altering a reviewed security branch instead of using a fresh migration branch.

Verification Checklist​

  • Every suspect name/version has a mapped parent chain.
  • Support status is authoritative and current.
  • Clean install exit and warning count are captured independently.
  • Unsupported exact versions are absent from the installed graph.
  • Unsupported exact versions are absent from shipped artifacts.
  • Replacement behavior and failure semantics pass focused tests.
  • Full test, typecheck, lint, build, and audit policies pass.
  • Every supported native artifact target passes on its native platform.
  • CI prevents reintroduction and configuration drift.
  • Final reviewers inspect the exact immutable head.

See references/npm-support-status-and-lockfile-verification.md for a reusable npm verification recipe.


Supporting files: this skill's supporting files are held in the docsite at docs/15-skills/_support/engineering/package-dependency-governance/ — fetch them fresh from jknash/docsite main alongside this page. Source: jknash/hermes-shared-skills · branch hermes-jkdev001 @ 1d0d545c3970 · skills/engineering/package-dependency-governance/ · view source · Imported 2026-10-04. Supporting files (references, scripts) remain in the source repository.

Published by Muse · 2026-10-04.