nx_stage_path.nx source
↩ module page · 335 lines · 17407 B
1// nx_stage_path.nx -- THE ONE HOME FOR "WHERE DO THE STAGED MODELS AND LEDGERS LIVE ON THIS HOST".
2//
3// WHY (measured 2026-08-19, lane B drain of the 150 trial-FAILING gates): 115 source sites across
4// ~60 organs spell the literal "/home/elderwesto/nx_stage/<file>" -- the dev box's WSL home. Every
5// nofloat/forge/autofix/coder gate that reads a model or ledger there was promoted to the NAS, where
6// that directory does not exist, and the roster trial read every one of them as RED: 37 gates
7// reporting "MODEL ABSENT" as if the no-float LLM were broken. They were reporting on their own
8// environment in the word reserved for a defect.
9// ★ A GATE THAT CANNOT DISTINGUISH "I COULD NOT LOOK" FROM "I LOOKED AND IT IS BROKEN" TEACHES
10// EVERYONE TO IGNORE IT. (nx_gate_verdict.gv_need already names this law; this lib is the
11// precondition that 37 gates were missing.)
12// ★ A PATH SPELLED AT 115 SITES IS 115 PLACES TO BE WRONG AND ZERO PLACES TO CONFIGURE.
13//
14// RESOLUTION ORDER (CLAUDE.md rule 17, highest wins):
15// 1. environment NX_STAGE=<dir> (read sovereignly from /proc/self/environ)
16// 2. conf knowledge/stage.conf `stage_root=<dir>` (opened via ep_open_rd: CWD, ../,
17// estate root, buildroot -- so the answer does not change with the launch dir)
18// 3. bootstrap SP_DEFAULT_ROOT -- the incumbent literal every consumer carried, kept here ONCE
19// so the dev box keeps working untouched and a NAS that wants model gates sets 1 or 2.
20// sp_root() REPORTS which rung answered, so a precondition message can say where it looked.
21//
22// CONTRACT FOR GATES: sp_skip_unless(GATE, path) -> returns 1 when <path> opens; otherwise prints the
23// gv_need precondition line and EXITS through gv_verdict (rc 3 = SKIP). A gate that calls it BEFORE
24// any check therefore reads SKIP -- "unobservable on this host" -- never RED, and never GREEN.
25// It must be called before the first gv_check: gv_verdict's ordering law turns (precondition missing
26// AND a failed check) into RED on purpose, and a gate that has already run checks against an absent
27// model has already failed them.
28//
29// LAYER: runtime/ library, no main(). Imports only runtime/ libs so _hdl_build/ organs may import it.
30// license_tier: ORIGINAL No hw writes (Rule 26).
31import "nx_syscalls.nx"
32import "nx_estate_path.nx"
33import "nx_gate_verdict.nx"
34
35// PATH_MAX on Linux is 4096 (limits.h): a staged path is bounded by the kernel, not by a guess.
36const SP_PATH_MAX: i64 = 4096
37// ONE read of /proc/self/environ. The kernel bounds a process environment at ARG_MAX; the estate's
38// incumbent environ reader (nx_runpath.rp_wsid) already uses this transfer size -- calibration reused.
39const SP_ENVIRON_BYTES: i64 = 65536
40const SP_DEFAULT_ROOT: *u8 = "/home/elderwesto/nx_stage"
41const SP_CONF: *u8 = "knowledge/stage.conf"
42const SP_CONF_KEY: *u8 = "stage_root="
43const SP_ENV_KEY: *u8 = "NX_STAGE="
44// THE SECOND HOST-LOCAL ROOT: the unified model store (diffusion/ text_encoder/ vae/ loras/ ...). Five
45// gates spelled its dev-box mount literally; the NAS carries the SAME layout at /volume1/ai/models, so
46// `models_root=` in knowledge/stage.conf is what makes those gates run for real off the dev box.
47const SP_MODELS_DEFAULT_ROOT: *u8 = "/mnt/c/Users/elder/elder-ai-platform/models/unified"
48const SP_MODELS_CONF_KEY: *u8 = "models_root="
49const SP_MODELS_ENV_KEY: *u8 = "NX_MODELS="
50const SP_SRC_ENV: i64 = 1
51const SP_SRC_CONF: i64 = 2
52const SP_SRC_DEFAULT: i64 = 3
53
54func sp_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
55func sp_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var p: i64 = o; while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } return p }
56// does buf[at..n) begin with the NUL-terminated lit?
57func sp_match(buf: *u8, at: i64, n: i64, lit: *u8) -> i64 {
58 var i: i64 = 0
59 while lit[i] != (0 as u8) { if at + i >= n { return 0 } if buf[at+i] != lit[i] { return 0 } i = i + 1 }
60 return 1
61}
62// copy buf[from..) into out until NUL/NL/CR or n; strip trailing spaces; returns length (0 = empty).
63func sp_take_value(buf: *u8, from: i64, n: i64, out: *u8) -> i64 {
64 var j: i64 = from
65 var k: i64 = 0
66 var go: i64 = 1
67 while go == 1 {
68 if j >= n { go = 0 } else {
69 let c: i64 = buf[j] as i64
70 if c == 0 { go = 0 } else { if c == 10 { go = 0 } else { if c == 13 { go = 0 } else {
71 if k < SP_PATH_MAX - 1 { out[k] = buf[j]; k = k + 1 }
72 j = j + 1
73 } } }
74 }
75 }
76 while k > 0 { if out[k-1] == (32 as u8) { k = k - 1 } else { break } }
77 out[k] = 0 as u8
78 return k
79}
80// environment lookup: NUL-separated KEY=VALUE entries. 0 = unset or empty.
81func sp_env(key: *u8, out: *u8) -> i64 {
82 out[0] = 0 as u8
83 let fd: i64 = sys_openat_rd("/proc/self/environ" as *u8)
84 if fd < 0 { return 0 }
85 let buf: *u8 = sys_mmap(SP_ENVIRON_BYTES)
86 let n: i64 = sys_read(fd, buf, SP_ENVIRON_BYTES - 1)
87 sys_close(fd)
88 var i: i64 = 0
89 var entry: i64 = 1
90 while i < n {
91 if entry == 1 { if sp_match(buf, i, n, key) == 1 { return sp_take_value(buf, i + sp_slen(key), n, out) } }
92 if buf[i] == (0 as u8) { entry = 1 } else { entry = 0 }
93 i = i + 1
94 }
95 return 0
96}
97// conf lookup: first line whose first byte begins <key> (comment lines start with a semicolon). 0 = absent.
98func sp_conf(key: *u8, out: *u8) -> i64 {
99 out[0] = 0 as u8
100 let fd: i64 = ep_open_rd(SP_CONF)
101 if fd < 0 { return 0 }
102 let buf: *u8 = sys_mmap(SP_ENVIRON_BYTES)
103 let n: i64 = sys_read(fd, buf, SP_ENVIRON_BYTES - 1)
104 sys_close(fd)
105 var i: i64 = 0
106 var bol: i64 = 1
107 while i < n {
108 if bol == 1 { if sp_match(buf, i, n, key) == 1 { return sp_take_value(buf, i + sp_slen(key), n, out) } }
109 if buf[i] == (10 as u8) { bol = 1 } else { bol = 0 }
110 i = i + 1
111 }
112 return 0
113}
114// generic root resolution: env key, then conf key, then the bootstrap default; returns the rung that answered.
115func sp_resolve_root(envkey: *u8, confkey: *u8, dflt: *u8, out: *u8) -> i64 {
116 if sp_env(envkey, out) > 0 { return SP_SRC_ENV }
117 if sp_conf(confkey, out) > 0 { return SP_SRC_CONF }
118 var o: i64 = sp_cat(out, 0, dflt)
119 out[o] = 0 as u8
120 return SP_SRC_DEFAULT
121}
122// the stage root for THIS host, written into out (SP_PATH_MAX bytes); returns the rung that answered.
123func sp_root(out: *u8) -> i64 { return sp_resolve_root(SP_ENV_KEY, SP_CONF_KEY, SP_DEFAULT_ROOT, out) }
124// the unified model-store root for THIS host.
125func sp_models_root(out: *u8) -> i64 { return sp_resolve_root(SP_MODELS_ENV_KEY, SP_MODELS_CONF_KEY, SP_MODELS_DEFAULT_ROOT, out) }
126// append "/<name>" to the root already in out (no double slash); returns out.
127func sp_join_name(name: *u8, out: *u8) -> *u8 {
128 var o: i64 = sp_slen(out)
129 if o > 0 { if out[o-1] != (47 as u8) { out[o] = 47 as u8; o = o + 1 } }
130 o = sp_cat(out, o, name)
131 out[o] = 0 as u8
132 return out
133}
134// out = "<stage root>/<name>"; returns out so it can replace a literal in place.
135func sp_path(name: *u8, out: *u8) -> *u8 { sp_root(out); return sp_join_name(name, out) }
136// out = "<models root>/<rel>" (rel may carry subdirs: diffusion/x.safetensors); returns out.
137func sp_models_path(rel: *u8, out: *u8) -> *u8 { sp_models_root(out); return sp_join_name(rel, out) }
138// 1 if <path> opens read-only on this host, else 0.
139func sp_present(path: *u8) -> i64 {
140 let fd: i64 = sys_openat_rd(path)
141 if fd < 0 { return 0 }
142 sys_close(fd)
143 return 1
144}
145// name the rung that resolved the root, for the precondition line.
146func sp_src_name(src: i64) -> *u8 {
147 if src == SP_SRC_ENV { return "NX_STAGE env" as *u8 }
148 if src == SP_SRC_CONF { return "knowledge/stage.conf" as *u8 }
149 return "bootstrap default" as *u8
150}
151// THE GATE CONTRACT. Returns 1 when <path> is present. Otherwise prints the precondition through
152// gv_need (so the counter and the wording are the base class's, not this lib's), emits the verdict
153// through gv_verdict (rc 3 = SKIP: ran 0 checks, 1 precondition missing) and EXITS with it.
154// Call it BEFORE the first check -- see the header for why the order is load-bearing.
155func sp_skip_because(gate: *u8, path: *u8, src: i64, envkey: *u8, confkey: *u8) -> i64 {
156 let msg: *u8 = sys_mmap(SP_PATH_MAX + 256)
157 var o: i64 = sp_cat(msg, 0, "staged artifact " as *u8)
158 o = sp_cat(msg, o, path)
159 o = sp_cat(msg, o, " (root from " as *u8)
160 o = sp_cat(msg, o, sp_src_name(src))
161 o = sp_cat(msg, o, "; set " as *u8)
162 o = sp_cat(msg, o, envkey)
163 o = sp_cat(msg, o, "<dir> or knowledge/stage.conf " as *u8)
164 o = sp_cat(msg, o, confkey)
165 o = sp_cat(msg, o, "<dir> to point this host at it)" as *u8)
166 msg[o] = 0 as u8
167 let ctr: *i64 = gv_ctr()
168 gv_need(msg, 0, ctr)
169 sys_exit(gv_verdict(gate, ctr, "" as *u8))
170 return 0
171}
172func sp_skip_unless(gate: *u8, path: *u8) -> i64 {
173 if sp_present(path) == 1 { return 1 }
174 let rootb: *u8 = sys_mmap(SP_PATH_MAX)
175 let src: i64 = sp_root(rootb)
176 return sp_skip_because(gate, path, src, SP_ENV_KEY, SP_CONF_KEY)
177}
178// same contract for the model store.
179func sp_models_skip_unless(gate: *u8, path: *u8) -> i64 {
180 if sp_present(path) == 1 { return 1 }
181 let rootb: *u8 = sys_mmap(SP_PATH_MAX)
182 let src: i64 = sp_models_root(rootb)
183 return sp_skip_because(gate, path, src, SP_MODELS_ENV_KEY, SP_MODELS_CONF_KEY)
184}
185// INLINE forms: resolve + guard + return the path in ONE expression, so a literal buried inside a call
186// (nsv_init("..."), sys_map_file("...", n)) is replaced without hoisting. Same ordering law applies:
187// the FIRST such call in a gate must precede its first check.
188func sp_guarded(gate: *u8, name: *u8) -> *u8 {
189 let p: *u8 = sp_path(name, sys_mmap(SP_PATH_MAX))
190 sp_skip_unless(gate, p)
191 return p
192}
193func sp_models_guarded(gate: *u8, rel: *u8) -> *u8 {
194 let p: *u8 = sp_models_path(rel, sys_mmap(SP_PATH_MAX))
195 sp_models_skip_unless(gate, p)
196 return p
197}
198
199// ---- THE ENGINE MODEL THIS HOST HAS STAGED (2026-09-18, search R0r/R0u/R0v) ----------------------------------
200// A gate whose property holds for ANY model the sovereign no-float engine runs (nx_nofloat_prefill_gate: the batched and
201// the sequential prefill are bit-identical on whatever weights are loaded) needs "a model this host has staged", not one
202// particular file. Before this key it could only name nx_coder_model.gguf under the stage root, and staging another model
203// UNDER THAT NAME would make every other consumer of the name (nx_coder_swap_gate needs the REAL coder model) judge a
204// different model -- a label that lies. So the need gets its own name, OPT-IN:
205// 1. environment NX_ENGINE_MODEL=<gguf>
206// 2. conf knowledge/stage.conf `engine_model=<gguf>`
207// 3. NOTHING -- deliberately no bootstrap default: out comes back empty with SP_SRC_NONE, so the caller falls through
208// to its incumbent path or SKIPs, exactly as before the key existed. Only a caller of sp_engine_model reads the key;
209// no other consumer of this lib changes behaviour.
210// A relative value resolves through ep_artifact_path (CWD, ../, the estate root, buildroot -- ep_open_rd's order), so the
211// answer does not change with the launch dir; a value that opens nowhere comes back AS DECLARED, so the caller's announce
212// and precondition lines name what was looked for.
213const SP_ENGINE_MODEL_ENV_KEY: *u8 = "NX_ENGINE_MODEL="
214const SP_ENGINE_MODEL_CONF_KEY: *u8 = "engine_model="
215const SP_SRC_NONE: i64 = 0
216
217// the engine model for THIS host into out (SP_PATH_MAX bytes); returns the rung that declared it, SP_SRC_NONE if none.
218func sp_engine_model(out: *u8) -> i64 {
219 out[0] = 0 as u8
220 let raw: *u8 = sys_mmap(SP_PATH_MAX)
221 var src: i64 = SP_SRC_NONE
222 if sp_env(SP_ENGINE_MODEL_ENV_KEY, raw) > 0 { src = SP_SRC_ENV } else {
223 if sp_conf(SP_ENGINE_MODEL_CONF_KEY, raw) > 0 { src = SP_SRC_CONF }
224 }
225 if src == SP_SRC_NONE { sys_munmap(raw, SP_PATH_MAX); return SP_SRC_NONE }
226 // ep_artifact_path writes <estate prefix><value> BEFORE its open can judge the join: one value (bounded by SP_PATH_MAX
227 // in sp_take_value) plus one prefix (itself a path under the same kernel PATH_MAX). A join that OPENED is shorter than
228 // PATH_MAX (the kernel refuses a longer name), so it fits out.
229 let res: *u8 = sys_mmap(SP_PATH_MAX + SP_PATH_MAX)
230 var o: i64 = 0
231 if ep_artifact_path(res, raw) == 1 { o = sp_cat(out, 0, res) } else { o = sp_cat(out, 0, raw) }
232 out[o] = 0 as u8
233 sys_munmap(res, SP_PATH_MAX + SP_PATH_MAX)
234 sys_munmap(raw, SP_PATH_MAX)
235 return src
236}
237// name the rung that declared the engine model, for an announce or precondition line.
238func sp_engine_src_name(src: i64) -> *u8 {
239 if src == SP_SRC_ENV { return "NX_ENGINE_MODEL env" as *u8 }
240 if src == SP_SRC_CONF { return "knowledge/stage.conf engine_model=" as *u8 }
241 return "none (engine_model unset)" as *u8
242}
243// THE GATE CONTRACT when a DECLARED engine model does not open on this host: the same exit as sp_skip_because (gv_need +
244// gv_verdict, rc 3 = SKIP, before the caller's first check), worded for a file rather than a root.
245func sp_engine_model_skip(gate: *u8, path: *u8, src: i64) -> i64 {
246 // one path (bounded by SP_PATH_MAX) plus the fixed wording (far shorter than a second path bound)
247 let msg: *u8 = sys_mmap(SP_PATH_MAX + SP_PATH_MAX)
248 var o: i64 = sp_cat(msg, 0, "engine model " as *u8)
249 o = sp_cat(msg, o, path)
250 o = sp_cat(msg, o, " (declared by " as *u8)
251 o = sp_cat(msg, o, sp_engine_src_name(src))
252 o = sp_cat(msg, o, ") does not open on this host; set " as *u8)
253 o = sp_cat(msg, o, SP_ENGINE_MODEL_ENV_KEY)
254 o = sp_cat(msg, o, "<gguf> or knowledge/stage.conf " as *u8)
255 o = sp_cat(msg, o, SP_ENGINE_MODEL_CONF_KEY)
256 o = sp_cat(msg, o, "<gguf> to a model this host has staged" as *u8)
257 msg[o] = 0 as u8
258 let ctr: *i64 = gv_ctr()
259 gv_need(msg, 0, ctr)
260 sys_exit(gv_verdict(gate, ctr, "" as *u8))
261 return 0
262}
263
264// ---- THE RIGOR ENVELOPE'S PARAMETERS (AD1, 2026-08-27) ------------------------------------------
265// nx_gate_verdict.gv_envelope is a PURE ruler: z, the bootstrap replicate count, the seed and the
266// interval-width target are its ARGUMENTS. They live in knowledge/rigor.conf so that a published
267// interval can be re-derived from a conf row and never from a literal in a gate, and this lib is
268// where they are read because it already owns conf resolution through ep_open_rd (CWD, ../, estate
269// root, buildroot -- the answer does not change with the launch dir) and already imports both halves.
270// Rule 17 order: env NX_RIGOR_<KEY>= is not read (a per-process override of a published statistical
271// parameter is exactly the knob that lets a seat flatter one number); conf > the base class default.
272const SP_RIGOR_CONF: *u8 = "knowledge/rigor.conf"
273const SP_RIGOR_KEY_Z: *u8 = "z_micro="
274const SP_RIGOR_KEY_B: *u8 = "boot_reps="
275const SP_RIGOR_KEY_SEED: *u8 = "boot_seed="
276const SP_RIGOR_KEY_WIDTH: *u8 = "width_target_permil="
277
278// conf lookup in ANY file: first line whose first byte begins <key>. 0 = absent (file or row).
279func sp_conf_in(file: *u8, key: *u8, out: *u8) -> i64 {
280 out[0] = 0 as u8
281 let fd: i64 = ep_open_rd(file)
282 if fd < 0 { return 0 }
283 let buf: *u8 = sys_mmap(SP_ENVIRON_BYTES)
284 let n: i64 = sys_read(fd, buf, SP_ENVIRON_BYTES - 1)
285 sys_close(fd)
286 var i: i64 = 0
287 var bol: i64 = 1
288 while i < n {
289 if bol == 1 { if sp_match(buf, i, n, key) == 1 { let r: i64 = sp_take_value(buf, i + sp_slen(key), n, out); sys_munmap(buf, SP_ENVIRON_BYTES); return r } }
290 if buf[i] == (10 as u8) { bol = 1 } else { bol = 0 }
291 i = i + 1
292 }
293 sys_munmap(buf, SP_ENVIRON_BYTES)
294 return 0
295}
296// plain decimal parse (leading '-' allowed); a non-numeric value reads as 0 -- callers keep their default on 0
297func sp_atoi(s: *u8) -> i64 {
298 var i: i64 = 0
299 var neg: i64 = 0
300 if s[0] == (45 as u8) { neg = 1; i = 1 }
301 var v: i64 = 0
302 var any: i64 = 0
303 var go: i64 = 1
304 while go == 1 {
305 let c: i64 = s[i] as i64
306 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1; i = i + 1 } else { go = 0 } } else { go = 0 }
307 }
308 if any == 0 { return 0 }
309 if neg == 1 { return 0 - v }
310 return v
311}
312// one rigor parameter: the conf row when present and positive, else the caller's default.
313func sp_rigor_int(key: *u8, dflt: i64) -> i64 {
314 let b: *u8 = sys_mmap(SP_PATH_MAX)
315 var v: i64 = dflt
316 if sp_conf_in(SP_RIGOR_CONF, key, b) > 0 { let p: i64 = sp_atoi(b); if p > 0 { v = p } }
317 sys_munmap(b, SP_PATH_MAX)
318 return v
319}
320// 1 when knowledge/rigor.conf resolves on this host (so a gate can gv_need it by name), else 0.
321func sp_rigor_present() -> i64 {
322 let fd: i64 = ep_open_rd(SP_RIGOR_CONF)
323 if fd < 0 { return 0 }
324 sys_close(fd)
325 return 1
326}
327// THE ONE CALL a publisher makes: fills the four parameters the envelope takes, from the conf with the
328// base-class defaults as the floor. p[0]=z_micro p[1]=boot_reps p[2]=boot_seed p[3]=width_target_permil.
329func sp_rigor_params(p: *i64) -> i64 {
330 p[0] = sp_rigor_int(SP_RIGOR_KEY_Z, GV_Z95_MICRO)
331 p[1] = sp_rigor_int(SP_RIGOR_KEY_B, GV_BOOT_B_DEFAULT)
332 p[2] = sp_rigor_int(SP_RIGOR_KEY_SEED, GV_BOOT_SEED_DEFAULT)
333 p[3] = sp_rigor_int(SP_RIGOR_KEY_WIDTH, 0)
334 return sp_rigor_present()
335}