Description
Distinguish an empty threat feed from a broken one.
Problem Statement
In anomaly-detector/src/audit-guard/threat-feed-fetcher.ts: when no feed URL is configured, updateFeed logs one console.warn and returns (lines 14-17). isThreat() then returns false forever, so THREAT_FEED_MATCH never fires and nothing distinguishes "no threats" from "no feed".
When all fetches fail, the code keeps this.threatAddresses indefinitely — lastUpdated is recorded but never checked, so a feed broken for weeks keeps serving stale data while the alert text claims "matches active blocklist in threat feed".
Finally, setMockThreats (line 71) is a public method on the production class that makes isThreat consult only the mock set — so a stray call disables real matching entirely.
Proposed Changes
Technical Implementation Scaffolding
- Target Repository: vero-audit-guard
- Target Path: anomaly-detector/src/audit-guard/threat-feed-fetcher.ts
- Branch Naming: fix/issue--threat-feed-staleness
- Authority Context: Security — silent detection gap
Acceptance Criteria
Definition of Done
Description
Distinguish an empty threat feed from a broken one.
Problem Statement
In
anomaly-detector/src/audit-guard/threat-feed-fetcher.ts: when no feed URL is configured,updateFeedlogs oneconsole.warnand returns (lines 14-17).isThreat()then returnsfalseforever, soTHREAT_FEED_MATCHnever fires and nothing distinguishes "no threats" from "no feed".When all fetches fail, the code keeps
this.threatAddressesindefinitely —lastUpdatedis recorded but never checked, so a feed broken for weeks keeps serving stale data while the alert text claims "matches active blocklist in threat feed".Finally,
setMockThreats(line 71) is a public method on the production class that makesisThreatconsult only the mock set — so a stray call disables real matching entirely.Proposed Changes
isStale(maxAgeMs)) and raise a dedicated alert when the feed is unconfigured or older than a configured max agesetMockThreats/clearMockThreatsbehind a test-only subclass or constructor-injected source rather than a public production methodTechnical Implementation Scaffolding
Acceptance Criteria
THREAT_FEED_URL(S)set, a run emits a distinguishable "feed unconfigured" alert, not silencelastUpdatedolder than the max age,isThreatresults are flagged stale and an alert is raisedisThreatcannot be neutered by production code pathsDefinition of Done