code wiki / _hdl_build / nx_room_protocol_gate.nx

nx_room_protocol_gate.nx source

↩ module page · 192 lines · 8695 B

1import "nx_gate_base.nx" 2// nx_room_protocol_gate.nx -- the room wire/memory CONTRACT as a Nishi-owned SSOT (api-first). 3// The video room's protocol constants (linear-memory region map + lane/codec params) were hand-duplicated 4// across app.v2.js AND nishi-video.component.js AND the wasm core -- three hand-maintained copies of one 5// contract (violates rule #11 no-magic-numbers + rule #15 DRY). This organ makes NishiLang the SINGLE 6// source of truth: it (1) EMITS the documented contract web_assets/nishi_room_protocol.txt and (2) VALIDATES 7// that BOTH shipped JS clients conform to it. Any client that drifts a constant -> RED. A mobile-native 8// client consumes the SAME contract with ZERO JS. This is the "lean into nishi lang / api-first" rung. 9// expect_exit: 0 license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "nx_gate_verdict.nx" 12 13func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 14" as *u8); return ok } 15func gn(v: i64) -> i64 { 16 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 17 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} 18 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 19 20// ---- the SSOT contract table (the ONE authoritative definition) ---- 21func rp_count() -> i64 { return 23 } 22func rp_name(i: i64) -> *u8 { 23 if i==0 { return "R_ID" as *u8 } 24 if i==1 { return "R_PAY" as *u8 } 25 if i==2 { return "R_WOUT" as *u8 } 26 if i==3 { return "R_WIN" as *u8 } 27 if i==4 { return "R_INFO" as *u8 } 28 if i==5 { return "R_F32" as *u8 } 29 if i==6 { return "R_FOUT" as *u8 } 30 if i==7 { return "R_PCM" as *u8 } 31 if i==8 { return "R_SCR" as *u8 } 32 if i==9 { return "R_STAGE" as *u8 } 33 if i==10 { return "R_STAGE2" as *u8 } 34 if i==11 { return "R_FTBL" as *u8 } 35 if i==12 { return "R_FSD" as *u8 } 36 if i==13 { return "R_FSS" as *u8 } 37 if i==14 { return "R_FOUT2" as *u8 } 38 if i==15 { return "R_FSCRA" as *u8 } 39 if i==16 { return "R_FSCRSH" as *u8 } 40 if i==17 { return "R_FDEC" as *u8 } 41 if i==18 { return "R_CHAT" as *u8 } 42 if i==19 { return "R_FST" as *u8 } 43 if i==20 { return "LANES" as *u8 } 44 if i==21 { return "AUDIO_CHUNK" as *u8 } 45 if i==22 { return "R_PLAN" as *u8 } 46 return "" as *u8 } 47func rp_val(i: i64) -> i64 { 48 if i==0 { return 0x200000 } 49 if i==1 { return 0x200100 } 50 if i==2 { return 0x220000 } 51 if i==3 { return 0x240000 } 52 if i==4 { return 0x260000 } 53 if i==5 { return 0x270000 } 54 if i==6 { return 0x280000 } 55 if i==7 { return 0x290000 } 56 if i==8 { return 0x2A0000 } 57 if i==9 { return 0x300000 } 58 if i==10 { return 0x400000 } 59 if i==11 { return 0x3000000 } 60 if i==12 { return 0x3010000 } 61 if i==13 { return 0x3020000 } 62 if i==14 { return 0x3030000 } 63 if i==15 { return 0x3040000 } 64 if i==16 { return 0x3050000 } 65 if i==17 { return 0x3060000 } 66 if i==18 { return 0x3080000 } 67 if i==19 { return 0x3100000 } 68 if i==20 { return 3 } 69 if i==21 { return 1024 } 70 if i==22 { return 0x2B0000 } // mb_plan output region (9 i64) -- the resource-intelligence API 71 return 0 } 72 73func is_ic(c: i64) -> i64 { 74 if c>=48 { if c<=57 { return 1 } } 75 if c>=65 { if c<=90 { return 1 } } 76 if c>=97 { if c<=122 { return 1 } } 77 if c==95 { return 1 } 78 return 0 } 79 80// parse an integer literal at hay[p0..] -- supports 0x hex and decimal 81func parse_int_at(hay: *u8, n: i64, p0: i64) -> i64 { 82 var p: i64 = p0 83 var base: i64 = 10 84 if p+1<n { if (hay[p] as i64)==48 { if (hay[p+1] as i64)==120 { base=16; p=p+2 } } } 85 var v: i64 = 0 86 var g: i64 = 1 87 while g==1 { 88 if p<n { 89 let c: i64 = hay[p] as i64 90 var d: i64 = 0-1 91 if c>=48 { if c<=57 { d=c-48 } } 92 if base==16 { if c>=97 { if c<=102 { d=c-97+10 } } } 93 if base==16 { if c>=65 { if c<=70 { d=c-65+10 } } } 94 if d<0 { g=0 } else { v=v*base+d; p=p+1 } 95 } else { g=0 } 96 } 97 return v } 98 99// find whole-word `name` FOLLOWED BY `= <int>` (a definition, not a usage); return value or -1 100func find_word_int(hay: *u8, n: i64, name: *u8) -> i64 { 101 var nl: i64=0; while name[nl]!=(0 as u8){nl=nl+1} 102 var i: i64=0 103 while i+nl<=n { 104 var j: i64=0; var ok: i64=1 105 while j<nl { if hay[i+j]!=name[j]{ok=0;j=nl} else {j=j+1} } 106 if ok==1 { 107 var bound: i64=1 108 if i>0 { if is_ic(hay[i-1] as i64)==1 { bound=0 } } 109 if i+nl<n { if is_ic(hay[i+nl] as i64)==1 { bound=0 } } 110 if bound==1 { 111 var p: i64=i+nl 112 var g: i64=1 113 while g==1 { if p<n { if (hay[p] as i64)==32 { p=p+1 } else { g=0 } } else { g=0 } } 114 if p<n { if (hay[p] as i64)==61 { 115 p=p+1 116 var g3: i64=1 117 while g3==1 { if p<n { if (hay[p] as i64)==32 { p=p+1 } else { g3=0 } } else { g3=0 } } 118 if p<n { if (hay[p] as i64)>=48 { if (hay[p] as i64)<=57 { return parse_int_at(hay,n,p) } } } 119 } } 120 } 121 } 122 i=i+1 123 } 124 return 0 - 1 } 125 126func fw(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 } 127func fhex(fd: i64, v: i64) -> i64 { 128 sys_write(fd, "0x" as *u8, 2) 129 let t: *u8 = sys_mmap(24); var m: i64=v; var k: i64=0 130 if m==0 { t[0]=48 as u8; k=1 } 131 while m>0 { let d: i64=m%16; if d<10 { t[k]=(48+d) as u8 } else { t[k]=(97+d-10) as u8 } m=m/16; k=k+1 } 132 let b: *u8 = sys_mmap(24); var i: i64=0 133 while i<k { b[i]=t[k-1-i]; i=i+1 } 134 sys_write(fd, b, k); return 0 } 135func fdec(fd: i64, v: i64) -> i64 { 136 let t: *u8 = sys_mmap(24); var m: i64=v; var k: i64=0 137 if m==0 { t[0]=48 as u8; k=1 } 138 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 139 let b: *u8 = sys_mmap(24); var i: i64=0 140 while i<k { b[i]=t[k-1-i]; i=i+1 } 141 sys_write(fd, b, k); return 0 } 142 143func main() -> i64 { 144 gw("=== nx_room_protocol_gate: Nishi-owned room contract SSOT + client conformance ===\n" as *u8) 145 // read both shipped JS clients 146 let abox: *i64 = sys_mmap(16) as *i64; abox[0]=0 147 let app: *u8 = sys_read_file("sites/nishifamily/video/app.v2.js" as *u8, abox) 148 if (app as i64)==0 { gw("no app.v2.js\n" as *u8); return 1 } 149 let an: i64 = abox[0] 150 let cbox: *i64 = sys_mmap(16) as *i64; cbox[0]=0 151 let comp: *u8 = sys_read_file("sites/nishifamily/video/nishi-video.component.js" as *u8, cbox) 152 if (comp as i64)==0 { gw("no nishi-video.component.js\n" as *u8); return 1 } 153 let cn: i64 = cbox[0] 154 155 // 1. EMIT the documented contract (the SSOT artifact any client -- web OR mobile-native -- consumes) 156 let fd: i64 = sys_openat_wr("web_assets/nishi_room_protocol.txt" as *u8, 0x1a4) 157 if fd < 0 { gw("cannot write nishi_room_protocol.txt\n" as *u8); return 1 } 158 fw(fd, "# Nishi Room Protocol -- SSOT (emitted by nx_room_protocol_gate). Clients CONSUME; never hand-copy.\n" as *u8) 159 fw(fd, "# wasm linear-memory region map + lane/codec params. A mobile-native client uses these with ZERO JS.\n" as *u8) 160 var t: i64 = 0 161 while t < rp_count() { 162 fw(fd, rp_name(t)); fw(fd, "=" as *u8); fhex(fd, rp_val(t)); fw(fd, " (" as *u8); fdec(fd, rp_val(t)); fw(fd, ")\n" as *u8) 163 t = t + 1 164 } 165 sys_close(fd) 166 gw(" emitted web_assets/nishi_room_protocol.txt (" as *u8); gn(rp_count()); gw(" contract constants)\n" as *u8) 167 168 // 2. VALIDATE both clients conform to the SSOT 169 var green: i64 = 1 170 var i: i64 = 0 171 while i < rp_count() { 172 let want: i64 = rp_val(i) 173 let av: i64 = find_word_int(app, an, rp_name(i)) 174 let cv: i64 = find_word_int(comp, cn, rp_name(i)) 175 var okrow: i64 = 1 176 if av != want { okrow = 0 } 177 if cv != want { okrow = 0 } 178 gw(" " as *u8); gw(rp_name(i)) 179 gw(" want=" as *u8); gn(want); gw(" app.v2=" as *u8); gn(av); gw(" component=" as *u8); gn(cv) 180 if okrow==1 { gw(" OK\n" as *u8) } else { gw(" !!! DRIFT\n" as *u8); green=0 } 181 i = i + 1 182 } 183 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 184 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 185 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 186 let ctr__dry: *i64 = gv_ctr() 187 ctr__dry[0] = green 188 ctr__dry[1] = 1 189 let rc__dry: i64 = gv_verdict("ROOM-PROTOCOL-GATE" as *u8, ctr__dry, "both JS clients conform to the Nishi-owned contract SSOT" as *u8) 190 sys_exit(rc__dry) 191 return rc__dry 192}