Skip to content

Incidents

An incident is a device, a time window, a set of model results, and the evidence behind them. It is not a notification and not a verdict.

Field Meaning
Title Short, generated from the models that fired
Severity info, low, medium, high, critical
Score 0–100, with its history over time
Status open, investigating, resolved, false_positive
Devices The devices involved
Models Which detection models produced it
Evidence The source records, in order
Workflow history Every status change, with actor, comment and sequence
Revision Incremented on every write

Each model result links to the specific persisted analysis result that produced it, with its own reason and evidence identifiers. You can always get from “this incident exists” to “because this model saw these records at this time”.

Raw payloads have a retention window. Observation evidence stays resolvable for 90 days, past the payload’s own expiry, so an incident from last month is still explicable even after the underlying raw record has aged out.

If an evidence identifier cannot be resolved — its source record is unavailable, or its record kind has no public form — it is listed separately as unresolved. It is never silently relabelled as model output, because “the model said so” and “we no longer have the record” are very different statements.

Changing status requires the analyst role, takes a comment, and appends to the history. Four statuses, and the honest ones matter most:

  • investigating — someone is looking.
  • resolved — dealt with.
  • false_positive — the detection was wrong. This is the feedback that makes the models better, and it is worth spending the thirty seconds on.

If enabled, an analyst can be asked to explain an incident. It returns a title, a narrative, hypotheses with confidence values, recommendations, and the list of evidence identifiers it was given — plus the model name and prompt version that produced it, so an odd answer is traceable rather than mysterious.

Its state is always visible: not_requested, queued, running, complete, failed, provider_disabled, or budget_exhausted.

Four hard rules:

  1. Off by default. It requires an explicit provider, an explicit model name, a nonzero daily budget and explicit token rates. Nyxtrace contains no guessed prices.
  2. Metadata only. Addresses, domains, ports, times, scores. No payloads, no credentials, no whole log files.
  3. Read only. It can never approve a proposal, change a threshold, activate a model or execute an action.
  4. A disabled provider or an exhausted budget is an explicit error. There is no automatic paid fallback and no hidden retry.

Network data is treated as attacker-controlled input: host names, user agents and DNS names go into the request as data, never as instructions.

There is also a deep mode. In this version it is a workflow label that uses the same bounded request as the standard mode — it does not enable extra tools, retries or spend. It is documented that way rather than implying more.

A local summary of new devices and active incidents is available for a given date. It is local metadata only — retrieving it does not send a message anywhere. Sending is a sink connector’s job.