code wiki / _hdl_build / nx_room_waitlobby.nx

nx_room_waitlobby.nx source

↩ module page · 133 lines · 6718 B

1// nx_room_waitlobby.nx -- X-ROOM (GEN-ROOM-waiting-room-lobby): sovereign 2// DETERMINISTIC admission-control FSM for the room's PRO-mode waiting room 3// (lobby). Participants KNOCK; the host ADMITs / DENYs / ADMIT_ALLs; the room 4// can be LOCKed (closed). Every transition is a reproducible, auditable verdict. 5// 6// EXCEED axis (honest) vs Zoom/Whereby waiting rooms: deterministic + audit- 7// replayable admission -- replay the same event stream, get the same admitted set 8// -- plus two integrity invariants a loose implementation can violate: 9// (I1) a host can only ADMIT/DENY someone who actually KNOCKED (no admitting a 10// ghost id = no silent gate-crash), 11// (I2) a KNOCK while the room is LOCKED is closed-out (DENIED) deterministically, 12// not racily admitted. 13// Pro waiting-room (explicit admit) is the DATA-distinct sibling of personal 14// instant-join; this organ is the explicit-admit half. 15// 16// status codes: 0=UNKNOWN 1=KNOCKING 2=ADMITTED 3=DENIED ; status[0] = locked flag. 17// event codes: 1=KNOCK 2=ADMIT 3=DENY 4=ADMIT_ALL 5=LOCK 6=UNLOCK. 18// 19// main() is the SELF-VALIDATING GATE. Evidence -> knowledge/status/room_waitlobby.log. 20// license_tier: ORIGINAL 21import "nx_syscalls.nx" 22 23const WL_LOG: *u8 = "knowledge/status/room_waitlobby.log" 24const WL_UNKNOWN: i64 = 0 25const WL_KNOCKING: i64 = 1 26const WL_ADMITTED: i64 = 2 27const WL_DENIED: i64 = 3 28 29func ww(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 } 30func wwn(fd: i64, v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64=v; if m<0 {m=0-m; sys_write(fd,"-" as *u8,1)}; let t: *u8 = sys_mmap(28); var k: i64=0; if m==0 {t[0]=48;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 } 31 32// process an ordered event stream into a fresh status array (index 0 = locked flag). 33// maxid participants 1..maxid. evt[]/eid[] are the event code and target id. 34func wl_run(maxid: i64, evt: *i64, eid: *i64, nev: i64, status: *i64) -> i64 { 35 var i: i64 = 0 36 while i <= maxid { status[i] = WL_UNKNOWN; i = i + 1 } // status[0]=locked=0 37 var e: i64 = 0 38 while e < nev { 39 let code: i64 = evt[e] 40 let id: i64 = eid[e] 41 if code == 1 { // KNOCK 42 if status[0] == 1 { status[id] = WL_DENIED } // I2: locked -> closed out 43 else { if status[id] == WL_UNKNOWN { status[id] = WL_KNOCKING } } 44 } 45 if code == 2 { // ADMIT (I1: only a knocker) 46 if status[id] == WL_KNOCKING { status[id] = WL_ADMITTED } 47 } 48 if code == 3 { // DENY (only a knocker) 49 if status[id] == WL_KNOCKING { status[id] = WL_DENIED } 50 } 51 if code == 4 { // ADMIT_ALL knockers 52 var j: i64 = 1 53 while j <= maxid { if status[j] == WL_KNOCKING { status[j] = WL_ADMITTED } j = j + 1 } 54 } 55 if code == 5 { status[0] = 1 } // LOCK 56 if code == 6 { status[0] = 0 } // UNLOCK 57 e = e + 1 58 } 59 return 0 60} 61 62func wl_count(maxid: i64, status: *i64, want: i64) -> i64 { 63 var c: i64 = 0 64 var i: i64 = 1 65 while i <= maxid { if status[i] == want { c = c + 1 } i = i + 1 } 66 return c 67} 68 69func main() -> i64 { 70 let evt: *i64 = sys_mmap(8 * 32) as *i64 71 let eid: *i64 = sys_mmap(8 * 32) as *i64 72 let st: *i64 = sys_mmap(8 * 16) as *i64 73 var ok: i64 = 1 74 let MAXID: i64 = 9 75 76 // timeline: 3 knock(open)->admit1,deny2,admit3 ; admit-ghost9(ignored) ; LOCK ; 77 // knock4,knock5(locked->denied) ; UNLOCK ; knock6,knock7 ; ADMIT_ALL 78 var n: i64 = 0 79 evt[n]=1; eid[n]=1; n=n+1 80 evt[n]=1; eid[n]=2; n=n+1 81 evt[n]=1; eid[n]=3; n=n+1 82 evt[n]=2; eid[n]=1; n=n+1 // admit 1 83 evt[n]=3; eid[n]=2; n=n+1 // deny 2 84 evt[n]=2; eid[n]=3; n=n+1 // admit 3 85 evt[n]=2; eid[n]=9; n=n+1 // admit ghost 9 -> IGNORED (never knocked) 86 evt[n]=5; eid[n]=0; n=n+1 // LOCK 87 evt[n]=1; eid[n]=4; n=n+1 // knock 4 while locked -> DENIED 88 evt[n]=1; eid[n]=5; n=n+1 // knock 5 while locked -> DENIED 89 evt[n]=6; eid[n]=0; n=n+1 // UNLOCK 90 evt[n]=1; eid[n]=6; n=n+1 // knock 6 91 evt[n]=1; eid[n]=7; n=n+1 // knock 7 92 evt[n]=4; eid[n]=0; n=n+1 // ADMIT_ALL -> 6,7 admitted 93 wl_run(MAXID, evt, eid, n, st) 94 95 let adm: i64 = wl_count(MAXID, st, WL_ADMITTED) 96 let den: i64 = wl_count(MAXID, st, WL_DENIED) 97 let kno: i64 = wl_count(MAXID, st, WL_KNOCKING) 98 if adm != 4 { ok = 0 } // 1,3,6,7 99 if den != 3 { ok = 0 } // 2 (denied) + 4,5 (locked-out) 100 if kno != 0 { ok = 0 } 101 if st[1] != WL_ADMITTED { ok = 0 } 102 if st[2] != WL_DENIED { ok = 0 } 103 if st[3] != WL_ADMITTED { ok = 0 } 104 if st[9] != WL_UNKNOWN { ok = 0 } // I1: ghost admit ignored 105 if st[4] != WL_DENIED { ok = 0 } // I2: locked knock closed out 106 if st[6] != WL_ADMITTED { ok = 0 } // ADMIT_ALL 107 108 // neg-control: SAME timeline but event 8 (LOCK) replaced by UNLOCK -> id4 knocks 109 // in OPEN mode and the trailing ADMIT_ALL lets it IN (ADMITTED). So the LOCK is 110 // the ONLY thing that kept id4 out: locked -> DENIED, open -> ADMITTED. The rule 111 // is MATERIAL iff id4's fate differs between the two runs (rule-sensitivity). 112 let st2: *i64 = sys_mmap(8 * 16) as *i64 113 evt[7] = 6 // was LOCK(5), now UNLOCK(6) = no lock 114 wl_run(MAXID, evt, eid, n, st2) 115 if st2[4] != WL_ADMITTED { ok = 0 } // open-mode + ADMIT_ALL -> id4 gets in 116 if st2[4] == st[4] { ok = 0 } // lock MATERIALLY changed id4's fate (2 vs 3) 117 118 ww(1, "ROOMWAITGATE admitted=" as *u8); wwn(1, adm); ww(1, " denied=" as *u8); wwn(1, den) 119 ww(1, " knocking=" as *u8); wwn(1, kno); ww(1, " ghost9=" as *u8); wwn(1, st[9]) 120 ww(1, " locked_knock4=" as *u8); wwn(1, st[4]); ww(1, " open_knock4=" as *u8); wwn(1, st2[4]) 121 if ok == 1 { ww(1, " verdict=GREEN\n" as *u8) } else { ww(1, " verdict=RED\n" as *u8) } 122 123 let lf: i64 = sys_openat_append(WL_LOG, 420) 124 if lf >= 0 { 125 ww(lf, "ROOMWAITGATE admitted=" as *u8); wwn(lf, adm); ww(lf, " denied=" as *u8); wwn(lf, den) 126 ww(lf, " knocking=" as *u8); wwn(lf, kno); ww(lf, " ghost9=" as *u8); wwn(lf, st[9]) 127 ww(lf, " locked_knock4=" as *u8); wwn(lf, st[4]); ww(lf, " open_knock4=" as *u8); wwn(lf, st2[4]) 128 if ok == 1 { ww(lf, " verdict=GREEN\n" as *u8) } else { ww(lf, " verdict=RED\n" as *u8) } 129 sys_close(lf) 130 } 131 if ok == 1 { sys_exit(0) } else { sys_exit(1) } 132 return 0 133}