code wiki / _hdl_build / nx_connect_api_gate.nx

nx_connect_api_gate.nx source

↩ module page · 192 lines · 12194 B

1// nx_connect_api_gate.nx -- gate for the CONNECT MCP front door. Drives ca_dispatch with synthetic argv 2// arrays (exactly as the tools daemon will pass params.arguments.argv) and asserts on the emitted JSON. 3// This proves the MCP surface is faithful to the 8 gated engines and that its contract holds. 4// license_tier: ORIGINAL expect_exit: 0 5import "nx_syscalls.nx" 6import "nx_connect_api_lib.nx" 7 8func ag_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 9func ag_n(v: i64) -> i64 { let t: *u8=sys_mmap(32); let o: i64=ca_putn(t,0,v); t[o]=0 as u8; ag_w(t); return 0 } 10func ag_check(pass: i64, label: *u8, fails: *i64) -> i64 { 11 ag_w(" " as *u8); ag_w(label); ag_w(": " as *u8) 12 if pass==1 { ag_w("PASS\n" as *u8) } else { ag_w("FAIL\n" as *u8); fails[0]=fails[0]+1 } 13 return 0 14} 15func ag_has(buf: *u8, n: i64, needle: *u8) -> i64 { 16 let m: i64 = ca_slen(needle) 17 if m==0 { return 0 } 18 var i: i64=0 19 while i+m<=n { 20 var k: i64=0 21 var hit: i64=1 22 while k<m { if buf[i+k]!=needle[k] { hit=0; k=m } else { k=k+1 } } 23 if hit==1 { return 1 } 24 i=i+1 25 } 26 return 0 27} 28// build a synthetic argv from up to 14 NUL-terminated string args (0 to stop) 29func ag_argv(a0:*u8,a1:*u8,a2:*u8,a3:*u8,a4:*u8,a5:*u8,a6:*u8,a7:*u8,a8:*u8,a9:*u8,a10:*u8,a11:*u8,a12:*u8,a13:*u8, outc: *i64) -> *i64 { 30 let av: *i64 = sys_mmap(16*8) as *i64 31 var c: i64=0 32 if (a0 as i64)!=0 { av[c]=a0 as i64; c=c+1 } else { outc[0]=c; return av } 33 if (a1 as i64)!=0 { av[c]=a1 as i64; c=c+1 } else { outc[0]=c; return av } 34 if (a2 as i64)!=0 { av[c]=a2 as i64; c=c+1 } else { outc[0]=c; return av } 35 if (a3 as i64)!=0 { av[c]=a3 as i64; c=c+1 } else { outc[0]=c; return av } 36 if (a4 as i64)!=0 { av[c]=a4 as i64; c=c+1 } else { outc[0]=c; return av } 37 if (a5 as i64)!=0 { av[c]=a5 as i64; c=c+1 } else { outc[0]=c; return av } 38 if (a6 as i64)!=0 { av[c]=a6 as i64; c=c+1 } else { outc[0]=c; return av } 39 if (a7 as i64)!=0 { av[c]=a7 as i64; c=c+1 } else { outc[0]=c; return av } 40 if (a8 as i64)!=0 { av[c]=a8 as i64; c=c+1 } else { outc[0]=c; return av } 41 if (a9 as i64)!=0 { av[c]=a9 as i64; c=c+1 } else { outc[0]=c; return av } 42 if (a10 as i64)!=0 { av[c]=a10 as i64; c=c+1 } else { outc[0]=c; return av } 43 if (a11 as i64)!=0 { av[c]=a11 as i64; c=c+1 } else { outc[0]=c; return av } 44 if (a12 as i64)!=0 { av[c]=a12 as i64; c=c+1 } else { outc[0]=c; return av } 45 if (a13 as i64)!=0 { av[c]=a13 as i64; c=c+1 } else { outc[0]=c; return av } 46 outc[0]=c 47 return av 48} 49 50func main() -> i64 { 51 let fails: *i64 = sys_mmap(16) as *i64 52 fails[0]=0 53 let out: *u8 = sys_mmap(65536) 54 let c: *i64 = sys_mmap(8) as *i64 55 let Z: *u8 = 0 as *u8 56 ag_w("=== nx_connect_api_gate -- the CONNECT MCP front door, JSON contract over 8 engines ===\n" as *u8) 57 58 // T1: help catalog is self-describing (agentic/workflow discovery) + carries the version envelope 59 var av: *i64 = ag_argv("help" as *u8, Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 60 var n: i64 = ca_dispatch(c[0], av, out) 61 var t1: i64=1 62 if ag_has(out, n, "\"v\":1" as *u8)==0 { t1=0 } 63 if ag_has(out, n, "\"tool\":\"nx_connect\"" as *u8)==0 { t1=0 } 64 if ag_has(out, n, "\"stateless\":1" as *u8)==0 { t1=0 } 65 if ag_has(out, n, "\"name\":\"match\"" as *u8)==0 { t1=0 } 66 if ag_has(out, n, "\"name\":\"group_remove\"" as *u8)==0 { t1=0 } 67 ag_check(t1, "T1 help: versioned envelope + self-describing verb catalog (8 verbs, stateless flag)" as *u8, fails) 68 69 // T2: match agrees with mx_match_weight -- reciprocal pair 45, one-sided 0, minor+date excluded 70 av = ag_argv("match" as *u8,"30" as *u8,"16" as *u8,"1" as *u8,"5" as *u8,"27" as *u8,"1" as *u8,"16" as *u8,"9" as *u8,"0" as *u8,Z,Z,Z,Z, c) 71 n = ca_dispatch(c[0], av, out) 72 var t2: i64=1 73 if ag_has(out, n, "\"weight\":45" as *u8)==0 { t2=0 } 74 av = ag_argv("match" as *u8,"30" as *u8,"16" as *u8,"1" as *u8,"5" as *u8,"29" as *u8,"4" as *u8,"16" as *u8,"1" as *u8,"0" as *u8,Z,Z,Z,Z, c) 75 n = ca_dispatch(c[0], av, out) 76 if ag_has(out, n, "\"weight\":0" as *u8)==0 { t2=0 } // Lena: learns French, one-sided 77 av = ag_argv("match" as *u8,"30" as *u8,"16" as *u8,"1" as *u8,"5" as *u8,"14" as *u8,"1" as *u8,"16" as *u8,"5" as *u8,"3" as *u8,Z,Z,Z,Z, c) 78 n = ca_dispatch(c[0], av, out) 79 if ag_has(out, n, "\"excluded\":1" as *u8)==0 { t2=0 } // minor on the DATE lane 80 ag_check(t2, "T2 match: 45 / 0 / excluded match the engine (reciprocal, one-sided, minor+date)" as *u8, fails) 81 82 // T3: lane refuses unilateral escalation and names the active lane 83 av = ag_argv("lane" as *u8,"3" as *u8,"0" as *u8,"1" as *u8,"1" as *u8,"0" as *u8,Z,Z,Z,Z,Z,Z,Z,Z, c) 84 n = ca_dispatch(c[0], av, out) 85 var t3: i64=1 86 if ag_has(out, n, "\"lane\":0" as *u8)==0 { t3=0 } 87 if ag_has(out, n, "\"name\":\"Language exchange\"" as *u8)==0 { t3=0 } 88 ag_check(t3, "T3 lane: unilateral Dating request stays Language exchange (mutual-min), lane named" as *u8, fails) 89 90 // T4: youth wall -- a non-guardian adult<->minor 1:1 DM is blocked; two-deep group is allowed 91 av = ag_argv("youth" as *u8,"1" as *u8,"0" as *u8,"0" as *u8,"0" as *u8,"0" as *u8,Z,Z,Z,Z,Z,Z,Z,Z, c) 92 n = ca_dispatch(c[0], av, out) 93 var t4: i64=1 94 if ag_has(out, n, "\"allowed\":0" as *u8)==0 { t4=0 } 95 av = ag_argv("youth" as *u8,"1" as *u8,"0" as *u8,"0" as *u8,"1" as *u8,"2" as *u8,Z,Z,Z,Z,Z,Z,Z,Z, c) 96 n = ca_dispatch(c[0], av, out) 97 if ag_has(out, n, "\"allowed\":1" as *u8)==0 { t4=0 } 98 ag_check(t4, "T4 youth: 1:1 adult<->minor blocked, two-deep group allowed" as *u8, fails) 99 100 // T5: wards -- our 5 community-safe fields = 0 forbidden; an admin model with 3 = forbidden 3 101 av = ag_argv("wards" as *u8,"5" as *u8,"0" as *u8,"0" as *u8,"0" as *u8,"0" as *u8,"0" as *u8,Z,Z,Z,Z,Z,Z,Z, c) 102 n = ca_dispatch(c[0], av, out) 103 var t5: i64=1 104 if ag_has(out, n, "\"forbidden\":0" as *u8)==0 { t5=0 } 105 if ag_has(out, n, "\"community_safe\":1" as *u8)==0 { t5=0 } 106 av = ag_argv("wards" as *u8,"5" as *u8,"0" as *u8,"0" as *u8,"3" as *u8,"1" as *u8,"5" as *u8,Z,Z,Z,Z,Z,Z,Z, c) 107 n = ca_dispatch(c[0], av, out) 108 if ag_has(out, n, "\"forbidden\":3" as *u8)==0 { t5=0 } 109 ag_check(t5, "T5 wards: community schema 0 forbidden, admin model 3 (boundary is load-bearing)" as *u8, fails) 110 111 // T6: events -- capacity refuses when full; a minor on a non-youth event is -4 112 av = ag_argv("events_rsvp" as *u8,"6" as *u8,"0" as *u8,"6" as *u8,"0" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 113 n = ca_dispatch(c[0], av, out) 114 var t6: i64=1 115 if ag_has(out, n, "\"code\":-2" as *u8)==0 { t6=0 } // full (6 present, cap 6) 116 av = ag_argv("events_rsvp" as *u8,"6" as *u8,"0" as *u8,"0" as *u8,"1" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 117 n = ca_dispatch(c[0], av, out) 118 if ag_has(out, n, "\"code\":-4" as *u8)==0 { t6=0 } // minor on a non-youth event 119 av = ag_argv("events_rsvp" as *u8,"6" as *u8,"1" as *u8,"1" as *u8,"1" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 120 n = ca_dispatch(c[0], av, out) 121 if ag_has(out, n, "\"code\":-3" as *u8)==0 { t6=0 } // youth event, only 1 adult -> two-deep 122 ag_check(t6, "T6 events_rsvp: -2 full, -4 minor-on-adult-event, -3 two-deep (real ev_rsvp verdicts)" as *u8, fails) 123 124 // T7: poll -- a voter on opt0 re-votes opt1; opt0 falls, opt1 rises, total unchanged (replace) 125 av = ag_argv("poll" as *u8,"2" as *u8,"1" as *u8,"0" as *u8,"1" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 126 n = ca_dispatch(c[0], av, out) 127 var t7: i64=1 128 if ag_has(out, n, "\"tally\":[1,2,0]" as *u8)==0 { t7=0 } // was [2,1,0]; one opt0 voter moved to opt1 129 if ag_has(out, n, "\"total\":3" as *u8)==0 { t7=0 } // total unchanged -> replace not append 130 ag_check(t7, "T7 poll: revote REPLACES ([2,1,0]->[1,2,0], total stays 3)" as *u8, fails) 131 132 // T8: group_remove -- admin removes member (1); admin cannot remove a peer admin (0); owner unremovable (0) 133 av = ag_argv("group_remove" as *u8,"2" as *u8,"1" as *u8,"0" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 134 n = ca_dispatch(c[0], av, out) 135 var t8: i64=1 136 if ag_has(out, n, "\"removed\":1" as *u8)==0 { t8=0 } // admin removes member 137 av = ag_argv("group_remove" as *u8,"2" as *u8,"2" as *u8,"0" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 138 n = ca_dispatch(c[0], av, out) 139 if ag_has(out, n, "\"removed\":0" as *u8)==0 { t8=0 } // no peer-admin coup 140 av = ag_argv("group_remove" as *u8,"2" as *u8,"3" as *u8,"1" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 141 n = ca_dispatch(c[0], av, out) 142 if ag_has(out, n, "\"removed\":0" as *u8)==0 { t8=0 } // owner unremovable 143 ag_check(t8, "T8 group_remove: admin removes member=1, peer-admin=0, owner=0 (no coup)" as *u8, fails) 144 145 // T9: STRUCTURED ERRORS -- unknown verb and a short arg list both return ok:0 with a slug, never crash 146 av = ag_argv("bogus" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 147 n = ca_dispatch(c[0], av, out) 148 var t9: i64=1 149 if ag_has(out, n, "\"ok\":0" as *u8)==0 { t9=0 } 150 if ag_has(out, n, "\"error\":\"unknown_verb\"" as *u8)==0 { t9=0 } 151 av = ag_argv("match" as *u8,"1" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 152 n = ca_dispatch(c[0], av, out) 153 if ag_has(out, n, "\"error\":\"usage\"" as *u8)==0 { t9=0 } 154 ag_check(t9, "T9 structured errors: unknown verb + short args return ok:0 + slug (never a crash)" as *u8, fails) 155 156 // T10: translate -- the language-exchange core, original preserved beside the translation 157 av = ag_argv("translate" as *u8,"1" as *u8,"0" as *u8,"привет друг" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 158 n = ca_dispatch(c[0], av, out) 159 var t10: i64=1 160 if ag_has(out, n, "\"translation\":\"hello friend\"" as *u8)==0 { t10=0 } 161 if ag_has(out, n, "\"original\":\"привет друг\"" as *u8)==0 { t10=0 } // original kept, JSON-escaped clean 162 if ag_has(out, n, "\"unlimited\":1" as *u8)==0 { t10=0 } 163 av = ag_argv("translate" as *u8,"9" as *u8,"0" as *u8,"x" as *u8,Z,Z,Z,Z,Z,Z,Z,Z,Z,Z, c) 164 n = ca_dispatch(c[0], av, out) 165 if ag_has(out, n, "\"error\":\"range\"" as *u8)==0 { t10=0 } // bad lang -> structured error 166 ag_check(t10, "T10 translate: ru->en 'hello friend' with original preserved; bad lang = structured error" as *u8, fails) 167 168 // T11: graph -- cross-silo unification. A and C share NO language but share hobby+faith+place: the 169 // language lane returns 0, the friendship lane finds them (84). The whole product thesis in one call. 170 // node = band teach learn hob faith optin place. A: teach EN(1) learn ES(2) hob MUSIC+COOK(5) faith 1 optin place 10. 171 // C: teach FR(4) learn DE(8) hob 21 faith 1 optin place 10 -> no reciprocal lang, shared hobby+faith+place. 172 // graph needs verb + 15 fields = 16 argv entries, beyond ag_argv's 14-slot helper, so build it manually. 173 let g: *i64 = sys_mmap(20*8) as *i64 174 g[0]="graph" as *u8 as i64 175 g[1]="1" as *u8 as i64; g[2]="1" as *u8 as i64; g[3]="2" as *u8 as i64; g[4]="5" as *u8 as i64; g[5]="1" as *u8 as i64; g[6]="1" as *u8 as i64; g[7]="10" as *u8 as i64 176 g[8]="1" as *u8 as i64; g[9]="4" as *u8 as i64; g[10]="8" as *u8 as i64; g[11]="21" as *u8 as i64; g[12]="1" as *u8 as i64; g[13]="1" as *u8 as i64; g[14]="10" as *u8 as i64 177 g[15]="1" as *u8 as i64 // FRIEND lane 178 n = ca_dispatch(16, g, out) 179 var t11: i64=1 180 if ag_has(out, n, "\"verb\":\"graph\"" as *u8)==0 { t11=0 } 181 if ag_has(out, n, "\"score\":84" as *u8)==0 { t11=0 } // cross-silo friendship found 182 g[15]="0" as *u8 as i64 // LANGUAGE lane 183 n = ca_dispatch(16, g, out) 184 if ag_has(out, n, "\"score\":0" as *u8)==0 { t11=0 } // no shared language -> 0 in the language lane 185 ag_check(t11, "T11 graph: cross-silo pair scores 84 in FRIEND lane, 0 in LANGUAGE lane (one model, the thesis)" as *u8, fails) 186 187 ag_w(" fails=" as *u8); ag_n(fails[0]); ag_w("\n" as *u8) 188 if fails[0]==0 { ag_w("VERDICT: verdict=GREEN (MCP front door: 8 engines behind one versioned, self-describing, stateless JSON contract)\n" as *u8); sys_exit(0) } 189 ag_w("VERDICT: verdict=RED\n" as *u8) 190 sys_exit(1) 191 return 1 192}