code wiki / _hdl_build / nx_gate_loop_register.nx

nx_gate_loop_register.nx source

↩ module page · 124 lines · 5745 B

1// nx_gate_loop_register.nx -- GOVERNED registration of the gate loop daemon 2// (GAME arc G5). ENGINEER verdict, all mechanical: 3// (a) pidfile names a LIVE pid (/proc/<pid>/comm opens); 4// (b) a second start REFUSES (singleton; exit 3) -- two loops would race 5// the gate's shared /tmp artifacts (observed corrupting verdicts); 6// (c) at least one GATELOOP beat line exists in the loop log. 7// Also flags the __syscall translation-table gap found during the build: 8// rv64 getpid (172) is NOT translated -> x86 received 172=iopl -> -ENOSYS. 9// license_tier: ORIGINAL 10import "nx_cap_register.nx" 11import "nx_pm_review_log.nx" 12import "nx_syscalls.nx" 13 14const GLR_LAYER: i64 = 4 15const GLR_STATUS: i64 = 2 16const GLR_IDX: i64 = 218 17const GLR_NLAYERS: i64 = 6 18 19func glr_run0(path: *u8) -> i64 { 20 let pid: i64 = sys_fork() 21 if pid == 0 { 22 let devnull: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 23 if devnull >= 0 { sys_dup3(devnull, 1, 0) } 24 let argv: *i64 = sys_mmap(32) as *i64; argv[0] = path as i64; argv[1] = 0 25 let envp: *i64 = sys_mmap(16) as *i64; envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 26 sys_execve(path, argv, envp); sys_exit(127) 27 } 28 let st: *i64 = sys_mmap(16) as *i64 29 sys_wait4(pid, st, 0) 30 let sig: i64 = st[0] & 0x7f 31 if sig != 0 { return 128 + sig } 32 return (st[0] >> 8) & 0xff 33} 34 35func glr_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } return off + i } 36func glr_cat_n(dst: *u8, off: i64, v: i64) -> i64 { 37 var o: i64 = off 38 var m: i64 = v 39 if m < 0 { dst[o] = 45; o = o + 1; m = 0 - m } 40 let t: *u8 = sys_mmap(28) 41 var k: i64 = 0 42 if m == 0 { t[0] = 48; k = 1 } 43 while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 } 44 var i: i64 = 0 45 while i < k { dst[o+i] = t[k-1-i]; i = i + 1 } 46 return o + k 47} 48 49func glr_read_pidfile() -> i64 { 50 let len_p: *i64 = sys_mmap(8) as *i64 51 let buf: *u8 = sys_read_file("/tmp/nishi_game_gate_loop.pid" as *u8, len_p) 52 if (buf as i64) == 0 { return 0 - 1 } 53 let n: i64 = len_p[0] 54 var v: i64 = 0 55 var any: i64 = 0 56 var i: i64 = 0 57 while i < n { 58 let c: i64 = buf[i] as i64 59 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1 } } 60 i = i + 1 61 } 62 if any == 0 { return 0 - 1 } 63 return v 64} 65 66func glr_pid_alive(pid: i64) -> i64 { 67 if pid <= 0 { return 0 } 68 let p: *u8 = sys_mmap(64) 69 var o: i64 = 0 70 o = glr_cat(p, o, "/proc/" as *u8) 71 o = glr_cat_n(p, o, pid) 72 o = glr_cat(p, o, "/comm" as *u8) 73 p[o] = 0 as u8 74 let fd: i64 = sys_openat_rd(p) 75 if fd < 0 { return 0 } 76 sys_close(fd) 77 return 1 78} 79 80func main() -> i64 { 81 // (a) live daemon per pidfile 82 let dpid: i64 = glr_read_pidfile() 83 let alive: i64 = glr_pid_alive(dpid) 84 cr_w(1, "ENGINEER: pidfile pid=" as *u8); cr_wn(1, dpid) 85 cr_w(1, " alive=" as *u8); cr_wn(1, alive); cr_w(1, " (need 1)\n" as *u8) 86 87 // (b) singleton refusal 88 let rc2: i64 = glr_run0("/tmp/nx_gate_loop.sov.elf" as *u8) 89 cr_w(1, "ENGINEER: second-start exit=" as *u8); cr_wn(1, rc2); cr_w(1, " (need 3 = refused)\n" as *u8) 90 91 // (c) beat evidence 92 let len_p: *i64 = sys_mmap(8) as *i64 93 let lbuf: *u8 = sys_read_file("/tmp/nishi_game_gate_loop.log" as *u8, len_p) 94 var beats: i64 = 0 95 if (lbuf as i64) != 0 { if len_p[0] > 0 { beats = 1 } } 96 cr_w(1, "ENGINEER: loop log non-empty=" as *u8); cr_wn(1, beats); cr_w(1, " (need 1)\n" as *u8) 97 98 var exit_ok: i64 = 0 99 if alive == 1 { if rc2 == 3 { if beats == 1 { exit_ok = 1 } } } 100 let eng: i64 = ig_engineer(1, 1, 1, exit_ok) 101 102 let cat: i64 = sys_openat_rd("knowledge/CAPABILITY_CATALOG.md" as *u8) 103 var documented: i64 = 0 104 if cat >= 0 { documented = ig_documented(1, 1); sys_close(cat) } 105 let council: i64 = ig_council(eng, 1, 1, 2) 106 let decision: i64 = ig_decision(eng, council, documented) 107 108 let pm: i64 = pm_open("/tmp/nishi_pm_review.log" as *u8) 109 if decision == IG_INGEST { 110 pm_deliverable(pm, "game-engine/gates" as *u8, "nx_gate_loop" as *u8, "GAME-G5 CLOSED: singleton loop daemon (pidfile+/proc aliveness, fork+setsid detach) runs nx_gate_sentinel every 30min; beats -> /tmp/nishi_game_gate_loop.log; regressions auto-escalate via the sentinel; grades now refresh with NO human/LLM trigger" as *u8) 111 } 112 pm_gap(pm, "toolchain/compiler" as *u8, "NEEDS-FIX" as *u8, "__syscall rv64 translation table incomplete" as *u8, "rv64 getpid(172) is NOT in the rv64->x86 translation table: x86 received raw 172=iopl -> -ENOSYS; a pidfile silently filled with -38 and the loop singleton failed open (two daemons raced the gate). Audit the table for other missing common numbers (getppid/kill/getuid...); meanwhile /proc/self/stat is the table-independent getpid." as *u8) 113 sys_close(pm) 114 cr_w(1, "GOVERNED decision=" as *u8); cr_wn(1, decision); cr_w(1, " (1=INGEST); PM log updated\n" as *u8) 115 116 if decision != IG_INGEST { sys_exit(1) } 117 if cr_can_register(GLR_LAYER, GLR_STATUS, GLR_NLAYERS, decision) != 1 { cr_w(1, "REFUSED\n" as *u8); sys_exit(1) } 118 let fd: i64 = sys_openat_append("/tmp/nishi_cap_registry.log" as *u8, 0x1a4) 119 cr_write_entry(fd, GLR_IDX, GLR_LAYER, "CON GATE-LOOP -- singleton daemon (pidfile + /proc aliveness; fork+setsid; refuses double-start exit 3) running nx_gate_sentinel on a 30-min beat; beats logged to /tmp/nishi_game_gate_loop.log; closes GAME-G5: game-engine grades refresh autonomously, regressions escalate to the PM review log with no LLM in the loop" as *u8, GLR_STATUS) 120 sys_close(fd) 121 cr_w(1, "CAPREG idx=" as *u8); cr_wn(1, GLR_IDX); cr_w(1, " REGISTERED\n" as *u8) 122 sys_exit(0) 123 return 0 124}