code wiki / _hdl_build / nx_aw_send.nx

nx_aw_send.nx source

↩ module page · 226 lines · 12801 B

1// nx_aw_send.nx -- the SOVEREIGN file sender (operator: "nishi ecosystem from the hardware rung up, each 2// rung; build if we are missing capabilities"). The MISSING rung was a coreutils-free transport receive: 3// nx_aw_push/nx_put stream bytes over our own SSH but land them with a remote `cat > file.tmp && mv` shell. 4// This organ closes that rung -- it streams a LOCAL file over the team's sovereign SSH straight into the NAS 5// control-plane binary's receiver: `nx_hostctl recv <dest>` (see nx_hostctl cmd_recv). NO cat/mv/tee/dd, NO 6// nascmd/.src/.dst spec files -- everything is argv-driven and the remote payload is ONE sovereign Nishi 7// binary that atomically installs the bytes. Vault+SSH spine reused from nx_aw_push; the cat receive removed. 8// nx_aw_send <local-src-path> <remote-dest-path> 9// e.g. nx_aw_send _offc/nx_sites_daemon_v2.elf /volume1/homes/elderwesto/nishihost/sites.elf.new 10// license_tier: ORIGINAL 11import "nx_syscalls.nx" 12import "nx_ssh_lib.nx" 13import "nx_arbiter.nx" // fl_acquire/fl_release -- serialize concurrent sibling publishes (the queue) 14import "nx_receipt.nx" // rcpt_emit -- transport acceptance receipt to the workstream ledger 15const AS_MAGIC_1000000: i64 = 1000000 16const AS_MAGIC_65536: i64 = 65536 17const AS_MAGIC_1048576: i64 = 1048576 18const AS_MAGIC_16384: i64 = 16384 19const AS_MAGIC_1024: i64 = 1024 20const AS_MAGIC_60000: i64 = 60000 21const AS_MAGIC_1800: i64 = 1800 22 23const AS_SECRET_OUT: *u8 = "/tmp/nxsecret.out" as *u8 24const AS_VAULT_NV: *u8 = "/home/elderwesto/.nishi/secrets/nas.nv" as *u8 25const AS_HOSTCTL: *u8 = "/volume1/homes/elderwesto/nishihost/nx_hostctl" as *u8 26 27func as_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 28func as_run(path: *u8, a1: *u8, a2: *u8) -> i64 { 29 let pid: i64 = sys_fork() 30 if pid == 0 { 31 let argv: *i64 = sys_mmap(64) as *i64 32 argv[0] = path as i64 33 var ai: i64 = 1 34 if (a1 as i64) != 0 { argv[ai] = a1 as i64; ai = ai + 1 } 35 if (a2 as i64) != 0 { argv[ai] = a2 as i64; ai = ai + 1 } 36 argv[ai] = 0 37 let envp: *i64 = sys_mmap(16) as *i64 38 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 39 sys_execve(path, argv, envp) 40 sys_exit(127) 41 } 42 let st: *i64 = sys_mmap(16) as *i64 43 sys_wait4(pid, st, 0) 44 return (st[0] >> 8) & 0xff 45} 46func as_unlink(path: *u8) -> i64 { __syscall(263, AT_FDCWD, path, 0, 0, 0, 0) return 0 } 47func as_napms(ms: i64) -> i64 { let ts: *i64 = sys_mmap(16) as *i64; ts[0] = 0; ts[1] = ms * AS_MAGIC_1000000; __syscall(35, ts as i64, 0, 0, 0, 0, 0); return 0 } 48 49// non-blocking drain of pending server packets (WINDOW_ADJUST) -- prevents bidirectional deadlock. 50func ssh_drain(st: *SshState) -> i64 { 51 let pfd: *u8 = sys_mmap(8); let fdv: i64 = st.fd 52 pfd[0]=(fdv&0xff) as u8; pfd[1]=((fdv>>8)&0xff) as u8; pfd[2]=((fdv>>16)&0xff) as u8; pfd[3]=((fdv>>24)&0xff) as u8 53 pfd[4]=1 as u8; pfd[5]=0 as u8 54 let buf: *u8 = sys_mmap(AS_MAGIC_65536); var run: i64 = 1 55 while run == 1 { let r: i64 = sys_poll(pfd, 1, 0); if r <= 0 { run = 0 } else { if ssh_enc_recv(st, buf) < 0 { run = 0 } } } 56 return 0 57} 58// stream `data` into a remote exec channel running `wcmd` (here: nx_hostctl recv <dest>). Same wire mechanism 59// as nx_aw_push's ssh_put_file, but the wcmd is a sovereign binary, not a shell receive. 60func ssh_send_to(st: *SshState, wcmd: *u8, wcmdlen: i64, data: *u8, datalen: i64) -> i64 { 61 let co: *u8 = sys_mmap(64); var c: i64 = 0 62 c = ssh_put_byte(co, c, 90); c = ssh_put_str(co, c, "session" as *u8, 7) 63 c = ssh_put_u32(co, c, 0); c = ssh_put_u32(co, c, AS_MAGIC_1048576); c = ssh_put_u32(co, c, AS_MAGIC_16384) 64 ssh_enc_send(st, co, c) 65 let rep: *u8 = sys_mmap(AS_MAGIC_65536); var rcid: i64 = 0 - 1; var guard: i64 = 0 66 while rcid < 0 { 67 if guard > 16 { return 0 - 1 } 68 let rl: i64 = ssh_enc_recv(st, rep); if rl < 0 { return 0 - 1 } 69 if rep[0] == 91 as u8 { rcid = ssh_u32be(rep, 5) } 70 if rep[0] == 92 as u8 { return 0 - 2 } 71 guard = guard + 1 72 } 73 let cr: *u8 = sys_mmap(AS_MAGIC_1024); var q: i64 = 0 74 q = ssh_put_byte(cr, q, 98); q = ssh_put_u32(cr, q, rcid); q = ssh_put_str(cr, q, "exec" as *u8, 4); q = ssh_put_byte(cr, q, 1); q = ssh_put_str(cr, q, wcmd, wcmdlen) 75 ssh_enc_send(st, cr, q) 76 var off: i64 = 0 77 while off < datalen { 78 var nn: i64 = datalen - off; if nn > AS_MAGIC_16384 { nn = AS_MAGIC_16384 } 79 let dp: *u8 = sys_mmap(nn + 64); var p: i64 = 0 80 p = ssh_put_byte(dp, p, 94); p = ssh_put_u32(dp, p, rcid); p = ssh_put_u32(dp, p, nn) 81 var i: i64 = 0; while i < nn { dp[p + i] = data[off + i]; i = i + 1 } p = p + nn 82 ssh_enc_send(st, dp, p) 83 ssh_drain(st) 84 off = off + nn 85 } 86 let eo: *u8 = sys_mmap(16); var e: i64 = 0; e = ssh_put_byte(eo, e, 96); e = ssh_put_u32(eo, e, rcid); ssh_enc_send(st, eo, e) 87 let pfd2: *u8 = sys_mmap(8); let fdv2: i64 = st.fd 88 pfd2[0]=(fdv2&0xff) as u8; pfd2[1]=((fdv2>>8)&0xff) as u8; pfd2[2]=((fdv2>>16)&0xff) as u8; pfd2[3]=((fdv2>>24)&0xff) as u8 89 pfd2[4]=1 as u8; pfd2[5]=0 as u8 90 // VISIBILITY (2026-07-02, the blind-send fix): the receiver (`nx_hostctl recv`) prints its 91 // real result ("installed bytes=N" / an error) as CHANNEL_DATA on THIS channel, and its true 92 // exit code arrives as the "exit-status" CHANNEL_REQUEST. The old loop DISCARDED both -- a 93 // failed/empty landing looked identical to success (the 2026-07-02 proxy_routes outage). 94 // Now: relay the receiver's words to stdout + capture exit-status; caller fails loudly on !=0. 95 var done: i64 = 0; var quiet: i64 = 0 96 var exit_status: i64 = 0 - 3 // -3 = sent but exit-status never seen (UNCONFIRMED) 97 while done == 0 { 98 let pr: i64 = sys_poll(pfd2, 1, 500) 99 if pr <= 0 { quiet = quiet + 1; if quiet >= 6 { done = 1 } } 100 else { 101 let rl: i64 = ssh_enc_recv(st, rep) 102 if rl < 0 { done = 1 } 103 else { 104 if rep[0] == 94 as u8 { 105 let dn: i64 = ssh_u32be(rep, 5) 106 if dn > 0 { if dn < AS_MAGIC_60000 { sys_write(1, " [recv] " as *u8, 9); sys_write(1, ((rep as i64) + 9) as *u8, dn) } } 107 } 108 if rep[0] == 98 as u8 { 109 let nl: i64 = ssh_u32be(rep, 5) 110 if nl == 11 { 111 let es: *u8 = "exit-status" as *u8 112 var em: i64 = 1 113 var ei: i64 = 0 114 while ei < 11 { if rep[9 + ei] != es[ei] { em = 0 } ei = ei + 1 } 115 if em == 1 { exit_status = ssh_u32be(rep, 21) } 116 } 117 } 118 if rep[0] == 97 as u8 { done = 1 } 119 } 120 } 121 } 122 let clo: *u8 = sys_mmap(16); var k: i64 = 0; k = ssh_put_byte(clo, k, 97); k = ssh_put_u32(clo, k, rcid); ssh_enc_send(st, clo, k) 123 return exit_status 124} 125 126func main(argc: i64, argv: *i64) -> i64 { 127 if argc < 3 { 128 ssh_puts("usage: nx_aw_send <local-src> <remote-dest> | nx_aw_send --build <name> <remote-dest>\n" as *u8); return 2 129 } 130 var srcp: *u8 = argv[1] as *u8 131 var dest: *u8 = argv[2] as *u8 132 // --build mode = SOVEREIGN single-call deploy (no bash orchestration): build <name> via nx_sov_build_run, then 133 // stream the FRESH /tmp/<name>.sov.elf -> <dest>. Solves the WSL /tmp-volatility that forced build+send chaining. 134 let a1: *u8 = argv[1] as *u8 135 var is_build: i64 = 1 136 let bm: *u8 = "--build" as *u8 137 var bi: i64 = 0 138 while bm[bi] != (0 as u8) { if a1[bi] != bm[bi] { is_build = 0 } bi = bi + 1 } 139 if a1[bi] != (0 as u8) { is_build = 0 } 140 if is_build == 1 { 141 if argc < 4 { ssh_puts("usage: nx_aw_send --build <name> <remote-dest>\n" as *u8); return 2 } 142 let name: *u8 = argv[2] as *u8 143 dest = argv[3] as *u8 144 ssh_puts("nx_aw_send --build: building " as *u8); ssh_puts(name); ssh_puts(" (nx_sov_build_run)...\n" as *u8) 145 if as_run("_offc/nx_sov_build_run.elf" as *u8, name, "--build-only" as *u8) != 0 { ssh_puts("nx_aw_send --build: BUILD FAILED\n" as *u8); return 4 } 146 let sb: *u8 = sys_mmap(256); var so: i64 = 0 147 let p1: *u8 = "/tmp/" as *u8; var i1: i64=0; while p1[i1]!=(0 as u8){sb[so]=p1[i1];so=so+1;i1=i1+1} 148 var i2: i64=0; while name[i2]!=(0 as u8){sb[so]=name[i2];so=so+1;i2=i2+1} 149 let p2: *u8 = ".sov.elf" as *u8; var i3: i64=0; while p2[i3]!=(0 as u8){sb[so]=p2[i3];so=so+1;i3=i3+1} 150 sb[so]=0 as u8 151 srcp = sb 152 } 153 154 // QUEUE (operator: concurrent publishes hammering the daemon is a proven disaster): serialize against ALL 155 // sibling workstream publishes on ONE kernel lease. Mutual exclusion = the researched fix (the NAS 156 // vault->ssh->doc-root chain is a critical section). Others WAIT their turn instead of racing /tmp/nxpass. 157 let lock_fd: i64 = fl_acquire("nas_push" as *u8, AS_MAGIC_1800, 100) 158 if lock_fd < 0 { ssh_puts("nx_aw_send: nas_push lease busy >180s -- aborting (retry)\n" as *u8); return 9 } 159 160 // ---- sovereign credential retrieval, retry-tolerant (WSL /tmp churns mid-op) ---- 161 let pwbox: *i64 = sys_mmap(16) as *i64 162 var pw: *u8 = 0 as *u8 163 var att: i64 = 0 164 while att < 12 { 165 if as_run("_offc/nx_machine_key.elf" as *u8, 0 as *u8, 0 as *u8) == 0 { 166 if as_run("_offc/nx_vault.elf" as *u8, "open" as *u8, AS_VAULT_NV) == 0 { 167 pw = sys_read_file(AS_SECRET_OUT, pwbox) 168 if (pw as i64) != 0 { att = 1000 } 169 } 170 } 171 if att < 1000 { att = att + 1; as_napms(150) } 172 } 173 as_unlink("/tmp/nxpass" as *u8) 174 if (pw as i64) == 0 { ssh_puts("nx_aw_send: secret derivation FAIL after 12 retries\n" as *u8); return 3 } 175 var pwlen: i64 = pwbox[0] 176 while pwlen > 0 { if pw[pwlen-1] == 10 as u8 { pwlen = pwlen - 1 } else { if pw[pwlen-1] == 13 as u8 { pwlen = pwlen - 1 } else { break } } } 177 178 let fbox: *i64 = sys_mmap(16) as *i64 179 let payload: *u8 = sys_read_file(srcp, fbox) 180 if (payload as i64) == 0 { ssh_puts("nx_aw_send: cannot read local src file\n" as *u8); as_unlink(AS_SECRET_OUT); return 5 } 181 let plen: i64 = fbox[0] 182 183 // ---- compose the SOVEREIGN remote receiver invocation: "<nx_hostctl> recv <dest>" ---- 184 let hp: *u8 = AS_HOSTCTL // copy the const to a local *u8 -- direct `const *u8`[i] indexing desyncs nx_cc 185 let wcmd: *u8 = sys_mmap(as_slen(hp) + as_slen(dest) + 16) 186 var wo: i64 = 0 187 var hi: i64 = 0; while hp[hi] != (0 as u8) { wcmd[wo]=hp[hi]; wo=wo+1; hi=hi+1 } 188 let mid: *u8 = " recv " as *u8; var mi: i64 = 0; while mid[mi] != (0 as u8) { wcmd[wo]=mid[mi]; wo=wo+1; mi=mi+1 } 189 var ddi: i64 = 0; while dest[ddi] != (0 as u8) { wcmd[wo]=dest[ddi]; wo=wo+1; ddi=ddi+1 } 190 191 let st: *SshState = sys_mmap(SSH_STATE_BYTES) as *SshState 192 if ssh_open_session(st, (192 << 24) | (168 << 16) | (8 << 8) | 227) != 0 { ssh_puts("nx_aw_send: SSH session FAIL\n" as *u8); as_unlink(AS_SECRET_OUT); return 7 } 193 if ssh_userauth_password(st, "elderwesto" as *u8, 10, pw, pwlen) != 1 { ssh_puts("nx_aw_send: SSH auth FAIL\n" as *u8); sys_close(st.fd); as_unlink(AS_SECRET_OUT); return 8 } 194 as_unlink(AS_SECRET_OUT) 195 ssh_puts("nx_aw_send: [auth ok] streaming -> " as *u8); ssh_puts(wcmd); ssh_puts("\n" as *u8) 196 let src_rc: i64 = ssh_send_to(st, wcmd, wo, payload, plen) 197 // Honest verdict from the receiver's OWN exit-status (the blind-send fix): 0 = install 198 // confirmed; >0 = the receiver FAILED (bad dest/perms/short write); -1/-2 = channel never 199 // opened; -3 = sent but unconfirmed (no exit-status arrived -- treat as suspect, not success). 200 if src_rc == 0 { 201 ssh_puts("===SEND-VERIFIED=== (recv exit-status 0)\n" as *u8) 202 rcpt_emit("nx_aw_send" as *u8, "send" as *u8, dest, "COMPLETED" as *u8, srcp) 203 sys_close(st.fd) 204 fl_release(lock_fd) 205 return 0 206 } 207 if src_rc > 0 { 208 ssh_puts("===SEND-FAILED=== recv exit-status NONZERO -- the file did NOT install; read the [recv] lines above\n" as *u8) 209 rcpt_emit("nx_aw_send" as *u8, "send" as *u8, dest, "FAILED" as *u8, srcp) 210 sys_close(st.fd) 211 fl_release(lock_fd) 212 return 6 213 } 214 if src_rc == (0 - 3) { 215 ssh_puts("===SEND-UNCONFIRMED=== no exit-status from recv -- VERIFY the landing (nx_aw_fetch / sha256) before acting on it\n" as *u8) 216 rcpt_emit("nx_aw_send" as *u8, "send" as *u8, dest, "UNCONFIRMED" as *u8, srcp) 217 sys_close(st.fd) 218 fl_release(lock_fd) 219 return 0 220 } 221 ssh_puts("===SEND-FAILED=== exec channel never opened (SSH failure)\n" as *u8) 222 rcpt_emit("nx_aw_send" as *u8, "send" as *u8, dest, "FAILED" as *u8, srcp) 223 sys_close(st.fd) 224 fl_release(lock_fd) 225 return 7 226}