nx_compare_serve.nx source
↩ module page · 140 lines · 8598 B
1// nx_compare_serve.nx -- fork-exec backend for the `nishi_compare` MCP tool. v2 SINGLE-SOURCE: serves the EXACT
2// file the public REST endpoint serves (sites/nishifamily/compare/... relative to the tools-API CWD = nishihost)
3// -- there is NO second copy to drift (operator 2026-07-09: no frozen snapshots). Domain map: "index" -> the
4// comparison index api.json, "openapi" -> the OpenAPI 3.1 contract, "measurement" -> the existing
5// maturity/measurement.json resource, investment -> maturity/investment.json, else -> <domain>/api.json.
6// Additive command: bindings <domain> returns a public-policy-checked artifact manifest.
7// No recomputation here: nx_compare_regen, nx_sota_status and nx_tokroi own their respective reports.
8// SECURITY: the caller-supplied domain is sanitized to [a-z]{1,40} ONLY -> no path
9// traversal / injection. Absent file -> structured JSON error envelope. license_tier: ORIGINAL expect_exit:0
10import "nx_syscalls.nx"
11import "nx_compare_openapi.nx"
12const CS_SIGNED_I64_MAX: i64 = 9223372036854775807
13
14func w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
15func wc(fd: i64, code: i64) -> i64 { let t: *u8 = sys_mmap(2); t[0] = code as u8; sys_write(fd, t, 1); return 0 }
16func scopy(dst: *u8, doff: i64, src: *u8) -> i64 { var i: i64 = 0; while src[i] != (0 as u8) { dst[doff+i] = src[i]; i = i + 1 } return doff + i }
17func streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 }
18func san_ok(s: *u8) -> i64 {
19 var i: i64 = 0
20 while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c < 97 { return 0 } if c > 122 { return 0 } i = i + 1; if i > 40 { return 0 } }
21 if i == 0 { return 0 }
22 return 1
23}
24func err_json(code: *u8, dom: *u8) -> i64 {
25 wc(1, 123); wc(1, 34); w(1, "v" as *u8); wc(1, 34); wc(1, 58); wc(1, 49); wc(1, 44)
26 wc(1, 34); w(1, "error" as *u8); wc(1, 34); wc(1, 58); wc(1, 123)
27 wc(1, 34); w(1, "code" as *u8); wc(1, 34); wc(1, 58); wc(1, 34); w(1, code); wc(1, 34); wc(1, 44)
28 wc(1, 34); w(1, "domain" as *u8); wc(1, 34); wc(1, 58); wc(1, 34); w(1, dom); wc(1, 34)
29 wc(1, 125); wc(1, 125); wc(1, 10)
30 return 0
31}
32// Complete contract reads reuse the gateway reader; observed size changes refuse the snapshot.
33func cs_complete(path: *u8, size: *i64) -> *u8 {
34 size[0] = 0
35 let fd: i64 = sys_openat_rd(path)
36 if fd < 0 { return 0 as *u8 }
37 let n: i64 = sys_lseek(fd, 0, 2)
38 sys_close(fd)
39 if n <= 0 { return 0 as *u8 }
40 if n >= CS_SIGNED_I64_MAX { return 0 as *u8 }
41 let buf: *u8 = sys_mmap(n + 1)
42 if (buf as i64) <= 0 { return 0 as *u8 }
43 let read: i64 = cgo_read(path, buf, n + 1)
44 if read != n { sys_munmap(buf, n + 1); return 0 as *u8 }
45 size[0] = n; return buf
46}
47
48func cs_public(domain: *u8) -> i64 {
49 let size: *i64 = sys_mmap(8) as *i64
50 if (size as i64) <= 0 { return 0 }
51 let conf: *u8 = cs_complete("knowledge/compare/access.conf" as *u8, size)
52 if (conf as i64) <= 0 { sys_munmap(size as *u8, 8); return 0 }
53 let required: i64 = cg_required(conf, size[0], domain)
54 sys_munmap(conf, size[0] + 1); sys_munmap(size as *u8, 8)
55 return required == CG_LVL_PUBLIC
56}
57
58func cs_bindings(argc: i64, argv: *i64) -> i64 {
59 if argc != 3 { err_json("usage_bindings_domain" as *u8, "invalid" as *u8); return 2 }
60 let domain: *u8 = argv[2] as *u8
61 if san_ok(domain) == 0 { err_json("bad_domain" as *u8, "invalid" as *u8); return 2 }
62 // No authenticated HR context reaches this adapter. Only current public domains are eligible.
63 if cs_public(domain) == 0 { err_json("not_found" as *u8, "unavailable" as *u8); return 1 }
64 let prefix: *u8 = "sites/nishifamily/compare/" as *u8
65 let suffix: *u8 = "/bindings.json" as *u8
66 let dn: i64 = cg_slen(domain)
67 let pn: i64 = cg_slen(prefix) + dn + cg_slen(suffix)
68 let path: *u8 = sys_mmap(pn + 1)
69 let size: *i64 = sys_mmap(8) as *i64
70 if (path as i64) <= 0 { err_json("allocation_failed" as *u8, "unavailable" as *u8); return 3 }
71 if (size as i64) <= 0 { err_json("allocation_failed" as *u8, "unavailable" as *u8); return 3 }
72 var po: i64 = scopy(path, 0, prefix); po = scopy(path, po, domain); po = scopy(path, po, suffix); path[po] = 0 as u8
73 let data: *u8 = cs_complete(path, size)
74 if (data as i64) <= 0 { err_json("not_found" as *u8, "unavailable" as *u8); return 1 }
75 var ascii: i64 = 1; var i: i64 = 0
76 while i < size[0] { if data[i] >= (128 as u8) { ascii = 0 }; i = i + 1 }
77 let a: *u8 = "{\"v\":1,\"resource\":\"domain-bindings-artifact\",\"response_kind\":\"artifact\",\"complete\":false,\"artifact_body_included\":false,\"domain\":\"" as *u8
78 let b: *u8 = "\",\"http_url\":\"https://nishifamily.com/compare/" as *u8
79 let c: *u8 = "/bindings.json\",\"source_artifact_path\":\"" as *u8
80 let d: *u8 = "\",\"total_bytes\":" as *u8
81 let e: *u8 = ",\"sha256\":null,\"next_offset\":0,\"ascii_only\":" as *u8
82 let f: *u8 = ",\"retrieval\":{\"tool\":\"nx_fs\",\"argv_template\":[\"read\",\"" as *u8
83 let g: *u8 = "\",\"<maxbytes>\",\"<offset>\"]},\"limitations\":[\"This response describes an artifact; it does not contain the complete bindings report\",\"Use bounded existing nx_fs windows and exclude reader footers when reconstructing bytes; total_bytes is the observed length, not a hash or immutable version\",\"ASCII status describes this file observation only; generic UTF-8 byte-window safety is not asserted; use the complete HTTP resource when needed\",\"This adapter verifies current public access and complete file readability, not schema, rank evidence, function behavior, investment returns or SOTA\"]}\n" as *u8
84 // Exact text inputs plus the maximum signed-i64 decimal width and boolean width.
85 let cap: i64 = cg_slen(a)+cg_slen(b)+cg_slen(c)+cg_slen(d)+cg_slen(e)+cg_slen(f)+cg_slen(g)+dn+dn+pn+pn+20+5
86 let out: *u8 = sys_mmap(cap)
87 if (out as i64) <= 0 { sys_munmap(data, size[0]+1); err_json("allocation_failed" as *u8, "unavailable" as *u8); return 3 }
88 var o: i64 = cg_cat(out, 0, a); o = cg_cat(out, o, domain)
89 o = cg_cat(out, o, b); o = cg_cat(out, o, domain); o = cg_cat(out, o, c); o = cg_cat(out, o, path)
90 o = cg_cat(out, o, d); o = cg_catnum(out, o, size[0]); o = cg_cat(out, o, e)
91 if ascii == 1 { o = cg_cat(out, o, "true" as *u8) } else { o = cg_cat(out, o, "false" as *u8) }
92 o = cg_cat(out, o, f); o = cg_cat(out, o, path); o = cg_cat(out, o, g)
93 var sent: i64 = 0
94 while sent < o {
95 let wrote: i64 = sys_write(1, ((out as i64) + sent) as *u8, o - sent)
96 if wrote <= 0 { return 3 }; sent = sent + wrote
97 }
98 sys_munmap(data, size[0]+1); sys_munmap(out, cap); sys_munmap(path, pn+1); sys_munmap(size as *u8, 8)
99 return 0
100}
101
102func main(argc: i64, argv: *i64) -> i64 {
103 if argc >= 2 { if streq(argv[1] as *u8, "bindings" as *u8) == 1 {
104 let rc: i64 = cs_bindings(argc, argv); sys_exit(rc); return rc
105 } }
106 var dom: *u8 = "index" as *u8
107 if argc >= 2 { dom = argv[1] as *u8 }
108 if san_ok(dom) == 0 { err_json("bad_domain" as *u8, "invalid" as *u8); sys_exit(0); return 0 }
109 let path: *u8 = sys_mmap(512)
110 var o: i64 = scopy(path, 0, "sites/nishifamily/compare/" as *u8)
111 if streq(dom, "index" as *u8) == 1 { o = scopy(path, o, "api.json" as *u8) } else {
112 if streq(dom, "openapi" as *u8) == 1 { o = scopy(path, o, "openapi.json" as *u8) } else {
113 if streq(dom, "measurement" as *u8) == 1 {
114 o = scopy(path, o, "maturity/measurement.json" as *u8)
115 } else {
116 if streq(dom, "investment" as *u8) == 1 {
117 o = scopy(path, o, "maturity/investment.json" as *u8)
118 } else {
119 o = scopy(path, o, dom)
120 o = scopy(path, o, "/api.json" as *u8)
121 }
122 }
123 }
124 }
125 path[o] = 0 as u8
126 // Size the read from the file: a larger valid measurement must never become a
127 // successful JSON prefix merely because the serving adapter had a fixed reserve.
128 let size: *i64 = sys_mmap(16) as *i64
129 size[0] = 0
130 let buf: *u8 = sys_read_file(path, size)
131 if (buf as i64) == 0 { err_json("not_found" as *u8, dom); sys_exit(0); return 0 }
132 var sent: i64 = 0
133 while sent < size[0] {
134 let n: i64 = sys_write(1, ((buf as i64) + sent) as *u8, size[0] - sent)
135 if n <= 0 { sys_free_file(buf, size[0]); return 3 }
136 sent = sent + n
137 }
138 sys_free_file(buf, size[0])
139 sys_exit(0); return 0
140}