Context
Phase 1 roadmap (#21) checklist item: "Fix vuln DB staleness (OSV.dev API, update scheduler)".
Discovered during Phase 1 review: scripts/osv_client.py has a 24h TTL cache (DEFAULT_TTL = 86400) with purge_expired() cleanup, but no automatic refresh mechanism. The cache only refreshes when:
vuln-scan is explicitly run, AND
- The specific package entry's TTL has expired
This means: if a new CVE is published today for a dependency in the user's project, CodeLens won't report it until (a) 24h pass AND (b) the user re-runs vuln-scan. There is no background scheduler, no push notification, no staleness indicator in the output.
Problem
Agents relying on vuln-scan for security posture have no way to know:
- Whether the cache is fresh or stale
- When the last successful OSV.dev API call was
- Whether a re-scan would surface new vulnerabilities
Proposed Change
1. Staleness flag in vuln-scan output
Add to vuln-scan JSON output:
{
"status": "ok",
"cache_info": {
"last_refresh": "2026-06-28T10:00:00Z",
"age_hours": 23.5,
"ttl_hours": 24,
"is_stale": false,
"stale_packages": ["requests@2.20.0"]
}
}
is_stale: true when age_hours >= ttl_hours OR when any cached package's entry is past TTL. stale_packages lists specific packages whose cache entries are expired.
2. --refresh flag on vuln-scan
codelens vuln-scan --refresh — bypasses cache, forces fresh OSV.dev API calls for all packages. Updates cache with new results.
3. --max-age flag on vuln-scan
codelens vuln-scan --max-age 6h — treats cache entries older than 6 hours as stale (overrides default 24h TTL for this run only). Useful for agents who want fresher data without full refresh.
4. Background refresh scheduler (optional, stretch)
A lightweight scheduler that runs in the MCP server process (when serve is active) and refreshes the top-N most-used packages' OSV entries every ttl_hours / 2. This keeps the cache warm for active agents. Out of scope for Phase 1 — file as follow-up if needed.
Acceptance Criteria
Priority
Medium — completes Phase 1 (#21). Not blocking (vuln-scan still works, just not freshness-aware), but agents have no way to trust the currency of CVE results without this.
Related
Context
Phase 1 roadmap (#21) checklist item: "Fix vuln DB staleness (OSV.dev API, update scheduler)".
Discovered during Phase 1 review:
scripts/osv_client.pyhas a 24h TTL cache (DEFAULT_TTL = 86400) withpurge_expired()cleanup, but no automatic refresh mechanism. The cache only refreshes when:vuln-scanis explicitly run, ANDThis means: if a new CVE is published today for a dependency in the user's project, CodeLens won't report it until (a) 24h pass AND (b) the user re-runs
vuln-scan. There is no background scheduler, no push notification, no staleness indicator in the output.Problem
Agents relying on
vuln-scanfor security posture have no way to know:Proposed Change
1. Staleness flag in vuln-scan output
Add to
vuln-scanJSON output:{ "status": "ok", "cache_info": { "last_refresh": "2026-06-28T10:00:00Z", "age_hours": 23.5, "ttl_hours": 24, "is_stale": false, "stale_packages": ["requests@2.20.0"] } }is_stale: truewhenage_hours >= ttl_hoursOR when any cached package's entry is past TTL.stale_packageslists specific packages whose cache entries are expired.2.
--refreshflag on vuln-scancodelens vuln-scan --refresh— bypasses cache, forces fresh OSV.dev API calls for all packages. Updates cache with new results.3.
--max-ageflag on vuln-scancodelens vuln-scan --max-age 6h— treats cache entries older than 6 hours as stale (overrides default 24h TTL for this run only). Useful for agents who want fresher data without full refresh.4. Background refresh scheduler (optional, stretch)
A lightweight scheduler that runs in the MCP server process (when
serveis active) and refreshes the top-N most-used packages' OSV entries everyttl_hours / 2. This keeps the cache warm for active agents. Out of scope for Phase 1 — file as follow-up if needed.Acceptance Criteria
vuln-scanoutput includescache_infoobject withlast_refresh,age_hours,is_stale,stale_packages--refreshflag forces fresh API calls and updates cache--max-ageflag overrides TTL for the current runPriority
Medium — completes Phase 1 (#21). Not blocking (vuln-scan still works, just not freshness-aware), but agents have no way to trust the currency of CVE results without this.
Related
scripts/osv_client.py(lines 51, 147-210 for cache logic)scripts/commands/vuln_scan.py