code wiki / (root) / nx_estate_path.nx

nx_estate_path.nx source

↩ module page · 94 lines · 5853 B

1// nx_estate_path.nx -- THE one act every estate organ performs before reading an artifact: 2// open a knowledge/ path WITHOUT caring which working directory it was launched from. 3// 4// WHY (measured twice in one session, 2026-08-04): 5// 1. nx_swarm_endpoint_lib read "knowledge/swarm_nodes.conf" relative. The gen daemon runs with 6// CWD=/volume1/ai/gen, so the SSOT silently missed and every consumer fell back to stale argv 7// endpoints -- the exact DHCP outage that lib was built to end, reintroduced by a CWD. 8// 2. nx_writebench and nx_writebench_gate each probed only "p" then "../p". Run from buildroot they 9// reported GREEN; run from nishihost (which is the tools-daemon CWD, i.e. EVERY MCP call) the 10// same honest board reported "result=LIAR claimed-artifacts-missing=8". A liar-killer that 11// accuses itself because of a working directory is worse than no liar-killer. 12// 13// ★★★THE LAW: a verdict that changes with the caller's working directory is not a measurement. 14// ★A fix that must be remembered at N sites has to bind to the ONE act all N perform. That act is 15// this function. Callers ask for an estate-relative path; nobody re-spells a probe order again. 16// 17// FAIL-CLOSED: absent everywhere still returns a negative fd. This widens WHERE we look, never what 18// counts as present -- an artifact that does not exist must still read as ABSENT. 19// 20// LAYER: runtime/ (primitive), so both runtime/ and _hdl_build/ organs may import it. Library only: 21// NO main(), so importing it can never cause the double-main trap. 22// license_tier: ORIGINAL 23// module: nishi-core.estate.path 24// capability: ESTATE_PATH_RESOLVE 25import "nx_syscalls.nx" 26const EP_MAGIC_1024: i64 = 1024 27 28const EP_ROOT: *u8 = "/volume1/homes/elderwesto/nishihost/\x00" as *u8 29const EP_BUILDROOT: *u8 = "/volume1/homes/elderwesto/nishihost/buildroot/\x00" as *u8 30 31func ep_join(out: *u8, pre: *u8, p: *u8) -> *u8 { 32 var o: i64 = 0 33 while pre[o] != (0 as u8) { out[o] = pre[o]; o = o + 1 } 34 var i: i64 = 0 35 while p[i] != (0 as u8) { out[o] = p[i]; o = o + 1; i = i + 1 } 36 out[o] = 0 as u8 37 return out 38} 39 40// ★ep_anchor -- the OTHER shape of this fix, for organs that read MANY estate paths (and build them 41// from prefixes at runtime, so there is no single call site to bind). Instead of rewriting N reads, 42// establish the working directory ONCE: if knowledge/ is not present in the CWD, chdir to the estate 43// root. Returns 1 if it moved, 0 if already anchored, -1 if it could not anchor. 44// 45// This is not a workaround, it is the contract made explicit -- the estate's own cron rows already 46// spell `cd /volume1/homes/elderwesto/nishihost && ./organ`, i.e. every scheduled invocation 47// ALREADY anchors. Organs that only work under that cd were relying on their caller to remember; 48// calling this as the first line of main means they no longer have to. 49// 50// ⚠USE ONLY IN ORGANS WHOSE SUBJECT IS THE ESTATE (a warden, a board, a census of the whole tree). 51// An organ that deliberately operates on WHATEVER TREE IT WAS RUN IN must NOT anchor -- for that 52// one the CWD is an input, not an accident. 53// ⚠THE MARKER MATTERS, AND MY FIRST CHOICE WAS WRONG. I first tested for `knowledge/` -- but 54// buildroot/ HAS a knowledge/ tree (that is the whole reason the write-lane logs split in two), so 55// the check passed from buildroot and the anchor silently no-opped: both organs still gave two 56// different answers. `daemons.reg` is the signed daemon SSOT and exists ONLY at the estate root 57// (verified: absent from buildroot, as are cron.reg and opaque_keys.bin; tool_allowlist.conf is 58// NOT usable -- buildroot has one too). 59// ★A PRESENCE TEST IS ONLY AS GOOD AS THE UNIQUENESS OF WHAT IT TESTS FOR. 60func ep_anchor() -> i64 { 61 let fd: i64 = sys_openat_rd("daemons.reg\x00" as *u8) 62 if fd >= 0 { sys_close(fd); return 0 } 63 // u26a0u26a0VERIFY BEFORE YOU MOVE. The old body chdir'd FIRST and verified AFTER, so on a mobile node 64 // carrying a stale /volume1 MOUNT (measured 2026-08-05: the mountpoint still EXISTS while the NAS 65 // is unreachable) the chdir SUCCEEDED, the daemons.reg check then failed, and this returned -1 66 // while LEAVING THE PROCESS IN THAT DIRECTORY. Every later relative read resolved against the dead 67 // mount -- nx_write reported "write_modes.tsv unreadable" with the file sitting perfectly readable 68 // in the node's own cwd. 69 // u2605u2605u2605u2605u2605u2605A FUNCTION THAT FAILS AFTER A SIDE EFFECT MUST UNDO THE SIDE EFFECT -- returning an error 70 // code while leaving the process somewhere else is not a failure, it is a trap that reports itself 71 // as handled. Probing the marker ABSOLUTELY designs the side effect out instead of cleaning it up, 72 // so the failure path has nothing to undo at all. 73 // u26a0A MOUNTPOINT EXISTING IS NOT THE FILESYSTEM BEING ALIVE (same class as an ARP entry for a 74 // powered-off host). 75 let probe: i64 = sys_openat_rd("/volume1/homes/elderwesto/nishihost/daemons.reg\x00" as *u8) 76 if probe < 0 { return 0 - 1 } 77 sys_close(probe) 78 if sys_chdir("/volume1/homes/elderwesto/nishihost\x00" as *u8) != 0 { return 0 - 1 } 79 return 1 80} 81 82// Open <p> read-only from wherever it legitimately lives. Probe order is deliberate: the caller's own 83// CWD wins (a hermetic gate fixture must not be shadowed by an estate file of the same name), then 84// one level up, then the two estate roots absolutely. Returns an fd, or negative when absent in ALL. 85func ep_open_rd(p: *u8) -> i64 { 86 var f: i64 = sys_openat_rd(p) 87 if f >= 0 { return f } 88 let b: *u8 = sys_mmap(EP_MAGIC_1024) 89 f = sys_openat_rd(ep_join(b, "../\x00" as *u8, p)) 90 if f >= 0 { return f } 91 f = sys_openat_rd(ep_join(b, EP_ROOT, p)) 92 if f >= 0 { return f } 93 return sys_openat_rd(ep_join(b, EP_BUILDROOT, p)) 94}