code wiki / _hdl_build / nx_apistack_canary_gate.nx

nx_apistack_canary_gate.nx source

↩ module page · 47 lines · 3014 B

1// nx_apistack_canary_gate.nx -- hermetic gate for CAP-API-CANARY. Proves pct=0 all-stable, pct=100 all-canary, an 2// exact deterministic split at pct=10, stickiness, and negative-hash safety. expect_exit: 0 3import "nx_syscalls.nx" 4import "nx_apistack_canary.nx" 5import "nx_gate_verdict.nx" 6 7func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 8func gn(v: i64) -> i64 { var t: i64=v; if t<0{sys_write(1,"-" as *u8,1);t=0-t} let tm:*u8=sys_mmap(24); var k:i64=0; if t==0{tm[0]=48 as u8;k=1} while t>0{tm[k]=(48+(t%10)) as u8;t=t/10;k=k+1} let b:*u8=sys_mmap(24); var j:i64=0; while j<k{b[j]=tm[k-1-j];j=j+1} sys_write(1,b,k); return 0 } 9 10func main(argc: i64, argv: *i64) -> i64 { 11 gp("=== nx_apistack_canary_gate (deterministic traffic split) ===\n" as *u8) 12 var pass: i64 = 0; var fail: i64 = 0 13 14 // T1 pct=0 -> all stable 15 var c0: i64 = 0; var i: i64 = 0 16 while i < 100 { c0 = c0 + cy_is_canary(0, i); i = i + 1 } 17 if c0 == 0 { pass=pass+1; gp(" T1 pct=0 -> 0 canary (all stable / instant rollback) PASS\n" as *u8) } else { fail=fail+1; gp(" T1 FAIL=" as *u8); gn(c0); gp("\n" as *u8) } 18 19 // T2 pct=100 -> all canary 20 var c100: i64 = 0; i = 0 21 while i < 100 { c100 = c100 + cy_is_canary(100, i); i = i + 1 } 22 if c100 == 100 { pass=pass+1; gp(" T2 pct=100 -> 100 canary (full cutover) PASS\n" as *u8) } else { fail=fail+1; gp(" T2 FAIL=" as *u8); gn(c100); gp("\n" as *u8) } 23 24 // T3 pct=10 over buckets 0..99 -> exactly 10 canary 25 var c10: i64 = 0; i = 0 26 while i < 100 { c10 = c10 + cy_is_canary(10, i); i = i + 1 } 27 if c10 == 10 { pass=pass+1; gp(" T3 pct=10 -> exactly 10/100 canary (deterministic split) PASS\n" as *u8) } else { fail=fail+1; gp(" T3 FAIL=" as *u8); gn(c10); gp("\n" as *u8) } 28 29 // T4 sticky: same key -> same side 30 let h: i64 = cy_keyhash("shard-andelinwest" as *u8, 17) 31 if cy_is_canary(30, h) == cy_is_canary(30, h) { pass=pass+1; gp(" T4 sticky (same key -> same side) PASS\n" as *u8) } else { fail=fail+1; gp(" T4 FAIL\n" as *u8) } 32 33 // T5 negative hash safe (0 or 1, no crash) 34 let r: i64 = cy_is_canary(10, 0 - 7) 35 if r == 0 { pass=pass+1; gp(" T5 negative hash -> valid bucket PASS\n" as *u8) } else { if r == 1 { pass=pass+1; gp(" T5 negative hash -> valid bucket PASS\n" as *u8) } else { fail=fail+1; gp(" T5 FAIL\n" as *u8) } } 36 37 gp("RESULT pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail) 38 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 39 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 40 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 41 let ctr__dry: *i64 = gv_ctr() 42 ctr__dry[0] = pass 43 ctr__dry[1] = pass + fail 44 let rc__dry: i64 = gv_verdict("APISTACK-CANARY-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 45 sys_exit(rc__dry) 46 return rc__dry 47}