code wiki / (root) / nx_fsops_lib_dynamic_edit_t145.nx

nx_fsops_lib_dynamic_edit_t145.nx source

↩ module page · 968 lines · 48550 B

1// nx_fsops_lib.nx -- CONSOLIDATED filesystem tool (MCP name: nx_fs, tool #4 of the 15), LIBRARY half. 2// (Source is named nx_fsops because nx_fs.nx is the safety-enveloped file-I/O STDLIB -- a different thing.) 3// READ-ONLY first increment: `read` (bounded file read) + `ls` (typed dir listing). Retires ssh-cat for 4// remote reads per rule 27 (api-first, no shell plumbing). 5// 6// BOUNDARY DEFENSE (rule 12 -- MCP callers are EXTERNAL input): `read` REFUSES any path that matches the 7// secret DENY-LIST: compiled-in default needles (secret/key/token/passw/.pem, matched case-insensitively 8// against the WHOLE path) plus data-driven extras from fs_read_deny.conf (one lowercase needle per line, 9// CWD-relative -- rule 11: policy in data, not code). The tools-api runs where key material lives; an 10// arbitrary-read tool that could return opaque_keys.bin or tools_cap_secret.key would convert a read-cap 11// into a key-theft primitive. Over-blocking is the SAFE failure direction for v1. 12// WRITE/EDIT increment (2026-07-16): fsx_write (ATOMIC tmp+fsync+rename) + fsx_edit (exact-string replace 13// with the Claude-Edit UNIQUENESS contract). Exposed as the SEPARATE tools-api name `nx_fs_write` (its own 14// cap class per knowledge/mcp/exposure_policy.txt: read=broad, write=cap) -- the `nx_fs` name stays read-only. 15// The write DENY is a superset of the read deny (never clobber key material) PLUS the OS device/kernel/ 16// firmware namespace via the nx_os_fs seam (rule 26 never-brick BY CONSTRUCTION -- not config-disableable) 17// PLUS the tool-registry escalation surface ("allowlist") PLUS data-driven extras (fs_write_deny.conf). 18// license_tier: ORIGINAL 19import "nx_syscalls.nx" 20import "nx_fio.nx" 21import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 22import "nx_vsz_watchdog_core.nx" // vw_read (bounded, procfs-safe) / vw_slen / vw_contains -- proven helpers 23import "nx_os_fs.nx" // osf_write_forbidden -- device/firmware-namespace deny (OS seam, rule 26) 24import "nx_os_proc.nx" // osp_selfpid -- unique atomic-write tmp suffix (no torn tmp under concurrency) 25const FSX_MAGIC_4095: i64 = 4095 26 27const FSX_READ_CAP: i64 = 1048576 // max bytes returned by `read` (truncation is MARKED, never silent) 28const FSX_DENY_CAP: i64 = 8192 // fs_read_deny.conf read cap 29const FSX_PATH_CAP: i64 = 1024 // lowercased path work buffer 30const FSX_DENT_BUF: i64 = 65536 // getdents64 batch buffer (matches the proven vsz/heal sizing) 31const FSX_LS_CAP: i64 = 200 // scale-law: max ls entries EMITTED; true total ALWAYS declared (65KB-dump fix) 32const FSX_RC_ABSENT: i64 = 3 // exit: path absent/unreadable (mirrors nx_fileop's exists convention) 33const FSX_RC_DENIED: i64 = 5 // exit: deny-list refused the read 34const FSX_UPPER_A: i64 = 65 // 'A' (ASCII lowercasing) 35const FSX_UPPER_Z: i64 = 90 // 'Z' 36const FSX_CASE_OFF: i64 = 32 // 'a' - 'A' 37const FSX_ASCII_0: i64 = 48 // '0' (decimal print) 38 39func fsx_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 40// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 41// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 42// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 43// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 44func fsx_putn(v: i64) -> i64 { nxi_out(v); return 0 } 45// lowercase copy of s into out (bounded), returns length 46func fsx_lower(s: *u8, out: *u8, cap: i64) -> i64 { 47 var i: i64 = 0 48 while s[i] != (0 as u8) { 49 if i >= cap - 1 { out[i] = 0 as u8; return i } 50 var c: i64 = s[i] as i64 51 if c >= FSX_UPPER_A { if c <= FSX_UPPER_Z { c = c + FSX_CASE_OFF } } 52 out[i] = c as u8 53 i = i + 1 54 } 55 out[i] = 0 as u8 56 return i 57} 58// exact NUL-terminated string equality 59func fsx_seq(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 } 60// is `needle` (NUL-terminated, lowercase) contained in lowercase path lp[0..ln)? 61// ---------- compare-and-swap decision (seq1422/seq1456) ---------- 62// 63// PURE, and in the LIB on purpose: the decision used to live inside the CLI's 64// main(), where a gate cannot reach it -- which is exactly how it shipped 65// refusing every correct expectation (seq1422). A rule nothing can drive is a 66// rule nothing can prove. 67// 68// tok is the raw argv token (`expect=<n>` / `expect=any` / a bare number); 69// cur is the file's real size. Returns 1 = ALLOW, 0 = REFUSE. 70func fsx_cas_val(tok: *u8) -> *u8 { 71 var i: i64 = 0 72 while tok[i] != (0 as u8) { 73 if tok[i] == (61 as u8) { return ((tok as i64) + i + 1) as *u8 } 74 i = i + 1 75 } 76 return tok 77} 78func fsx_cas_ok(cur: i64, tok: *u8) -> i64 { 79 let v: *u8 = fsx_cas_val(tok) 80 if fsx_seq(v, "any" as *u8) == 1 { return 1 } 81 var n: i64 = 0 82 var i: i64 = 0 83 var got: i64 = 0 84 while v[i] != (0 as u8) { 85 let c: i64 = v[i] as i64 86 if c >= 48 { if c <= 57 { n = n * 10 + (c - 48); got = 1 } } 87 i = i + 1 88 } 89 if got == 0 { return 0 } 90 if n == cur { return 1 } 91 return 0 92} 93 94func fsx_deny_hit(lp: *u8, ln: i64, needle: *u8) -> i64 { 95 let nl: i64 = vw_slen(needle) 96 if nl == 0 { return 0 } 97 return vw_contains(lp, ln, needle, nl) 98} 99// data-driven deny extras: one lowercase needle per line in `conf`; 1 = some line matches the path. 100// Factored out so the read deny (fs_read_deny.conf) and write deny (fs_write_deny.conf) share ONE scanner. 101func fsx_conf_deny(lp: *u8, ln: i64, conf: *u8) -> i64 { 102 let cb: *u8 = sys_mmap(FSX_DENY_CAP) 103 let cn: i64 = vw_read(conf, cb, FSX_DENY_CAP - 1) 104 if cn > 0 { 105 var ls: i64 = 0 106 var i: i64 = 0 107 while i <= cn { 108 var eol: i64 = 0 109 if i == cn { eol = 1 } else { if cb[i] == (10 as u8) { eol = 1 } } 110 if eol == 1 { 111 if i > ls { 112 cb[i] = 0 as u8 // terminate the line in place 113 if fsx_deny_hit(lp, ln, (cb as i64 + ls) as *u8) == 1 { return 1 } 114 } 115 ls = i + 1 116 } 117 i = i + 1 118 } 119 } 120 return 0 121} 122const FSX_SNIFF_CAP: i64 = 4096 123 124func fsx_isalnum(c: i64) -> i64 { 125 if c >= 48 { if c <= 57 { return 1 } } 126 if c >= 97 { if c <= 122 { return 1 } } 127 if c >= 65 { if c <= 90 { return 1 } } 128 return 0 129} 130 131func fsx_ends_with(lp: *u8, ln: i64, suf: *u8) -> i64 { 132 let sl: i64 = vw_slen(suf) 133 if sl == 0 { return 0 } 134 if sl > ln { return 0 } 135 var i: i64 = 0 136 while i < sl { 137 if lp[ln - sl + i] != suf[i] { return 0 } 138 i = i + 1 139 } 140 return 1 141} 142 143func fsx_basename_is(lp: *u8, ln: i64, name: *u8) -> i64 { 144 let nl: i64 = vw_slen(name) 145 if nl == 0 { return 0 } 146 if nl > ln { return 0 } 147 if fsx_ends_with(lp, ln, name) == 0 { return 0 } 148 if nl == ln { return 1 } 149 let c: i64 = lp[ln - nl - 1] as i64 150 if c == 47 { return 1 } 151 if c == 92 { return 1 } 152 return 0 153} 154 155// Whole-word containment: bounded by non-alphanumeric on BOTH sides, so `api_secret.txt` is denied and 156// `secretary_notes.md` is not. 157func fsx_word_has(lp: *u8, ln: i64, w: *u8) -> i64 { 158 let wl: i64 = vw_slen(w) 159 if wl == 0 { return 0 } 160 if wl > ln { return 0 } 161 var i: i64 = 0 162 while i + wl <= ln { 163 var eq: i64 = 1 164 var k: i64 = 0 165 while k < wl { if lp[i + k] != w[k] { eq = 0; k = wl } else { k = k + 1 } } 166 if eq == 1 { 167 var lb: i64 = 1 168 if i > 0 { if fsx_isalnum(lp[i - 1] as i64) == 1 { lb = 0 } } 169 var rb: i64 = 1 170 if i + wl < ln { if fsx_isalnum(lp[i + wl] as i64) == 1 { rb = 0 } } 171 if lb == 1 { if rb == 1 { return 1 } } 172 } 173 i = i + 1 174 } 175 return 0 176} 177 178// CONTENT LEG: sniff the leading bytes for what a secret actually IS. This is the half a name-only list 179// can never do -- it denies a private key no matter what it is called, including `notes.txt`. 180// A CERTIFICATE is deliberately NOT denied: certs are public by definition, and denying them is the same 181// category error as denying the tokenizer. 182func fsx_content_secret(path: *u8) -> i64 { 183 let fd: i64 = sys_openat_rd(path) 184 if fd < 0 { return 0 } 185 let b: *u8 = sys_mmap(FSX_SNIFF_CAP) 186 let n: i64 = sys_read(fd, b, FSX_SNIFF_CAP - 1) 187 sys_close(fd) 188 if n <= 0 { return 0 } 189 if vw_contains(b, n, "PRIVATE KEY-----" as *u8, 16) == 1 { return 1 } 190 if vw_contains(b, n, "OPENSSH PRIVATE KEY" as *u8, 19) == 1 { return 1 } 191 if vw_contains(b, n, "PGP PRIVATE KEY BLOCK" as *u8, 21) == 1 { return 1 } 192 if vw_contains(b, n, "PuTTY-User-Key-File" as *u8, 19) == 1 { return 1 } 193 return 0 194} 195 196// DENY check: 1 = refuse this path. SOTA-2026 REWRITE (2026-07-31). 197// 198// THE OLD RULE WAS WRONG IN BOTH DIRECTIONS, measured on real paths: 199// OVER-BLOCKED substring "token" denied runtime/nx_tokenizer.nx -- the compiler's own tokenizer, which 200// contains no secret -- and blocked BOTH nx_fs read AND nx_fs_write on it, while 201// nx_shelltool grep returned the same bytes freely. It cost real work and bought nothing. 202// substring "key" likewise denies monkey / keyword / keyboard. 203// UNDER-BLOCKED `id_rsa`, the canonical SSH private key filename, contains NONE of 204// secret/key/token/passw/.pem and sailed straight through. 205// A denylist that blocks source and passes private keys is not a security control -- it is a rename away 206// from useless in one direction and a permanent nuisance in the other. 207// 208// REPLACEMENT -- two INDEPENDENT legs, either one denies: 209// (1) PATH leg: real secret-bearing EXTENSIONS and exact BASENAMES, matched at a true suffix/segment 210// boundary, plus whole-word `secret`/`password`. No substring-anywhere matching survives. 211// (2) CONTENT leg: PEM/OpenSSH/PGP/PuTTY private-key armour, which catches a secret regardless of name. 212// Net effect: strictly MORE secrets denied (id_rsa, a renamed key, a key with no extension) and strictly 213// FEWER ordinary sources blocked. 214func fsx_denied(path: *u8) -> i64 { 215 let lp: *u8 = sys_mmap(FSX_PATH_CAP) 216 let ln: i64 = fsx_lower(path, lp, FSX_PATH_CAP) 217 218 if fsx_ends_with(lp, ln, ".pem" as *u8) == 1 { return 1 } 219 if fsx_ends_with(lp, ln, ".key" as *u8) == 1 { return 1 } 220 if fsx_ends_with(lp, ln, ".cap" as *u8) == 1 { return 1 } 221 if fsx_ends_with(lp, ln, ".p12" as *u8) == 1 { return 1 } 222 if fsx_ends_with(lp, ln, ".pfx" as *u8) == 1 { return 1 } 223 if fsx_ends_with(lp, ln, ".jks" as *u8) == 1 { return 1 } 224 if fsx_ends_with(lp, ln, ".ppk" as *u8) == 1 { return 1 } 225 if fsx_ends_with(lp, ln, "_rsa" as *u8) == 1 { return 1 } 226 if fsx_ends_with(lp, ln, "_dsa" as *u8) == 1 { return 1 } 227 if fsx_ends_with(lp, ln, "_ecdsa" as *u8) == 1 { return 1 } 228 if fsx_ends_with(lp, ln, "_ed25519" as *u8) == 1 { return 1 } 229 230 if fsx_basename_is(lp, ln, ".env" as *u8) == 1 { return 1 } 231 if fsx_basename_is(lp, ln, "credentials" as *u8) == 1 { return 1 } 232 if fsx_basename_is(lp, ln, "shadow" as *u8) == 1 { return 1 } 233 if fsx_basename_is(lp, ln, "opaque_keys.bin" as *u8) == 1 { return 1 } 234 235 // CALIBRATED BY WORD FREQUENCY, not by one uniform rule -- the gate proved a uniform rule wrong in 236 // BOTH directions within minutes. `secret` and `passw` are high-signal and essentially absent from 237 // ordinary source, so SUBSTRING matching is correct for them and catches mysecret_key.bin. `key` and 238 // `token` are common English fragments (tokenizer, monkey, keyword, keyboard) and must NEVER be 239 // substring-matched -- that is what denied the compiler's own tokenizer. They are covered instead by 240 // the extension/suffix rules above and by the content leg below. 241 if fsx_deny_hit(lp, ln, "secret" as *u8) == 1 { return 1 } 242 if fsx_deny_hit(lp, ln, "passw" as *u8) == 1 { return 1 } 243 if fsx_deny_hit(lp, ln, "credential" as *u8) == 1 { return 1 } 244 245 if fsx_content_secret(path) == 1 { return 1 } 246 247 return fsx_conf_deny(lp, ln, "fs_read_deny.conf" as *u8) 248} 249// read: emit up to `cap` bytes of path to stdout. Returns bytes emitted; -1 absent; -2 DENIED. 250// deniedp/absent are ALSO visible in the CLI exit code. Truncation is marked with a trailing banner. 251// Failure reporter that KEEPS THE ERRNO. sys_openat_rd returns -errno, and the old message printed 252// "ABSENT" for every negative -- so EACCES (-13, EXISTS but unopenable) read as "missing", which are 253// OPPOSITE remedies. Cost a real hour on 2026-08-01: knowledge/foundation existed with mode 0100 and 254// every instrument in the stack called it absent (the mkdirp read-back that printed the errno cracked 255// the case in one call). rc>=0 means a probe re-open SUCCEEDED: the earlier read failed for a 256// non-open reason (an empty file), so say THAT. Always returns -1 (callers' contract unchanged; 257// the -2 DENIED sentinel stays distinct). 258func fsx_fail(path: *u8, rc: i64) -> i64 { 259 if rc >= 0 { sys_close(rc); fsx_puts("NX-FS EMPTY: 0 bytes: " as *u8); fsx_puts(path); fsx_puts("\n" as *u8); return 0 - 1 } 260 if rc == 0 - 13 { 261 fsx_puts("NX-FS PERMISSION (EACCES): exists but this process may not open it: " as *u8) 262 fsx_puts(path); fsx_puts("\n" as *u8) 263 return 0 - 1 264 } 265 if rc == 0 - 2 { fsx_puts("NX-FS ABSENT: " as *u8); fsx_puts(path); fsx_puts("\n" as *u8); return 0 - 1 } 266 fsx_puts("NX-FS ERROR rc=" as *u8); fsx_putn(rc) 267 fsx_puts(": " as *u8); fsx_puts(path); fsx_puts("\n" as *u8) 268 return 0 - 1 269} 270 271const FSX_SEEK_END: i64 = 2 // lseek whence: EOF offset = size, WITHOUT reading a single byte 272 273// TRUE SIZE -- the one thing no other read verb in this lib can give you (2026-08-07, debt 1786054029). 274// read/lines/outline all report BYTES THEY READ against FSX_READ_CAP/FSX_LINES_SCAN, and they DO honestly 275// declare the cap -- but an honest floor is still not a measurement: "bytes=1048576 (covers first 1048576 276// bytes only)" is the IDENTICAL answer for a 1.05MB file and a 30MB one. 277// MEASURED COST OF NOT HAVING IT: bounding ONE 1.38MB journal took TWELVE probe reads at hand-chosen 278// offsets, because the only way to learn a big file size was to binary-search EOF by hand. 279// lseek(SEEK_END) reads ZERO bytes, so the answer is exact at ANY size for one syscall. 280// Deny-list still applies: consistency with every other verb beats a special case for a metadata read. 281// CONTRACT DIFFERS FROM fsx_read ON PURPOSE: an EMPTY file returns 0, never -1. Size is the one caller for 282// which "absent" and "zero bytes" are DIFFERENT FACTS, so fsx_fail -- which folds both to -1 -- is not used 283// here. (Same distinction lt_read_tail needed: -1 ABSENT vs 0 EMPTY. A reader that conflates them cannot 284// tell a lane that never wrote from a lane whose file vanished.) 285// A DECLARED FLOOR IS HONEST BUT IT IS NOT A MEASUREMENT -- IF THE NUMBER IS CHEAP, EMIT THE NUMBER. 286func fsx_size(path: *u8) -> i64 { 287 if fsx_denied(path) == 1 { 288 fsx_puts("NX-FS-SIZE DENIED: path matches the secret deny-list. WHY: this tool never returns key material.\n" as *u8) 289 return 0 - (2 as i64) 290 } 291 let fd: i64 = sys_openat_rd(path) 292 if fd < 0 { 293 fsx_puts("NX-FS-SIZE ABSENT: cannot open " as *u8); fsx_puts(path) 294 fsx_puts(" . FIX: confirm the path with `nx_fs ls <dir>`.\n" as *u8) 295 return 0 - 1 296 } 297 let sz: i64 = sys_lseek(fd, 0, FSX_SEEK_END) 298 sys_close(fd) 299 if sz < 0 { 300 fsx_puts("NX-FS-SIZE UNSEEKABLE: " as *u8); fsx_puts(path) 301 fsx_puts(" (a pipe/char device has no size; this is NOT a zero-byte file)\n" as *u8) 302 return 0 - 1 303 } 304 fsx_puts("NX-FS-SIZE " as *u8); fsx_puts(path) 305 fsx_puts(" bytes=" as *u8); fsx_putn(sz) 306 fsx_puts(" exact=1 read_bytes=0\n" as *u8) 307 return sz 308} 309 310func fsx_read(path: *u8, cap: i64) -> i64 { 311 if fsx_denied(path) == 1 { 312 fsx_puts("NX-FS DENIED: path matches the secret deny-list (defaults + fs_read_deny.conf)\n" as *u8) 313 return 0 - (2 as i64) // DENIED sentinel (distinct from -1 absent) 314 } 315 var want: i64 = cap 316 if want <= 0 { want = FSX_READ_CAP } 317 if want > FSX_READ_CAP { want = FSX_READ_CAP } 318 let buf: *u8 = sys_mmap(want + 1) 319 let n: i64 = vw_read(path, buf, want) 320 // vw_read flattens the errno (-1 for every failure); re-probe the open ONLY on the failure path 321 // so the message can distinguish absent / permission / empty. Zero cost on success. 322 if n <= 0 { return fsx_fail(path, sys_openat_rd(path)) } 323 sys_write(1, buf, n) 324 if n == want { 325 fsx_puts("\n[NX-FS TRUNCATED at " as *u8); fsx_putn(n); fsx_puts(" bytes]\n" as *u8) 326 } 327 return n 328} 329// WINDOWED read (eats debt seq222: the tools-call transport caps ~64KB, so files past the cap were 330// unreadable over MCP): emit up to `cap` bytes starting at byte `off`. Same deny-list as fsx_read. 331// A separate function (NOT an fsx_read arity change) so every existing caller keeps its exact contract. 332func fsx_read_at(path: *u8, cap: i64, off: i64) -> i64 { 333 if fsx_denied(path) == 1 { 334 fsx_puts("NX-FS DENIED: path matches the secret deny-list (defaults + fs_read_deny.conf)\n" as *u8) 335 return 0 - (2 as i64) 336 } 337 var want: i64 = cap 338 if want <= 0 { want = FSX_READ_CAP } 339 if want > FSX_READ_CAP { want = FSX_READ_CAP } 340 let fd: i64 = sys_openat_rd(path) 341 if fd < 0 { return fsx_fail(path, fd) } 342 if off > 0 { if sys_lseek(fd, off, 0) < 0 { sys_close(fd); fsx_puts("NX-FS ABSENT: seek failed " as *u8); fsx_puts(path); fsx_puts("\n" as *u8); return 0 - 1 } } 343 let buf: *u8 = sys_mmap(want + 1) 344 var got: i64 = 0 345 var sc: i64 = 1 346 while sc == 1 { 347 let r: i64 = sys_read(fd, ((buf as i64 + got) as *u8), want - got) 348 if r <= 0 { sc = 0 } else { got = got + r; if got >= want { sc = 0 } } 349 } 350 sys_close(fd) 351 if got <= 0 { fsx_puts("NX-FS EOF: no bytes at offset " as *u8); fsx_putn(off); fsx_puts(" in " as *u8); fsx_puts(path); fsx_puts("\n" as *u8); return 0 - 1 } 352 sys_write(1, buf, got) 353 if got == want { 354 fsx_puts("\n[NX-FS WINDOW off=" as *u8); fsx_putn(off); fsx_puts(" n=" as *u8); fsx_putn(got); fsx_puts(" -- more remains]\n" as *u8) 355 } 356 return got 357} 358const FSX_LINES_SCAN: i64 = 1048576 // line-addressing scan window (matches the proven read cap) 359const FSX_LINES_MAXOUT: i64 = 262144 // max bytes emitted by one `lines` call (transport-friendly) 360const FSX_LINES_DEFN: i64 = 40 // default line count when the caller omits it 361const FSX_LINES_MAXN: i64 = 400 // max lines per call 362 363// LINE-ADDRESSED read -- THE MISSING PRIMITIVE (measured 2026-07-20): `grep` reports file:LINE but `read` 364// takes BYTES, so the two did NOT compose -- locating one function in a remote file meant hand 365// binary-searching byte offsets (cost one subagent 70K tokens + 22 calls for a single extraction). 366// Emits lines [start, start+count) 1-based, then a DECLARED envelope banner (scale-law: a caller can 367// NEVER be silently windowed -- scanned bytes, scan cap, over-window and clip flags are all stated). 368// Same deny-list as fsx_read. Returns bytes emitted; -1 absent; -2 DENIED. 369func fsx_read_lines(path: *u8, start: i64, count: i64) -> i64 { 370 if fsx_denied(path) == 1 { 371 fsx_puts("NX-FS DENIED: path matches the secret deny-list (defaults + fs_read_deny.conf)\n" as *u8) 372 return 0 - (2 as i64) 373 } 374 var s: i64 = start 375 if s < 1 { s = 1 } 376 var c: i64 = count 377 if c <= 0 { c = FSX_LINES_DEFN } 378 if c > FSX_LINES_MAXN { c = FSX_LINES_MAXN } 379 let buf: *u8 = sys_mmap(FSX_LINES_SCAN + 1) 380 let n: i64 = vw_read(path, buf, FSX_LINES_SCAN) 381 if n <= 0 { return fsx_fail(path, sys_openat_rd(path)) } 382 // walk to the first byte of line `s`; cur > s afterwards means we ran off the end (fail-loud, not empty) 383 var i: i64 = 0 384 var cur: i64 = 1 385 while cur < s { 386 if i >= n { cur = s + 1 } else { 387 if buf[i] == (10 as u8) { cur = cur + 1 } 388 i = i + 1 389 } 390 } 391 if cur > s { 392 fsx_puts("NX-FS LINES: start line " as *u8); fsx_putn(s) 393 fsx_puts(" is beyond EOF (scanned " as *u8); fsx_putn(n); fsx_puts(" bytes)\n" as *u8) 394 return 0 395 } 396 let from: i64 = i 397 var lines_out: i64 = 0 398 var j: i64 = i 399 var go: i64 = 1 400 while go == 1 { 401 if j >= n { go = 0 } else { 402 if buf[j] == (10 as u8) { 403 lines_out = lines_out + 1 404 j = j + 1 405 if lines_out >= c { go = 0 } 406 } else { j = j + 1 } 407 } 408 } 409 var outn: i64 = j - from 410 var clipped: i64 = 0 411 if outn > FSX_LINES_MAXOUT { outn = FSX_LINES_MAXOUT; clipped = 1 } 412 if outn > 0 { sys_write(1, ((buf as i64 + from) as *u8), outn) } 413 fsx_puts("\n[NX-FS LINES start=" as *u8); fsx_putn(s) 414 fsx_puts(" lines=" as *u8); fsx_putn(lines_out) 415 fsx_puts(" next=" as *u8); fsx_putn(s + lines_out) 416 fsx_puts(" bytes=" as *u8); fsx_putn(outn) 417 fsx_puts(" scanned=" as *u8); fsx_putn(n) 418 fsx_puts(" scan_cap=" as *u8); fsx_putn(FSX_LINES_SCAN) 419 if n >= FSX_LINES_SCAN { fsx_puts(" FILE-EXCEEDS-SCAN-WINDOW" as *u8) } 420 if clipped == 1 { fsx_puts(" BYTE-CLIPPED" as *u8) } 421 fsx_puts("]\n" as *u8) 422 return outn 423} 424// ==== WRITE/EDIT half (cap class: write; tools-api name nx_fs_write) ========================= 425// ★ONE DEFINITION, TWO NAMES: this const KEEPS its name so no caller changes, but its VALUE now comes 426// from the shim's MODE_0644 instead of a second literal. This line already called itself "the ecosystem's 427// file-create mode idiom" -- and it was right, which is why adding MODE_0644 to nx_syscalls without 428// finding it created a 64th copy rather than a single ruler. 429// ★★★SEARCHING BY NAME FINDS ONLY WHAT SHARES YOUR NAMING CONVENTION. TO FIND A DUPLICATE CONSTANT YOU 430// MUST SEARCH BY VALUE: a grep for `_MODE_0644` returned 10, a grep for `= 0x1a4` returned 66. 431const FSX_MODE_RW: i64 = MODE_0644 // 0644 -- the ecosystem's file-create mode idiom 432const FSX_DEC: i64 = 10 // decimal base (pid rendering in the tmp suffix) 433const FSX_EDIT_OUT: i64 = 2097152 // edit output buffer (2x read cap: bounded replacement growth) 434const FSX_TMP_ROOM: i64 = 32 // reserved room for ".nxw" + pid digits + NUL in the tmp name 435const FSX_RC_IO: i64 = 4 // exit: io failure (open/short-write/rename) 436const FSX_RC_NOMATCH: i64 = 6 // exit: edit found 0 occurrences (file UNCHANGED) 437const FSX_RC_AMBIG: i64 = 7 // exit: edit found >1 occurrences without `all` (file UNCHANGED) 438 439// write-DENY: read deny (never clobber key material) + OS device/firmware namespace (rule 26, seam, 440// BY CONSTRUCTION) + registry-escalation needle + fs_write_deny.conf extras (data-driven). 441// TAIL -- the "WHERE DOES THIS FILE END" primitive, answered from the file's own end in ONE call. 442// The documented recipe was `size`, then `read <path> <n> <size-n>`: two calls and an offset the caller 443// carries by hand. What actually happened (measured 2026-09-03): a caller chose a `lines` start from an 444// EARLIER run's size, read a window that landed mid-file, and published the window's last line as the 445// file's last line -- while the envelope on that very read said next=212. Two false mechanisms and a 446// false scope claim followed. ★A WINDOW READ IS NOT A TAIL READ. This verb cannot be pointed at the 447// middle: it seeks to the end, walks BACKWARD for the last `count` line starts, and declares its window. 448// Same deny-list as every read verb. Returns bytes emitted; 0 for an empty file (banner, never silence); 449// -1 absent/unseekable; -2 DENIED. 450func fsx_tail(path: *u8, count: i64) -> i64 { 451 if fsx_denied(path) == 1 { 452 fsx_puts("NX-FS DENIED: path matches the secret deny-list (defaults + fs_read_deny.conf)\n" as *u8) 453 return 0 - (2 as i64) 454 } 455 var c: i64 = count 456 if c <= 0 { c = FSX_LINES_DEFN } 457 if c > FSX_LINES_MAXN { c = FSX_LINES_MAXN } 458 let fd: i64 = sys_openat_rd(path) 459 if fd < 0 { return fsx_fail(path, fd) } 460 let sz: i64 = sys_lseek(fd, 0, FSX_SEEK_END) 461 if sz < 0 { 462 sys_close(fd) 463 fsx_puts("NX-FS TAIL UNSEEKABLE: " as *u8); fsx_puts(path) 464 fsx_puts(" (a pipe/char device has no end to seek to)\n" as *u8) 465 return 0 - 1 466 } 467 if sz == 0 { 468 sys_close(fd) 469 fsx_puts("[NX-FS TAIL lines=0 total_bytes=0 window_off=0 scanned=0 EMPTY-FILE]\n" as *u8) 470 return 0 471 } 472 // read the LAST scan-window of the file, never the first: a log past the window still yields its end 473 var off: i64 = 0 474 if sz > FSX_LINES_SCAN { off = sz - FSX_LINES_SCAN } 475 if sys_lseek(fd, off, 0) < 0 { 476 sys_close(fd) 477 fsx_puts("NX-FS ABSENT: seek failed " as *u8); fsx_puts(path); fsx_puts("\n" as *u8) 478 return 0 - 1 479 } 480 let buf: *u8 = sys_mmap(FSX_LINES_SCAN + 1) 481 var n: i64 = 0 482 var sc: i64 = 1 483 while sc == 1 { 484 let r: i64 = sys_read(fd, ((buf as i64 + n) as *u8), FSX_LINES_SCAN - n) 485 if r <= 0 { sc = 0 } else { n = n + r; if n >= FSX_LINES_SCAN { sc = 0 } } 486 } 487 sys_close(fd) 488 if n <= 0 { return fsx_fail(path, 0 - 1) } 489 // a single trailing newline terminates the last line; it is not an empty extra line 490 var lim: i64 = n 491 var terminated: i64 = 0 492 if buf[n - 1] == (10 as u8) { lim = n - 1; terminated = 1 } 493 // walk backward for `c` line starts 494 var p: i64 = lim 495 var seen: i64 = 0 496 var start: i64 = 0 497 var go: i64 = 1 498 while go == 1 { 499 if p <= 0 { start = 0; go = 0 } else { 500 p = p - 1 501 if buf[p] == (10 as u8) { 502 seen = seen + 1 503 if seen >= c { start = p + 1; go = 0 } 504 } 505 } 506 } 507 var lines_out: i64 = seen + 1 508 if seen >= c { lines_out = c } 509 // count the window's lines once so a caller can address the whole file with `lines` afterwards 510 var wl: i64 = 0 511 var q: i64 = 0 512 while q < lim { if buf[q] == (10 as u8) { wl = wl + 1 } q = q + 1 } 513 wl = wl + 1 514 let outn: i64 = n - start 515 if outn > 0 { sys_write(1, ((buf as i64 + start) as *u8), outn) } 516 if terminated == 0 { fsx_puts("\n" as *u8) } 517 fsx_puts("[NX-FS TAIL lines=" as *u8); fsx_putn(lines_out) 518 fsx_puts(" bytes=" as *u8); fsx_putn(outn) 519 fsx_puts(" total_bytes=" as *u8); fsx_putn(sz) 520 fsx_puts(" window_off=" as *u8); fsx_putn(off) 521 fsx_puts(" scanned=" as *u8); fsx_putn(n) 522 fsx_puts(" window_lines=" as *u8); fsx_putn(wl) 523 fsx_puts(" last_line_terminated=" as *u8); fsx_putn(terminated) 524 if off > 0 { fsx_puts(" WINDOW-IS-TAIL-OF-FILE" as *u8) } 525 if off > 0 { if start == 0 { fsx_puts(" FIRST-LINE-MAY-BE-PARTIAL" as *u8) } } 526 fsx_puts("]\n" as *u8) 527 return outn 528} 529 530func fsx_write_denied(path: *u8) -> i64 { 531 if fsx_denied(path) == 1 { return 1 } 532 if osf_write_forbidden(path) == 1 { return 1 } 533 let lp: *u8 = sys_mmap(FSX_PATH_CAP) 534 let ln: i64 = fsx_lower(path, lp, FSX_PATH_CAP) 535 if fsx_deny_hit(lp, ln, "allowlist" as *u8) == 1 { return 1 } 536 return fsx_conf_deny(lp, ln, "fs_write_deny.conf" as *u8) 537} 538// ---------- APPEND-ONLY write for journals and boards (2026-09-02) ---------- 539// ONE O_APPEND write under an exclusive flock: the row lands whole and AFTER every row already there, and 540// there is no read-modify-write window for a sibling seat to lose it in. MEASURED the same day: a `log|` 541// row appended to lang.plan by anchored CAS edit (receipt OK bytes=51180) was gone minutes later -- a 542// sibling's whole-file write had rebuilt the file from its own stale read. A BOARD IS A JOURNAL; JOURNALS 543// ARE APPENDED, NEVER REWRITTEN. The write deny-list applies unchanged (a new write path must never become 544// a way into the secret or device namespace). 545// CONTRACT: body must end in '\n' (a row that does not terminate glues itself to the next seat's row -> 546// FSX_APP_NONL, file unchanged); an empty body is refused (FSX_APP_EMPTY); when the file's LAST byte is not 547// a newline (a rewrite left an unterminated tail) one newline is prepended INSIDE the same locked write, so 548// the caller sees bytes-written == blen + 1 and can announce the heal. Returns bytes written; -2 DENIED; 549// -3 io (open/lock/short write). 550const FSX_NL: i64 = 10 // '\n' -- the row terminator this verb requires and heals 551const FSX_APP_EMPTY: i64 = 0 - 4 // append refused: nothing to append 552const FSX_APP_NONL: i64 = 0 - 5 // append refused: body does not end in a newline 553const FSX_SEEK_SET: i64 = 0 // lseek whence: absolute offset (the tail probe) 554// 1 = the file exists, is non-empty and its last byte is NOT a newline (an unterminated tail); else 0. 555func fsx_tail_unterminated(path: *u8) -> i64 { 556 let fd: i64 = sys_openat_rd(path) 557 if fd < 0 { return 0 } 558 let sz: i64 = sys_lseek(fd, 0, FSX_SEEK_END) 559 var unterminated: i64 = 0 560 if sz > 0 { 561 if sys_lseek(fd, sz - 1, FSX_SEEK_SET) == sz - 1 { 562 let lb: *u8 = sys_mmap(16) 563 if sys_read(fd, lb, 1) == 1 { if lb[0] != (FSX_NL as u8) { unterminated = 1 } } 564 } 565 } 566 sys_close(fd) 567 return unterminated 568} 569func fsx_append(path: *u8, body: *u8, blen: i64) -> i64 { 570 if fsx_write_denied(path) == 1 { 571 fsx_puts("NX-FS DENIED: append refused (secret/device-namespace/allowlist deny)\n" as *u8) 572 return 0 - (2 as i64) 573 } 574 if blen <= 0 { return FSX_APP_EMPTY } 575 if body[blen - 1] != (FSX_NL as u8) { return FSX_APP_NONL } 576 let heal: i64 = fsx_tail_unterminated(path) 577 let fd: i64 = sys_openat_append(path, FSX_MODE_RW) 578 if fd < 0 { return 0 - (3 as i64) } 579 sys_flock(fd, SYS_LOCK_EX) 580 let total: i64 = blen + heal 581 let buf: *u8 = sys_mmap(total + 1) 582 var i: i64 = 0 583 if heal == 1 { buf[0] = FSX_NL as u8; i = 1 } 584 var j: i64 = 0 585 while j < blen { buf[i] = body[j]; i = i + 1; j = j + 1 } 586 var off: i64 = 0 587 while off < total { 588 let w: i64 = sys_write(fd, ((buf as i64 + off) as *u8), total - off) 589 if w <= 0 { sys_flock(fd, SYS_LOCK_UN); sys_close(fd); return 0 - (3 as i64) } 590 off = off + w 591 } 592 sys_fsync(fd) 593 sys_flock(fd, SYS_LOCK_UN) 594 sys_close(fd) 595 return total 596} 597// ATOMIC full-file write: content lands via <path>.nxw<pid> + fsync + rename, so a reader NEVER sees a 598// torn file and concurrent writers each land whole (last rename wins; pid suffix = no shared tmp). 599// Returns bytes written; -2 DENIED; -3 io error (path too long / open / short write / rename). 600func fsx_write(path: *u8, body: *u8, blen: i64) -> i64 { 601 if fsx_write_denied(path) == 1 { 602 fsx_puts("NX-FS DENIED: write refused (secret/device-namespace/allowlist deny)\n" as *u8) 603 return 0 - (2 as i64) 604 } 605 let plen: i64 = vw_slen(path) 606 if plen + FSX_TMP_ROOM >= FSX_PATH_CAP { return 0 - (3 as i64) } 607 let tmp: *u8 = sys_mmap(FSX_PATH_CAP) 608 var i: i64 = 0 609 while i < plen { tmp[i] = path[i]; i = i + 1 } 610 let suf: *u8 = ".nxw" as *u8 611 var s: i64 = 0 612 while suf[s] != (0 as u8) { tmp[i] = suf[s]; i = i + 1; s = s + 1 } 613 var pid: i64 = osp_selfpid() 614 if pid < 0 { pid = 0 } 615 if pid == 0 { tmp[i] = FSX_ASCII_0 as u8; i = i + 1 } else { 616 let ds: *u8 = sys_mmap(FSX_TMP_ROOM) 617 var k: i64 = 0 618 while pid > 0 { ds[k] = (FSX_ASCII_0 + (pid % FSX_DEC)) as u8; pid = pid / FSX_DEC; k = k + 1 } 619 while k > 0 { tmp[i] = ds[k-1]; i = i + 1; k = k - 1 } 620 } 621 tmp[i] = 0 as u8 622 let fd: i64 = sys_openat_wr(tmp, FSX_MODE_RW) 623 if fd < 0 { return 0 - (3 as i64) } 624 var off: i64 = 0 625 while off < blen { 626 let w: i64 = sys_write(fd, ((body as i64 + off) as *u8), blen - off) 627 // UNLINK THE SCRATCH ON THE FAILURE PATH. The success path renames it away, which is exactly 628 // why a successful write leaves nothing and this leak stayed invisible: only FAILED writes 629 // litter. Each one left A FULL COPY OF THE FILE BESIDE THE FILE, and 1,054 had accumulated 630 // tree-wide by 2026-08-20 -- litter every census that globs a data directory then EATS. 631 // MEASURED that day: scratch copies under knowledge/compare/ carry [@key] citation marks the 632 // authored files do not, so a directory-wide mark census read 1,259 marks where the truth was 633 // 737. A BACKLOG WITH AN INFLOW CANNOT BE DRAINED BY A CAMPAIGN, ONLY BY CLOSING THE INFLOW: 634 // the one-time reap of 994 files was re-littered at ~2/min while it ran. 635 if w <= 0 { sys_close(fd); sys_unlinkat(tmp); return 0 - (3 as i64) } 636 off = off + w 637 } 638 sys_fsync(fd) 639 sys_close(fd) 640 // PRESERVE the original file's mode across tmp+rename (debt eaten 2026-07-18: an edit of an 641 // executable script used to land 0644 -- the exec bit vanished and the cron runner broke with 642 // rc=126). st_mode = u32 at stat offset 24; keep the permission bits (low 12) only. 643 let sb: *u8 = sys_mmap(160) 644 if sys_fstatat(path, sb) == 0 { 645 let m0: i64 = sb[24] as i64 646 let m1: i64 = sb[25] as i64 647 let om: i64 = (m0 + (m1 * 256)) & FSX_MAGIC_4095 648 if om != FSX_MODE_RW { nx_chmod(tmp, om) } 649 } 650 // The same law at the last possible failure: if the rename cannot complete, the tmp is not a 651 // partial result anyone wants -- it is litter wearing the shape of a real file. Take it with us. 652 if sys_renameat(tmp, path) < 0 { sys_unlinkat(tmp); return 0 - (3 as i64) } 653 return blen 654} 655// count non-overlapping occurrences of nee[0..nl) in hay[0..hn) 656func fsx_count_occ(hay: *u8, hn: i64, nee: *u8, nl: i64) -> i64 { 657 if nl <= 0 { return 0 } 658 var c: i64 = 0 659 var i: i64 = 0 660 while i + nl <= hn { 661 var m: i64 = 1 662 var j: i64 = 0 663 while j < nl { if hay[i+j] != nee[j] { m = 0; j = nl } else { j = j + 1 } } 664 if m == 1 { c = c + 1; i = i + nl } else { i = i + 1 } 665 } 666 return c 667} 668// replace occurrences of nee with rep into out (allf=0: first only; 1: all). Returns new length; -1 overflow. 669func fsx_replace(hay: *u8, hn: i64, nee: *u8, nl: i64, rep: *u8, rl: i64, out: *u8, ocap: i64, allf: i64) -> i64 { 670 var o: i64 = 0 671 var i: i64 = 0 672 var used: i64 = 0 673 while i < hn { 674 var m: i64 = 0 675 if i + nl <= hn { if nl > 0 { 676 var ok: i64 = 1 677 if allf == 0 { if used == 1 { ok = 0 } } 678 if ok == 1 { 679 m = 1 680 var j: i64 = 0 681 while j < nl { if hay[i+j] != nee[j] { m = 0; j = nl } else { j = j + 1 } } 682 } 683 } } 684 if m == 1 { 685 if o + rl > ocap { return 0 - 1 } 686 var k: i64 = 0 687 while k < rl { out[o] = rep[k]; o = o + 1; k = k + 1 } 688 i = i + nl 689 used = 1 690 } else { 691 if o + 1 > ocap { return 0 - 1 } 692 out[o] = hay[i] 693 o = o + 1 694 i = i + 1 695 } 696 } 697 return o 698} 699// EDIT: exact-string replace with the UNIQUENESS contract (the Claude-Edit SOTA semantic): 700// 0 matches -> -6 NOMATCH (file untouched); >1 without allf -> -7 AMBIGUOUS (file untouched); 701// otherwise replace (allf=1: every occurrence) and land ATOMICALLY via fsx_write. 702// Returns new byte length; -1 absent; -2 DENIED; -3 io/overflow; -6 nomatch; -7 ambiguous. 703func fsx_edit(path: *u8, olds: *u8, news: *u8, allf: i64) -> i64 { 704 if fsx_write_denied(path) == 1 { 705 fsx_puts("NX-FS DENIED: edit refused (secret/device-namespace/allowlist deny)\n" as *u8) 706 return 0 - 2 707 } 708 let region: *NxFileReadRegion = sys_mmap(__size_of(NxFileReadRegion)) as *NxFileReadRegion 709 if (region as i64) <= 0 { return 0 - 3 } 710 fio_region_init(region) 711 if fio_region_open(path, region) != 0 { 712 sys_munmap(region as *u8, __size_of(NxFileReadRegion)) 713 return 0 - 1 714 } 715 let n: i64 = region.total 716 if n <= 0 { 717 fio_region_close(region) 718 sys_munmap(region as *u8, __size_of(NxFileReadRegion)) 719 return 0 - 1 720 } 721 let buf: *u8 = sys_mmap(n) 722 if (buf as i64) <= 0 { 723 fio_region_close(region) 724 sys_munmap(region as *u8, __size_of(NxFileReadRegion)) 725 return 0 - 3 726 } 727 let readn: i64 = fio_region_next(region, buf, n) 728 sys_munmap(region as *u8, __size_of(NxFileReadRegion)) 729 if readn != n { sys_munmap(buf,n); return 0 - 3 } 730 let ol: i64 = vw_slen(olds) 731 let rl: i64 = vw_slen(news) 732 let cnt: i64 = fsx_count_occ(buf,n,olds,ol) 733 if cnt == 0 { sys_munmap(buf,n); return 0 - FSX_RC_NOMATCH } 734 if cnt > 1 && allf == 0 { sys_munmap(buf,n); return 0 - FSX_RC_AMBIG } 735 // Derive exact output extent from measured input and replacement count. 736 // The numeric bound is the signed length representation, not a file-size policy. 737 let delta: i64 = rl - ol 738 if delta > 0 { 739 if cnt > (9223372036854775807 - n) / delta { 740 sys_munmap(buf,n); return 0 - 3 741 } 742 } 743 let expected: i64 = n + cnt * delta 744 var capacity: i64 = expected 745 if capacity == 0 { capacity = 1 } 746 let out: *u8 = sys_mmap(capacity) 747 if (out as i64) <= 0 { sys_munmap(buf,n); return 0 - 3 } 748 let nn: i64 = fsx_replace(buf,n,olds,ol,news,rl,out,capacity,allf) 749 var result: i64 = 0 - 3 750 if nn == expected { result = fsx_write(path,out,nn) } 751 sys_munmap(out,capacity) 752 sys_munmap(buf,n) 753 return result 754} 755 756// SELF-ANCHORED EDIT PREDICATE (pure, no I/O). Does the replacement CONTAIN its own anchor? 757// UNIQUENESS IS TESTED AGAINST THE PRE-IMAGE; THE RETRY GUARANTEE IS A CLAIM ABOUT THE POST-IMAGE. 758// They coincide ONLY when the replacement destroys its anchor. When `news` contains `olds` the anchor 759// SURVIVES the apply and is STILL UNIQUE, so a retry returns OK whether or not the first call landed -- 760// the three-state table (OK=had-not-landed / NOMATCH=had-landed) collapses to ONE state and OK carries 761// ZERO discriminating information. 762// MEASURED 2026-09-04 over 12,806 edit calls in this laptop's transcripts: 8,308 true replaces, 4,343 763// self-anchored (339 permil), 155 identity, sum reconciles. Seats re-issue the unsafe shape at 95 permil 764// against a 99 permil control on the safe shape -- i.e. the retry doctrine is applied UNIFORMLY AND 765// BLINDLY because nothing in the tool discriminated by shape. Three double-applies are confirmed in the 766// record, plus the 2026-09-04 incident that produced two definitions of ba_confirmed and broke the gate 767// that admits every build on this estate. 768// The law was already banked on 2026-08-20 in nx_atomic_publish as CALLER advice keyed on a SELF-DECLARED 769// kind=. A caller can get that declaration wrong, and one did. The primitive holds BOTH strings, so the 770// kind is DERIVABLE rather than declarable -- and deriving it here is what makes writer and reader unable 771// to disagree, instead of asking them to agree by discipline. 772// Returns 1 self-anchored (retry UNSAFE) | 0 true replace (retry exact-safe). 773// An empty anchor is NOT self-anchored: fsx_edit never reaches the apply with ol==0. 774func fsx_edit_self_anchored(olds: *u8, news: *u8) -> i64 { 775 let ol: i64 = vw_slen(olds) 776 if ol == 0 { return 0 } 777 if fsx_count_occ(news, vw_slen(news), olds, ol) > 0 { return 1 } 778 return 0 779} 780 781// ls (declared below the self-anchored-edit predicate): one entry per line "<t> <name>" (t: d=dir f=file l=link o=other; . and .. skipped). 782// Returns entry count; -1 if the dir cannot be opened. 783// PAGING (2026-08-05). The cap was always honest -- it declared total= and truncated=1 -- but an 784// honest refusal is not access: knowledge/status/ holds 1027 entries, so 827 of them were simply 785// UNREACHABLE through this tool, and a worker that listed it reported "queue empty" over a job that 786// was sitting right there. u2605u2605u2605u2605u2605DECLARING A TRUNCATION IS NOT THE SAME AS OFFERING A WAY PAST IT -- 787// a loud cap with no next page is still a wall. `skip` is that way past. 788// Contract preserved exactly (rule 19): fsx_ls(dir) keeps its old signature and behaviour. 789func fsx_ls(dir: *u8) -> i64 { return fsx_ls_from(dir, 0) } 790 791func fsx_ls_from(dir: *u8, skip: i64) -> i64 { 792 let fd: i64 = sys_openat_rd(dir) 793 if fd < 0 { return fsx_fail(dir, fd) } 794 let dbuf: *u8 = sys_mmap(FSX_DENT_BUF) 795 var cnt: i64 = 0 796 var shown: i64 = 0 797 var run: i64 = 1 798 while run == 1 { 799 let n: i64 = sys_getdents64(fd, dbuf, FSX_DENT_BUF) 800 if n <= 0 { run = 0 } else { 801 var off: i64 = 0 802 while off < n { 803 let rec: *u8 = ((dbuf as i64 + off) as *u8) 804 let reclen: i64 = dirent_reclen(rec) 805 if reclen <= 0 { off = n } else { 806 let name: *u8 = dirent_name(rec) 807 // skip "." and ".." 808 var isdot: i64 = 0 809 if fsx_seq(name, "." as *u8) == 1 { isdot = 1 } 810 if fsx_seq(name, ".." as *u8) == 1 { isdot = 1 } 811 if isdot == 0 { 812 if cnt >= skip { if shown < FSX_LS_CAP { 813 let t: i64 = dirent_type(rec) 814 if t == DT_DIR { fsx_puts("d " as *u8) } else { 815 if t == DT_REG { fsx_puts("f " as *u8) } else { 816 if t == DT_LNK { fsx_puts("l " as *u8) } else { fsx_puts("o " as *u8) } } } 817 fsx_puts(name) 818 fsx_puts("\n" as *u8) 819 shown = shown + 1 820 } } 821 cnt = cnt + 1 822 } 823 off = off + reclen 824 } 825 } 826 } 827 } 828 sys_close(fd) 829 // SCALE-LAW: cap the emitted list but ALWAYS declare the true total; truncation is LOUD not silent 830 fsx_puts("NX-FS-LS skip=" as *u8) 831 fsx_putn(skip) 832 fsx_puts(" shown=" as *u8) 833 fsx_putn(shown) 834 fsx_puts(" total=" as *u8) 835 fsx_putn(cnt) 836 // u26a0THE OLD PREDICATE (cnt > shown) BECOMES A LIE THE MOMENT skip EXISTS: the LAST page would 837 // still report truncated=1 forever, so a caller paging until truncated=0 would never stop. 838 // What actually remains is everything past the window just emitted. 839 if cnt > skip + shown { fsx_puts(" truncated=1 (more remain -- next page: ls <dir> " as *u8); fsx_putn(skip + shown); fsx_puts(")\n" as *u8) } else { fsx_puts(" truncated=0\n" as *u8) } 840 return cnt 841} 842 843// ==== THE CLAIM-OR-OUT VERB (ES26, 2026-09-06) ==== 844// The most common ritual in the estate's action journal is two reads of the job lane -- the terminal marker 845// (.claim) and then the output (.out): 120,106 adjacent pairs and 87,785 triples measured by nx_actlog steps. 846// ONE call answers both. The marker decides the state and only a DONE marker earns the read of the output, so a 847// running job never reads as dead, a never-claimed id never reads as running, and an empty output never reads as 848// still working. States are NAMED, never guessed: a marker with no state token this reader knows is UNPARSED and 849// printed verbatim as data. The id is digits only, so the verb cannot be aimed outside the directory it is given. 850// fsx_job_at takes the directory so the gate drives it on a /tmp fixture; fsx_job is the production binding. 851const FSX_JOB_DIR: *u8 = "_jobs/" 852const FSX_JOB_PFX: *u8 = "job_" 853const FSX_JOB_CLAIM: *u8 = ".claim" 854const FSX_JOB_OUT: *u8 = ".out" 855const FSX_JOB_IDMAX: i64 = 24 // a job id is an epoch-shaped integer; longer than this is not an id 856const FSX_JOB_NOSUCH: i64 = 1 // no marker: the id was never claimed (unknown id, or the lane has not claimed it yet) 857const FSX_JOB_RUNNING: i64 = 2 // marker reads state=CLAIMED 858const FSX_JOB_DONE: i64 = 3 // marker reads state=DONE with bytes>0: the output was printed 859const FSX_JOB_DONE_EMPTY: i64 = 4 // marker reads state=DONE with bytes=0: the tool produced NOTHING 860const FSX_JOB_UNPARSED: i64 = 5 // marker present, no state token this reader knows: printed verbatim 861const FSX_JOB_REFUSED: i64 = 6 // id is not digits-only 862const FSX_JOB_OUT_ABSENT: i64 = 7 // marker says DONE with bytes>0 but the output file is unreadable 863const FSX_RC_JOB_RUNNING: i64 = 8 // CLI exit for RUNNING, distinct from every other fs exit code 864const FSX_ASCII_9: i64 = 57 // '9' (decimal parse upper bound) 865// first offset of needle in buf[0..n), -1 when absent (flag-terminated compare, the cursor is never the sentinel) 866func fsx_find(buf: *u8, n: i64, needle: *u8) -> i64 { 867 var m: i64 = 0 868 while needle[m] != (0 as u8) { m = m + 1 } 869 if m == 0 { return 0 - 1 } 870 var i: i64 = 0 871 while i + m <= n { 872 var j: i64 = 0 873 var same: i64 = 1 874 while j < m { if buf[i + j] != needle[j] { same = 0 } j = j + 1 } 875 if same == 1 { return i } 876 i = i + 1 877 } 878 return 0 - 1 879} 880// the integer right after `key` in buf[0..n); -1 when the key is absent or carries no digits 881func fsx_kv_int(buf: *u8, n: i64, key: *u8) -> i64 { 882 let at: i64 = fsx_find(buf, n, key) 883 if at < 0 { return 0 - 1 } 884 var kl: i64 = 0 885 while key[kl] != (0 as u8) { kl = kl + 1 } 886 var f: i64 = at + kl 887 var v: i64 = 0 888 var nd: i64 = 0 889 var scan: i64 = 1 890 while scan == 1 { 891 if f >= n { scan = 0 } else { 892 let c: i64 = buf[f] as i64 893 if c < FSX_ASCII_0 { scan = 0 } else { if c > FSX_ASCII_9 { scan = 0 } else { v = v * (10 as i64) + (c - FSX_ASCII_0); nd = nd + 1; f = f + 1 } } 894 } 895 } 896 if nd == 0 { return 0 - 1 } 897 return v 898} 899func fsx_job_id_ok(id: *u8) -> i64 { 900 var i: i64 = 0 901 while id[i] != (0 as u8) { 902 let c: i64 = id[i] as i64 903 if c < FSX_ASCII_0 { return 0 } 904 if c > FSX_ASCII_9 { return 0 } 905 i = i + 1 906 } 907 if i == 0 { return 0 } 908 if i > FSX_JOB_IDMAX { return 0 } 909 return 1 910} 911// <dir><pfx><id><sfx> into out; returns the length 912func fsx_job_path(dir: *u8, id: *u8, sfx: *u8, out: *u8) -> i64 { 913 let pfx: *u8 = FSX_JOB_PFX 914 var o: i64 = 0 915 var i: i64 = 0 916 while dir[i] != (0 as u8) { out[o] = dir[i]; o = o + 1; i = i + 1 } 917 i = 0 918 while pfx[i] != (0 as u8) { out[o] = pfx[i]; o = o + 1; i = i + 1 } 919 i = 0 920 while id[i] != (0 as u8) { out[o] = id[i]; o = o + 1; i = i + 1 } 921 i = 0 922 while sfx[i] != (0 as u8) { out[o] = sfx[i]; o = o + 1; i = i + 1 } 923 out[o] = 0 as u8 924 return o 925} 926// returns the FSX_JOB_* state; prints the marker verbatim and, on DONE with bytes>0, the output through fsx_read 927// (truncation marked, deny-list inherited) 928func fsx_job_at(dir: *u8, id: *u8) -> i64 { 929 if fsx_job_id_ok(id) == 0 { 930 fsx_puts("NX-FS-JOB REFUSED: the id must be digits only (a job number), got: " as *u8); fsx_puts(id); fsx_puts("\n" as *u8) 931 return FSX_JOB_REFUSED 932 } 933 let cp: *u8 = sys_mmap(FSX_PATH_CAP) 934 let op: *u8 = sys_mmap(FSX_PATH_CAP) 935 fsx_job_path(dir, id, FSX_JOB_CLAIM, cp) 936 fsx_job_path(dir, id, FSX_JOB_OUT, op) 937 let cb: *u8 = sys_mmap(FSX_MAGIC_4095 + 1) 938 let cn: i64 = vw_read(cp, cb, FSX_MAGIC_4095) 939 fsx_puts("NX-FS-JOB id=" as *u8); fsx_puts(id) 940 if cn <= 0 { 941 fsx_puts(" NOSUCH: no marker at " as *u8); fsx_puts(cp) 942 fsx_puts(" -- the id was never claimed by the lane (unknown id, or not claimed yet); a claimed job carries state=CLAIMED\n" as *u8) 943 return FSX_JOB_NOSUCH 944 } 945 fsx_puts(" marker=" as *u8) 946 var cl: i64 = cn 947 var strip: i64 = 1 948 while strip == 1 { if cl <= 0 { strip = 0 } else { if cb[cl - 1] == (FSX_NL as u8) { cl = cl - 1 } else { strip = 0 } } } 949 sys_write(1, cb, cl) 950 if fsx_find(cb, cn, "state=DONE" as *u8) >= 0 { 951 let b: i64 = fsx_kv_int(cb, cn, "bytes=" as *u8) 952 if b == 0 { 953 fsx_puts(" DONE-EMPTY: the tool produced NOTHING (bytes=0); it is not still working\n" as *u8) 954 return FSX_JOB_DONE_EMPTY 955 } 956 fsx_puts(" DONE: output follows\n" as *u8) 957 let r: i64 = fsx_read(op, 0) 958 if r > 0 { return FSX_JOB_DONE } 959 return FSX_JOB_OUT_ABSENT 960 } 961 if fsx_find(cb, cn, "state=CLAIMED" as *u8) >= 0 { 962 fsx_puts(" RUNNING: claimed, no terminal state yet -- the lane rewrites this marker atomically when the job ends\n" as *u8) 963 return FSX_JOB_RUNNING 964 } 965 fsx_puts(" UNPARSED: no state token this reader knows -- the marker above is data, decide from it\n" as *u8) 966 return FSX_JOB_UNPARSED 967} 968func fsx_job(id: *u8) -> i64 { return fsx_job_at(FSX_JOB_DIR, id) }