17318d4225
An XDR incident is an aggregate; the SOC works the detections under it. The alerts endpoint was already exposed as a read command, but nothing could feed an alert rule with it — no results path, no dedup key, no watermark, no mapper, no incident type. All five are here now, so an alert rule can be pointed at reply.alerts the same way it is pointed at reply.incidents. get_alerts pages past the API's 100-results-per-call ceiling: an alert feed carries far more than a hundred detections between two polls, and whatever a single page leaves behind is never fetched again, because the next run's watermark has already moved past it. On an incremental fetch it also sorts oldest first, so a window larger than the limit drops its most recent alerts — the only ones the next poll can still see — and says so via `truncated`. Two fixes to the incident side while in the same files: - The severity expression compared strings, which the mapping engine cannot do (it reads numeric comparisons only). Every test read as false, so every ingested incident silently took the alert rule's default severity. The bare field works: Riposte maps critical/high/medium/low onto 1-5 itself. - The incident mapper carried no `time`, so the detection anchor was missing and MTTD stayed empty for the whole feed. creation_time fills it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>