nx_redact_gate.nx source
↩ module page · 100 lines · 5119 B
1// nx_redact_gate.nx -- REDACTION COMPLETENESS GATE.
2// Proves precise SSN detection (and the boundary precision that avoids false positives on a wrong grouping,
3// a trailing extra digit, or an SSN-shaped run embedded after digits), privilege-marker scanning, the empty-
4// needle hole being closed, and the FAIL-CLOSED production decision (producible only if reviewed AND clean;
5// a reviewed-but-dirty doc and an unreviewed-clean doc are both blocked). license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
6
7import "nx_redact_lib.nx"
8import "nx_matter_lib.nx"
9
10func rg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
11func rg_putn(v: i64) -> i64 {
12 let t: *u8 = sys_mmap(32)
13 var o: i64 = 0
14 var m: i64 = v
15 if m < 0 { t[o] = 45 as u8; o = o + 1; m = 0 - m }
16 let d: *u8 = sys_mmap(32)
17 var k: i64 = 0
18 if m == 0 { d[0] = 48 as u8; k = 1 }
19 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
20 var i: i64 = 0
21 while i < k { t[o] = d[k - 1 - i]; o = o + 1; i = i + 1 }
22 sys_write(1, t, o)
23 return 0
24}
25func rg_ck(cnt: *i64, name: *u8, got: i64, want: i64) -> i64 {
26 if got == want {
27 cnt[0] = cnt[0] + 1
28 rg_puts(" PASS " as *u8); rg_puts(name); rg_puts(" = " as *u8); rg_putn(got); rg_puts("\n" as *u8)
29 return 1
30 }
31 cnt[1] = cnt[1] + 1
32 rg_puts(" FAIL " as *u8); rg_puts(name); rg_puts(" got " as *u8); rg_putn(got)
33 rg_puts(" want " as *u8); rg_putn(want); rg_puts("\n" as *u8)
34 return 0
35}
36
37func main(argc: i64, argv: *i64) -> i64 {
38 let cnt: *i64 = sys_mmap(16) as *i64
39 cnt[0] = 0
40 cnt[1] = 0
41
42 rg_puts("NISHI-REDACT-GATE (redaction completeness: precise SSN + privilege scan, fail-closed production)\n" as *u8)
43
44 let marker: *u8 = "ATTORNEY-CLIENT PRIVILEGED" as *u8
45 let mlen: i64 = redact_len(marker)
46 let empty: *u8 = "" as *u8
47
48 // clean document
49 let clean: *u8 = "Case memo has no sensitive data here." as *u8
50 let cl: i64 = redact_len(clean)
51 rg_ck(cnt, "R1 clean doc: no SSN found" as *u8, redact_find_ssn(clean, cl), REDACT_NOT_FOUND)
52 rg_ck(cnt, "R2 clean doc: SSN count 0" as *u8, redact_count_ssn(clean, cl), 0)
53 rg_ck(cnt, "R3 clean doc: clean for production" as *u8, redact_clean_for_production(clean, cl, marker, mlen), 1)
54
55 // document with an SSN
56 let ssn: *u8 = "SSN 123-45-6789 on file for plaintiff." as *u8
57 let sl: i64 = redact_len(ssn)
58 rg_ck(cnt, "R4 SSN doc: found at index 4" as *u8, redact_find_ssn(ssn, sl), 4)
59 rg_ck(cnt, "R5 SSN doc: count 1" as *u8, redact_count_ssn(ssn, sl), 1)
60 rg_ck(cnt, "R6 SSN doc: NOT clean" as *u8, redact_clean_for_production(ssn, sl, marker, mlen), 0)
61
62 // two SSNs
63 let two: *u8 = "IDs 111-22-3333 and 444-55-6666 both." as *u8
64 let tl: i64 = redact_len(two)
65 rg_ck(cnt, "R7 two-SSN doc: count 2" as *u8, redact_count_ssn(two, tl), 2)
66
67 // privilege marker present
68 let priv: *u8 = "This memo is ATTORNEY-CLIENT PRIVILEGED material." as *u8
69 let pl: i64 = redact_len(priv)
70 rg_ck(cnt, "R8 privileged doc: marker at index 13" as *u8, redact_contains(priv, pl, marker, mlen), 13)
71 rg_ck(cnt, "R9 privileged doc: NOT clean (privilege leak blocked)" as *u8, redact_clean_for_production(priv, pl, marker, mlen), 0)
72
73 // ---- SSN PRECISION: no false positives ----
74 let wrong: *u8 = "Grouping 12-34-5678 is not an SSN." as *u8
75 rg_ck(cnt, "R10 wrong grouping dd-dd-dddd -> not matched" as *u8, redact_find_ssn(wrong, redact_len(wrong)), REDACT_NOT_FOUND)
76 let trail: *u8 = "Long 123-45-67890 has an extra digit." as *u8
77 rg_ck(cnt, "R11 trailing extra digit -> not matched (boundary after)" as *u8, redact_find_ssn(trail, redact_len(trail)), REDACT_NOT_FOUND)
78 let lead: *u8 = "Prefixed 9123-45-6789 embedded here." as *u8
79 rg_ck(cnt, "R12 leading digit prefix -> not matched (boundary before)" as *u8, redact_find_ssn(lead, redact_len(lead)), REDACT_NOT_FOUND)
80
81 // ---- empty needle is not a match (substring-of-everything hole closed) ----
82 rg_ck(cnt, "R13 empty marker is NOT a match" as *u8, redact_contains(clean, cl, empty, 0), REDACT_NOT_FOUND)
83
84 // ---- *FAIL-CLOSED production decision ----
85 rg_ck(cnt, "R14 clean + reviewed -> PRODUCIBLE" as *u8, redact_production_ok(clean, cl, 1, marker, mlen), 1)
86 rg_ck(cnt, "R15 clean but UNREVIEWED -> blocked" as *u8, redact_production_ok(clean, cl, 0, marker, mlen), 0)
87 rg_ck(cnt, "R16 reviewed but has SSN -> blocked (dirty)" as *u8, redact_production_ok(ssn, sl, 1, marker, mlen), 0)
88 rg_ck(cnt, "R17 reviewed but privileged -> blocked" as *u8, redact_production_ok(priv, pl, 1, marker, mlen), 0)
89
90 rg_puts("nx_redact_gate: pass=" as *u8); rg_putn(cnt[0])
91 rg_puts(" fail=" as *u8); rg_putn(cnt[1]); rg_puts("\n" as *u8)
92 if cnt[1] == 0 {
93 rg_puts("REDACT nx_redact: VERDICT=GREEN (precise SSN + privilege detection; fail-closed production, no leak by omission)\n" as *u8)
94 sys_exit(0)
95 return 0
96 }
97 rg_puts("REDACT nx_redact: VERDICT=RED\n" as *u8)
98 sys_exit(1)
99 return 1
100}