---
title: "Incidents"
description: "Keep one record of an incident, with the jobs, audit entries, kill switches and egress denials that tell what happened, deadline clocks for the regimes you say apply, reminders before each deadline, and a timeline that verifies offline."
canonical_url: "https://docs.oz0.ai/govern/incidents"
---
# Incidents

> Keep one record of an incident, with the jobs, audit entries, kill switches and egress denials that tell what happened, deadline clocks for the regimes you say apply, reminders before each deadline, and a timeline that verifies offline.

For: tenant admins and governance reviewers.

Create an incident to record an agent's unwanted action and your organisation's response. The record links the jobs and audit entries that show what happened, the kill switch used, the owner, deadlines and actions taken. The [audit trail](https://docs.oz0.ai/govern/audit-trail) records every change with its actor and reason, so the record can support a response to an authority under a deadline.

<note>

The clocks are a tool, not legal advice. Which regimes apply to you, what starts each clock and how a month is counted are for your lawyers to say. The built-in regimes below are **defaults to be confirmed**; change them to what your lawyers tell you. A stage marked notified records what you entered in OZ: it does not say that a notification was made, accepted or sufficient.

</note>

## Open one

```bash [Terminal]
oz0 incident open --title "Upload to a paste site" --severity high \
  --regime gdpr --regime nis2 --aware-at 2026-10-12T08:30:00Z \
  --owner team:security --job job-9eae… --reason "egress denial on a support agent's job"
```

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      What it is
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Title
    </td>
    
    <td>
      One line, at most 200 characters. Keep personal data out of it; notes are for details
    </td>
  </tr>
  
  <tr>
    <td>
      Severity
    </td>
    
    <td>
      One of your tenant's severities (<code>
        low
      </code>
      
      , <code>
        medium
      </code>
      
      , <code>
        high
      </code>
      
      , <code>
        critical
      </code>
      
       unless you set others)
    </td>
  </tr>
  
  <tr>
    <td>
      Regimes
    </td>
    
    <td>
      The regimes you say apply; add or remove them later with <code>
        oz0 incident clock
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Aware
    </td>
    
    <td>
      When you became aware of it (default now). <code>
        --aware-at
      </code>
      
       takes RFC 3339 or how long ago, such as <code>
        2h
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Classified
    </td>
    
    <td>
      When it was classified, for regimes that count from classification (<code>
        --classified-at
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      Owner
    </td>
    
    <td>
      <code>
        person:&lt;account>
      </code>
      
       or <code>
        team:&lt;name>
      </code>
      
       of the tenant: who is reminded besides the tenant's admins
    </td>
  </tr>
</tbody>
</table>

In the console, *Govern*, *Incidents* lists those opened in the [period](https://docs.oz0.ai/getting-started/web-ui/navigation#periods-filters-and-pages) you pick (the last 30 days unless you pick another, so an older incident that is still open shows with a longer period), filtered by state, with their next deadline, and opens each record, which you can print from the browser.

## Clocks

Each regime that applies has stages, and each stage a deadline: its span after what it counts from. The record shows each one with the time left:

```bash [Terminal]
oz0 incident show inc-01a1300e-53f3-7dbc-bf41-c7f700105376
```

```text [Output]
REGIME                         STAGE                 COUNTS FROM  DEADLINE          STATE
gdpr (to be confirmed)   notification (72h)    awareness    2026-10-15 10:30  70h 12m left
nis2 (to be confirmed)   early_warning (24h)   awareness    2026-10-13 10:30  22h 12m left
dora (to be confirmed)   initial (4h)          classification  -              waiting for classification
```

The built-in regimes, as data your tenant can change:

<table>
<thead>
  <tr>
    <th>
      Regime
    </th>
    
    <th>
      Stages
    </th>
    
    <th>
      Counts from
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        gdpr
      </code>
      
       (GDPR Art. 33)
    </td>
    
    <td>
      <code>
        notification
      </code>
      
       72 hours
    </td>
    
    <td>
      awareness
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        nis2
      </code>
      
       (NIS2 Art. 23)
    </td>
    
    <td>
      <code>
        early_warning
      </code>
      
       24 hours, <code>
        notification
      </code>
      
       72 hours, <code>
        final_report
      </code>
      
       1 month
    </td>
    
    <td>
      awareness
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        dora
      </code>
      
       (DORA Art. 19)
    </td>
    
    <td>
      <code>
        initial
      </code>
      
       4 hours, <code>
        intermediate
      </code>
      
       72 hours, <code>
        final_report
      </code>
      
       1 month
    </td>
    
    <td>
      classification
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ai_act_73
      </code>
      
       (AI Act Art. 73)
    </td>
    
    <td>
      <code>
        report
      </code>
      
       15 days
    </td>
    
    <td>
      awareness
    </td>
  </tr>
</tbody>
</table>

Every one is marked *to be confirmed*. A month is a calendar month in UTC. A stage may also count from when an earlier stage of its regime was marked notified (`"from": "stage:notification"`), if that is how your lawyers read it.

A clock is *waiting* while what it counts from is unknown, *running*, *due soon* in the last quarter of its window, *missed* after its deadline, and *marked* (or *marked late*) once someone marks the stage:

```bash [Terminal]
oz0 incident notify inc-01a1… gdpr notification --reference "IMY-2026-17" --reason "sent through the authority's form"
oz0 incident notify inc-01a1… gdpr notification --undo --reason "entered by mistake"
```

### Your own regimes

```bash [Terminal]
oz0 incident regimes                      # what applies now
oz0 incident regimes --json > regimes.json
oz0 incident regimes --file regimes.json --reason "per our DPO, case 2026/41"
oz0 incident regimes --defaults --reason "back to the built-in ones"
```

```json [regimes.json]
{
  "regimes": [
    {"name": "gdpr", "label": "GDPR Art. 33", "basis": "awareness", "stages": [{"name": "notification", "after": "72h"}]},
    {"name": "sector", "label": "Our sector's rule", "basis": "classification",
     "stages": [{"name": "first", "after": "24h"}, {"name": "final", "after": "1mo", "from": "stage:first"}]}
  ],
  "severities": ["low", "medium", "high", "critical"],
  "remind_before": ["24h", "4h", "1h"],
  "classify_within": "24h"
}
```

Spans are a whole number and `m`, `h`, `d` or `mo`, from one minute to twelve months; at most 16 regimes of 8 stages each. Your regimes are a [governance setting](https://docs.oz0.ai/govern/reviewed-changes#four-eyes-for-governance-changes) (`incident_regimes`): removing a regime or a stage, giving a stage longer, counting from a later moment, dropping a reminder, or dropping or lengthening `classify_within` loosens it, so it takes a reason and, with four eyes on, a second admin. An open incident keeps the regimes it was given; editing the defaults never moves its deadlines.

A regime that counts from classification, such as `dora`, waits until someone records when the incident was classified (`oz0 incident clock inc-01a1… --classified-at now --reason "..."`). So that a forgotten classification does not stay silent, `classify_within` (24 hours by default; leave it out to turn the warning off) is how long an open incident may wait unclassified after awareness before `oz0 doctor` warns in its `incident classification` row. It is a prompt your tenant sets, not a legal deadline: whether such a regime also has a limit counted from awareness is a question for your lawyers (*to be confirmed*).

## Reminders

Before each deadline of a stage not yet marked, the incident's owner (the person, or the team's members) and the tenant's admins are reminded by email, at each of the tenant's `remind_before` points that falls inside the stage's window (24 hours, 4 hours and 1 hour before, by default) and once more when the deadline passes. Only the latest point that is due is sent, so an incident recorded late gets one reminder, not a burst. [Notification rules](https://docs.oz0.ai/admin/notifications) that name the event `incident.deadline` reach their webhooks and chat channels too.

Reminders go out through the email relay and webhooks your operators and admins already configured; nothing new leaves the cluster. A reminder carries the incident's ID, title, severity, the regime and stage, the deadline and the time left; no figure about people. Each one is in the audit trail as `incident.reminder` with how many deliveries it made.

`oz0 doctor` fails its `incident_deadline_missed` row while a deadline has passed unmarked, warns in `incident deadlines` while one is near, and warns in `incident classification` about an incident left unclassified (above). These rows are computed from the open incidents each time; nothing needs to be resolved by hand.

## Links

```bash [Terminal]
oz0 incident link inc-01a1… job job-9eae…                       # the job is tagged incident:<id>
oz0 incident link inc-01a1… egress --job job-9eae…               # every egress denial of the job
oz0 incident link inc-01a1… egress seq:166                       # one, by its audit entry
oz0 incident link inc-01a1… kill kill-01a1000c-299b-…            # a kill switch
oz0 incident link inc-01a1… receipt rcpt-01a1…                   # a kill or revocation receipt
oz0 incident link inc-01a1… audit --since 2026-10-12T08:00:00Z --until 2026-10-12T10:00:00Z
oz0 incident link inc-01a1… audit --from-seq 120 --to-seq 180
oz0 incident link inc-01a1… finding f-7c1d…                      # an eval finding
oz0 incident link inc-01a1… incident inc-01a0…                   # a related incident
oz0 incident unlink inc-01a1… job job-9eae… --reason "wrong job"
```

Each item is checked in the incident's tenant when you link it and keeps its own time and a one-line summary for the timeline. An audit range holds at most 50,000 entries; egress denials by job or time at most 100 at once; an incident at most 500 links. Every link and unlink takes a reason. `oz0 job search tag:incident:<id>` finds the linked jobs.

## Notes

```bash [Terminal]
oz0 incident note inc-01a1… "Customer informed by phone at 10:05."
oz0 incident note inc-01a1… --file notes.txt
```

Notes are free text, at most 8 KiB each and 200 per incident. They are content: only people with the [content permission](https://docs.oz0.ai/admin/tenants) read them, in the record and in the export. A note's audit entry names its ID and length, never its text.

## The timeline export

```bash [Terminal]
oz0 incident export inc-01a1… --out timeline.json --html timeline.html
oz0 incident verify timeline.json --key 1d06721c68a4f066…    # the fingerprint oz0 audit key prints
```

A timeline exported without the content permission holds [blinded entries](https://docs.oz0.ai/govern/audit-trail/records#what-a-job-read-or-wrote), which only its signature covers, so `incident verify` fails on it without `--key` unless `--unpinned` says that showing the file is whole is enough.

`timeline.json` (format `oz0-incident-timeline/1`) holds the record, its clocks at the export, every link with its time and summary, the notes (with the content permission), a timeline of everything in time order (the incident's own audit entries, which carry their `seq`, keep their chain's order: one whose writer's clock had stepped back shows its own time and still follows the entry before it), and the audit entries of its linked ranges, its own entries and each linked item's entries, as whole pieces of the tenant's hash chain.

A checkpoint signed with the [audit key](https://docs.oz0.ai/govern/audit-trail/evidence-bundles#the-audit-key-and-the-gateway-keys) names each piece's first link and last entry, the chain's head, and the SHA-256 of the rest of the document.

`oz0 incident verify` checks all of it without the cluster: the signature (pinned with `--key`), that nothing in the document changed, and every entry's hashes and links.

Without the content permission an entry's private part is left out and its hash kept, so the export still verifies.

`timeline.html` is one printable page made from the same document; print it from your browser. It is a rendering, not the evidence: hand over the JSON with it. There is no regulator template in it; the export is the input to whatever form your authority asks for. Each export is in the audit trail as `incident.export`.

The incident's records travel with the tenant's other tables in the tenant export (`oz0 tenant export`); their notes only with `--content`.

## Who may

The tenant's admins open, change, link, mark, close and export incidents, and so do operator certificates, which act as cluster admins on every admin API. Once roles are data, reading takes `incidents.read` (the auditor and the privacy officer have it) and changing `incidents.manage` (the privacy officer has it); changing the regimes takes `governance.write`. Nodes, apps' API keys, scoped keys and other tenants' people are refused.

## Audit actions

<table>
<thead>
  <tr>
    <th>
      Action
    </th>
    
    <th>
      What it records
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        incident.open
      </code>
    </td>
    
    <td>
      the title's length, severity, regimes, moments, owner and reason; the title itself in the entry's private part
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        incident.update
      </code>
    </td>
    
    <td>
      what changed (severity, owner, awareness, classification, regimes; a new title as for <code>
        incident.open
      </code>
      
      ) and why
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        incident.link
      </code>
      
      , <code>
        incident.unlink
      </code>
    </td>
    
    <td>
      the kind and references, and why
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        incident.notified
      </code>
    </td>
    
    <td>
      a stage marked (when, reference) or taken back, and why
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        incident.note
      </code>
    </td>
    
    <td>
      a note's ID and length
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        incident.close
      </code>
      
      , <code>
        incident.reopen
      </code>
    </td>
    
    <td>
      why
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        incident.reminder
      </code>
    </td>
    
    <td>
      a reminder sent by the edge: the stage, its deadline, the phase and how many deliveries
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        incident.export
      </code>
    </td>
    
    <td>
      a timeline exported, and whether with content
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tenant.incident_regimes
      </code>
    </td>
    
    <td>
      the tenant's regimes changed
    </td>
  </tr>
</tbody>
</table>


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
