code wiki / (root) / nx_conductor_live.nx

nx_conductor_live.nx source

↩ module page · 280 lines · 16601 B

1// nx_conductor_live.nx -- the Nishi CONDUCTOR, v3: the LIVE, WARDEN-GATED tick 2// that ticks the INVENTION ORGANS via the SOVEREIGN code path (NO .sh). 3// 4// v1 (nx_conductor.nx) was OBSERVE-ONLY (measure canaries + journal, no Warden, 5// no action). v2 was LIVE+Warden-gated but dispatched each gate by fork+exec'ing 6// a .sh WRAPPER via /bin/bash -- the LAST non-sovereign part. v3 REMOVES that: 7// the beat now runs the invention organs (AUTHOR + VERIFY-BY-PROOF) directly via 8// the gr_gate shape ported INTO the Conductor (cl_run/cl_gate): fork+exec the 9// PINNED known-good compiler -> as -> ld -> nx_run_timeout, exit-code = verdict. 10// No /bin/bash, no .sh anywhere on the dispatch path -- argv[0] is the known-good 11// ELF / as / ld, never a shell. (Operator cardinal: sovereign NishiLang only.) 12// 13// Each BEAT it (1) asks the WARDEN to authorize the additive verify/author-to- 14// memory action, then (2) ticks the two invention organs hang-safe (each stage, 15// including cc/as/ld, runs under a self-SIGALRM deadline so a looping build- 16// oracle or organ kills itself -- it cannot wedge the beat), and (3) journals the 17// verdict to the event bus -- on cadence, UNATTENDED. This flips the build-> 18// verify->invent loop from "a human runs it" to "the crew ticks itself." 19// 20// The Warden GATES, it does not rubber-stamp: each beat we show it ALLOW the 21// safe (additive, read-only) verify/author-to-MEMORY tick AND DENY a forbidden 22// source overwrite -- proving the cardinal gate is live in the loop (#13 23// additive-only). The author organ EMITs to MEMORY only; an EMIT-to-SOURCE would 24// be a W_OVERWRITE_SRC -> DENIED. The exit code itself proves the deny fired on 25// every beat (warden_denies must == CL_BEATS). 26// 27// Composes nx_run_timeout (hang-safety + nx_rt_alarm) + nx_warden_lib (the 28// cardinal gate). Sovereign: raw syscalls, zero deps, ZERO shell. Bounded beats 29// (testable); the unbounded daemon is a config flip once this is trusted. 30// license_tier: ORIGINAL 31 32import "nx_run_timeout.nx" 33import "nx_warden_lib.nx" 34import "nx_win_ledger.nx" // ADDITIVE: post-verify win-ledger journaling (self-learning capture) 35import "nx_framed_append.nx" // WMS LIVE-1/LIVE-3: locked single-write framing (heartbeat + event-log torn-write kill) 36 37const CL_EVENTLOG: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/_offc/nx_crew_events.log" 38const CL_GATE_TIMEOUT_MS: i64 = 12000 // per-organ RUN hang bound 39const CL_BUILD_TIMEOUT_MS: i64 = 60000 // per cc/as/ld stage hang bound (compiler can loop) 40const CL_CADENCE_MS: i64 = 500 // sleep between beats (short for the demo) 41const CL_BEATS: i64 = 3 // bounded; unbounded daemon = config flip 42const CL_MODE_FILE: i64 = 420 43const CL_NGATES: i64 = 2 // the two invention organs (author + verify-by-proof) 44 45// SOVEREIGN dispatch oracles -- the PINNED known-good compiler + tolerated build 46// oracles (as/ld). argv[0] of every spawn below is one of THESE, never /bin/bash. 47const CL_CC: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/_offc/nx_cc_known_good.elf" 48const CL_AS: *u8 = "/usr/bin/as" 49const CL_LD: *u8 = "/usr/bin/ld" 50// UNIQUE /tmp tag (distinct from gr_gate's /tmp/nx_gr.* -> no race vs gate-runner) 51const CL_S: *u8 = "/tmp/nx_cl.s" 52const CL_O: *u8 = "/tmp/nx_cl.o" 53const CL_ELF: *u8 = "/tmp/nx_cl.elf" 54// WMS LIVE-1/LIVE-3 additive wiring 55const CL_REC_CAP: i64 = 256 // bounded event/heartbeat record (matches WMS-R0 RECCAP) 56const CL_HB_CHANNEL: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/knowledge/status/wms_heartbeat.log" 57const CL_CONDUCTOR_WS: i64 = 1 // the conductor's own workstream id in the heartbeat channel 58 59func cl_wstr(fd: i64, s: *u8) -> i64 { 60 var n: i64 = 0 61 while s[n] != 0 as u8 { n = n + 1 } 62 sys_write(fd, s, n) 63 return 0 64} 65func cl_wnum(fd: i64, n: i64) -> i64 { 66 if n == 0 { sys_write(fd, "0" as *u8, 1); return 0 } 67 var m: i64 = n 68 let d: *u8 = sys_mmap(24) 69 var k: i64 = 0 70 while m > 0 { d[k] = (0x30 + (m % 10)) as u8; m = m / 10; k = k + 1 } 71 var i: i64 = k - 1 72 while i >= 0 { let o: *u8 = sys_mmap(1); o[0] = d[i]; sys_write(fd, o, 1); i = i - 1 } 73 return 0 74} 75 76// WMS LIVE-1: beat the conductor's own liveness as ONE locked framed write. Mirrors 77// nx_heartbeat_monitor's hbm_build "HBX ws=<id> epoch=<e> seq=<n> actor=<pid> END" contract so M1's 78// hbm_scan reads it -- inlined (single fa_appendz) so the live daemon needs no main-bearing import. 79// Additive + fire-and-forget: the beat NEVER affects the verdict/Warden/exit accounting below. 80func cl_hb_beat(seq: i64) -> i64 { 81 let epoch: i64 = sys_now_realtime_sec() 82 let pid: i64 = __syscall(172, 0, 0, 0, 0, 0, 0) // getpid (actor). rv64 getpid=172; raw x86 39 is an RV64 KEY translated to ioctl(16) -> -ENOTTY (debt idx 2277) 83 let buf: *u8 = sys_mmap(CL_REC_CAP + 16) 84 var o: i64 = 0 85 o = fa_cat(buf, o, "HBX ws=" as *u8); o = fa_catn(buf, o, CL_CONDUCTOR_WS) 86 o = fa_cat(buf, o, " epoch=" as *u8); o = fa_catn(buf, o, epoch) 87 o = fa_cat(buf, o, " seq=" as *u8); o = fa_catn(buf, o, seq) 88 o = fa_cat(buf, o, " actor=" as *u8); o = fa_catn(buf, o, pid) 89 o = fa_cat(buf, o, " END" as *u8) 90 buf[o] = 0 as u8 91 return fa_appendz(CL_HB_CHANNEL, buf, CL_REC_CAP) 92} 93 94// SOVEREIGN spawn: fork+exec `path` with argv/envp, child stdout -> out_path if 95// non-null else /dev/null, stderr -> /dev/null. Ported from gr_run BUT made 96// hang-safe -- the child arms a self-SIGALRM deadline (nx_rt_alarm, reused from 97// nx_run_timeout) before execve, so a looping build-oracle (the known-good 98// compiler CAN loop on bad source; see the print-codegen-triage ledger) kills 99// ITSELF at the deadline instead of wedging the beat. Guards pid<0 BEFORE wait4 100// so a fork failure is never silently decoded as exit 0 (a false PROVEN). On 101// success returns the child exit code; on a deadline hit returns NX_RT_TIMEOUT; 102// on fork failure returns NX_RT_FORK_FAIL. 103func cl_run(path: *u8, argv: *i64, envp: *i64, out_path: *u8, timeout_ms: i64) -> i64 { 104 var tsec: i64 = (timeout_ms + 999) / 1000 // ceil to whole seconds 105 if tsec < 1 { tsec = 1 } 106 let pid: i64 = sys_fork() 107 if pid == 0 { 108 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0) 109 if (out_path as i64) != 0 { 110 let ofd: i64 = sys_openat_wr(out_path, CL_MODE_FILE) 111 if ofd >= 0 { sys_dup3(ofd, 1, 0) } 112 } 113 if (out_path as i64) == 0 { if dn >= 0 { sys_dup3(dn, 1, 0) } } 114 if dn >= 0 { sys_dup3(dn, 2, 0) } 115 nx_rt_alarm(tsec) // self-deadline: SIGALRM terminates a hung stage 116 sys_execve(path, argv, envp) 117 sys_exit(127) 118 } 119 if pid < 0 { return NX_RT_FORK_FAIL } 120 let st: *i64 = sys_mmap(16) as *i64 121 let r: i64 = sys_wait4(pid, st, 0) 122 if r < 0 { return NX_RT_FORK_FAIL } 123 let status: i64 = st[0] 124 let termsig: i64 = status & 0x7f 125 if termsig == NX_RT_SIGALRM { return NX_RT_TIMEOUT } // deadline hit = HANG/loop 126 if termsig != 0 { return 1000 + termsig } // other signal = crashed 127 return wait_exit_code(status) 128} 129 130// SOVEREIGN gate: compile + assemble + link an invention organ .nx, then run it 131// hang-safe; the organ's exit code IS the verdict (0 = PROVEN), or a negative 132// stage code on a build-oracle failure, or NX_RT_TIMEOUT on any hang. This is the 133// gr_gate shape ported into the Conductor -- argv[0] is the known-good ELF / as / 134// ld, NEVER /bin/bash. EVERY stage (cc/as/ld AND the run) is deadline-bounded. 135func cl_gate(testnx: *u8, elapsed_out: *i64) -> i64 { 136 let envp: *i64 = sys_mmap(8) as *i64 137 envp[0] = 0 138 // 1. compile: cc testnx > CL_S 139 let a1: *i64 = sys_mmap(32) as *i64 140 a1[0] = CL_CC as i64; a1[1] = testnx as i64; a1[2] = 0 141 if cl_run(CL_CC, a1, envp, CL_S, CL_BUILD_TIMEOUT_MS) != 0 { return 0 - 1 } 142 // 2. assemble: as CL_S -o CL_O 143 let a2: *i64 = sys_mmap(40) as *i64 144 a2[0] = CL_AS as i64; a2[1] = CL_S as i64; a2[2] = ("-o" as *u8) as i64; a2[3] = CL_O as i64; a2[4] = 0 145 if cl_run(CL_AS, a2, envp, 0 as *u8, CL_BUILD_TIMEOUT_MS) != 0 { return 0 - 2 } 146 // 3. link: ld -o CL_ELF CL_O 147 let a3: *i64 = sys_mmap(40) as *i64 148 a3[0] = CL_LD as i64; a3[1] = ("-o" as *u8) as i64; a3[2] = CL_ELF as i64; a3[3] = CL_O as i64; a3[4] = 0 149 if cl_run(CL_LD, a3, envp, 0 as *u8, CL_BUILD_TIMEOUT_MS) != 0 { return 0 - 3 } 150 // 4. run the organ hang-safe; its exit code IS the verdict 151 let a4: *i64 = sys_mmap(16) as *i64 152 a4[0] = CL_ELF as i64; a4[1] = 0 153 return nx_run_timeout(CL_ELF, a4, envp, CL_GATE_TIMEOUT_MS, elapsed_out) 154} 155 156// WMS LIVE-3: the event record was 8 sequential sys_write calls to one O_APPEND fd -- a torn-write 157// channel under concurrent beats (the exact "NOTES epoch=NOTES epoch=" bug class). Now assembled 158// into ONE buffer and emitted with a SINGLE locked fa_appendz. Output is byte-identical 159// ("beat=<b> tick=<label> verdict=<v> ms=<ms>\n"); fa_appendz supplies the framing newline. 160func cl_event(beat: i64, label: *u8, verdict: *u8, ms: i64) -> i64 { 161 let buf: *u8 = sys_mmap(CL_REC_CAP + 16) 162 var o: i64 = 0 163 o = fa_cat(buf, o, "beat=" as *u8); o = fa_catn(buf, o, beat) 164 o = fa_cat(buf, o, " tick=" as *u8); o = fa_cat(buf, o, label) 165 o = fa_cat(buf, o, " verdict=" as *u8); o = fa_cat(buf, o, verdict) 166 o = fa_cat(buf, o, " ms=" as *u8); o = fa_catn(buf, o, ms) 167 buf[o] = 0 as u8 168 return fa_appendz(CL_EVENTLOG, buf, CL_REC_CAP) 169} 170 171// ADDITIVE win-ledger journaling for ONE verify-by-proof verdict. Strictly a 172// SIDE EFFECT: it records the verified organ as an NxWinRecord (claim=the organ, 173// repro=the SAME gate just ticked, expected=the gate's real known answer) and 174// re-verifies it on the PINNED compiler, appending HOLDS/REFUTED to the ledger's 175// own in-memory hash-chained journal. It is FIRE-AND-FORGET: every failure path 176// (null ledger, invalid record, journal append fault) is swallowed and returns 177// without touching the beat -- so journaling can never flip the beat verdict, the 178// Warden ALLOW/DENY asserts, or the exit gate. Returns the ledger entry count 179// AFTER this attempt (unchanged on any failure), purely for the proof line. 180func cl_journal_win(L: *NxWinLedger, repro_gate: *u8) -> i64 { 181 if (L as i64) == 0 { return -1 } // non-fatal: no ledger -> skip 182 if nx_win_ledger_is_valid(L) != 1 { return -1 } // non-fatal: bad ledger -> skip 183 let r: *NxWinRecord = nx_win_record_new( 184 "verify-by-proof: mul x8 == shl x3 (membership-as-PROOF)" as *u8, // claim = the organ verified 185 "meet" as *u8, // exceed axis 186 "e-graph membership re-derives the strength-reduction equiv; sound per rule_soundness gate" as *u8, 187 repro_gate, // repro = the SAME gate just ticked 188 "3584" as *u8) // expected known answer (mul 448 x8 == shl 448 x3) 189 if (r as i64) == 0 { return nx_win_ledger_count(L) } // non-fatal: alloc fault -> skip, count unchanged 190 nx_win_record_add_assumption(r, "pinned nx_cc_known_good.elf re-gates (not the active poisoned compiler)" as *u8) 191 nx_win_record_add_assumption(r, "membership proof is total over the tested operand domain" as *u8) 192 // record_and_verify is itself defensive (returns negative on bad input, never 193 // crashes); its return is ADVISORY only -- we do not branch the beat on it. 194 nx_win_ledger_record_and_verify(L, r) 195 return nx_win_ledger_count(L) 196} 197 198func main() -> i64 { 199 cl_wstr(1, "NISHI CONDUCTOR v3 -- LIVE, WARDEN-GATED tick: ticks the INVENTION ORGANS sovereign (no .sh), UNATTENDED\n") 200 cl_wstr(1, "===================================================================================================\n") 201 202 // the verification grid = the two INVENTION ORGANS (proven gate-runner 16+18), 203 // ticked via the sovereign cl_gate path -- NO .sh, argv[0] = known-good ELF. 204 let names: *i64 = sys_mmap(CL_NGATES * 8) as *i64 205 let gates: *i64 = sys_mmap(CL_NGATES * 8) as *i64 206 names[0] = ("author : superopt PROPOSE/SCORE/VERIFY/EMIT(mem) " as *u8) as i64 207 gates[0] = ("/mnt/c/Users/elder/nishi-core/nxc2/runtime/_hdl_build/nx_superopt_test.nx" as *u8) as i64 208 names[1] = ("verify : membership-as-PROOF (mul x8 == shl x3) " as *u8) as i64 209 gates[1] = ("/mnt/c/Users/elder/nishi-core/nxc2/runtime/_hdl_build/nx_eqsat_membership_proof_test.nx" as *u8) as i64 210 211 // ADDITIVE: a process-local win-ledger (in-memory, hash-chained) capturing 212 // each verify-by-proof verdict as a falsifiable win record. Constructed OUTSIDE 213 // the beat-verdict / Warden / exit accounting -- pure self-learning capture. 214 let win_ledger: *NxWinLedger = nx_win_ledger_new() 215 216 var beat: i64 = 0 217 var allgreen_beats: i64 = 0 218 var warden_denies: i64 = 0 219 while beat < CL_BEATS { 220 cl_wstr(1, "beat "); cl_wnum(1, beat); cl_wstr(1, ":\n") 221 cl_hb_beat(beat) // WMS LIVE-1: durable liveness beat -> M1 sees a real crash as STALLED 222 223 // THE WARDEN GATES THE TICK. allow the safe verify action... 224 let auth: i64 = warden_authorize(W_ADDITIVE, CL_EVENTLOG, 0) 225 // ...and prove it DENIES a forbidden one (overwriting source). 226 let deny: i64 = warden_authorize(W_OVERWRITE_SRC, "/mnt/c/Users/elder/nishi-core/nxc2/runtime/nx_eqsat.nx" as *u8, 1) 227 if deny == W_DENY { warden_denies = warden_denies + 1 } 228 cl_wstr(1, " warden: verify-tick=") 229 if auth == W_ALLOW { cl_wstr(1, "ALLOW") } else { cl_wstr(1, "DENY") } 230 cl_wstr(1, " overwrite-src=") 231 if deny == W_ALLOW { cl_wstr(1, "ALLOW") } else { cl_wstr(1, "DENY") } 232 cl_wstr(1, "\n") 233 234 if auth == W_ALLOW { 235 var i: i64 = 0 236 var proven: i64 = 0 237 while i < CL_NGATES { 238 let el: *i64 = sys_mmap(8) as *i64 239 el[0] = 0 240 let rc: i64 = cl_gate(gates[i] as *u8, el) 241 var verdict: *u8 = "PROVEN " as *u8 242 if rc != 0 { 243 if rc == NX_RT_TIMEOUT { verdict = "TIMEOUT" as *u8 } else { verdict = "FAIL " as *u8 } 244 } 245 if rc == 0 { proven = proven + 1 } 246 cl_wstr(1, " "); cl_wstr(1, names[i] as *u8); cl_wstr(1, " "); cl_wstr(1, verdict) 247 cl_wstr(1, " "); cl_wnum(1, el[0]); cl_wstr(1, "ms\n") 248 cl_event(beat, names[i] as *u8, verdict, el[0]) 249 // ADDITIVE win-ledger journaling for the verify-by-proof organ 250 // (i == 1). Strictly AFTER the proven tally + cl_event above, and 251 // OUTSIDE allgreen_beats/warden_denies/exit accounting. Fire-and- 252 // forget: cl_journal_win swallows every failure -> NON-FATAL, the 253 // beat still passes on a real all-green tick. (We only journal when 254 // the organ actually PROVEN this beat, so the win record is honest.) 255 if i == 1 { 256 if rc == 0 { 257 let wc: i64 = cl_journal_win(win_ledger, gates[1] as *u8) 258 cl_wstr(1, " win-ledger: recorded verify-by-proof; entries="); cl_wnum(1, wc); cl_wstr(1, "\n") 259 } 260 } 261 i = i + 1 262 } 263 cl_wstr(1, " beat verdict: "); cl_wnum(1, proven); cl_wstr(1, "/"); cl_wnum(1, CL_NGATES); cl_wstr(1, " PROVEN\n") 264 if proven == CL_NGATES { allgreen_beats = allgreen_beats + 1 } 265 } 266 sys_sleep_ms(CL_CADENCE_MS) 267 beat = beat + 1 268 } 269 270 cl_wstr(1, "HEARTBEAT: "); cl_wnum(1, CL_BEATS); cl_wstr(1, " beats, Warden-gated, engine verification journaled -- the loop ticked WITHOUT a human.\n") 271 cl_wstr(1, " all-green beats="); cl_wnum(1, allgreen_beats); cl_wstr(1, " warden-denies="); cl_wnum(1, warden_denies); cl_wstr(1, "\n") 272 // ADDITIVE proof line: the win-ledger gained entries (2 per verified beat: 273 // a RECORD entry + a HOLDS/REFUTED entry). Reported AFTER the verdict, OUTSIDE 274 // the exit gate -- a journaling shortfall here can never change the exit code. 275 cl_wstr(1, " win-ledger entries="); cl_wnum(1, nx_win_ledger_count(win_ledger)); cl_wstr(1, " (additive self-learning capture; journaling is non-fatal)\n") 276 // exit 0 only if every beat verified the engine AND the Warden denied every forbidden action 277 if allgreen_beats != CL_BEATS { sys_exit(1); return 1 } 278 if warden_denies != CL_BEATS { sys_exit(2); return 2 } 279 sys_exit(0); return 0 280}