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}