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}