---
title: "Start every reporting clock from one · Agent Wranglers"
url: https://agentwranglers.se/playbook/compliance/breaches-and-reporting/reporting-clocks
updated: 2026-10-20
licence: "All rights reserved"
---

# Start every reporting clock from one moment

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Breaches and reporting](https://agentwranglers.se/playbook/compliance/breaches-and-reporting)
- Rule: Record the moment you became aware of an incident, and compute every legal and contract deadline from it in code, the moment the incident opens.
- How: One incident can start several clocks at once. GDPR Article 33 gives 72 hours to tell the supervisory authority about a personal data breach. NIS2 Article 23 asks for an early warning within 24 hours and a notification within 72 hours. A final report follows one month after the notification. The Cyber Resilience Act uses 24 hours and 72 hours as well, for products. US state laws count in days, as in [US breach notice laws](https://agentwranglers.se/playbook/compliance/us-state-privacy-laws/us-breach-notice-laws). Add the deadlines in your customer contracts. The [breach plan](https://agentwranglers.se/playbook/website/privacy/breach-plan) and [security incidents](https://agentwranglers.se/playbook/operations/incidents/security-incidents) rules cover the rest of the response.
- Check: A unit test opens an incident with awareness at `2026-10-20T09:00Z` and the GDPR and NIS2 flags set. The tool shows the NIS2 early warning due at `2026-10-21T09:00Z` and the GDPR report due at `2026-10-23T09:00Z`.

Example:

```js
const HOUR_MS = 3_600_000;
const CLOCKS = {
  gdpr: [{ step: 'report to supervisory authority', hours: 72 }],
  nis2: [{ step: 'early warning', hours: 24 }, { step: 'incident notification', hours: 72 }, { step: 'final report, at the latest', hours: 72 + 30 * 24 }],
  cra: [{ step: 'early warning', hours: 24 }, { step: 'notification', hours: 72 }],
};

export const reportingDeadlines = (awareAt, laws, contractHours = []) => [
  ...laws.flatMap(law => CLOCKS[law].map(({ step, hours }) => ({ law, step, due: new Date(awareAt.getTime() + hours * HOUR_MS) }))),
  ...contractHours.map(({ customer, hours }) => ({ law: 'contract', step: `notify ${customer}`, due: new Date(awareAt.getTime() + hours * HOUR_MS) })),
].sort((a, b) => a.due - b.due);
```

```python
from datetime import datetime, timedelta

CLOCKS = {
    "gdpr": [("report to supervisory authority", 72)],
    "nis2": [("early warning", 24), ("incident notification", 72), ("final report, at the latest", 72 + 30 * 24)],
    "cra": [("early warning", 24), ("notification", 72)],
}

def reporting_deadlines(aware_at: datetime, laws: list[str], contract_hours: list[tuple[str, int]] = ()) -> list[dict]:
    steps = [{"law": law, "step": step, "due": aware_at + timedelta(hours=hours)}
             for law in laws for step, hours in CLOCKS[law]]
    steps += [{"law": "contract", "step": f"notify {customer}", "due": aware_at + timedelta(hours=hours)}
              for customer, hours in contract_hours]
    return sorted(steps, key=lambda s: s["due"])
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers compliance playbook: https://agentwranglers.se/playbook/compliance/breaches-and-reporting/reporting-clocks`.

- Next: [Log every breach with its decision](https://agentwranglers.se/playbook/compliance/breaches-and-reporting/breach-register)
- [Breaches and reporting](https://agentwranglers.se/playbook/compliance/breaches-and-reporting)
