Skip to content
Back to skills

Dependency Upgrade

BSecurity

Use when a ticket bumps, adds, or removes a dependency — a security advisory, a major-version upgrade, a lockfile refresh, a Dependabot follow-up — and the change must be proven safe with the repo's tests and the upstream changelog, not assumed. Invoke for "upgrade X to v4", "fix the audit finding", "remove the unused package", or any change to a manifest or lockfile.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 28, 2026
ai-agentsgonodeapisecurity

Works with

  • api
  • mcp

Security analysis

B84/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 29, 2026

npx -y skills add tmj-90/gaffer --skill dependency-upgrade --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dependency Upgrade?

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

Security grade badge for Dependency Upgrade
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/tmj-90-dependency-upgrade/badge)](https://www.skillsdirectory.com/skills/tmj-90-dependency-upgrade)

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-upgrade
description: Use when a ticket bumps, adds, or removes a dependency — a security advisory, a major-version upgrade, a lockfile refresh, a Dependabot follow-up — and the change must be proven safe with the repo's tests and the upstream changelog, not assumed. Invoke for "upgrade X to v4", "fix the audit finding", "remove the unused package", or any change to a manifest or lockfile.
stack: []
area: workflow
---

# Upgrade a dependency safely

A dependency change imports someone else's decisions into your build. Treat it like a
code change from a stranger: read what changed, run everything that could be affected,
keep the lockfile honest, and never "bump and hope".

**Gaffer constraints — read first.**

- Your delivery prompt forbids installing, updating or removing dependencies in any
  ecosystem; that needs human approval. The safety hook enforces it for
  `npm|pnpm|yarn install|i|add|ci|update|up|upgrade|remove|rm|uninstall` and
  `pip install`. Do not look for a command that dodges the hook (bare `yarn`,
  `bun install`, `uv sync`, `poetry add`, `bundle install`, `go get`, `cargo update`
  are equally off-limits), and never hand-edit a lockfile to fake one.
- In a delivery worktree `node_modules` is a symlink to the main checkout's install.
  Never run `npm ci`, `pnpm install`, `update` or `prune` there: it rewrites or empties
  the shared install and breaks every other worktree.
- Consequence: your tests run against the version that is ALREADY installed, not the
  one in your edited manifest. Check which version actually ran
  (`node -p "require('<pkg>/package.json').version"`, `pip show <pkg>`, `go list -m <mod>`)
  before claiming the new version is tested.

## Steps

1. **Pin down the reason.** A security advisory (which CVE/GHSA, which versions are
   fixed), a feature you need, or hygiene. The reason sets the minimum target and does not
   license unrelated bumps. For an advisory, prefer the smallest version that fixes it.
   Call `search_lore` for pinned versions and known incompatibilities in this repo.
2. **Classify the jump with semver.** Patch and minor promise compatibility; major does
   not; any bump inside `0.y.z` may break. Treat a transitive major change, a raised
   `engines`/runtime floor, or a changed peer-dependency range as a major.
3. **Read the upstream changelog, release notes and migration guide** between the
   current and target versions. List every breaking change, deprecation and behaviour
   change, then `grep` the repo for the imports and APIs each one names. An empty grep
   is evidence too; record it. A major bump with no notes read is a guess.
4. **For a NEW package, vet it before adding it:** exact name (typosquats differ by one
   character), maintainer and release activity, licence against the repo's policy,
   whether it runs install scripts, and whether the standard library or an existing
   dependency already covers the need (the `minimalism` skill). New dependencies need a
   human decision in this factory: `request_decision` with the justification.
5. **Do not run the package manager yourself.** The manifest and lockfile must be
   produced by the owning tool (e.g. `pnpm up <pkg>@<ver> --ignore-scripts`,
   `go get <mod>@<ver>`, `cargo update -p <crate> --precise <ver>`), and that is a
   human's step here. Unless the target version is already installed and locked on the
   branch, stop (see "Stop and escalate") with the exact command a human should run.
   Scope stays at one package plus the transitive changes it forces; a lockfile diff of
   thousands of lines hides the one that matters.
6. **Adapt the code minimally** to the breaking changes you listed. If the upgrade
   forces a refactor larger than the ticket implies, stop and `request_decision` with the
   size and the option of an interim minor/patch bump.
7. **Verify at the edges.** With the target version actually installed, run build,
   typecheck, lint, the full test suite and any integration or browser suite the repo
   has — dependency changes break at the boundaries. Then run the ecosystem audit
   (`pnpm audit`, `npm audit`, `pip-audit`, `cargo audit`, `govulncheck`) and confirm the
   advisory is gone and no new high-severity finding appeared.
8. **Evidence** via the `record-evidence` skill: the version pair, the changelog items
   you handled (and the empty greps), the verification output with the installed version
   shown, the audit result, and any transitive major change. On a resume that call is
   refused: do not retry; put this, the AC → test map and the smallest-change note in
   your final message.

## Done when

The manifest and lockfile were produced by the package manager, the version under test
is the target version, the full verification and audit pass, and every breaking change
in the notes is either handled or shown not to apply. Otherwise you are not done: the
ticket is blocked with the exact command and your changelog analysis.

## Stop and escalate when

- The lockfile cannot be regenerated because installs are off-limits to you:
  `mark_ticket_blocked` with the exact command (e.g.
  `pnpm up <pkg>@<ver> --ignore-scripts`) and the changelog analysis you already did, so
  the human run is one step.
- The tests could only run against the old installed version: say so plainly; never
  report them as proof of the upgrade.
- The upgrade needs a fork, a patch-package, or a vendored copy: that is a decision.

## Rules

- Lockfiles are generated, never hand-edited; one package manager, at CI's version.
- One package per ticket unless the ticket is a refresh; no drive-by bumps.
- `.npmrc` and other credential files are blocked by the hook; registry and auth
  changes are a human's job.
- Work on the delivery branch (the `create-branch` skill verifies); commit, never push.

## Capture lore

This skill is one of the places durable, reusable knowledge naturally surfaces:
**While bumping a package you learn which pins must not move, which packages break each other, and which manager version CI insists on.** That kind of fact is *lore*. Capture it via the **lore-capture
protocol in your brief** (`CLAUDE.factory.md`, step 11 "Memory contribution"):
call the Memory MCP `suggest_lore` once at the close of your work — reusable
conventions, gotchas, decisions, and boundaries only, never per-ticket trivia.

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…