code wiki / _hdl_build / nx_res_census.nx
nx_res_census.nx source
↩ module page · 277 lines · 14867 B
1// nx_res_census.nx -- THE RUNTIME RESOURCE WITNESS (per-daemon + system, trend-logged). 2026-07-05 OOM arc +
2// operator: "efficiency in our resource use across ALL the nishi ecosystems ... live resources and storage and
3// all the other axes" + "measured every poll, not discovered at OOM".
4//
5// WHY THIS ORGAN EXISTS (no-tool-proliferation: consolidation-check DONE, justified NEW): nx_explore for
6// VmRSS / proc_status / resource_census / diskspace = 0 files -- NOTHING reads per-process memory anywhere in
7// the ecosystem; the 26GiB health_eval leak + the 2.5TB clock commit were discovered AT OOM, and the leak
8// diagnosis lived only in a memory note. This is the RUNTIME half of the two-witness law: the static half
9// (nx_antipattern_catalog leaksweep) catches the DIRECT mmap-in-loop shape but proved BLIND to the
10// helper-indirection tier (nx_seed_announce_all: 199MB grown, ZERO static sites) -- only a per-daemon
11// RSS/VmSize GROWTH TREND catches that class. Single responsibility (Cardinal 9): MEASURE + LOG + show DELTA.
12// It is a WITNESS, not a judge -- no thresholds baked in (Cardinal 11); the judge tier composes later
13// (nx_metric_ledger BETTER/WORSE, mgmt_snapshot surface, clock-registry cadence = OWNER wiring on the NAS;
14// hardware-up honesty: this run proves the mechanism on the dev substrate, the target wiring is hostctl/clock).
15//
16// SIGNATURE TABLE (banked by the OOM workstream): huge VmSize = commit-leak / fork-wedge class; huge anon-RSS
17// = the OOM-killer class. Both columns logged so the trend separates them.
18//
19// MMAP DISCIPLINE: every buffer HOISTED once in main -- this organ must scan CLEAN under the leaksweep it
20// complements (practice the law). license_tier: ORIGINAL lineage_id: nishi_res_census_v1 expect_exit: 0
21import "nx_sovjson_lib.nx"
22import "nx_syscalls.nx"
23import "nx_dir.nx"
24
25const RC_LOG: *u8 = "knowledge/status/res_census.log\x00"
26const RC_PIDCAP: i64 = 8192 // /proc numeric entries enumerated (dir rows)
27const RC_FBUF: i64 = 65536 // one proc-file read buffer (status/cmdline/meminfo), reused
28const RC_LOGBUF: i64 = 4194304 // prior trend-log window for delta lookup (TRUNC honestly noted)
29
30func rc_slen(s: *u8) -> i64 { return sj_vlen(s) }
31func rc_w(fd: i64, s: *u8) -> i64 { sys_write(fd, s, rc_slen(s)); return 0 }
32// digits writer via caller-provided scratch (NO per-call mmap -- the whole point of this arc)
33func rc_wn(fd: i64, v: i64, scr: *u8) -> i64 {
34 var m: i64 = v
35 if m < 0 { sys_write(fd, "-\x00" as *u8, 1); m = 0 - m }
36 var k: i64 = 0
37 if m == 0 { scr[0] = 48 as u8; k = 1 }
38 while m > 0 { scr[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
39 var i: i64 = 0
40 while i < k { scr[24 + i] = scr[k - 1 - i]; i = i + 1 }
41 sys_write(fd, (scr as i64 + 24) as *u8, k)
42 return 0
43}
44func rc_cat(dst: *u8, o: i64, s: *u8) -> i64 { return sj_cat(dst, o, s) }
45func rc_catn(dst: *u8, o: i64, v: i64, scr: *u8) -> i64 {
46 var x: i64 = o; var m: i64 = v
47 if m < 0 { dst[x] = 45 as u8; x = x + 1; m = 0 - m }
48 var k: i64 = 0
49 if m == 0 { scr[0] = 48 as u8; k = 1 }
50 while m > 0 { scr[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
51 var j: i64 = 0
52 while j < k { dst[x] = scr[k - 1 - j]; x = x + 1; j = j + 1 }
53 return x
54}
55// substring find in buf[0..n) -> first index or -1
56func rc_find(buf: *u8, n: i64, needle: *u8) -> i64 {
57 let nl: i64 = rc_slen(needle)
58 if nl == 0 { return 0 - 1 }
59 var i: i64 = 0
60 while i + nl <= n {
61 var m: i64 = 0; var ok: i64 = 1
62 while m < nl { if buf[i + m] != needle[m] { ok = 0; m = nl } else { m = m + 1 } }
63 if ok == 1 { return i }
64 i = i + 1
65 }
66 return 0 - 1
67}
68// parse the first decimal run at/after buf[i..n) -> value (skips non-digits first); -1 if none
69func rc_num_after(buf: *u8, n: i64, i0: i64) -> i64 {
70 var i: i64 = i0
71 while i < n { if buf[i] >= (48 as u8) { if buf[i] <= (57 as u8) { break } } i = i + 1 }
72 if i >= n { return 0 - 1 }
73 var v: i64 = 0
74 while i < n { if buf[i] < (48 as u8) { break } if buf[i] > (57 as u8) { break } v = v * 10 + ((buf[i] - (48 as u8)) as i64); i = i + 1 }
75 return v
76}
77// "Label: 12345 kB" -> 12345; -1 when label absent
78func rc_kb(buf: *u8, n: i64, label: *u8) -> i64 {
79 let p: i64 = rc_find(buf, n, label)
80 if p < 0 { return 0 - 1 }
81 return rc_num_after(buf, n, p + rc_slen(label))
82}
83func rc_all_digits(nm: *u8, len: i64) -> i64 {
84 if len <= 0 { return 0 }
85 var i: i64 = 0
86 while i < len { if nm[i] < (48 as u8) { return 0 } if nm[i] > (57 as u8) { return 0 } i = i + 1 }
87 return 1
88}
89// open + read whole small file into caller buffer -> bytes (0 on open fail). NO allocation here.
90func rc_readf(path: *u8, buf: *u8, cap: i64) -> i64 {
91 let fd: i64 = sys_openat_rd(path)
92 if fd < 0 { return 0 }
93 var total: i64 = 0; var go: i64 = 1
94 while go == 1 {
95 let r: i64 = sys_read(fd, (buf as i64 + total) as *u8, cap - total)
96 if r <= 0 { go = 0 } else { total = total + r; if total >= cap { go = 0 } }
97 }
98 sys_close(fd)
99 return total
100}
101func rc_openat_append(path: *u8) -> i64 { return __syscall(257, AT_FDCWD, path, 0x441, 0x1a4, 0, 0) } // O_WRONLY|O_CREAT|O_APPEND 0644 (same idiom as nx_tools_api revocation list)
102
103// last prior sample for `name` in the trend log: find the LAST "RESC <epoch> <name> " line, pull field after
104// tag ("rss_kb=" or "vm_kb="). -1 when no history. (Scan is linear over the window; ~60B/line -> 4MB window
105// ~= 70k samples; when the log outgrows the window we TRUNC-note rather than silently mis-trend.)
106func rc_prev(logbuf: *u8, ln: i64, name: *u8, tag: *u8) -> i64 {
107 var best: i64 = 0 - 1
108 var i: i64 = 0
109 let nl: i64 = rc_slen(name)
110 while i < ln {
111 // line starts here; must begin "RESC "
112 if i + 5 < ln {
113 if logbuf[i] == (82 as u8) { // 'R'
114 if rc_find((logbuf as i64 + i) as *u8, 5, "RESC \x00" as *u8) == 0 {
115 // name is the 3rd space-separated field: skip "RESC ", skip epoch digits, skip one space
116 var j: i64 = i + 5
117 while j < ln { if logbuf[j] == (32 as u8) { break } j = j + 1 }
118 j = j + 1
119 // compare [j..j+nl) == name and next char is ' '
120 if j + nl < ln {
121 var m: i64 = 0; var ok: i64 = 1
122 while m < nl { if logbuf[j + m] != name[m] { ok = 0; m = nl } else { m = m + 1 } }
123 if ok == 1 { if logbuf[j + nl] != (32 as u8) { ok = 0 } }
124 if ok == 1 {
125 // find tag within THIS line only
126 var e: i64 = j
127 while e < ln { if logbuf[e] == (10 as u8) { break } e = e + 1 }
128 let rel: i64 = rc_find((logbuf as i64 + j) as *u8, e - j, tag)
129 if rel >= 0 { let v: i64 = rc_num_after((logbuf as i64 + j) as *u8, e - j, rel + rc_slen(tag)); if v >= 0 { best = v } }
130 }
131 }
132 }
133 }
134 }
135 while i < ln { if logbuf[i] == (10 as u8) { break } i = i + 1 }
136 i = i + 1
137 }
138 return best
139}
140
141func main(argc: i64, argv: *i64) -> i64 {
142 var procroot: *u8 = "/proc\x00" as *u8
143 if argc >= 2 { procroot = argv[1] as *u8 } // override = the LIAR-KILL lever (bogus root must yield 0)
144
145 // ---- ALL buffers hoisted ONCE (this organ must pass the leaksweep it complements) ----
146 let rows: *NxDirRow = (sys_mmap(NX_DIR_ROW_BYTES * RC_PIDCAP)) as *NxDirRow
147 let arena: *u8 = sys_mmap(RC_PIDCAP * 32)
148 let res: *NxDirResult = (sys_mmap(64)) as *NxDirResult
149 let fbuf: *u8 = sys_mmap(RC_FBUF) // one proc-file buffer, reused for every read
150 let logbuf: *u8 = sys_mmap(RC_LOGBUF) // prior trend window
151 let path: *u8 = sys_mmap(512)
152 let name: *u8 = sys_mmap(128)
153 let line: *u8 = sys_mmap(512)
154 let scr: *u8 = sys_mmap(64) // shared digits scratch (rc_wn/rc_catn)
155
156 rc_w(1, "=== nx_res_census -- RUNTIME resource witness (per-nishi-daemon RSS/VmSize + system; trend vs last) ===\n\x00" as *u8)
157
158 // prior log window (for deltas)
159 let ln: i64 = rc_readf(RC_LOG, logbuf, RC_LOGBUF)
160 if ln >= RC_LOGBUF { rc_w(1, " ⚠ trend window FULL (4MB) -- oldest history beyond window not consulted (no silent lie; rotate the log)\n\x00" as *u8) }
161
162 let epoch: i64 = sys_now_realtime_sec()
163 let logfd: i64 = rc_openat_append(RC_LOG)
164
165 // ---- SYSTEM axes first: MemAvailable / SwapFree (meminfo) + load1 (loadavg) ----
166 var o: i64 = 0
167 o = rc_cat(path, 0, procroot); o = rc_cat(path, o, "/meminfo\x00" as *u8); path[o] = 0 as u8
168 let mn: i64 = rc_readf(path, fbuf, RC_FBUF)
169 let memavail: i64 = rc_kb(fbuf, mn, "MemAvailable:\x00" as *u8)
170 let swapfree: i64 = rc_kb(fbuf, mn, "SwapFree:\x00" as *u8)
171 o = rc_cat(path, 0, procroot); o = rc_cat(path, o, "/loadavg\x00" as *u8); path[o] = 0 as u8
172 let ldn: i64 = rc_readf(path, fbuf, RC_FBUF)
173 // load1 as reported text (first token verbatim -- no float math needed for a witness)
174 var l1e: i64 = 0
175 while l1e < ldn { if fbuf[l1e] == (32 as u8) { break } l1e = l1e + 1 }
176 if mn > 0 {
177 var lo: i64 = rc_cat(line, 0, "RESC \x00" as *u8)
178 lo = rc_catn(line, lo, epoch, scr)
179 lo = rc_cat(line, lo, " SYSTEM memavail_kb=\x00" as *u8); lo = rc_catn(line, lo, memavail, scr)
180 lo = rc_cat(line, lo, " swapfree_kb=\x00" as *u8); lo = rc_catn(line, lo, swapfree, scr)
181 lo = rc_cat(line, lo, " load1=\x00" as *u8)
182 var t: i64 = 0
183 while t < l1e { if lo < 500 { line[lo] = fbuf[t]; lo = lo + 1 } t = t + 1 }
184 line[lo] = 10 as u8; lo = lo + 1
185 sys_write(1, " \x00" as *u8, 2); sys_write(1, line, lo)
186 if logfd >= 0 { sys_write(logfd, line, lo) }
187 }
188
189 // ---- per-daemon axes: every /proc/<pid> whose cmdline names an nx_ organ ----
190 let rc: i64 = nx_dir_list(procroot, rows, RC_PIDCAP, arena, RC_PIDCAP * 32, 0, res)
191 var found: i64 = 0
192 var grew: i64 = 0
193 if res.n_filled > 0 {
194 var i: i64 = 0
195 while i < res.n_filled {
196 let row: *NxDirRow = ((rows as i64) + i * NX_DIR_ROW_BYTES) as *NxDirRow
197 i = i + 1
198 if rc_all_digits(row.name_ptr, row.name_len) != 1 { continue }
199 // cmdline -> is it ours? (argv0 contains "nx_")
200 var po: i64 = rc_cat(path, 0, procroot); path[po] = 47 as u8; po = po + 1
201 var k: i64 = 0
202 while k < row.name_len { path[po] = row.name_ptr[k]; po = po + 1; k = k + 1 }
203 let pidend: i64 = po
204 po = rc_cat(path, po, "/cmdline\x00" as *u8); path[po] = 0 as u8
205 let cn: i64 = rc_readf(path, fbuf, RC_FBUF)
206 if cn <= 0 { continue }
207 if rc_find(fbuf, cn, "nx_\x00" as *u8) < 0 { continue }
208 // short name = basename of argv0 (argv0 ends at first NUL)
209 var a0e: i64 = 0
210 while a0e < cn { if fbuf[a0e] == (0 as u8) { break } a0e = a0e + 1 }
211 var bs: i64 = 0
212 var s: i64 = 0
213 while s < a0e { if fbuf[s] == (47 as u8) { bs = s + 1 } s = s + 1 }
214 var nn: i64 = 0
215 while bs < a0e { if nn < 120 { name[nn] = fbuf[bs]; nn = nn + 1 } bs = bs + 1 }
216 name[nn] = 0 as u8
217 // status -> VmRSS / VmSize
218 po = pidend
219 po = rc_cat(path, po, "/status\x00" as *u8); path[po] = 0 as u8
220 let sn: i64 = rc_readf(path, fbuf, RC_FBUF)
221 if sn <= 0 { continue }
222 let rss: i64 = rc_kb(fbuf, sn, "VmRSS:\x00" as *u8)
223 let vsz: i64 = rc_kb(fbuf, sn, "VmSize:\x00" as *u8)
224 if rss < 0 { continue } // kernel thread / no VM -- not a daemon we account
225 found = found + 1
226 // trend vs last sample of the SAME name
227 let prss: i64 = rc_prev(logbuf, ln, name, "rss_kb=\x00" as *u8)
228 let pvsz: i64 = rc_prev(logbuf, ln, name, "vm_kb=\x00" as *u8)
229 var lo2: i64 = rc_cat(line, 0, "RESC \x00" as *u8)
230 lo2 = rc_catn(line, lo2, epoch, scr)
231 lo2 = rc_cat(line, lo2, " \x00" as *u8)
232 lo2 = rc_cat(line, lo2, name)
233 lo2 = rc_cat(line, lo2, " pid=\x00" as *u8)
234 var pi: i64 = 0
235 while pi < row.name_len { line[lo2] = row.name_ptr[pi]; lo2 = lo2 + 1; pi = pi + 1 }
236 lo2 = rc_cat(line, lo2, " rss_kb=\x00" as *u8); lo2 = rc_catn(line, lo2, rss, scr)
237 lo2 = rc_cat(line, lo2, " vm_kb=\x00" as *u8); lo2 = rc_catn(line, lo2, vsz, scr)
238 line[lo2] = 10 as u8
239 if logfd >= 0 { sys_write(logfd, line, lo2 + 1) }
240 // stdout adds the delta view (the WITNESS: growth is visible per run, at +kb not at OOM)
241 sys_write(1, " \x00" as *u8, 2); sys_write(1, line, lo2)
242 if prss >= 0 {
243 rc_w(1, " [d_rss=\x00" as *u8); rc_wn(1, rss - prss, scr)
244 rc_w(1, "kb d_vm=\x00" as *u8); rc_wn(1, vsz - pvsz, scr)
245 rc_w(1, "kb since last]\x00" as *u8)
246 if rss - prss > 0 { grew = grew + 1 }
247 } else {
248 rc_w(1, " [first sample -- baseline]\x00" as *u8)
249 }
250 rc_w(1, "\n\x00" as *u8)
251 }
252 }
253 if logfd >= 0 { sys_close(logfd) }
254
255 // ---- GATE (prove-not-assert): [pos] the census must find >=1 nishi process -- ITSELF (self-witness:
256 // our own cmdline names nx_res_census). [neg/liar-kill] a bogus proc root must enumerate NOTHING. ----
257 let bres: *NxDirResult = res // reuse the hoisted result struct for the control
258 let brc: i64 = nx_dir_list("/proc_bogus_rc_zzz9\x00" as *u8, rows, RC_PIDCAP, arena, RC_PIDCAP * 32, 0, bres)
259 var neg_ok: i64 = 0
260 if bres.n_filled <= 0 { neg_ok = 1 }
261
262 rc_w(1, " ---- RES-CENSUS GATE ----\n\x00" as *u8)
263 rc_w(1, " nishi processes witnessed=\x00" as *u8); rc_wn(1, found, scr)
264 rc_w(1, " (self-witness expected>=1) grew_since_last=\x00" as *u8); rc_wn(1, grew, scr)
265 rc_w(1, " liar-kill(bogus /proc -> 0)=\x00" as *u8)
266 if neg_ok == 1 { rc_w(1, "PASS\n\x00" as *u8) } else { rc_w(1, "FAIL\n\x00" as *u8) }
267 rc_w(1, " trend log -> knowledge/status/res_census.log (append-only; the judge tier composes nx_metric_ledger / mgmt_snapshot; NAS cadence = clock-registry wiring, owner-gated)\n\x00" as *u8)
268 var ok: i64 = 1
269 if found < 1 { ok = 0 }
270 if neg_ok != 1 { ok = 0 }
271 if ok == 1 {
272 rc_w(1, "NX-RES-CENSUS GREEN: runtime witness live (per-daemon rss/vm + system axes, delta vs last) -- the 2nd witness the leaksweep cannot be\n\x00" as *u8)
273 sys_exit(0); return 0
274 }
275 rc_w(1, "NX-RES-CENSUS RED: witness failed its controls\n\x00" as *u8)
276 sys_exit(1); return 1
277}