code wiki / _hdl_build / nx_cwdguard.nx
nx_cwdguard.nx source
↩ module page · 240 lines · 10924 B
1// nx_cwdguard.nx -- THE STANDING GUARD for the CWD-DEPENDENT-VERDICT class (debt 1785879363).
2//
3// WHAT BIT US (measured 2026-08-04, three separate organs in one session):
4// * nx_swarm_endpoint_lib read knowledge/swarm_nodes.conf relative; the gen daemon runs with
5// CWD=/volume1/ai/gen, so the SSOT silently missed and gen dispatched at a DEAD GPU address.
6// * nx_writebench printed verdict=GREEN coverage=553 from buildroot and result=LIAR
7// claimed-artifacts-missing=8 from nishihost -- the tools-daemon CWD, i.e. EVERY MCP call.
8// * nx_law_warden returned RED "law plane unseeded" and nx_sota_status reported an EMPTY estate
9// (no proven domains at all) purely because of the directory they were launched from.
10// ★★★★★★A VERDICT THAT CHANGES WITH THE CALLER'S WORKING DIRECTORY IS NOT A MEASUREMENT.
11//
12// ★WHY THIS DETECTOR IS STATIC, NOT A DIFFER. The obvious guard -- run each tool from two
13// directories and compare -- is WRONG HERE, and I proved it on myself: comparing output md5 flagged
14// nx_barcheck (a TLS bench whose ms= timings vary per run) and nx_frontier_watch (which APPENDS a
15// row per run, so its base row advances every time) as CWD-fragile when NEITHER IS. It also would
16// EXECUTE mutating organs twice per sweep just to look at them. So this guard reads SOURCE:
17// an organ is AT RISK when it opens an estate path RELATIVE and carries no anchor. That is cheap,
18// deterministic, side-effect-free, and has no false positives from clocks or counters.
19// ⚠HONEST ENVELOPE: at-risk is a RISK, not a proven defect -- an organ whose subject genuinely IS
20// "whatever tree I was pointed at" is CORRECT to read relative. This names candidates for a human
21// or a follow-up differ to adjudicate; it must never be read as a list of confirmed bugs.
22//
23// nx_cwdguard -- scan, print the at-risk roster + verdict
24// nx_cwdguard selftest -- teeth, incl. the NEGATIVE control (an anchored organ is NOT flagged)
25// license_tier: ORIGINAL expect_exit: 0
26// module: nishi-core.estate.cwdguard
27import "nx_syscalls.nx"
28import "nx_estate_path.nx"
29
30const CG_SCRATCH: i64 = 1048576
31const CG_MAXTOOLS: i64 = 2048
32const CG_NAMECAP: i64 = 64
33
34func cg_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
35func cg_n(v: i64) -> i64 {
36 let t: *u8 = sys_mmap(32); let b: *u8 = sys_mmap(32)
37 var m: i64 = v; var k: i64 = 0
38 if m == 0 { t[0] = 48 as u8; k = 1 }
39 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
40 var i: i64 = 0
41 while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
42 sys_write(1, b, k); return 0
43}
44
45// read a whole file via the CWD-proof resolver (this guard must not be fragile in the way it detects)
46func cg_slurp(path: *u8, buf: *u8, cap: i64) -> i64 {
47 let fd: i64 = ep_open_rd(path)
48 if fd < 0 { return 0 - 1 }
49 var t: i64 = 0
50 var r: i64 = 1
51 while r > 0 {
52 if t >= cap { r = 0 } else {
53 r = sys_read(fd, ((buf as i64) + t) as *u8, cap - t)
54 if r > 0 { t = t + r }
55 }
56 }
57 sys_close(fd)
58 return t
59}
60
61func cg_has(buf: *u8, n: i64, needle: *u8) -> i64 {
62 var m: i64 = 0
63 while needle[m] != (0 as u8) { m = m + 1 }
64 if m == 0 { return 0 }
65 if m > n { return 0 }
66 var i: i64 = 0
67 while i <= n - m {
68 var j: i64 = 0
69 var same: i64 = 1
70 while j < m { if buf[i + j] != needle[j] { same = 0; j = m } else { j = j + 1 } }
71 if same == 1 { return 1 }
72 i = i + 1
73 }
74 return 0
75}
76
77// Does this source read an ESTATE path relatively? Any of the known open/read primitives applied to
78// a bare "knowledge/..." literal. (A leading '/' would be absolute and is not a risk.)
79func cg_reads_relative(buf: *u8, n: i64) -> i64 {
80 if cg_has(buf, n, "sys_openat_rd(\"knowledge/" as *u8) == 1 { return 1 }
81 if cg_has(buf, n, "sys_read_file(\"knowledge/" as *u8) == 1 { return 1 }
82 if cg_has(buf, n, "slurp(\"knowledge/" as *u8) == 1 { return 1 }
83 return 0
84}
85
86// Is it anchored / already CWD-proof? Either binding to nx_estate_path, or doing its own chdir.
87func cg_anchored(buf: *u8, n: i64) -> i64 {
88 if cg_has(buf, n, "ep_anchor" as *u8) == 1 { return 1 }
89 if cg_has(buf, n, "ep_open_rd" as *u8) == 1 { return 1 }
90 if cg_has(buf, n, "sys_chdir" as *u8) == 1 { return 1 }
91 return 0
92}
93
94// copy field 1 (tab-separated) of the line starting at off into name; returns length (0 = skip row)
95func cg_toolname(buf: *u8, off: i64, end: i64, name: *u8) -> i64 {
96 if off >= end { return 0 }
97 if buf[off] == (35 as u8) { return 0 }
98 var i: i64 = off
99 var k: i64 = 0
100 while i < end {
101 let c: i64 = buf[i] & 0xff
102 if c == 9 { i = end } else {
103 if k < CG_NAMECAP - 1 { name[k] = buf[i]; k = k + 1 }
104 i = i + 1
105 }
106 }
107 name[k] = 0 as u8
108 return k
109}
110
111// try runtime/<name>.nx then runtime/_hdl_build/<name>.nx; returns bytes read (or -1)
112func cg_load_source(name: *u8, nl: i64, buf: *u8) -> i64 {
113 let p: *u8 = sys_mmap(256)
114 var o: i64 = 0
115 let pre: *u8 = "buildroot/runtime/" as *u8
116 while pre[o] != (0 as u8) { p[o] = pre[o]; o = o + 1 }
117 var i: i64 = 0
118 while i < nl { p[o + i] = name[i]; i = i + 1 }
119 p[o + nl] = 46 as u8; p[o + nl + 1] = 110 as u8; p[o + nl + 2] = 120 as u8; p[o + nl + 3] = 0 as u8
120 var r: i64 = cg_slurp(p, buf, CG_SCRATCH)
121 if r > 0 { return r }
122 let p2: *u8 = sys_mmap(256)
123 var o2: i64 = 0
124 let pre2: *u8 = "buildroot/runtime/_hdl_build/" as *u8
125 while pre2[o2] != (0 as u8) { p2[o2] = pre2[o2]; o2 = o2 + 1 }
126 i = 0
127 while i < nl { p2[o2 + i] = name[i]; i = i + 1 }
128 p2[o2 + nl] = 46 as u8; p2[o2 + nl + 1] = 110 as u8; p2[o2 + nl + 2] = 120 as u8; p2[o2 + nl + 3] = 0 as u8
129 return cg_slurp(p2, buf, CG_SCRATCH)
130}
131
132func cg_scan() -> i64 {
133 ep_anchor()
134 let reg: *u8 = sys_mmap(CG_SCRATCH)
135 let rn: i64 = cg_slurp("tool_allowlist.conf" as *u8, reg, CG_SCRATCH)
136 if rn <= 0 {
137 cg_w("NX-CWDGUARD RED -- tool_allowlist.conf unreadable (fail-closed: no roster, no verdict)\n" as *u8)
138 return 1
139 }
140 let src: *u8 = sys_mmap(CG_SCRATCH)
141 let name: *u8 = sys_mmap(CG_NAMECAP)
142 var scanned: i64 = 0
143 var nosrc: i64 = 0
144 var atrisk: i64 = 0
145 var safe: i64 = 0
146 cg_w("=== NX-CWDGUARD: organs whose VERDICT could depend on the caller's working directory ===\n" as *u8)
147 cg_w("at-risk = reads a relative knowledge/ path AND carries no anchor. A RISK, not a proven defect.\n" as *u8)
148 var p: i64 = 0
149 var rows: i64 = 0
150 while p < rn {
151 // ⚠THE POSITION MUST SURVIVE THE SEARCH. My first version terminated the scan with
152 // `q = rn + 1` on finding the newline, which DESTROYED the very index it had just found --
153 // eol became rn, every row read as one giant line, and the guard reported
154 // registry_rows=1 ... at_risk=0 verdict=GREEN over a 773-row registry. A VACUOUS GREEN.
155 // Caught only because the row COUNT is printed: ★★★★★A PARSER THAT LOSES THE POSITION
156 // REPORTS SUCCESS AND MEANS NOTHING -- print parsed-row counts, and read them.
157 var q: i64 = p
158 var eol: i64 = rn
159 var go: i64 = 1
160 while go == 1 {
161 if q >= rn { eol = rn; go = 0 }
162 else { if reg[q] == (10 as u8) { eol = q; go = 0 } else { q = q + 1 } }
163 }
164 if eol > p { if rows < CG_MAXTOOLS {
165 let nl: i64 = cg_toolname(reg, p, eol, name)
166 if nl > 0 {
167 rows = rows + 1
168 let sn: i64 = cg_load_source(name, nl, src)
169 if sn <= 0 { nosrc = nosrc + 1 } else {
170 scanned = scanned + 1
171 if cg_reads_relative(src, sn) == 1 {
172 if cg_anchored(src, sn) == 1 { safe = safe + 1 } else {
173 atrisk = atrisk + 1
174 cg_w(" AT-RISK " as *u8); sys_write(1, name, nl); cg_w("\n" as *u8)
175 }
176 } else { safe = safe + 1 }
177 }
178 }
179 } }
180 p = eol + 1
181 }
182 cg_w("registry_rows=" as *u8); cg_n(rows)
183 cg_w(" source_found=" as *u8); cg_n(scanned)
184 cg_w(" source_missing=" as *u8); cg_n(nosrc)
185 cg_w(" at_risk=" as *u8); cg_n(atrisk)
186 cg_w(" cwd_proof_or_absolute=" as *u8); cg_n(safe)
187 cg_w("\nenvelope: source_missing rows are UNJUDGED (an elf whose .nx is not in the buildroot cannot be\n" as *u8)
188 cg_w("read) -- they are printed as a count, never folded into safe. Coverage is scanned/rows.\n" as *u8)
189 if atrisk == 0 { cg_w("NX-CWDGUARD GREEN -- no registered organ reads an estate path relative without an anchor\n" as *u8); return 0 }
190 cg_w("NX-CWDGUARD FINDINGS -- adjudicate each: anchor it, or confirm the CWD is genuinely its input\n" as *u8)
191 return 0
192}
193
194// Teeth. The negative control is the one that matters: a detector that flags everything is useless.
195func cg_selftest() -> i64 {
196 var pass: i64 = 0
197 var total: i64 = 0
198 let a: *u8 = "let f = sys_read_file(\"knowledge/status/x.log\") // no anchor here\x00" as *u8
199 var an: i64 = 0
200 while a[an] != (0 as u8) { an = an + 1 }
201 total = total + 1
202 if cg_reads_relative(a, an) == 1 { if cg_anchored(a, an) == 0 { pass = pass + 1; cg_w("T1 relative+unanchored -> AT-RISK OK\n" as *u8) } }
203
204 let b: *u8 = "ep_anchor()\nlet f = sys_read_file(\"knowledge/status/x.log\")\x00" as *u8
205 var bn: i64 = 0
206 while b[bn] != (0 as u8) { bn = bn + 1 }
207 total = total + 1
208 if cg_anchored(b, bn) == 1 { pass = pass + 1; cg_w("T2 NEG-CONTROL anchored -> NOT flagged OK\n" as *u8) }
209
210 let c: *u8 = "let f = sys_read_file(\"/volume1/homes/elderwesto/nishihost/knowledge/x\")\x00" as *u8
211 var cn: i64 = 0
212 while c[cn] != (0 as u8) { cn = cn + 1 }
213 total = total + 1
214 if cg_reads_relative(c, cn) == 0 { pass = pass + 1; cg_w("T3 NEG-CONTROL absolute path -> NOT flagged OK\n" as *u8) }
215
216 let d: *u8 = "let f = ep_open_rd(\"knowledge/status/x.log\")\x00" as *u8
217 var dn: i64 = 0
218 while d[dn] != (0 as u8) { dn = dn + 1 }
219 total = total + 1
220 if cg_anchored(d, dn) == 1 { pass = pass + 1; cg_w("T4 NEG-CONTROL ep_open_rd -> NOT flagged OK\n" as *u8) }
221
222 let e: *u8 = "no estate reads at all, pure integer organ\x00" as *u8
223 var en: i64 = 0
224 while e[en] != (0 as u8) { en = en + 1 }
225 total = total + 1
226 if cg_reads_relative(e, en) == 0 { pass = pass + 1; cg_w("T5 NEG-CONTROL no estate read -> NOT flagged OK\n" as *u8) }
227
228 cg_w("CWDGUARD-SELFTEST " as *u8); cg_n(pass); cg_w("/" as *u8); cg_n(total)
229 if pass == total { cg_w(" verdict=GREEN\n" as *u8); return 0 }
230 cg_w(" verdict=RED\n" as *u8)
231 return 1
232}
233
234func main(argc: i64, argv: *i64) -> i64 {
235 if argc >= 2 {
236 let v: *u8 = argv[1] as *u8
237 if v[0] == (115 as u8) { return cg_selftest() }
238 }
239 return cg_scan()
240}