Skip to content

fix(deps): Dependabot lockfiles bypass the minimumReleaseAge cooldown #441

Description

@EricAndrechek

Summary

pnpm-workspace.yaml sets minimumReleaseAge: 10080 (7 days) as a supply-chain defense against compromised releases. Dependabot doesn't know about it, so the lockfiles it generates can contain packages published inside that window — and nothing in CI catches it.

Evidence

Dependabot recreated #416 on current main. A local pnpm install refused the lockfile outright:

[ERR_PNPM_NO_MATURE_MATCHING_VERSION]
@esbuild/openbsd-arm64@0.28.2 was published at 2026-08-08T19:57:56.000Z,
within the minimumReleaseAge cutoff (2026-08-03T19:23:49.523Z)
…and 34 more

35+ entries younger than the cooldown. Fixing it required a full rebuild (pnpm clean --lockfile + pnpm install), which re-resolved to policy-respecting versions (astro 7.1.6 rather than a fresher build, Starlight 0.41.6, etc.).

Why CI does not catch this

CI installs with pnpm install --frozen-lockfile, which installs exactly what the lockfile pins and does not re-check minimumReleaseAge. The policy only bites on a non-frozen local install — i.e. only when a human or agent happens to regenerate. A Dependabot npm PR merged as-is would therefore pull sub-cooldown packages into main with every check green.

This is the inverse of the usual lockfile-drift failure mode: the lockfile is internally consistent, so nothing complains — it just quietly violates the stated policy.

Suggested fix

Add a CI check that fails when the committed lockfile contains entries published inside the cooldown. Options, roughly in order of preference:

  1. A make target that resolves each lockfile entry's publish date against the registry and compares to minimumReleaseAge, wired into the Lint job. Self-contained, no new dependencies.
  2. A scheduled/PR job that runs pnpm install --no-frozen-lockfile --lockfile-only in a scratch tree and fails if the lockfile changes — catches cooldown violations and ordinary drift together.
  3. Teach the Dependabot flow to regenerate: a workflow that reacts to dependabot/npm_and_yarn/** pushes, rebuilds the lockfile under policy, and commits the result back to the PR branch.

Option 1 is the tightest gate; option 3 removes the manual step but needs write-back permissions on Dependabot branches.

Interim workaround

Regenerate the lockfile locally before merging any Dependabot npm PR:

pnpm clean --lockfile && pnpm install

Scope check on what has already merged

main is currently clean — make verify (which runs pnpm install --frozen-lockfile) passes at 3c7d62b, and #439's lockfile was regenerated locally as part of the version-holds fix before merge. This issue is about the general gap, not a known live breach.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions