code wiki / _hdl_build / nx_gateadjudicate.nx

nx_gateadjudicate.nx source

↩ module page · 1329 lines · 70748 B

1// nx_gateadjudicate.nx -- THE GATE ADJUDICATION CENSUS: every gate source in the compile corpus, its 2// adoption ladder (file facts), the execution surfaces that name it, and the ONE remedy bucket it 3// falls in. Built for campaign lane B (2026-08-18): "2,287 uninvoked gate sources wire-or-retire, 4// 105 deployed-dark, 2,182 undeployed" -- numbers measured once on 2026-08-07 over ONE source 5// directory (2,317 gates) and later shown to understate the population by ~880 (nx_gatesubj on the 6// whole corpus: 3,194). A campaign that works a stale list re-investigates what is already fixed, so 7// step 0 of the lane is this instrument, re-runnable, full population, partition summed. 8// 9// WHAT ALREADY EXISTED (asked first -- nx_spendgate/nx_capsearch, 2026-08-18): 10// nx_gatesubj every gate's SUBJECT from its own source (the population enumerator; composed here 11// through the same gk_corpus_scan so the denominator cannot disagree) 12// nx_catalog PER-NAME adoption ladder (SOURCE.BUILT.STAGED.PROMOTED.REGISTERED.AUTHORISED.INVOKED) 13// -- its INVOKED axis is the MCP actlog only, and gates are mostly run by beats, so a 14// gate reads DARK there while a clock row runs it nightly 15// nx_wirecensus registered-but-never-called over the MCP surface (S4) 16// nx_gate_rollup reads knowledge/gatereg.conf rows -> knowledge/status/<gate>.log verdicts 17// nx_gatebuilt_gate authored-vs-compiled census (prints a bounded list, no partition) 18// None joins the GATE population to the surfaces that CAUSE EXECUTION. That join is this organ. 19// 20// THE EDGE DEFINITION IS THE QUESTION (measured 08-07: four definitions gave 75 / 0 / 2,043 / 30). 21// A gate counts as INVOKED only through a surface that runs it or collects its verdict: 22// CLOCK its own .elf is the organ of a clock row, OR its name appears in that row's ARGUMENTS 23// (clocksched- live, clockjobs- desired; measured: rows like `nx_sov_build_run.elf <gate>` 24// and `nx_law_warden.elf scan` carry args, so the organ column is split at its first space) 25// ROSTER its name is MENTIONED inside the source of an organ that IS on the clock (2-hop, e.g. 26// nx_estate_census_run -> nx_gatesubj.elf; nx_gfx_gates_beat -> "nx_gltf_load_gate"+".elf", 27// so the match is the identifier, not the .elf literal), or inside an organ listed in 28// knowledge/gateadjudicate_rosters.conf (off-host rosters such as the laptop's 29// nx_memplane_run, declared as DATA -- never a name baked in here) 30// GATES a knowledge/compare/*.gates row (the executed-evidence map nx_swcompare_evidence runs) 31// GATEREG a knowledge/gatereg.conf row (nx_gate_rollup collects its verdict) 32// GROSTER a knowledge/gateroster.conf row -- the data-driven roster nx_gate_roster_run runs on the 33// clock; counted as a surface ONLY while nx_gate_roster_run itself is a roster organ (on the 34// clock or in the rosters conf), otherwise the conf is a list nothing executes and is NOT 35// credited (printed as groster_inert=1 so the reader sees the missing clock row) 36// ACTLOG an MCP invocation on record in knowledge/status/actlog.jrnl (tail window, declared) 37// A mere MENTION of <gate>.elf in some other source is recorded as REF (something wants it) but is 38// NOT invocation -- report generators name their findings, and that class contaminated three 39// measurements in one hour on 08-07. ★ AN UNSTAMPED REPORT IS INDISTINGUISHABLE FROM A REGISTRY. 40// TRIAL the LATEST row for the gate in knowledge/status/gateroster.jrnl (nx_gate_roster_run's journal: 41// trial or beat). NOT a surface -- it is the REASON that travels with DEPLOYED-DARK: a dark gate 42// that has been trialed and FAILED (RED/ABSENT/TIMEOUT) is a defect worklist, not a wiring 43// worklist, and a dark gate that trialed GREEN/SKIP is one `admit` away from LIVE. The bucket 44// stays DEPLOYED-DARK (the partition does not change); the sub-counts split it by remedy. 45// BTRIAL same, from knowledge/status/gatebuild.jrnl -- the BUILT-ARTIFACT sweep lane: trials run the 46// gate's buildroot/_build/<n>.sov.elf IN PLACE (no promote, nothing deployed), so the 47// 2,181-strong BUILT-UNPROMOTED class can be adjudicated on EVIDENCE (passing = a promote 48// candidate, failing = fix-or-retire) instead of by a mass action the record forbids. 49// LOG (a knowledge/status/*.log the gate writes, with its age) is EVIDENCE it once ran, not a surface. 50// ⚠ LOG NAMES DROP THE ORGAN PREFIX: nx_p384_ecdh_gate writes p384_ecdh_gate.log, _mmu_gate writes 51// mmu.log (measured 2026-08-18 against knowledge/gatereg.conf, which is DERIVED from those logs). So a 52// log/gatereg row matches gate <n> when its basename equals <n> minus a leading "nx_" or "_" (STEM), 53// (or the full name), or -- only when no gate matches exactly AND no non-gate ORGAN of that stem exists in 54// the corpus -- STEM minus a trailing "_gate". Measured 2026-08-18 without that second guard: resmon.log, 55// shipcheck.log, asset_access.log (ORGAN status logs, whose verdict= lines the rollup collects on the 56// organ's behalf) were credited to nx_resmon_gate / nx_shipcheck_gate / nx_asset_access_gate and made 57// 50+ dark gates read as "ran today". ★ A LOG NAMED FOR THE SUBJECT IS THE SUBJECT'S LOG, NOT ITS GATE'S. 58// A log that then matches more than one gate is counted AMBIGUOUS and printed, not silently credited to both. 59// 60// LADDER (file facts, the same paths nx_catalog stats): 61// SRC hdl|rt . BUILT buildroot/_build/<n>.sov.elf . STAGED <n>.sov.elf.new . 62// PROMOTED <n>.elf | _offc/<n>.elf | buildroot/_offc/<n>.elf . REG tool_allowlist.conf field 0 63// 64// THE PARTITION (one bucket per gate, remedies differ, sum printed and checked): 65// LIVE invoked AND promoted -> nothing to do (verdict is collected) 66// INVOKED-MISSING invoked AND NOT promoted -> an invocation GAP: build+promote 67// DEPLOYED-DARK promoted, NOT invoked -> wire to a roster (or retire the binary) 68// BUILT-UNPROMOTED built, not promoted, not invoked -> promote or retire the build 69// SOURCE-ONLY no artifact, not invoked -> REFERENCED (ref>0: something names it, 70// adjudicate) | UNREFERENCED (nothing in the corpus names it: retire candidate) 71// ★★★★★ "94% NOT DEPLOYED" IS A HEADLINE; A SUMMED PARTITION BY REMEDY IS A DECISION. 72// 73// DECLARED BLIND SPOTS (printed every run, so a reader never mistakes them for zero): 74// - laptop hooks / laptop rosters are not on this host; declare them in the rosters conf. 75// - ACTLOG is a tail window of GA_ACT_TAIL bytes; older invocations are invisible. 76// - a ROSTER edge is 2-hop and static: the organ names the .elf; whether that code path runs is 77// the organ's business. It is still a surface that CAN cause execution, unlike a report. 78// 79// usage: nx_gateadjudicate [--rows <path>] [--list <CLASS> <path>] [--estate <dir>] 80// --list <CLASS> <path> (repeatable, up to GA_MAXLISTS per run) write the gate NAMES of one bucket, one per line, in nx_gate_roster_run's 81// roster/trial format -- path-qualified when the binary is not at the estate 82// root (`_offc/<n>`, `buildroot/_offc/<n>`), because the runner execs 83// ./<row>.elf and a bare name for an _offc-only gate journals ABSENT (measured 84// on trial 1: promoted gates reported ABSENT purely from the row's spelling). 85// roster/trial format (CLASS = LIVE | INVOKED-MISSING | DEPLOYED-DARK | 86// BUILT-UNPROMOTED | SOURCE-ONLY | DARK-UNTRIED | DARK-PASSING | DARK-FAILING) -- 87// the last three are DEPLOYED-DARK split by its TRIAL axis, and LIVE-FAILING is the 88// LIVE gates whose latest roster/trial row is RED/ABSENT/TIMEOUT -- collected AND read, 89// which is the whole point of wiring; a trial list is emitted by the census 90// itself, never hand-filtered from its rows. A SOURCE-ONLY list WITHHOLDS 91// gates whose source was modified today (src_age_d == 0) and prints how many: 92// that list feeds a reversible-retire campaign, and the estate's measured law 93// is that a fresh artifact can be ANOTHER SEAT'S WORK IN FLIGHT -- the guard 94// belongs in the emitter, not in the operator's memory 95// --rows <path> write one row per gate: name|src|src_age_d|built|staged|prom|reg|clock|roster|gates|gatereg|groster|act|log|logage_d|ref|first_ref|trial|class 96// (always) a CLUSTER table: gates grouped by their first name token after the prefix, one line per 97// cluster with its bucket counts, sorted by UNINVOKED desc -- the campaign is worked per cluster, 98// never per row, because a shared cause reports once per consumer. 99// --estate <dir> chdir here instead of ep_anchor() (laptop smoke; the census is about the NAS estate) 100// exit: 0 census printed . 1 REFUSED (corpus/table cap or unreadable tree -- never a truncated census) 101// 3 UNOBSERVABLE (no estate root on this host) 102// Appends ONE line per run to knowledge/status/gateadjudicate.log (a level cannot express a trend). 103// license_tier: ORIGINAL Read-only over the estate except its own two artifacts. No hw writes (Rule 26). 104import "nx_gatekit_lib.nx" 105import "nx_estate_path.nx" 106import "nx_clock_sched.nx" 107 108const GA_MAXF: i64 = 32768 // corpus files (gk_corpus_scan REFUSES past this, never truncates) 109const GA_SLOT: i64 = 192 // bytes per corpus path slot 110const GA_MAXG: i64 = 6144 // gates the table holds (REFUSE past it -- a silent cap is a smaller number that reads as better news) 111const GA_GSLOT: i64 = 128 // bytes per gate name 112const GA_MSG: i64 = 65536 113const GA_ROWCAP: i64 = 4194304 // rows artifact; refuse if exceeded 114const GA_ACT_TAIL: i64 = 4194304 // actlog tail window (DECLARED: older invocations invisible) 115const GA_STATBUF: i64 = 256 116const GA_MTIME_OFF: i64 = 88 // x86_64 struct stat: st_mtim.tv_sec 117const GA_SEC_PER_DAY: i64 = 86400 118const GA_MAXCLK: i64 = 512 // clock/roster organ basenames (live + desired planes + conf) 119const GA_MAXCLU: i64 = 4096 // distinct cluster keys (a full table prints FLOOR, never silently stops counting) 120const GA_MAXLISTS: i64 = 8 // --list specs accepted per run (a clock row emits several worklists in one pass) 121const GA_CLUSHOW: i64 = 60 // cluster lines printed (the rest are in the rows artifact; the count of hidden clusters is printed) 122const GA_LOG: *u8 = "knowledge/status/gateadjudicate.log" 123const GA_ROSTERS: *u8 = "knowledge/gateadjudicate_rosters.conf" 124const GA_ALLOW: *u8 = "tool_allowlist.conf" 125const GA_GATEREG: *u8 = "knowledge/gatereg.conf" 126const GA_GROSTER: *u8 = "knowledge/gateroster.conf" 127const GA_ROSTJRNL: *u8 = "knowledge/status/gateroster.jrnl" 128const GA_BUILDJRNL: *u8 = "knowledge/status/gatebuild.jrnl" 129const GA_BUILT_PREFIX: *u8 = "buildroot/_build/" 130const GA_BUILT_SUFFIX: *u8 = ".sov" 131const GA_ACTLOG: *u8 = "knowledge/status/actlog.jrnl" 132const GA_STATUS: *u8 = "knowledge/status/" 133const GA_CMP1: *u8 = "knowledge/compare/" 134const GA_CMP2: *u8 = "buildroot/knowledge/compare/" 135const GA_CLK_LIVE: *u8 = "knowledge/store/clocksched-" 136const GA_CLK_WANT: *u8 = "knowledge/store/clockjobs-" 137 138// ---- small helpers ------------------------------------------------------------------------------- 139 140func ga_isid(c: i64) -> i64 { 141 if c >= 97 { if c <= 122 { return 1 } } 142 if c >= 65 { if c <= 90 { return 1 } } 143 if c >= 48 { if c <= 57 { return 1 } } 144 if c == 95 { return 1 } 145 return 0 146} 147 148// does NUL-terminated s end with NUL-terminated suf? 149func ga_endswith(s: *u8, suf: *u8) -> i64 { 150 let l: i64 = gk_len(s) 151 let k: i64 = gk_len(suf) 152 if k > l { return 0 } 153 var i: i64 = 0 154 while i < k { if s[l - k + i] != suf[i] { return 0 } i = i + 1 } 155 return 1 156} 157 158// pointer to the basename of a NUL-terminated path 159func ga_base(p: *u8) -> *u8 { 160 var bo: i64 = 0 161 var i: i64 = 0 162 while p[i] != (0 as u8) { if p[i] == (47 as u8) { bo = i + 1 } i = i + 1 } 163 return ((p as i64) + bo) as *u8 164} 165 166func ga_gslot(g: *u8, i: i64) -> *u8 { return ((g as i64) + i * GA_GSLOT) as *u8 } 167func ga_cslot(names: *u8, i: i64) -> *u8 { return ((names as i64) + i * GA_SLOT) as *u8 } 168 169// compare a byte run [p, p+n) against NUL-terminated s 170func ga_eqrun(s: *u8, p: *u8, n: i64) -> i64 { 171 var i: i64 = 0 172 while i < n { if s[i] == (0 as u8) { return 0 } if s[i] != p[i] { return 0 } i = i + 1 } 173 if s[i] != (0 as u8) { return 0 } 174 return 1 175} 176 177// linear lookup of a byte run in the gate table; -1 if absent. (3k names x few hits per file -- 178// the scan is dominated by bytes read, not by this loop.) 179func ga_find(gn: *u8, ng: i64, p: *u8, n: i64) -> i64 { 180 var i: i64 = 0 181 while i < ng { if ga_eqrun(ga_gslot(gn, i), p, n) == 1 { return i } i = i + 1 } 182 return 0 - 1 183} 184 185// mtime (epoch seconds) of a path, or -1 186func ga_mtime(path: *u8, sb: *u8) -> i64 { 187 if sys_fstatat(path, sb) != 0 { return 0 - 1 } 188 var v: i64 = 0 189 var i: i64 = 7 190 while i >= 0 { v = (v << 8) | (sb[GA_MTIME_OFF + i] as i64); i = i - 1 } 191 return v 192} 193 194// append one NUL-terminated line to a file (create 0644 if absent) 195func ga_appendline(path: *u8, line: *u8) -> i64 { 196 let fd: i64 = sys_openat_append(path, 420) 197 if fd < 0 { return 0 - 1 } 198 let n: i64 = gk_len(line) 199 let w: i64 = gk_write_all(fd, line, n) 200 sys_close(fd) 201 return w 202} 203 204// Scan a byte buffer for identifier runs that end in "_gate" and are followed by `after` (".elf", 205// or NUL for "any delimiter"); each hit resolves against the gate table and marks flag[g] (and 206// counts into cnt[g] when cnt is non-null, recording the first referrer index in first[g]). 207// `self` (may be -1) is never marked -- an organ naming its own basename is not a reference. 208func ga_scan_buf(buf: *u8, n: i64, gn: *u8, ng: i64, flag: *i64, cnt: *i64, first: *i64, refidx: i64, self: i64, want_elf: i64) -> i64 { 209 var hits: i64 = 0 210 var i: i64 = 0 211 while i < n { 212 // find the end of an identifier run 213 if ga_isid(buf[i] as i64) == 1 { 214 var e: i64 = i 215 var fin: i64 = 0 216 while fin == 0 { 217 if e >= n { fin = 1 } 218 if fin == 0 { if ga_isid(buf[e] as i64) == 1 { e = e + 1 } else { fin = 1 } } 219 } 220 // run is [i, e) 221 var take: i64 = 0 222 if e - i >= 6 { 223 if buf[e - 5] == (95 as u8) { if buf[e - 4] == (103 as u8) { if buf[e - 3] == (97 as u8) { if buf[e - 2] == (116 as u8) { if buf[e - 1] == (101 as u8) { take = 1 } } } } } 224 } 225 if take == 1 { 226 if want_elf == 1 { 227 take = 0 228 if e + 4 <= n { 229 if buf[e] == (46 as u8) { if buf[e + 1] == (101 as u8) { if buf[e + 2] == (108 as u8) { if buf[e + 3] == (102 as u8) { take = 1 } } } } 230 } 231 } 232 } 233 if take == 1 { 234 let g: i64 = ga_find(gn, ng, ((buf as i64) + i) as *u8, e - i) 235 if g >= 0 { 236 if g != self { 237 flag[g] = 1 238 if cnt != (0 as *i64) { 239 if cnt[g] == 0 { first[g] = refidx } 240 cnt[g] = cnt[g] + 1 241 } 242 hits = hits + 1 243 } 244 } 245 } 246 i = e 247 } 248 i = i + 1 249 } 250 return hits 251} 252 253// STEM of a gate name: minus a leading "nx_" or "_". Returns the offset into the name. 254func ga_stemoff(nm: *u8) -> i64 { 255 if nm[0] == (110 as u8) { if nm[1] == (120 as u8) { if nm[2] == (95 as u8) { return 3 } } } 256 if nm[0] == (95 as u8) { return 1 } 257 return 0 258} 259 260// Match a log/gatereg basename run [p,p+n) against the gate table by STEM, then by STEM minus "_gate" 261// (fallback only when no exact stem matched). Marks flag[g] for every match; returns the number of 262// gates matched (0, 1, or >1 = ambiguous). 263// compare cb[off .. off+n) with p[0..n) (no terminator requirement on cb beyond the run) 264func ga_eqrun_n(cb: *u8, off: i64, p: *u8, n: i64) -> i64 { 265 var k: i64 = 0 266 while k < n { if cb[off + k] != p[k] { return 0 } k = k + 1 } 267 return 1 268} 269 270// does the compile corpus hold a source whose basename is <pre><run>.nx, for pre in {nx_, _, ""}? 271func ga_organ_exists(names: *u8, scanned: i64, p: *u8, n: i64) -> i64 { 272 var i: i64 = 0 273 while i < scanned { 274 let cb: *u8 = ga_base(ga_cslot(names, i)) 275 let bl: i64 = gk_len(cb) - 3 // minus ".nx" 276 var hit: i64 = 0 277 if bl == n { if ga_eqrun_n(cb, 0, p, n) == 1 { hit = 1 } } 278 if hit == 0 { if bl == n + 3 { if cb[0] == (110 as u8) { if cb[1] == (120 as u8) { if cb[2] == (95 as u8) { if ga_eqrun_n(cb, 3, p, n) == 1 { hit = 1 } } } } } } 279 if hit == 0 { if bl == n + 1 { if cb[0] == (95 as u8) { if ga_eqrun_n(cb, 1, p, n) == 1 { hit = 1 } } } } 280 if hit == 1 { return 1 } 281 i = i + 1 282 } 283 return 0 284} 285 286func ga_logmatch(gn: *u8, ng: i64, p: *u8, n: i64, flag: *i64, lastg: *i64, names: *u8, scanned: i64) -> i64 { 287 var matched: i64 = 0 288 var i: i64 = 0 289 while i < ng { 290 let nm: *u8 = ga_gslot(gn, i) 291 let so: i64 = ga_stemoff(nm) 292 var hit: i64 = 0 293 if ga_eqrun(((nm as i64) + so) as *u8, p, n) == 1 { hit = 1 } 294 if hit == 0 { if ga_eqrun(nm, p, n) == 1 { hit = 1 } } 295 if hit == 1 { flag[i] = 1; lastg[0] = i; matched = matched + 1 } 296 i = i + 1 297 } 298 if matched > 0 { return matched } 299 // fallback: stem minus trailing "_gate" (5 bytes) -- ONLY when no non-gate organ owns that stem 300 if ga_organ_exists(names, scanned, p, n) == 1 { return 0 } 301 i = 0 302 while i < ng { 303 let nm: *u8 = ga_gslot(gn, i) 304 let so: i64 = ga_stemoff(nm) 305 let sl: i64 = gk_len(nm) - so 306 if sl > 5 { 307 if ga_endswith(nm, "_gate" as *u8) == 1 { 308 if sl - 5 == n { 309 var eq: i64 = 1 310 var k: i64 = 0 311 while k < n { if nm[so + k] != p[k] { eq = 0; k = n } else { k = k + 1 } } 312 if eq == 1 { flag[i] = 1; lastg[0] = i; matched = matched + 1 } 313 } 314 } 315 } 316 i = i + 1 317 } 318 return matched 319} 320 321// Walk one directory; for every regular entry whose name ends with `ext`, mark the gate named by the 322// entry (mode 1: entry basename minus ext IS the gate name -> flag + age) or scan the file's rows for 323// <gate>.elf literals (mode 2: .gates maps). Returns entries examined, or -1 if the dir is unopenable. 324func ga_dirpass(dir: *u8, ext: *u8, mode: i64, gn: *u8, ng: i64, flag: *i64, age: *i64, now: i64, sb: *u8, ambig: *i64, names: *u8, scanned: i64) -> i64 { 325 let fd: i64 = sys_openat_rd(dir) 326 if fd < 0 { return 0 - 1 } 327 let gbuf: *u8 = sys_mmap(65536) 328 let path: *u8 = sys_mmap(4096) 329 let nm2: *u8 = sys_mmap(512) 330 let lenp: *i64 = sys_mmap(16) as *i64 331 var seen: i64 = 0 332 var nread: i64 = __syscall(217, fd, gbuf, 65536, 0, 0, 0) 333 while nread > 0 { 334 var off: i64 = 0 335 while off < nread { 336 let reclen: i64 = (gbuf[off + 16] as i64) | ((gbuf[off + 17] as i64) << 8) 337 if reclen <= 0 { off = nread } 338 if reclen > 0 { 339 let nm: *u8 = ((gbuf as i64) + off + 19) as *u8 340 if ga_endswith(nm, ext) == 1 { 341 seen = seen + 1 342 var po: i64 = gk_cat(path, 0, dir) 343 po = gk_cat(path, po, nm) 344 path[po] = 0 as u8 345 if mode == 1 { 346 // knowledge/status/<stem>.log -> evidence + age (stem rule, see header) 347 let l: i64 = gk_len(nm) 348 let k: i64 = gk_len(ext) 349 var q: i64 = 0 350 while q < l - k { nm2[q] = nm[q]; q = q + 1 } 351 nm2[q] = 0 as u8 352 let lastg: *i64 = sys_mmap(8) as *i64 353 lastg[0] = 0 - 1 354 let m: i64 = ga_logmatch(gn, ng, nm2, l - k, flag, lastg, names, scanned) 355 if m > 1 { ambig[0] = ambig[0] + 1 } 356 if m >= 1 { 357 let mt: i64 = ga_mtime(path, sb) 358 // age is recorded on the last matched gate; an ambiguous log's age is 359 // still a real mtime, so record it rather than -1 360 if mt > 0 { age[lastg[0]] = (now - mt) / GA_SEC_PER_DAY } 361 if mt <= 0 { age[lastg[0]] = 0 - 1 } 362 } 363 } 364 if mode == 2 { 365 let b: *u8 = sys_read_file(path, lenp) 366 if lenp[0] > 0 { 367 ga_scan_buf(b, lenp[0], gn, ng, flag, 0 as *i64, 0 as *i64, 0, 0 - 1, 1) 368 sys_free_file(b, lenp[0]) 369 } 370 } 371 } 372 off = off + reclen 373 } 374 } 375 nread = __syscall(217, fd, gbuf, 65536, 0, 0, 0) 376 } 377 sys_close(fd) 378 return seen 379} 380 381// Load one clock plane and (a) mark gates whose own .elf is an organ column, (b) append every organ 382// basename (minus .elf) to the roster table. Returns rows loaded (0 if the plane is empty/absent). 383func ga_clockpass(prefix: *u8, gn: *u8, ng: i64, g_clock: *i64, ros: *u8, nros: *i64) -> i64 { 384 let names: *u8 = sys_mmap(CLK_MAXJOBS * CLK_NAMEW) 385 let orgs: *u8 = sys_mmap(CLK_MAXJOBS * CLK_NAMEW) 386 let iv: *i64 = sys_mmap(CLK_MAXJOBS * 8) as *i64 387 let nd: *i64 = sys_mmap(CLK_MAXJOBS * 8) as *i64 388 let np: *i64 = sys_mmap(8) as *i64 389 np[0] = 0 390 let r: i64 = clk_load_plane(prefix, names, orgs, iv, nd, np) 391 if r <= 0 { return 0 } 392 let first: *u8 = sys_mmap(CLK_NAMEW + 8) 393 var i: i64 = 0 394 while i < np[0] { 395 let org: *u8 = clk_slot(orgs, i) 396 // the organ column is "<path> [args...]": the FIRST TOKEN is the organ, the rest are its args 397 var fl: i64 = 0 398 var ff: i64 = 0 399 while ff == 0 { 400 if org[fl] == (0 as u8) { ff = 1 } 401 if ff == 0 { if org[fl] == (32 as u8) { ff = 1 } else { if fl < CLK_NAMEW { first[fl] = org[fl] } fl = fl + 1 } } 402 } 403 first[fl] = 0 as u8 404 let base: *u8 = ga_base(first) 405 // strip a trailing ".elf" and then a trailing ".sov" for the name comparison 406 let l: i64 = gk_len(base) 407 var nl: i64 = l 408 if ga_endswith(base, ".elf" as *u8) == 1 { nl = l - 4 } 409 if nl > 4 { if base[nl - 4] == (46 as u8) { if base[nl - 3] == (115 as u8) { if base[nl - 2] == (111 as u8) { if base[nl - 1] == (118 as u8) { nl = nl - 4 } } } } } 410 // (a) direct: the gate's own elf is scheduled, or a gate is named in the row's ARGUMENTS 411 let g: i64 = ga_find(gn, ng, base, nl) 412 if g >= 0 { g_clock[g] = 1 } 413 if org[fl] == (32 as u8) { ga_scan_buf(((org as i64) + fl) as *u8, gk_len(org) - fl, gn, ng, g_clock, 0 as *i64, 0 as *i64, 0, 0 - 1, 0) } 414 // (b) roster table entry (dedup by exact name) 415 var dup: i64 = 0 416 var j: i64 = 0 417 while j < nros[0] { if ga_eqrun(ga_gslot(ros, j), base, nl) == 1 { dup = 1 } j = j + 1 } 418 if dup == 0 { 419 if nros[0] < GA_MAXCLK { 420 let dst: *u8 = ga_gslot(ros, nros[0]) 421 var q: i64 = 0 422 while q < nl { if q < GA_GSLOT - 1 { dst[q] = base[q] } q = q + 1 } 423 if q > GA_GSLOT - 1 { q = GA_GSLOT - 1 } 424 dst[q] = 0 as u8 425 nros[0] = nros[0] + 1 426 } 427 } 428 i = i + 1 429 } 430 return np[0] 431} 432 433// Read the off-host roster conf (one organ basename per line, comments with a leading semicolon or 434// blank lines ignored) into the roster table. Returns lines adopted, or -1 if the conf is absent. 435func ga_rosterconf(path: *u8, ros: *u8, nros: *i64) -> i64 { 436 let lenp: *i64 = sys_mmap(16) as *i64 437 let b: *u8 = sys_read_file(path, lenp) 438 if lenp[0] <= 0 { return 0 - 1 } 439 let n: i64 = lenp[0] 440 var adopted: i64 = 0 441 var i: i64 = 0 442 while i < n { 443 let e: i64 = gk_eol(b, i, n) 444 // a line whose first non-blank byte is ';' (59) or the hash mark (35) is a comment: skip it, 445 // else the first word of the comment would be adopted as a roster organ (measured on the 446 // laptop smoke: "; off-host rosters" adopted `off`). 447 var c0: i64 = i 448 var fc: i64 = 0 449 while fc == 0 { 450 if c0 >= e { fc = 1 } 451 if fc == 0 { if b[c0] == (32 as u8) { c0 = c0 + 1 } else { fc = 1 } } 452 } 453 var skip: i64 = 0 454 if c0 < e { if b[c0] == (59 as u8) { skip = 1 } } 455 if c0 < e { if b[c0] == (35 as u8) { skip = 1 } } 456 if skip == 1 { c0 = e } 457 // trim: identifier run only 458 var s: i64 = c0 459 var f1: i64 = 0 460 while f1 == 0 { 461 if s >= e { f1 = 1 } 462 if f1 == 0 { if ga_isid(b[s] as i64) == 1 { f1 = 1 } else { s = s + 1 } } 463 } 464 var t: i64 = s 465 var f2: i64 = 0 466 while f2 == 0 { 467 if t >= e { f2 = 1 } 468 if f2 == 0 { if ga_isid(b[t] as i64) == 1 { t = t + 1 } else { f2 = 1 } } 469 } 470 if t > s { 471 if nros[0] < GA_MAXCLK { 472 let dst: *u8 = ga_gslot(ros, nros[0]) 473 var q: i64 = 0 474 while q < t - s { if q < GA_GSLOT - 1 { dst[q] = b[s + q] } q = q + 1 } 475 if q > GA_GSLOT - 1 { q = GA_GSLOT - 1 } 476 dst[q] = 0 as u8 477 nros[0] = nros[0] + 1 478 adopted = adopted + 1 479 } 480 } 481 i = e + 1 482 } 483 sys_free_file(b, n) 484 return adopted 485} 486 487// roster-journal pass: knowledge/status/gateroster.jrnl rows are `epoch TAB tag TAB gate TAB verdict TAB 488// exit=N TAB ms=N`; the LATEST row per gate wins (append-only journal). Writes trial[g] = 1 GREEN . 2 SKIP 489// . 3 RED . 4 ABSENT . 5 TIMEOUT (0 = never trialed). The gate field may be path-qualified 490// (`_offc/<n>`): only the basename is matched. Returns rows read, or -1 if the journal is absent. 491func ga_jrnleq(b: *u8, rs: i64, re: i64, lit: *u8) -> i64 { 492 let l: i64 = gk_len(lit) 493 if re - rs != l { return 0 } 494 var k: i64 = 0 495 while k < l { if b[rs + k] != lit[k] { return 0 } k = k + 1 } 496 return 1 497} 498func ga_jrnlpass(path: *u8, gn: *u8, ng: i64, trial: *i64) -> i64 { 499 let lenp: *i64 = sys_mmap(16) as *i64 500 let b: *u8 = sys_read_file(path, lenp) 501 if lenp[0] <= 0 { return 0 - 1 } 502 let n: i64 = lenp[0] 503 var rows: i64 = 0 504 var i: i64 = 0 505 while i < n { 506 let e: i64 = gk_eol(b, i, n) 507 var f: i64 = 0 508 var fs: i64 = i 509 var gs: i64 = 0 510 var ge: i64 = 0 511 var vs: i64 = 0 512 var ve: i64 = 0 513 var t: i64 = i 514 while t <= e { 515 var atend: i64 = 0 516 if t == e { atend = 1 } 517 if atend == 0 { if b[t] == (9 as u8) { atend = 1 } } 518 if atend == 1 { 519 if f == 2 { gs = fs; ge = t } 520 if f == 3 { vs = fs; ve = t } 521 f = f + 1 522 fs = t + 1 523 } 524 t = t + 1 525 } 526 if ge > gs { if ve > vs { 527 rows = rows + 1 528 // basename of the gate field, minus a trailing .elf 529 var bs: i64 = gs 530 var q: i64 = gs 531 while q < ge { if b[q] == (47 as u8) { bs = q + 1 } q = q + 1 } 532 var be: i64 = ge 533 if be - bs > 4 { if b[be - 4] == (46 as u8) { if b[be - 3] == (101 as u8) { if b[be - 2] == (108 as u8) { if b[be - 1] == (102 as u8) { be = be - 4 } } } } } 534 // built-sweep rows are spelled `buildroot/_build/<n>.sov` -- strip the .sov the same way 535 if be - bs > 4 { if b[be - 4] == (46 as u8) { if b[be - 3] == (115 as u8) { if b[be - 2] == (111 as u8) { if b[be - 1] == (118 as u8) { be = be - 4 } } } } } 536 let g: i64 = ga_find(gn, ng, ((b as i64) + bs) as *u8, be - bs) 537 if g >= 0 { 538 var v: i64 = 0 539 if ga_jrnleq(b, vs, ve, "GREEN" as *u8) == 1 { v = 1 } 540 if ga_jrnleq(b, vs, ve, "SKIP" as *u8) == 1 { v = 2 } 541 if ga_jrnleq(b, vs, ve, "RED" as *u8) == 1 { v = 3 } 542 if ga_jrnleq(b, vs, ve, "ABSENT" as *u8) == 1 { v = 4 } 543 if ga_jrnleq(b, vs, ve, "TIMEOUT" as *u8) == 1 { v = 5 } 544 trial[g] = v 545 } 546 } } 547 i = e + 1 548 } 549 sys_free_file(b, n) 550 return rows 551} 552 553// gateroster pass: every non-comment first-word of knowledge/gateroster.conf that names a gate marks 554// GROSTER (rows may carry a trailing ".elf" or an "_offc/" prefix, both stripped). Returns rows matched, 555// or -1 if the conf is absent. 556func ga_grosterpass(path: *u8, gn: *u8, ng: i64, flag: *i64) -> i64 { 557 let lenp: *i64 = sys_mmap(16) as *i64 558 let b: *u8 = sys_read_file(path, lenp) 559 if lenp[0] <= 0 { return 0 - 1 } 560 let n: i64 = lenp[0] 561 var hits: i64 = 0 562 var i: i64 = 0 563 while i < n { 564 let e: i64 = gk_eol(b, i, n) 565 var c0: i64 = i 566 var fc: i64 = 0 567 while fc == 0 { 568 if c0 >= e { fc = 1 } 569 if fc == 0 { if b[c0] == (32 as u8) { c0 = c0 + 1 } else { fc = 1 } } 570 } 571 var skip: i64 = 0 572 if c0 >= e { skip = 1 } 573 if skip == 0 { if b[c0] == (59 as u8) { skip = 1 } } 574 if skip == 0 { if b[c0] == (35 as u8) { skip = 1 } } 575 if skip == 0 { 576 // token: up to space or eol; then strip a leading path (after last '/') and a trailing .elf 577 var t: i64 = c0 578 var ft: i64 = 0 579 while ft == 0 { 580 if t >= e { ft = 1 } 581 if ft == 0 { if b[t] == (32 as u8) { ft = 1 } else { t = t + 1 } } 582 } 583 var bs: i64 = c0 584 var q: i64 = c0 585 while q < t { if b[q] == (47 as u8) { bs = q + 1 } q = q + 1 } 586 var be: i64 = t 587 if be - bs > 4 { if b[be - 4] == (46 as u8) { if b[be - 3] == (101 as u8) { if b[be - 2] == (108 as u8) { if b[be - 1] == (102 as u8) { be = be - 4 } } } } } 588 if be > bs { 589 let g: i64 = ga_find(gn, ng, ((b as i64) + bs) as *u8, be - bs) 590 if g >= 0 { flag[g] = 1; hits = hits + 1 } 591 } 592 } 593 i = e + 1 594 } 595 sys_free_file(b, n) 596 return hits 597} 598 599// registry pass: every line of tool_allowlist.conf whose field 0 (up to TAB) names a gate marks REG. 600func ga_regpass(path: *u8, gn: *u8, ng: i64, g_reg: *i64) -> i64 { 601 let lenp: *i64 = sys_mmap(16) as *i64 602 let b: *u8 = sys_read_file(path, lenp) 603 if lenp[0] <= 0 { return 0 - 1 } 604 let n: i64 = lenp[0] 605 var rows: i64 = 0 606 var i: i64 = 0 607 while i < n { 608 let e: i64 = gk_eol(b, i, n) 609 var t: i64 = i 610 var f3: i64 = 0 611 while f3 == 0 { 612 if t >= e { f3 = 1 } 613 if f3 == 0 { if b[t] == (9 as u8) { f3 = 1 } else { t = t + 1 } } 614 } 615 if t > i { 616 let g: i64 = ga_find(gn, ng, ((b as i64) + i) as *u8, t - i) 617 if g >= 0 { g_reg[g] = 1 } 618 } 619 rows = rows + 1 620 i = e + 1 621 } 622 sys_free_file(b, n) 623 return rows 624} 625 626// gatereg pass: every non-comment row of knowledge/gatereg.conf is `<banner>TAB<log-path>`; the log 627// path's basename minus ".log" is stem-matched against the gate table (same rule as the LOG axis, 628// because gatereg IS derived from those logs). Returns rows that matched a gate, or -1 if absent. 629func ga_gateregpass(path: *u8, gn: *u8, ng: i64, flag: *i64, ambig: *i64, names: *u8, scanned: i64) -> i64 { 630 let lenp: *i64 = sys_mmap(16) as *i64 631 let b: *u8 = sys_read_file(path, lenp) 632 if lenp[0] <= 0 { return 0 - 1 } 633 let n: i64 = lenp[0] 634 let lastg: *i64 = sys_mmap(8) as *i64 635 var hits: i64 = 0 636 var i: i64 = 0 637 while i < n { 638 let e: i64 = gk_eol(b, i, n) 639 var comment: i64 = 0 640 if b[i] == (35 as u8) { comment = 1 } 641 if comment == 0 { 642 // last field: from after the last TAB (or line start) to e; then basename; then strip .log 643 var f: i64 = i 644 var t: i64 = i 645 while t < e { if b[t] == (9 as u8) { f = t + 1 } t = t + 1 } 646 var bs: i64 = f 647 t = f 648 while t < e { if b[t] == (47 as u8) { bs = t + 1 } t = t + 1 } 649 var be: i64 = e 650 if be - bs > 4 { 651 if b[be - 4] == (46 as u8) { if b[be - 3] == (108 as u8) { if b[be - 2] == (111 as u8) { if b[be - 1] == (103 as u8) { be = be - 4 } } } } 652 } 653 if be > bs { 654 let m: i64 = ga_logmatch(gn, ng, ((b as i64) + bs) as *u8, be - bs, flag, lastg, names, scanned) 655 if m > 1 { ambig[0] = ambig[0] + 1 } 656 if m >= 1 { hits = hits + 1 } 657 } 658 } 659 i = e + 1 660 } 661 sys_free_file(b, n) 662 return hits 663} 664 665// actlog pass: TAIL window of the MCP invocation journal; identifier runs ending in _gate mark ACT. 666func ga_actpass(path: *u8, gn: *u8, ng: i64, flag: *i64, winout: *i64) -> i64 { 667 let fd: i64 = sys_openat_rd(path) 668 if fd < 0 { winout[0] = 0 - 1; return 0 - 1 } 669 let sz: i64 = sys_lseek(fd, 0, 2) 670 var start: i64 = 0 671 if sz > GA_ACT_TAIL { start = sz - GA_ACT_TAIL } 672 sys_lseek(fd, start, 0) 673 let cap: i64 = sz - start 674 let b: *u8 = sys_mmap(cap + 16) 675 var total: i64 = 0 676 var go: i64 = 1 677 while go == 1 { 678 let r: i64 = sys_read(fd, ((b as i64) + total) as *u8, cap - total) 679 if r <= 0 { go = 0 } else { total = total + r; if total >= cap { go = 0 } } 680 } 681 sys_close(fd) 682 winout[0] = total 683 if total <= 0 { return 0 } 684 return ga_scan_buf(b, total, gn, ng, flag, 0 as *i64, 0 as *i64, 0, 0 - 1, 0) 685} 686 687func ga_yn(msg: *u8, o: i64, v: i64) -> i64 { 688 if v > 0 { return gk_cat(msg, o, "1|" as *u8) } 689 return gk_cat(msg, o, "0|" as *u8) 690} 691 692func main(argc: i64, argv: *i64) -> i64 { 693 let msg: *u8 = sys_mmap(GA_MSG) 694 var o: i64 = 0 695 var rowsp: *u8 = 0 as *u8 696 let listcls_a: *i64 = sys_mmap(GA_MAXLISTS * 8) as *i64 697 let listp_a: *i64 = sys_mmap(GA_MAXLISTS * 8) as *i64 698 var nlists: i64 = 0 699 var lists_dropped: i64 = 0 700 var estate: *u8 = 0 as *u8 701 var a: i64 = 1 702 while a < argc { 703 let s: *u8 = argv[a] as *u8 704 if gk_streq(s, "--rows" as *u8) == 1 { if a + 1 < argc { rowsp = argv[a + 1] as *u8; a = a + 1 } } 705 if gk_streq(s, "--list" as *u8) == 1 { if a + 2 < argc { 706 var room: i64 = 0 707 if nlists < GA_MAXLISTS { room = 1 } 708 if room == 1 { listcls_a[nlists] = argv[a + 1]; listp_a[nlists] = argv[a + 2]; nlists = nlists + 1 } 709 if room == 0 { lists_dropped = lists_dropped + 1 } 710 a = a + 2 } } 711 if gk_streq(s, "--estate" as *u8) == 1 { if a + 1 < argc { estate = argv[a + 1] as *u8; a = a + 1 } } 712 a = a + 1 713 } 714 715 // ---- P0 anchor: a verdict that changes with the caller's cwd is not a measurement ---------- 716 if estate != (0 as *u8) { 717 if sys_chdir(estate) != 0 { 718 o = gk_cat(msg, 0, "nx_gateadjudicate: UNOBSERVABLE -- cannot chdir to --estate\nverdict=UNOBSERVABLE\n" as *u8) 719 gk_say(msg, o) 720 return 3 721 } 722 } 723 if estate == (0 as *u8) { 724 if ep_anchor() < 0 { 725 o = gk_cat(msg, 0, "nx_gateadjudicate: UNOBSERVABLE -- no estate root on this host (ep_anchor failed; pass --estate <dir> for a smoke run)\nverdict=UNOBSERVABLE\n" as *u8) 726 gk_say(msg, o) 727 return 3 728 } 729 } 730 let now: i64 = sys_now_realtime_sec() 731 let sb: *u8 = sys_mmap(GA_STATBUF) 732 733 // ---- P1 corpus: the ONE denominator (REFUSES, never truncates) -------------------------------- 734 let names: *u8 = sys_mmap(GA_MAXF * GA_SLOT) 735 let scanned: i64 = gk_corpus_scan(names, GA_SLOT, GA_MAXF) 736 if scanned == (0 - 2) { o = gk_cat(msg, 0, "nx_gateadjudicate: REFUSED -- corpus exceeds GA_MAXF; a truncated census is not a census.\nverdict=REFUSED\n" as *u8); gk_say(msg, o); return 1 } 737 if scanned == (0 - 3) { o = gk_cat(msg, 0, "nx_gateadjudicate: REFUSED -- a source path exceeds GA_SLOT.\nverdict=REFUSED\n" as *u8); gk_say(msg, o); return 1 } 738 if scanned <= 0 { o = gk_cat(msg, 0, "nx_gateadjudicate: REFUSED -- could not scan the compile corpus.\nverdict=REFUSED\n" as *u8); gk_say(msg, o); return 1 } 739 740 // ---- P2 gate table ----------------------------------------------------------------------- 741 let gn: *u8 = sys_mmap(GA_MAXG * GA_GSLOT) 742 let g_src: *i64 = sys_mmap(GA_MAXG * 8) as *i64 // 1 hdl, 2 rt 743 let g_cidx: *i64 = sys_mmap(GA_MAXG * 8) as *i64 // corpus index of the gate source 744 let g_built: *i64 = sys_mmap(GA_MAXG * 8) as *i64 745 let g_staged: *i64 = sys_mmap(GA_MAXG * 8) as *i64 746 let g_proot: *i64 = sys_mmap(GA_MAXG * 8) as *i64 747 let g_poffc: *i64 = sys_mmap(GA_MAXG * 8) as *i64 748 let g_pbro: *i64 = sys_mmap(GA_MAXG * 8) as *i64 749 let g_reg: *i64 = sys_mmap(GA_MAXG * 8) as *i64 750 let g_clock: *i64 = sys_mmap(GA_MAXG * 8) as *i64 751 let g_roster: *i64 = sys_mmap(GA_MAXG * 8) as *i64 752 let g_gates: *i64 = sys_mmap(GA_MAXG * 8) as *i64 753 let g_greg: *i64 = sys_mmap(GA_MAXG * 8) as *i64 754 let g_gros: *i64 = sys_mmap(GA_MAXG * 8) as *i64 755 let g_trial: *i64 = sys_mmap(GA_MAXG * 8) as *i64 756 let g_btrial: *i64 = sys_mmap(GA_MAXG * 8) as *i64 757 let g_act: *i64 = sys_mmap(GA_MAXG * 8) as *i64 758 let g_log: *i64 = sys_mmap(GA_MAXG * 8) as *i64 759 let g_logage: *i64 = sys_mmap(GA_MAXG * 8) as *i64 760 let g_srcage: *i64 = sys_mmap(GA_MAXG * 8) as *i64 761 let g_ref: *i64 = sys_mmap(GA_MAXG * 8) as *i64 762 let g_ref1: *i64 = sys_mmap(GA_MAXG * 8) as *i64 763 let g_refflag: *i64 = sys_mmap(GA_MAXG * 8) as *i64 // scratch: ga_scan_buf's flag slot when the counter is g_ref 764 let g_class: *i64 = sys_mmap(GA_MAXG * 8) as *i64 765 let c_isgate: *i64 = sys_mmap(GA_MAXF * 8) as *i64 // corpus idx -> gate idx or -1 766 var ng: i64 = 0 767 var ci: i64 = 0 768 while ci < scanned { 769 let cp: *u8 = ga_cslot(names, ci) 770 c_isgate[ci] = 0 - 1 771 if ga_endswith(cp, "_gate.nx" as *u8) == 1 { 772 if ng >= GA_MAXG { 773 o = gk_cat(msg, 0, "nx_gateadjudicate: REFUSED -- more gates than GA_MAXG; raise the table, do not sample.\nverdict=REFUSED\n" as *u8) 774 gk_say(msg, o) 775 return 1 776 } 777 let base: *u8 = ga_base(cp) 778 let l: i64 = gk_len(base) 779 let dst: *u8 = ga_gslot(gn, ng) 780 var q: i64 = 0 781 while q < l - 3 { if q < GA_GSLOT - 1 { dst[q] = base[q] } q = q + 1 } 782 if q > GA_GSLOT - 1 { q = GA_GSLOT - 1 } 783 dst[q] = 0 as u8 784 g_src[ng] = 2 785 if gk_has(cp, "/_hdl_build/" as *u8) == 1 { g_src[ng] = 1 } 786 g_cidx[ng] = ci 787 g_logage[ng] = 0 - 1 788 g_srcage[ng] = 0 - 1 789 let smt: i64 = ga_mtime(cp, sb) 790 if smt > 0 { g_srcage[ng] = (now - smt) / GA_SEC_PER_DAY } 791 g_ref1[ng] = 0 - 1 792 c_isgate[ci] = ng 793 ng = ng + 1 794 } 795 ci = ci + 1 796 } 797 if ng <= 0 { o = gk_cat(msg, 0, "nx_gateadjudicate: REFUSED -- no *_gate.nx in the corpus.\nverdict=REFUSED\n" as *u8); gk_say(msg, o); return 1 } 798 799 // ---- P3 clock planes + off-host roster conf -> roster table ---------------------------------- 800 let ros: *u8 = sys_mmap(GA_MAXCLK * GA_GSLOT) 801 let nros: *i64 = sys_mmap(8) as *i64 802 nros[0] = 0 803 let clk_live: i64 = ga_clockpass(GA_CLK_LIVE, gn, ng, g_clock, ros, nros) 804 let clk_want: i64 = ga_clockpass(GA_CLK_WANT, gn, ng, g_clock, ros, nros) 805 let ros_conf: i64 = ga_rosterconf(GA_ROSTERS, ros, nros) 806 807 // ---- P4 exec-literal scan over the WHOLE corpus (REF everywhere, ROSTER when the referrer is a roster organ) 808 let lenp: *i64 = sys_mmap(16) as *i64 809 var files_read: i64 = 0 810 var files_unreadable: i64 = 0 811 var bytes_read: i64 = 0 812 var ros_referrers: i64 = 0 813 ci = 0 814 while ci < scanned { 815 let cp: *u8 = ga_cslot(names, ci) 816 let b: *u8 = sys_read_file(cp, lenp) 817 if lenp[0] <= 0 { files_unreadable = files_unreadable + 1 } 818 if lenp[0] > 0 { 819 files_read = files_read + 1 820 bytes_read = bytes_read + lenp[0] 821 let self: i64 = c_isgate[ci] 822 // is this file a roster organ? (its basename minus .nx is in the roster table) 823 let base: *u8 = ga_base(cp) 824 let bl: i64 = gk_len(base) 825 var isros: i64 = 0 826 var j: i64 = 0 827 while j < nros[0] { if ga_eqrun(ga_gslot(ros, j), base, bl - 3) == 1 { isros = 1 } j = j + 1 } 828 if isros == 1 { ros_referrers = ros_referrers + 1 } 829 ga_scan_buf(b, lenp[0], gn, ng, g_refflag, g_ref, g_ref1, ci, self, 1) 830 // A ROSTER organ exists to run things, and it commonly builds the elf path at runtime 831 // ("nx_x_gate" as *u8 + ".elf" -- measured: nx_gfx_gates_beat names its 8 gates that way), 832 // so for roster organs ANY identifier mention counts as the edge (want_elf=0). This can 833 // only over-credit LIVE, i.e. it errs toward NOT retiring -- the safe direction for a 834 // signal that feeds a destructive remedy. 835 if isros == 1 { ga_scan_buf(b, lenp[0], gn, ng, g_roster, 0 as *i64, 0 as *i64, ci, self, 0) } 836 sys_free_file(b, lenp[0]) 837 } 838 ci = ci + 1 839 } 840 var gi: i64 = 0 841 842 // ---- P5..P8 registries / maps / journal / logs ------------------------------------------------ 843 let reg_rows: i64 = ga_regpass(GA_ALLOW, gn, ng, g_reg) 844 let ambig: *i64 = sys_mmap(16) as *i64 845 ambig[0] = 0 846 ambig[1] = 0 847 let greg_hits: i64 = ga_gateregpass(GA_GATEREG, gn, ng, g_greg, ((ambig as i64) + 8) as *i64, names, scanned) 848 let gates1: i64 = ga_dirpass(GA_CMP1, ".gates" as *u8, 2, gn, ng, g_gates, g_logage, now, sb, ambig, names, scanned) 849 let gates2: i64 = ga_dirpass(GA_CMP2, ".gates" as *u8, 2, gn, ng, g_gates, g_logage, now, sb, ambig, names, scanned) 850 // GROSTER counts only while the roster runner is itself a roster organ (on the clock / in the conf) 851 var gros_live: i64 = 0 852 var rq: i64 = 0 853 while rq < nros[0] { if gk_streq(ga_gslot(ros, rq), "nx_gate_roster_run" as *u8) == 1 { gros_live = 1 } rq = rq + 1 } 854 var gros_hits: i64 = 0 - 1 855 if gros_live == 1 { gros_hits = ga_grosterpass(GA_GROSTER, gn, ng, g_gros) } 856 let jrnl_rows: i64 = ga_jrnlpass(GA_ROSTJRNL, gn, ng, g_trial) 857 let bjrnl_rows: i64 = ga_jrnlpass(GA_BUILDJRNL, gn, ng, g_btrial) 858 let actwin: *i64 = sys_mmap(8) as *i64 859 let act_hits: i64 = ga_actpass(GA_ACTLOG, gn, ng, g_act, actwin) 860 let logs_seen: i64 = ga_dirpass(GA_STATUS, ".log" as *u8, 1, gn, ng, g_log, g_logage, now, sb, ambig, names, scanned) 861 862 // ---- P9 ladder stats ------------------------------------------------------------------------ 863 let p: *u8 = sys_mmap(4096) 864 gi = 0 865 while gi < ng { 866 let nm: *u8 = ga_gslot(gn, gi) 867 var po: i64 = gk_cat(p, 0, "buildroot/_build/" as *u8); po = gk_cat(p, po, nm); po = gk_cat(p, po, ".sov.elf" as *u8); p[po] = 0 as u8 868 g_built[gi] = gk_exists(p) 869 po = gk_cat(p, 0, nm); po = gk_cat(p, po, ".sov.elf.new" as *u8); p[po] = 0 as u8 870 g_staged[gi] = gk_exists(p) 871 po = gk_cat(p, 0, nm); po = gk_cat(p, po, ".elf" as *u8); p[po] = 0 as u8 872 g_proot[gi] = gk_exists(p) 873 po = gk_cat(p, 0, "_offc/" as *u8); po = gk_cat(p, po, nm); po = gk_cat(p, po, ".elf" as *u8); p[po] = 0 as u8 874 g_poffc[gi] = gk_exists(p) 875 po = gk_cat(p, 0, "buildroot/_offc/" as *u8); po = gk_cat(p, po, nm); po = gk_cat(p, po, ".elf" as *u8); p[po] = 0 as u8 876 g_pbro[gi] = gk_exists(p) 877 gi = gi + 1 878 } 879 880 // ---- P10 classify + partition --------------------------------------------------------------- 881 var n_live: i64 = 0 882 var n_gap: i64 = 0 883 var n_dark: i64 = 0 884 var n_dark_reg: i64 = 0 885 var n_dark_log: i64 = 0 886 var n_dark_ref: i64 = 0 887 var n_live_fail: i64 = 0 888 var n_bup_untried: i64 = 0 889 var n_bup_pass: i64 = 0 890 var n_bup_fail: i64 = 0 891 var n_dark_untried: i64 = 0 892 var n_dark_pass: i64 = 0 893 var n_dark_fail: i64 = 0 894 var n_bup: i64 = 0 895 var n_src: i64 = 0 896 var n_src_ref: i64 = 0 897 var n_src_unref: i64 = 0 898 var n_hdl: i64 = 0 899 var n_rt: i64 = 0 900 var s_clock: i64 = 0 901 var s_roster: i64 = 0 902 var s_gates: i64 = 0 903 var s_greg: i64 = 0 904 var s_gros: i64 = 0 905 var s_act: i64 = 0 906 var s_reg: i64 = 0 907 var s_log: i64 = 0 908 var s_ref: i64 = 0 909 var s_prom: i64 = 0 910 var s_proot: i64 = 0 911 var s_poffc: i64 = 0 912 var s_pbro: i64 = 0 913 var s_built: i64 = 0 914 var s_staged: i64 = 0 915 gi = 0 916 while gi < ng { 917 var invoked: i64 = 0 918 if g_clock[gi] > 0 { invoked = 1 } 919 if g_roster[gi] > 0 { invoked = 1 } 920 if g_gates[gi] > 0 { invoked = 1 } 921 if g_greg[gi] > 0 { invoked = 1 } 922 if g_gros[gi] > 0 { invoked = 1 } 923 if g_act[gi] > 0 { invoked = 1 } 924 var prom: i64 = 0 925 if g_proot[gi] > 0 { prom = 1 } 926 if g_poffc[gi] > 0 { prom = 1 } 927 if g_pbro[gi] > 0 { prom = 1 } 928 var cls: i64 = 0 929 if invoked == 1 { if prom == 1 { cls = 1; n_live = n_live + 1; if g_trial[gi] >= 3 { n_live_fail = n_live_fail + 1 } } } 930 if invoked == 1 { if prom == 0 { cls = 2; n_gap = n_gap + 1 } } 931 if invoked == 0 { if prom == 1 { 932 cls = 3; n_dark = n_dark + 1 933 if g_reg[gi] > 0 { n_dark_reg = n_dark_reg + 1 } 934 if g_log[gi] > 0 { n_dark_log = n_dark_log + 1 } 935 if g_ref[gi] > 0 { n_dark_ref = n_dark_ref + 1 } 936 if g_trial[gi] == 0 { n_dark_untried = n_dark_untried + 1 } 937 if g_trial[gi] == 1 { n_dark_pass = n_dark_pass + 1 } 938 if g_trial[gi] == 2 { n_dark_pass = n_dark_pass + 1 } 939 if g_trial[gi] >= 3 { n_dark_fail = n_dark_fail + 1 } 940 } } 941 if invoked == 0 { if prom == 0 { if g_built[gi] > 0 { 942 cls = 4; n_bup = n_bup + 1 943 if g_btrial[gi] == 0 { n_bup_untried = n_bup_untried + 1 } 944 if g_btrial[gi] == 1 { n_bup_pass = n_bup_pass + 1 } 945 if g_btrial[gi] == 2 { n_bup_pass = n_bup_pass + 1 } 946 if g_btrial[gi] >= 3 { n_bup_fail = n_bup_fail + 1 } 947 } } } 948 if invoked == 0 { if prom == 0 { if g_built[gi] == 0 { 949 cls = 5; n_src = n_src + 1 950 if g_ref[gi] > 0 { n_src_ref = n_src_ref + 1 } 951 if g_ref[gi] == 0 { n_src_unref = n_src_unref + 1 } 952 } } } 953 g_class[gi] = cls 954 if g_src[gi] == 1 { n_hdl = n_hdl + 1 } 955 if g_src[gi] == 2 { n_rt = n_rt + 1 } 956 if g_clock[gi] > 0 { s_clock = s_clock + 1 } 957 if g_roster[gi] > 0 { s_roster = s_roster + 1 } 958 if g_gates[gi] > 0 { s_gates = s_gates + 1 } 959 if g_greg[gi] > 0 { s_greg = s_greg + 1 } 960 if g_gros[gi] > 0 { s_gros = s_gros + 1 } 961 if g_act[gi] > 0 { s_act = s_act + 1 } 962 if g_reg[gi] > 0 { s_reg = s_reg + 1 } 963 if g_log[gi] > 0 { s_log = s_log + 1 } 964 if g_ref[gi] > 0 { s_ref = s_ref + 1 } 965 if prom == 1 { s_prom = s_prom + 1 } 966 if g_proot[gi] > 0 { s_proot = s_proot + 1 } 967 if g_poffc[gi] > 0 { s_poffc = s_poffc + 1 } 968 if g_pbro[gi] > 0 { s_pbro = s_pbro + 1 } 969 if g_built[gi] > 0 { s_built = s_built + 1 } 970 if g_staged[gi] > 0 { s_staged = s_staged + 1 } 971 gi = gi + 1 972 } 973 let part_sum: i64 = n_live + n_gap + n_dark + n_bup + n_src 974 975 // ---- report --------------------------------------------------------------------------------- 976 o = gk_cat(msg, 0, "nx_gateadjudicate: the gate adjudication census, whole compile corpus, one bucket per gate\n" as *u8) 977 o = gk_cat(msg, o, " corpus_files=" as *u8); o = gk_catn(msg, o, scanned) 978 o = gk_cat(msg, o, " gate_sources=" as *u8); o = gk_catn(msg, o, ng) 979 o = gk_cat(msg, o, " (hdl_build=" as *u8); o = gk_catn(msg, o, n_hdl) 980 o = gk_cat(msg, o, " runtime=" as *u8); o = gk_catn(msg, o, n_rt) 981 o = gk_cat(msg, o, ") files_read=" as *u8); o = gk_catn(msg, o, files_read) 982 o = gk_cat(msg, o, " unreadable=" as *u8); o = gk_catn(msg, o, files_unreadable) 983 o = gk_cat(msg, o, " bytes_read=" as *u8); o = gk_catn(msg, o, bytes_read) 984 o = gk_cat(msg, o, "\n surfaces: clock_live_rows=" as *u8); o = gk_catn(msg, o, clk_live) 985 o = gk_cat(msg, o, " clock_desired_rows=" as *u8); o = gk_catn(msg, o, clk_want) 986 o = gk_cat(msg, o, " roster_conf_lines=" as *u8); o = gk_catn(msg, o, ros_conf) 987 o = gk_cat(msg, o, " roster_organs=" as *u8); o = gk_catn(msg, o, nros[0]) 988 o = gk_cat(msg, o, " roster_sources_found=" as *u8); o = gk_catn(msg, o, ros_referrers) 989 o = gk_cat(msg, o, " registry_rows=" as *u8); o = gk_catn(msg, o, reg_rows) 990 o = gk_cat(msg, o, " gatereg_hits=" as *u8); o = gk_catn(msg, o, greg_hits) 991 o = gk_cat(msg, o, " gateroster_hits=" as *u8); o = gk_catn(msg, o, gros_hits) 992 if gros_live == 0 { o = gk_cat(msg, o, " groster_inert=1" as *u8) } 993 o = gk_cat(msg, o, " gates_maps=" as *u8); o = gk_catn(msg, o, gates1) 994 o = gk_cat(msg, o, "+" as *u8); o = gk_catn(msg, o, gates2) 995 o = gk_cat(msg, o, " actlog_window_bytes=" as *u8); o = gk_catn(msg, o, actwin[0]) 996 o = gk_cat(msg, o, " actlog_hits=" as *u8); o = gk_catn(msg, o, act_hits) 997 o = gk_cat(msg, o, " status_logs=" as *u8); o = gk_catn(msg, o, logs_seen) 998 o = gk_cat(msg, o, " roster_journal_rows=" as *u8); o = gk_catn(msg, o, jrnl_rows) 999 o = gk_cat(msg, o, " build_journal_rows=" as *u8); o = gk_catn(msg, o, bjrnl_rows) 1000 o = gk_cat(msg, o, "\n roster organs (clock live+desired planes + conf; * = source found in corpus):" as *u8) 1001 var ri: i64 = 0 1002 while ri < nros[0] { 1003 o = gk_cat(msg, o, " " as *u8) 1004 o = gk_cat(msg, o, ga_gslot(ros, ri)) 1005 var found: i64 = 0 1006 var rj: i64 = 0 1007 while rj < scanned { 1008 let cb: *u8 = ga_base(ga_cslot(names, rj)) 1009 if ga_eqrun(ga_gslot(ros, ri), cb, gk_len(cb) - 3) == 1 { found = 1; rj = scanned } else { rj = rj + 1 } 1010 } 1011 if found == 1 { o = gk_cat(msg, o, "*" as *u8) } 1012 ri = ri + 1 1013 } 1014 o = gk_cat(msg, o, "\n axes over gates: BUILT=" as *u8); o = gk_catn(msg, o, s_built) 1015 o = gk_cat(msg, o, " STAGED=" as *u8); o = gk_catn(msg, o, s_staged) 1016 o = gk_cat(msg, o, " PROMOTED=" as *u8); o = gk_catn(msg, o, s_prom) 1017 o = gk_cat(msg, o, " (root=" as *u8); o = gk_catn(msg, o, s_proot) 1018 o = gk_cat(msg, o, " _offc=" as *u8); o = gk_catn(msg, o, s_poffc) 1019 o = gk_cat(msg, o, " buildroot/_offc=" as *u8); o = gk_catn(msg, o, s_pbro); o = gk_cat(msg, o, ")" as *u8) 1020 o = gk_cat(msg, o, " REG=" as *u8); o = gk_catn(msg, o, s_reg) 1021 o = gk_cat(msg, o, " CLOCK=" as *u8); o = gk_catn(msg, o, s_clock) 1022 o = gk_cat(msg, o, " ROSTER=" as *u8); o = gk_catn(msg, o, s_roster) 1023 o = gk_cat(msg, o, " GATES=" as *u8); o = gk_catn(msg, o, s_gates) 1024 o = gk_cat(msg, o, " GATEREG=" as *u8); o = gk_catn(msg, o, s_greg) 1025 o = gk_cat(msg, o, " GROSTER=" as *u8); o = gk_catn(msg, o, s_gros) 1026 o = gk_cat(msg, o, " ACTLOG=" as *u8); o = gk_catn(msg, o, s_act) 1027 o = gk_cat(msg, o, " LOG=" as *u8); o = gk_catn(msg, o, s_log) 1028 o = gk_cat(msg, o, " REF=" as *u8); o = gk_catn(msg, o, s_ref) 1029 o = gk_cat(msg, o, " log_ambiguous=" as *u8); o = gk_catn(msg, o, ambig[0]) 1030 o = gk_cat(msg, o, " gatereg_ambiguous=" as *u8); o = gk_catn(msg, o, ambig[1]) 1031 o = gk_cat(msg, o, "\n PARTITION (one bucket per gate, by remedy):\n" as *u8) 1032 o = gk_cat(msg, o, " LIVE " as *u8); o = gk_catn(msg, o, n_live); o = gk_cat(msg, o, " invoked+promoted: verdict collected [latest roster/trial row FAILING=" as *u8) 1033 o = gk_catn(msg, o, n_live_fail); o = gk_cat(msg, o, " -- collected AND read: the alarm worklist]\n" as *u8) 1034 o = gk_cat(msg, o, " INVOKED-MISSING " as *u8); o = gk_catn(msg, o, n_gap); o = gk_cat(msg, o, " a surface names it, no binary anywhere: build+promote (a GAP)\n" as *u8) 1035 o = gk_cat(msg, o, " DEPLOYED-DARK " as *u8); o = gk_catn(msg, o, n_dark); o = gk_cat(msg, o, " promoted, no surface runs it: wire to a roster or retire [registered=" as *u8) 1036 o = gk_catn(msg, o, n_dark_reg); o = gk_cat(msg, o, " has_status_log=" as *u8); o = gk_catn(msg, o, n_dark_log); o = gk_cat(msg, o, " named_by_a_source=" as *u8); o = gk_catn(msg, o, n_dark_ref); o = gk_cat(msg, o, "]\n" as *u8) 1037 o = gk_cat(msg, o, " by trial (latest gateroster.jrnl row): untried=" as *u8); o = gk_catn(msg, o, n_dark_untried) 1038 o = gk_cat(msg, o, " passing=" as *u8); o = gk_catn(msg, o, n_dark_pass); o = gk_cat(msg, o, " (one `admit` from LIVE) failing=" as *u8); o = gk_catn(msg, o, n_dark_fail) 1039 o = gk_cat(msg, o, " (RED/ABSENT/TIMEOUT: a defect worklist, not a wiring one) sum=" as *u8); o = gk_catn(msg, o, n_dark_untried + n_dark_pass + n_dark_fail) 1040 if n_dark_untried + n_dark_pass + n_dark_fail == n_dark { o = gk_cat(msg, o, " == dark\n" as *u8) } 1041 if n_dark_untried + n_dark_pass + n_dark_fail != n_dark { o = gk_cat(msg, o, " != dark: LEAK\n" as *u8) } 1042 o = gk_cat(msg, o, " BUILT-UNPROMOTED " as *u8); o = gk_catn(msg, o, n_bup); o = gk_cat(msg, o, " compiled only: promote or retire the build\n" as *u8) 1043 o = gk_cat(msg, o, " by built-artifact trial (gatebuild.jrnl): untried=" as *u8); o = gk_catn(msg, o, n_bup_untried) 1044 o = gk_cat(msg, o, " passing=" as *u8); o = gk_catn(msg, o, n_bup_pass); o = gk_cat(msg, o, " (promote candidates WITH evidence) failing=" as *u8); o = gk_catn(msg, o, n_bup_fail) 1045 o = gk_cat(msg, o, " (fix or retire) sum=" as *u8); o = gk_catn(msg, o, n_bup_untried + n_bup_pass + n_bup_fail) 1046 if n_bup_untried + n_bup_pass + n_bup_fail == n_bup { o = gk_cat(msg, o, " == built_unprom\n" as *u8) } 1047 if n_bup_untried + n_bup_pass + n_bup_fail != n_bup { o = gk_cat(msg, o, " != built_unprom: LEAK\n" as *u8) } 1048 o = gk_cat(msg, o, " SOURCE-ONLY " as *u8); o = gk_catn(msg, o, n_src); o = gk_cat(msg, o, " no artifact: REFERENCED=" as *u8) 1049 o = gk_catn(msg, o, n_src_ref); o = gk_cat(msg, o, " (something names its .elf: adjudicate) UNREFERENCED=" as *u8); o = gk_catn(msg, o, n_src_unref); o = gk_cat(msg, o, " (nothing in the corpus names it: retire candidates)\n" as *u8) 1050 o = gk_cat(msg, o, " SUM " as *u8); o = gk_catn(msg, o, part_sum) 1051 if part_sum == ng { o = gk_cat(msg, o, " == gate_sources: partition RECONCILES\n" as *u8) } 1052 if part_sum != ng { o = gk_cat(msg, o, " != gate_sources: PARTITION LEAK -- do not plan against these numbers\n" as *u8) } 1053 o = gk_cat(msg, o, " BLIND SPOTS (declared): off-host rosters/hooks only via " as *u8); o = gk_cat(msg, o, GA_ROSTERS) 1054 if ros_conf < 0 { o = gk_cat(msg, o, " (ABSENT: laptop-rostered gates read as REF-only here)" as *u8) } 1055 o = gk_cat(msg, o, "; ACTLOG is a tail window; ROSTER edges are static 2-hop.\n" as *u8) 1056 o = gk_cat(msg, o, " UNINVOKED (the lane-B worklist) = DEPLOYED-DARK + BUILT-UNPROMOTED + SOURCE-ONLY = " as *u8) 1057 o = gk_catn(msg, o, n_dark + n_bup + n_src) 1058 o = gk_cat(msg, o, "\n" as *u8) 1059 gk_say(msg, o) 1060 1061 // ---- clusters: first name token after the prefix; counts per bucket; sorted by uninvoked desc ---- 1062 let ck: *u8 = sys_mmap(GA_MAXCLU * GA_GSLOT) 1063 let cn: *i64 = sys_mmap(GA_MAXCLU * 8) as *i64 // gates in cluster 1064 let c1: *i64 = sys_mmap(GA_MAXCLU * 8) as *i64 // live 1065 let c3: *i64 = sys_mmap(GA_MAXCLU * 8) as *i64 // dark 1066 let c4: *i64 = sys_mmap(GA_MAXCLU * 8) as *i64 // built-unpromoted 1067 let c5: *i64 = sys_mmap(GA_MAXCLU * 8) as *i64 // source-only 1068 let creg: *i64 = sys_mmap(GA_MAXCLU * 8) as *i64 // registered 1069 var ncl: i64 = 0 1070 var clu_floor: i64 = 0 1071 let tok: *u8 = sys_mmap(GA_GSLOT) 1072 gi = 0 1073 while gi < ng { 1074 let nm: *u8 = ga_gslot(gn, gi) 1075 let so: i64 = ga_stemoff(nm) 1076 var t: i64 = 0 1077 var ft: i64 = 0 1078 while ft == 0 { 1079 if nm[so + t] == (0 as u8) { ft = 1 } 1080 if ft == 0 { if nm[so + t] == (95 as u8) { ft = 1 } else { if t < GA_GSLOT - 2 { tok[t] = nm[so + t] } t = t + 1 } } 1081 } 1082 if t > GA_GSLOT - 2 { t = GA_GSLOT - 2 } 1083 tok[t] = 0 as u8 1084 var idx: i64 = 0 - 1 1085 var j: i64 = 0 1086 while j < ncl { if gk_streq(ga_gslot(ck, j), tok) == 1 { idx = j; j = ncl } else { j = j + 1 } } 1087 if idx < 0 { 1088 if ncl < GA_MAXCLU { 1089 let dst: *u8 = ga_gslot(ck, ncl) 1090 var q: i64 = 0 1091 while q <= t { dst[q] = tok[q]; q = q + 1 } 1092 idx = ncl 1093 ncl = ncl + 1 1094 } 1095 if idx < 0 { clu_floor = 1 } 1096 } 1097 if idx >= 0 { 1098 cn[idx] = cn[idx] + 1 1099 if g_class[gi] == 1 { c1[idx] = c1[idx] + 1 } 1100 if g_class[gi] == 3 { c3[idx] = c3[idx] + 1 } 1101 if g_class[gi] == 4 { c4[idx] = c4[idx] + 1 } 1102 if g_class[gi] == 5 { c5[idx] = c5[idx] + 1 } 1103 if g_reg[gi] > 0 { creg[idx] = creg[idx] + 1 } 1104 } 1105 gi = gi + 1 1106 } 1107 // selection sort of an index permutation by uninvoked = c3+c4+c5, descending 1108 let ord: *i64 = sys_mmap(GA_MAXCLU * 8) as *i64 1109 var oi: i64 = 0 1110 while oi < ncl { ord[oi] = oi; oi = oi + 1 } 1111 oi = 0 1112 while oi < ncl { 1113 var best: i64 = oi 1114 var oj: i64 = oi + 1 1115 while oj < ncl { 1116 let ub: i64 = c3[ord[best]] + c4[ord[best]] + c5[ord[best]] 1117 let uj: i64 = c3[ord[oj]] + c4[ord[oj]] + c5[ord[oj]] 1118 if uj > ub { best = oj } 1119 oj = oj + 1 1120 } 1121 let tmp: i64 = ord[oi] 1122 ord[oi] = ord[best] 1123 ord[best] = tmp 1124 oi = oi + 1 1125 } 1126 var singles: i64 = 0 1127 var sci: i64 = 0 1128 while sci < ncl { if cn[sci] == 1 { singles = singles + 1 } sci = sci + 1 } 1129 o = gk_cat(msg, 0, " CLUSTERS (first name token after the prefix): clusters=" as *u8); o = gk_catn(msg, o, ncl) 1130 o = gk_cat(msg, o, " singletons=" as *u8); o = gk_catn(msg, o, singles) 1131 if clu_floor == 1 { o = gk_cat(msg, o, " (TABLE FULL: cluster count is a FLOOR)" as *u8) } 1132 o = gk_cat(msg, o, " shown=" as *u8) 1133 var show: i64 = ncl 1134 if show > GA_CLUSHOW { show = GA_CLUSHOW } 1135 o = gk_catn(msg, o, show) 1136 o = gk_cat(msg, o, " (sorted by uninvoked desc; hidden clusters carry the remainder, see rows artifact)\n" as *u8) 1137 o = gk_cat(msg, o, " cluster|gates|live|dark|built_unprom|source_only|registered\n" as *u8) 1138 gk_say(msg, o) 1139 oi = 0 1140 var shown_gates: i64 = 0 1141 while oi < show { 1142 let c: i64 = ord[oi] 1143 o = gk_cat(msg, 0, " " as *u8) 1144 o = gk_cat(msg, o, ga_gslot(ck, c)); o = gk_cat(msg, o, "|" as *u8) 1145 o = gk_catn(msg, o, cn[c]); o = gk_cat(msg, o, "|" as *u8) 1146 o = gk_catn(msg, o, c1[c]); o = gk_cat(msg, o, "|" as *u8) 1147 o = gk_catn(msg, o, c3[c]); o = gk_cat(msg, o, "|" as *u8) 1148 o = gk_catn(msg, o, c4[c]); o = gk_cat(msg, o, "|" as *u8) 1149 o = gk_catn(msg, o, c5[c]); o = gk_cat(msg, o, "|" as *u8) 1150 o = gk_catn(msg, o, creg[c]); o = gk_cat(msg, o, "\n" as *u8) 1151 gk_say(msg, o) 1152 shown_gates = shown_gates + cn[c] 1153 oi = oi + 1 1154 } 1155 o = gk_cat(msg, 0, " (shown clusters cover " as *u8); o = gk_catn(msg, o, shown_gates) 1156 o = gk_cat(msg, o, " of " as *u8); o = gk_catn(msg, o, ng); o = gk_cat(msg, o, " gates; hidden clusters=" as *u8); o = gk_catn(msg, o, ncl - show); o = gk_cat(msg, o, ")\n" as *u8) 1157 gk_say(msg, o) 1158 1159 // ---- rows artifact (optional) ----------------------------------------------------------------- 1160 if rowsp != (0 as *u8) { 1161 let rb: *u8 = sys_mmap(GA_ROWCAP) 1162 var ro: i64 = gk_cat(rb, 0, "<!-- NX-DERIVED: regenerated artefact, not authored memory -->\n" as *u8) 1163 ro = gk_cat(rb, ro, "name|src|src_age_d|built|staged|prom|reg|clock|roster|gates|gatereg|groster|act|log|logage_d|ref|first_ref|trial|class\n" as *u8) 1164 var over: i64 = 0 1165 gi = 0 1166 while gi < ng { 1167 if ro + 1024 > GA_ROWCAP { over = 1; gi = ng } 1168 if over == 0 { 1169 ro = gk_cat(rb, ro, ga_gslot(gn, gi)); ro = gk_cat(rb, ro, "|" as *u8) 1170 if g_src[gi] == 1 { ro = gk_cat(rb, ro, "hdl|" as *u8) } 1171 if g_src[gi] == 2 { ro = gk_cat(rb, ro, "rt|" as *u8) } 1172 ro = gk_catn(rb, ro, g_srcage[gi]); ro = gk_cat(rb, ro, "|" as *u8) 1173 ro = ga_yn(rb, ro, g_built[gi]) 1174 ro = ga_yn(rb, ro, g_staged[gi]) 1175 var pm: i64 = 0 1176 if g_proot[gi] > 0 { pm = pm + 1 } 1177 if g_poffc[gi] > 0 { pm = pm + 2 } 1178 if g_pbro[gi] > 0 { pm = pm + 4 } 1179 ro = gk_catn(rb, ro, pm); ro = gk_cat(rb, ro, "|" as *u8) 1180 ro = ga_yn(rb, ro, g_reg[gi]) 1181 ro = ga_yn(rb, ro, g_clock[gi]) 1182 ro = ga_yn(rb, ro, g_roster[gi]) 1183 ro = ga_yn(rb, ro, g_gates[gi]) 1184 ro = ga_yn(rb, ro, g_greg[gi]) 1185 ro = ga_yn(rb, ro, g_gros[gi]) 1186 ro = ga_yn(rb, ro, g_act[gi]) 1187 ro = ga_yn(rb, ro, g_log[gi]) 1188 ro = gk_catn(rb, ro, g_logage[gi]); ro = gk_cat(rb, ro, "|" as *u8) 1189 ro = gk_catn(rb, ro, g_ref[gi]); ro = gk_cat(rb, ro, "|" as *u8) 1190 if g_ref1[gi] >= 0 { ro = gk_cat(rb, ro, ga_base(ga_cslot(names, g_ref1[gi]))) } 1191 if g_ref1[gi] < 0 { ro = gk_cat(rb, ro, "-" as *u8) } 1192 ro = gk_cat(rb, ro, "|" as *u8) 1193 if g_trial[gi] == 0 { ro = gk_cat(rb, ro, "-" as *u8) } 1194 if g_trial[gi] == 1 { ro = gk_cat(rb, ro, "GREEN" as *u8) } 1195 if g_trial[gi] == 2 { ro = gk_cat(rb, ro, "SKIP" as *u8) } 1196 if g_trial[gi] == 3 { ro = gk_cat(rb, ro, "RED" as *u8) } 1197 if g_trial[gi] == 4 { ro = gk_cat(rb, ro, "ABSENT" as *u8) } 1198 if g_trial[gi] == 5 { ro = gk_cat(rb, ro, "TIMEOUT" as *u8) } 1199 ro = gk_cat(rb, ro, "|" as *u8) 1200 if g_class[gi] == 1 { ro = gk_cat(rb, ro, "LIVE" as *u8) } 1201 if g_class[gi] == 2 { ro = gk_cat(rb, ro, "INVOKED-MISSING" as *u8) } 1202 if g_class[gi] == 3 { ro = gk_cat(rb, ro, "DEPLOYED-DARK" as *u8) } 1203 if g_class[gi] == 4 { ro = gk_cat(rb, ro, "BUILT-UNPROMOTED" as *u8) } 1204 if g_class[gi] == 5 { if g_ref[gi] > 0 { ro = gk_cat(rb, ro, "SOURCE-ONLY-REFERENCED" as *u8) } } 1205 if g_class[gi] == 5 { if g_ref[gi] == 0 { ro = gk_cat(rb, ro, "SOURCE-ONLY-UNREFERENCED" as *u8) } } 1206 ro = gk_cat(rb, ro, "\n" as *u8) 1207 gi = gi + 1 1208 } 1209 } 1210 if over == 1 { 1211 o = gk_cat(msg, 0, " rows: REFUSED -- artifact would exceed GA_ROWCAP; nothing written (a partial rows file reads as a whole one)\n" as *u8) 1212 gk_say(msg, o) 1213 } 1214 if over == 0 { 1215 rb[ro] = 0 as u8 1216 let w: i64 = gk_write(rowsp, rb) 1217 o = gk_cat(msg, 0, " rows: wrote=" as *u8); o = gk_catn(msg, o, w); o = gk_cat(msg, o, " of=" as *u8); o = gk_cat(msg, o, rowsp) 1218 o = gk_cat(msg, o, " rows_written=" as *u8); o = gk_catn(msg, o, ng); o = gk_cat(msg, o, "\n" as *u8) 1219 gk_say(msg, o) 1220 } 1221 } 1222 1223 // ---- class list (optional): the census emits its own worklists --------------------------------- 1224 var li: i64 = 0 1225 while li < nlists { 1226 let listcls: *u8 = listcls_a[li] as *u8 1227 let listp: *u8 = listp_a[li] as *u8 1228 li = li + 1 1229 var want: i64 = 0 1230 if gk_streq(listcls, "LIVE" as *u8) == 1 { want = 1 } 1231 if gk_streq(listcls, "INVOKED-MISSING" as *u8) == 1 { want = 2 } 1232 if gk_streq(listcls, "DEPLOYED-DARK" as *u8) == 1 { want = 3 } 1233 if gk_streq(listcls, "BUILT-UNPROMOTED" as *u8) == 1 { want = 4 } 1234 if gk_streq(listcls, "SOURCE-ONLY" as *u8) == 1 { want = 5 } 1235 // DEPLOYED-DARK sub-lists by trial verdict (the REASON travels with the count; a seat can pull the 1236 // failing worklist without re-deriving it from rows): 6 untried, 7 passing, 8 failing 1237 if gk_streq(listcls, "DARK-UNTRIED" as *u8) == 1 { want = 6 } 1238 if gk_streq(listcls, "DARK-PASSING" as *u8) == 1 { want = 7 } 1239 if gk_streq(listcls, "DARK-FAILING" as *u8) == 1 { want = 8 } 1240 if gk_streq(listcls, "LIVE-FAILING" as *u8) == 1 { want = 9 } 1241 // BUILT-UNPROMOTED by built-artifact trial; rows spelled `buildroot/_build/<n>.sov` so the runner 1242 // execs the built artifact in place (it appends .elf) -- journal these to gatebuild.jrnl, NOT the 1243 // roster journal: admit must never wire an undeployed artifact onto the beat. 1244 if gk_streq(listcls, "BUILT-UNTRIED" as *u8) == 1 { want = 10 } 1245 if gk_streq(listcls, "BUILT-PASSING" as *u8) == 1 { want = 11 } 1246 if gk_streq(listcls, "BUILT-FAILING" as *u8) == 1 { want = 12 } 1247 if want == 0 { 1248 o = gk_cat(msg, 0, " list: REFUSED -- unknown class (LIVE|INVOKED-MISSING|DEPLOYED-DARK|BUILT-UNPROMOTED|SOURCE-ONLY|DARK-UNTRIED|DARK-PASSING|DARK-FAILING|LIVE-FAILING|BUILT-UNTRIED|BUILT-PASSING|BUILT-FAILING)\n" as *u8) 1249 gk_say(msg, o) 1250 } 1251 if want > 0 { 1252 let lb: *u8 = sys_mmap(GA_ROWCAP) 1253 var lo2: i64 = gk_cat(lb, 0, "; NX-DERIVED by nx_gateadjudicate: class=" as *u8) 1254 lo2 = gk_cat(lb, lo2, listcls) 1255 lo2 = gk_cat(lb, lo2, " epoch=" as *u8); lo2 = gk_catn(lb, lo2, now) 1256 lo2 = gk_cat(lb, lo2, " -- one gate per line, nx_gate_roster_run trial/roster format\n" as *u8) 1257 var lcount: i64 = 0 1258 var withheld: i64 = 0 1259 gi = 0 1260 while gi < ng { 1261 var sel: i64 = 0 1262 if g_class[gi] == want { sel = 1 } 1263 if want == 6 { if g_class[gi] == 3 { if g_trial[gi] == 0 { sel = 1 } } } 1264 if want == 7 { if g_class[gi] == 3 { if g_trial[gi] == 1 { sel = 1 } } } 1265 if want == 7 { if g_class[gi] == 3 { if g_trial[gi] == 2 { sel = 1 } } } 1266 if want == 8 { if g_class[gi] == 3 { if g_trial[gi] >= 3 { sel = 1 } } } 1267 if want == 9 { if g_class[gi] == 1 { if g_trial[gi] >= 3 { sel = 1 } } } 1268 if want == 10 { if g_class[gi] == 4 { if g_btrial[gi] == 0 { sel = 1 } } } 1269 if want == 11 { if g_class[gi] == 4 { if g_btrial[gi] == 1 { sel = 1 } } } 1270 if want == 11 { if g_class[gi] == 4 { if g_btrial[gi] == 2 { sel = 1 } } } 1271 if want == 12 { if g_class[gi] == 4 { if g_btrial[gi] >= 3 { sel = 1 } } } 1272 if sel == 1 { 1273 var take: i64 = 1 1274 // SOURCE-ONLY feeds a retire campaign: never emit a source modified TODAY -- 1275 // a fresh artifact can be another seat's work in flight (measured law). 1276 if want == 5 { if g_srcage[gi] == 0 { take = 0; withheld = withheld + 1 } } 1277 if take == 1 { 1278 if lo2 + 256 < GA_ROWCAP { 1279 var builtrow: i64 = 0 1280 if want >= 10 { builtrow = 1 } 1281 if builtrow == 1 { lo2 = gk_cat(lb, lo2, GA_BUILT_PREFIX) } 1282 if builtrow == 0 { if g_proot[gi] == 0 { if g_poffc[gi] > 0 { lo2 = gk_cat(lb, lo2, "_offc/" as *u8) } } } 1283 if builtrow == 0 { if g_proot[gi] == 0 { if g_poffc[gi] == 0 { if g_pbro[gi] > 0 { lo2 = gk_cat(lb, lo2, "buildroot/_offc/" as *u8) } } } } 1284 lo2 = gk_cat(lb, lo2, ga_gslot(gn, gi)) 1285 if builtrow == 1 { lo2 = gk_cat(lb, lo2, GA_BUILT_SUFFIX) } 1286 lb[lo2] = 10 as u8 1287 lo2 = lo2 + 1 1288 lcount = lcount + 1 1289 } 1290 } 1291 } 1292 gi = gi + 1 1293 } 1294 lb[lo2] = 0 as u8 1295 let lw: i64 = gk_write(listp, lb) 1296 o = gk_cat(msg, 0, " list: class=" as *u8); o = gk_cat(msg, o, listcls) 1297 o = gk_cat(msg, o, " names=" as *u8); o = gk_catn(msg, o, lcount) 1298 if withheld > 0 { o = gk_cat(msg, o, " withheld_same_day=" as *u8); o = gk_catn(msg, o, withheld) } 1299 o = gk_cat(msg, o, " wrote=" as *u8); o = gk_catn(msg, o, lw) 1300 o = gk_cat(msg, o, " of=" as *u8); o = gk_cat(msg, o, listp) 1301 o = gk_cat(msg, o, "\n" as *u8) 1302 gk_say(msg, o) 1303 } 1304 } 1305 1306 if lists_dropped > 0 { 1307 o = gk_cat(msg, 0, " list: DROPPED " as *u8); o = gk_catn(msg, o, lists_dropped) 1308 o = gk_cat(msg, o, " --list spec(s) beyond GA_MAXLISTS -- not emitted, said so\n" as *u8) 1309 gk_say(msg, o) 1310 } 1311 1312 // ---- trend line (append-only; a level cannot express a trajectory) ------------------------------ 1313 let ln: *u8 = sys_mmap(1024) 1314 var lo: i64 = gk_cat(ln, 0, "epoch=" as *u8); lo = gk_catn(ln, lo, now) 1315 lo = gk_cat(ln, lo, " gates=" as *u8); lo = gk_catn(ln, lo, ng) 1316 lo = gk_cat(ln, lo, " live=" as *u8); lo = gk_catn(ln, lo, n_live) 1317 lo = gk_cat(ln, lo, " gap=" as *u8); lo = gk_catn(ln, lo, n_gap) 1318 lo = gk_cat(ln, lo, " dark=" as *u8); lo = gk_catn(ln, lo, n_dark) 1319 lo = gk_cat(ln, lo, " built_unprom=" as *u8); lo = gk_catn(ln, lo, n_bup) 1320 lo = gk_cat(ln, lo, " src_ref=" as *u8); lo = gk_catn(ln, lo, n_src_ref) 1321 lo = gk_cat(ln, lo, " src_unref=" as *u8); lo = gk_catn(ln, lo, n_src_unref) 1322 lo = gk_cat(ln, lo, " corpus=" as *u8); lo = gk_catn(ln, lo, scanned) 1323 lo = gk_cat(ln, lo, "\n" as *u8) 1324 ln[lo] = 0 as u8 1325 let ap: i64 = ga_appendline(GA_LOG, ln) 1326 o = gk_cat(msg, 0, " trend: appended=" as *u8); o = gk_catn(msg, o, ap); o = gk_cat(msg, o, " to " as *u8); o = gk_cat(msg, o, GA_LOG); o = gk_cat(msg, o, "\n" as *u8) 1327 gk_say(msg, o) 1328 return 0 1329}