Dormant then released

Check P7 · provenance family · severity MEDIUM · automatic · one of the 12 npm and PyPI package checks

Maps to OWASP LLM03 ATLAS AML.T0012 A release after a year of silence is the shape a taken-over maintainer account leaves; the check names the shape, not a compromise.

The question this check asks: has this package woken up? A package that published nothing for a year and then shipped a release in the last fortnight is either a maintainer coming back or someone else using the maintainer's account.

Why it matters

A dormant package with a long install history is worth more to an attacker than a new one: people already depend on it, and nobody is watching it. Taking over the maintainer's account and publishing one release reaches all of them. The hijacked chalk and debug releases of September 2025 were published from a real maintainer's account; a sudden release after a long silence is the shape such a takeover leaves in the history, whether or not it is one.

How RepoGates scores it

The release history is read — npm's per-version times from the package's whole record, PyPI's upload times — and the two most recent releases compared. pkg-dormant-release is MEDIUM and 6 points when the gap between them is 365 days or more and the latest was published 14 days ago or less. The finding prints both numbers. A MEDIUM is a warning under the default profile. After the fortnight the row no longer fires; the release has then been out long enough for a report to exist, which P1 reads.

False positives we know about

A maintainer coming back. Projects go quiet and wake up, and the first release after a long gap is usually exactly that; the check cannot tell the difference from the history and does not pretend to. It is a warning for two weeks, with both numbers on the report.

What this check does not cover

Who published the release. That is P8's question, on npm. What changed in it. The release's code is not read or compared with the one before. A takeover that kept publishing on an active package leaves no gap to read.

Scope, the same on every page of this roster: RepoGates does not see git clone, package managers or curl — outside Claude Code with the RepoGates plugin, whose hook refuses a clone or install that names a blocked repository on the command line, before it runs. The hook sees Bash tool calls in that one client and nothing else; a package named on the line (npm install express, pip install flask, npx, npm create) is judged by its own verdict under this roster, its declared repository riding along. Direct dependencies named on the command line only; transitive dependencies and lockfiles are not resolved. A package added by editing package.json or requirements.txt and installed later is not a line the hook judges. Edit and Write are read for one thing only — an API key about to be saved — checked on the machine and never sent; that guard asks, it never denies. This roster reads what npmjs.org and pypi.org publish about a package — its record, its release history, its declared repository — and never the package's code or what it installs after it. A registry other than those two (a --registry or --index-url on the line) is asked about, not assessed. A package the registry no longer serves is not assessed, never a pass. A PASS means nothing matched on what was read.

Check it yourself

npm view NAME time --json | jq 'to_entries | sort_by(.value) | .[-3:]'
curl -s https://pypi.org/pypi/NAME/json | jq '[.releases | to_entries[] | {v: .key, t: (.value[0].upload_time)}] | sort_by(.t) | .[-3:]'

Then read the release's notes and the repository's recent commits: a maintainer coming back usually says so.

Questions

Why is a release after a long silence a warning? Because it is the shape an account takeover leaves: a package people already depend on, untouched for a year, suddenly ships a release. It is also what a maintainer coming back looks like, which is why it is a medium finding and never a block.

Why only the last 14 days? Because the window in which the release is new is the window in which nobody has had time to report it. After that, a malicious release is likely to have an OSV report, which the known-malicious check reads.

Does RepoGates compare the new release with the old one? No. The check reads publication times from the registry's record. What changed in the release is in the package's code, which this tier does not read.

Related checks

P8 Publisher change · P1 Known malicious · C7 Maintenance activity.

Add RepoGates to Chrome Pricing

Sources for this page: the thresholds and weights from the product's own roster and scoring tables.