code wiki / _hdl_build / nx_hr_gate.nx

nx_hr_gate.nx source

↩ module page · 65 lines · 4904 B

1// nx_hr_gate.nx -- referee for NISHI HR (the S-class user-management SSOT). PROVES the lifecycle + deny-by-default: 2// enroll operator(3)+family(1) -> resolve 3 / 1 · unknown cred -> 0 (deny-by-default) 3// suspend family -> resolve 0 (LEAK-CHECK: a suspended user grants nothing) · set_role 1->3 -> resolve 3 4// hr_cred_id stable (provision-by-handle id == re-derived id) · append-only (history records > current users) 5// GREEN iff every row matches. Prints verdict=GREEN to STDOUT *and* returns the exit code. 6// Durable -> knowledge/status/hr_gate.log. license_tier: ORIGINAL 7import "nx_hr.nx" 8import "nx_g_puts_lib.nx" 9import "nx_syscalls.nx" 10 11func 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 } 12func 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 } 13func 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 } 14func gtrunc(path: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd>=0 { sys_close(fd) } return 0 } 15func g_streq(a: *u8, b: *u8) -> i64 { var i: i64=0; while 1==1 { let ca: i64=a[i] as i64; let cb: i64=b[i] as i64; if ca!=cb { return 0 } if ca==0 { return 1 } i=i+1 } return 1 } 16func chk(got: i64, want: i64, label: *u8) -> i64 { 17 g_puts(" "); g_puts(label); g_puts(" got="); g_num(got); g_puts(" want="); g_num(want) 18 if got == want { g_puts(" PASS\n"); return 1 } 19 g_puts(" FAIL\n"); return 0 20} 21 22func main() -> i64 { 23 g_puts("=== NISHI HR GATE (S-class user management: enroll/resolve/role/suspend, deny-by-default, append-only) ===\n" as *u8) 24 var pass: i64=0 25 var rows: i64=0 26 let store: *u8 = "/tmp/nx_hr_test" as *u8 27 let realm: *u8 = "nishi_hub_test" as *u8; let realm_n: i64 = 14 28 let fam: *u8 = "andelin" as *u8 29 let actor: *u8 = "operator" as *u8 30 gtrunc(store) 31 32 let cid_op: *u8 = sys_mmap(96); let cid_aunt: *u8 = sys_mmap(96) 33 rows=rows+1; pass=pass+chk(hr_enroll(store, realm, realm_n, "operator" as *u8, 8, 3, fam, 1000, actor, cid_op), 0, "enroll operator(3)" as *u8) 34 rows=rows+1; pass=pass+chk(hr_slen(cid_op), 64, " -> cred_id is 64-hex" as *u8) 35 rows=rows+1; pass=pass+chk(hr_enroll(store, realm, realm_n, "aunt" as *u8, 4, 1, fam, 1000, actor, cid_aunt), 0, "enroll aunt(1)" as *u8) 36 37 rows=rows+1; pass=pass+chk(hr_resolve_level(store, cid_op, 64), 3, "resolve operator -> 3" as *u8) 38 rows=rows+1; pass=pass+chk(hr_resolve_level(store, cid_aunt, 64), 1, "resolve aunt -> 1" as *u8) 39 rows=rows+1; pass=pass+chk(hr_resolve_level(store, "0000000000000000000000000000000000000000000000000000000000000000" as *u8, 64), 0, "resolve UNKNOWN -> 0 (deny-by-default)" as *u8) 40 41 rows=rows+1; pass=pass+chk(hr_suspend(store, cid_aunt, "aunt" as *u8, fam, 2000, actor), 0, "suspend aunt" as *u8) 42 rows=rows+1; pass=pass+chk(hr_resolve_level(store, cid_aunt, 64), 0, " -> resolve aunt -> 0 (SUSPENDED leak-check)" as *u8) 43 rows=rows+1; pass=pass+chk(hr_resolve_level(store, cid_op, 64), 3, " -> operator still 3 (others unaffected)" as *u8) 44 45 rows=rows+1; pass=pass+chk(hr_set_role(store, cid_aunt, "aunt" as *u8, 3, fam, 3000, actor), 0, "set_role aunt -> 3 (promote+reactivate)" as *u8) 46 rows=rows+1; pass=pass+chk(hr_resolve_level(store, cid_aunt, 64), 3, " -> resolve aunt -> 3 (role change live)" as *u8) 47 48 // stability: provision-by-handle derives the SAME id the runtime resolves (the SSOT correctness property) 49 let cid_op2: *u8 = sys_mmap(96); hr_cred_id(realm, realm_n, "operator" as *u8, 8, cid_op2) 50 rows=rows+1; pass=pass+chk(g_streq(cid_op, cid_op2), 1, "hr_cred_id STABLE (same handle -> same id)" as *u8) 51 52 // append-only: 2 enroll + 1 suspend + 1 set_role = 4 records preserved (history, not overwrite) 53 rows=rows+1; pass=pass+chk(hr_record_count(store), 4, "append-only: 4 history records preserved" as *u8) 54 55 g_puts("----\nNISHI-HR-GATE rows=" as *u8); g_num(rows); g_puts(" pass=" as *u8); g_num(pass) 56 if pass==rows { g_puts(" verdict=GREEN\n" as *u8) } else { g_puts(" verdict=RED\n" as *u8) } 57 let lg: i64=sys_openat_append("knowledge/status/hr_gate.log" as *u8, 0x1a4) 58 if lg>=0 { 59 g_w(lg, "NISHI-HR-GATE rows=" as *u8); g_wn(lg, rows); g_w(lg, " pass=" as *u8); g_wn(lg, pass) 60 if pass==rows { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } 61 sys_close(lg) 62 } 63 if pass==rows { sys_exit(0); return 0 } 64 sys_exit(1); return 1 65}