code wiki / _hdl_build / nx_ciq_family_gate.nx
nx_ciq_family_gate.nx source
↩ module page · 76 lines · 5465 B
1// nx_ciq_family_gate.nx -- the OPAQUE family-level gate for the CIQ publish (operator: "opaque gate it behind
2// the family level"). Defines + PROVES the authz policy the wiki render daemon adopts for the /wiki/family/
3// route prefix, composing the proven nx_authz longest-prefix level rule (no reinvention):
4// policy: /wiki/ -> level 0 (public) ; /wiki/family/ -> level 2 (family) [longer prefix wins]
5// "OPAQUE" (the operator's word) = stronger than a visible 403: authz_filter OMITS family items from a
6// non-family user's listing entirely, so an anonymous/public visitor never even SEES that the CIQ analysis
7// exists. PROVES by construction:
8// (1) anon (lvl0) requesting /wiki/family/ciq.html -> DENY ; family (lvl2) -> ALLOW ; public page -> ALLOW
9// (2) OPAQUE: a public listing filters OUT the family items (count drops); a family listing keeps them.
10// This is the gating LOGIC, tested; wiring it into nx_wiki_doc_render's serve path = the wiki workstream's
11// coordinated adoption step. 100% sovereign. license_tier: ORIGINAL expect_exit: 0
12import "nx_syscalls.nx"
13import "nx_authz.nx"
14import "nx_gate_verdict.nx"
15
16func fw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
17func fn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 }
18func slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
19
20const LVL_PUBLIC: i64 = 0
21const LVL_FAMILY: i64 = 2
22
23func main() -> i64 {
24 // resource policy (data-driven, rule 11): two prefix rules, longest wins
25 let paths: *i64 = sys_mmap(8 * 4) as *i64
26 let lens: *i64 = sys_mmap(8 * 4) as *i64
27 let reql: *i64 = sys_mmap(8 * 4) as *i64
28 paths[0] = "/wiki/" as *u8 as i64; lens[0] = slen("/wiki/" as *u8); reql[0] = LVL_PUBLIC
29 paths[1] = "/wiki/family/" as *u8 as i64; lens[1] = slen("/wiki/family/" as *u8); reql[1] = LVL_FAMILY
30 let npol: i64 = 2
31
32 let r_fam: *u8 = "/wiki/family/ciq.html" as *u8
33 let r_pub: *u8 = "/wiki/start.html" as *u8
34
35 fw("=== nx_ciq_family_gate -- opaque family-level gate for the CIQ publish ===\n" as *u8)
36 fw("policy: /wiki/ -> level 0 (public) ; /wiki/family/ -> level 2 (family)\n" as *u8)
37
38 // (1) access control
39 let a_anon_fam: i64 = authz_level_allow(LVL_PUBLIC, paths, lens, reql, npol, r_fam, slen(r_fam))
40 let a_fam_fam: i64 = authz_level_allow(LVL_FAMILY, paths, lens, reql, npol, r_fam, slen(r_fam))
41 let a_anon_pub: i64 = authz_level_allow(LVL_PUBLIC, paths, lens, reql, npol, r_pub, slen(r_pub))
42 fw(" anon -> /wiki/family/ciq.html : " as *u8); if a_anon_fam==0 { fw("DENY (correct)\n" as *u8) } else { fw("ALLOW (WRONG)\n" as *u8) }
43 fw(" family-> /wiki/family/ciq.html : " as *u8); if a_fam_fam==1 { fw("ALLOW (correct)\n" as *u8) } else { fw("DENY (WRONG)\n" as *u8) }
44 fw(" anon -> /wiki/start.html : " as *u8); if a_anon_pub==1 { fw("ALLOW (correct)\n" as *u8) } else { fw("DENY (WRONG)\n" as *u8) }
45
46 // (2) OPAQUE listing: a public listing must OMIT the family items (not even visible)
47 let items: *i64 = sys_mmap(8 * 8) as *i64
48 let ilen: *i64 = sys_mmap(8 * 8) as *i64
49 items[0] = "/wiki/start.html" as *u8 as i64; ilen[0] = slen(items[0] as *u8)
50 items[1] = "/wiki/family/ciq.html" as *u8 as i64; ilen[1] = slen(items[1] as *u8)
51 items[2] = "/wiki/family/ciq_ai.md" as *u8 as i64; ilen[2] = slen(items[2] as *u8)
52 items[3] = "/wiki/family/ciq_machine.nxr" as *u8 as i64; ilen[3] = slen(items[3] as *u8)
53 let nit: i64 = 4
54 let out: *i64 = sys_mmap(8 * 8) as *i64
55 let vis_anon: i64 = authz_filter(LVL_PUBLIC, items, ilen, nit, paths, lens, reql, npol, out)
56 let vis_fam: i64 = authz_filter(LVL_FAMILY, items, ilen, nit, paths, lens, reql, npol, out)
57 fw(" OPAQUE listing: anon sees " as *u8); fn(vis_anon); fw("/" as *u8); fn(nit); fw(" items (family items omitted), family sees " as *u8); fn(vis_fam); fw("/" as *u8); fn(nit); fw("\n" as *u8)
58
59 // GATE: access control correct AND opaque listing hides exactly the 3 family items from anon
60 var ok: i64 = 1
61 if a_anon_fam != 0 { ok = 0 } // anon must be DENIED the family page
62 if a_fam_fam != 1 { ok = 0 } // family must be ALLOWED
63 if a_anon_pub != 1 { ok = 0 } // anon must see public pages
64 if vis_anon != 1 { ok = 0 } // anon listing: only the 1 public item survives (3 family OMITTED)
65 if vis_fam != nit { ok = 0 } // family listing: all items visible
66 fw("--- gate --- access-control correct & opaque-listing hides family items from non-family: " as *u8); if ok==1 { fw("PASS" as *u8) } else { fw("FAIL" as *u8) } fw("\n" as *u8)
67 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
68 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
69 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
70 let ctr__dry: *i64 = gv_ctr()
71 ctr__dry[0] = ok
72 ctr__dry[1] = 1
73 let rc__dry: i64 = gv_verdict("CIQ-FAMILY-GATE" as *u8, ctr__dry, "CIQ publish is opaque-gated behind family level; ready for wiki-daemon adoption on /wiki/family/)" as *u8)
74 sys_exit(rc__dry)
75 return rc__dry
76}