code wiki / _hdl_build / nx_wirecensus_lib.nx

nx_wirecensus_lib.nx source

↩ module page · 567 lines · 25575 B

1// nx_wirecensus_lib.nx -- S4 OF THE WIRING CENSUS: REGISTERED BUT NEVER CALLED. 2// 3// WHY THIS AND NOT MORE CALL-GRAPH (July-2026 external SOTA, debt id=1785451391): the field's largest 4// dead-surface win came from RUNTIME evidence, not static analysis -- an Express codebase shed 16,000 5// lines (35 pct) by cross-referencing ACCESS LOGS against REGISTERED ROUTES, and the write-up states 6// plainly that static tools "only detect unreachable code, not the absence of live traffic". 7// nx_adopt already answers the static question (S1: defined, zero external callers). It structurally 8// CANNOT see a tool that is registered, callable, advertised -- and that nobody has ever invoked. 9// That tool is worse than dead code: it occupies the capability surface and reads as a feature. 10// 11// THE TWO WITNESSES, and why one is strong and one is weak (stated so the verdict is not oversold): 12// W1 cap_consent.log "CAPMINT ... allow=<csv> ..." -- STRONG. A capability is MANDATORY to invoke 13// a tool over /mcp, so a tool that never appears in any allow= list was never callable in 14// practice. Absence here is close to proof. 15// W2 actlog.jrnl TAB field 2 = the tool actually invoked -- WEAK BUT POSITIVE. Seats log 16// VOLUNTARILY, so absence proves nothing; PRESENCE proves use. Used only to rescue tools from 17// the dark list, never to condemn them. 18// A tool is DARK only if BOTH witnesses are silent. Union, not intersection -- the conservative side. 19// 20// KNOWN BLIND SPOT, REPORTED NOT HIDDEN: caps minted before this log existed, or minted with the 21// root nx_cap_mint on the NAS rather than POST /api/cap/mint, never reach cap_consent.log. So DARK is 22// an UPPER BOUND on unused surface, exactly as nx_adopt's raw count was an upper bound before the 23// public/local split. Anyone quoting this number must quote the bound with it. 24// license_tier: ORIGINAL Read-only. No hw writes (Rule 26). 25import "nx_syscalls.nx" 26const WC_MAGIC_262144: i64 = 262144 27const WC_MAGIC_1048576: i64 = 1048576 28 29const WC_BUF: i64 = 4194304 30const WC_MAXT: i64 = 2048 31const WC_NAMEMAX: i64 = 64 32const WC_TAB: i64 = 9 33const WC_NL: i64 = 10 34const WC_HASH: i64 = 35 35const WC_COMMA: i64 = 44 36const WC_SP: i64 = 32 37 38// TAIL-ANCHORED READ FOR APPEND-ONLY LEDGERS (2026-08-07). 39// wc_read below fills from offset 0 and stops at cap, so a journal LARGER than the cap keeps its 40// OLDEST bytes and silently drops its NEWEST -- exactly backwards for a log whose recent rows ARE the 41// evidence. MEASURED by nx_capcliff the day this was written: knowledge/status/actlog.jrnl is 42// 5,295,855B against WC_BUF 4,194,304 = 1262 permil, so the most recent ~1.1MB of invocations were 43// invisible and every tool invoked only inside that window was counted DARK. The census even warns 44// that DARK is an upper bound; this is one concrete reason why. 45// THIS IS THE STRUCTURAL FIX, NOT A CAP RAISE. nx_debt DB_CAP has been raised THREE times and its own 46// note says so: `a cap that can be crossed in silence will be crossed again`. Seeking to (size - cap) 47// cannot be outgrown. 48// TRADE, stated: the first line in the window may be a partial row. The caller's line parser drops it, 49// which costs one truncated row at the boundary instead of the entire tail. 50func wc_read_tail(path: *u8, buf: *u8, cap: i64) -> i64 { 51 let fd: i64 = sys_openat_rd(path) 52 if fd < 0 { return 0 - 1 } 53 let sz: i64 = sys_lseek(fd, 0, 2) 54 var off: i64 = 0 55 if sz > cap { off = sz - cap } 56 sys_lseek(fd, off, 0) 57 var n: i64 = 0 58 var go: i64 = 1 59 while go == 1 { 60 let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - n) 61 if r <= 0 { go = 0 } else { n = n + r; if n >= cap { go = 0 } } 62 } 63 sys_close(fd) 64 return n 65} 66 67func wc_read(path: *u8, buf: *u8, cap: i64) -> i64 { 68 let fd: i64 = sys_openat_rd(path) 69 if fd < 0 { return 0 - 1 } 70 var n: i64 = 0 71 var go: i64 = 1 72 while go == 1 { 73 let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - n) 74 if r <= 0 { go = 0 } else { n = n + r; if n >= cap { go = 0 } } 75 } 76 sys_close(fd) 77 return n 78} 79 80func wc_name_ch(c: i64) -> i64 { 81 if c >= 97 { if c <= 122 { return 1 } } 82 if c >= 65 { if c <= 90 { return 1 } } 83 if c >= 48 { if c <= 57 { return 1 } } 84 if c == 95 { return 1 } 85 return 0 86} 87 88func wc_has(names: *u8, lens: *i64, cnt: i64, p: *u8, l: i64) -> i64 { 89 var i: i64 = 0 90 while i < cnt { 91 if lens[i] == l { 92 let base: i64 = i * WC_NAMEMAX 93 var k: i64 = 0 94 var same: i64 = 1 95 while k < l { if names[base + k] != p[k] { same = 0; k = l } else { k = k + 1 } } 96 if same == 1 { return 1 } 97 } 98 i = i + 1 99 } 100 return 0 101} 102 103// CANONICAL NAME LENGTH: drop a trailing ".elf" so the three sets are comparable. Required because 104// organ_kind.conf is INCONSISTENT -- it carries "sites.elf daemon" AND "nx_mgmt_api daemon" -- while 105// the allowlist stores full ELF paths and the directory listing stores filenames. Comparing those 106// without canonicalising silently mismatches every row and the census reports confident nonsense. 107func wc_elflen(p: *u8, l: i64) -> i64 { 108 if l > 4 { 109 if p[l-4] == (46 as u8) { if p[l-3] == (101 as u8) { 110 if p[l-2] == (108 as u8) { if p[l-1] == (102 as u8) { return l - 4 } } } } 111 } 112 return l 113} 114 115// add if absent. returns new count. trunc incremented when the table is full. 116func wc_add(names: *u8, lens: *i64, cnt: i64, p: *u8, l: i64, trunc: *i64) -> i64 { 117 if l <= 0 { return cnt } 118 if l >= WC_NAMEMAX { return cnt } 119 if wc_has(names, lens, cnt, p, l) == 1 { return cnt } 120 if cnt >= WC_MAXT { trunc[0] = trunc[0] + 1; return cnt } 121 let base: i64 = cnt * WC_NAMEMAX 122 var k: i64 = 0 123 while k < l { names[base + k] = p[k]; k = k + 1 } 124 names[base + l] = 0 as u8 125 lens[cnt] = l 126 return cnt + 1 127} 128 129// DECLARED SURFACE: field 0 of every non-comment, non-blank line of tool_allowlist.conf. 130func wc_parse_registered(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 { 131 var cnt: i64 = 0 132 var ls: i64 = 0 133 var i: i64 = 0 134 while i <= n { 135 var eol: i64 = 0 136 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } } 137 if eol == 1 { 138 if i > ls { 139 if buf[ls] != (WC_HASH as u8) { 140 var e: i64 = ls 141 var go: i64 = 1 142 while go == 1 { 143 if e >= i { go = 0 } else { 144 if buf[e] == (WC_TAB as u8) { go = 0 } else { e = e + 1 } 145 } 146 } 147 cnt = wc_add(names, lens, cnt, (buf as i64 + ls) as *u8, e - ls, trunc) 148 } 149 } 150 ls = i + 1 151 } 152 i = i + 1 153 } 154 return cnt 155} 156 157// W1 AUTHORISED: every name in every "allow=" CSV in cap_consent.log. Terminates each name at a 158// comma or any non-name byte, so "allow=a,b exp=..." yields exactly a and b. 159func wc_parse_authorised(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 { 160 var cnt: i64 = 0 161 var i: i64 = 0 162 let last: i64 = n - 6 163 while i <= last { 164 var hit: i64 = 0 165 if buf[i] == (97 as u8) { if buf[i+1] == (108 as u8) { if buf[i+2] == (108 as u8) { 166 if buf[i+3] == (111 as u8) { if buf[i+4] == (119 as u8) { if buf[i+5] == (61 as u8) { hit = 1 } } } } } } 167 if hit == 1 { 168 var p: i64 = i + 6 169 var run: i64 = 1 170 while run == 1 { 171 var e: i64 = p 172 var go: i64 = 1 173 while go == 1 { 174 if e >= n { go = 0 } else { 175 if wc_name_ch(buf[e] as i64) == 1 { e = e + 1 } else { go = 0 } 176 } 177 } 178 cnt = wc_add(names, lens, cnt, (buf as i64 + p) as *u8, e - p, trunc) 179 if e < n { 180 if buf[e] == (WC_COMMA as u8) { p = e + 1 } else { run = 0 } 181 } else { run = 0 } 182 } 183 i = p 184 } else { i = i + 1 } 185 } 186 return cnt 187} 188 189// W2 INVOKED: TAB field 2 of actlog.jrnl (epoch \t ws \t TOOL \t verb \t outcome \t note). 190// PRESENCE ONLY -- seats log voluntarily, so this can rescue a tool from the dark list but must 191// never be used to condemn one. 192func wc_parse_invoked(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 { 193 var cnt: i64 = 0 194 var ls: i64 = 0 195 var i: i64 = 0 196 while i <= n { 197 var eol: i64 = 0 198 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } } 199 if eol == 1 { 200 if i > ls { 201 var tabs: i64 = 0 202 var fs: i64 = 0 - 1 203 var fe: i64 = 0 - 1 204 var p: i64 = ls 205 while p < i { 206 if buf[p] == (WC_TAB as u8) { 207 tabs = tabs + 1 208 if tabs == 2 { fs = p + 1 } else { if tabs == 3 { if fe < 0 { fe = p } } } 209 } 210 p = p + 1 211 } 212 if fs >= 0 { 213 if fe < 0 { fe = i } 214 cnt = wc_add(names, lens, cnt, (buf as i64 + fs) as *u8, fe - fs, trunc) 215 } 216 } 217 ls = i + 1 218 } 219 i = i + 1 220 } 221 return cnt 222} 223 224// ---- S3: BUILT + PROMOTED BUT NEVER REGISTERED -------------------------------------------------- 225// The class that bit this session twice: an artifact is compiled, promoted to live, and then nothing 226// exposes it, so it is callable by nobody and invisible to every consumer. nx_srcdiverge_gate is the 227// canonical instance -- promoted, unregistered, and it is the detector for a different stranding class. 228// 229// FALSE-POSITIVE CONTROL, and without it this check is unusable: nishihost holds DAEMONS (sites.elf, 230// nx_mgmt_api.elf) and LIBS which are correctly NOT tools. organ_kind.conf already declares what each 231// organ IS, so daemons and libs are excluded by DECLARATION rather than by a name heuristic. An organ 232// that is neither registered nor declared is the real finding: nobody said what it is OR wired it. 233 234// field 1 of an allowlist row is the ABS ELF PATH; collect its BASENAME so it can be compared to a 235// directory listing. 236func wc_parse_registered_elfs(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 { 237 var cnt: i64 = 0 238 var ls: i64 = 0 239 var i: i64 = 0 240 while i <= n { 241 var eol: i64 = 0 242 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } } 243 if eol == 1 { 244 if i > ls { if buf[ls] != (WC_HASH as u8) { 245 var tabs: i64 = 0 246 var fs: i64 = 0 - 1 247 var fe: i64 = i 248 var p: i64 = ls 249 while p < i { 250 if buf[p] == (WC_TAB as u8) { 251 tabs = tabs + 1 252 if tabs == 1 { fs = p + 1 } else { if tabs == 2 { if fe == i { fe = p } } } 253 } 254 p = p + 1 255 } 256 if fs >= 0 { 257 var bs: i64 = fs 258 var q: i64 = fs 259 while q < fe { if buf[q] == (47 as u8) { bs = q + 1 } q = q + 1 } 260 let bp: *u8 = (buf as i64 + bs) as *u8 261 cnt = wc_add(names, lens, cnt, bp, wc_elflen(bp, fe - bs), trunc) 262 } 263 } } 264 ls = i + 1 265 } 266 i = i + 1 267 } 268 return cnt 269} 270 271// names in organ_kind.conf whose declared kind is daemon or lib -- correctly NOT tools. 272func wc_parse_nontools(buf: *u8, n: i64, names: *u8, lens: *i64, trunc: *i64) -> i64 { 273 var cnt: i64 = 0 274 var ls: i64 = 0 275 var i: i64 = 0 276 while i <= n { 277 var eol: i64 = 0 278 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } } 279 if eol == 1 { 280 if i > ls { if buf[ls] != (WC_HASH as u8) { 281 var e: i64 = ls 282 var go: i64 = 1 283 while go == 1 { 284 if e >= i { go = 0 } else { 285 if buf[e] == (WC_SP as u8) { go = 0 } else { e = e + 1 } 286 } 287 } 288 if e < i { 289 let k: i64 = e + 1 290 var isnt: i64 = 0 291 if k + 5 < i { if buf[k] == (100 as u8) { isnt = 1 } } // daemon 292 if k + 2 < i { if buf[k] == (108 as u8) { isnt = 1 } } // lib 293 if isnt == 1 { 294 let np: *u8 = (buf as i64 + ls) as *u8 295 cnt = wc_add(names, lens, cnt, np, wc_elflen(np, e - ls), trunc) 296 } 297 } 298 } } 299 ls = i + 1 300 } 301 i = i + 1 302 } 303 return cnt 304} 305 306// every *.elf in a directory (exact suffix, so .elf.prev / .elf.new / .bak-* never match). 307func wc_scan_elfs(dir: *u8, names: *u8, lens: *i64, trunc: *i64) -> i64 { 308 var cnt: i64 = 0 309 let dfd: i64 = __syscall(257, 0 - 100, dir, 0x10000, 0, 0, 0) 310 if dfd < 0 { return 0 } 311 let db: *u8 = sys_mmap(WC_MAGIC_262144) 312 var more: i64 = 1 313 while more == 1 { 314 let got: i64 = sys_getdents64(dfd, db, WC_MAGIC_262144) 315 if got <= 0 { more = 0 } else { 316 var p: i64 = 0 317 while p < got { 318 let rec: *u8 = (db as i64 + p) as *u8 319 let rl: i64 = dirent_reclen(rec) 320 if rl <= 0 { p = got } else { 321 if dirent_type(rec) == DT_REG { 322 let nm: *u8 = dirent_name(rec) 323 var l: i64 = 0 324 while nm[l] != (0 as u8) { l = l + 1 } 325 if l > 4 { 326 if nm[l-4] == (46 as u8) { if nm[l-3] == (101 as u8) { 327 if nm[l-2] == (108 as u8) { if nm[l-1] == (102 as u8) { 328 cnt = wc_add(names, lens, cnt, nm, wc_elflen(nm, l), trunc) 329 } } } } 330 } 331 } 332 p = p + rl 333 } 334 } 335 } 336 } 337 sys_close(dfd) 338 return cnt 339} 340 341// ---- S3 TRIAGE: split UNEXPOSED into convention-inferred buckets vs the real residue ------------- 342// WHY: the first S3 run returned 253 "unexposed" and the list was dominated by RUNNING DAEMONS 343// (nx_siteedit_daemon, nx_analyst_serve, redirect...). They only looked stranded because 344// organ_kind.conf declares 32 of 743 promoted artifacts -- 4 pct coverage -- so the number MIXED 345// "correctly a daemon" with "genuinely stranded". That is the same category-mixing trap already 346// banked twice today (nx_adopt's DARK, nx_dupfunc's 3.3k), and a mixed number is a headline. 347// 348// THE FIX IS NOT TO HAND-WRITE 711 DECLARATIONS -- organ_kind.conf says "add a row, do NOT guess", 349// and a wrong row there lets /api/promote swap a live daemon with no health probe (rule-26 hazard). 350// So: DERIVE what evidence can classify, and report only what it cannot. 351// CRITICAL DISTINCTION: these suffix rules are CONVENTION-INFERRED and are for REPORTING ONLY. They 352// must never feed a promote decision -- organ_kind.conf stays the sole authority for that. A census 353// may guess out loud; a deploy verb may not. 354// ORACLE-shaped: _gate / _test / _kat (mirrors the /api/gate_run bound, which is itself a rule) 355// DAEMON-shaped: _daemon / _serve / _gw / _gateway 356// residue : UNCLASSIFIED -- the honest S3 number and the only rows worth a human backfill. 357func wc_suffix_is(p: *u8, l: i64, suf: *u8, sl: i64) -> i64 { 358 if l <= sl { return 0 } 359 var i: i64 = 0 360 while i < sl { if p[l - sl + i] != suf[i] { return 0 } i = i + 1 } 361 return 1 362} 363func wc_looks_oracle(p: *u8, l: i64) -> i64 { 364 if wc_suffix_is(p, l, "_gate" as *u8, 5) == 1 { return 1 } 365 if wc_suffix_is(p, l, "_test" as *u8, 5) == 1 { return 1 } 366 if wc_suffix_is(p, l, "_kat" as *u8, 4) == 1 { return 1 } 367 return 0 368} 369func wc_looks_daemon(p: *u8, l: i64) -> i64 { 370 if wc_suffix_is(p, l, "_daemon" as *u8, 7) == 1 { return 1 } 371 if wc_suffix_is(p, l, "_serve" as *u8, 6) == 1 { return 1 } 372 if wc_suffix_is(p, l, "_gateway" as *u8, 8) == 1 { return 1 } 373 if wc_suffix_is(p, l, "_gw" as *u8, 3) == 1 { return 1 } 374 return 0 375} 376 377// ---- S7: PROMOTED, UNREGISTERED, BUT INVOKED BY A PLAN OR CRON ---------------------------------- 378// WHY THIS CLASS EXISTS: S3 sees REGISTRY exposure only, so an organ invoked by a PLAN or a CRON row 379// reads as unexposed even though it runs on a schedule. A census whose residue cannot be acted on is 380// a census nobody runs, and retiring a cron-invoked organ because the registry never saw it is the 381// specific damage this class prevents. 382// 383// ⚠THE FIRST EVIDENCE SOURCE I PICKED WAS WRONG, AND THE ORGAN MEASURED IT: log stems. The theory was 384// that a promoted artifact writing logs/X.log or knowledge/status/X.log has run. Live result: 224 log 385// stems seen, 0 rescues. Logs here are named after the JOB (surfsentinel.log), never after the ORGAN 386// (nx_link_sentinel), so stem-matching can never join them. Kept only as a weak positive. 387// 388// I ALSO ASSERTED A WIRING THAT DOES NOT EXIST and the plane refuted it: I claimed 389// nx_link_sentinel/nx_nav_sentinel were invoked by plan-surfsentinel-. Dumping that plane shows it is 390// TEN nx_https_get steps against ten URLs and NOTHING ELSE. Those two organs are NOT in it. So S3's 391// UNCLASSIFIED label may have been right about them all along, and my "correction" was the error. 392// 393// THE CORRECT WITNESS, now measured: the plan planes themselves. knowledge/store/plan-*/ rows carry 394// the invoked tool in COLUMN 1 (e.g. "10 <TAB> nx_https_get <TAB> <url>"). That is a direct, positive 395// record of what actually gets called on a schedule. Column 1 of every plan- plane is the S7 source; 396// log stems are not. This function is retained for the weak signal but must not be read as S7. 397func wc_strip_logsuffix(p: *u8, l: i64) -> i64 { 398 // ".cron.log" (9) then ".log" (4) -- longest first, or "x.cron" survives as a bogus name. 399 if l > 9 { 400 if wc_suffix_is(p, l, ".cron.log" as *u8, 9) == 1 { return l - 9 } 401 } 402 if l > 4 { 403 if wc_suffix_is(p, l, ".log" as *u8, 4) == 1 { return l - 4 } 404 } 405 return 0 406} 407 408// collect the STEM of every *.log / *.cron.log in a directory, ACCUMULATING onto cnt0 and returning 409// the new total. Takes a starting count on purpose: log evidence lives in more than one directory 410// (logs/ and knowledge/status/), and a version that reset to 0 per call would have each scan CLOBBER 411// the previous one from index 0 and silently under-count the rescue set. 412func wc_scan_logs(dir: *u8, names: *u8, lens: *i64, cnt0: i64, trunc: *i64) -> i64 { 413 var cnt: i64 = cnt0 414 let dfd: i64 = __syscall(257, 0 - 100, dir, 0x10000, 0, 0, 0) 415 if dfd < 0 { return 0 } 416 let db: *u8 = sys_mmap(WC_MAGIC_262144) 417 var more: i64 = 1 418 while more == 1 { 419 let got: i64 = sys_getdents64(dfd, db, WC_MAGIC_262144) 420 if got <= 0 { more = 0 } else { 421 var p: i64 = 0 422 while p < got { 423 let rec: *u8 = (db as i64 + p) as *u8 424 let rl: i64 = dirent_reclen(rec) 425 if rl <= 0 { p = got } else { 426 if dirent_type(rec) == DT_REG { 427 let nm: *u8 = dirent_name(rec) 428 var l: i64 = 0 429 while nm[l] != (0 as u8) { l = l + 1 } 430 let stem: i64 = wc_strip_logsuffix(nm, l) 431 if stem > 0 { cnt = wc_add(names, lens, cnt, nm, stem, trunc) } 432 } 433 p = p + rl 434 } 435 } 436 } 437 } 438 sys_close(dfd) 439 return cnt 440} 441 442// ---- S7, CORRECT WITNESS: the tool named in COLUMN 1 of every plan- plane row ------------------- 443// Measured, not assumed: dumping plan-surfsentinel- gives rows shaped 444// "<seq> TAB nx_https_get TAB https://... TAB 127.0.0.1:8443" 445// and the seg-store .docs file carries that text verbatim (with q:<n> framing between rows). So a 446// tool INVOKED BY A SCHEDULED PLAN is exactly an identifier that is TAB-delimited on BOTH sides. 447// URLs and paths cannot collide with it because ':' and '/' are not name bytes. 448// 449// POSITIVE-ONLY, like every other rescue witness here: an over-broad match (a bare-identifier ARG 450// caught alongside a real tool) can only RESCUE a name from the residue, never condemn one. That 451// asymmetry is what makes a slightly loose extractor safe -- the failure mode is a smaller residue, 452// not a wrongly-retired organ. 453func wc_scan_plan_tools(dir: *u8, names: *u8, lens: *i64, cnt0: i64, trunc: *i64) -> i64 { 454 var cnt: i64 = cnt0 455 let dfd: i64 = __syscall(257, 0 - 100, dir, 0x10000, 0, 0, 0) 456 if dfd < 0 { return cnt } 457 let db: *u8 = sys_mmap(WC_MAGIC_262144) 458 let fb: *u8 = sys_mmap(WC_MAGIC_1048576) 459 let path: *u8 = sys_mmap(512) 460 var dl: i64 = 0 461 while dir[dl] != (0 as u8) { dl = dl + 1 } 462 var more: i64 = 1 463 while more == 1 { 464 let got: i64 = sys_getdents64(dfd, db, WC_MAGIC_262144) 465 if got <= 0 { more = 0 } else { 466 var p: i64 = 0 467 while p < got { 468 let rec: *u8 = (db as i64 + p) as *u8 469 let rl: i64 = dirent_reclen(rec) 470 if rl <= 0 { p = got } else { 471 if dirent_type(rec) == DT_REG { 472 let nm: *u8 = dirent_name(rec) 473 var l: i64 = 0 474 while nm[l] != (0 as u8) { l = l + 1 } 475 // plan-*.docs only: the plan planes, not their hist- twins or manifests 476 var isplan: i64 = 0 477 if l > 10 { 478 if nm[0] == (112 as u8) { if nm[1] == (108 as u8) { 479 if nm[2] == (97 as u8) { if nm[3] == (110 as u8) { 480 if nm[4] == (45 as u8) { 481 if wc_suffix_is(nm, l, ".docs" as *u8, 5) == 1 { isplan = 1 } 482 } } } } } 483 } 484 if isplan == 1 { 485 var w: i64 = 0 486 while w < dl { path[w] = dir[w]; w = w + 1 } 487 path[w] = 47 as u8 488 w = w + 1 489 var k: i64 = 0 490 while k < l { if w + 2 < 512 { path[w] = nm[k]; w = w + 1 } k = k + 1 } 491 path[w] = 0 as u8 492 let n: i64 = wc_read(path, fb, WC_MAGIC_1048576) 493 if n > 0 { 494 var i: i64 = 1 495 while i < n { 496 if fb[i - 1] == (WC_TAB as u8) { 497 var e: i64 = i 498 var go: i64 = 1 499 while go == 1 { 500 if e >= n { go = 0 } else { 501 if wc_name_ch(fb[e] as i64) == 1 { e = e + 1 } else { go = 0 } 502 } 503 } 504 if e > i { if e < n { if fb[e] == (WC_TAB as u8) { 505 cnt = wc_add(names, lens, cnt, (fb as i64 + i) as *u8, e - i, trunc) 506 } } } 507 if e > i { i = e } else { i = i + 1 } 508 } else { i = i + 1 } 509 } 510 } 511 } 512 } 513 p = p + rl 514 } 515 } 516 } 517 } 518 sys_close(dfd) 519 return cnt 520} 521 522// Is `name` present in buf as a WHOLE line-leading token? Used to skip already-declared organs when 523// emitting. Line-leading + boundary-checked so nx_adopt never satisfies nx_adopt_lib and a partial 524// name can never suppress a real emission. 525func wc_contains_name(buf: *u8, n: i64, p: *u8, l: i64) -> i64 { 526 if l <= 0 { return 0 } 527 var ls: i64 = 0 528 var i: i64 = 0 529 while i <= n { 530 var eol: i64 = 0 531 if i == n { eol = 1 } else { if buf[i] == (WC_NL as u8) { eol = 1 } } 532 if eol == 1 { 533 if i - ls > l { 534 var same: i64 = 1 535 var k: i64 = 0 536 while k < l { if buf[ls + k] != p[k] { same = 0; k = l } else { k = k + 1 } } 537 if same == 1 { if buf[ls + l] == (WC_SP as u8) { return 1 } } 538 } 539 ls = i + 1 540 } 541 i = i + 1 542 } 543 return 0 544} 545 546// THE VERDICT: registered names present in NEITHER witness. Writes their indices into dark[]. 547func wc_dark(rnames: *u8, rlens: *i64, rcnt: i64, 548 anames: *u8, alens: *i64, acnt: i64, 549 inames: *u8, ilens: *i64, icnt: i64, 550 dark: *i64, darkcap: i64) -> i64 { 551 var d: i64 = 0 552 var i: i64 = 0 553 while i < rcnt { 554 let base: i64 = i * WC_NAMEMAX 555 let p: *u8 = (rnames as i64 + base) as *u8 556 let l: i64 = rlens[i] 557 var seen: i64 = 0 558 if wc_has(anames, alens, acnt, p, l) == 1 { seen = 1 } 559 if seen == 0 { if wc_has(inames, ilens, icnt, p, l) == 1 { seen = 1 } } 560 if seen == 0 { 561 if d < darkcap { dark[d] = i } 562 d = d + 1 563 } 564 i = i + 1 565 } 566 return d 567}