code wiki / _hdl_build / nx_gatebuilt_gate.nx
nx_gatebuilt_gate.nx source
↩ module page · 589 lines · 35788 B
1// nx_gatebuilt_gate.nx -- THE UNBUILT-GATE CENSUS. For every authored *_gate.nx, does a promoted *_gate.elf
2// actually exist? A gate that lives only in source makes its subject PERMANENTLY UNVERIFIABLE, and nothing
3// in the ecosystem reports it.
4//
5// WHY (found by accident 2026-07-30, id 1785472297): I tried to VERIFY the FD_CLOEXEC port-hostage fix before
6// eating three sev-9 rows that depend on it. `POST /api/gate_run target=nx_cloexec_gate` returned
7// **exit_code=127 verdict=NOT-FOUND bytes=0** -- a fully-written gate (T1 control proving the disease state is
8// reachable, T5 neg-control, T6 non-vacuity) that had NEVER BEEN COMPILED. Building it took one call and it
9// came back 6/6 GREEN. Until then, three sev-9 incidents rested on a fix nobody could prove.
10// A two-glob spot check then said the gap is systemic: ~2877 *_gate.nx sources vs ~187 *_gate.elf binaries.
11//
12// WHY NOTHING ELSE CATCHES IT -- an unbuilt gate is invisible in EVERY direction:
13// nx_gate_rollup reads LOGS -> no binary means no log means the gate is ABSENT from the roster, not RED.
14// nx_wirecensus S3 counts promoted-but-unregistered -- never authored-but-unbuilt.
15// every debt row citing 'gate-proven' reads as evidence regardless.
16// It is the exact INVERSE of PROVEN_UNWIRED (4952 capabilities BUILT+GATED+never called): there the gate
17// exists and the capability is unused; here the capability is used and the gate does not exist.
18// BOTH SCORE AS DONE.
19//
20// LAW: AN UNBUILT GATE IS INDISTINGUISHABLE FROM A PASSING ONE IN EVERY REPORT THAT MENTIONS IT.
21//
22// SECOND CLASS, ADDED 2026-08-07 -- STALE-BUILT: the binary EXISTS but PREDATES its own source. Strictly
23// WORSE than unbuilt, because unbuilt fails LOUD: /api/gate_run answers exit 127 NOT-FOUND for a missing
24// binary, but exit 0 verdict=GREEN for a stale one -- and a GREEN is believed. Found the expensive way:
25// nx_fsops_gate served pass=23/23 GREEN off a 2026-07-29 binary while its source declared 28 checks. The
26// contradiction sat in the SAME response (printed total != declared total) and nothing read it; I reported
27// "no regression" on that GREEN. MEASURED on this census first run: 3168 sources, 715 built, of which only
28// 176 are CURRENT and 539 are STALE-BUILT -- so 5.6pc of authored gates can speak about their own source.
29// LAW: A STALE GATE IS WORSE THAN AN UNBUILT ONE. UNBUILT FAILS LOUD; STALE PASSES QUIETLY.
30// COROLLARY, and the reason this organ must be rebuilt on every edit: EDITING A GATE SOURCE WITHOUT
31// REBUILDING IT CREATES THE VERY CONDITION THIS GATE REPORTS.
32//
33// ENVELOPE, declared in the output and never silent: FLAT scan of the two named dirs (no recursion, so the
34// _attic/_retired/_stage_local shadow trees are deliberately EXCLUDED and this counts LIVE gates only);
35// existence is probed with openat, not a read, so it is cheap and cannot be fooled by an empty file being
36// unreadable; the shown list is capped and the cap is printed.
37// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
38import "nx_syscalls.nx"
39import "nx_srcfresh.nx" // sf_prov_stale -- EXACT content freshness; the clock is only the fallback now
40import "nx_doc_mainscan.nx" // ms_has_main_buf -- the estate TOKENIZED entry-point predicate (see hasmain)
41
42const GB_DIR1: *u8 = "buildroot/runtime" as *u8
43const GB_DIR2: *u8 = "buildroot/runtime/_hdl_build" as *u8
44const GB_DIRBUF: i64 = 262144
45const GB_NAMEBUF: i64 = 512
46const GB_MAXSHOW: i64 = 25
47const GB_RECLEN_OFF: i64 = 16
48const GB_NAME_OFF: i64 = 19
49const GB_STATBUF: i64 = 256 // fstatat buffer -- sized as nx_gate_verdict_lib.gv_mtime does
50const GB_STAT_MTIME_OFF: i64 = 88 // st_mtime offset, LIFTED from gv_mtime rather than re-derived
51const GB_SEC_MIN: i64 = 60
52const GB_MAXSTALE: i64 = 25 // capped list, and the cap is PRINTED
53const GB_MAXPARTIAL: i64 = 40 // PARTIAL names listed: a count nobody can act on is a scoreboard
54const GB_LINE: i64 = 640
55const GB_MODE_644: i64 = 0x1a4
56// FULL ENUMERATION LANDS IN A FILE, because the POPULATION does not fit a 16KB gate transcript and a capped
57// list is a SAMPLE. stdout keeps a DECLARED preview; these two artefacts carry every row, so the counts
58// become a work order instead of a scoreboard. ★NO SAMPLING: enumerate the population or say sampled=1.
59const GB_WO_BUILD: *u8 = "knowledge/status/gatebuilt_buildstate.tsv"
60const GB_WO_GV: *u8 = "knowledge/status/gatebuilt_verdictstate.tsv"
61const GB_SRCSCAN: i64 = 262144 // entry-point probe buffer, allocated ONCE and REUSED per scan
62
63func gb_puts(s: *u8) {
64 var n: i64 = 0
65 while s[n] != (0 as u8) { n = n + 1 }
66 sys_write(1, s, n)
67}
68
69func gb_puti(x: i64) {
70 var buf: *u8 = sys_mmap(64) as *u8
71 var v: i64 = x
72 var neg: i64 = 0
73 if v < 0 {
74 neg = 1
75 v = 0 - v
76 }
77 var i: i64 = 40
78 if v == 0 {
79 i = i - 1
80 buf[i] = 48 as u8
81 }
82 while v > 0 {
83 let d: i64 = v - (v / 10) * 10
84 i = i - 1
85 buf[i] = (d + 48) as u8
86 v = v / 10
87 }
88 if neg == 1 {
89 i = i - 1
90 buf[i] = 45 as u8
91 }
92 sys_write(1, ((buf as i64) + i) as *u8, 40 - i)
93}
94
95// does name end with "_gate.nx" ?
96func gb_is_gate_src(nm: *u8, n: i64) -> i64 {
97 if n < 8 { return 0 }
98 let t: *u8 = "_gate.nx" as *u8
99 var k: i64 = 0
100 while k < 8 {
101 if nm[n - 8 + k] != t[k] { return 0 }
102 k = k + 1
103 }
104 return 1
105}
106
107// cheap existence probe: openat for read. Never reads the file.
108func gb_exists(path: *u8) -> i64 {
109 let fd: i64 = sys_openat_rd(path)
110 if fd < 0 { return 0 }
111 sys_close(fd)
112 return 1
113}
114
115// needle-at-offset (no deep if-nesting: 5 nested ifs on one line is a documented NishiLang build failure).
116func gb_at(buf: *u8, i: i64, n: i64, needle: *u8) -> i64 {
117 var k: i64 = 0
118 while needle[k] != (0 as u8) {
119 if i + k >= n { return 0 }
120 if buf[i + k] != needle[k] { return 0 }
121 k = k + 1
122 }
123 return 1
124}
125// Does this source declare an entry point? A *_gate.nx WITHOUT main is a LIB, and a lib has no binary BY
126// DESIGN -- nxasm answers rc=102 "UNDEFINED label: main". Counting those as UNBUILT inflates the census with
127// work that CANNOT be done, and it sends the reader to run a build that cannot succeed (measured on myself
128// 2026-08-07: nx_janitor_dupname). The buffer is passed IN, never allocated here -- one 256KB mmap per file
129// across ~2400 files would be 640MB of address space for a census.
130// The whole file is scanned, not a head window, because in this codebase main is conventionally LAST.
131// Read a source ONCE into the shared scratch and return its length (-1 unreadable). Replaces the old
132// gb_has_main, which read the file per question -- three probes now cost ONE read instead of three.
133// one work-order row: <class>\t<path>\t<number>\n. fd<0 is a NO-OP so a census still runs when the artefact
134// cannot be opened -- a work order is a bonus, never a precondition for measuring.
135func gb_wo(fd: i64, lb: *u8, cls: *u8, path: *u8, num: i64) -> i64 {
136 if fd < 0 { return 0 }
137 var o: i64 = 0
138 var i: i64 = 0
139 while cls[i] != (0 as u8) { lb[o] = cls[i]; o = o + 1; i = i + 1 }
140 lb[o] = 9 as u8
141 o = o + 1
142 i = 0
143 while path[i] != (0 as u8) { lb[o] = path[i]; o = o + 1; i = i + 1 }
144 lb[o] = 9 as u8
145 o = o + 1
146 var m: i64 = num
147 if m < 0 { lb[o] = 45 as u8; o = o + 1; m = 0 - m }
148 let tb: *u8 = sys_mmap(32)
149 var k: i64 = 0
150 if m == 0 { tb[0] = 48 as u8; k = 1 }
151 while m > 0 { tb[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
152 var j: i64 = 0
153 while j < k { lb[o] = tb[k - 1 - j]; o = o + 1; j = j + 1 }
154 sys_munmap(tb, 32)
155 lb[o] = 10 as u8
156 o = o + 1
157 sys_write(fd, lb, o)
158 return 0
159}
160func gb_read_src(path: *u8, buf: *u8) -> i64 {
161 let fd: i64 = sys_openat_rd(path)
162 if fd < 0 { return 0 - 1 }
163 let n: i64 = sys_read(fd, buf, GB_SRCSCAN)
164 sys_close(fd)
165 return n
166}
167// does `needle` occur anywhere in the first n bytes? The whole file is scanned, not a head window, because
168// in this codebase main is conventionally LAST.
169// A MENTION IS NOT AN IMPORT, AND A QUOTED NAME IS NOT A CALL.
170// My first version of the D001 probe used plain substring search and therefore counted THIS VERY ORGAN as
171// base-class compliant -- because the probe strings and envelope prose below literally contain
172// nx_gate_verdict.nx and gv_check(. That is the exact source-literal defect I had just filed against the
173// D001 generator (debt 1786111258), committed one function later, and it silently inflated a number I had
174// already published. nx_gate_dry_apply has the same flaw and answered "already inherits the base class"
175// for this gate while nx_gate_migrate probe answered inherits_base=0 -- two organs, opposite answers, same
176// subject.
177// gb_import_at_bol: the needle must start a LINE, so an indented string literal or a prose mention cannot
178// masquerade as an import declaration.
179func gb_import_at_bol(buf: *u8, n: i64, needle: *u8) -> i64 {
180 var i: i64 = 0
181 var bol: i64 = 1
182 while i < n {
183 if bol == 1 { if gb_at(buf, i, n, needle) == 1 { return 1 } }
184 if buf[i] == (10 as u8) { bol = 1 }
185 else { bol = 0 }
186 i = i + 1
187 }
188 return 0
189}
190// gb_call_site: the needle must NOT be preceded by a double-quote, which is what distinguishes a real
191// gv_check(...) call from the string "gv_check(" appearing inside a probe or a message.
192func gb_call_site(buf: *u8, n: i64, needle: *u8) -> i64 {
193 var i: i64 = 0
194 while i < n {
195 if gb_at(buf, i, n, needle) == 1 {
196 if i == 0 { return 1 }
197 if buf[i - 1] != (34 as u8) { return 1 }
198 }
199 i = i + 1
200 }
201 return 0
202}
203func gb_find(buf: *u8, n: i64, needle: *u8) -> i64 {
204 var i: i64 = 0
205 while i < n {
206 if gb_at(buf, i, n, needle) == 1 { return 1 }
207 i = i + 1
208 }
209 return 0
210}
211// mtime, or -1 if unstattable. Same syscall + offset gv_mtime already proved; NOT a second derivation.
212func gb_mtime(path: *u8) -> i64 {
213 let sb: *u8 = sys_mmap(GB_STATBUF)
214 if sys_fstatat(path, sb) != 0 { sys_munmap(sb, GB_STATBUF); return 0 - 1 }
215 let mp: *i64 = ((sb as i64) + GB_STAT_MTIME_OFF) as *i64
216 let m: i64 = mp[0]
217 sys_munmap(sb, GB_STATBUF)
218 return m
219}
220
221// scan ONE dir flat; ctr[0]=gate srcs seen, ctr[1]=built, ctr[2]=unbuilt, ctr[3]=shown
222func gb_scan(dir: *u8, ctr: *i64) -> i64 {
223 let fd: i64 = sys_openat_rd(dir)
224 if fd < 0 { return 0 - 1 }
225 let dbuf: *u8 = sys_mmap(GB_DIRBUF)
226 let probe: *u8 = sys_mmap(GB_NAMEBUF)
227 let spath: *u8 = sys_mmap(GB_NAMEBUF) // <dir>/<name>.nx -- the SOURCE side of the comparison
228 let sbuf: *u8 = sys_mmap(GB_SRCSCAN + 1) // entry-point probe scratch, reused for every file
229 let gbn1: *u8 = sys_mmap(256) // ms_has_main_buf token scratch, allocated ONCE for the whole scan
230 let gbn2: *u8 = sys_mmap(256) // NEVER ALLOCATE IN A HOT LOOP -- 3,184 files would be 6,368 mmaps
231 let lbuf: *u8 = sys_mmap(GB_LINE) // work-order line scratch, reused for every row
232 let ppath: *u8 = sys_mmap(GB_NAMEBUF) // <basename>.provenance -- the EXACT ruler when present
233 var rounds: i64 = 0
234 var n: i64 = sys_getdents64(fd, dbuf, GB_DIRBUF)
235 while n > 0 {
236 rounds = rounds + 1
237 var p: i64 = 0
238 while p < n {
239 let reclen: i64 = (dbuf[p + GB_RECLEN_OFF] as i64) + ((dbuf[p + GB_RECLEN_OFF + 1] as i64) * 256)
240 if reclen <= 0 { p = n }
241 else {
242 let nm: *u8 = ((dbuf as i64) + p + GB_NAME_OFF) as *u8
243 var ln: i64 = 0
244 while nm[ln] != (0 as u8) { ln = ln + 1 }
245 if gb_is_gate_src(nm, ln) == 1 {
246 ctr[0] = ctr[0] + 1
247 // probe = <basename minus ".nx"> + ".elf" (promoted organs live at cwd = nishihost root)
248 var w: i64 = 0
249 while w < ln - 3 {
250 probe[w] = nm[w]
251 w = w + 1
252 }
253 probe[w] = 46 as u8
254 probe[w + 1] = 101 as u8
255 probe[w + 2] = 108 as u8
256 probe[w + 3] = 102 as u8
257 probe[w + 4] = 0 as u8
258 // <basename>.provenance, built the same way as probe: /api/build writes it beside the
259 // artifact, so its presence means an EXACT src-digest comparison is available.
260 var pw: i64 = 0
261 while pw < ln - 3 { ppath[pw] = nm[pw]; pw = pw + 1 }
262 ppath[pw] = 46 as u8
263 let psuf: *u8 = "provenance" as *u8
264 var pk: i64 = 0
265 while psuf[pk] != (0 as u8) { ppath[pw + 1 + pk] = psuf[pk]; pk = pk + 1 }
266 ppath[pw + 1 + pk] = 0 as u8
267 // SOURCE PATH built ONCE for BOTH arms: the built arm needs it for the mtime compare,
268 // the unbuilt arm needs it for the entry-point probe.
269 var sp: i64 = 0
270 while dir[sp] != (0 as u8) { spath[sp] = dir[sp]; sp = sp + 1 }
271 spath[sp] = 47 as u8
272 sp = sp + 1
273 var sq: i64 = 0
274 while sq < ln { spath[sp + sq] = nm[sq]; sq = sq + 1 }
275 spath[sp + sq] = 0 as u8
276 let sn: i64 = gb_read_src(spath, sbuf)
277 // TWO PREDICATES, BOTH REPORTED -- corrected 2026-08-07. This field used a PLAIN
278 // SUBSTRING search for "func main" while THIS SAME FILE, thirty lines below, correctly
279 // uses gb_import_at_bol/gb_call_site for D001 on the stated grounds that "A MENTION IS
280 // NOT AN IMPORT, AND A QUOTED NAME IS NOT A CALL". I applied the anchored predicate to
281 // one field and a raw substring to the other, in the same organ, on the same day.
282 // WHAT THIS ACTUALLY FIXES -- stated precisely because the FIRST version of THIS COMMENT
283 // overclaimed and was corrected the same hour. The tokenizer rejects `func mainloop`
284 // (the substring "func main" matches it as a PREFIX: a real false POSITIVE) and accepts
285 // `func<TAB>main` / `func main` (a real false NEGATIVE). It does NOT strip comments,
286 // AND NEITHER DOES THE SUBSTRING, so a gate whose header merely DISCUSSES `func main`
287 // still counts as declaring one. THAT CLASS REMAINS OPEN for BOTH predicates:
288 // nx_doc_mainscan.nx is the standing existence proof (a LIB whose header holds the
289 // literal "(functions only, no `func main`)"), and closing it needs the comment stripper
290 // nx_gatelaw_gate ALREADY HAS -- compose it, do not write a second one.
291 // A TRUE LAW CITED AS THE REASON FOR A CHANGE THAT DOES NOT IMPLEMENT IT IS A FALSE
292 // JUSTIFICATION WITH AN IMPECCABLE PEDIGREE, AND IT IS WORSE THAN NO COMMENT AT ALL --
293 // the next reader believes the class is handled. MEASURED: disagree=0 over 3,190 sources,
294 // so this change is a HARDENING with zero present-day impact, not a miscount repaired.
295 // ms_has_main_buf is COMPOSED from nx_doc_mainscan, the estate's existing tokenized
296 // predicate (whole-word `func` then the identifier `main`), never re-implemented.
297 // THE LEGACY SUBSTRING IS RETAINED AS A LIVE CONTROL and every disagreement is COUNTED
298 // AND NAMED, because a silent correction is indistinguishable from a silent regression.
299 // TWO COUNTERS OF THE SAME POPULATION ARE A FREE AUDIT. num = sub - tok, so +1 is a
300 // comment/string mention the substring believed and the tokenizer rejected.
301 var hasmain: i64 = 0
302 var hasmain_sub: i64 = 0
303 if sn > 0 {
304 hasmain = ms_has_main_buf(sbuf, sn, gbn1, gbn2)
305 hasmain_sub = gb_find(sbuf, sn, "func main" as *u8)
306 }
307 if hasmain != hasmain_sub {
308 ctr[18] = ctr[18] + 1
309 gb_wo(ctr[14], lbuf, "MAIN-DISAGREE" as *u8, spath, hasmain_sub - hasmain)
310 }
311 // D001 COMPLIANCE / RED-BY-CONSTRUCTION IMMUNITY, measured by BEHAVIOUR not by a source
312 // literal. A gate that imports nx_gate_verdict AND actually calls gv_check cannot have a
313 // declared total that differs from its EXECUTED total, because gv_check increments both --
314 // so it is structurally immune to the unreachable-pass defect found in nx_mgmt_api_gate
315 // (declared 20, executed 22, could never go GREEN). Anything else hand-rolls its counter
316 // and is a CANDIDATE for that defect.
317 // PROBING IMPORT+CALL ALSO FIXES THE D001 DETECTOR'S CASE SENSITIVITY (debt 1786111258):
318 // the promote guard flags on the literal "verdict=GREEN", so a gate spelling it "VERDICT="
319 // slips through and is silently exempt from the migration. A BEHAVIOUR PROBE CANNOT BE
320 // FOOLED BY CAPITALISATION, WHICH IS WHY IT IS THE RIGHT MEASURE FOR A POPULATION COUNT.
321 if sn > 0 {
322 // THREE STATES, NOT TWO -- because "inherits the base class" names TWO DIFFERENT
323 // PROPERTIES and I conflated them. GROUND-TRUTHED 2026-08-07 on nx_aes256_gcm_gate and
324 // nx_analyze_gate: both have `import "nx_gate_verdict.nx"` + gv_ctr + gv_verdict and
325 // ZERO gv_check. That is why nx_gate_dry_apply says "already inherits the base class"
326 // while a gv_check probe says hand-rolled -- BOTH ANSWERS ARE CORRECT ABOUT DIFFERENT
327 // THINGS, and reporting either alone misrepresents the fleet:
328 // FULL import + gv_check -> gv_check increments passed AND total, so declared ==
329 // executed BY CONSTRUCTION: immune to an unreachable
330 // pass condition, and D001-satisfied.
331 // PARTIAL import + gv_verdict, NO gv_check -> the VERDICT is readable (D001 is
332 // satisfied, nx_gate_green can judge it) but ctr[1] is
333 // HAND-SET, so declared CAN diverge from executed. This
334 // is exactly the shape nx_mgmt_api_gate was in when it
335 // declared 20 against 22 executing teeth and could
336 // never go GREEN. STILL SUSCEPTIBLE.
337 // NONE no usable base-class adoption -> both defects available.
338 // ★TWO INSTRUMENTS THAT DISAGREE MAY BOTH BE RIGHT; THE DEFECT IS THEN IN THE SHARED
339 // NAME, NOT IN EITHER MEASUREMENT. The red-by-construction candidate set is
340 // PARTIAL + NONE, and the D001 backlog is NONE alone -- they are NOT the same number.
341 var imp: i64 = 0
342 if gb_import_at_bol(sbuf, sn, "import \"nx_gate_verdict.nx\"" as *u8) == 1 { imp = 1 }
343 if imp == 1 {
344 if gb_call_site(sbuf, sn, "gv_check(" as *u8) == 1 { ctr[9] = ctr[9] + 1; gb_wo(ctr[15], lbuf, "FULL" as *u8, spath, 0) }
345 else {
346 if gb_call_site(sbuf, sn, "gv_verdict(" as *u8) == 1 {
347 // REFINED 2026-08-07, THIRD CORRECTION TO THIS MEASURE. PARTIAL is NOT
348 // automatically susceptible. Read on a real migrated gate
349 // (nx_asset_access_gate): dry_apply emits ctr__dry[0]=pass; ctr__dry[1]=total
350 // and that `total` is INCREMENTED PER CHECK (`total = total + 1` before every
351 // expect), so declared == executed BY CONSTRUCTION there too. The defect
352 // needs the total to come from a CONSTANT -- nx_mgmt_api_gate hand-set
353 // ctr[1] = MG_CHECKS, a literal 20, against 22 executing teeth.
354 // So susceptibility = a gv_verdict tail with NO per-check total increment.
355 // HEURISTIC, AND LABELLED AS ONE: presence of any known increment idiom
356 // clears a gate. It can only OVER-report susceptibility, never under-report,
357 // which is the safe direction for a defect census.
358 var inc: i64 = 0
359 if gb_find(sbuf, sn, "total = total + 1" as *u8) == 1 { inc = 1 }
360 if gb_find(sbuf, sn, "tot = tot + 1" as *u8) == 1 { inc = 1 }
361 if gb_find(sbuf, sn, "ttl = ttl + 1" as *u8) == 1 { inc = 1 }
362 if gb_find(sbuf, sn, "[1] + 1" as *u8) == 1 { inc = 1 }
363 if inc == 1 { ctr[13] = ctr[13] + 1; gb_wo(ctr[15], lbuf, "PARTIAL_OK" as *u8, spath, 0) }
364 else { ctr[10] = ctr[10] + 1; gb_wo(ctr[15], lbuf, "PARTIAL_SUSPECT" as *u8, spath, 0) }
365 // NAME THE MEMBERS. This class satisfies D001 yet stays susceptible, and
366 // nx_gate_dry_apply SKIPs every one of them as "already inherits", so it is
367 // the population the mechanical path can never reach. A COUNT NOBODY CAN
368 // ACT ON IS A SCOREBOARD, NOT A WORK ORDER -- and the row-conversion rung
369 // needs these names to census which check-row idiom dominates.
370 if ctr[12] < GB_MAXPARTIAL {
371 // FULL PATH, not the basename: this census scans TWO dirs, so a
372 // bare name sends the reader hunting. spath is already built.
373 gb_puts(" PARTIAL " as *u8)
374 gb_puts(spath)
375 gb_puts("\n" as *u8)
376 ctr[12] = ctr[12] + 1
377 }
378 }
379 else { ctr[11] = ctr[11] + 1; gb_wo(ctr[15], lbuf, "NONE" as *u8, spath, 0) }
380 }
381 }
382 else { ctr[11] = ctr[11] + 1; gb_wo(ctr[15], lbuf, "NONE" as *u8, spath, 0) }
383 }
384 if gb_exists(probe) == 1 {
385 ctr[1] = ctr[1] + 1
386 // STALE-BUILT: the THIRD member of this family, and the only one nothing reported.
387 // An UNBUILT gate at least fails LOUD -- /api/gate_run returns exit 127 NOT-FOUND.
388 // A gate whose binary PREDATES its own source returns exit 0 verdict=GREEN and is
389 // believed. MEASURED 2026-08-07: nx_fsops_gate served pass=23/23 GREEN off a
390 // 2026-07-29 binary while its source declared 28 checks -- the contradiction sat in
391 // the SAME response and nothing read it.
392 // LAW: A STALE GATE IS WORSE THAN AN UNBUILT ONE. UNBUILT FAILS LOUD; STALE PASSES QUIETLY.
393 // PROVENANCE FIRST (2026-08-07, live): sf_prov_stale compares the src digest RECORDED
394 // AT BUILD TIME against the source digest NOW. Exact, no clock, and it cannot be
395 // fooled by an mtime that moves. /api/build writes <target>.provenance beside the
396 // artifact, so the sidecar's presence IS the licence to stop guessing.
397 // THE CLOCK PATH BELOW IS NOW EXPLICITLY THE FALLBACK, for artifacts built before
398 // provenance existed -- and the split is COUNTED so a reader knows how much of the
399 // fleet number is exact and how much is a hint. Measured need: this census read
400 // stale=541/current=189 then stale=740/current=0 within two hours off the clock alone.
401 // * A FALLBACK THAT IS NOT COUNTED IS INDISTINGUISHABLE FROM THE MEASURE.
402 let pv: i64 = sf_prov_stale(ppath, spath)
403 if pv >= 0 { ctr[16] = ctr[16] + 1 }
404 else { ctr[17] = ctr[17] + 1 }
405 if pv == 1 { ctr[4] = ctr[4] + 1; gb_wo(ctr[14], lbuf, "STALE-PROV" as *u8, spath, 0) }
406 if pv == 0 { ctr[5] = ctr[5] + 1; gb_wo(ctr[14], lbuf, "CURRENT-PROV" as *u8, spath, 0) }
407 if pv < 0 {
408 let mte: i64 = gb_mtime(probe)
409 let mts: i64 = gb_mtime(spath)
410 if mte < 0 { ctr[7] = ctr[7] + 1 }
411 else {
412 if mts < 0 { ctr[7] = ctr[7] + 1 }
413 else {
414 if mts > mte {
415 ctr[4] = ctr[4] + 1
416 gb_wo(ctr[14], lbuf, "STALE" as *u8, spath, (mts - mte) / GB_SEC_MIN)
417 if ctr[6] < GB_MAXSTALE {
418 gb_puts(" STALE-BUILT " as *u8)
419 gb_puts(nm)
420 gb_puts(" lag_min=" as *u8)
421 gb_puti((mts - mte) / GB_SEC_MIN)
422 gb_puts("\n" as *u8)
423 ctr[6] = ctr[6] + 1
424 }
425 }
426 else { ctr[5] = ctr[5] + 1; gb_wo(ctr[14], lbuf, "CURRENT" as *u8, spath, 0) }
427 }
428 }
429 }
430 }
431 else {
432 // A *_gate.nx with NO `func main` is a LIB, and a lib has no binary BY DESIGN. Counting
433 // it UNBUILT inflates the census with work that CANNOT be done and sends the reader to
434 // run a build that fails rc=102. Split, do not fold.
435 // BEFORE REPORTING SOMETHING MISSING, CHECK WHETHER IT WAS EVER SUPPOSED TO EXIST.
436 if hasmain == 0 { ctr[8] = ctr[8] + 1; gb_wo(ctr[14], lbuf, "LIB" as *u8, spath, 0) }
437 else {
438 ctr[2] = ctr[2] + 1
439 gb_wo(ctr[14], lbuf, "UNBUILT" as *u8, spath, 0)
440 if ctr[3] < GB_MAXSHOW {
441 gb_puts(" UNBUILT " as *u8)
442 gb_puts(nm)
443 gb_puts("\n" as *u8)
444 ctr[3] = ctr[3] + 1
445 }
446 }
447 }
448 }
449 p = p + reclen
450 }
451 }
452 n = sys_getdents64(fd, dbuf, GB_DIRBUF)
453 }
454 sys_close(fd)
455 return rounds
456}
457
458func main(argc: i64, argv: *i64) -> i64 {
459 var ctr: *i64 = sys_mmap(256) as *i64 // 32 slots: [16]=prov-judged [17]=clock-judged, added 2026-08-07
460 ctr[0] = 0
461 ctr[1] = 0
462 ctr[2] = 0
463 ctr[3] = 0
464 ctr[4] = 0
465 ctr[5] = 0
466 ctr[6] = 0
467 ctr[7] = 0
468 ctr[8] = 0
469 ctr[9] = 0
470 ctr[10] = 0
471 ctr[11] = 0
472 ctr[12] = 0
473 ctr[13] = 0
474 ctr[16] = 0
475 ctr[17] = 0
476 ctr[18] = 0
477 // TRUNCATE-ON-OPEN: the work order describes THIS run, so a stale tail from a previous run would be a
478 // silent lie about the current population.
479 ctr[14] = sys_openat_wr(GB_WO_BUILD, GB_MODE_644)
480 ctr[15] = sys_openat_wr(GB_WO_GV, GB_MODE_644)
481
482 gb_puts("=== nx_gatebuilt_gate -- does every AUTHORED gate have a COMPILED binary? ===\n" as *u8)
483 gb_puts(" (an unbuilt gate is indistinguishable from a passing one in every report that mentions it)\n" as *u8)
484
485 let r1: i64 = gb_scan(GB_DIR1, ctr)
486 let r2: i64 = gb_scan(GB_DIR2, ctr)
487
488 if r1 < 0 {
489 gb_puts("VERDICT=RED cannot open " as *u8)
490 gb_puts(GB_DIR1)
491 gb_puts(" -- a census that cannot read its corpus must refuse, never report zero.\n" as *u8)
492 return 1
493 }
494 if r2 < 0 {
495 gb_puts("VERDICT=RED cannot open " as *u8)
496 gb_puts(GB_DIR2)
497 gb_puts(" -- a census that cannot read its corpus must refuse, never report zero.\n" as *u8)
498 return 1
499 }
500
501 if ctr[2] > GB_MAXSHOW {
502 gb_puts(" ... " as *u8)
503 gb_puti(ctr[2] - GB_MAXSHOW)
504 gb_puts(" more UNBUILT not shown (list capped at " as *u8)
505 gb_puti(GB_MAXSHOW)
506 gb_puts(", the cap is declared not silent)\n" as *u8)
507 }
508
509 if ctr[4] > GB_MAXSTALE {
510 gb_puts(" ... " as *u8)
511 gb_puti(ctr[4] - GB_MAXSTALE)
512 gb_puts(" more STALE-BUILT not shown (list capped at " as *u8)
513 gb_puti(GB_MAXSTALE)
514 gb_puts(", the cap is declared not silent)\n" as *u8)
515 }
516
517 gb_puts("\nNX-GATEBUILT gate_sources=" as *u8); gb_puti(ctr[0])
518 gb_puts(" built=" as *u8); gb_puti(ctr[1])
519 gb_puts(" UNBUILT=" as *u8); gb_puti(ctr[2])
520 var permil: i64 = 0
521 if ctr[0] > 0 { permil = ctr[1] * 1000 / ctr[0] }
522 gb_puts(" built_permil=" as *u8); gb_puti(permil)
523 gb_puts(" stale_built=" as *u8); gb_puti(ctr[4])
524 gb_puts(" current_built=" as *u8); gb_puti(ctr[5])
525 gb_puts(" unstattable=" as *u8); gb_puti(ctr[7])
526 gb_puts(" freshness_EXACT_provenance=" as *u8); gb_puti(ctr[16])
527 gb_puts(" freshness_fallback_clock=" as *u8); gb_puti(ctr[17])
528 gb_puts(" lib_shaped_no_main=" as *u8); gb_puti(ctr[8])
529 gb_puts(" main_predicate_disagree=" as *u8); gb_puti(ctr[18])
530 gb_puts(" gv_FULL=" as *u8); gb_puti(ctr[9])
531 gb_puts(" gv_PARTIAL_const_total_SUSPECT=" as *u8); gb_puti(ctr[10])
532 gb_puts(" gv_PARTIAL_counted_total_ok=" as *u8); gb_puti(ctr[13])
533 gb_puts(" gv_NONE=" as *u8); gb_puti(ctr[11])
534 gb_puts(" redbyconstruction_UPPER_BOUND=" as *u8); gb_puti(ctr[10] + ctr[11])
535 gb_puts(" partial_named=" as *u8); gb_puti(ctr[12])
536 gb_puts("\n" as *u8)
537 // THE POPULATION IS ENUMERATED IN FULL, IN FILES -- stdout above is a DECLARED PREVIEW, not the data.
538 // A capped list is a sample and a sample must never be published as a population fact (rule 29).
539 if ctr[14] >= 0 { sys_close(ctr[14]) }
540 if ctr[15] >= 0 { sys_close(ctr[15]) }
541 // ⚠STALE/CURRENT COMES FROM A CANDIDATE CLOCK RULER AND IT HAS BECOME UNRELIABLE ON THIS ESTATE.
542 // MEASURED 2026-08-07: this split read stale=541 current=189, then stale=740 current=0 (every built
543 // gate) within two hours. lag_sec is a DIFFERENCE BETWEEN TWO FILE MTIMES, so it cannot move unless a
544 // file moves -- yet untouched gates drifted by MORE lag than the wall time elapsed (nx_aes256_gcm_gate
545 // 482948 -> 557268, +20.6h of lag in ~2h), at DIFFERENT rates per gate, which no single tree-wide event
546 // explains. Something is moving artifact mtimes BACKWARDS. Two independent implementations (gb_mtime
547 // seconds, sf_mtime_ns nanoseconds) agree with each other, so this is the ESTATE, not the arithmetic.
548 // ★A DIFFERENCE OF TWO FIXED TIMESTAMPS THAT CHANGES BY ITSELF MEANS AN INPUT IS NOT FIXED -- AND A
549 // RULER WHOSE INPUTS MOVE UNDER IT CANNOT CARRY A FLEET NUMBER.
550 // So the counts are printed but explicitly NOT to be planned against; the replacement already exists:
551 // /api/build now records src_sha256 + elf_sha256 into <target>.provenance, which is an EXACT content
552 // comparison with no clock in it (debt 1786113214). Treat build/UNBUILT/LIB as sound (existence and
553 // entry-point are not clock-derived) and STALE/CURRENT as advisory until provenance is live.
554 gb_puts(" freshness_ruler=PROVENANCE-FIRST: freshness_EXACT_provenance rows are an EXACT src-digest\n" as *u8)
555 gb_puts(" comparison (no clock); freshness_fallback_clock rows have NO sidecar and are a HINT only.\n" as *u8)
556 gb_puts(" MEASURED THE DIFFERENCE: the clock alone reported stale=740 current=0 on this same fleet;\n" as *u8)
557 gb_puts(" provenance reports current=684 stale=61 -- the clock was wrong about ~92pc of built gates.\n" as *u8)
558 gb_puts(" work_order_buildstate=" as *u8); gb_puts(GB_WO_BUILD)
559 gb_puts(" work_order_verdictstate=" as *u8); gb_puts(GB_WO_GV)
560 if ctr[14] < 0 { gb_puts(" (buildstate file UNWRITABLE -- counts above stand, the work order does not)" as *u8) }
561 if ctr[15] < 0 { gb_puts(" (verdictstate file UNWRITABLE -- counts above stand, the work order does not)" as *u8) }
562 gb_puts("\n" as *u8)
563 gb_puts("envelope: FLAT scan of buildroot/runtime + _hdl_build (no recursion -- _attic/_retired/_stage_local\n" as *u8)
564 gb_puts(" shadow trees deliberately EXCLUDED so this counts LIVE gates); existence probed with openat, not\n" as *u8)
565 gb_puts(" a read; promoted organs resolve at cwd. A gate built but promoted under another name reads UNBUILT.\n" as *u8)
566 gb_puts(" STALENESS IS REPORTED HERE, NOT JUDGED: the verdict stays bound to this organ ONE subject (is a\n" as *u8)
567 gb_puts(" binary present?) per rule 9. stale_built compares mtime of the gate elf against its OWN source\n" as *u8)
568 gb_puts(" only -- it does NOT walk the import closure, so a gate invalidated by a shared dep reads CURRENT\n" as *u8)
569 gb_puts(" here. That closure is nx_rebuild_plan job (it names the TRIGGER file); nx_stale_check <target>\n" as *u8)
570 gb_puts(" rebuilds and byte-compares to CONFIRM one target -- mtime alone proves a source moved, not that\n" as *u8)
571 gb_puts(" codegen changed. Turning fleet staleness into this verdict would make it permanently RED = noise.\n" as *u8)
572 gb_puts(" HAND_ROLLED_VERDICT is the RED-BY-CONSTRUCTION candidate set, also reported not judged. A gate\n" as *u8)
573 gb_puts(" importing nx_gate_verdict AND calling gv_check has declared == executed BY CONSTRUCTION and so\n" as *u8)
574 gb_puts(" cannot hold an unreachable pass condition. A hand-rolled counter can, and one did: nx_mgmt_api_gate\n" as *u8)
575 gb_puts(" declared 20 while 22 teeth ran, printing passed 22/20 RED with every tooth passing. Measured by\n" as *u8)
576 gb_puts(" IMPORT+CALL, never by a source literal: the promote-time D001 check keys on lowercase verdict=GREEN\n" as *u8)
577 gb_puts(" and MISSES a gate spelling it VERDICT= (debt 1786111258), so this count is the honest one.\n" as *u8)
578
579 if ctr[0] == 0 {
580 gb_puts("VERDICT=RED found ZERO gate sources -- a census that finds nothing has failed, not passed.\n" as *u8)
581 return 1
582 }
583 if ctr[2] == 0 {
584 gb_puts("VERDICT=GREEN every authored gate has a compiled binary.\n" as *u8)
585 return 0
586 }
587 gb_puts("VERDICT=RED authored gates with NO binary exist -- every claim resting on one is UNPROVEN.\n" as *u8)
588 return 1
589}