code wiki / _hdl_build / nx_dp_reclassify_gate.nx

nx_dp_reclassify_gate.nx source

↩ module page · 120 lines · 7610 B

1// nx_dp_reclassify_gate.nx -- MEASURED hermetic gate for per-doc secret reclassification. Seeds its OWN fixture 2// docs in a FRESH per-run shard (dpsec<unix-sec> -- append-only tombstones from a prior run would otherwise 3// poison a re-run's T1), then proves LOGICAL secret-isolation by construction: 4// T1 pre : docS is live -- found by dss_search AND readable via dp_read(pub) 5// T2 run : dpr_run(domain, cidS) returns 0 6// T3 gone : dss_search now OMITS docS (tombstone shadows its postings) 7// T4 moved: dp_read(pub) MISS, but the secret shard HIT with byte-identical content (bytes preserved) 8// T5 neg : a sibling public doc (docK) is untouched -- still searchable 9// Verdict MEASURED. GREEN iff 5/5. Appends knowledge/status/dp_reclassify_gate.log. license_tier: ORIGINAL 10import "nx_dp_reclassify.nx" // dpr_run (+ dp_*/dss_*/ss_*/sys_* transitively) 11import "nx_docportal_lib.nx" // dp_ingest_policy / dp_read / DP_VIS_PUBLIC / DP_USE_PUB_SEARCH (explicit; dedup'd) 12import "nx_docportal_search_seg.nx" // dss_search / dss_mkkey (explicit, mirrors policy_gate; dedup'd) 13 14func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 15func g_num(v: i64) -> i64 { 16 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 17 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 18 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 19 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 20} 21func g_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 22func g_wn(fd: i64, v: i64) -> i64 { 23 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m } 24 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 25 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 26 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(fd, bb, k); return 0 27} 28func g_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 29func g_cat(out: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { out[o] = s[i]; o = o + 1; i = i + 1 } return o } 30func g_catnum(out: *u8, o: i64, v: i64) -> i64 { 31 if v == 0 { out[o] = 48 as u8; return o + 1 } 32 var m: i64 = v; let t: *u8 = sys_mmap(28); var k: i64 = 0 33 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 34 var i: i64 = 0; while i < k { out[o] = t[k - 1 - i]; o = o + 1; i = i + 1 } return o 35} 36func g_eq(a: *u8, al: i64, b: *u8, bl: i64) -> i64 { if al != bl { return 0 } var i: i64 = 0; while i < al { if a[i] != b[i] { return 0 } i = i + 1 } return 1 } 37 38func main() -> i64 { 39 g_puts("=== DP RECLASSIFY GATE (secret-isolation: evict from ALL live surfaces + preserve bytes) ===\n" as *u8) 40 // fresh per-run domain so append-only tombstones from a prior run never poison this run's T1 41 let dom: *u8 = sys_mmap(64) 42 var dn: i64 = g_cat(dom, 0, "dpsec" as *u8) 43 dn = g_catnum(dom, dn, sys_now_realtime_sec()) 44 dom[dn] = 0 as u8 45 46 let tS: *u8 = "SECRETMARK Confidential settlement terms for the Okafor matter -- internal only." as *u8 47 let tK: *u8 = "KEEPMARK Public estate-planning overview about probate timelines in Utah." as *u8 48 let cidS: *i64 = sys_mmap(16) as *i64 49 let cidK: *i64 = sys_mmap(16) as *i64 50 dp_ingest_policy(dom, DP_VIS_PUBLIC, DP_USE_PUB_SEARCH, tS, g_slen(tS), cidS) 51 dp_ingest_policy(dom, DP_VIS_PUBLIC, DP_USE_PUB_SEARCH, tK, g_slen(tK), cidK) 52 53 let scids: *i64 = sys_mmap(16 * 8) as *i64 54 let sscores: *i64 = sys_mmap(16 * 8) as *i64 55 var pass: i64 = 0 56 57 // T1 pre: docS searchable AND dp_read(pub) hit 58 let qS: *u8 = "secretmark" as *u8 59 let n1: i64 = dss_search(dom, qS, g_slen(qS), scids, sscores, 16) 60 var found1: i64 = 0 61 if n1 >= 1 { if scids[0] == cidS[0] { found1 = 1 } } 62 let pq: *i64 = sys_mmap(16) as *i64; let lq: *i64 = sys_mmap(16) as *i64 63 let read1: i64 = dp_read(dom, DP_VIS_PUBLIC, cidS[0], pq, lq) 64 var t1: i64 = 0; if found1 == 1 { if read1 == 1 { t1 = 1 } } pass = pass + t1 65 g_puts(" T1 pre: docS searchable + dp_read(pub) hit (found=" as *u8); g_num(found1); g_puts(" read=" as *u8); g_num(read1); g_puts("): " as *u8) 66 if t1 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 67 68 // T2: run the reclassify 69 let rc: i64 = dpr_run(dom, cidS[0]) 70 var t2: i64 = 0; if rc == 0 { t2 = 1 } pass = pass + t2 71 g_puts(" T2 reclassify rc=0 (rc=" as *u8); g_num(rc); g_puts("): " as *u8) 72 if t2 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 73 74 // T3: docS now OMITTED from live search 75 let n3: i64 = dss_search(dom, qS, g_slen(qS), scids, sscores, 16) 76 var t3: i64 = 0; if n3 == 0 { t3 = 1 } pass = pass + t3 77 g_puts(" T3 docS gone from dss_search (n=" as *u8); g_num(n3); g_puts("): " as *u8) 78 if t3 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 79 80 // T4: dp_read(pub) MISS, but the secret shard HIT with byte-identical content 81 let read4: i64 = dp_read(dom, DP_VIS_PUBLIC, cidS[0], pq, lq) 82 let sec: *u8 = sys_mmap(512) 83 var sp: i64 = g_cat(sec, 0, "knowledge/store/dp-" as *u8) 84 sp = g_cat(sec, sp, dom); sp = g_cat(sec, sp, "-secret-" as *u8); sec[sp] = 0 as u8 85 let hsec: *i64 = ss_open(sec) 86 let dkey: *u8 = sys_mmap(64); dss_mkkey(cidS[0], dkey) 87 var sechit: i64 = 0 88 var bytes_ok: i64 = 0 89 if (hsec as i64) != 0 { 90 let sq: *i64 = sys_mmap(16) as *i64; let sl: *i64 = sys_mmap(16) as *i64 91 if ss_hget(hsec, dkey, sq, sl) == 1 { 92 sechit = 1 93 if g_eq(sq[0] as *u8, sl[0], tS, g_slen(tS)) == 1 { bytes_ok = 1 } 94 } 95 } 96 var t4: i64 = 0; if read4 == 0 { if sechit == 1 { if bytes_ok == 1 { t4 = 1 } } } pass = pass + t4 97 g_puts(" T4 pub MISS + secret HIT identical bytes (pubread=" as *u8); g_num(read4); g_puts(" sechit=" as *u8); g_num(sechit); g_puts(" bytes=" as *u8); g_num(bytes_ok); g_puts("): " as *u8) 98 if t4 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 99 100 // T5 neg-control: sibling docK untouched -- still searchable 101 let qK: *u8 = "keepmark" as *u8 102 let n5: i64 = dss_search(dom, qK, g_slen(qK), scids, sscores, 16) 103 var found5: i64 = 0 104 if n5 >= 1 { if scids[0] == cidK[0] { found5 = 1 } } 105 var t5: i64 = 0; if found5 == 1 { t5 = 1 } pass = pass + t5 106 g_puts(" T5 sibling docK untouched + searchable (found=" as *u8); g_num(found5); g_puts("): " as *u8) 107 if t5 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 108 109 g_puts("----\nDP-RECLASSIFY rows=5 pass=" as *u8); g_num(pass); g_puts("\n" as *u8) 110 let lg: i64 = sys_openat_append("knowledge/status/dp_reclassify_gate.log" as *u8, 0x1a4) 111 if lg >= 0 { 112 g_w(lg, "DP-RECLASSIFY pre=" as *u8); g_wn(lg, t1); g_w(lg, " run=" as *u8); g_wn(lg, t2) 113 g_w(lg, " search_gone=" as *u8); g_wn(lg, t3); g_w(lg, " pubmiss_secrethit_preserved=" as *u8); g_wn(lg, t4) 114 g_w(lg, " sibling_untouched=" as *u8); g_wn(lg, t5); g_w(lg, " rows=5 pass=" as *u8); g_wn(lg, pass) 115 if pass == 5 { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } 116 sys_close(lg) 117 } 118 if pass == 5 { g_puts("DP-RECLASSIFY GREEN (secret-isolation by construction; live surfaces evicted, bytes preserved -- measured)\n" as *u8); sys_exit(0); return 0 } 119 g_puts("DP-RECLASSIFY RED\n" as *u8); sys_exit(1); return 1 120}