code wiki / _hdl_build / nx_envelope_audit.nx

nx_envelope_audit.nx source

↩ module page · 203 lines · 10633 B

1// nx_envelope_audit.nx -- F227 THE SCALE-ENVELOPE SWEEP (operator scale-law: "every tool DECLARES its 2// envelope IN ITS OUTPUT -- silent capping is forbidden BY CONSTRUCTION"; editcover row 3 silent-truncation). 3// A bounded read that never says it was bounded is how a seat (any model) silently believes a partial answer 4// is the whole answer -- the ark v1 lesson and the nx_debt 64KB blind spot were both this class. This organ 5// MEASURES the law across the fleet a seat can actually CALL (the registered tool_allowlist rows -- not all 6// ~15k .nx, that is the honest scope: an unregistered organ cannot mislead an agent). 7// PER ROW: resolve the source from the elf basename -> probe buildroot/runtime/_hdl_build/<base>.nx then 8// buildroot/runtime/<base>.nx -> classify: 9// DECLARING = source carries an envelope-declaration marker (envelope | caps: | window_bytes) 10// SILENT-CAP-CAND = has bounded-read consts (_CAP / _MAX) but NO declaration <- the actionable set 11// UNBOUNDED-OR-NA = no bounded-read consts found (nothing to declare, or reads are unbounded) 12// NAME-PROBE-MISS = no <elfbase>.nx in either probe dir. NOT proof of missing source: a tool's elf and 13// source names can DIVERGE (verified 07-20: nx_fs_write.elf builds from nx_fsops_write.nx). Treat as 14// 'not found BY NAME PROBE' and verify by content before ever claiming a source is lost. 15// LIAR-KILLED: this is a CANDIDATE detector over source text, never an absolute verdict -- the output says so, 16// and it reports counts + the candidate list so a human/referee adjudicates. Measurement first; a ratchet 17// floor comes only AFTER a measured baseline (never a gate on an unmeasured fleet). 18// DOGFOOD: declares its OWN envelope in its own output (512 rows, 256KB per source, 64 candidates listed). 19// nx_envelope_audit [allowlist] [outpath] 20// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 21import "nx_syscalls.nx" 22 23const EA_ALLOW: *u8 = "tool_allowlist.conf" as *u8 24const EA_OUT: *u8 = "knowledge/status/envelope_audit.log" as *u8 25const EA_D1: *u8 = "buildroot/runtime/_hdl_build/" as *u8 26const EA_D2: *u8 = "buildroot/runtime/" as *u8 27const EA_ALLOWCAP: i64 = 262144 28const EA_SRCCAP: i64 = 262144 29const EA_REPCAP: i64 = 131072 30const EA_MAXROWS: i64 = 512 31const EA_MAXLIST: i64 = 64 32const EA_NL: i64 = 10 33const EA_TAB: i64 = 9 34const EA_HASH: i64 = 35 35const EA_SLASH: i64 = 47 36const EA_DOT: i64 = 46 37const EA_MODE: i64 = 0x1a4 38const EA_STDOUT: i64 = 1 39const EA_STDERR: i64 = 2 40const EA_PATHCAP: i64 = 512 41const EA_NAMECAP: i64 = 256 42 43func ea_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 44func ea_werr(s: *u8) -> i64 { sys_write(EA_STDERR, s, ea_slen(s)); return 0 } 45func ea_puts(b: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var j: i64 = 0; while s[j] != (0 as u8) { if o < EA_REPCAP - 8 { b[o] = s[j]; o = o + 1 } j = j + 1 } return o } 46func ea_puti(b: *u8, off: i64, v: i64) -> i64 { 47 var o: i64 = off 48 var m: i64 = v 49 if m < 0 { b[o] = 45 as u8; o = o + 1; m = 0 - m } 50 let t: *u8 = sys_mmap(28) 51 var k: i64 = 0 52 if m == 0 { t[0] = 48 as u8; k = 1 } 53 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 54 var i: i64 = 0 55 while i < k { if o < EA_REPCAP - 8 { b[o] = t[k - 1 - i]; o = o + 1 } i = i + 1 } 56 return o 57} 58func ea_read(path: *u8, buf: *u8, cap: i64) -> i64 { 59 let fd: i64 = sys_openat_rd(path) 60 if fd < 0 { return 0 - 1 } 61 var n: i64 = 0 62 var go: i64 = 1 63 while go == 1 { let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap { go = 0 } } 64 sys_close(fd) 65 return n 66} 67func ea_has(buf: *u8, n: i64, needle: *u8) -> i64 { 68 let m: i64 = ea_slen(needle) 69 if m == 0 { return 0 } 70 if m > n { return 0 } 71 var i: i64 = 0 72 while i + m <= n { 73 var j: i64 = 0 74 var ok: i64 = 1 75 while j < m { if buf[i+j] != needle[j] { ok = 0; j = m } else { j = j + 1 } } 76 if ok == 1 { return 1 } 77 i = i + 1 78 } 79 return 0 80} 81func main(argc: i64, argv: *i64) -> i64 { 82 var allow: *u8 = EA_ALLOW 83 var outp: *u8 = EA_OUT 84 if argc > 1 { allow = argv[1] as *u8 } 85 if argc > 2 { outp = argv[2] as *u8 } 86 let ab: *u8 = sys_mmap(EA_ALLOWCAP) 87 let an: i64 = ea_read(allow, ab, EA_ALLOWCAP) 88 if an <= 0 { ea_werr("ENVELOPE-AUDIT READ-FAIL: tool_allowlist unreadable\n" as *u8); sys_exit(4); return 4 } 89 let src: *u8 = sys_mmap(EA_SRCCAP) 90 let rep: *u8 = sys_mmap(EA_REPCAP) 91 let cand: *u8 = sys_mmap(EA_REPCAP) 92 let miss: *u8 = sys_mmap(EA_REPCAP) 93 let base: *u8 = sys_mmap(EA_NAMECAP) 94 let name: *u8 = sys_mmap(EA_NAMECAP) 95 let path: *u8 = sys_mmap(EA_PATHCAP) 96 var co: i64 = 0 97 var mo: i64 = 0 98 var rows: i64 = 0 99 var declaring: i64 = 0 100 var silent: i64 = 0 101 var na: i64 = 0 102 var missing: i64 = 0 103 var listed: i64 = 0 104 var mlisted: i64 = 0 105 var i: i64 = 0 106 while i < an { 107 var le: i64 = i 108 var s: i64 = 1 109 while s == 1 { if le >= an { s = 0 } else { if ab[le] == (EA_NL as u8) { s = 0 } else { le = le + 1 } } } 110 if le > i { if ab[i] != (EA_HASH as u8) { 111 if rows < EA_MAXROWS { 112 var ne: i64 = i 113 var s2: i64 = 1 114 while s2 == 1 { if ne >= le { s2 = 0 } else { if ab[ne] == (EA_TAB as u8) { s2 = 0 } else { ne = ne + 1 } } } 115 if ne > i { if ne < le { 116 var k: i64 = 0 117 while i + k < ne { if k < EA_NAMECAP - 2 { name[k] = ab[i + k] } k = k + 1 } 118 name[k] = 0 as u8 119 var ps: i64 = ne + 1 120 var pe: i64 = ps 121 var s3: i64 = 1 122 while s3 == 1 { if pe >= le { s3 = 0 } else { if ab[pe] == (EA_TAB as u8) { s3 = 0 } else { pe = pe + 1 } } } 123 var bs: i64 = ps 124 var scan: i64 = ps 125 while scan < pe { if ab[scan] == (EA_SLASH as u8) { bs = scan + 1 } scan = scan + 1 } 126 var be: i64 = pe 127 if be - bs > 4 { if ab[be-4] == (EA_DOT as u8) { be = be - 4 } } 128 var bk: i64 = 0 129 while bs + bk < be { if bk < EA_NAMECAP - 2 { base[bk] = ab[bs + bk] } bk = bk + 1 } 130 base[bk] = 0 as u8 131 if bk > 0 { 132 rows = rows + 1 133 var po: i64 = ea_puts(path, 0, EA_D1) 134 po = ea_puts(path, po, base) 135 po = ea_puts(path, po, ".nx" as *u8) 136 path[po] = 0 as u8 137 var sn: i64 = ea_read(path, src, EA_SRCCAP) 138 if sn <= 0 { 139 po = ea_puts(path, 0, EA_D2) 140 po = ea_puts(path, po, base) 141 po = ea_puts(path, po, ".nx" as *u8) 142 path[po] = 0 as u8 143 sn = ea_read(path, src, EA_SRCCAP) 144 } 145 if sn <= 0 { 146 missing = missing + 1 147 if mlisted < EA_MAXLIST { mo = ea_puts(miss, mo, base); mo = ea_puts(miss, mo, " " as *u8); mlisted = mlisted + 1 } 148 } else { 149 var decl: i64 = 0 150 if ea_has(src, sn, "envelope" as *u8) == 1 { decl = 1 } 151 if ea_has(src, sn, "caps:" as *u8) == 1 { decl = 1 } 152 if ea_has(src, sn, "window_bytes" as *u8) == 1 { decl = 1 } 153 var bounded: i64 = 0 154 if ea_has(src, sn, "_CAP" as *u8) == 1 { bounded = 1 } 155 if ea_has(src, sn, "_MAX" as *u8) == 1 { bounded = 1 } 156 if decl == 1 { declaring = declaring + 1 } 157 else { 158 if bounded == 1 { 159 silent = silent + 1 160 if listed < EA_MAXLIST { co = ea_puts(cand, co, name); co = ea_puts(cand, co, " " as *u8); listed = listed + 1 } 161 } else { na = na + 1 } 162 } 163 } 164 } 165 } } 166 } 167 } } 168 i = le + 1 169 } 170 var o: i64 = 0 171 o = ea_puts(rep, o, "ENVELOPE-AUDIT (F227 scale-law sweep) rows=" as *u8) 172 o = ea_puti(rep, o, rows) 173 o = ea_puts(rep, o, " declaring=" as *u8) 174 o = ea_puti(rep, o, declaring) 175 o = ea_puts(rep, o, " silent_cap_candidates=" as *u8) 176 o = ea_puti(rep, o, silent) 177 o = ea_puts(rep, o, " unbounded_or_na=" as *u8) 178 o = ea_puti(rep, o, na) 179 o = ea_puts(rep, o, " name_probe_miss=" as *u8) 180 o = ea_puti(rep, o, missing) 181 var idx: i64 = 0 182 let denom: i64 = declaring + silent 183 if denom > 0 { idx = (declaring * 1000) / denom } 184 o = ea_puts(rep, o, " declare_index_permille=" as *u8) 185 o = ea_puti(rep, o, idx) 186 o = ea_puts(rep, o, " (of the bounded set: declaring vs declaring+candidates)\n" as *u8) 187 o = ea_puts(rep, o, "ENVELOPE (own, dogfood): 512 allowlist rows scanned, 256KB per source read, 64 names listed per class; scope = REGISTERED tools only (an unregistered organ cannot mislead a seat).\n" as *u8) 188 o = ea_puts(rep, o, "METHOD (liar-killed): CANDIDATE detector over source text -- declaration markers (envelope | caps: | window_bytes) vs bounded-read consts (_CAP | _MAX). NOT an absolute verdict: a candidate may declare its bound in prose this scan cannot see, and a declaring tool may still cap somewhere undeclared. Referee adjudicates; ratchet floor only AFTER this baseline is reviewed.\n" as *u8) 189 o = ea_puts(rep, o, "SILENT-CAP CANDIDATES (bounded, no declaration): " as *u8) 190 o = ea_puts(rep, o, cand) 191 o = ea_puts(rep, o, "\nNAME-PROBE MISS (no <elfbase>.nx in the probe dirs -- NOT proof of a lost source: elf and source names can diverge, verified nx_fs_write.elf builds from nx_fsops_write.nx; verify BY CONTENT before claiming loss. A genuine miss means the tool cannot be rebuilt on the NAS via /api/build): " as *u8) 192 o = ea_puts(rep, o, miss) 193 o = ea_puts(rep, o, "\n" as *u8) 194 sys_write(EA_STDOUT, rep, o) 195 let tmp: *u8 = sys_mmap(EA_PATHCAP) 196 var t: i64 = ea_puts(tmp, 0, outp) 197 t = ea_puts(tmp, t, ".tmp" as *u8) 198 tmp[t] = 0 as u8 199 let fd: i64 = sys_openat_wr(tmp, EA_MODE) 200 if fd >= 0 { sys_write(fd, rep, o); sys_close(fd); sys_renameat(tmp, outp) } 201 sys_exit(0) 202 return 0 203}