Skip to content
Back to skills

Dependency Audit

ASecurity

Dependency health and internal coupling audit for Node.js/TypeScript projects. 11 dimensions: supply chain CVEs, supply-chain integrity (typosquat/dependency-confusion/malicious-package/SBOM), freshness, dead dependencies, license compliance, bundle weight, circular dependencies, coupling metrics, architecture boundary violations, barrel file health, and change coupling. Tiered tooling with graceful degradation. Switches: zuvo:dependency-audit full | [path] | --supply-chain | --coupling | --d...

  • 8 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added May 28, 2026
developmentjavascripttypescriptpythonrustgojavaphpkotlinbashsql

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 21, 2026

npx -y skills add greglas75/zuvo --skill dependency-audit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dependency Audit?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dependency Audit
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/greglas75-dependency-audit/badge)](https://www.skillsdirectory.com/skills/greglas75-dependency-audit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dependency-audit
description: >
  Dependency health and internal coupling audit for Node.js/TypeScript projects.
  11 dimensions: supply chain CVEs, supply-chain integrity (typosquat/dependency-confusion/malicious-package/SBOM), freshness, dead dependencies,
  license compliance, bundle weight, circular dependencies, coupling metrics,
  architecture boundary violations, barrel file health, and change coupling.
  Tiered tooling with graceful degradation.
  Switches: zuvo:dependency-audit full | [path] | --supply-chain | --coupling | --dead | --bundle | --lock-in
category: Infra audits
codesift_tools:
  always:
    - analyze_project
    - index_status
    - index_folder
    - index_file
    - plan_turn
    - get_file_tree            # find package.json/composer.json/pyproject.toml + workspace files
    - find_dead_code           # KEY — unused exports / dead deps
    - find_unused_imports      # KEY — barrel-file health, dead deps
    - find_circular_deps       # KEY — circular module detection
    - fan_in_fan_out           # KEY — coupling metrics
    - check_boundaries         # architecture boundary violations
    - search_text              # import statements, require() patterns
    - search_patterns
    - audit_scan
    - get_file_outline
  by_stack:
    typescript: [get_type_info]
    javascript: []
    python: [python_audit, analyze_async_correctness, analyze_python_deps]
    php: [php_project_audit, php_security_scan, resolve_php_namespace]
    kotlin: [analyze_sealed_hierarchy, find_extension_functions, trace_flow_chain, trace_suspend_chain, trace_compose_tree, analyze_compose_recomposition, trace_hilt_graph, trace_room_schema, analyze_kmp_declarations, extract_kotlin_serialization_contract]
    nestjs: [nest_audit]
    nextjs: [framework_audit, nextjs_route_map]
    astro: [astro_audit, astro_actions_audit, astro_hydration_audit]
    hono: [analyze_hono_app, audit_hono_security]
    express: []
    fastify: []
    react: [react_quickstart, analyze_hooks, analyze_renders, audit_compiler_readiness]
    django: [analyze_django_settings, effective_django_view_security, taint_trace]
    fastapi: [trace_fastapi_depends, get_pydantic_models]
    flask: [find_framework_wiring]
    jest: []
    yii: [resolve_php_service]
    prisma: [analyze_prisma_schema]
    drizzle: []
    sql: [sql_audit]
    postgres: [migration_lint]
---

# zuvo:dependency-audit

Audit external dependency health and internal module coupling. Scores 11 dimensions with tiered tooling -- gracefully degrades when specialized tools
are unavailable.

**Scope:** Node.js / TypeScript projects (npm, pnpm, yarn, bun).
**When to use:** Before releases, after adding many dependencies, periodic
health check, after monorepo restructuring, before lock-in reviews.
**When NOT to use:** Code quality (`zuvo:review`), DB-specific
(`zuvo:db-audit`), full-stack performance (`zuvo:performance-audit`), OWASP
(`/security-audit`).


> **Scanner exit codes:** follow `../../shared/includes/scanner-invocation.md` — `npm/pip-audit/osv-scanner` exit non-zero WHEN they find vulns (success); never treat non-zero as failure.

## Known Limitations

Dispatch follows `../../shared/includes/execution-policy.md` through env-compat. Reuse existing
authorization within that policy; session restrictions take precedence. Run each required gate
and report its actual independence or an unmet requirement.

- Node.js/TypeScript only. Python, Go, Rust, and Java are not supported.
- `npm query` selectors are npm-specific. pnpm/yarn/bun fall back to lockfile
  analysis.
- D5 (bundle impact) uses Bundlephobia API for triage -- not precise without
  actual build statistics.
- D7 (instability metrics) requires dependency-cruiser for Ca/Ce/I. Without it,
  only fan-in/fan-out via grep.
- D10 (change coupling) requires 3+ months of git history.
- Monorepo workspace scoping is partial -- tools operate on workspace root
  unless filtered.

## Mandatory File Loading

Read every file below before starting. Print the checklist.

```
CORE FILES LOADED:
  1. ../../shared/includes/codesift-setup.md   -- [READ | MISSING -> STOP]
  2. ../../shared/includes/env-compat.md        -- [READ | MISSING -> STOP]
  3. ../../rules/cq-patterns.md                 -- [READ | MISSING -> STOP]
  4. ../../shared/includes/run-logger.md        -- [READ | MISSING -> STOP]
  5. ../../shared/includes/retrospective.md        -- [READ | MISSING -> STOP]
```

If any file is MISSING, STOP. Do not proceed from memory.

---

## Argument Parsing

| Token | Behavior |
|-------|----------|
| _(empty)_ or `full` | All 11 dimensions, scope = project root |
| `[path]` | Scope to a package or directory (see scope rules below) |
| `--supply-chain` | D1 (CVE) + D11 (integrity) only |
| `--coupling` | D6, D7, D8, D9 only |
| `--dead` | D3 only |
| `--bundle` | D5 only |
| `--lock-in` | D7 vendor lock-in focus |
| `--no-api` | Skip Bundlephobia and OpenSSF API calls |

**Path scope rules:**

| Path points to | Manifest found? | D1-D5, D11 (external) | D6-D10 (internal) |
|----------------|-----------------|-------------------|---------------------|
| Package root (own `package.json`) | Yes | Score for this package | Score within path |
| Subdirectory within a package | Inherited from parent | Mark INHERITED | Score within path |
| No `package.json` above | No | Mark SKIPPED | Score within path |

---

## Safety Gate

This audit is **read-only**. The only write target is `zuvo/audits/`. Do not
install, uninstall, or modify any dependency. Do not run `npm audit fix` or
equivalent automatically.

---

## MANDATORY TOOL CALLS — Dependency Audit Validity Gate

**This audit is INVALID if any tool below is skipped when its trigger condition holds.** "DEFERRED", "N/A", "no fresh deps" are NOT valid reasons.

| Tool | Trigger | Reason | Skip allowed? |
|------|---------|--------|---------------|
| `find_dead_code` | Always | KEY — unused exports = dead code = candidate dead deps | **NO** |
| `find_unused_imports` | Always | KEY — barrel-file health, dead transitive deps | **NO** |
| `find_circular_deps` | Always | KEY — circular module detection (D6) | **NO** |
| `fan_in_fan_out` | Always | KEY — coupling metrics (D7) | **NO** |
| `check_boundaries` | Always | D8 architecture boundary violations | **NO** |
| `audit_scan` | Always | Compound CQ + dep pattern check | **NO** |
| `analyze_python_deps` | Python detected | D1 supply-chain CVE check via PyPI | **NO** when Python |
| Stack-specific tools | Framework/language detected | Stack-specific dep gates | **NO** when matches |

### Forbidden escape hatches: `find_dead_code: skipped`, `find_circular_deps: N/A`, `codesift: unavailable` (when deferred), `retrospective: skipped` — all REJECTED.

### Required POSTAMBLE: report on disk → retro appended → `~/.zuvo/append-runlog` exit 0. Every D-dim finding needs `path/to/file.ext:LINE` (verify-audit gate).

### Mandatory acknowledgment (REQUIRED — print verbatim before Phase 0)

```
Mandatory-tools-acknowledgment: I will run find_dead_code + find_unused_imports + find_circular_deps + fan_in_fan_out + check_boundaries + audit_scan + analyze_python_deps (when Python) + stack-specific tools for this dependency audit. Every D-dim finding will cite a `path/to/file.ext:LINE` resolving in the current tree.
```

### CodeSift preload

**Use the deterministic preload helper FIRST.** Run `~/.zuvo/compute-preload dependency-audit "$PWD"` before any ToolSearch. Copy `[CodeSift matching trace]` verbatim, issue printed `ToolSearch(query="select:...")`. Math gate enforced.

---

## Phase 0: Preflight

### 0.1 Manifest and Lockfile

```
Step 1: Find package.json at TARGET_ROOT, walk up to project root if needed.
        If not found -> STOP: "No package.json. This skill requires Node.js."

Step 2: Find lockfile (package-lock.json, pnpm-lock.yaml, yarn.lock, bun.lockb).

Step 3: Validate package manager works: <pm> ls --json 2>&1

Decision matrix:
  | Manifest | Lockfile | node_modules | Action |
  |----------|----------|-------------|--------|
  | Yes | Yes | Yes | Full audit D1-D11 |
  | Yes | Yes | No | STOP: "Run <pm> install first." |
  | Yes | No | Yes | D1 capped at 6/15. D1.5 = CRITICAL. |
  | Yes | No | No | STOP: "No lockfile and no node_modules." |
  | No | -- | -- | STOP: "No package.json found." |
```

### 0.2 Package Manager Detection

| Signal | PM |
|--------|----|
| `package-lock.json` | npm |
| `pnpm-lock.yaml` | pnpm |
| `yarn.lock` | Yarn (detect version: `yarn --version`, 1.x = Classic, 2+ = Berry) |
| `bun.lockb` or `bun.lock` | Bun |

### 0.3 Framework Detection (for D8 layer rules)

| Signal | Framework | Layer Pattern |
|--------|-----------|---------------|
| `next.config.*` | Next.js App Router | app/ (server) -> lib/ -> components/ (client) |
| `nest-cli.json` or `@nestjs/core` | NestJS | controllers -> services -> repositories |
| `vite.config.*` + no SSR | Vite SPA | pages -> features -> shared |
| `express` in deps | Express | routes -> middleware -> services |

### 0.4 Tool Availability

Run in parallel:

```bash
# Tier 1 -- PM built-in
<pm> audit --json 2>/dev/null
<pm> ls --json 2>/dev/null
<pm> outdated --json 2>/dev/null

# Tier 2 -- npx (no install)
npx knip --reporter json 2>/dev/null
npx license-checker --json --production 2>/dev/null

# Tier 3 -- check availability
npx depcruise --version 2>/dev/null
npx madge --version 2>/dev/null
```

Record which tools are available. Missing tools degrade specific dimensions
but do not block the audit.

---

## Phase 1: Data Collection

### 1.1 External Dependency Data

**PM audit output:** Vulnerability report with severity levels.

**PM outdated output:** Current vs latest version for each dependency.

**Lockfile analysis:**
- Install scripts (`postinstall`, `preinstall`)
- Git dependencies (`git+`, `github:`)
- Lockfile integrity (uncommitted changes, drift from manifest)

**Manifest analysis:** Read `package.json` -- count prod/dev deps, version
specifier types (`^`, `~`, exact), overrides, resolutions.

### 1.2 Internal Dependency Graph

**With dependency-cruiser:**
```bash
npx --yes depcruise --no-config --output-type json --metrics TARGET_ROOT
```

**With madge (fallback):**
```bash
npx --yes madge --json TARGET_ROOT
npx --yes madge --circular --json --ts-config tsconfig.json TARGET_ROOT
npx --yes madge --orphans --json TARGET_ROOT
```

**Grep fallback (always available):**
Search for import/export statements to build an approximate dependency graph.

---

## Phase 2: Dimension Analysis (D1-D11)

### Agent Dispatch

Refer to `env-compat.md` for the dispatch pattern.

**When parallel dispatch is available:**

| Agent | Dimensions | Input |
|-------|-----------|-------|
| Supply Chain Scanner | D1, D4, D11 | PM audit, lockfile, license data, OSV/Socket + typosquat/confusion/postinstall heuristics |
| Coupling Analyzer | D6, D7, D8, D9 | dep-cruiser/madge output |
| Freshness Checker | D2, D3, D5 | PM outdated, knip output |

**D10 (Change Coupling)** runs in the lead agent (requires git log).

**Without parallel dispatch:** Execute all dimensions sequentially.

### D1: Supply Chain and Vulnerabilities -- Weight 15, Max 15, Critical Gate

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Known CVEs | Zero critical/high CVEs in production deps | Unpatched critical CVE | CRITICAL |
| Install scripts | Only trusted packages run postinstall | Unknown package with postinstall | HIGH |
| Signature verification | Lockfile signatures verified | No signature verification | MEDIUM |
| Git dependencies | Zero git deps in production | `git+` URLs bypass registry auditing | HIGH |
| Lockfile integrity | Committed, matches manifest, reproducible | Missing or diverged lockfile | HIGH |

Critical gate: known exploit-grade CVE in production → triggers FAIL. The gate fires on that FINDING; a D1 score of 0 also fires it but is not required.

### D2: Freshness and Maintenance Health -- Weight 10, Max 10

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Major version lag | Within 1 major version of latest | 3+ major versions behind | HIGH |
| Maintenance status | Active maintainer, recent releases | Abandoned (no release > 2 years) | HIGH |
| Deprecated packages | Zero deprecated deps | Using packages with `npm deprecate` notice | MEDIUM |

### D3: Dead Dependencies -- Weight 10, Max 10

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Unused production deps | Zero unused in `dependencies` | Package in manifest, never imported | HIGH |
| Phantom dependencies | All imports resolve to declared deps | Import works only because of hoisting | MEDIUM |
| Duplicate functionality | One library per task (date, HTTP, validation) | lodash + underscore + ramda all installed | MEDIUM |

Use `knip` output when available. Otherwise grep for import statements and
cross-reference against `package.json` dependencies.

### D4: License Compliance -- Weight 8, Max 8, Critical Gate

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Copyleft in production | Zero GPL/AGPL in bundled code | GPL dependency in production app | CRITICAL |
| Unknown licenses | All deps have declared licenses | Missing license field | MEDIUM |
| License compatibility | All licenses compatible with project license | Conflicting license chain | HIGH |

Critical gate: GPL in production closed-source app → triggers FAIL. The gate fires on that FINDING; a D4 score of 0 also fires it but is not required.

### D5: Bundle and Weight Impact -- Weight 8, Max 8

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Heavy dependencies | Alternatives exist for large deps (moment -> dayjs, lodash -> native) | 500 KB+ dep used for one function | HIGH |
| Tree-shaking support | `sideEffects: false` in dep, ESM exports | CommonJS-only dep in frontend bundle | MEDIUM |
| Duplicate versions | Single version in bundle | 3 versions of the same package | MEDIUM |

### D6: Circular Dependencies -- Weight 12, Max 12, Critical Gate

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Runtime cycles | Zero circular dependency chains at runtime | Module A imports B, B imports A | CRITICAL |
| Type-only cycles | Type-only imports (`import type`) are acceptable | Type cycle causes runtime initialization bug | LOW |
| Cycle depth | N/A | 4+ module cycle chain | HIGH |

Critical gate: runtime circular dependency causing initialization bug → triggers FAIL. The gate fires on that FINDING; a D6 score of 0 also fires it but is not required.

### D7: Coupling Metrics -- Weight 10, Max 10

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Instability (I = Ce/(Ca+Ce)) | Balanced: stable foundations, unstable leaves | Core module with I > 0.8 (depends on everything) | HIGH |
| Fan-out | Module imports < 10 direct dependencies | Single file imports 30+ modules | HIGH |
| Fan-in | Shared module is aware of its consumers | Utility used by 50+ files, fragile to change | MEDIUM |
| Vendor lock-in | Adapter pattern around vendor SDKs | Vendor SDK calls spread across 20+ files | MEDIUM |

### D8: Architecture Boundary Violations -- Weight 12, Max 12, Critical Gate

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Layer enforcement | UI -> Services -> Data, never backward | Component imports from data layer directly | HIGH |
| Secret in client | Server-only vars never imported in client code | Client bundle imports `process.env.SECRET` | CRITICAL |
| Domain boundaries | Features do not cross-import internal modules | Feature A reaches into Feature B internals | MEDIUM |

Critical gate: secret leaked to client bundle → triggers FAIL. The gate fires on that FINDING; a D8 score of 0 also fires it but is not required.

### D9: Barrel File Health -- Weight 7, Max 7

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Re-export scope | Barrel re-exports < 5 symbols, public API only | `export *` pulling in 50+ symbols | HIGH |
| Circular risk | Barrel does not create import cycles | Barrel creates cycle between modules | HIGH |
| Tree-shake impact | `sideEffects: false` set, named exports | Barrel defeats tree-shaking | MEDIUM |

### D10: Change Coupling -- Weight 8, Max 8

Analyze git history (last 6 months) for files that always change together:

```bash
git log --name-only --pretty=format:"---COMMIT---" --since="6 months ago" -- TARGET_ROOT
```

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Co-change clusters | Related files change together (test + impl) | Unrelated modules always change together | HIGH |
| Shotgun surgery | Feature change touches 1-3 files | Every feature touches 10+ files | HIGH |
| God module churn | Hot files are small and well-tested | Largest file is also most-changed | CRITICAL |

### D11: Supply-Chain Integrity -- Weight 10, Max 10

Distinct from D1 (known-CVE vulnerabilities) and D4 (licence): D11 is about whether a dependency is
**the package you think it is, from a trustworthy source, with a verifiable provenance**. Scan the
manifest + lockfile.

| Check | Good | Bad | Severity |
|-------|------|-----|----------|
| Typosquatting | Package names match the intended, popular library | A near-miss name (`reqeust`, `crossenv`, `lodahs`, `discord.js-selfbot`) — likely typosquat | CRITICAL |
| Dependency confusion | Internal/scoped packages pinned to the private registry; scope reserved on the public registry | An unscoped internal name also resolvable from the public npm/PyPI (attacker can publish a higher version) | CRITICAL |
| Malicious-package signals | No install-time exfiltration | `postinstall`/`preinstall` running `curl`/`wget`/base64-decoded payloads, or a dep flagged by OSV/Socket/npm advisories as malware — **after excluding well-known build tools per the Phase-3 False Positive Filters (esbuild/sharp/prisma/@swc/core legitimately use postinstall)**; a lifecycle script alone is not malware | CRITICAL |
| Lockfile integrity | Committed lockfile with integrity hashes; CI uses `npm ci`/`--frozen-lockfile` | No lockfile, or install resolves floating versions in CI | HIGH |
| Provenance / signing | Releases verified (npm provenance, Sigstore/cosign, SLSA attestation) for critical deps | No provenance on any dependency; unsigned artifacts | MEDIUM |
| SBOM | An SBOM (CycloneDX/SPDX) is generated and current | No SBOM — cannot answer "am I affected by X" fast | MEDIUM |

Tools (tiered, graceful degradation): OSV-Scanner / `npm audit signatures` / Socket CLI when present;
otherwise heuristic name-distance + `postinstall` grep + lockfile presence. Findings cite the manifest
`package.json:LINE` / lockfile entry. `--supply-chain` scopes the run to D1 + D11.

Critical gate: ANY confirmed typosquat, dependency-confusion exposure, or malicious-package signal in
production dependencies triggers FAIL (finding-presence, whatever the numeric score).

---

## Phase 3: Verification and Scoring

### False Positive Filters

| Pattern | Skip When |
|---------|-----------|
| Install script flagged | Well-known build tool (esbuild, sharp, prisma, @swc/core) |
| Unused dep | Framework plugin loaded via config (knip handles 139+ but misses some) |
| Circular dep | Type-only cycle (`import type`) with `isolatedModules` |
| Floating `^` version | Lockfile present and committed |
| Layer violation in Next.js | Server component IS the server layer |
| Barrel flagged | < 5 re-exports AND no circular deps caused |
| `export *` | `sideEffects: false` is set in the package |

### Scoring

**Critical gates — any ONE of these findings triggers FAIL, whatever the numeric score:**

| Gate | Fires on |
|------|----------|
| D1 | a known exploit-grade CVE reachable in production |
| D4 | a GPL-family licence in a closed-source production app |
| D6 | a runtime circular dependency causing an initialization bug |
| D8 | a secret leaked to the client bundle |
| D11 | a confirmed typosquat, dependency-confusion exposure, or malicious-package signal in production deps |

**These gates fire on the FINDING, not on an aggregate score of zero.** Read as "the dimension
scored 0" they are nearly unreachable, because every one of them spreads several checks over its
weight: D8 carries three checks across 12 points, so a secret in the client bundle beside clean layering and clean domain boundaries scores about 8/12 — the leak never blocks the audit. The named condition in each parenthesis IS the trigger — a dimension score of 0
remains sufficient to fire the gate, it is simply not necessary.

**N/A handling:** Exclude dimensions with INSUFFICIENT DATA, SKIPPED, or
INHERITED from both numerator and denominator.

| Grade | Percentage |
|-------|-----------|
| A | >= 85% |
| B | >= 70% and < 85% |
| C | >= 50% and < 70% |
| D | < 50% |

---

## Phase 4: Report

Save to: `zuvo/audits/dependency-audit-[YYYY-MM-DD].md` — at the **project root** (`zuvo/` resolves via `git rev-parse --show-toplevel`; override `$ZUVO_OUTPUT_DIR`. See `../../shared/includes/report-output-location.md`).

**REQUIRED:** emit the Tool Availability Block (template in `../../shared/includes/codesift-setup.md`) at the top of the report, after the title and before findings. Auditing degraded runs depends on this — do NOT skip it.

### Report Structure

```markdown
# Dependency & Coupling Audit Report

## Metadata
| Field | Value |
|-------|-------|
| Project | [name] |
| Date | [YYYY-MM-DD] |
| Package Manager | [npm/pnpm/yarn/bun] |
| Scope | [full / path] |
| Total prod deps | [N] |
| Total dev deps | [N] |

## Executive Summary

**Score: [N] / [MAX]** -- [A/B/C/D or FAIL]

| Metric | Count |
|--------|-------|
| CRITICAL findings | N |
| HIGH findings | N |
| MEDIUM findings | N |

[2-3 sentence summary]

## Dimension Scores

| # | Dimension | Score | Max | Tool Used | Notes |
|---|-----------|-------|-----|-----------|-------|
| D1 | Supply Chain | [N] | 15 | <pm> audit | |
| D2 | Freshness | [N] | 10 | <pm> outdated | |
| D3 | Dead Deps | [N] | 10 | knip / grep | |
| D4 | Licenses | [N] | 8 | license-checker | |
| D5 | Bundle Weight | [N] | 8 | Bundlephobia | |
| D6 | Circular Deps | [N] | 12 | dep-cruiser / madge | |
| D7 | Coupling Metrics | [N] | 10 | dep-cruiser / grep | |
| D8 | Architecture | [N] | 12 | dep-cruiser / grep | |
| D9 | Barrel Health | [N] | 7 | grep | |
| D10 | Change Coupling | [N] | 8 | git log | |
| D11 | Supply-Chain Integrity | [N] | 10 | OSV / Socket / heuristic | |
| **Total** | | **[N]** | **[M]** | | |

## Critical Gate Status
[D1, D4, D6, D8, D11 -- PASS/FAIL per gate]

## Delete These Tomorrow
[Unused deps that can be removed with zero code changes]

## Findings (sorted by severity)
[Per finding: ID, severity, dimension, description, fix]

## Cross-Cutting Patterns

| Pattern | Dims | Impact |
|---------|------|--------|
| Barrel causing circular deps | D9+D6 | Fix barrel, cycles disappear |
| God module + high churn | D7+D10 | Max blast radius on hot code |
| Unused dep with known CVE | D3+D1 | Dead code + security risk |

## Remediation Roadmap

### Quick Wins (< 1 hour)
### Short-term (1 day)
### Medium-term (1 week)
```

---

## Phase 5: Next-Step Routing

```
RECOMMENDED NEXT ACTION
------------------------------------
D1 CRITICAL (CVE)           -> npm audit fix or manual upgrade
D11 typosquat/malicious pkg -> REMOVE the package immediately + rotate any exposed creds; report to registry
D11 dependency confusion    -> for an UNSCOPED internal name: rename to a private @scope (or defensively publish a placeholder on the public registry) + pin the private registry in .npmrc; for a scoped one: reserve the @scope publicly
D11 no lockfile/provenance  -> commit lockfile, enable `npm ci`, add SBOM (CycloneDX) + provenance
D4 GPL in production        -> replace with MIT/Apache alternative
D6 runtime circular dep     -> zuvo:refactor [module path]
D8 boundary violation       -> zuvo:refactor [violating file]
D9 barrel causing cycles    -> zuvo:refactor [barrel file]
D10 high change coupling    -> zuvo:refactor [coupled files]
Score < 60%                 -> prioritize "Delete These Tomorrow" list first
Score >= 85%                -> schedule next audit in 3 months
------------------------------------
```

---

## Completion Gate Check

Before printing the final output block, verify every item. Unfinished items = pipeline incomplete.

```
COMPLETION GATE CHECK
[ ] Tool availability printed: PM audit, knip, dep-cruiser, license-checker
[ ] D1 supply chain: CRITICAL/HIGH CVEs checked for reachability
[ ] D4 license: GPL/AGPL in production flagged
[ ] D6 circular dependency detection ran
[ ] Critical gates printed: D1, D4, D6, D8, D11
[ ] "Delete These Tomorrow" section present
[ ] Report saved to zuvo/audits/
[ ] Run: line printed and appended to log
```

## DEPENDENCY-AUDIT COMPLETE

Score: [N] / [MAX] -- [grade]
Package Manager: [npm/pnpm/yarn/bun]
Dimensions: [N scored] | Critical gates: [PASS/FAIL]
Findings: [N critical] / [N total]

### Validity Gate (REQUIRED — print BEFORE Run line, AFTER retro append + append-runlog)

```
VALIDITY GATE
  triggers_held: language=<X> python=<yes|no>
  required_tool_calls:
    find_dead_code: [<N> unused exports | NOT_CALLED — VIOLATES_TRIGGER]
    find_unused_imports: [<N> | NOT_CALLED — VIOLATES_TRIGGER]
    find_circular_deps: [<N> cycles | NOT_CALLED — VIOLATES_TRIGGER]
    fan_in_fan_out: [<max_in>/<max_out> | NOT_CALLED — VIOLATES_TRIGGER]
    check_boundaries: [<N> violations | NOT_CALLED — VIOLATES_TRIGGER]
    audit_scan: [<N> findings | NOT_CALLED — VIOLATES_TRIGGER]
    analyze_python_deps: [<N> CVEs | not_required (no Python) | NOT_CALLED — VIOLATES_TRIGGER]
    stack_specific: [<result> | not_required | NOT_CALLED — VIOLATES_TRIGGER]
  postamble:
    retros_log_appended: [yes(bytes_added=N) | NOT_APPENDED]
    retros_md_appended: [yes(entry_count=N) | NOT_APPENDED]
    verify_audit_pass: [yes(<verified>/<total>) | NOT_RUN | REJECTED]
  gate_status: [PASS | FAIL — <which gates missing>]
```

If `gate_status = FAIL` → VERDICT = INCOMPLETE.

Append the Run line via the retro-gated wrapper (NOT direct `>> runs.log`):

```bash
printf '%b\n' "$RUN_LINE" | ~/.zuvo/append-runlog
```

Run: <ISO-8601-Z>	dependency-audit	<project>	<N-critical>	<N-total>	<VERDICT>	-	<N>-dimensions	<NOTES>	<BRANCH>	<SHA7>	<INCLUDES>	<TIER>


### Retrospective (REQUIRED)

Follow the retrospective protocol from `retrospective.md`.
Gate check → structured questions → TSV emit → markdown append.
If gate check skips: print "RETRO: skipped (trivial session)" and proceed.

After printing this block, append the `Run:` line value (without the `Run: ` prefix) to the log file path resolved per `run-logger.md`.

VERDICT: PASS (0 critical findings), WARN (1-3 critical), FAIL (4+ critical).

---

## Execution Notes

- All commands use the resolved `TARGET_ROOT` from argument parsing
- CodeSift integration follows `codesift-setup.md`
- Agent dispatch follows `env-compat.md`
- Tool unavailability degrades individual dimensions, not the entire audit
- Yarn version detection is critical: Classic (1.x) and Berry (2+) have
  different command syntax
- `npm query` selectors are npm-only; pnpm/yarn/bun use lockfile grep as
  fallback
- `--no-api` flag skips Bundlephobia and OpenSSF calls for air-gapped or
  rate-limited environments

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.