code wiki / _hdl_build / nx_galx_audit.nx
nx_galx_audit.nx source
↩ module page · 134 lines · 5791 B
1// nx_galx_audit.nx -- audit the ENTIRE cid->path store. Every entry. No sampling.
2//
3// Operator 2026-08-07: *"not to do it only partially but have full ecosystem scope as you seem to
4// do sample size bullshit"*. Fair, and specific: after joining 109 gen images I reported
5// "5/5 serve 200" and called the job verified. Five. Of a hundred and nine. Of two hundred and
6// thirty-five thousand.
7// ★★★★★★ A SPOT CHECK PROVES THE MECHANISM CAN WORK, NEVER THAT THE POPULATION DOES. The whole
8// class of defect this session has been about -- 0 of 109 joined, a stale index, a collision that
9// silently ate an image -- is INVISIBLE to a sample drawn from the head of a file, because the head
10// is the oldest and most-tested part of any append-only store.
11// ★★★★★ SAMPLE THE HEAD OF AN APPEND-ONLY FILE AND YOU HAVE SAMPLED ITS PAST, NOT ITS PRESENT.
12//
13// So: walk every bucket, resolve every path, stat every file. The cost is one stat per entry and it
14// is worth paying, because the answer "how much of this gallery is actually backed by bytes" has
15// apparently never been asked.
16//
17// Usage: nx_galx_audit <idx> <blob> [--list-missing N]
18// license_tier: ORIGINAL
19
20import "nx_syscalls.nx"
21import "nx_strconv.nx"
22import "nx_galx_cid_index.nx"
23const K_MAGIC_4096: i64 = 4096
24const K_MAGIC_4000: i64 = 4000
25
26func ga_puts(s: *u8) -> i64 {
27 var n: i64 = 0
28 while s[n] != (0 as u8) { n = n + 1 }
29 return sys_write(1, s, n)
30}
31func ga_i(v: i64) -> i64 {
32 let b: *u8 = sys_mmap(32)
33 return sys_write(1, b, nx_strconv_format_i64(v, b))
34}
35// permille of a of b, guarding b==0 -- an integer quotient inside a report fails silently on small
36// inputs, and a rate printed as 0 because the denominator was 0 is a lie, not a measurement.
37func ga_permille(a: i64, b: i64) -> i64 {
38 if b <= 0 { return 0 - 1 }
39 return (a * 1000) / b
40}
41
42func main(argc: i64, argv: *i64) -> i64 {
43 if argc < 3 {
44 ga_puts("usage: nx_galx_audit <idx> <blob> [--list-missing N]\n" as *u8)
45 return 2
46 }
47 var list_missing: i64 = 0
48 if argc > 4 { list_missing = nx_strconv_parse_i64(argv[4] as *u8, sys_mmap(64) as *i64) }
49
50 let ip: *i64 = sys_mmap(16) as *i64
51 let idx: *u8 = sys_read_file(argv[1] as *u8, ip)
52 if (idx as i64) == 0 { ga_puts("idx unreadable\n" as *u8); return 3 }
53 let bp: *i64 = sys_mmap(16) as *i64
54 let blob: *u8 = sys_read_file(argv[2] as *u8, bp)
55 if (blob as i64) == 0 { ga_puts("blob unreadable\n" as *u8); return 4 }
56
57 let nb: i64 = cidx_rd64(idx, 0)
58 let nent_hdr: i64 = cidx_rd64(idx, 8)
59 let blob_len: i64 = bp[0]
60
61 var occupied: i64 = 0
62 var resolvable: i64 = 0
63 var missing: i64 = 0
64 var bad_off: i64 = 0
65 var empty_path: i64 = 0
66 var shown: i64 = 0
67 let path: *u8 = sys_mmap(K_MAGIC_4096)
68 let stbuf: *u8 = sys_mmap(256)
69
70 var b: i64 = 0
71 while b < nb {
72 let bo: i64 = 16 + b * 24
73 let h: i64 = cidx_rd64(idx, bo)
74 if h != 0 {
75 occupied = occupied + 1
76 let poff: i64 = cidx_rd64(idx, bo + 8)
77 let plen: i64 = cidx_rd64(idx, bo + 16)
78 if plen <= 0 { empty_path = empty_path + 1 }
79 else {
80 // A path_off/len outside the blob is a CORRUPT entry, and it must be counted
81 // separately from a missing FILE -- they have completely different remedies.
82 if poff < 0 { bad_off = bad_off + 1 }
83 else {
84 if poff + plen > blob_len { bad_off = bad_off + 1 }
85 else {
86 if plen > K_MAGIC_4000 { bad_off = bad_off + 1 }
87 else {
88 var i: i64 = 0
89 while i < plen { path[i] = blob[poff + i]; i = i + 1 }
90 path[plen] = 0
91 if sys_fstatat(path, stbuf) < 0 {
92 missing = missing + 1
93 if shown < list_missing {
94 ga_puts(" MISSING " as *u8)
95 sys_write(1, path, plen)
96 ga_puts("\n" as *u8)
97 shown = shown + 1
98 }
99 } else { resolvable = resolvable + 1 }
100 }
101 }
102 }
103 }
104 }
105 b = b + 1
106 }
107
108 ga_puts("buckets=" as *u8); ga_i(nb)
109 ga_puts(" header_entries=" as *u8); ga_i(nent_hdr)
110 ga_puts(" occupied=" as *u8); ga_i(occupied)
111 ga_puts("\n" as *u8)
112 // ★ A PARTITION IS A CLAIM: CHECK THE PARTS SUM. If these four do not add to `occupied`, the
113 // audit itself has a hole and every rate below is quoted against the wrong denominator.
114 ga_puts("resolvable=" as *u8); ga_i(resolvable)
115 ga_puts(" missing_file=" as *u8); ga_i(missing)
116 ga_puts(" corrupt_offset=" as *u8); ga_i(bad_off)
117 ga_puts(" empty_path=" as *u8); ga_i(empty_path)
118 ga_puts("\n" as *u8)
119 let summed: i64 = resolvable + missing + bad_off + empty_path
120 ga_puts("parts_sum=" as *u8); ga_i(summed)
121 if summed == occupied { ga_puts(" == occupied OK\n" as *u8) }
122 else { ga_puts(" != occupied AUDIT HOLE\n" as *u8) }
123
124 // header_entries vs occupied is its own check: they disagree if a crash landed between the
125 // bucket write and the counter bump (the deliberate ordering in nx_galx_cidput).
126 ga_puts("backed_permille=" as *u8); ga_i(ga_permille(resolvable, occupied))
127 ga_puts(" load_factor_permille=" as *u8); ga_i(ga_permille(occupied, nb))
128 ga_puts("\n" as *u8)
129
130 if summed != occupied { return 3 }
131 if missing > 0 { return 1 }
132 if bad_off > 0 { return 1 }
133 return 0
134}