code wiki / _hdl_build / nx_video_chat_gate.nx
nx_video_chat_gate.nx source
↩ module page · 54 lines · 3632 B
1// nx_video_chat_gate.nx -- gate for the /video ROOM TEXT CHAT rung (R3 of the rival-parity ladder,
2// operator 2026-07-02 "have all of their features like texting"). Proves the WIRING is present in the
3// shipped client sources: (a) app.js sends type:"chat" over the existing relay (zero server change --
4// nx_signaling_v2 sig2_broadcast fans any frame out), (b) app.js receives + renders via textContent
5// (no HTML injection), (c) history persists in the PROFILE namespace nishi_chat_<room> (separate from
6// clearable caches -- the browser profile-store split), (d) index.html carries the panel + composer +
7// unread badge. LIVENESS of the deployed copy = the funcheck row video_chat (this gate is source-truth;
8// funcheck is served-truth). NEG-control: a bogus pattern must be ABSENT or the gate is a liar.
9// expect_exit: 0 license_tier: ORIGINAL
10import "nx_syscalls.nx"
11
12func slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
13func pw(s: *u8) -> i64 { sys_write(1,s,slen(s)); return 0 }
14func pn(v: i64) -> i64 {
15 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m}
16 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}
17 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 }
18func contains(hay: *u8, n: i64, needle: *u8) -> i64 {
19 let nl: i64=slen(needle); if nl==0 {return 1}
20 var i: i64=0
21 while i+nl<=n { var j: i64=0; var ok: i64=1; while j<nl { if hay[i+j]!=needle[j]{ok=0;j=nl} else {j=j+1} } if ok==1{return 1} i=i+1 }
22 return 0 }
23func filehas(path: *u8, pat: *u8) -> i64 {
24 let box: *i64 = sys_mmap(16) as *i64; box[0]=0
25 let b: *u8 = sys_read_file(path, box)
26 if (b as i64)==0 { return 0 }
27 return contains(b, box[0], pat) }
28func check(name: *u8, path: *u8, pat: *u8, want: i64) -> i64 {
29 let got: i64 = filehas(path, pat)
30 pw(" " as *u8)
31 if got==want { pw("PASS " as *u8) } else { pw("FAIL " as *u8) }
32 pw(name); pw("\n" as *u8)
33 if got==want { return 1 }
34 return 0 }
35
36func main() -> i64 {
37 pw("=== nx_video_chat_gate: room text chat wiring (R3 rival-parity) ===\n" as *u8)
38 var pass: i64 = 0
39 let APPJS: *u8 = "sites/nishifamily/video/app.js" as *u8
40 let HTML: *u8 = "sites/nishifamily/video/index.html" as *u8
41 pass = pass + check("T1 app.js sends type:chat over the relay " as *u8, APPJS, "type: \"chat\"" as *u8, 1)
42 pass = pass + check("T2 app.js receives m.type===chat " as *u8, APPJS, "m.type === \"chat\"" as *u8, 1)
43 pass = pass + check("T3 history in PROFILE namespace nishi_chat_ " as *u8, APPJS, "nishi_chat_" as *u8, 1)
44 pass = pass + check("T4 injection-safe render (textContent) " as *u8, APPJS, "w.textContent = mine" as *u8, 1)
45 pass = pass + check("T5 history capped (no unbounded growth) " as *u8, APPJS, "h.slice(-200)" as *u8, 1)
46 pass = pass + check("T6 index.html chat panel " as *u8, HTML, "id=\"chatlog\"" as *u8, 1)
47 pass = pass + check("T7 index.html composer input " as *u8, HTML, "id=\"chatin\"" as *u8, 1)
48 pass = pass + check("T8 index.html bar button + unread badge " as *u8, HTML, "id=\"chatBadge\"" as *u8, 1)
49 pass = pass + check("T9 NEG-control bogus pattern ABSENT " as *u8, APPJS, "zz_bogus_chat_pattern_qq" as *u8, 0)
50 pw("VIDEO-CHAT-GATE pass=" as *u8); pn(pass); pw("/9" as *u8)
51 if pass==9 { pw(" verdict=GREEN -- chat wired in source; deploy + funcheck video_chat row = served-truth\n" as *u8); return 0 }
52 pw(" verdict=RED\n" as *u8)
53 return 1
54}