nx_asset_visibility_gate.nx source
↩ module page · 140 lines · 7821 B
1// nx_asset_visibility_gate.nx -- KAT + TEETH for nx_asset_visibility (flag public/private BY SOURCE),
2// now reading the policy from the NATIVE seg_store (no TSV). The gate SEEDS its own isolated /tmp
3// policy store (vis_seed) and reads via the _p variants, so it never touches the production policy.
4//
5// (a) gallery location -> operator-only, NOT public (b) web_assets/ -> public
6// (c) downloaded -> private, NOT public (d) type=doc fallback -> public
7// TEETH: (e) UNKNOWN source -> operator-only (fail-closed) (f) NO policy store -> operator-only
8// bridge: gallery->OWNER, wiki->ANON, downloaded->PRO (plugs into R6/aa_decide)
9//
10// Verdict appended to knowledge/status/asset_visibility_gate.log (additive law #13).
11// expect_exit: 0 license_tier: ORIGINAL
12import "nx_syscalls.nx"
13import "nx_canon_cid.nx"
14import "nx_asset_record.nx"
15import "nx_asset_access.nx"
16import "nx_asset_visibility.nx"
17import "nx_gate_verdict.nx"
18
19func g_puts(logfd: i64, s: *u8) -> i64 {
20 var n: i64 = 0
21 while s[n] != (0 as u8) { n = n + 1 }
22 sys_write(1, s, n)
23 if logfd > 0 { sys_write(logfd, s, n) }
24 return 0
25}
26func g_putn(logfd: i64, v: i64) -> i64 {
27 let bb: *u8 = sys_mmap(28)
28 var m: i64 = v
29 if m < 0 { g_puts(logfd, "-\x00" as *u8); m = 0 - m }
30 let t: *u8 = sys_mmap(28)
31 var k: i64 = 0
32 if m == 0 { t[0] = 48 as u8; k = 1 }
33 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
34 var i: i64 = 0
35 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
36 sys_write(1, bb, k)
37 if logfd > 0 { sys_write(logfd, bb, k) }
38 return 0
39}
40func g_streq(a: *u8, b: *u8) -> i64 {
41 var i: i64 = 0
42 while 1 == 1 { if a[i] != b[i] { return 0 } if a[i] == (0 as u8) { return 1 } i = i + 1 }
43 return 1
44}
45func E() -> *u8 { return "\x00" as *u8 }
46func sset(a: *i64, i: i64, s: *u8) -> i64 { a[i] = s as i64; return 0 }
47
48func mk_src(typ: *u8, prov: *u8, loc: *u8, out: *u8) -> i64 {
49 let core: *i64 = sys_mmap(8 * 8) as *i64
50 sset(core, 0, typ); sset(core, 1, "Asset\x00" as *u8); sset(core, 2, E())
51 sset(core, 3, "2026-06-20\x00" as *u8); sset(core, 4, "v-1\x00" as *u8); sset(core, 5, E()); sset(core, 6, E())
52 let pz: *i64 = sys_mmap(8 * 8) as *i64
53 sset(pz, 0, prov); sset(pz, 1, E()); sset(pz, 2, E()); sset(pz, 3, E()); sset(pz, 4, E()); sset(pz, 5, E())
54 let mz: *i64 = sys_mmap(8 * 8) as *i64
55 sset(mz, 0, E()); sset(mz, 1, E()); sset(mz, 2, E()); sset(mz, 3, E())
56 let oz: *i64 = sys_mmap(8 * 8) as *i64
57 sset(oz, 0, E()); sset(oz, 1, loc); sset(oz, 2, E()); sset(oz, 3, "1\x00" as *u8); sset(oz, 4, E()); sset(oz, 5, E())
58 let keys: *i64 = sys_mmap(8 * 48) as *i64
59 let vals: *i64 = sys_mmap(8 * 48) as *i64
60 let n: i64 = ar_fields(core, pz, mz, oz, keys, vals)
61 return ar_encode(keys, vals, n, out)
62}
63
64func gt_prefix(prefix: *u8, base: *u8) -> i64 {
65 var po: i64 = 0
66 while base[po] != (0 as u8) { prefix[po] = base[po]; po = po + 1 }
67 var m: i64 = sys_now_ms()
68 let ds: *u8 = sys_mmap(28)
69 var k: i64 = 0
70 if m == 0 { ds[0] = 48 as u8; k = 1 }
71 while m > 0 { ds[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
72 var j: i64 = 0
73 while j < k { prefix[po] = ds[k - 1 - j]; po = po + 1; j = j + 1 }
74 prefix[po] = 45 as u8; po = po + 1
75 prefix[po] = 0 as u8
76 return po
77}
78
79// assert vis_of_p == want_viz AND vis_is_public_p == want_pub against policy store `pp`.
80func expect_vis(logfd: i64, label: *u8, rec: *u8, n: i64, pp: *u8, want_viz: *u8, want_pub: i64) -> i64 {
81 let viz: *u8 = vis_of_p(rec, n, pp)
82 let pub: i64 = vis_is_public_p(rec, n, pp)
83 g_puts(logfd, label); g_puts(logfd, " -> vis=\x00" as *u8); g_puts(logfd, viz); g_puts(logfd, " public=\x00" as *u8); g_putn(logfd, pub); g_puts(logfd, ": \x00" as *u8)
84 var ok: i64 = 1
85 if g_streq(viz, want_viz) == 0 { ok = 0 }
86 if pub != want_pub { ok = 0 }
87 if ok == 1 { g_puts(logfd, "PASS\n\x00" as *u8); return 1 }
88 g_puts(logfd, "FAIL\n\x00" as *u8); return 0
89}
90
91func main() -> i64 {
92 let logfd: i64 = sys_openat_append("knowledge/status/asset_visibility_gate.log\x00" as *u8, 0x1a4)
93 g_puts(logfd, "=== ASSET-VISIBILITY-GATE (flag public/private BY SOURCE, NATIVE store, no TSV) ===\n\x00" as *u8)
94
95 // seed an ISOLATED /tmp policy store (production policy untouched).
96 let pp: *u8 = sys_mmap(256); gt_prefix(pp, "/tmp/vispol-\x00" as *u8)
97 let src: i64 = vis_seed(pp)
98 g_puts(logfd, " seeded native policy store rc=\x00" as *u8); g_putn(logfd, src); g_puts(logfd, " at \x00" as *u8); g_puts(logfd, pp); g_puts(logfd, "\n\x00" as *u8)
99
100 var pass: i64 = 0
101 var total: i64 = 0
102
103 let rGal: *u8 = sys_mmap(8192); let nGal: i64 = mk_src("image\x00" as *u8, "machine\x00" as *u8, "knowledge/staging/media/gallery/20260612_x_laptop.png\x00" as *u8, rGal)
104 let rWiki: *u8 = sys_mmap(8192); let nWiki: i64 = mk_src("doc\x00" as *u8, "machine\x00" as *u8, "web_assets/charter.html\x00" as *u8, rWiki)
105 let rDl: *u8 = sys_mmap(8192); let nDl: i64 = mk_src("video\x00" as *u8, "downloaded\x00" as *u8, "https://example.com/clip.mp4\x00" as *u8, rDl)
106 let rDocX: *u8 = sys_mmap(8192); let nDocX: i64 = mk_src("doc\x00" as *u8, "machine\x00" as *u8, "some/unlisted/path.html\x00" as *u8, rDocX)
107 let rUnk: *u8 = sys_mmap(8192); let nUnk: i64 = mk_src("image\x00" as *u8, "machine\x00" as *u8, "some/random/path.png\x00" as *u8, rUnk)
108
109 total = total + 1; pass = pass + expect_vis(logfd, " (a) gallery source\x00" as *u8, rGal, nGal, pp, "operator-only\x00" as *u8, 0)
110 total = total + 1; pass = pass + expect_vis(logfd, " (b) public wiki source\x00" as *u8, rWiki, nWiki, pp, "public\x00" as *u8, 1)
111 total = total + 1; pass = pass + expect_vis(logfd, " (c) downloaded source\x00" as *u8, rDl, nDl, pp, "private\x00" as *u8, 0)
112 total = total + 1; pass = pass + expect_vis(logfd, " (d) doc fallback (type rule)\x00" as *u8, rDocX, nDocX, pp, "public\x00" as *u8, 1)
113 total = total + 1; pass = pass + expect_vis(logfd, " (e TEETH) unknown source -> fail-closed\x00" as *u8, rUnk, nUnk, pp, "operator-only\x00" as *u8, 0)
114
115 // (f) TEETH: NO policy store at all -> fail-closed operator-only (never public).
116 total = total + 1
117 let viz_nopol: *u8 = vis_of_p(rWiki, nWiki, "/tmp/vispol-DOES-NOT-EXIST-\x00" as *u8)
118 g_puts(logfd, " (f TEETH) missing policy store -> vis=\x00" as *u8); g_puts(logfd, viz_nopol); g_puts(logfd, " (want operator-only): \x00" as *u8)
119 if g_streq(viz_nopol, "operator-only\x00" as *u8) == 1 { pass = pass + 1; g_puts(logfd, "PASS\n\x00" as *u8) } else { g_puts(logfd, "FAIL\n\x00" as *u8) }
120
121 // bridge to R6 access levels
122 total = total + 1
123 var br: i64 = 1
124 if vis_required_level_p(rGal, nGal, pp) != AA_OWNER() { br = 0 }
125 if vis_required_level_p(rWiki, nWiki, pp) != AA_ANON() { br = 0 }
126 if vis_required_level_p(rDl, nDl, pp) != AA_PRO() { br = 0 }
127 g_puts(logfd, " (g) required-level bridge (gallery=OWNER, wiki=ANON, downloaded=PRO): \x00" as *u8)
128 if br == 1 { pass = pass + 1; g_puts(logfd, "PASS\n\x00" as *u8) } else { g_puts(logfd, "FAIL\n\x00" as *u8) }
129
130 g_puts(logfd, "ASSET-VISIBILITY-GATE passed \x00" as *u8); g_putn(logfd, pass); g_puts(logfd, "/\x00" as *u8); g_putn(logfd, total)
131 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
132 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
133 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
134 let ctr__dry: *i64 = gv_ctr()
135 ctr__dry[0] = pass
136 ctr__dry[1] = total
137 let rc__dry: i64 = gv_verdict("ASSET-VISIBILITY-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
138 sys_exit(rc__dry)
139 return rc__dry
140}