code wiki / _hdl_build / nx_tokgate.nx

nx_tokgate.nx source

↩ module page · 597 lines · 28235 B

1// nx_tokgate.nx -- TOKEN PRE-FLIGHT (engineshift ES17): the cheaper read is named BEFORE the expensive one lands. 2// 3// Operator 2026-09-02: "design the llm capabilities around minimizing unnecessary token usage autonomously 4// without my need for engagement as part of our standard ways of working without making the design and 5// coding and other stuff worse." MEASURED the same day by nx_seat_meter_beat residue over 40 days of this 6// seat's transcripts: reasoning 56 permil, authored 245 permil, MECHANICAL 668 permil -- two thirds of every 7// token is tool output re-read into context. The lever is the read, not the thinking. 8// 9// So this rides PreToolUse on Read and on the estate's nx_fs read. It sizes the subject and, when a whole-file 10// read would land more than the floor, names the digest that answers the same question in fewer bytes. 11// It NEVER blocks and emits nothing under the floor: (law) A PRE-FLIGHT THAT CAN REFUSE WILL BE DISABLED; ONE 12// THAT ONLY INFORMS SURVIVES -- and one that fires on every small read becomes noise that gets switched off. 13// (ASCII only in this file: a non-ASCII byte in the source arrived on the NAS twin 2 bytes longer through the 14// JSON argv lane, so the two trees could not be proven identical by hash.) 15// The floor is DATA (hooks/tokgate.conf, floor_bytes|N); when the conf is unreadable the bootstrap floor is 16// used and the message SAYS floor_src=bootstrap, so a silent default can never masquerade as a measurement. 17// 18// NO POWERSHELL IN THE PATH: this organ parses the hook JSON itself. Sibling of nx_memnew / nx_organnew. 19// nx_tokgate [conf-path] [shellverb-conf-path] stdin = the PreToolUse payload; stdout = {"systemMessage":...} or nothing 20// 21// ES22 / sovereignty SV3 (2026-09-05) -- THE SHELL INTERLOCK, tg_shell_interlock. Operator, verbatim: "stop using its own 22// tools when it loads and to use these and nishi estate only and if there is a gap to build into the nishi estate from 23// the first byte, no more ps1 and python and shell". The same organ now also rides PreToolUse on Bash and PowerShell: 24// it reads the command and, from DATA (hooks/shellverb.conf: tree | allow | verb rows), names the estate verb that does 25// the same work -- one row per DISTINCT verb, each stat'd against the declared source trees so the advisory can never 26// name a verb the tree cannot show (source=present / ABSENT / unverified) -- or prints GAP when no row matches, never 27// a guess. The sanctioned launcher (wsl -e _offc/<organ>.elf) is allow-listed by needle and draws nothing. Advisory 28// only: the interlock exists because the law was prose in two channels, and the estate has measured what happens to 29// an invariant that depends on a seat remembering (nx_memnew: the same doctrine written 4x with the organ one call away). 30// license_tier: ORIGINAL. No writes. No hw writes (Rule 26). 31import "nx_syscalls.nx" 32import "nx_gatekit_lib.nx" 33 34const TG_IN: i64 = 262144 35const TG_MSG: i64 = 65536 36const TG_PATH: i64 = 4096 37const TG_ROW: i64 = 256 38const TG_CONF_DEFAULT: *u8 = "/mnt/c/Users/elder/nishi-ops/hooks/tokgate.conf" 39const TG_FLOOR_BOOTSTRAP: i64 = 3072 // ONLY when the conf is unreadable, and the message names that source 40const TG_BYTES_PER_TOKEN: i64 = 4 // the estimate the message prints, declared as an estimate 41const TG_SRC_BOOTSTRAP: i64 = 0 42const TG_SRC_CONF: i64 = 1 43// ---- ES22 shell interlock ---- 44const TG_SHELLCONF_DEFAULT: *u8 = "/mnt/c/Users/elder/nishi-ops/hooks/shellverb.conf" 45const TG_CMD: i64 = 65536 // a harness command body (the payload buffer TG_IN bounds it anyway) 46const TG_FIELD: i64 = 1024 // one conf field: needle, verb, note or source name 47const TG_VERB_TABLE: i64 = 64 // distinct verbs one advisory names before it says verbs_capped=1 48const TG_EXCERPT: i64 = 96 // bytes of the command echoed back so the reader sees WHICH call drew this 49const TG_MSG_RESERVE: i64 = 4096 // headroom kept for the closing lines; verb rows stop (announced) before it 50const TG_VS_ABSENT: i64 = 0 // tg_verb_source: no tree row holds <source>.nx 51const TG_VS_PRESENT: i64 = 1 // a tree row holds it 52const TG_VS_UNVERIFIED: i64 = 2 // the conf declares no tree row, so nothing could be checked 53// ---- bytes and shapes the code spells out, each named for its meaning (rule 11) ---- 54const TG_CH_QUOTE: i64 = 34 55const TG_CH_BACKSLASH: i64 = 92 56const TG_CH_SLASH: i64 = 47 57const TG_CH_SPACE: i64 = 32 58const TG_CH_LF: i64 = 10 59const TG_CH_CR: i64 = 13 60const TG_CH_HASH: i64 = 35 // a comment row in a conf 61const TG_CH_PIPE: i64 = 124 62const TG_CH_COLON: i64 = 58 63const TG_CH_RBRACKET: i64 = 93 64const TG_CH_QMARK: i64 = 63 // what a unicode escape reads as for matching 65const TG_CH_n: i64 = 110 66const TG_CH_u: i64 = 117 67const TG_UPPER_A: i64 = 65 68const TG_UPPER_Z: i64 = 90 69const TG_CASE_DELTA: i64 = 32 70const TG_ZERO: i64 = 48 71const TG_NINE: i64 = 57 72const TG_DECIMAL: i64 = 10 73const TG_UESC_HEX_DIGITS: i64 = 4 // the four hex digits after backslash-u 74const TG_I64_BYTES: i64 = 8 75const TG_NUMBUF: i64 = 64 76const TG_MISMATCH: i64 = 9 // added to kl so the compare loop leaves on the first differing byte (never equals kl) 77const TG_FOUND_EOF: i64 = 2 // tg_strval: the key was seen but the payload ended before its value 78const TG_DRIVE_COLON_AT: i64 = 1 // X:/... -- where the colon and the slash of a Windows drive path sit 79const TG_DRIVE_SLASH_AT: i64 = 2 80const TG_DRIVE_PREFIX_LEN: i64 = 3 81const TG_ARGV_VERB: i64 = 0 // nx_fs argv: verb, path, byte cap 82const TG_ARGV_PATH: i64 = 1 83const TG_ARGV_CAP: i64 = 2 84const TG_ARG_CONF: i64 = 1 // this organ's own argv: the tokgate conf, then the shellverb conf 85const TG_ARG_SHELLCONF: i64 = 2 86const TG_COL_KIND: i64 = 0 // shellverb.conf columns 87const TG_COL_NEEDLE: i64 = 1 88const TG_COL_TREEDIR: i64 = 1 // a tree row carries its directory in the needle column 89const TG_COL_VERB: i64 = 2 90const TG_COL_NOTE: i64 = 3 91const TG_COL_SOURCE: i64 = 4 92 93// read all of stdin 94func tg_slurp(b: *u8, cap: i64) -> i64 { 95 var n: i64 = 0 96 var go: i64 = 1 97 while go == 1 { 98 let r: i64 = sys_read(0, (b as i64 + n) as *u8, cap - n - 1) 99 if r <= 0 { go = 0 } 100 if r > 0 { 101 n = n + r 102 if n >= cap - 1 { go = 0 } 103 } 104 } 105 b[n] = 0 as u8 106 return n 107} 108 109// the string value of a JSON key (`key` includes its quotes, e.g. "\"file_path\""). Not a JSON parser: the keys 110// this organ reads are unique in a hook payload and their values are plain strings, so a scan is exact. 111func tg_strval(b: *u8, n: i64, key: *u8, out: *u8, cap: i64) -> i64 { 112 let kl: i64 = gk_len(key) 113 var i: i64 = 0 114 while i + kl < n { 115 var j: i64 = 0 116 while j < kl { 117 if b[i + j] != key[j] { j = kl + TG_MISMATCH } 118 if j < kl { j = j + 1 } 119 } 120 if j == kl { 121 var p: i64 = i + kl 122 var found: i64 = 0 123 while found == 0 { 124 if p >= n { found = TG_FOUND_EOF } 125 if found == 0 { 126 if b[p] == TG_CH_QUOTE as u8 { found = 1 } 127 if found == 0 { p = p + 1 } 128 } 129 } 130 if found == 1 { 131 p = p + 1 132 var k: i64 = 0 133 var end: i64 = 0 134 while end == 0 { 135 if p >= n { end = 1 } 136 if end == 0 { 137 if b[p] == TG_CH_QUOTE as u8 { end = 1 } 138 if end == 0 { 139 var c: i64 = b[p] as i64 140 if c == TG_CH_BACKSLASH { 141 c = TG_CH_SLASH 142 if p + 1 < n { 143 if b[p + 1] == TG_CH_BACKSLASH as u8 { p = p + 1 } 144 } 145 } 146 if k < cap - 1 { out[k] = c as u8; k = k + 1 } 147 p = p + 1 148 } 149 } 150 } 151 out[k] = 0 as u8 152 return k 153 } 154 } 155 i = i + 1 156 } 157 out[0] = 0 as u8 158 return 0 159} 160 161// the idx-th string inside "argv":[ ... ]; -1 when the array ends first 162func tg_argv_str(b: *u8, n: i64, idx: i64, out: *u8, cap: i64) -> i64 { 163 let key: *u8 = "\"argv\":[" as *u8 164 let s: i64 = gk_out_pos(b, n, key) 165 out[0] = 0 as u8 166 if s < 0 { return 0 - 1 } 167 var p: i64 = s + gk_len(key) 168 var got: i64 = 0 169 while got <= idx { 170 // seek the next quote or the closing bracket 171 var seek: i64 = 1 172 while seek == 1 { 173 if p >= n { return 0 - 1 } 174 if b[p] == TG_CH_RBRACKET as u8 { return 0 - 1 } 175 if b[p] == TG_CH_QUOTE as u8 { seek = 0 } else { p = p + 1 } 176 } 177 p = p + 1 178 var k: i64 = 0 179 var end: i64 = 0 180 while end == 0 { 181 if p >= n { end = 1 } 182 if end == 0 { 183 if b[p] == TG_CH_QUOTE as u8 { end = 1 } 184 if end == 0 { 185 var c: i64 = b[p] as i64 186 if c == TG_CH_BACKSLASH { if p + 1 < n { p = p + 1; c = b[p] as i64 } } 187 if got == idx { if k < cap - 1 { out[k] = c as u8; k = k + 1 } } 188 p = p + 1 189 } 190 } 191 } 192 if got == idx { out[k] = 0 as u8; return k } 193 p = p + 1 194 got = got + 1 195 } 196 return 0 - 1 197} 198 199// the hook speaks WINDOWS paths; this organ runs in WSL. Every filesystem question is asked in /mnt/<drive>/ form. 200func tg_wsl(src: *u8, out: *u8, cap: i64) -> i64 { 201 let l: i64 = gk_len(src) 202 if l < TG_DRIVE_PREFIX_LEN { out[0] = 0 as u8; return 0 } 203 var drive: i64 = 0 204 if src[TG_DRIVE_COLON_AT] == TG_CH_COLON as u8 { if src[TG_DRIVE_SLASH_AT] == TG_CH_SLASH as u8 { drive = 1 } } 205 if drive == 0 { 206 var q: i64 = 0 207 while q < l { if q < cap - 1 { out[q] = src[q] } q = q + 1 } 208 out[l] = 0 as u8 209 return l 210 } 211 var o: i64 = gk_cat(out, 0, "/mnt/" as *u8) 212 var c: i64 = src[0] as i64 213 if c >= TG_UPPER_A { if c <= TG_UPPER_Z { c = c + TG_CASE_DELTA } } 214 out[o] = c as u8 215 o = o + 1 216 var i: i64 = TG_DRIVE_SLASH_AT 217 while i < l { 218 if o < cap - 1 { out[o] = src[i]; o = o + 1 } 219 i = i + 1 220 } 221 out[o] = 0 as u8 222 return o 223} 224 225func tg_base(p: *u8) -> *u8 { 226 let l: i64 = gk_len(p) 227 var i: i64 = l - 1 228 var s: i64 = 0 229 while i >= 0 { 230 if p[i] == TG_CH_SLASH as u8 { s = i + 1; i = 0 - 1 } 231 if i >= 0 { i = i - 1 } 232 } 233 return (p as i64 + s) as *u8 234} 235 236// the path ends in .jsonl (the suffix is bound ONCE and its length derived, so the two cannot drift) 237func tg_is_jsonl(p: *u8) -> i64 { 238 let suf: *u8 = ".jsonl" as *u8 239 let sl: i64 = gk_len(suf) 240 let l: i64 = gk_len(p) 241 if l < sl { return 0 } 242 var i: i64 = 0 243 while i < sl { if p[l - sl + i] != suf[i] { return 0 } i = i + 1 } 244 return 1 245} 246 247// JSON string body escapes for the message 248func tg_esc(dst: *u8, o: i64, src: *u8, n: i64) -> i64 { 249 var i: i64 = 0 250 var p: i64 = o 251 while i < n { 252 let c: i64 = src[i] as i64 253 if c == TG_CH_QUOTE { dst[p] = TG_CH_BACKSLASH as u8; p = p + 1; dst[p] = TG_CH_QUOTE as u8; p = p + 1 } 254 if c == TG_CH_BACKSLASH { dst[p] = TG_CH_BACKSLASH as u8; p = p + 1; dst[p] = TG_CH_BACKSLASH as u8; p = p + 1 } 255 if c == TG_CH_LF { dst[p] = TG_CH_BACKSLASH as u8; p = p + 1; dst[p] = TG_CH_n as u8; p = p + 1 } 256 if c != TG_CH_QUOTE { if c != TG_CH_BACKSLASH { if c != TG_CH_LF { if c != TG_CH_CR { 257 dst[p] = c as u8; p = p + 1 258 } } } } 259 i = i + 1 260 } 261 return p 262} 263func tg_escs(dst: *u8, o: i64, src: *u8) -> i64 { return tg_esc(dst, o, src, gk_len(src)) } 264func tg_escn(dst: *u8, o: i64, v: i64) -> i64 { 265 let t: *u8 = sys_mmap(TG_NUMBUF) 266 let tl: i64 = gk_catn(t, 0, v) 267 t[tl] = 0 as u8 268 return tg_esc(dst, o, t, tl) 269} 270 271// the floor from the conf row `floor_bytes|N`; src[0] = TG_SRC_CONF or TG_SRC_BOOTSTRAP 272func tg_floor(conf: *u8, src: *i64) -> i64 { 273 src[0] = TG_SRC_BOOTSTRAP 274 let lp: *i64 = sys_mmap(TG_I64_BYTES) as *i64 275 let b: *u8 = sys_read_file(conf, lp) 276 if (b as i64) == 0 { return TG_FLOOR_BOOTSTRAP } 277 let n: i64 = lp[0] 278 let key: *u8 = "floor_bytes|" as *u8 279 let kl: i64 = gk_len(key) 280 var i: i64 = 0 281 while i < n { 282 let e: i64 = gk_eol(b, i, n) 283 if e - i > kl { if b[i] != TG_CH_HASH as u8 { 284 var j: i64 = 0 285 var same: i64 = 1 286 while j < kl { if b[i + j] != key[j] { same = 0 } j = j + 1 } 287 if same == 1 { 288 var v: i64 = 0 289 var q: i64 = i + kl 290 while q < e { let c: i64 = b[q] as i64; if c >= TG_ZERO { if c <= TG_NINE { v = v * TG_DECIMAL + (c - TG_ZERO) } } q = q + 1 } 291 if v > 0 { src[0] = TG_SRC_CONF; return v } 292 } 293 } } 294 i = e + 1 295 } 296 return TG_FLOOR_BOOTSTRAP 297} 298 299func tg_emit(msg: *u8, m: i64) -> i64 { 300 var o: i64 = m 301 o = gk_cat(msg, o, "\"}" as *u8) 302 gk_write_all(1, msg, o) 303 return 0 304} 305 306// ES17 tg_advise: THE decision. Given the hook payload and the floor, build the advisory into msg and return its 307// length, or return 0 for silence. Pure over its inputs apart from one stat of the Read subject. 308func tg_advise(inb: *u8, n: i64, tool: *u8, floor: i64, fsrc: *i64, msg: *u8) -> i64 { 309 var m: i64 = gk_cat(msg, 0, "{\"systemMessage\":\"" as *u8) 310 311 // ---- Read: size the subject on disk ---- 312 if gk_streq(tool, "Read" as *u8) == 1 { 313 let fp: *u8 = sys_mmap(TG_PATH) 314 if tg_strval(inb, n, "\"file_path\"" as *u8, fp, TG_PATH) == 0 { return 0 } 315 // a bounded read is already the cheap form 316 if gk_out_has(inb, n, "\"limit\"" as *u8) == 1 { return 0 } 317 let wp: *u8 = sys_mmap(TG_PATH) 318 tg_wsl(fp, wp, TG_PATH) 319 let sz: i64 = gk_size(wp) 320 if sz <= floor { return 0 } 321 m = tg_escs(msg, m, "TOKEN PRE-FLIGHT (ES17, advisory): " as *u8) 322 m = tg_escs(msg, m, tg_base(fp)) 323 m = tg_escs(msg, m, " is " as *u8) 324 m = tg_escn(msg, m, sz) 325 m = tg_escs(msg, m, " B, about " as *u8) 326 m = tg_escn(msg, m, sz / TG_BYTES_PER_TOKEN) 327 m = tg_escs(msg, m, " tokens if read whole (floor " as *u8) 328 m = tg_escn(msg, m, floor) 329 m = tg_escs(msg, m, " B, floor_src=" as *u8) 330 if fsrc[0] == TG_SRC_CONF { m = tg_escs(msg, m, "conf" as *u8) } else { m = tg_escs(msg, m, "bootstrap" as *u8) } 331 m = tg_escs(msg, m, ").\nCheaper reads that answer most questions: Read with offset and limit on the region you need; Grep -n for the symbol first, then read that window; " as *u8) 332 if tg_is_jsonl(fp) == 1 { m = tg_escs(msg, m, "a .jsonl transcript belongs to nx_seat resume_map or nx_seat_meter_beat, not to a Read; " as *u8) } 333 m = tg_escs(msg, m, "an organ source usually answers from its header (Read limit 40). Measured 2026-09-02: 668 permil of this seat's tokens were tool output re-read into context. This message never blocks." as *u8) 334 return m 335 } 336 337 // ---- nx_fs read: the subject is on the NAS, so the byte cap is the whole question ---- 338 if gk_streq(tool, "mcp__nishi__nx_fs" as *u8) == 1 { 339 let verb: *u8 = sys_mmap(TG_ROW) 340 if tg_argv_str(inb, n, TG_ARGV_VERB, verb, TG_ROW) < 0 { return 0 } 341 if gk_streq(verb, "read" as *u8) == 0 { return 0 } 342 let path: *u8 = sys_mmap(TG_PATH) 343 if tg_argv_str(inb, n, TG_ARGV_PATH, path, TG_PATH) < 0 { return 0 } 344 let capS: *u8 = sys_mmap(TG_ROW) 345 var cap: i64 = 0 346 if tg_argv_str(inb, n, TG_ARGV_CAP, capS, TG_ROW) > 0 { 347 var q: i64 = 0 348 while capS[q] != (0 as u8) { let c: i64 = capS[q] as i64; if c >= TG_ZERO { if c <= TG_NINE { cap = cap * TG_DECIMAL + (c - TG_ZERO) } } q = q + 1 } 349 } 350 if cap > 0 { if cap <= floor { return 0 } } 351 m = tg_escs(msg, m, "TOKEN PRE-FLIGHT (ES17, advisory): nx_fs read " as *u8) 352 m = tg_escs(msg, m, path) 353 if cap == 0 { m = tg_escs(msg, m, " with NO byte cap" as *u8) } else { m = tg_escs(msg, m, " with cap " as *u8); m = tg_escn(msg, m, cap); m = tg_escs(msg, m, " B" as *u8) } 354 m = tg_escs(msg, m, " (floor " as *u8) 355 m = tg_escn(msg, m, floor) 356 m = tg_escs(msg, m, " B, floor_src=" as *u8) 357 if fsrc[0] == TG_SRC_CONF { m = tg_escs(msg, m, "conf" as *u8) } else { m = tg_escs(msg, m, "bootstrap" as *u8) } 358 m = tg_escs(msg, m, ").\nCheaper: nx_fs size <path> first; then a window at most the floor at the offset you need (nx_fs read <path> <bytes> <offset>) or nx_fs lines <path> <start> <count>; " as *u8) 359 if gk_out_pos(path, gk_len(path), "_jobs/" as *u8) >= 0 { m = tg_escs(msg, m, "for a job artifact read _jobs/<id>.claim first: state=DONE bytes=N says whether it finished and how big it is; " as *u8) } 360 m = tg_escs(msg, m, "a receipt you already hold (bytes, hashes, prev=) needs no re-read. This message never blocks." as *u8) 361 return m 362 } 363 return 0 364} 365 366// --------------------------------------------------------------------------------------------------------------- 367// ES22 SHELL INTERLOCK (sovereignty SV3 shares the contract) 368// --------------------------------------------------------------------------------------------------------------- 369func tg_is_shell_tool(tool: *u8) -> i64 { 370 if gk_streq(tool, "Bash" as *u8) == 1 { return 1 } 371 if gk_streq(tool, "PowerShell" as *u8) == 1 { return 1 } 372 return 0 373} 374 375// the JSON string body of `key` (quotes included) with escapes DECODED for matching: backslash-quote is a quote, a 376// doubled backslash and an escaped slash both read as a slash (a needle never has to spell a backslash, and a Windows 377// path matches the same as a WSL one), control escapes read as a space, a unicode escape as a question mark. 378// tg_strval is deliberately NOT changed: the ES17 path relies on its slash convention for Windows file paths. 379func tg_jstr(b: *u8, n: i64, key: *u8, out: *u8, cap: i64) -> i64 { 380 out[0] = 0 as u8 381 let s: i64 = gk_out_pos(b, n, key) 382 if s < 0 { return 0 } 383 var p: i64 = s + gk_len(key) 384 var seek: i64 = 1 385 while seek == 1 { 386 if p >= n { return 0 } 387 if b[p] == TG_CH_QUOTE as u8 { seek = 0 } else { p = p + 1 } 388 } 389 p = p + 1 390 var k: i64 = 0 391 var end: i64 = 0 392 while end == 0 { 393 if p >= n { end = 1 } 394 if end == 0 { 395 var c: i64 = b[p] as i64 396 if c == TG_CH_QUOTE { end = 1 } 397 if end == 0 { 398 if c == TG_CH_BACKSLASH { 399 p = p + 1 400 if p >= n { end = 1 } 401 if end == 0 { 402 let e: i64 = b[p] as i64 403 c = TG_CH_SPACE 404 if e == TG_CH_QUOTE { c = TG_CH_QUOTE } 405 if e == TG_CH_BACKSLASH { c = TG_CH_SLASH } 406 if e == TG_CH_SLASH { c = TG_CH_SLASH } 407 if e == TG_CH_u { c = TG_CH_QMARK; p = p + TG_UESC_HEX_DIGITS } 408 } 409 } 410 } 411 if end == 0 { 412 if k < cap - 1 { out[k] = c as u8; k = k + 1 } 413 p = p + 1 414 } 415 } 416 } 417 out[k] = 0 as u8 418 return k 419} 420 421// the idx-th pipe-separated field of the row [s,e) into out (CR stripped, so a CRLF conf reads the same); its length 422func tg_field(b: *u8, s: i64, e: i64, idx: i64, out: *u8, cap: i64) -> i64 { 423 var p: i64 = s 424 var f: i64 = 0 425 var k: i64 = 0 426 var done: i64 = 0 427 while done == 0 { 428 if p >= e { done = 1 } 429 if done == 0 { 430 let c: i64 = b[p] as i64 431 if c == TG_CH_PIPE { 432 if f == idx { done = 1 } 433 f = f + 1 434 } else { 435 if f == idx { if c != TG_CH_CR { if k < cap - 1 { out[k] = c as u8; k = k + 1 } } } 436 } 437 p = p + 1 438 } 439 } 440 out[k] = 0 as u8 441 return k 442} 443 444// does <name>.nx exist under any tree| row of the conf? TG_VS_PRESENT / TG_VS_ABSENT / TG_VS_UNVERIFIED (no tree row 445// declared, so nothing could be looked at -- an advisory must say it could not look, never imply it did) 446func tg_verb_source(cb: *u8, cn: i64, name: *u8, kind: *u8, root: *u8, path: *u8) -> i64 { 447 var trees: i64 = 0 448 var i: i64 = 0 449 while i < cn { 450 let e: i64 = gk_eol(cb, i, cn) 451 if e > i { if cb[i] != TG_CH_HASH as u8 { 452 tg_field(cb, i, e, TG_COL_KIND, kind, TG_FIELD) 453 if gk_streq(kind, "tree" as *u8) == 1 { 454 trees = trees + 1 455 tg_field(cb, i, e, TG_COL_TREEDIR, root, TG_FIELD) 456 var o: i64 = gk_cat(path, 0, root) 457 o = gk_cat(path, o, name) 458 o = gk_cat(path, o, ".nx" as *u8) 459 path[o] = 0 as u8 460 if gk_exists(path) == 1 { return TG_VS_PRESENT } 461 } 462 } } 463 i = e + 1 464 } 465 if trees == 0 { return TG_VS_UNVERIFIED } 466 return TG_VS_ABSENT 467} 468 469// ES22 tg_shell_interlock: THE decision for a Bash or PowerShell call. Builds the advisory into msg and returns its 470// length; 0 is silence (no command in the payload, or the sanctioned launcher). Pure over the payload and the conf 471// apart from one stat per DISTINCT verb named. 472func tg_shell_interlock(inb: *u8, n: i64, tool: *u8, shellconf: *u8, msg: *u8) -> i64 { 473 let cmd: *u8 = sys_mmap(TG_CMD) 474 let cl: i64 = tg_jstr(inb, n, "\"command\"" as *u8, cmd, TG_CMD) 475 if cl <= 0 { return 0 } 476 var m: i64 = gk_cat(msg, 0, "{\"systemMessage\":\"" as *u8) 477 let lp: *i64 = sys_mmap(TG_I64_BYTES) as *i64 478 let cb: *u8 = sys_read_file(shellconf, lp) 479 if (cb as i64) == 0 { 480 m = tg_escs(msg, m, "SHELL PRE-FLIGHT (ES22, advisory): shellverb.conf unreadable at " as *u8) 481 m = tg_escs(msg, m, shellconf) 482 m = tg_escs(msg, m, " -- no verb table, so this " as *u8) 483 m = tg_escs(msg, m, tool) 484 m = tg_escs(msg, m, " call reads GAP by construction (conf_src=unreadable). Restore the table before trusting any silence from this hook. This message never blocks." as *u8) 485 return m 486 } 487 let cn: i64 = lp[0] 488 let kind: *u8 = sys_mmap(TG_FIELD) 489 let needle: *u8 = sys_mmap(TG_FIELD) 490 let note: *u8 = sys_mmap(TG_FIELD) 491 let srcn: *u8 = sys_mmap(TG_FIELD) 492 let root: *u8 = sys_mmap(TG_FIELD) 493 let path: *u8 = sys_mmap(TG_PATH) 494 // pass 1: the sanctioned launcher draws nothing 495 var i: i64 = 0 496 while i < cn { 497 let e: i64 = gk_eol(cb, i, cn) 498 if e > i { if cb[i] != TG_CH_HASH as u8 { 499 tg_field(cb, i, e, TG_COL_KIND, kind, TG_FIELD) 500 if gk_streq(kind, "allow" as *u8) == 1 { 501 if tg_field(cb, i, e, TG_COL_NEEDLE, needle, TG_FIELD) > 0 { 502 if gk_out_pos(cmd, cl, needle) >= 0 { return 0 } 503 } 504 } 505 } } 506 i = e + 1 507 } 508 // pass 2: every verb row whose needle is in the command -- one row per DISTINCT verb, each source stat'd 509 let seen: *u8 = sys_mmap(TG_VERB_TABLE * TG_FIELD) 510 var nseen: i64 = 0 511 var capped: i64 = 0 512 var truncated: i64 = 0 513 let body: *u8 = sys_mmap(TG_MSG) 514 var bm: i64 = 0 515 i = 0 516 while i < cn { 517 let e: i64 = gk_eol(cb, i, cn) 518 if e > i { if cb[i] != TG_CH_HASH as u8 { 519 tg_field(cb, i, e, TG_COL_KIND, kind, TG_FIELD) 520 if gk_streq(kind, "verb" as *u8) == 1 { 521 if tg_field(cb, i, e, TG_COL_NEEDLE, needle, TG_FIELD) > 0 { 522 if gk_out_pos(cmd, cl, needle) >= 0 { 523 if nseen >= TG_VERB_TABLE { capped = 1 } else { 524 let slot: *u8 = (seen as i64 + nseen * TG_FIELD) as *u8 525 tg_field(cb, i, e, TG_COL_VERB, slot, TG_FIELD) 526 var dup: i64 = 0 527 var s: i64 = 0 528 while s < nseen { if gk_streq((seen as i64 + s * TG_FIELD) as *u8, slot) == 1 { dup = 1 } s = s + 1 } 529 if dup == 0 { 530 if bm >= TG_MSG - TG_MSG_RESERVE { truncated = 1 } else { 531 tg_field(cb, i, e, TG_COL_NOTE, note, TG_FIELD) 532 if tg_field(cb, i, e, TG_COL_SOURCE, srcn, TG_FIELD) == 0 { let sl: i64 = gk_cat(srcn, 0, slot); srcn[sl] = 0 as u8 } 533 bm = tg_escs(body, bm, "\n " as *u8) 534 bm = tg_escs(body, bm, needle) 535 bm = tg_escs(body, bm, " -> mcp__nishi__" as *u8) 536 bm = tg_escs(body, bm, slot) 537 let pres: i64 = tg_verb_source(cb, cn, srcn, kind, root, path) 538 if pres == TG_VS_PRESENT { bm = tg_escs(body, bm, " source=present" as *u8) } 539 if pres == TG_VS_ABSENT { bm = tg_escs(body, bm, " source=ABSENT (no tree row holds its .nx: this row names a verb the tree cannot show -- fix the row, never trust it)" as *u8) } 540 if pres == TG_VS_UNVERIFIED { bm = tg_escs(body, bm, " source=unverified (the conf declares no tree row)" as *u8) } 541 if gk_len(note) > 0 { bm = tg_escs(body, bm, " -- " as *u8); bm = tg_escs(body, bm, note) } 542 } 543 nseen = nseen + 1 544 } 545 } 546 } 547 } 548 } 549 } } 550 i = e + 1 551 } 552 m = tg_escs(msg, m, "SHELL PRE-FLIGHT (ES22, advisory): the seat has one surface, the estate, and this " as *u8) 553 m = tg_escs(msg, m, tool) 554 m = tg_escs(msg, m, " call reaches for a shell. command: " as *u8) 555 var ex: i64 = cl 556 if ex > TG_EXCERPT { ex = TG_EXCERPT } 557 m = tg_esc(msg, m, cmd, ex) 558 if cl > TG_EXCERPT { m = tg_escs(msg, m, " ..." as *u8) } 559 if nseen == 0 { 560 m = tg_escs(msg, m, "\nGAP -- no verb row in " as *u8) 561 m = tg_escs(msg, m, shellconf) 562 m = tg_escs(msg, m, " matches this command. Declare it: a verb row (verb|needle|organ|note) there, and when no organ does this work yet, a rung on /compare/engineshift naming the build. Never a guessed verb." as *u8) 563 } else { 564 m = tg_escs(msg, m, "\nverbs=" as *u8) 565 m = tg_escn(msg, m, nseen) 566 m = tg_escs(msg, m, " -- the estate does this work:" as *u8) 567 var q: i64 = 0 568 while q < bm { msg[m] = body[q]; m = m + 1; q = q + 1 } 569 if capped == 1 { m = tg_escs(msg, m, "\nverbs_capped=1 (the table holds " as *u8); m = tg_escn(msg, m, TG_VERB_TABLE); m = tg_escs(msg, m, " distinct verbs; rows beyond it were counted, not shown)" as *u8) } 570 if truncated == 1 { m = tg_escs(msg, m, "\nrows_truncated=1 (message reserve reached; the verb count above is still complete)" as *u8) } 571 } 572 m = tg_escs(msg, m, "\nconf_src=conf. A denied MCP tool takes the cap token as the sibling parameter _cap. This message never blocks." as *u8) 573 return m 574} 575 576func main(argc: i64, argv: *i64) -> i64 { 577 var conf: *u8 = TG_CONF_DEFAULT 578 if argc > TG_ARG_CONF { conf = argv[TG_ARG_CONF] as *u8 } 579 var shellconf: *u8 = TG_SHELLCONF_DEFAULT 580 if argc > TG_ARG_SHELLCONF { shellconf = argv[TG_ARG_SHELLCONF] as *u8 } 581 let inb: *u8 = sys_mmap(TG_IN) 582 let n: i64 = tg_slurp(inb, TG_IN) 583 if n <= 0 { return 0 } 584 let tool: *u8 = sys_mmap(TG_ROW) 585 if tg_strval(inb, n, "\"tool_name\"" as *u8, tool, TG_ROW) == 0 { return 0 } 586 let msg: *u8 = sys_mmap(TG_MSG) 587 var m: i64 = 0 588 if tg_is_shell_tool(tool) == 1 { 589 m = tg_shell_interlock(inb, n, tool, shellconf, msg) 590 } else { 591 let fsrc: *i64 = sys_mmap(TG_I64_BYTES) as *i64 592 let floor: i64 = tg_floor(conf, fsrc) 593 m = tg_advise(inb, n, tool, floor, fsrc, msg) 594 } 595 if m > 0 { tg_emit(msg, m) } 596 return 0 597}