code wiki / (root) / nx_vizsla_mcp_gate.nx

nx_vizsla_mcp_gate.nx source

↩ module page · 262 lines · 10858 B

1// nx_vizsla_mcp_gate.nx -- GATE: the VIZSLA coordination tools are REAL MCP-level APIs. Drives the 2// EXACT execution layer /mcp tools/call uses (nx_tool_exec_allow tea_resolve/tea_run_argv over the 3// PRODUCTION tool_allowlist.conf) + the discovery registry readback (what tools/list serves) + the 4// rich-schema conf rows. Nothing is mocked: the resolved blessed ELFs run with a real argv and their 5// real stdout comes back through the capture path -- exactly what an MCP client receives. 6// 7// Rows: 8// 1 registry-discovery tool_get readback for vizsla_plan + vizsla_doc (tools/list source) 9// 2 allowlist-resolve tea_resolve(production conf) vizsla_plan -> TEA_OK + the blessed elf path 10// 3 mcp-exec-plan tea_run_argv board over the demo store -> VIZSLA-PLAN-VERDICT captured 11// 4 mcp-exec-ics tea_run_argv ics export -> real .ics on disk + BEGIN:VCALENDAR + verdict 12// 5 mcp-exec-doc tea_run_argv doc put -> list captures docs=1 (mutating tool works e2e) 13// 6 blocked-non-green nx_http_probe row is RED -> TEA_BLOCKED, nothing executed [neg control] 14// 7 notfound-unknown ghost tool -> TEA_NOTFOUND [negative control] 15// 8 schema-rows tool_schemas.conf carries vizsla_plan + vizsla_doc annotation rows 16// Evidence: VIZSLA-MCP-GATE -> stdout + knowledge/status/vizsla_gate.log; exit 0 iff 8/8. 17// expect_exit: 0 license_tier: ORIGINAL 18import "nx_tool_exec_allow.nx" 19import "nx_tool_registry.nx" 20import "nx_gate_verdict.nx" 21 22func mg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 23func mg_p(s: *u8) -> i64 { sys_write(1, s, mg_slen(s)); return 0 } 24 25func mg_cat(dst: *u8, off: i64, s: *u8) -> i64 { 26 var i: i64 = 0 27 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 28 return off + i 29} 30 31func mg_catn(dst: *u8, off: i64, v: i64) -> i64 { 32 var o: i64 = off 33 var m: i64 = v 34 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 35 let t: *u8 = sys_mmap(28) 36 var k: i64 = 0 37 if m == 0 { t[0] = 48 as u8; k = 1 } 38 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 39 var i: i64 = 0 40 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 41 return o + k 42} 43 44func mg_readall(path: *u8, szout: *i64) -> *u8 { 45 let fd: i64 = sys_openat_rd(path) 46 if fd < 0 { szout[0] = 0 - 1; return 0 as *u8 } 47 let sz: i64 = sys_lseek(fd, 0, 2) 48 sys_lseek(fd, 0, 0) 49 let buf: *u8 = sys_mmap(sz + 64) 50 var got: i64 = 0 51 var n: i64 = 1 52 while n > 0 { 53 n = sys_read(fd, (buf as i64 + got) as *u8, 65536) 54 if n > 0 { got = got + n } 55 } 56 sys_close(fd) 57 szout[0] = got 58 return buf 59} 60 61func mg_memhas(b: *u8, sz: i64, needle: *u8) -> i64 { 62 let n: i64 = mg_slen(needle) 63 if sz < n { return 0 } 64 var i: i64 = 0 65 while i + n <= sz { 66 var ok: i64 = 1 67 var j: i64 = 0 68 while j < n { 69 if b[i + j] != needle[j] { ok = 0; j = n } else { j = j + 1 } 70 } 71 if ok == 1 { return 1 } 72 i = i + 1 73 } 74 return 0 75} 76 77func mg_filehas(path: *u8, needle: *u8) -> i64 { 78 let szp: *i64 = sys_mmap(16) as *i64 79 let b: *u8 = mg_readall(path, szp) 80 if szp[0] <= 0 { return 0 } 81 return mg_memhas(b, szp[0], needle) 82} 83 84func mg_row(name: *u8, pass: i64) -> i64 { 85 mg_p("ROW " as *u8) 86 mg_p(name) 87 if pass == 1 { mg_p(" PASS\n" as *u8) } else { mg_p(" FAIL\n" as *u8) } 88 return pass 89} 90 91func main(argc: i64, argv: *i64) -> i64 { 92 mg_p("=== VIZSLA MCP GATE: coordination tools live on the tools/call execution plane ===\n" as *u8) 93 let conf: *u8 = "tool_allowlist.conf" as *u8 94 var pass: i64 = 0 95 var r: i64 = 0 96 97 // row 1: discovery registry readback (the tools/list source) 98 let p1: *i64 = sys_mmap(8) as *i64 99 let l1: *i64 = sys_mmap(8) as *i64 100 let g1: i64 = tool_get("vizsla_plan" as *u8, p1, l1) 101 let g2: i64 = tool_get("vizsla_doc" as *u8, p1, l1) 102 r = 0 103 if g1 == 1 { if g2 == 1 { r = 1 } } 104 pass = pass + mg_row("registry-discovery" as *u8, r) 105 106 // row 2: production allowlist resolves the tool NAME to the blessed elf 107 let path: *u8 = sys_mmap(4096) 108 let code: i64 = tea_resolve_from(conf, "vizsla_plan" as *u8, 11, path, 4096) 109 r = 0 110 if code == TEA_OK { 111 if mg_memhas(path, mg_slen(path), "_offc/nx_vizsla_plan.elf" as *u8) == 1 { r = 1 } 112 } 113 pass = pass + mg_row("allowlist-resolve" as *u8, r) 114 115 // row 3: EXECUTE vizsla_plan board over the demo store via the tools/call layer 116 let av: *i64 = sys_mmap(8 * 12) as *i64 117 av[0] = 0 118 av[1] = "board" as *u8 as i64 119 av[2] = "knowledge/vizsla/demo/plan-" as *u8 as i64 120 av[3] = "summer" as *u8 as i64 121 av[4] = "2026-07-08" as *u8 as i64 122 av[5] = 0 123 let out: *u8 = sys_mmap(16384) 124 let outlen: *i64 = sys_mmap(16) as *i64 125 let rc: *i64 = sys_mmap(16) as *i64 126 let x3: i64 = tea_run_argv_from(conf, "vizsla_plan" as *u8, 11, av, out, 16384, outlen, rc) 127 r = 0 128 if x3 == 0 { if rc[0] == TEA_OK { 129 if mg_memhas(out, outlen[0], "VIZSLA-PLAN-VERDICT plan=summer" as *u8) == 1 { 130 if mg_memhas(out, outlen[0], "VIZSLA-PLAN-CRITICAL plan=summer" as *u8) == 1 { r = 1 } 131 } 132 } } 133 pass = pass + mg_row("mcp-exec-plan" as *u8, r) 134 135 // row 4: EXECUTE vizsla_ics export -- a side-effectful tool writes a REAL artifact 136 let av4: *i64 = sys_mmap(8 * 12) as *i64 137 av4[0] = 0 138 av4[1] = "export" as *u8 as i64 139 av4[2] = "knowledge/vizsla/demo/cal-" as *u8 as i64 140 av4[3] = "2026-07-01" as *u8 as i64 141 av4[4] = "2026-12-31" as *u8 as i64 142 av4[5] = "/tmp/vzm_mcp.ics" as *u8 as i64 143 av4[6] = 0 144 let x4: i64 = tea_run_argv_from(conf, "vizsla_ics" as *u8, 10, av4, out, 16384, outlen, rc) 145 r = 0 146 if x4 == 0 { if rc[0] == TEA_OK { 147 if mg_memhas(out, outlen[0], "VIZSLA-ICS-VERDICT events=3 rules=2" as *u8) == 1 { 148 if mg_filehas("/tmp/vzm_mcp.ics" as *u8, "BEGIN:VCALENDAR" as *u8) == 1 { 149 if mg_filehas("/tmp/vzm_mcp.ics" as *u8, "RRULE:FREQ=YEARLY" as *u8) == 1 { r = 1 } 150 } 151 } 152 } } 153 pass = pass + mg_row("mcp-exec-ics" as *u8, r) 154 155 // row 5: EXECUTE vizsla_doc put then list -- a MUTATING tool works end-to-end 156 let fdw: i64 = sys_openat_wr("/tmp/vzm_doc.txt" as *u8, 0x1a4) 157 if fdw >= 0 { sys_write(fdw, "mcp-plane document body\n" as *u8, 24); sys_close(fdw) } 158 let pfx: *u8 = sys_mmap(128) 159 var po: i64 = 0 160 po = mg_cat(pfx, po, "/tmp/vzmD" as *u8) 161 po = mg_catn(pfx, po, sys_now_us()) 162 po = mg_cat(pfx, po, "-" as *u8) 163 pfx[po] = 0 as u8 164 let av5: *i64 = sys_mmap(8 * 12) as *i64 165 av5[0] = 0 166 av5[1] = "put" as *u8 as i64 167 av5[2] = pfx as i64 168 av5[3] = "mcpdoc" as *u8 as i64 169 av5[4] = "/tmp/vzm_doc.txt" as *u8 as i64 170 av5[5] = "note" as *u8 as i64 171 av5[6] = "plan:summer" as *u8 as i64 172 av5[7] = "2026-07-08" as *u8 as i64 173 av5[8] = "7401" as *u8 as i64 174 av5[9] = 0 175 let x5a: i64 = tea_run_argv_from(conf, "vizsla_doc" as *u8, 10, av5, out, 16384, outlen, rc) 176 var ok5: i64 = 0 177 if x5a == 0 { if mg_memhas(out, outlen[0], " new=1 segment=seg-7401" as *u8) == 1 { ok5 = 1 } } 178 let av5b: *i64 = sys_mmap(8 * 8) as *i64 179 av5b[0] = 0 180 av5b[1] = "list" as *u8 as i64 181 av5b[2] = pfx as i64 182 av5b[3] = "-" as *u8 as i64 183 av5b[4] = 0 184 let x5b: i64 = tea_run_argv_from(conf, "vizsla_doc" as *u8, 10, av5b, out, 16384, outlen, rc) 185 r = 0 186 if ok5 == 1 { if x5b == 0 { 187 if mg_memhas(out, outlen[0], "VIZSLA-DOC-LIST rel=- docs=1" as *u8) == 1 { 188 if mg_memhas(out, outlen[0], "docid=mcpdoc doctype=note rel=plan:summer" as *u8) == 1 { r = 1 } 189 } 190 } } 191 pass = pass + mg_row("mcp-exec-doc" as *u8, r) 192 // NOTE: the COMPOSING tool vizsla_notify (which double-forks: tools/call -> notify -> remind) is proven 193 // over tools/call by the SEPARATE nx_vizsla_notify_mcp_gate (3/3), kept in a fresh minimal process so the 194 // degraded WSL box's fork-accumulation flake (a 5th+ tr_run_capture fork can transiently fail) never 195 // masks a real result. Splitting keeps both gates deterministically GREEN and honest. 196 197 // row 6: RED-status tool is BLOCKED (negative control -- allowlist status is load-bearing) 198 let code6: i64 = tea_resolve_from(conf, "nx_http_probe" as *u8, 13, path, 4096) 199 r = 0 200 if code6 == TEA_BLOCKED { r = 1 } 201 pass = pass + mg_row("blocked-non-green" as *u8, r) 202 203 // row 7: unknown tool -> NOTFOUND (negative control) 204 let code7: i64 = tea_resolve_from(conf, "vizsla_ghost" as *u8, 12, path, 4096) 205 r = 0 206 if code7 == TEA_NOTFOUND { r = 1 } 207 pass = pass + mg_row("notfound-unknown" as *u8, r) 208 209 // row 8: rich MCP annotation rows present (tab-separated -- needles built with real TABs) 210 let nd: *u8 = sys_mmap(64) 211 var no: i64 = 0 212 no = mg_cat(nd, no, "vizsla_plan" as *u8) 213 nd[no] = 9 as u8; no = no + 1 214 no = mg_cat(nd, no, "Vizsla Planner" as *u8) 215 nd[no] = 0 as u8 216 let nd2: *u8 = sys_mmap(64) 217 no = 0 218 no = mg_cat(nd2, no, "vizsla_doc" as *u8) 219 nd2[no] = 9 as u8; no = no + 1 220 no = mg_cat(nd2, no, "Vizsla Documents" as *u8) 221 nd2[no] = 0 as u8 222 r = 0 223 if mg_filehas("knowledge/tool_schemas.conf" as *u8, nd) == 1 { 224 if mg_filehas("knowledge/tool_schemas.conf" as *u8, nd2) == 1 { r = 1 } 225 } 226 pass = pass + mg_row("schema-rows" as *u8, r) 227 228 let permil: i64 = (pass * 1000) / 8 229 let logfd: i64 = sys_openat_append("knowledge/status/vizsla_gate.log" as *u8, 0x1a4) 230 var fdi: i64 = 0 231 while fdi < 2 { 232 var fd: i64 = 1 233 if fdi == 1 { fd = logfd } 234 if fd > 0 { 235 let line: *u8 = sys_mmap(256) 236 var o: i64 = 0 237 o = mg_cat(line, o, "VIZSLA-MCP-GATE epoch=" as *u8) 238 o = mg_catn(line, o, sys_now_realtime_sec()) 239 o = mg_cat(line, o, " rows=8 pass=" as *u8) 240 o = mg_catn(line, o, pass) 241 o = mg_cat(line, o, " permil=" as *u8) 242 o = mg_catn(line, o, permil) 243 if pass == 8 { 244 o = mg_cat(line, o, " verdict=GREEN\n" as *u8) 245 } else { 246 o = mg_cat(line, o, " verdict=RED\n" as *u8) 247 } 248 sys_write(fd, line, o) 249 } 250 fdi = fdi + 1 251 } 252 if logfd > 0 { sys_close(logfd) } 253 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 254 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 255 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 256 let ctr__dry: *i64 = gv_ctr() 257 ctr__dry[0] = pass 258 ctr__dry[1] = 8 259 let rc__dry: i64 = gv_verdict("VIZSLA-MCP-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 260 sys_exit(rc__dry) 261 return rc__dry 262}