nx_privacy_lib.nx
buildroot/runtime/nx_privacy_lib.nx
about
nx_privacy_lib.nx -- PRIVACY COMPLIANCE: GDPR / CCPA subject-request clocks and breach notification.
The OneTrust-class category we had at zero. Two clocks decide almost all exposure here, and both are
routinely started from the wrong event.
u2605THE 72-HOUR CLOCK RUNS FROM AWARENESS, NOT FROM THE BREACH (GDPR Art 33(1)). A controller that
discovers on day 30 an intrusion that began on day 1 has 72 hours from DAY 30. Teams anchor to the
incident date, conclude they are already hopelessly late, and then delay further -- or anchor to the
forensic-conclusion date and report far too late. Awareness is the anchor; the incident date is
evidence, not a deadline input.
u2605AN EXTENSION MUST BE CLAIMED INSIDE THE ORIGINAL WINDOW. GDPR Art 12(3) allows a two-month extension
on a subject access request, and CCPA allows a further 45 days -- but only if the data subject is
informed WITHIN the original period. Notice given on day 31 of a 30-day window does not buy 60 more
days; it is simply a late response. Encoded so a late claim can never extend anything.
u2605ENCRYPTION IS A DEFENCE TO SUBJECT NOTIFICATION, NOT TO REGULATOR NOTIFICATION (Art 34(3)(a) vs
Art 33). Rendering the data unintelligible excuses telling the individuals; it does NOT excuse telling
the supervisory authority. Conflating the two is a real and expensive error, so they are separate.
All periods are DATA (rule 11). Time is in HOURS for the breach clock and DAYS for request clocks --
deliberately different units because the statutes use different units, and silently converting is how
72 hours becomes "3 business days".
STRUCTURE: pure decision core, zero I/O. license_tier: ORIGINAL LIB.
dependencies 1 imports · 2 importers
imports: nx_matter_lib.nx
imported by: nx_legal_svc.nxnx_privacy_gate.nx
structs
| none |
consts
| 27 | const PRV_UNSET: i64 = 0 - 2000000002 |
| 28 | const PRV_UNKNOWN: i64 = 0 - 1 |
| 30 | const PRV_ONTIME: i64 = 0 |
| 31 | const PRV_LATE: i64 = 1 |
| 33 | const PRV_GDPR_DSAR_DAYS: i64 = 30 |
| 34 | const PRV_GDPR_EXT_DAYS: i64 = 60 |
| 35 | const PRV_CCPA_DSAR_DAYS: i64 = 45 |
| 36 | const PRV_CCPA_EXT_DAYS: i64 = 45 |
| 37 | const PRV_BREACH_HOURS: i64 = 72 |
functions
| 39 | func prv_is1(v: i64) -> i64 |
| 46 | func prv_deadline_pure(received: i64, base_days: i64, ext_claimed: i64, ext_notice_day: i64, ext_days: i64) -> i64 |
| 55 | func prv_gdpr_dsar_pure(received: i64, ext_claimed: i64, ext_notice_day: i64) -> i64 |
| 59 | func prv_ccpa_dsar_pure(received: i64, ext_claimed: i64, ext_notice_day: i64) -> i64 |
| 64 | func prv_response_status_pure(deadline: i64, responded: i64) -> i64 |
| 71 | func prv_days_remaining_pure(deadline: i64, asof: i64) -> i64 called by 1: main |
| 81 | func prv_breach_deadline_pure(aware_hour: i64) -> i64 |
| 86 | func prv_breach_status_pure(aware_hour: i64, reported_hour: i64) -> i64 |
| 96 | func prv_notify_authority_pure(is_personal_data: i64, risk_to_rights: i64) -> i64 |
| 104 | func prv_notify_subjects_pure(is_personal_data: i64, high_risk: i64, encrypted: i64) -> i64 |
| 112 | func prv_exposure_pure(late_responses: i64, late_breaches: i64, unknown: i64) -> i64 called by 1: main |
| 116 | func prv_status_label(s: i64, out: *u8) -> i64 |