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}