code wiki / (root) / nx_estate_path.nx

nx_estate_path.nx source

↩ module page · 190 lines · 11458 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} 95 96// ---- ep_artifact_path: THE PATH HALF OF ep_open_rd (2026-08-25) ---- 97// ep_open_rd hands back an FD, which is right for a streaming reader and wrong for every caller that 98// wants the WHOLE file -- those compose sys_read_file, which takes a PATH and does its own open, 99// lseek-END sizing and growth. Without this half a caller must either open the file twice or 100// re-implement that read loop, which is the duplicate-ruler defect this file exists to prevent. 101// MEASURED THE DAY IT WAS ADDED: nx_extllm read "knowledge/extllm_terms.conf" relative and got nothing. 102// The conf lives in buildroot/knowledge/ while the tools daemon runs with CWD=nishihost. It failed 103// CLOSED and refused rather than assuming -- correct -- but the artifact was present the whole time, 104// which is exactly the working-directory verdict this file's own law forbids. 105// Same probe order and the same fail-closed contract as ep_open_rd: 1 + path in out, 0 + empty out. 106func ep_artifact_path(out: *u8, p: *u8) -> i64 { 107 var f: i64 = sys_openat_rd(p) 108 if f >= 0 { 109 sys_close(f) 110 var i: i64 = 0 111 while p[i] != (0 as u8) { out[i] = p[i]; i = i + 1 } 112 out[i] = 0 as u8 113 return 1 114 } 115 f = sys_openat_rd(ep_join(out, "../\x00" as *u8, p)) 116 if f >= 0 { sys_close(f); return 1 } 117 f = sys_openat_rd(ep_join(out, EP_ROOT, p)) 118 if f >= 0 { sys_close(f); return 1 } 119 f = sys_openat_rd(ep_join(out, EP_BUILDROOT, p)) 120 if f >= 0 { sys_close(f); return 1 } 121 out[0] = 0 as u8 122 return 0 123} 124 125// ---- ep_src_path: THE SOURCE-ROOT HALF OF THIS FILE'S OWN LAW (2026-08-17) ---- 126// This file solved the ESTATE-PATH half and left the SOURCE-ROOT half open; the estate paid twice in 127// one day -- nx_catalog said "ABSENT ... It does not exist" and nx_stale_check said NOSOURCE, both 128// about organs that exist, because each carried its OWN two-root probe. 129// MEASURED, corpus_complete=1: bin/ 20 + hub/ 28 + wiki/ 35 = 83 files invisible to a two-root probe, 130// incl. nx_sites_daemon whose binary sites.elf is 815,480 B on disk. 131// ★I ALMOST SHIPPED THE DUPLICATE-RULER DEFECT WHILE FIXING THE LOOKUP DEFECT (cat_src in one organ, 132// sc_src in the other, the same function twice). This is the one guard both compose. 133// ★MATCH THE RESOLVER YOU REPORT ON: roots are the shipping import.nx try_resolve_import set. 134// ★COMPOSING ep_open_rd INHERITS CWD-INDEPENDENCE -- the private copies used a bare relative open and 135// would answer differently by launch directory. DEDUPLICATING MADE IT MORE CORRECT, NOT JUST SHORTER. 136// ⚠BOTTOM OF FILE ON PURPOSE: nx is single-pass, so ep_src_try sees ep_open_rd only if defined after. 137// Historical two roots FIRST: this can only turn an ABSENT into a found source, never the reverse. 138// FAIL-CLOSED like ep_open_rd. Returns 1 + writes the path into out; 0 + empty out when absent. 139func ep_src_try(out: *u8, sub: *u8, target: *u8) -> i64 { 140 var o: i64 = 0 141 let pre: *u8 = "runtime/\x00" as *u8 142 while pre[o] != (0 as u8) { out[o] = pre[o]; o = o + 1 } 143 var i: i64 = 0 144 while sub[i] != (0 as u8) { out[o] = sub[i]; o = o + 1; i = i + 1 } 145 i = 0 146 while target[i] != (0 as u8) { out[o] = target[i]; o = o + 1; i = i + 1 } 147 let suf: *u8 = ".nx\x00" as *u8 148 i = 0 149 while suf[i] != (0 as u8) { out[o] = suf[i]; o = o + 1; i = i + 1 } 150 out[o] = 0 as u8 151 // BUILDROOT-ANCHORED BY CONSTRUCTION -- CORRECTED 2026-08-17, HOURS AFTER SHIPPING THE CWD-FIRST 152 // VERSION ABOVE. ep_open_rd probes the CALLER'S CWD first, which is right for reading an estate 153 // ARTIFACT and WRONG for resolving SOURCE. MEASURED: nishihost/runtime/ is an ARTIFACT directory -- 154 // its _hdl_build/ holds 39 .bin/.bin.gold golden fixtures for the kernel and driver gates (total=48, 155 // truncated=0) -- and it has ALSO accumulated ~24 stray .nx copies plus probe/.nxw scratch. Those 156 // copies DISAGREE with the source tree: nx_filehash cmp on nx_licgate.nx gives identical=0, 157 // 18327 B (48d780af) at the estate root vs 16855 B (e7be44df) in buildroot. 158 // ★A CWD-FIRST SOURCE PROBE LAUNCHED FROM nishihost WOULD RESOLVE A DIFFERENT FILE THAN THE BUILD 159 // LANE COMPILES -- and it would do so silently, which is the same class of defect this file exists 160 // to end, one layer down. The build lane is buildroot-rooted (nx_stale_check chdir's to buildroot; 161 // nx_sov_build_run runs from there), so THE SOURCE TREE IS buildroot/runtime BY DEFINITION. 162 // CWD remains a FALLBACK so a hermetic or local tree still resolves -- it simply can no longer WIN. 163 // On a buildroot hit `out` is rewritten to the ABSOLUTE path, so the caller opens what was probed 164 // rather than a relative path that may resolve elsewhere. 165 let ab: *u8 = sys_mmap(EP_MAGIC_1024) 166 ep_join(ab, EP_BUILDROOT, out) 167 let fa: i64 = sys_openat_rd(ab) 168 if fa >= 0 { 169 sys_close(fa) 170 var k: i64 = 0 171 while ab[k] != (0 as u8) { out[k] = ab[k]; k = k + 1 } 172 out[k] = 0 as u8 173 return 1 174 } 175 let f: i64 = ep_open_rd(out) 176 if f < 0 { return 0 } 177 sys_close(f) 178 return 1 179} 180 181func ep_src_path(out: *u8, target: *u8) -> i64 { 182 if ep_src_try(out, "\x00" as *u8, target) == 1 { return 1 } 183 if ep_src_try(out, "_hdl_build/\x00" as *u8, target) == 1 { return 1 } 184 if ep_src_try(out, "bin/\x00" as *u8, target) == 1 { return 1 } 185 if ep_src_try(out, "hub/\x00" as *u8, target) == 1 { return 1 } 186 if ep_src_try(out, "wiki/\x00" as *u8, target) == 1 { return 1 } 187 if ep_src_try(out, "kernel/\x00" as *u8, target) == 1 { return 1 } 188 out[0] = 0 as u8 189 return 0 190}