Live test against abuse.ch revealed two issues with the stage-19 wiring:
- ThreatFox returns `ioc` (not `ioc_value`) and `first_seen` (not
`first_seen_utc`) — older field names from stale docs. Parser now reads
the real names and falls back to the old aliases defensively. Also
captures `malware_malpedia` (per-family writeup URL) and
`threat_type_desc` for richer downstream prose.
- MalwareBazaar's API expects form-encoded bodies, unlike ThreatFox's
JSON. Extended _http with form_body=; MB fetcher switched to it.
Verified live: 10 ThreatFox cases landed with mixed botnet/malware
classification (4/6 split from threat_type signal — first real
incident-type diversity from a single feed). 10 MalwareBazaar cases
landed with sha256+sha1 hash observables and exe/file_type metadata.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
38 tests covering the pure worker-line logic: Classifyline rules, Routeline
TLP/country/incident-type gates, Sealine seal/unseal round-trip, Proofline
confidence scoring, Mapline CVEResolver escalation, Trainline dataset
well-posedness (the v1/v3 input-signal bugs are now regression-guarded), and
the Scoutline feed parsers. pytest added as a dev extra.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>