code wiki / (root) / nx_mgmt_call.nx

nx_mgmt_call.nx source

↩ module page · 94 lines · 5653 B

1// nx_mgmt_call.nx -- the mgmt-API driver forked as an MCP tool. Mints a FRESH admin session from the NAS key bundle 2// (no staleness, no stored secret) and issues one authenticated call to the loopback mgmt API (:18098), printing the 3// response body. This is what makes the SOTA control plane (deploy/reconcile/restart/services/health) reachable over 4// MCP without the shell. Runs as the (root) tools daemon's child, which can read the elderwesto-owned key bundle. 5// CLI: nx_mgmt_call <METHOD> <path> [json_body] e.g. nx_mgmt_call GET /api/services 6// nx_mgmt_call POST /api/deploy '{"target":"tools_api"}' 7import "nx_session_mint_lib.nx" // msm_mint_b64, msm_slen 8import "nx_tool_http_backend.nx" // thb_fetch (loopback HTTP client) 9const MC_MAGIC_86400: i64 = 86400 10const MC_MAGIC_131072: i64 = 131072 11const MC_MAGIC_1048576: i64 = 1048576 12 13const MC_KEYS: *u8 = "opaque_keys.bin" as *u8 // relative to the daemon cwd (nishihost) 14const MC_REALM: *u8 = "nishi_site_admin" as *u8 15const MC_HANDLE: *u8 = "elderwesto" as *u8 16const MC_PORT: i64 = 18098 17 18func mc_puts(buf: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { buf[off] = s[i]; off = off + 1; i = i + 1 } return off } 19func mc_putn(buf: *u8, off: i64, s: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { buf[off] = s[i]; off = off + 1; i = i + 1 } return off } 20func mc_puti(buf: *u8, off: i64, v: i64) -> i64 { 21 if v == 0 { buf[off] = 0x30 as u8; return off + 1 } 22 let tmp: *u8 = sys_mmap(32); var k: i64 = 0; var m: i64 = v 23 while m > 0 { tmp[k] = (0x30 + (m % 10)) as u8; k = k + 1; m = m / 10 } 24 var j: i64 = k - 1 25 while j >= 0 { buf[off] = tmp[j]; off = off + 1; j = j - 1 } 26 return off 27} 28 29func main(argc: i64, argv: *i64) -> i64 { 30 if argc < 3 { sys_write(2, "usage: nx_mgmt_call <METHOD> <path> [json_body]\n" as *u8, 48); return 1 } 31 let method: *u8 = argv[1] as *u8 32 let path: *u8 = argv[2] as *u8 33 var body: *u8 = "" as *u8 34 var body_n: i64 = 0 35 if argc >= 4 { body = argv[3] as *u8; body_n = msm_slen(body) } 36 37 // 1. mint a fresh admin session 38 let now: i64 = sys_now_realtime_sec() 39 let b64: *u8 = sys_mmap(512) 40 let blen: i64 = msm_mint_b64(MC_KEYS, MC_REALM, msm_slen(MC_REALM), MC_HANDLE, msm_slen(MC_HANDLE), now, MC_MAGIC_86400, b64) 41 if blen < 0 { sys_write(2, "MINT-FAIL\n" as *u8, 10); return 2 } 42 43 // 2. build the authenticated request 44 let req: *u8 = sys_mmap(MC_MAGIC_131072) 45 var o: i64 = 0 46 o = mc_puts(req, o, method); o = mc_puts(req, o, " " as *u8); o = mc_puts(req, o, path); o = mc_puts(req, o, " HTTP/1.0\r\n" as *u8) 47 o = mc_puts(req, o, "Host: 127.0.0.1\r\n" as *u8) 48 o = mc_puts(req, o, "X-Nishi-Session: " as *u8); o = mc_putn(req, o, b64, blen); o = mc_puts(req, o, "\r\n" as *u8) 49 if body_n > 0 { 50 o = mc_puts(req, o, "Content-Type: application/json\r\n" as *u8) 51 o = mc_puts(req, o, "Content-Length: " as *u8); o = mc_puti(req, o, body_n); o = mc_puts(req, o, "\r\n" as *u8) 52 } 53 o = mc_puts(req, o, "Connection: close\r\n\r\n" as *u8) 54 if body_n > 0 { o = mc_putn(req, o, body, body_n) } 55 56 // 3. call the loopback mgmt API 57 let out: *u8 = sys_mmap(MC_MAGIC_1048576) 58 let n: i64 = thb_fetch("127.0.0.1" as *u8, 9, MC_PORT, req, o, out, MC_MAGIC_1048576) 59 if n <= 0 { 60 // seq1806: `n` was the ONLY discriminator available and it was DISCARDED. A bare "FETCH-FAIL" 61 // cannot distinguish (a) the request NEVER LEFT -- safe to retry -- from (b) the request was 62 // SERVED and only the RESPONSE was lost -- NOT safe to blindly retry a non-idempotent call 63 // such as /api/cap/mint. Those two have OPPOSITE correct responses, and the caller was given 64 // no way to tell them apart. 65 // MEASURED 2026-07-30: two consecutive FETCH-FAILs on /api/build while the build SUCCEEDED 66 // BOTH times (213831B artifact on disk), plus a FETCH-FAIL on /api/cap/mint whose outcome is 67 // still unknown. Every sibling probe organ prints rc= (nx_doh_probe prints rc AND status); 68 // the one organ driving MUTATIONS printed the least. 69 // ⚠mc_puti renders a NEGATIVE as EMPTY (its `while m > 0` never runs), so the sign is handled 70 // explicitly here -- printing nothing for the most common failure code would reproduce the bug. 71 let eb: *u8 = sys_mmap(512); var eo: i64 = 0 72 eo = mc_puts(eb, eo, "FETCH-FAIL rc=" as *u8) 73 if n < 0 { eo = mc_puts(eb, eo, "-" as *u8); eo = mc_puti(eb, eo, 0 - n) } 74 if n >= 0 { eo = mc_puti(eb, eo, n) } 75 eo = mc_puts(eb, eo, " port=" as *u8); eo = mc_puti(eb, eo, MC_PORT) 76 eo = mc_puts(eb, eo, " method=" as *u8); eo = mc_puts(eb, eo, method) 77 eo = mc_puts(eb, eo, " path=" as *u8); eo = mc_puts(eb, eo, path) 78 eo = mc_puts(eb, eo, " reqbytes=" as *u8); eo = mc_puti(eb, eo, o) 79 eo = mc_puts(eb, eo, " OUTCOME=UNKNOWN (the request may have been SERVED and only the response lost -- VERIFY BY ARTIFACT before retrying anything non-idempotent)\n" as *u8) 80 sys_write(2, eb, eo) 81 return 3 82 } 83 84 // 4. print the response BODY (after CRLFCRLF); fall back to the whole response if no header terminator 85 var bo: i64 = 0 86 var found: i64 = 0 87 var i: i64 = 0 88 while i + 3 < n { 89 if out[i] == (13 as u8) { if out[i + 1] == (10 as u8) { if out[i + 2] == (13 as u8) { if out[i + 3] == (10 as u8) { bo = i + 4; found = 1; i = n } } } } 90 i = i + 1 91 } 92 if found == 1 { sys_write(1, ((out as i64) + bo) as *u8, n - bo) } else { sys_write(1, out, n) } 93 return 0 94}