Threat-intel signal ingest — converts a CVE + affected-asset + claim payload into a queued engagement-scope row for the validation pipeline.
signal.json they have on hand.{OUTPUT_DIR}/inbox/ on a cron (default every 15 minutes) and processes any new signal files it finds.tools/ti-ingest.py --in <path-or-stdin>.signal_id, cve (one or more), assets (one or more), claim. Optional: confidence, source, references.tools/nvd-lookup.py <CVE> and attach {score, severity, cwe} to the row.(asset, cve) pair already exists in queue/scope-*.json. Re-queue only if the prior row's status is REJECTED AND the TI signal carries a higher confidence than the last attempt.(asset, cve) pair at queue/scope-{ts}-{asset_id}-{cve}.json. The Validation Run task picks these up.{OUTPUT_DIR}/
inbox/
signal-{ts}.json # raw payload, kept for audit
queue/
scope-{ts}-{asset}-{cve}.json
{
"scope_id": "scope-20260513-asset42-CVE-2024-12345",
"signal_id": "ti-2026-0042",
"asset": {"id": "asset42", "url": "https://app.example.com", "tier": "revenue"},
"cve": "CVE-2024-12345",
"nvd": {"score": 9.8, "severity": "CRITICAL", "cwe": "CWE-79"},
"claim": "Reflected XSS via search parameter",
"confidence": "high",
"source": "vendor-advisory",
"references": ["https://..."],
"queued_at": "2026-05-13T10:00:00Z",
"status": "queued"
}
inbox/ before any transformation.nvd-lookup errors, write the row with nvd: null and nvd_error: "..."; do not drop the signal.asset.id against artifacts/org-surface.json (from Org Recon Refresh task). Unknown assets get a row but flagged unknown_asset: true so the validator skips them.reference/ingest-schema.md — full input/output JSON schemas.