Breaches and reporting Required
Start every reporting clock from one moment
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 to do it
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. Add the deadlines in your customer contracts. The breach plan and security incidents rules cover the rest of the response.
Example
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);
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"])
How to 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.
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.