Check cache.
safe-pkgs caches package decisions locally so repeated requests avoid unnecessary registry lookups while still honoring configurable TTL expiration.
What is cached
check_package responses
Serialized JSON tool decisions are stored directly and reused until TTL expiry.
check_lockfile package evaluations
Lockfile audits call the same package evaluation path, so they automatically benefit from cache hits.
Storage path
SAFE_PKGS_CACHE_DB_PATHif set (full SQLite file path).- Otherwise:
~/.cache/safe-pkgs/cache.db.
Parent directories are created automatically when missing.
Cache key format
Examples:
check_package:fca103...f7a6f:npm:lodash@4.17.21check_package:2de8d2...44d9a:cargo:serde@1.0.217check_package:90f5aa...ab302:pypi:requests@2.31.0- Omitted version is normalized to
latest: check_package:fca103...f7a6f:npm:lodash@latest
policy_fingerprint in the key means policy changes naturally cold-miss older
entries and repopulate cache under the new policy scope.
Fingerprint calculation
Both fingerprints are lowercase SHA-256 hex strings (64 chars):
config_fingerprint = sha256(canonical_policy_config_json)policy_fingerprint = sha256({ policy_snapshot_version, registry, config_fingerprint, enabled_checks })
Canonicalization rules:
- Normalize check IDs.
- Lowercase registry keys.
- Sort and deduplicate list-like fields.
- Use stable map ordering.
Operational-only settings like cache.ttl_minutes are intentionally excluded
from config_fingerprint because they do not change policy semantics.
Lifecycle behavior
- Resolve enabled checks for the registry.
- Compute canonical config and policy fingerprints.
- Build key from policy fingerprint, registry, package name, and requested version.
- Attempt
getfrom SQLite. - If entry is expired, delete it and treat as miss.
- On miss, run live checks and serialize result.
- Upsert into cache with refreshed
expires_at.
TTL and schema
- Config key:
[cache].ttl_minutes - Default:
30 - Expiry validation happens on read (
get).
CREATE TABLE IF NOT EXISTS cache_entries (
cache_key TEXT PRIMARY KEY,
cache_value TEXT NOT NULL,
expires_at INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_cache_entries_expires_at ON cache_entries (expires_at);
Operations note
Deleting the cache DB is safe; it will be recreated on next run.