Guard · AI incident response

AI Incident Response

A detection is a row. A case is something somebody works. AI Incident Response is the loop between the two: a signal becomes a case with a lifecycle, an owner and a clock your team sets; a playbook runs the containment verbs that already ship; and what comes out of it becomes a lesson and then a guard that warns before the next one. It does not detect prompt injection and it does not respond on its own. It removes the typing between a decision and its execution, and leaves the decision with a person.

Why a case and not an alert

Security tooling is good at producing rows. The gap this closes is between a row and a thing a person can act on. A case has a lifecycle, an owner, a deadline, a timeline and an outcome. It survives a restart, it can be argued with, and it is the object every later number is computed from.

  • It opens by rule, never by judgment. A queue filled by clicking is the queue nobody reads. Cases open from the durable findings store when a finding meets the rule, and a pass that finds nothing reports "no finding met the rule" as a real answer.
  • Its title is built from a rule and a place. Never from matched text. That is what lets a case title travel into a ticket, a chat channel and a teammate's screen without carrying evidence with it.
  • A name never travels without its attribution band. When a case names a developer it always shows the confidence that produced the name. A label without its band presents an inference as a fact.

The lifecycle

Seven states, and the moves between them are checked. Reopening is always allowed from a closed state, because a wrong verdict has to be correctable: a case closed as a false positive that turns out to be real must not need a second case to say so.

  a finding meets the rule
            |
            v
   open ---> acknowledged ---> investigating ---> contained ---> resolved
     |            |                  |                |             |
     |            |                  |                |             +--> reopen
     +------------+------------------+----------------+
                  |
                  +--> false_positive   (not real; disputes its pattern)
                  +--> duplicate        (already tracked elsewhere)

false_positive is not an inert label. It counts as a dispute against the pattern the finding belongs to, and a pattern disputed more than half the time is demoted out of armed. That is deliberate: the queue's own verdicts are the only thing that stops a noisy rule staying loud for ever.

The clock your team sets

Each severity has a target: how long a case of that severity has before it is late. A team that sets nothing gets sensible defaults; a team that sets one severity overrides only that one.

  • The deadline is recomputed, not stamped once. It comes from the case's open time plus your team's current hours, on every render. Shortening your critical target re-times the cases you already have, which is exactly the moment you expect the new number to apply.
  • A breach is announced once. Not once per hourly sweep. It goes to your connected sinks through the same path a case-opened notice does.
  • A resolved case is measured against when it resolved. Never against now, or every closed case drifts further past target for ever and a queue being worked well reads as one getting worse.
Send a class where your team actually reads it
You can route each class of case to its own sinks, so security cases go to the security channel and operations cases go somewhere else. Routing narrows and never drops: a class you have not configured, and a class routed only to sinks that are no longer connected, both go to every connected sink. An alert you configured and then silently never received would be worse than one that went somewhere unexpected.

Playbooks: the response, run once

A playbook is a named sequence over containment verbs that already ship. It introduces no new way to contain anything: the verbs are the alphabet, a playbook is a word. A playbook that needs a new verb is a request for a new verb, filed as one and reviewed as one.

  • Dry-run first. The dry run mutates nothing and walks exactly the list the real run walks.
  • Every step is recorded, including the ones that did not work. Actor, verb, arguments, result and duration. A failed step stops the run and records why. A response record that only holds successes cannot be used to measure a response.
  • A destructive step needs two independent switches. A named human promotion for that repo and verb, and an armed hook on the machine. Neither implies the other, and running a playbook is not a promotion. A blocked step is refused and recorded, never silently skipped.
This is the part worth being slow about
The whole value of a playbook is that it goes faster, and going faster is exactly how an automated response takes a team's own build down. The product never promotes a verb for you, and there is no setting that makes it.

The fix arrives as a proposal

A worked case drafts a remediation: a title, a body naming the rule and the place, and the guard it would arm. You open it as a pull request. It is a proposal, unreviewed until you review it, and the section that matters is deliberately left for you to write.

The draft never contains matched text, and a case with no attribution still produces one. Waiting for confident attribution before offering a fix would mean the cases hardest to attribute get the least help.

Where the evidence stays

Evidence never leaves the machine that observed it. This is the boundary the whole program is built around, and it is enforced by refusing rather than by cleaning.

  • Your team's hosted view gets labels, counts and hashes. A rule, a place, a severity, how many times. Never an excerpt, a prompt, a transcript, a file path or a session id.
  • A payload carrying evidence is refused, not sanitised. The hosted ingest answers 422 and stores nothing. Quietly cleaning it would hide the bug in whatever sent it, and that bug would keep happening.
  • A ticket carries a link and a label. When a case opens a Jira or Linear issue it carries the bounded title and a reference back to the case, so closing the issue closes the case. It never carries what the detector matched.

What this does not claim

Four things, stated here because they are easier to assume than to check.

  • It does not do autonomous incident response. A playbook removes the typing between a decision and its execution. The decision stays a person's.
  • It does not detect prompt injection. That has been the position since the first phase and nothing here changes it.
  • A drafted fix is not a verified fix. It is a proposal, exactly like the routing proposals it is modeled on.
  • An SLA number is your promise to yourself. It is not a benchmark against other teams, and nothing here ranks you against anybody.

Related

  • Security: the trust boundaries and the live footgun scan the findings store is fed from.
  • Incidents ledger: the hosted list of prevented incidents and what each one saved.
  • Signal: the raw detections underneath every case.
  • Rules: the rule engine a guard is armed in.

Last updated