code wiki / _hdl_build / nx_ha_quorum_gate.nx
nx_ha_quorum_gate.nx source
↩ module page · 43 lines · 3107 B
1// nx_ha_quorum_gate.nx -- hermetic gate for CAP-HA-QUORUM. Proves majority math and split-brain-safe leader
2// election (minority partition -> no leader). Sovereign: nx_syscalls + nx_ha_quorum. expect_exit: 0
3import "nx_syscalls.nx"
4import "nx_ha_quorum.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 }
9func mk3(a: i64, b: i64, c: i64) -> *i64 { let h: *i64 = sys_mmap(32) as *i64; h[0]=a; h[1]=b; h[2]=c; return h }
10
11func main(argc: i64, argv: *i64) -> i64 {
12 gp("=== nx_ha_quorum_gate (majority quorum + split-brain-safe leader) ===\n" as *u8)
13 var pass: i64 = 0; var fail: i64 = 0
14
15 // quorum math
16 if qm_has_quorum(2,3)==1 { if qm_has_quorum(1,3)==0 { if qm_has_quorum(2,4)==0 { if qm_has_quorum(3,4)==1 { pass=pass+1; gp(" T1 quorum math (2/3 yes, 1/3 no, 2/4 no, 3/4 yes) PASS\n" as *u8) } else { fail=fail+1; gp(" T1 FAIL 3/4\n" as *u8) } } else { fail=fail+1; gp(" T1 FAIL 2/4\n" as *u8) } } else { fail=fail+1; gp(" T1 FAIL 1/3\n" as *u8) } } else { fail=fail+1; gp(" T1 FAIL 2/3\n" as *u8) }
17
18 // all healthy -> node 0 leads
19 if qm_leader(mk3(1,1,1), 3) == 0 { pass=pass+1; gp(" T2 all up -> leader node 0 PASS\n" as *u8) } else { fail=fail+1; gp(" T2 FAIL\n" as *u8) }
20
21 // node 0 down, 2/3 up -> node 1 leads (quorum holds)
22 if qm_leader(mk3(0,1,1), 3) == 1 { pass=pass+1; gp(" T3 node0 down, quorum 2/3 -> leader node 1 PASS\n" as *u8) } else { fail=fail+1; gp(" T3 FAIL\n" as *u8) }
23
24 // only 1/3 up -> NO quorum -> NO leader (split-brain prevented)
25 if qm_leader(mk3(0,0,1), 3) == (0-1) { pass=pass+1; gp(" T4 minority 1/3 -> NO leader (split-brain prevented) PASS\n" as *u8) } else { fail=fail+1; gp(" T4 FAIL minority led\n" as *u8) }
26
27 // node 0 up, node 1 down, node 2 up -> 2/3 quorum -> node 0 leads
28 if qm_leader(mk3(1,0,1), 3) == 0 { pass=pass+1; gp(" T5 mixed 2/3 -> leader node 0 PASS\n" as *u8) } else { fail=fail+1; gp(" T5 FAIL\n" as *u8) }
29
30 // all down -> no leader
31 if qm_leader(mk3(0,0,0), 3) == (0-1) { pass=pass+1; gp(" T6 all down -> no leader PASS\n" as *u8) } else { fail=fail+1; gp(" T6 FAIL\n" as *u8) }
32
33 gp("RESULT pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail)
34 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
35 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
36 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
37 let ctr__dry: *i64 = gv_ctr()
38 ctr__dry[0] = pass
39 ctr__dry[1] = pass + fail
40 let rc__dry: i64 = gv_verdict("HA-QUORUM-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
41 sys_exit(rc__dry)
42 return rc__dry
43}