nx_fsops_write_dynamic_t145.nx
buildroot/runtime/nx_fsops_write_dynamic_t145.nx
about
nx_fsops_write.nx -- WRITE-CLASS CLI of the consolidated fs tool (tools-api name: nx_fs_write).
2026-07-30: `write` is now COMPARE-AND-SWAP gated (seq1379) -- see the block above fsw_usage.
Deliberately a SEPARATE binary from the read-only `nx_fs`: the exposure policy (knowledge/mcp/
exposure_policy.txt) grades reads broad and writes cap-gated, so the two live under different
capability grants. One shared library (nx_fsops_lib) -- no logic duplicated.
write <path> <content> -> ATOMIC full-file write (tmp+fsync+rename)
edit <path> <old> <new> [all] -> exact-string replace, UNIQUENESS contract (Claude-Edit semantic)
append <path> <row> -> APPEND-ONLY (one O_APPEND write under flock; row must end in '\n'):
the journal/board verb -- no anchor, no expect token, nothing rewritten
exit: 0 ok | 2 usage | 3 absent | 4 io | 5 DENIED | 6 NOMATCH | 7 AMBIGUOUS (surfaced in MCP _meta)
DENY BY CONSTRUCTION (rule 26 + 12): secret material, OS device/firmware namespace (nx_os_fs seam),
the tool allowlist, + fs_write_deny.conf extras. license_tier: ORIGINAL
dependencies 2 imports · 0 importers
imports: nx_fsops_lib_dynamic_edit_t145.nxnx_apistack_idempotency.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 16 | const FSW_USAGE_RC: i64 = 2 |
| 17 | const FSW_ARG_VERB: i64 = 1 // argv slot of the verb |
| 18 | const FSW_ARG_PATH: i64 = 2 // argv slot of the path |
| 19 | const FSW_ARG_A: i64 = 3 // write: content | edit: old-string |
| 20 | const FSW_ARG_B: i64 = 4 // edit: new-string |
| 21 | const FSW_ARG_ALL: i64 = 5 // edit: optional literal "all" |
| 22 | const FSW_ARGC_WRITE: i64 = 4 // write path content |
| 23 | const FSW_ARGC_EDIT: i64 = 5 // edit path old new |
| 24 | const FSW_ARGC_EDITALL: i64 = 6 // edit path old new all |
| 36 | const FSW_RC_CLOBBER: i64 = 8 // distinct from ABSENT/DENIED/IO/NOMATCH/AMBIG so callers can branch on it |
| 37 | const FSW_ARG_EXPECT: i64 = 4 // write: optional expect token |
| 38 | const FSW_ARGC_WRITE_EXPECT: i64 = 5 |
| 81 | const FSW_FNV_OFF: i64 = 0xcbf29ce484222325 |
| 82 | const FSW_FNV_PRIME: i64 = 0x100000001b3 |
| 151 | const FSW_IDEM_LEDGER: *u8 = "knowledge/status/fswrite_idem.jrnl" as *u8 // CWD-relative like every status file |
| 152 | const FSW_IDEM_RESULT_CAP: i64 = 1024 |
| 153 | const FSW_KEY_MIN_CH: i64 = 33 // printable ASCII, no space: a key with a TAB or newline would corrupt the ledger row |
| 154 | const FSW_KEY_MAX_CH: i64 = 126 |
| 236 | const FSW_DIR_MODE: i64 = 0x1ed // 0755 on any parent this creates -- same mode the rest of the tree uses |
| 237 | const FSW_RC_DENIED_SENTINEL: i64 = 2 // fsx_write's DENIED return; it prints its own reason, we must not double-report |
functions
| 54 | func fsw_argval(s: *u8) -> *u8 called by 1: fsw_dispatch |
| 64 | func fsw_cur_size(path: *u8) -> i64 |
| 83 | func fsw_content_hash(path: *u8) -> i64 |
| 93 | func fsw_hex_of(v: i64, out: *u8) -> i64 |
| 100 | func fsw_hex_val(s: *u8) -> i64 called by 1: fsw_expect_val |
| 120 | func fsw_print_hash(path: *u8) -> i64 |
| 126 | func fsw_expect_val(ex: *u8, path: *u8, cur: i64) -> i64 |
| 133 | func fsw_atoi(s: *u8) -> i64 called by 1: fsw_expect_val |
| 155 | func fsw_prefix(s: *u8, p: *u8) -> i64 { var i: i64 = 0; while p[i] != (0 as u8) { if s[i] != p[i] { return 0 } i = i + 1 } return 1 } |
| 156 | func fsw_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var oo: i64 = o; while s[i] != (0 as u8) { d[oo] = s[i]; oo = oo + 1; i = i + 1 } d[oo] = 0 as u8; return oo } called by 1: fsw_idem_record |
| 157 | func fsw_catn(d: *u8, o: i64, v: i64) -> i64 called by 1: fsw_idem_record |
| 170 | func fsw_keyarg(argc: i64, argv: *i64, from: i64) -> *u8 |
| 179 | func fsw_key_ok(key: *u8) -> i64 |
| 192 | func fsw_idem_replay(key: *u8) -> i64 |
| 211 | func fsw_idem_record(key: *u8, rc: i64, verb: *u8, path: *u8) -> i64 called by 1: fsw_dispatch calls 7: fsw_key_okfsw_catfsw_catnfsw_cur_sizefsw_hex_offsw_content_hash+1 |
| 231 | func fsw_usage() -> i64 |
| 249 | func fsw_mkparents(path: *u8) -> i64 |
| 274 | func fsw_rc(r: i64) -> i64 called by 1: fsw_dispatch |
| 287 | func fsw_payload_failure(path: *u8, stage: *u8, raw: i64, code: i64, next: *u8, status: *i64) -> *u8 |
| 295 | func fsw_load_text(path: *u8, status: *i64) -> *u8 |
| 329 | func main(argc: i64, argv: *i64) -> i64 |
| 352 | func fsw_dispatch(argc: i64, argv: *i64) -> i64 |