code wiki / _hdl_build / nx_home_gate.nx
nx_home_gate.nx source
↩ module page · 94 lines · 7184 B
1// nx_home_gate.nx -- SOVEREIGN loopback proof of nx_home (H0 control plane). Forks the real /tmp/nx_home.sov.elf,
2// then a Nishi HTTP client (this gate) drives it over a loopback socket -- no python/shell, no real hardware:
3// R1 GET state lists the registry (living_room/bedroom/kitchen)
4// R2 all devices start OFF (zero "on":1)
5// R3 POST cmd on=1&bri=80 -> response shows on:1, brightness:80 (command applied + returned)
6// R4 GET state -> the change PERSISTED (exactly one on:1, brightness 80 present)
7// R5 repeat the same cmd -> identical (IDEMPOTENT, #10)
8// R6 unknown device -> "unknown device" (structured error)
9// R7 unknown device -> HTTP 404 status
10// Then POST /home/shutdown for clean teardown (no sys_kill needed). GREEN iff 7/7. Requires /tmp/nx_home.sov.elf.
11// Durable knowledge/status/nx_home_gate.log. license_tier: ORIGINAL
12import "nx_syscalls.nx"
13import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host
14import "nx_gate_emit_lib.nx"
15
16func g_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; 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}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 }
17func g_w(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 }
18func g_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; 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}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 }
19func g_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
20func g_contains(hay: *u8, n: i64, needle: *u8) -> i64 {
21 let nl: i64=g_strlen(needle); if nl==0 { return 0 }
22 var i: i64=0
23 while i+nl<=n { var j: i64=0; var hit: i64=1; while j<nl { if hay[i+j]!=needle[j] { hit=0; j=nl } else { j=j+1 } } if hit==1 { return 1 } i=i+1 }
24 return 0
25}
26func g_count(hay: *u8, n: i64, needle: *u8) -> i64 {
27 let nl: i64=g_strlen(needle); if nl==0 { return 0 }
28 var cnt: i64=0; var i: i64=0
29 while i+nl<=n { var j: i64=0; var hit: i64=1; while j<nl { if hay[i+j]!=needle[j] { hit=0; j=nl } else { j=j+1 } } if hit==1 { cnt=cnt+1; i=i+nl } else { i=i+1 } }
30 return cnt
31}
32func g_sockaddr(buf: *u8, port: i64, a: i64, b: i64, c: i64, d: i64) -> i64 {
33 var i: i64=0; while i<16 { buf[i]=0 as u8; i=i+1 }
34 buf[0]=2 as u8; buf[2]=((port>>8)&0xff) as u8; buf[3]=(port&0xff) as u8
35 buf[4]=a as u8; buf[5]=b as u8; buf[6]=c as u8; buf[7]=d as u8; return 0
36}
37// connect (busy-retry past the fork race), send req, read full response (server closes); return len
38func http_req(port: i64, req: *u8, reqlen: i64, resp: *u8, cap: i64) -> i64 {
39 let dest: *u8=sys_mmap(16); g_sockaddr(dest, port, 127, 0, 0, 1)
40 var fd: i64=0; var connected: i64=0; var tries: i64=0
41 while connected==0 {
42 fd=sys_socket(AF_INET, SOCK_STREAM, 0); if fd<0 { return 0-1 }
43 if nx_connect_bounded(fd, dest, 16, NX_CONN_DEFAULT_MS)==0 { connected=1 } else { sys_close(fd); tries=tries+1; if tries>40000 { return 0-2 } }
44 }
45 sys_write(fd, req, reqlen)
46 var total: i64=0; var r: i64=sys_read(fd, resp, cap)
47 while r>0 { total=total+r; if total>=cap { r=0 } else { r=sys_read(fd, ((resp as i64)+total) as *u8, cap-total) } }
48 sys_close(fd); return total
49}
50
51func main() -> i64 {
52 g_puts("=== NX_HOME GATE: sovereign control-plane loopback (Nishi client + server; no python/shell) ===\n" as *u8)
53 let GETSTATE: *u8="GET /home/state HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n" as *u8
54 let CMDON: *u8="POST /home/cmd?id=living_room&on=1&bri=80 HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" as *u8
55 let CMDBAD: *u8="POST /home/cmd?id=nope HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" as *u8
56 let SHUTDOWN: *u8="POST /home/shutdown HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" as *u8
57
58 let pid: i64=sys_fork()
59 if pid==0 {
60 let o: i64=sys_openat_wr("/tmp/nx_home_srv.log" as *u8, 0x1a4); if o>=0 { sys_dup3(o,1,0); sys_dup3(o,2,0) }
61 let argv: *i64=sys_mmap(8*8) as *i64
62 argv[0]="/tmp/nx_home.sov.elf" as *u8 as i64; argv[1]="8200" as *u8 as i64; argv[2]=0
63 let envp: *i64=sys_mmap(16) as *i64; envp[0]="PATH=/usr/bin:/bin" as *u8 as i64; envp[1]=0
64 sys_execve("/tmp/nx_home.sov.elf" as *u8, argv, envp); sys_exit(127)
65 }
66
67 let r1: *u8=sys_mmap(65536); let n1: i64=http_req(8200, GETSTATE, g_strlen(GETSTATE), r1, 65536)
68 let r2: *u8=sys_mmap(65536); let n2: i64=http_req(8200, CMDON, g_strlen(CMDON), r2, 65536)
69 let r3: *u8=sys_mmap(65536); let n3: i64=http_req(8200, GETSTATE, g_strlen(GETSTATE), r3, 65536)
70 let r4: *u8=sys_mmap(65536); let n4: i64=http_req(8200, CMDON, g_strlen(CMDON), r4, 65536)
71 let r5: *u8=sys_mmap(65536); let n5: i64=http_req(8200, CMDBAD, g_strlen(CMDBAD), r5, 65536)
72 let r6: *u8=sys_mmap(4096); http_req(8200, SHUTDOWN, g_strlen(SHUTDOWN), r6, 4096)
73 let st: *i64=sys_mmap(16) as *i64; sys_wait4(pid, st, 0)
74
75 var pass: i64=0; let rows: i64=7
76 var lists: i64=0; if g_contains(r1,n1,"living_room" as *u8)==1 { if g_contains(r1,n1,"bedroom" as *u8)==1 { if g_contains(r1,n1,"kitchen" as *u8)==1 { lists=1 } } }
77 pass=pass+g_check(" R1 GET state lists 3 devices" as *u8, lists)
78 var offstart: i64=0; if g_count(r1,n1,"\"on\":1" as *u8)==0 { offstart=1 }
79 pass=pass+g_check(" R2 all devices start OFF" as *u8, offstart)
80 var applied: i64=0; if g_contains(r2,n2,"\"on\":1" as *u8)==1 { if g_contains(r2,n2,"\"brightness\":80" as *u8)==1 { applied=1 } }
81 pass=pass+g_check(" R3 POST cmd applied (on:1, bri:80 returned)" as *u8, applied)
82 var persisted: i64=0; if g_count(r3,n3,"\"on\":1" as *u8)==1 { if g_contains(r3,n3,"\"brightness\":80" as *u8)==1 { persisted=1 } }
83 pass=pass+g_check(" R4 state PERSISTED (exactly one on:1)" as *u8, persisted)
84 var idem: i64=0; if g_contains(r4,n4,"\"on\":1" as *u8)==1 { if g_contains(r4,n4,"\"brightness\":80" as *u8)==1 { idem=1 } }
85 pass=pass+g_check(" R5 IDEMPOTENT (repeat = same state)" as *u8, idem)
86 pass=pass+g_check(" R6 unknown device -> structured error" as *u8, g_contains(r5,n5,"unknown device" as *u8))
87 pass=pass+g_check(" R7 unknown device -> HTTP 404" as *u8, g_contains(r5,n5,"404" as *u8))
88
89 g_puts("----\nNX-HOME rows=" as *u8); g_num(rows); g_puts(" pass=" as *u8); g_num(pass); g_puts("\n" as *u8)
90 let lg: i64=sys_openat_append("knowledge/status/nx_home_gate.log" as *u8, 0x1a4)
91 if lg>=0 { g_w(lg, "NX-HOME rows=" as *u8); g_wn(lg, rows); g_w(lg, " pass=" as *u8); g_wn(lg, pass); if pass==rows { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } sys_close(lg) }
92 if pass==rows { g_puts("NX-HOME GREEN (sovereign home-control plane proven against a Nishi loopback)\n" as *u8); sys_exit(0); return 0 }
93 g_puts("NX-HOME RED\n" as *u8); sys_exit(1); return 1
94}