Install
$ agentstack add skill-mitodl-agent-kit-dependency-updates ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Dependency Updates
Scope
| Layer | Examples | |-------|---------| | Language library / framework | Python packages, npm packages, Go modules, Ruby gems, Cargo crates, Maven artifacts | | Container base image | FROM python:3.9-slim → 3.12-slim, ubuntu:20.04 → 24.04, distroless variants | | System / OS packages | apt-get install, Alpine apk, Homebrew brew in CI | | Helm / Kubernetes charts | Bitnami charts, operator Helm releases, CRD-carrying chart upgrades | | Database / storage | PostgreSQL, Redis, Elasticsearch, MongoDB — via Helm, Docker Compose, or operators | | Infrastructure tooling | Terraform providers, Pulumi SDKs, OpenTofu modules |
Effort sizing
| Bump | Library | Infra / DB | Base image | |------|---------|-----------|------------| | Patch (x.y.z) | Changelog skim + test run | Changelog skim + test run | Rebuild + smoke | | Minor (x.y.0) | Changelog + usage check + test | Changelog + values diff + test | Rebuild + smoke test | | Major (x.0.0) | Full Phase 1–6 | Full Phase 1–6 + staging | Full Phase 1–6 + rebuild | | Digest / date pin | Rebuild + smoke | N/A | Rebuild + smoke |
Phase 0 — Discover what is outdated
When you don't have an automated tool handing you a list, generate it yourself. Run the appropriate command for each ecosystem present in the project.
Python
uv pip list --outdated # uv projects (installed packages vs latest)
pip list --outdated # pip-managed environments
pip-audit # combined outdated + known vulnerabilities
JavaScript / TypeScript
npm outdated # shows current / wanted / latest per package
bun outdated # Bun 1.1.0+; use `bunx npm-check-updates` on older Bun
yarn outdated # yarn classic
pnpm outdated # pnpm
npm audit # known vulnerabilities
Go
go list -m -u all # shows available updates for every module in go.mod
govulncheck ./... # known vulnerabilities in the dependency graph
Ruby
bundle outdated # shows gems with available updates
bundle audit # known vulnerabilities (requires bundler-audit)
Rust
cargo outdated # requires cargo-outdated: cargo install cargo-outdated
cargo audit # known vulnerabilities
Helm / Kubernetes charts
helm repo update
helm search repo --versions | head -20 # see all available versions
# Check what versions are currently pinned in Chart.yaml:
helm dependency list # shows pinned versions; compare against helm search output for latest
Docker base images
There is no universal "outdated" command for base images. Check freshness by:
# Pull the latest version of the pinned tag, then compare repo digests
docker pull : --quiet
docker inspect : --format '{{index .RepoDigests 0}}'
# Compare against the digest pinned in your Dockerfile (FROM @sha256:...)
Or check the image's registry page / GitHub releases for the upstream project.
Terraform / OpenTofu providers
terraform providers lock -upgrade # updates .terraform.lock.hcl with latest versions
tofu providers lock -upgrade # OpenTofu equivalent
# Then review what changed:
git diff .terraform.lock.hcl
Apt / system packages (in Dockerfile or CI)
# Run inside the container to see what is upgradable
apt-get update && apt list --upgradable 2>/dev/null
Phase 1 — Characterize each update
For each outdated package (from Phase 0, from Renovate, or from a targeted single-package check):
# If the update came as a PR:
gh pr checkout
git diff HEAD~1 -- '*.toml' '*.json' '*.yaml' '*.lock' 'Dockerfile*' '*.tf'
# If you are applying the update manually, record the old version first:
# grep pyproject.toml # or go.mod, package.json, Chart.yaml, etc.
Establish for each package:
- Version range: old → new
- Bump classification: patch / minor / major / digest
- Direct or transitive dependency
- Stack layer (library, chart, base image, system, DB)
Phase 2 — Evaluate the changelog
Where to find it
- GitHub releases (most authoritative):
gh api repos///releases --jq '.[].body' - Package registry pages — PyPI, npm, crates.io, pkg.go.dev all link to changelogs
CHANGELOG.mdin the repo — often more complete than release notes- Helm charts — diff
values.yamlbetween versions, which is where breaking changes hide:
``bash helm show values / --version > old.yaml helm show values / --version > new.yaml diff old.yaml new.yaml ``
- Docker base images — check the upstream project release page plus the base OS release notes (e.g., Debian Bookworm migration guide)
What to flag
Read every entry from the current version to the new version:
- Breaking change — API removals, signature changes, renamed config keys, removed CLI flags
- Deprecation — items that now emit warnings; not merge blockers, but open a follow-up task
- Security fix — CVE IDs and advisory links; these jump to the front of the queue
- Silent behavior change — changed defaults, altered retry/timeout/encoding behavior
- Runtime requirement raised — minimum Python/Node/Go version bumped above what you run
Phase 3 — Locate usages (blast radius)
Build a list of every file that references the package.
Language libraries
# Adapt the pattern and --type flag to the language
rg "" --type py # Python
rg "\"\"" go.mod # Go module declaration
rg "" --type ts --type tsx # TypeScript
rg "''" Gemfile # Ruby
rg '""' Cargo.toml # Rust
Also search config files that reference the package by name: plugin configs, lint configs, CI workflow steps.
Docker / container base images
rg "FROM " --glob 'Dockerfile*' --glob '*.dockerfile'
rg "apt-get install" --glob 'Dockerfile*' # apt lines may reference packages affected by base change
Multi-stage builds: check whether intermediate AS build stages also use the image.
Helm / Kubernetes charts
rg "" charts/ -l
# Render the current state as a baseline before upgrading
helm template -f values.yaml > baseline.yaml
Phase 4 — Evaluate impact
Cross-reference each usage site against the changelog flags from Phase 2.
| Finding | Decision | |---------|----------| | No breaking changes in range | Skip Phase 5, go to Phase 6 | | Deprecated API in use | Note; do not block; open a follow-up task | | Removed/changed API in use | Must adapt before applying → Phase 5 | | Behavior change at a usage site | Write or update a test to assert the new behavior | | Runtime requirement raised above current | Upgrade runtime first as a separate dependency |
Layer-specific checks
Base image (Docker):
- A base image bump often changes two things simultaneously: the OS version (e.g., Buster → Bookworm) and the bundled runtime (e.g., Python 3.9 → 3.12). Evaluate both axes separately.
- Check
apt-get installlines for packages that were renamed or removed in the new OS version - Run
docker buildlocally — ABI and missing-library failures surface here, not at changelog review time - In multi-stage builds, confirm both
FROMlines change to the same new base to avoid ABI mismatches when copying compiled artifacts between stages - Python runtime stdlib removals — two distinct waves (PEP numbers tell you the version):
- Python 3.12 (PEP 632):
distutilsremoved — usesetuptoolsinstead. This is the most common silent build-time kill for packages that callsetup.pyor importdistutilsdirectly. - Python 3.13 (PEP 594):
cgi,cgitb,imghdr,aifc,chunk,crypt,mailcap,msilib,nis,nntplib,ossaudiodev,pipes,sndhdr,spwd,sunau,telnetlib,uu,xdrlib— all removed. If the target base image bundles Python 3.13, search for any of these:
``bash rg "import (cgi|cgitb|imghdr|aifc|crypt|mailcap|pipes|telnetlib)" --type py pip show setuptools # must be present if any dep still calls distutils at install time ``
Helm chart major bumps:
- Diff CRDs: fields may be promoted, removed, or have changed validation
- Verify
apiVersionin rendered manifests is supported by your target cluster version - Identify renamed or removed
values.yamlkeys against your override files - Run
helm template --version -f your-values.yaml | kubectl apply --dry-run=server -f -to surface renamed or missing keys before upgrading
Database / operator major versions:
- Check for removed SQL functions, changed defaults, wire protocol changes
- Verify the ORM or driver supports the new server version
- Determine if the chart upgrade implies a data migration — PostgreSQL major upgrades require
pg_upgradeor a dump-restore cycle; this must be planned independently of the chart bump - Validate against a staging or local instance before applying to production
Infrastructure tooling:
- Run
plan/previewbefore merging — provider majors often rename resources or move arguments - Check for deprecated resource types that were removed in the new version
Phase 5 — Adapt code (only if Phase 4 found a blocker)
Make the minimum change to satisfy the new API. Do not refactor surrounding code.
If the package provides a codemod, migration script, or official upgrade guide, follow it rather than hand-editing.
After adapting:
- Re-run type checkers and linters
- Confirm the changed call sites resolve (
python -c "import ",go build ./..., etc.) - For Docker: rebuild locally and confirm startup behavior
Phase 6 — Verify
Run the full test suite before committing the update.
# Substitute your project's test command
pytest -x # Python
go test ./... # Go
npm test # JS/TS
cargo test # Rust
bundle exec rspec # Ruby
Also run linters and type checkers — minor bumps can introduce type errors without breaking tests.
For infrastructure:
helm template . -f values.yaml | kubectl apply --dry-run=server -f -
pulumi preview --stack
terraform plan
Interpreting failures
- Import / link errors → API changed; return to Phase 5
- Type errors → fix call sites; don't suppress without an explanatory comment
- Failures in unrelated modules → investigate before assuming pre-existing; transitive behavior changes surface far from the import
- Docker build failures → check
apt-getpins and runtime compatibility with the new base - Helm dry-run failures → a value key was renamed or a CRD version changed; re-run the values diff
Batch strategy — working through a backlog
Whether you discovered the backlog via uv pip list --outdated, npm outdated, go list -m -u all, or a pile of Renovate PRs, the same sequencing logic applies.
Step 1: Build the full inventory
Run Phase 0 for every ecosystem in the project. Produce a flat list: package name, current version, latest version, bump type. Group by ecosystem.
Step 2: Classify by risk tier
| Tier | Criteria | Approach | |------|----------|----------| | 1 — Security | Known CVE or security advisory | Apply immediately, ahead of everything else | | 2 — Patch | x.y.z bumps | Batch-apply per ecosystem; one test run per batch | | 3 — Minor (clean) | No breaking flags in changelog | Review + test, one ecosystem group at a time | | 4 — Minor (with deprecations) | Deprecations in use | Review + adapt + test; open follow-up tasks | | 5 — Major | API or behavior changes | Full Phase 1–6 per package, one at a time | | 6 — Runtime / OS / DB | Base image, database major, language runtime | Last; staging validation required |
Step 3: Determine what can be parallelized
Many updates within a tier can be applied simultaneously:
Safe to batch (apply together, one test run):
- All patch bumps within a single ecosystem (e.g., every Go module patch in one
go get -u=patch ./...) - All minor bumps within an ecosystem that have no breaking flags and no dependency relationships between them
- Updates across different ecosystems at the same tier (Go patches and npm patches can proceed simultaneously on separate branches)
Must be sequenced (one at a time or in explicit order):
- Runtime before libraries — if a library requires Python 3.12+, upgrade Python first; the library upgrade is blocked until then
- Leaf before root — if package A imports package B, upgrade B before A, or their version constraints may conflict
- DB client before DB server — the driver or ORM must support the new protocol before the server is upgraded
- CRDs before operator chart — Kubernetes applies CRDs separately; an operator upgrade that references a missing CRD field will fail
- Major bumps within the same module graph — do not combine multiple major bumps that touch overlapping files; you won't be able to attribute failures
For cross-ecosystem updates (Go service + npm frontend + Helm charts), those ecosystems are independent and their work streams can proceed in parallel even when their internal sequencing differs.
Step 4: Apply in waves, test between each
Wave 1 — Security: apply individually; fast-path merge
Wave 2 — Patches: batch per ecosystem with `uv sync`, `go get -u=patch`, `npm update --save-exact`, etc.
Wave 3 — Clean minors: one ecosystem group at a time; full test suite after each group
Wave 4 — Minors with deprecations: adapt call sites, then test
Wave 5 — Majors: one package at a time, full Phase 1–6
Wave 6 — Runtime / OS / DB: coordinate with deployment; validate in staging
Run the full test suite after each wave. If a wave introduces failures, diagnose before proceeding to the next wave — do not accumulate undiagnosed failures across multiple waves.
Useful batch-apply commands by ecosystem
# Python — apply all patch-level updates
uv lock --upgrade-package # upgrade a single package in the lockfile
uv lock --upgrade && uv sync # upgrade all to latest allowed by constraints
# Go — apply patch updates only
go get -u=patch ./...
go mod tidy
# npm — update to latest satisfying semver range
npm update
# Update a specific package to a specific version
npm install @
# Rust
cargo update # update all deps within semver constraints
cargo update -p # update a single crate
# Ruby
bundle update --patch # patch-level updates only
bundle update # update a single gem
# Helm — update a chart dependency to a new version
# Edit Chart.yaml version pin, then:
helm dependency update
Step 5: Track progress
Keep a simple checklist in a tracking issue or branch description:
[ ] Wave 1 — security: CVE-2024-xxxxx (pkg A), CVE-2024-yyyyy (pkg B)
[x] Wave 2 — patches: 14 Go modules, 8 npm packages — CI green
[ ] Wave 3 — clean minors: Go (in progress), npm (pending), Helm (pending)
Decision matrix
| Signal | Action | |--------|--------| | Patch bump, tests green | Apply | | Minor bump, no breaking flags, tests green | Apply | | Minor bump, deprecation warnings new | Apply + open follow-up task | | Major bump, no usage of changed APIs, tests green | Apply | | Major bump, removed API in use | Adapt code (Phase 5), then apply | | Base image major bump | Build locally, smoke test, then apply | | DB / operator major bump | Validate in staging; coordinate with deploy | | Security advisory (any bump size) | Prioritize; apply ahead of the queue | | Tests fail, root cause unclear | Do not apply; open investigation task | | Runtime version requirement raised | Upgrade runtime first as its own wave | | Two updates touch overlapping files | Sequence them; do not combine |
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: mitodl
- Source: mitodl/agent-kit
- License: BSD-3-Clause
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.