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}