code wiki / _hdl_build / nx_mkdirp.nx

nx_mkdirp.nx source

↩ module page · 112 lines · 5094 B

1// nx_mkdirp.nx -- the missing sovereign mkdir-p MCP primitive: create a directory PATH (with parents). 2// The ecosystem had NO exposed mkdir verb (nx_fs_write cannot create parent dirs) -> knowledge/fetched/ 3// never existed -> the ~119 *_research_fetch organs ALL SAVE-FAIL'd (seq191). This fills that gap. 4// GUARDED BY CONSTRUCTION (rule 12/26): path MUST start knowledge/ | sites/ | /tmp/ , NO '..' -> writes 5// confined to safe roots, never OS/system dirs. Idempotent (mkdirat EEXIST ignored). Pattern = the proven 6// __syscall(258=mkdirat, AT_FDCWD=-100, path, 0755) used across nx_manga_get_gate / nx_evidence_gather. 7// nx_mkdirp <relpath> -> creates each path component; prints MKDIRP OK <path> 8// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 9import "nx_syscalls.nx" 10const MP_MAGIC_1024: i64 = 1024 11 12const MP_OUT: i64 = 1 13const MP_ERR: i64 = 2 14 15func mp_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 16func mp_puts(s: *u8) -> i64 { sys_write(MP_OUT, s, mp_slen(s)); return 0 } 17func mp_werr(s: *u8) -> i64 { sys_write(MP_ERR, s, mp_slen(s)); return 0 } 18func mp_starts(p: *u8, pre: *u8) -> i64 { 19 var i: i64 = 0 20 while pre[i] != (0 as u8) { 21 if p[i] != pre[i] { return 0 } 22 i = i + 1 23 } 24 return 1 25} 26func mp_has_dotdot(p: *u8) -> i64 { 27 var i: i64 = 0 28 while p[i] != (0 as u8) { 29 if p[i] == (46 as u8) { if p[i+1] == (46 as u8) { return 1 } } 30 i = i + 1 31 } 32 return 0 33} 34func mp_prefix_ok(p: *u8) -> i64 { 35 if mp_starts(p, "knowledge/" as *u8) == 1 { return 1 } 36 if mp_starts(p, "sites/" as *u8) == 1 { return 1 } 37 if mp_starts(p, "/tmp/" as *u8) == 1 { return 1 } 38 return 0 39} 40// RUNTIME-COMPUTED syscall number: a LITERAL passes through the rv64->x86 constant-translate path 41// (nx_x86_64_ctx maps 34->258), so storing it first is the documented escape hatch (sys_symlinkat 42// "forced RUNTIME", nx_cms_gate `nb[0]=258`). Returns the RAW rc -- callers need the errno. 43func mp_mkdir_one(path: *u8) -> i64 { 44 let nbox: *i64 = sys_mmap(16) as *i64 45 nbox[0] = 258 46 let rc: i64 = __syscall(nbox[0], 0 - 100, path as i64, 0x1ed, 0, 0, 0) 47 sys_munmap(nbox as *u8, 16) 48 return rc 49} 50// A directory opens read-only on Linux, so this is a real existence probe, not an inference. 51func mp_exists(path: *u8) -> i64 { 52 let fd: i64 = sys_openat_rd(path) 53 if fd < 0 { return 0 } 54 sys_close(fd) 55 return 1 56} 57 58func main(argc: i64, argv: *i64) -> i64 { 59 if argc < 2 { mp_werr("usage: nx_mkdirp <relpath under knowledge/|sites/|/tmp/>\n" as *u8); sys_exit(1); return 1 } 60 let p: *u8 = argv[1] as *u8 61 if mp_has_dotdot(p) == 1 { mp_werr("REFUSED: path must not contain '..'\n" as *u8); sys_exit(2); return 2 } 62 if mp_prefix_ok(p) == 0 { mp_werr("REFUSED: path must start knowledge/ | sites/ | /tmp/\n" as *u8); sys_exit(3); return 3 } 63 64 let buf: *u8 = sys_mmap(MP_MAGIC_1024) 65 var i: i64 = 0 66 while p[i] != (0 as u8) { buf[i] = p[i]; i = i + 1 } 67 buf[i] = 0 as u8 68 let plen: i64 = i 69 70 var j: i64 = 1 71 while j < plen { 72 if buf[j] == (47 as u8) { 73 buf[j] = 0 as u8 74 mp_mkdir_one(buf) 75 buf[j] = 47 as u8 76 } 77 j = j + 1 78 } 79 let rc: i64 = mp_mkdir_one(buf) 80 81 // READ-BACK. This organ EXISTS because ~119 fetch organs silently save-failed on a missing dir -- 82 // and it was reproducing that exact failure one layer up: it discarded the mkdirat rc and printed 83 // "MKDIRP OK" unconditionally. Measured 2026-08-01: it reported OK for knowledge/foundation/cred 84 // and the directory was never there, which sent a caller hunting a phantom root-mismatch. 85 // A WRITER IS ONLY TESTED BY A READ-BACK -- and the primitive every other writer depends on is 86 // the LAST place an unchecked success belongs. 87 if mp_exists(buf) == 0 { 88 // DISTINGUISH THE TWO FAILURES -- they have OPPOSITE remedies and reporting either as the 89 // other is what cost this session an hour. rc=-17 EEXIST + unopenable = the dir IS THERE and 90 // we lack permission (fix ownership); anything else = genuinely not created. 91 // nx_fs makes exactly this mistake, printing "ABSENT: cannot open dir" for EACCES. 92 mp_werr("MKDIRP FAILED: " as *u8); mp_werr(p) 93 if rc == 0 - 17 { mp_werr(" EXISTS but cannot be opened -- PERMISSION, not absence (rc=" as *u8) } 94 else { mp_werr(" was not created (rc=" as *u8) } 95 let t: *u8 = sys_mmap(32) 96 var m: i64 = rc 97 if m < 0 { mp_werr("-" as *u8); m = 0 - m } 98 var k: i64 = 0 99 if m == 0 { t[0] = 48 as u8; k = 1 } 100 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 101 let o: *u8 = sys_mmap(32) 102 var q: i64 = 0 103 while q < k { o[q] = t[k - 1 - q]; q = q + 1 } 104 sys_write(MP_ERR, o, k) 105 mp_werr("). NOT created -- do not treat this as success.\n" as *u8) 106 sys_exit(4) 107 return 4 108 } 109 mp_puts("MKDIRP OK " as *u8); mp_puts(p); mp_puts(" (verified present)\n" as *u8) 110 sys_exit(0) 111 return 0 112}