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}