code wiki / _hdl_build / nx_hr_entitle_gate.nx

nx_hr_entitle_gate.nx source

↩ module page · 94 lines · 7705 B

1// nx_hr_entitle_gate.nx -- referee for SUPERUSER-BY-CONSTRUCTION entitlement resolution (nx_hr_entitle). PROVES: 2// * an ACTIVE owner (elderwesto, lvl 3) is entitled to EVERY line even though NONE are keyed to "elderwesto" 3// (auto-access to everything) ; a member (brad) gets only public("*") + own-handle lines (deny-by-default) ; 4// * THE BY-CONSTRUCTION / NO-DRIFT PROOF: append a brand-new resource -> the owner's count auto-increments with 5// ZERO edits to any grant, while the member's count is unchanged ; leak-checks: a member cannot see an 6// admin-keyed resource, and an INVITED (not-yet-active) owner gets NOTHING extra (superadmin requires active). 7// GREEN iff every row matches. Durable -> knowledge/status/hr_entitle_gate.log. 8import "nx_hr_entitle.nx" 9import "nx_g_puts_lib.nx" 10import "nx_hr_admin.nx" 11import "nx_hr.nx" 12import "nx_syscalls.nx" 13 14func g_num(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 } 15func 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 } 16func g_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; 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(fd,bb,k); return 0 } 17func gtrunc(path: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd>=0 { sys_close(fd) } return 0 } 18func g_mkpfx(base: *u8, ms: i64, out: *u8) -> i64 { var o: i64=0; while base[o]!=(0 as u8){out[o]=base[o];o=o+1} let t: *u8=sys_mmap(28); var m: i64=ms; 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 z: i64=k-1; while z>=0{out[o]=t[z];o=o+1;z=z-1} out[o]=0 as u8; return o } 19func g_writefile(path: *u8, s: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd<0 { return 1 } var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd, s, n); sys_close(fd); return 0 } 20func g_append(path: *u8, s: *u8) -> i64 { let fd: i64 = sys_openat_append(path, 0x1a4); if fd<0 { return 1 } var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd, s, n); sys_close(fd); return 0 } 21func g_contains(hay: *u8, hlen: i64, needle: *u8) -> i64 { 22 var nl: i64=0; while needle[nl]!=(0 as u8){nl=nl+1} 23 if nl==0 { return 1 } 24 var i: i64=0 25 while i+nl<=hlen { var j: i64=0; var ok: i64=1; while j<nl { if hay[i+j]!=needle[j]{ok=0;j=nl} else {j=j+1} } if ok==1 {return 1} i=i+1 } 26 return 0 27} 28func chk(got: i64, want: i64, label: *u8) -> i64 { 29 g_puts(" "); g_puts(label); g_puts(" got="); g_num(got); g_puts(" want="); g_num(want) 30 if got == want { g_puts(" PASS\n"); return 1 } 31 g_puts(" FAIL\n"); return 0 32} 33 34func main() -> i64 { 35 g_puts("=== NISHI HR ENTITLE GATE (superuser-by-construction: owner=auto-everything, no drift) ===\n" as *u8) 36 var pass: i64=0; var rows: i64=0 37 let hr: *u8 = sys_mmap(96); g_mkpfx("/tmp/nx_he_hr_" as *u8, sys_now_ms(), hr) // seg_store prefix (cutover) 38 let ent: *u8 = sys_mmap(96); g_mkpfx("/tmp/nx_he_ent_" as *u8, sys_now_ms(), ent) // entitlement seg_store (cutover) 39 let NR: *u8 = "nishi_site_admin" as *u8; let NRN: i64 = 16 40 let fam: *u8 = "andelin" as *u8 41 42 // HR roster: elderwesto active owner(3); brad active member(1); ghost INVITED owner(3) -- not yet active. 43 let cid: *u8 = sys_mmap(96) 44 hra_enroll(hr, NR, NRN, "elderwesto" as *u8, 10, HRA_LVL_OWNER, fam, 1000, "system" as *u8, cid) 45 hra_enroll(hr, NR, NRN, "brad" as *u8, 4, HRA_LVL_MEMBER, fam, 1000, "elderwesto" as *u8, cid) 46 hra_invite(hr, NR, NRN, "ghost" as *u8, 5, HRA_LVL_OWNER, fam, 1000, "elderwesto" as *u8, cid) 47 48 // entitlements: 2 public + 3 member-keyed + 1 admin-keyed("gallery", nobody's handle) = 6 lines. NONE keyed "elderwesto". 49 he_ent_put(ent, "*" as *u8, "Public Wiki" as *u8, "/wiki" as *u8) 50 he_ent_put(ent, "*" as *u8, "Family Video" as *u8, "/video" as *u8) 51 he_ent_put(ent, "brad" as *u8, "Brad Photos" as *u8, "/u/brad" as *u8) 52 he_ent_put(ent, "jensen" as *u8, "Jensen Photos" as *u8, "/u/jensen" as *u8) 53 he_ent_put(ent, "kelli" as *u8, "Kelli Photos" as *u8, "/u/kelli" as *u8) 54 he_ent_put(ent, "gallery" as *u8, "Gallery" as *u8, "/gallery" as *u8) 55 56 // owner sees ALL 6 (auto-everything) though zero lines are keyed to elderwesto 57 rows=rows+1; pass=pass+chk(he_count_access(hr, NR, NRN, "elderwesto" as *u8, 10, ent), 6, "owner elderwesto sees ALL 6 (auto-everything)" as *u8) 58 // member brad: public(2) + own(1) = 3 59 rows=rows+1; pass=pass+chk(he_count_access(hr, NR, NRN, "brad" as *u8, 4, ent), 3, "member brad sees 3 (public + own only)" as *u8) 60 // jensen not enrolled (unknown) -> not super -> public(2) + jensen-keyed(1) = 3 61 rows=rows+1; pass=pass+chk(he_count_access(hr, NR, NRN, "jensen" as *u8, 6, ent), 3, "unenrolled jensen sees 3 (no superadmin)" as *u8) 62 // stranger with no keyed line -> public only 63 rows=rows+1; pass=pass+chk(he_count_access(hr, NR, NRN, "stranger" as *u8, 8, ent), 2, "stranger sees 2 (public only, deny-by-default)" as *u8) 64 // INVITED owner ghost is NOT active -> NOT superadmin -> public only (must be active to be super) 65 rows=rows+1; pass=pass+chk(he_count_access(hr, NR, NRN, "ghost" as *u8, 5, ent), 2, "INVITED owner ghost sees 2 (superadmin requires ACTIVE)" as *u8) 66 67 // === THE BY-CONSTRUCTION / NO-DRIFT PROOF: add a brand-new resource; owner auto-sees it, member unchanged === 68 he_ent_put(ent, "newapp" as *u8, "New App" as *u8, "/newapp" as *u8) 69 rows=rows+1; pass=pass+chk(he_count_access(hr, NR, NRN, "elderwesto" as *u8, 10, ent), 7, "ADD resource -> owner auto-sees it (6->7, ZERO grants edited)" as *u8) 70 rows=rows+1; pass=pass+chk(he_count_access(hr, NR, NRN, "brad" as *u8, 4, ent), 3, "ADD resource -> member brad UNCHANGED (3)" as *u8) 71 72 // emit shape + content 73 let ob: *u8 = sys_mmap(65536) 74 let lo: i64 = he_emit_access(hr, NR, NRN, "elderwesto" as *u8, 10, ent, ob, 65536) 75 rows=rows+1; pass=pass+chk(g_contains(ob, lo, "\"super\":1" as *u8), 1, "owner emit has super:1" as *u8) 76 rows=rows+1; pass=pass+chk(g_contains(ob, lo, "/newapp" as *u8), 1, "owner emit includes the NEW /newapp url" as *u8) 77 let ob2: *u8 = sys_mmap(65536) 78 let lo2: i64 = he_emit_access(hr, NR, NRN, "brad" as *u8, 4, ent, ob2, 65536) 79 rows=rows+1; pass=pass+chk(g_contains(ob2, lo2, "\"super\":0" as *u8), 1, "member emit has super:0" as *u8) 80 rows=rows+1; pass=pass+chk(g_contains(ob2, lo2, "/u/brad" as *u8), 1, "member emit includes own /u/brad" as *u8) 81 rows=rows+1; pass=pass+chk(g_contains(ob2, lo2, "/newapp" as *u8), 0, "member emit EXCLUDES /newapp (leak-check)" as *u8) 82 rows=rows+1; pass=pass+chk(g_contains(ob2, lo2, "/gallery" as *u8), 0, "member emit EXCLUDES admin /gallery (leak-check)" as *u8) 83 84 g_puts("----\nNISHI-HR-ENTITLE-GATE rows=" as *u8); g_num(rows); g_puts(" pass=" as *u8); g_num(pass) 85 if pass==rows { g_puts(" verdict=GREEN\n" as *u8) } else { g_puts(" verdict=RED\n" as *u8) } 86 let lg: i64=sys_openat_append("knowledge/status/hr_entitle_gate.log" as *u8, 0x1a4) 87 if lg>=0 { 88 g_w(lg, "NISHI-HR-ENTITLE-GATE rows=" as *u8); g_wn(lg, rows); g_w(lg, " pass=" as *u8); g_wn(lg, pass) 89 if pass==rows { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } 90 sys_close(lg) 91 } 92 if pass==rows { sys_exit(0); return 0 } 93 sys_exit(1); return 1 94}