code wiki / (root) / nx_fsops_lib.nx

nx_fsops_lib.nx

buildroot/runtime/nx_fsops_lib.nx

48279 B967 linesdepth 6pulls 10 transitivereach 342 importersview sourcekind librarytopic fsops
docsdependenciesstructsconstsfunctions

about

nx_fsops_lib.nx -- CONSOLIDATED filesystem tool (MCP name: nx_fs, tool #4 of the 15), LIBRARY half. (Source is named nx_fsops because nx_fs.nx is the safety-enveloped file-I/O STDLIB -- a different thing.) READ-ONLY first increment: `read` (bounded file read) + `ls` (typed dir listing). Retires ssh-cat for remote reads per rule 27 (api-first, no shell plumbing). BOUNDARY DEFENSE (rule 12 -- MCP callers are EXTERNAL input): `read` REFUSES any path that matches the secret DENY-LIST: compiled-in default needles (secret/key/token/passw/.pem, matched case-insensitively against the WHOLE path) plus data-driven extras from fs_read_deny.conf (one lowercase needle per line, CWD-relative -- rule 11: policy in data, not code). The tools-api runs where key material lives; an arbitrary-read tool that could return opaque_keys.bin or tools_cap_secret.key would convert a read-cap into a key-theft primitive. Over-blocking is the SAFE failure direction for v1. WRITE/EDIT increment (2026-07-16): fsx_write (ATOMIC tmp+fsync+rename) + fsx_edit (exact-string replace with the Claude-Edit UNIQUENESS contract). Exposed as the SEPARATE tools-api name `nx_fs_write` (its own cap class per knowledge/mcp/exposure_policy.txt: read=broad, write=cap) -- the `nx_fs` name stays read-only. The write DENY is a superset of the read deny (never clobber key material) PLUS the OS device/kernel/ firmware namespace via the nx_os_fs seam (rule 26 never-brick BY CONSTRUCTION -- not config-disableable) PLUS the tool-registry escalation surface ("allowlist") PLUS data-driven extras (fs_write_deny.conf). license_tier: ORIGINAL

dependencies 6 imports · 33 importers

nx_syscalls.nx nx_fio.nx nx_itoa_lib.nx nx_vsz_watchdog_core.nx nx_os_fs.nx nx_os_proc.nx nx_fsops_lib.nx nx_bundle_ingest.nx nx_bundle_ingest_cli_candidate_t14 nx_cast_static_canonical_gate_t335 nx_cast_static_emit_gate_t335.nx nx_cdmap_pixjudge.nx nx_fs_create_lib.nx nx_fsops.nx nx_fsops_gate.nx nx_fsops_outline.nx nx_fsops_write.nx

diagram shows first 10 each side; +0 more imports, +23 more importers in the complete lists below.

imports: nx_syscalls.nxnx_fio.nxnx_itoa_lib.nxnx_vsz_watchdog_core.nxnx_os_fs.nxnx_os_proc.nx

imported by: nx_bundle_ingest.nxnx_bundle_ingest_cli_candidate_t144.nxnx_cast_static_canonical_gate_t335.nxnx_cast_static_emit_gate_t335.nxnx_cdmap_pixjudge.nxnx_fs_create_lib.nxnx_fsops.nxnx_fsops_gate.nxnx_fsops_outline.nxnx_fsops_write.nxnx_fsops_write_candidate_t190.nxnx_game_page_artifact_lib.nxnx_id_epoch_prepare_gate_t293.nxnx_id_ledger_audit_t190.nxnx_id_ledger_claim_audit_t219.nxnx_id_ledger_existing_keys_audit_t219.nxnx_id_ledger_provenance_audit_t219.nxnx_material_cast_gate_t302.nxnx_material_normal_shader_gate_t301.nxnx_normal_shader_gate_t290.nxnx_nxa_texbake_region_capacity_t278.nxnx_nxa_texbake_region_edge_t278.nxnx_nxa_texbake_region_lib.nxnx_site_publish_alpha_candidate_t343.nxnx_site_publish_boundary_candidate_t336.nxnx_site_publish_edge_lib_t139.nxnx_site_publish_lib.nxnx_site_publish_lib_pre_release_t141.nxnx_site_publish_prepare_lib_t256.nxnx_site_publish_prepare_t198.nxnx_site_publish_release_candidate_t141.nxnx_store_id_probe.nxnx_texture_array_gate_t289.nx

structs

none

consts

25const FSX_MAGIC_4095: i64 = 4095
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)
122const FSX_SNIFF_CAP: i64 = 4096
271const FSX_SEEK_END: i64 = 2 // lseek whence: EOF offset = size, WITHOUT reading a single byte
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
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)
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)
850const FSX_JOB_DIR: *u8 = "_jobs/"
851const FSX_JOB_PFX: *u8 = "job_"
852const FSX_JOB_CLAIM: *u8 = ".claim"
853const FSX_JOB_OUT: *u8 = ".out"
854const FSX_JOB_IDMAX: i64 = 24 // a job id is an epoch-shaped integer; longer than this is not an id
855const FSX_JOB_NOSUCH: i64 = 1 // no marker: the id was never claimed (unknown id, or the lane has not claimed it yet)
856const FSX_JOB_RUNNING: i64 = 2 // marker reads state=CLAIMED
857const FSX_JOB_DONE: i64 = 3 // marker reads state=DONE with bytes>0: the output was printed
858const FSX_JOB_DONE_EMPTY: i64 = 4 // marker reads state=DONE with bytes=0: the tool produced NOTHING
859const FSX_JOB_UNPARSED: i64 = 5 // marker present, no state token this reader knows: printed verbatim
860const FSX_JOB_REFUSED: i64 = 6 // id is not digits-only
861const FSX_JOB_OUT_ABSENT: i64 = 7 // marker says DONE with bytes>0 but the output file is unreadable
862const FSX_RC_JOB_RUNNING: i64 = 8 // CLI exit for RUNNING, distinct from every other fs exit code
863const FSX_ASCII_9: i64 = 57 // '9' (decimal parse upper bound)

functions

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 }
44func fsx_putn(v: i64) -> i64 { nxi_out(v); return 0 }
46func fsx_lower(s: *u8, out: *u8, cap: i64) -> i64
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 }
70func fsx_cas_val(tok: *u8) -> *u8
called by 1: fsx_cas_ok
78func fsx_cas_ok(cur: i64, tok: *u8) -> i64
called by 1: main calls 2: fsx_cas_valfsx_seq
94func fsx_deny_hit(lp: *u8, ln: i64, needle: *u8) -> i64
101func fsx_conf_deny(lp: *u8, ln: i64, conf: *u8) -> i64
124func fsx_isalnum(c: i64) -> i64
called by 1: fsx_word_has
131func fsx_ends_with(lp: *u8, ln: i64, suf: *u8) -> i64
143func fsx_basename_is(lp: *u8, ln: i64, name: *u8) -> i64
called by 1: fsx_denied calls 1: fsx_ends_with
157func fsx_word_has(lp: *u8, ln: i64, w: *u8) -> i64
calls 1: fsx_isalnum
182func fsx_content_secret(path: *u8) -> i64
214func fsx_denied(path: *u8) -> i64
258func fsx_fail(path: *u8, rc: i64) -> i64
286func fsx_size(path: *u8) -> i64
310func fsx_read(path: *u8, cap: i64) -> i64
332func fsx_read_at(path: *u8, cap: i64, off: i64) -> i64
369func fsx_read_lines(path: *u8, start: i64, count: i64) -> i64
450func fsx_tail(path: *u8, count: i64) -> i64
530func fsx_write_denied(path: *u8) -> i64
555func fsx_tail_unterminated(path: *u8) -> i64
569func fsx_append(path: *u8, body: *u8, blen: i64) -> i64
600func fsx_write(path: *u8, body: *u8, blen: i64) -> i64
655func fsx_count_occ(hay: *u8, hn: i64, nee: *u8, nl: i64) -> i64
668func fsx_replace(hay: *u8, hn: i64, nee: *u8, nl: i64, rep: *u8, rl: i64, out: *u8, ocap: i64, allf: i64) -> i64
called by 1: fsx_edit
702func fsx_edit(path: *u8, olds: *u8, news: *u8, allf: i64) -> i64
773func fsx_edit_self_anchored(olds: *u8, news: *u8) -> i64
788func fsx_ls(dir: *u8) -> i64 { return fsx_ls_from(dir, 0) }
called by 1: main calls 1: fsx_ls_from
790func fsx_ls_from(dir: *u8, skip: i64) -> i64
865func fsx_find(buf: *u8, n: i64, needle: *u8) -> i64
880func fsx_kv_int(buf: *u8, n: i64, key: *u8) -> i64
called by 1: fsx_job_at calls 1: fsx_find
898func fsx_job_id_ok(id: *u8) -> i64
called by 1: fsx_job_at
911func fsx_job_path(dir: *u8, id: *u8, sfx: *u8, out: *u8) -> i64
called by 1: fsx_job_at
927func fsx_job_at(dir: *u8, id: *u8) -> i64
967func fsx_job(id: *u8) -> i64 { return fsx_job_at(FSX_JOB_DIR, id) }
called by 1: main calls 1: fsx_job_at