code wiki / _hdl_build / nx_assure.nx
nx_assure.nx source
↩ module page · 431 lines · 20810 B
1// nx_assure.nx -- WORLD-CLASS ASSURANCE RULER (worldclass-assurance lane, 2026-07-24). Operator:
2// "we need to get to the point our system is world class -- DARPA/NASA/Linux-level and above." That
3// is not a vibe, it is a CHECKABLE STANDARD. This organ scores the real .nx corpus against a subset
4// of the NASA/JPL "Power of Ten" rules for safety-critical code (Holzmann 2006) that are mechanically
5// decidable on NishiLang, emits per-rule violation counts, every violation LOCATABLE (file:fn), and an
6// honest corpus permille. CYNICAL BY CONSTRUCTION (the author-optimism law): a rule that cannot be
7// mechanically decided is declared NOT-CHECKED and counts as NEITHER pass nor fail -- the headline can
8// never inflate by claiming credit for what it did not measure.
9//
10// CHECKED (sound, non-gameable):
11// R1 no self-recursion -- fn body calls its own name (P10 rule 1: no recursion)
12// R2 bounded loops -- no `while true` / `while 1` (P10 rule 2)
13// R3 no dynamic alloc inside a loop -- no sys_mmap lexically inside a `while` (P10 rule 3;
14// THIS is the per-iteration-mmap OOM class banked across
15// sessions -- the single highest-value mechanical check)
16// R4 function length <= AS_MAXLEN lines -- (P10 rule 4: short functions)
17// G gate coverage -- every organ-with-main has a _gate/_test sibling (Nishi
18// assurance: fresh-compile-run is the only judge, so a
19// shippable organ WITHOUT a gate is unproven)
20// NOT-CHECKED (declared, never scored as pass): R5 assertion density, R6 minimal scope, R7 checked
21// returns, R8 preprocessor (NishiLang has none -- N/A), R9 single-deref pointers, R10 zero warnings
22// (nx_cc builds clean by construction -- reproducible-build ruler is a separate arc).
23//
24// verbs: audit [dir] (default runtime/_hdl_build) | selftest
25// license_tier: ORIGINAL No hw writes (Rule 26).
26import "nx_syscalls.nx"
27
28const AS_FCAP: i64 = 262144
29const AS_DCAP: i64 = 65536
30const AS_TCAP: i64 = 65536 // one extracted function (organs have big fns)
31const AS_PATHCAP: i64 = 256
32const AS_MAXLEN: i64 = 75 // P10-R4 line budget
33const AS_ZERO: i64 = 48
34const AS_NAMES: i64 = 4096 // main-organ base-name table
35const AS_NAMEBUF: i64 = 131072
36
37func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
38func wn(v: i64) -> i64 {
39 var m: i64 = v
40 if m < 0 { w("-" as *u8); m = 0 - m }
41 let t: *u8 = sys_mmap(24)
42 var k: i64 = 0
43 if m == 0 { t[0] = AS_ZERO as u8; k = 1 }
44 while m > 0 { t[k] = (AS_ZERO + (m % 10)) as u8; m = m / 10; k = k + 1 }
45 let o: *u8 = sys_mmap(24)
46 var i: i64 = 0
47 while i < k { o[i] = t[k - 1 - i]; i = i + 1 }
48 sys_write(1, o, k)
49 return 0
50}
51func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
52func sfind(hay: *u8, hn: i64, needle: *u8, from: i64) -> i64 {
53 let m: i64 = slen(needle)
54 if m == 0 { return 0 - 1 }
55 var i: i64 = from
56 while i + m <= hn {
57 var j: i64 = 0
58 var ok: i64 = 1
59 while j < m { if hay[i + j] != needle[j] { ok = 0; j = m } else { j = j + 1 } }
60 if ok == 1 { return i }
61 i = i + 1
62 }
63 return 0 - 1
64}
65func scontains(h: *u8, hn: i64, n: *u8) -> i64 { if sfind(h, hn, n, 0) >= 0 { return 1 } return 0 }
66func as_read(path: *u8, buf: *u8, cap: i64) -> i64 {
67 let fd: i64 = sys_openat_rd(path)
68 if fd < 0 { return 0 - 1 }
69 var n: i64 = 0
70 var go: i64 = 1
71 while go == 1 {
72 if n >= cap { sys_close(fd); return 0 - 2 }
73 let r: i64 = sys_read(fd, ((buf as i64) + n) as *u8, cap - n)
74 if r <= 0 { go = 0 } else { n = n + r }
75 }
76 sys_close(fd)
77 return n
78}
79
80// function boundary: from "func" at `at` through brace depth 0 -> end | -1
81func as_fnend(b: *u8, n: i64, at: i64) -> i64 {
82 var e: i64 = at
83 var depth: i64 = 0
84 var seen: i64 = 0
85 var go: i64 = 1
86 while go == 1 {
87 if e >= n { go = 0 }
88 else {
89 let c: i64 = b[e] as i64
90 if c == 123 { depth = depth + 1; seen = 1 }
91 if c == 125 { depth = depth - 1 }
92 e = e + 1
93 if seen == 1 { if depth == 0 { go = 0 } }
94 }
95 }
96 if seen == 0 { return 0 - 1 }
97 if depth != 0 { return 0 - 1 }
98 return e
99}
100// parse name into nb (null-terminated) from a fn text starting "func "; ret name len | 0
101func as_fnname(t: *u8, tn: i64, nb: *u8) -> i64 {
102 let po: i64 = sfind(t, tn, "(" as *u8, 0)
103 if po < 6 { return 0 }
104 var nl: i64 = 0
105 var i: i64 = 5
106 while i < po { if nl < 90 { nb[nl] = t[i]; nl = nl + 1 } i = i + 1 }
107 nb[nl] = 0 as u8
108 return nl
109}
110// body-start offset (first '{' after the signature)
111func as_bodystart(t: *u8, tn: i64) -> i64 { return sfind(t, tn, "{" as *u8, 0) }
112
113// R1: does the body call its own name? (name followed by '(' after the signature, prev char non-id)
114func as_recurses(t: *u8, tn: i64, name: *u8, nl: i64) -> i64 {
115 let bo: i64 = as_bodystart(t, tn)
116 if bo < 0 { return 0 }
117 let needle: *u8 = sys_mmap(128)
118 var i: i64 = 0
119 while i < nl { needle[i] = name[i]; i = i + 1 }
120 needle[nl] = 40 as u8
121 needle[nl + 1] = 0 as u8
122 var p: i64 = bo
123 var go: i64 = 1
124 while go == 1 {
125 let at: i64 = sfind(t, tn, needle, p)
126 if at < 0 { go = 0 }
127 else {
128 let prev: i64 = t[at - 1] as i64
129 var isid: i64 = 0
130 if prev >= 97 { if prev <= 122 { isid = 1 } }
131 if prev >= 65 { if prev <= 90 { isid = 1 } }
132 if prev >= 48 { if prev <= 57 { isid = 1 } }
133 if prev == 95 { isid = 1 }
134 if isid == 0 { return 1 }
135 p = at + nl + 1
136 }
137 }
138 return 0
139}
140// R2: unbounded loop smell
141func as_unbounded(t: *u8, tn: i64) -> i64 {
142 if scontains(t, tn, "while true" as *u8) == 1 { return 1 }
143 if scontains(t, tn, "while 1 " as *u8) == 1 { return 1 }
144 if scontains(t, tn, "while 1{" as *u8) == 1 { return 1 }
145 if scontains(t, tn, "while (1)" as *u8) == 1 { return 1 }
146 if scontains(t, tn, "while (true)" as *u8) == 1 { return 1 }
147 return 0
148}
149// R3: sys_mmap lexically INSIDE a while-block. Walk brace depth; track a stack bit "in a while" per
150// depth. mmap while any enclosing block was opened by a `while` header => per-iteration alloc.
151func as_mmap_in_loop(t: *u8, tn: i64) -> i64 {
152 // wl[d] = 1 if the block opened at depth d was a while-block
153 let wl: *i64 = sys_mmap(256 * 8) as *i64
154 var d: i64 = 0
155 var i: i64 = 0
156 // pending: a `while` seen since the last '{' at this level
157 var pend: i64 = 0
158 var inloop: i64 = 0
159 while i < tn {
160 // detect `while` keyword start (word-boundary)
161 if i + 5 <= tn {
162 if t[i] == (119 as u8) { if t[i+1] == (104 as u8) { if t[i+2] == (105 as u8) { if t[i+3] == (108 as u8) { if t[i+4] == (101 as u8) {
163 let pv: i64 = t[i-1] as i64
164 var idp: i64 = 0
165 if pv >= 97 { if pv <= 122 { idp = 1 } }
166 if pv >= 65 { if pv <= 90 { idp = 1 } }
167 if pv == 95 { idp = 1 }
168 if idp == 0 { pend = 1 }
169 } } } } }
170 }
171 let c: i64 = t[i] as i64
172 if c == 123 {
173 d = d + 1
174 if d < 256 { wl[d] = pend }
175 if pend == 1 { inloop = inloop + 1 }
176 pend = 0
177 }
178 if c == 125 {
179 if d < 256 { if wl[d] == 1 { if inloop > 0 { inloop = inloop - 1 } } }
180 d = d - 1
181 }
182 // mmap check when inside >=1 while-block
183 if inloop > 0 {
184 if i + 8 <= tn { if t[i] == (115 as u8) { if sfind(t, tn, "sys_mmap" as *u8, i) == i { return 1 } } }
185 }
186 i = i + 1
187 }
188 return 0
189}
190// count newlines in body -> logical line span
191func as_lines(t: *u8, tn: i64) -> i64 {
192 var c: i64 = 0
193 var i: i64 = 0
194 while i < tn { if t[i] == (10 as u8) { c = c + 1 } i = i + 1 }
195 return c + 1
196}
197
198// name-set for gate coverage
199static g_names: *u8 // packed null-terminated base names of organs-with-main
200static g_names_o: i64
201static g_gatebase: *u8 // packed base names that ARE a _gate/_test file
202static g_gatebase_o: i64
203static g_selfver: *u8 // base names whose OWN source self-verifies (contains VERDICT=)
204static g_selfver_o: i64
205static g_listmode: i64 // 1 = print each violation as `Rn file:fn` (actionable backlog)
206static g_curfile: *u8 // current file basename, for list output
207
208func as_pack(dst: *u8, o: i64, s: *u8, n: i64) -> i64 {
209 var i: i64 = 0
210 while i < n { dst[o] = s[i]; o = o + 1; i = i + 1 }
211 dst[o] = 0 as u8
212 return o + 1
213}
214func as_inpack(pk: *u8, pn: i64, s: *u8, sn: i64) -> i64 {
215 var p: i64 = 0
216 while p < pn {
217 var q: i64 = p
218 while pk[q] != (0 as u8) { q = q + 1 }
219 if q - p == sn { var eq: i64 = 1; var z: i64 = 0; while z < sn { if pk[p + z] != s[z] { eq = 0; z = sn } else { z = z + 1 } } if eq == 1 { return 1 } }
220 p = q + 1
221 }
222 return 0
223}
224// strip ".nx" and a trailing "_gate"/"_test" -> base name into nb; ret (0 normal | 1 was gate/test)
225func as_base(nm: *u8, nl: i64, nb: *u8) -> i64 {
226 var e: i64 = nl
227 if e >= 3 { if nm[e-3] == (46 as u8) { if nm[e-2] == (110 as u8) { if nm[e-1] == (120 as u8) { e = e - 3 } } } }
228 var isg: i64 = 0
229 if e >= 5 { if nm[e-5] == (95 as u8) { if nm[e-4] == (103 as u8) { if nm[e-3] == (97 as u8) { if nm[e-2] == (116 as u8) { if nm[e-1] == (101 as u8) { e = e - 5; isg = 1 } } } } } }
230 if isg == 0 { if e >= 5 { if nm[e-5] == (95 as u8) { if nm[e-4] == (116 as u8) { if nm[e-3] == (101 as u8) { if nm[e-2] == (115 as u8) { if nm[e-1] == (116 as u8) { e = e - 5; isg = 1 } } } } } } }
231 var z: i64 = 0
232 while z < e { nb[z] = nm[z]; z = z + 1 }
233 nb[e] = 0 as u8
234 return isg
235}
236func as_name_ok(nm: *u8, nl: i64) -> i64 {
237 if nl < 4 { return 0 }
238 if nm[nl-3] != (46 as u8) { return 0 }
239 if nm[nl-2] != (110 as u8) { return 0 }
240 if nm[nl-1] != (120 as u8) { return 0 }
241 if scontains(nm, nl, ".bak" as *u8) == 1 { return 0 }
242 if scontains(nm, nl, "premigrate" as *u8) == 1 { return 0 }
243 return 1
244}
245
246func as_audit(dir: *u8) -> i64 {
247 let fbuf: *u8 = sys_mmap(AS_FCAP)
248 let dbuf: *u8 = sys_mmap(AS_DCAP)
249 let tbuf: *u8 = sys_mmap(AS_TCAP)
250 let path: *u8 = sys_mmap(AS_PATHCAP)
251 let nb: *u8 = sys_mmap(96)
252 let base: *u8 = sys_mmap(96)
253 g_names = sys_mmap(AS_NAMEBUF)
254 g_gatebase = sys_mmap(AS_NAMEBUF)
255 g_selfver = sys_mmap(AS_NAMEBUF)
256 g_names_o = 0
257 g_gatebase_o = 0
258 g_selfver_o = 0
259 var files: i64 = 0
260 var fns: i64 = 0
261 var v_rec: i64 = 0
262 var v_unb: i64 = 0
263 var v_mmap: i64 = 0
264 var v_len: i64 = 0
265 var maxlen_seen: i64 = 0
266 var worst_name: *u8 = sys_mmap(96)
267 worst_name[0] = 0 as u8
268
269 let dfd: i64 = sys_openat_rd(dir)
270 if dfd < 0 { w("cannot open dir " as *u8); w(dir); w("\n" as *u8); return 1 }
271 var dgo: i64 = 1
272 while dgo == 1 {
273 let nr: i64 = sys_getdents64(dfd, dbuf, AS_DCAP)
274 if nr <= 0 { dgo = 0 }
275 else {
276 var off: i64 = 0
277 while off < nr {
278 let rl: i64 = (dbuf[off + 16] as i64) + ((dbuf[off + 17] as i64) * 256)
279 let nmp: *u8 = ((dbuf as i64) + off + 19) as *u8
280 let nml: i64 = slen(nmp)
281 if as_name_ok(nmp, nml) == 1 {
282 let isg: i64 = as_base(nmp, nml, base)
283 if isg == 1 { g_gatebase_o = as_pack(g_gatebase, g_gatebase_o, base, slen(base)) }
284 var po: i64 = 0
285 var di: i64 = 0
286 while dir[di] != (0 as u8) { path[po] = dir[di]; po = po + 1; di = di + 1 }
287 path[po] = 47 as u8
288 po = po + 1
289 var fi: i64 = 0
290 while nmp[fi] != (0 as u8) { path[po] = nmp[fi]; po = po + 1; fi = fi + 1 }
291 path[po] = 0 as u8
292 let fl: i64 = as_read(path, fbuf, AS_FCAP)
293 if fl > 0 {
294 files = files + 1
295 g_curfile = nmp
296 if scontains(fbuf, fl, "func main(" as *u8) == 1 {
297 if isg == 0 { g_names_o = as_pack(g_names, g_names_o, base, slen(base)) }
298 // self-verifying: an organ whose own source emits a VERDICT (selftest/gate
299 // convention) is assured even without a separate _gate file sibling.
300 if scontains(fbuf, fl, "VERDICT=" as *u8) == 1 { g_selfver_o = as_pack(g_selfver, g_selfver_o, base, slen(base)) }
301 }
302 var p: i64 = 0
303 var fgo: i64 = 1
304 while fgo == 1 {
305 let q: i64 = sfind(fbuf, fl, "func " as *u8, p)
306 if q < 0 { fgo = 0 }
307 else {
308 var atl: i64 = 0
309 if q == 0 { atl = 1 }
310 if q > 0 { if fbuf[q-1] == (10 as u8) { atl = 1 } }
311 var e: i64 = q + 5
312 if atl == 1 {
313 let fe: i64 = as_fnend(fbuf, fl, q)
314 if fe > q {
315 e = fe
316 let tn: i64 = fe - q
317 if tn < AS_TCAP - 1 {
318 var z: i64 = 0
319 while z < tn { tbuf[z] = fbuf[q + z]; z = z + 1 }
320 tbuf[tn] = 0 as u8
321 let nl2: i64 = as_fnname(tbuf, tn, nb)
322 if nl2 > 0 {
323 fns = fns + 1
324 if as_recurses(tbuf, tn, nb, nl2) == 1 { v_rec = v_rec + 1; if g_listmode == 1 { w("R1 recursion " as *u8); w(g_curfile); w(":" as *u8); w(nb); w("\n" as *u8) } }
325 if as_unbounded(tbuf, tn) == 1 { v_unb = v_unb + 1; if g_listmode == 1 { w("R2 unbounded " as *u8); w(g_curfile); w(":" as *u8); w(nb); w("\n" as *u8) } }
326 if as_mmap_in_loop(tbuf, tn) == 1 { v_mmap = v_mmap + 1; if g_listmode == 1 { w("R3 mmap-loop " as *u8); w(g_curfile); w(":" as *u8); w(nb); w("\n" as *u8) } }
327 let ln: i64 = as_lines(tbuf, tn)
328 if ln > AS_MAXLEN { v_len = v_len + 1; if g_listmode == 1 { w("R4 len=" as *u8); wn(ln); w(" " as *u8); w(g_curfile); w(":" as *u8); w(nb); w("\n" as *u8) } }
329 if ln > maxlen_seen { maxlen_seen = ln; var wz: i64 = 0; while wz < nl2 { worst_name[wz] = nb[wz]; wz = wz + 1 } worst_name[nl2] = 0 as u8 }
330 }
331 }
332 }
333 }
334 p = e
335 }
336 }
337 }
338 }
339 off = off + rl
340 }
341 }
342 }
343 sys_close(dfd)
344 // gate coverage: organs-with-main whose base is in the gatebase set
345 var organs: i64 = 0
346 var gated: i64 = 0
347 var p2: i64 = 0
348 while p2 < g_names_o {
349 var q2: i64 = p2
350 while g_names[q2] != (0 as u8) { q2 = q2 + 1 }
351 organs = organs + 1
352 var cov: i64 = as_inpack(g_gatebase, g_gatebase_o, ((g_names as i64) + p2) as *u8, q2 - p2)
353 if cov == 0 { cov = as_inpack(g_selfver, g_selfver_o, ((g_names as i64) + p2) as *u8, q2 - p2) }
354 if cov == 1 { gated = gated + 1 }
355 p2 = q2 + 1
356 }
357 // permille per rule = (fns clean of that violation) / fns
358 var pm_rec: i64 = 1000
359 var pm_unb: i64 = 1000
360 var pm_mmap: i64 = 1000
361 var pm_len: i64 = 1000
362 if fns > 0 {
363 pm_rec = ((fns - v_rec) * 1000) / fns
364 pm_unb = ((fns - v_unb) * 1000) / fns
365 pm_mmap = ((fns - v_mmap) * 1000) / fns
366 pm_len = ((fns - v_len) * 1000) / fns
367 }
368 var pm_gate: i64 = 1000
369 if organs > 0 { pm_gate = (gated * 1000) / organs }
370 // composite = mean of the 5 checked rules (each equally weighted; NOT-CHECKED rules excluded)
371 let comp: i64 = (pm_rec + pm_unb + pm_mmap + pm_len + pm_gate) / 5
372 w("=== NX-ASSURE Power-of-Ten-class ruler dir=" as *u8); w(dir); w(" ===\n" as *u8)
373 w("files=" as *u8); wn(files); w(" functions=" as *u8); wn(fns); w(" organs(main)=" as *u8); wn(organs); w("\n" as *u8)
374 w("R1 no-recursion " as *u8); wn(pm_rec); w(" permille (violations=" as *u8); wn(v_rec); w(")\n" as *u8)
375 w("R2 bounded-loops " as *u8); wn(pm_unb); w(" permille (violations=" as *u8); wn(v_unb); w(")\n" as *u8)
376 w("R3 no-alloc-in-loop " as *u8); wn(pm_mmap); w(" permille (violations=" as *u8); wn(v_mmap); w(") <- per-iteration sys_mmap OOM class\n" as *u8)
377 w("R4 fn-len<=" as *u8); wn(AS_MAXLEN); w(" " as *u8); wn(pm_len); w(" permille (violations=" as *u8); wn(v_len); w(", longest=" as *u8); wn(maxlen_seen); w(" @ " as *u8); w(worst_name); w(")\n" as *u8)
378 w("G assurance-cover " as *u8); wn(pm_gate); w(" permille (" as *u8); wn(gated); w("/" as *u8); wn(organs); w(" organs have a _gate/_test sibling OR self-verify via VERDICT=)\n" as *u8)
379 w("NOT-CHECKED (never scored as pass): R5 assert-density R6 minimal-scope R7 checked-returns R8 preprocessor(N/A) R9 single-deref R10 warnings(clean-by-construction)\n" as *u8)
380 w("NX-ASSURE composite=" as *u8); wn(comp); w(" permille over 5 mechanically-decided rules (HONEST: unmeasured rules excluded, not assumed-pass)\n" as *u8)
381 return 0
382}
383
384func as_selftest() -> i64 {
385 var passn: i64 = 0
386 // T1 recursion detected
387 let r1: *u8 = "func fac(n: i64) -> i64 { if n < 2 { return 1 } return n * fac(n - 1) }" as *u8
388 let nb: *u8 = sys_mmap(96)
389 let l1: i64 = as_fnname(r1, slen(r1), nb)
390 if as_recurses(r1, slen(r1), nb, l1) == 1 { passn = passn + 1; w("T1 recursion-detect PASS\n" as *u8) } else { w("T1 FAIL\n" as *u8) }
391 // T2 non-recursion clean (calls a DIFFERENT fn)
392 let r2: *u8 = "func g(n: i64) -> i64 { return h(n) + n }" as *u8
393 let l2: i64 = as_fnname(r2, slen(r2), nb)
394 if as_recurses(r2, slen(r2), nb, l2) == 0 { passn = passn + 1; w("T2 nonrecursion-clean PASS\n" as *u8) } else { w("T2 FAIL\n" as *u8) }
395 // T3 mmap-in-loop detected
396 let r3: *u8 = "func bad() -> i64 { var i: i64 = 0 while i < 10 { let p: *u8 = sys_mmap(16) i = i + 1 } return 0 }" as *u8
397 if as_mmap_in_loop(r3, slen(r3)) == 1 { passn = passn + 1; w("T3 mmap-in-loop-detect PASS\n" as *u8) } else { w("T3 FAIL\n" as *u8) }
398 // T4 mmap OUTSIDE loop is clean (init-time alloc)
399 let r4: *u8 = "func ok() -> i64 { let p: *u8 = sys_mmap(16) var i: i64 = 0 while i < 10 { i = i + 1 } return 0 }" as *u8
400 if as_mmap_in_loop(r4, slen(r4)) == 0 { passn = passn + 1; w("T4 mmap-init-clean PASS\n" as *u8) } else { w("T4 FAIL\n" as *u8) }
401 // T5 unbounded loop
402 let r5: *u8 = "func spin() -> i64 { while true { } return 0 }" as *u8
403 if as_unbounded(r5, slen(r5)) == 1 { passn = passn + 1; w("T5 unbounded-detect PASS\n" as *u8) } else { w("T5 FAIL\n" as *u8) }
404 // T6 base-name strip
405 let bn: *u8 = sys_mmap(96)
406 let isg: i64 = as_base("nx_foo_gate.nx" as *u8, 14, bn)
407 var ok6: i64 = 0
408 if isg == 1 { if sfind(bn, slen(bn), "nx_foo" as *u8, 0) == 0 { if slen(bn) == 6 { ok6 = 1 } } }
409 if ok6 == 1 { passn = passn + 1; w("T6 base-strip PASS\n" as *u8) } else { w("T6 FAIL base=" as *u8); w(bn); w("\n" as *u8) }
410 w("NX-ASSURE selftest " as *u8); wn(passn); w("/6 " as *u8)
411 if passn == 6 { w("VERDICT=GREEN\n" as *u8); return 0 }
412 w("VERDICT=RED\n" as *u8)
413 return 1
414}
415
416func main(argc: i64, argv: *i64) -> i64 {
417 var verb: *u8 = "selftest" as *u8
418 if argc > 1 { verb = argv[1] as *u8 }
419 if verb[0] == (97 as u8) {
420 var dir: *u8 = "runtime/_hdl_build" as *u8
421 if argc > 2 { dir = argv[2] as *u8 }
422 return as_audit(dir)
423 }
424 if verb[0] == (108 as u8) { // 'list' -> print every violation as `Rn file:fn` then the summary
425 g_listmode = 1
426 var dir: *u8 = "runtime/_hdl_build" as *u8
427 if argc > 2 { dir = argv[2] as *u8 }
428 return as_audit(dir)
429 }
430 return as_selftest()
431}