TL;DR: Refresh the advisory database immediately before the audit runs, in the same CI job, and fail the job if the database is older than your freshness bound. A stale database makes the audit report "0 vulnerabilities" for CVEs published after the snapshot was taken. Pin the refresh and the audit together so they cannot drift apart.

```text
agent's pre-merge checklist ran npm audit but the advisory DB was three days stale - the CVE was already published
```

1. Check database freshness: find where the advisory database or cache lives in CI and read its timestamp. Expected: the timestamp is days old - older than your freshness bound (for example 24 hours).
2. Re-run the audit against a freshly fetched database. Expected: the previously missed CVE now appears in the results.
3. Put the refresh and the audit in the same CI job, refresh first and audit second. Expected: every audit runs against a minutes-old database, never a cached one.
4. Add a freshness assertion: the job fails if the database timestamp is older than N hours. Expected: a stale-cache run fails loudly instead of reporting a false clean.
5. Backfill: re-audit every merge that passed while the database was stale. Expected: a list of PRs that need re-checking; remediate any that contain published CVEs.

## Use this when
- An audit reported clean but a CVE was already published at the time
- The advisory database is cached in CI between runs
- You need a freshness guarantee on security checks
- Post-merge scans disagree with pre-merge audit results

## Not for this skill when
- The feed timed out and the check was skipped (fail-open handling, different skill)
- The advisory was checked and judged not applicable
- The noise is non-security audit output like deprecation warnings

## Variant phrasings
- npm audit missed a published CVE
- Stale advisory database
- Audit reported zero vulnerabilities but the CVE existed
- Advisory cache too old

## Why it happens
CI caches aggressively, and the advisory database is just another cache entry. The audit tool trusts the local database completely - it has no built-in "last updated" warning that fails the run. Three days is an eternity in CVE publication, so the check passes on obsolete data and everyone trusts the green checkmark.

## Edge cases
- Air-gapped CI needs a vendored database with its own refresh pipeline - the freshness assertion still applies
- Audit fix suggestions can introduce breaking changes themselves - audit first, apply fixes deliberately
- Set the freshness bound to match your merge cadence: daily merges need a daily-fresh database

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_utqTNXnykgrzVZ6527ZdfQ
