nx_librarian_audit.nx source
↩ module page · 124 lines · 5318 B
1// nx_librarian_audit.nx -- LIBRARIAN rung 1: the FORMAT-SPRAWL INSTRUMENT. The operator's charge
2// (2026-07-10): "a bunch of tsv and other non native and non interoperable formats kicking around" --
3// this lib MEASURES that mechanically so the migration ladder is driven by numbers, not vibes. It walks
4// data roots via raw getdents64 and classifies every regular file by format class, tallying count+bytes:
5// 0 tsv · 1 csv · 2 json/jsonl · 3 pipe-data (.q .axes .matrix .list .sota .cal .compdocs .flows
6// .steps) · 4 txt · 5 raw · 6 SEG-STORE (the sovereign native store: *seg-*.docs/.idx/.pos) · 7 log
7// 8 conf · 9 other
8// The NATIVE share (class 6) over total data bytes is the honest permille the migration work must move.
9// Read-only by construction: opens directories and files O_RDONLY, writes nothing. license_tier: ORIGINAL
10import "nx_syscalls.nx"
11const K_MAGIC_65536: i64 = 65536
12const K_MAGIC_1024: i64 = 1024
13
14// st layout: 20 i64 slots -- st[class*2]=file count, st[class*2+1]=bytes. Caller zeroes.
15func la_ends(name: *u8, nlen: i64, suf: *u8) -> i64 {
16 var sl: i64 = 0
17 while suf[sl] != (0 as u8) { sl = sl + 1 }
18 if sl > nlen { return 0 }
19 var i: i64 = 0
20 while i < sl {
21 if name[nlen - sl + i] != suf[i] { return 0 }
22 i = i + 1
23 }
24 return 1
25}
26func la_has(name: *u8, nlen: i64, needle: *u8) -> i64 {
27 var m: i64 = 0
28 while needle[m] != (0 as u8) { m = m + 1 }
29 var i: i64 = 0
30 while i + m <= nlen {
31 var j: i64 = 0
32 var ok: i64 = 1
33 while j < m { if name[i + j] != needle[j] { ok = 0; j = m } else { j = j + 1 } }
34 if ok == 1 { return 1 }
35 i = i + 1
36 }
37 return 0
38}
39
40func la_class(name: *u8, nlen: i64) -> i64 {
41 // native seg-store first: *seg-*.docs / .idx / .pos
42 if la_has(name, nlen, "seg-\x00" as *u8) == 1 {
43 if la_ends(name, nlen, ".docs\x00" as *u8) == 1 { return 6 }
44 if la_ends(name, nlen, ".idx\x00" as *u8) == 1 { return 6 }
45 if la_ends(name, nlen, ".pos\x00" as *u8) == 1 { return 6 }
46 }
47 if la_ends(name, nlen, ".tsv\x00" as *u8) == 1 { return 0 }
48 if la_ends(name, nlen, ".csv\x00" as *u8) == 1 { return 1 }
49 if la_ends(name, nlen, ".json\x00" as *u8) == 1 { return 2 }
50 if la_ends(name, nlen, ".jsonl\x00" as *u8) == 1 { return 2 }
51 if la_ends(name, nlen, ".q\x00" as *u8) == 1 { return 3 }
52 if la_ends(name, nlen, ".axes\x00" as *u8) == 1 { return 3 }
53 if la_ends(name, nlen, ".matrix\x00" as *u8) == 1 { return 3 }
54 if la_ends(name, nlen, ".list\x00" as *u8) == 1 { return 3 }
55 if la_ends(name, nlen, ".sota\x00" as *u8) == 1 { return 3 }
56 if la_ends(name, nlen, ".cal\x00" as *u8) == 1 { return 3 }
57 if la_ends(name, nlen, ".compdocs\x00" as *u8) == 1 { return 3 }
58 if la_ends(name, nlen, ".flows\x00" as *u8) == 1 { return 3 }
59 if la_ends(name, nlen, ".steps\x00" as *u8) == 1 { return 3 }
60 if la_ends(name, nlen, ".txt\x00" as *u8) == 1 { return 4 }
61 if la_ends(name, nlen, ".raw\x00" as *u8) == 1 { return 5 }
62 if la_ends(name, nlen, ".log\x00" as *u8) == 1 { return 7 }
63 if la_ends(name, nlen, ".conf\x00" as *u8) == 1 { return 8 }
64 return 9
65}
66
67func la_fsize(path: *u8) -> i64 {
68 let fd: i64 = sys_openat_rd(path)
69 if fd < 0 { return 0 }
70 let sz: i64 = sys_lseek(fd, 0, 2)
71 sys_close(fd)
72 if sz < 0 { return 0 }
73 return sz
74}
75
76// scan ONE directory (non-recursive); tallies into st; returns regular files seen, or -1 open-fail.
77func la_scan_dir(dirpath: *u8, st: *i64) -> i64 {
78 let fd: i64 = sys_openat_rd(dirpath)
79 if fd < 0 { return 0 - 1 }
80 let buf: *u8 = sys_mmap(K_MAGIC_65536)
81 let path: *u8 = sys_mmap(K_MAGIC_1024)
82 var files: i64 = 0
83 var going: i64 = 1
84 while going == 1 {
85 let n: i64 = sys_getdents64(fd, buf, K_MAGIC_65536)
86 if n <= 0 { going = 0 } else {
87 var off: i64 = 0
88 while off < n {
89 let p: i64 = (buf as i64) + off
90 let rl: *u8 = (p + 16) as *u8
91 let reclen: i64 = (rl[0] as i64) + ((rl[1] as i64) * 256)
92 let tb: *u8 = (p + 18) as *u8
93 let dtype: i64 = tb[0] as i64
94 let nm: *u8 = (p + 19) as *u8
95 if dtype == 8 { if nm[0] != (46 as u8) {
96 var nl: i64 = 0
97 while nm[nl] != (0 as u8) { nl = nl + 1 }
98 // full path = dirpath / name
99 var o: i64 = 0
100 var k: i64 = 0
101 while dirpath[k] != (0 as u8) { path[o] = dirpath[k]; o = o + 1; k = k + 1 }
102 path[o] = 47 as u8
103 o = o + 1
104 k = 0
105 while k < nl { path[o] = nm[k]; o = o + 1; k = k + 1 }
106 path[o] = 0 as u8
107 let cls: i64 = la_class(nm, nl)
108 let sz: i64 = la_fsize(path)
109 st[cls * 2] = st[cls * 2] + 1
110 st[cls * 2 + 1] = st[cls * 2 + 1] + sz
111 files = files + 1
112 } }
113 if reclen <= 0 { off = n } else { off = off + reclen }
114 }
115 }
116 }
117 sys_close(fd)
118 return files
119}
120
121func la_permil(part: i64, total: i64) -> i64 {
122 if total <= 0 { return 0 }
123 return (part * 1000) / total
124}