code wiki / (root) / nx_redact_lib.nx

nx_redact_lib.nx source

↩ module page · 112 lines · 4497 B

1// nx_redact_lib.nx -- REDACTION COMPLETENESS verifier for e-discovery production. Deterministic, byte-exact. 2// 3// The content-level companion to nx_ediscovery (which is the ALLOW-LIST: only affirmatively-reviewed, 4// responsive documents may be produced). This is the other half: even a responsive document must have its 5// sensitive content redacted before it leaves the door. Where mainstream PII tools FLAG a hit for a human to 6// eyeball, this is FAIL-CLOSED -- a document is not producible while any detectable SSN or privilege marker 7// remains, full stop. Deterministic byte scanning, no LLM, no probability. 8// 9// The SSN detector is PRECISE, not greedy: it matches ddd-dd-dddd only at a real number boundary, so it does 10// NOT false-fire on a wrong grouping (dd-dd-dddd) or on an SSN-shaped run embedded in a longer digit string 11// (over-blocking a clean doc is safe but annoying; the boundary checks keep it honest). Missing a real SSN 12// (a false NEGATIVE) is the dangerous case and is what the byte-exact pattern forecloses. 13// 14// SCALE ENVELOPE (declared): substring is naive O(len*needle); KMP is the speed rung for large productions. 15// license_tier: ORIGINAL No hw writes (Rule 26). LIB. 16 17const REDACT_NOT_FOUND: i64 = 0 - 1 18 19func redact_len(s: *u8) -> i64 { 20 var n: i64 = 0 21 while s[n] != (0 as u8) { n = n + 1 } 22 return n 23} 24 25func redact_is_digit(c: u8) -> i64 { 26 if (c as i64) < 48 { return 0 } 27 if (c as i64) > 57 { return 0 } 28 return 1 29} 30 31// is there a precise SSN (ddd-dd-dddd) starting at index i, at a non-digit boundary on both sides? 32func redact_is_ssn_at(doc: *u8, i: i64, len: i64) -> i64 { 33 if i + 11 > len { return 0 } 34 if i > 0 { 35 if redact_is_digit(doc[i - 1]) == 1 { return 0 } 36 } 37 if redact_is_digit(doc[i]) == 0 { return 0 } 38 if redact_is_digit(doc[i + 1]) == 0 { return 0 } 39 if redact_is_digit(doc[i + 2]) == 0 { return 0 } 40 if doc[i + 3] != (45 as u8) { return 0 } 41 if redact_is_digit(doc[i + 4]) == 0 { return 0 } 42 if redact_is_digit(doc[i + 5]) == 0 { return 0 } 43 if doc[i + 6] != (45 as u8) { return 0 } 44 if redact_is_digit(doc[i + 7]) == 0 { return 0 } 45 if redact_is_digit(doc[i + 8]) == 0 { return 0 } 46 if redact_is_digit(doc[i + 9]) == 0 { return 0 } 47 if redact_is_digit(doc[i + 10]) == 0 { return 0 } 48 if i + 11 < len { 49 if redact_is_digit(doc[i + 11]) == 1 { return 0 } 50 } 51 return 1 52} 53 54// first SSN index or REDACT_NOT_FOUND. 55func redact_find_ssn(doc: *u8, len: i64) -> i64 { 56 var i: i64 = 0 57 var found: i64 = REDACT_NOT_FOUND 58 while i < len { 59 if found == REDACT_NOT_FOUND { 60 if redact_is_ssn_at(doc, i, len) == 1 { found = i } 61 } 62 i = i + 1 63 } 64 return found 65} 66 67// count of SSN occurrences (non-overlapping by construction of the boundary checks). 68func redact_count_ssn(doc: *u8, len: i64) -> i64 { 69 var i: i64 = 0 70 var c: i64 = 0 71 while i < len { 72 if redact_is_ssn_at(doc, i, len) == 1 { c = c + 1 } 73 i = i + 1 74 } 75 return c 76} 77 78// naive substring: first index of `needle` in `doc`, or REDACT_NOT_FOUND. An empty needle is NOT a match 79// (closes the substring-of-everything hole). 80func redact_contains(doc: *u8, len: i64, needle: *u8, nlen: i64) -> i64 { 81 if nlen == 0 { return REDACT_NOT_FOUND } 82 if nlen > len { return REDACT_NOT_FOUND } 83 var i: i64 = 0 84 var found: i64 = REDACT_NOT_FOUND 85 while i <= len - nlen { 86 if found == REDACT_NOT_FOUND { 87 var j: i64 = 0 88 var hit: i64 = 1 89 while j < nlen { 90 if doc[i + j] != needle[j] { hit = 0 } 91 j = j + 1 92 } 93 if hit == 1 { found = i } 94 } 95 i = i + 1 96 } 97 return found 98} 99 100// *is the document clean enough to leave the door? No SSN AND no privilege marker present. 101func redact_clean_for_production(doc: *u8, len: i64, marker: *u8, mlen: i64) -> i64 { 102 if redact_find_ssn(doc, len) != REDACT_NOT_FOUND { return 0 } 103 if redact_contains(doc, len, marker, mlen) != REDACT_NOT_FOUND { return 0 } 104 return 1 105} 106 107// *FAIL-CLOSED production decision: producible ONLY if the document was reviewed AND is redaction-clean. 108// Either gate alone is insufficient -- an unreviewed clean doc and a reviewed dirty doc are both blocked. 109func redact_production_ok(doc: *u8, len: i64, reviewed: i64, marker: *u8, mlen: i64) -> i64 { 110 if reviewed == 0 { return 0 } 111 return redact_clean_for_production(doc, len, marker, mlen) 112}