code wiki / _hdl_build / nx_novel_close.nx

nx_novel_close.nx source

↩ module page · 748 lines · 35495 B

1// nx_novel_close.nx -- the INDEPENDENT REFEREE that CLOSES genuinely-built NOVEL 2// queue rows that nx_reconcile refuses to touch (NOVEL is never auto-flipped by 3// design: novel work is judged after the visit). A NOVEL row whose deliverable is 4// really built+gated cannot otherwise close, so its dependents stay FLOATING in 5// nx_capability_ladder. 6// 7// This organ adjudicates each candidate MECHANICALLY -- it does NOT trust the row's 8// stored ||MARK. Referee check per candidate (an auto_builder-emitted deliverable): 9// DELETE the deliverable .nx + _test.nx -> re-run nx_auto_builder from its 10// build-spec -> assert ALL of: (a) BOTH files RE-EMITTED, (b) builder exit==0 11// AND stdout carries the candidate's green marker "AUTO-BUILD GREEN: <name> 12// shape=<N> KAT green", (c) line 1 of the re-emitted primary .nx carries 13// "AUTHORED BY THE NISHI BUILDER" (proves author=organ, not a hand-written 14// false-green). Only ALL-PASS closes the row. A stale/hand-written deliverable 15// cannot survive deletion -> strongest no-false-green probe. The organ is NOT the 16// builder, so there is NO self-grade: it re-runs the team's own auto_builder and 17// reads the verdict. 18// 19// NOVEL is 5 bytes, DONE is 4 -> closing SHRINKS the line by 1 byte, so this is a 20// LENGTH-CHANGING line REWRITE (reconcile only does same-length 4-byte in-place 21// patches). We read the whole file, and for a referee-PASSED candidate row scoped 22// by (field1==id AND field6=="NOVEL") emit the prefix, write "DONE", then the rest 23// from after "NOVEL" (skip 5 src bytes, write 4). NEVER global-replace "NOVEL" 24// (other rows' descriptions contain it); field6 is located by tab position. 25// 26// BAKED SELF-TEST runs FIRST on a SCRATCH scenario (control_pos via the proven erf 27// pipeline MUST close; control_neg via a non-existent spec MUST NOT close); any 28// mismatch -> print RED + nonzero exit, real queue UNTOUCHED. Proves it cannot 29// false-close (sibling of nx_capability_ladder / nx_epic_rollup baked controls). 30// 31// argv[1] = queue-path override (scratch queue for dry-run; no side effects 32// beyond that named file -- like reconcile's is_live guard). No-arg => 33// LIVE: operates on knowledge/registry/assignment_queue.tsv (the only 34// run that writes the real queue) and writes a .bak first. 35// 36// SOVEREIGN ONLY (nx_cc->nxasm, no gcc/python/qemu). Additive/history-sacred: the 37// log is append-only; referee deletions are repaired by the re-emit (verified) or 38// restored from backup on FAIL. The referee execs /tmp/nx_auto_builder.sov.elf, so 39// the wrapper must build nx_auto_builder into /tmp in the SAME shell session. 40// license_tier: ORIGINAL 41// 42// module: nishi-core.autonomy.novel_close 43// depends: nishi-core.sys.syscalls 44// capability: NO_FLOAT_NOVEL_CLOSE_REFEREE 45import "nx_registry_lock.nx" // lib-only (pulls nx_syscalls transitively); gives rt_lock/rt_unlock + the SHARED queue lock 46import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 47const Q_MAGIC_262144: i64 = 262144 48const Q_MAGIC_65536: i64 = 65536 49const Q_MAGIC_4096: i64 = 4096 50 51const Q_CAP: i64 = 1048576 52const MAXCAND: i64 = 64 53 54func nc_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 55// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 56// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 57// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 58// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 59func nc_wn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 } 60func nc_len(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 61 62// unlinkat(AT_FDCWD, path, 0) -- x86_64 raw 263 passes through (fsync/74 precedent). 63func nc_unlink(path: *u8) -> i64 { return __syscall(263, AT_FDCWD, path, 0, 0, 0, 0) } 64 65func nc_read(path: *u8, buf: *u8, cap: i64) -> i64 { 66 let fd: i64 = sys_openat_rd(path) 67 if fd < 0 { return 0 } 68 var n: i64 = 0 69 var r: i64 = sys_read(fd, buf, cap - 1) 70 while r > 0 { n = n + r; if n >= cap - 1 { r = 0 } else { r = sys_read(fd, buf + n, cap - 1 - n) } } 71 sys_close(fd) 72 return n 73} 74 75func nc_exists(path: *u8) -> i64 { 76 let fd: i64 = sys_openat_rd(path) 77 if fd < 0 { return 0 } 78 sys_close(fd) 79 return 1 80} 81 82func nc_write_all(fd: i64, buf: *u8, len: i64) -> i64 { 83 var off: i64 = 0 84 while off < len { let w: i64 = sys_write(fd, buf + off, len - off); if w <= 0 { off = len } else { off = off + w } } 85 return 0 86} 87 88// copy src -> dst (whole file). 1 ok / 0 fail. 89func nc_copy(src: *u8, dst: *u8) -> i64 { 90 let buf: *u8 = sys_mmap(Q_CAP) 91 let rf: i64 = sys_openat_rd(src) 92 if rf < 0 { return 0 } 93 var n: i64 = 0 94 var r: i64 = sys_read(rf, buf, Q_CAP - 1) 95 while r > 0 { n = n + r; if n >= Q_CAP - 1 { r = 0 } else { r = sys_read(rf, buf + n, Q_CAP - 1 - n) } } 96 sys_close(rf) 97 let wf: i64 = sys_openat_wr(dst, 0x1a4) 98 if wf < 0 { return 0 } 99 nc_write_all(wf, buf, n) 100 sys_close(wf) 101 return 1 102} 103 104// substring search in buf[0,n) 105func nc_contains(buf: *u8, n: i64, needle: *u8) -> i64 { 106 let nl: i64 = nc_len(needle) 107 if nl == 0 { return 1 } 108 var i: i64 = 0 109 while i + nl <= n { 110 var k: i64 = 0 111 var ok: i64 = 1 112 while k < nl { if buf[i+k] != needle[k] { ok = 0; k = nl } else { k = k + 1 } } 113 if ok == 1 { return 1 } 114 i = i + 1 115 } 116 return 0 117} 118 119// exact byte-match of pat (len pl) at buf+i 120func nc_at(buf: *u8, n: i64, i: i64, pat: *u8, pl: i64) -> i64 { 121 if i + pl > n { return 0 } 122 var k: i64 = 0 123 while k < pl { if buf[i+k] != pat[k] { return 0 } k = k + 1 } 124 return 1 125} 126 127// concat s into dst at off (null-terminates); returns new off 128func nc_cat(dst: *u8, off: i64, s: *u8) -> i64 { 129 var o: i64 = off; var i: i64 = 0 130 while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } 131 dst[o] = 0 as u8 132 return o 133} 134func nc_path_d(dst: *u8, name: *u8) -> i64 { 135 var o: i64 = nc_cat(dst, 0, "runtime/_hdl_build/" as *u8); o = nc_cat(dst, o, name); o = nc_cat(dst, o, ".nx" as *u8); return o 136} 137func nc_path_t(dst: *u8, name: *u8) -> i64 { 138 var o: i64 = nc_cat(dst, 0, "runtime/_hdl_build/" as *u8); o = nc_cat(dst, o, name); o = nc_cat(dst, o, "_test.nx" as *u8); return o 139} 140 141// REFEREE RE-VERIFY: delete D+T -> exec /tmp/nx_auto_builder.sov.elf <spec> 142// (stdout -> /tmp/_nc_ab_out.log, stderr silenced) -> assert (a) BOTH re-emitted, 143// (b) exit==0 AND green marker in stdout, (c) AUTHORED-BY header on D line1. 144// Returns 1 PASS / 0 FAIL. On FAIL restores D+T from backup so a transient builder 145// failure never leaves a real capability deleted (additive / history-sacred). 146func nc_referee(name: *u8, spec: *u8, green: *u8) -> i64 { 147 let dpath: *u8 = sys_mmap(512); nc_path_d(dpath, name) 148 let tpath: *u8 = sys_mmap(512); nc_path_t(tpath, name) 149 let dbak: *u8 = "/tmp/_nc_d.bak" as *u8 150 let tbak: *u8 = "/tmp/_nc_t.bak" as *u8 151 let had_d: i64 = nc_exists(dpath); if had_d == 1 { nc_copy(dpath, dbak) } 152 let had_t: i64 = nc_exists(tpath); if had_t == 1 { nc_copy(tpath, tbak) } 153 // no-false-green probe: DELETE both deliverables 154 nc_unlink(dpath) 155 nc_unlink(tpath) 156 // re-run the team's auto_builder, stdout -> outlog, stderr -> /dev/null 157 let outlog: *u8 = "/tmp/_nc_ab_out.log" as *u8 158 let pid: i64 = sys_fork() 159 if pid == 0 { 160 let of: i64 = sys_openat_wr(outlog, 0x1a4) 161 if of >= 0 { sys_dup3(of, 1, 0) } 162 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 163 if dn >= 0 { sys_dup3(dn, 2, 0) } 164 let lane: *u8 = "/tmp/nx_auto_builder.sov.elf" as *u8 165 let argv: *i64 = sys_mmap(32) as *i64 166 argv[0] = lane as i64 167 argv[1] = spec as i64 168 argv[2] = 0 169 let envp: *i64 = sys_mmap(16) as *i64 170 envp[0] = 0 171 sys_execve(lane, argv, envp) 172 sys_exit(127) 173 } 174 let st: *i64 = sys_mmap(16) as *i64 175 sys_wait4(pid, st, 0) 176 let ec: i64 = wait_exit_code(st[0]) 177 // (a) BOTH re-emitted 178 let re_d: i64 = nc_exists(dpath) 179 let re_t: i64 = nc_exists(tpath) 180 // (b) green marker in builder stdout 181 let outbuf: *u8 = sys_mmap(Q_MAGIC_262144) 182 let on: i64 = nc_read(outlog, outbuf, Q_MAGIC_262144) 183 let has_green: i64 = nc_contains(outbuf, on, green) 184 // (c) AUTHORED-BY header on line 1 of re-emitted D 185 var has_hdr: i64 = 0 186 if re_d == 1 { 187 let dbuf: *u8 = sys_mmap(Q_MAGIC_262144) 188 let dn2: i64 = nc_read(dpath, dbuf, Q_MAGIC_262144) 189 // line-1 length = bytes up to the first '\n' (the header must be on line 1). 190 var l1: i64 = 0 191 var nl: i64 = dn2 192 var s: i64 = 0 193 while s < dn2 { if dbuf[s] == (10 as u8) { nl = s; s = dn2 } else { s = s + 1 } } 194 l1 = nl 195 has_hdr = nc_contains(dbuf, l1, "AUTHORED BY THE NISHI BUILDER" as *u8) 196 } 197 var pass: i64 = 0 198 if re_d == 1 { if re_t == 1 { if ec == 0 { if has_green == 1 { if has_hdr == 1 { pass = 1 } } } } } 199 if pass == 0 { 200 if had_d == 1 { nc_copy(dbak, dpath) } 201 if had_t == 1 { nc_copy(tbak, tpath) } 202 } 203 return pass 204} 205 206// RUN-referee (for a NOVEL row whose deliverable is NOT auto_builder-emitted -- e.g. a 207// re-instrumented measurement organ like nx_cms_wp_scorecard). REBUILD+RUN the organ via 208// ./_offc/nx_sov_build_run.elf (independent: the closer is not the organ's author, and it 209// rebuilds from source + runs fresh -- no trust of stored state), capture stdout, and assert 210// BOTH the candidate's green substring AND "run-exit=0" appear. Returns 1 PASS / 0 FAIL. 211// No deletion/restore needed (it does not mutate the deliverable; it rebuilds it). 212func nc_referee_run(organ: *u8, green: *u8) -> i64 { 213 let outlog: *u8 = "/tmp/_nc_run_out.log" as *u8 214 let pid: i64 = sys_fork() 215 if pid == 0 { 216 let of: i64 = sys_openat_wr(outlog, 0x1a4) 217 if of >= 0 { sys_dup3(of, 1, 0) } 218 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 219 if dn >= 0 { sys_dup3(dn, 2, 0) } 220 let lane: *u8 = "./_offc/nx_sov_build_run.elf" as *u8 221 let argv: *i64 = sys_mmap(32) as *i64 222 argv[0] = lane as i64 223 argv[1] = organ as i64 224 argv[2] = 0 225 let envp: *i64 = sys_mmap(16) as *i64 226 envp[0] = 0 227 sys_execve(lane, argv, envp) 228 sys_exit(127) 229 } 230 let st: *i64 = sys_mmap(16) as *i64 231 sys_wait4(pid, st, 0) 232 let outbuf: *u8 = sys_mmap(Q_MAGIC_262144) 233 let on: i64 = nc_read(outlog, outbuf, Q_MAGIC_262144) 234 var pass: i64 = 0 235 if nc_contains(outbuf, on, green) == 1 { 236 if nc_contains(outbuf, on, "run-exit=0" as *u8) == 1 { pass = 1 } 237 } 238 return pass 239} 240 241// ---- helpers for the DEPS-DONE referee ---- 242// exact equality of the field starting at fstart (bounded by next tab or line_end) to s[0,sl). 243func nc_field_eq(buf: *u8, fstart: i64, line_end: i64, s: *u8, sl: i64) -> i64 { 244 var fend: i64 = fstart 245 var d: i64 = 0 246 while d == 0 { 247 if fend >= line_end { d = 1 } else { if buf[fend] == (9 as u8) { d = 1 } else { fend = fend + 1 } } 248 } 249 if fend - fstart != sl { return 0 } 250 var k: i64 = 0 251 while k < sl { if buf[fstart+k] != s[k] { return 0 } k = k + 1 } 252 return 1 253} 254 255// does the dep field [dep_off, next-tab-or-line_end) contain id as a whole SPACE-separated 256// token? Handles single-dep (token == whole field) AND multi-dep ("A B C"); token-bounded so 257// "R4-H2-001" never substring-matches "R4-H2-0011" (the no-false-close guard for this referee). 258func nc_dep_has_token(buf: *u8, dep_off: i64, line_end: i64, id: *u8, idl: i64) -> i64 { 259 var dep_end: i64 = dep_off 260 var d: i64 = 0 261 while d == 0 { 262 if dep_end >= line_end { d = 1 } else { if buf[dep_end] == (9 as u8) { d = 1 } else { dep_end = dep_end + 1 } } 263 } 264 var ts: i64 = dep_off 265 var p: i64 = dep_off 266 var found: i64 = 0 267 while p <= dep_end { 268 var sep: i64 = 0 269 if p == dep_end { sep = 1 } else { if buf[p] == (32 as u8) { sep = 1 } } 270 if sep == 1 { 271 if p - ts == idl { 272 var k: i64 = 0 273 var eq: i64 = 1 274 while k < idl { if buf[ts+k] != id[k] { eq = 0; k = idl } else { k = k + 1 } } 275 if eq == 1 { found = 1 } 276 } 277 ts = p + 1 278 } 279 p = p + 1 280 } 281 return found 282} 283 284// DEPS-DONE referee: for a SPEC/umbrella NOVEL row with NO code deliverable (e.g. the HTTP/2 285// ladder spec R4-H2-001). The spec is "realized" exactly when EVERY queue row that names it 286// as a dep (field7) is DONE (field6). Mechanical: the closer SCANS the live queue and runs 287// NOTHING -- no organ, no self-grade. Requires >=1 child (never vacuously closes a childless 288// row). Returns 1 PASS (>=1 child, ALL DONE) / 0 FAIL. Reusable rule-11 for any umbrella/spec 289// row -> serves the no-float + anti-Frankenstein (X-GEN-005) law. 290func nc_referee_deps(id: *u8, qpath: *u8) -> i64 { 291 let buf: *u8 = sys_mmap(Q_CAP) 292 let n: i64 = nc_read(qpath, buf, Q_CAP) 293 if n <= 0 { return 0 } 294 let idl: i64 = nc_len(id) 295 var children: i64 = 0 296 var not_done: i64 = 0 297 var ls: i64 = 0 298 var i: i64 = 0 299 while i <= n { 300 var eol: i64 = 0 301 if i == n { eol = 1 } else { if buf[i] == (10 as u8) { eol = 1 } } 302 if eol == 1 { 303 if i > ls { 304 var tabs: i64 = 0 305 var p: i64 = ls 306 var st_off: i64 = 0 - 1 307 var dep_off: i64 = 0 - 1 308 while p < i { 309 if buf[p] == (9 as u8) { 310 tabs = tabs + 1 311 if tabs == 5 { st_off = p + 1 } 312 if tabs == 6 { dep_off = p + 1 } 313 } 314 p = p + 1 315 } 316 if dep_off >= 0 { if st_off >= 0 { 317 if nc_dep_has_token(buf, dep_off, i, id, idl) == 1 { 318 children = children + 1 319 if nc_field_eq(buf, st_off, i, "DONE" as *u8, 4) != 1 { not_done = not_done + 1 } 320 } 321 } } 322 } 323 ls = i + 1 324 } 325 i = i + 1 326 } 327 if children >= 1 { if not_done == 0 { return 1 } } 328 return 0 329} 330 331// FILECHECK referee (for a NOVEL row whose deliverable is a FETCHED/GENERATED FILE carrying a 332// content marker -- e.g. a research-substrate doc fetched by _dlr_fetch_one). Reads the file at 333// <path> (field3) and asserts it contains <anchor> (field4) -- the NOVEL-row twin of reconcile's 334// ||MARK file-content check (reconcile refuses NOVEL). A failed/blocked fetch writes no anchor 335// (error/empty page lacks the distinctive anchor) -> cannot false-close. Returns 1 PASS / 0 FAIL. 336func nc_referee_file(path: *u8, anchor: *u8) -> i64 { 337 let buf: *u8 = sys_mmap(Q_CAP) 338 let n: i64 = nc_read(path, buf, Q_CAP) 339 if n <= 0 { return 0 } 340 if nc_contains(buf, n, anchor) == 1 { return 1 } 341 return 0 342} 343 344// In queue buf, locate a line where field1==id AND field6=="NOVEL". On hit sets 345// *line_start to that line offset and returns 1; else 0. Exact full-field equality 346// (bounded by tabs), never prefix; field6 = char after the 5th tab. 347func nc_find_novel(buf: *u8, n: i64, id: *u8, line_start: *i64) -> i64 { 348 let idl: i64 = nc_len(id) 349 var ls: i64 = 0 350 var i: i64 = 0 351 while i <= n { 352 var eol: i64 = 0 353 if i == n { eol = 1 } else { if buf[i] == (10 as u8) { eol = 1 } } 354 if eol == 1 { 355 var f1ok: i64 = 0 356 if ls + idl < i { 357 if nc_at(buf, n, ls, id, idl) == 1 { if buf[ls+idl] == (9 as u8) { f1ok = 1 } } 358 } 359 if f1ok == 1 { 360 var tabs: i64 = 0 361 var p: i64 = ls 362 var fs: i64 = 0 - 1 363 while p < i { 364 if buf[p] == (9 as u8) { tabs = tabs + 1; if tabs == 5 { fs = p + 1; p = i } } 365 p = p + 1 366 } 367 if fs >= 0 { 368 if nc_at(buf, n, fs, "NOVEL\t" as *u8, 6) == 1 { *line_start = ls; return 1 } 369 } 370 } 371 ls = i + 1 372 } 373 i = i + 1 374 } 375 return 0 376} 377 378// Locate the field6 status start offset for the line at line_start (5th tab + 1). 379func nc_status_off(buf: *u8, n: i64, line_start: i64) -> i64 { 380 var p: i64 = line_start 381 var tabs: i64 = 0 382 while p < n { 383 if buf[p] == (10 as u8) { return 0 - 1 } 384 if buf[p] == (9 as u8) { tabs = tabs + 1; if tabs == 5 { return p + 1 } } 385 p = p + 1 386 } 387 return 0 - 1 388} 389 390// Close the candidate id in queue file qpath IFF currently NOVEL. Assumes referee 391// already PASSED. Whole-file rewrite: [0,sstart) + "DONE" + [sstart+5, n). 392// Returns 1 if a line was rewritten, else 0. 393func nc_write_close(qpath: *u8, id: *u8) -> i64 { 394 let buf: *u8 = sys_mmap(Q_CAP) 395 let n: i64 = nc_read(qpath, buf, Q_CAP) 396 if n <= 0 { return 0 } 397 let lsp: *i64 = sys_mmap(16) as *i64 398 lsp[0] = 0 - 1 399 if nc_find_novel(buf, n, id, lsp) != 1 { return 0 } 400 let sstart: i64 = nc_status_off(buf, n, lsp[0]) 401 if sstart < 0 { return 0 } 402 if nc_at(buf, n, sstart, "NOVEL" as *u8, 5) != 1 { return 0 } 403 let wf: i64 = sys_openat_wr(qpath, 0x1a4) 404 if wf < 0 { return 0 } 405 nc_write_all(wf, buf, sstart) 406 nc_write_all(wf, "DONE" as *u8, 4) 407 nc_write_all(wf, buf + sstart + 5, n - sstart - 5) 408 sys_close(wf) 409 return 1 410} 411 412// Process the queue against a candidate set. For each candidate found NOVEL, run 413// the referee; on PASS, rewrite NOVEL->DONE and log. Re-reads the file fresh per 414// candidate (lengths shift after a close). Returns flips, or -1 if queue missing. 415func nc_process(qpath: *u8, ids: *i64, specs: *i64, names: *i64, greens: *i64, 416 ncand: i64, do_log: i64, lfd: i64) -> i64 { 417 let buf: *u8 = sys_mmap(Q_CAP) 418 let n0: i64 = nc_read(qpath, buf, Q_CAP) 419 if n0 <= 0 { return 0 - 1 } 420 var flips: i64 = 0 421 var c: i64 = 0 422 while c < ncand { 423 let id: *u8 = ids[c] as *u8 424 // fresh read each candidate 425 let qn: i64 = nc_read(qpath, buf, Q_CAP) 426 let lsp: *i64 = sys_mmap(16) as *i64 427 lsp[0] = 0 - 1 428 if nc_find_novel(buf, qn, id, lsp) == 1 { 429 let name: *u8 = names[c] as *u8 430 let spec: *u8 = specs[c] as *u8 431 let green: *u8 = greens[c] as *u8 432 // referee type (DATA-driven by spec field): "RUN" -> RUN-referee (rebuild+run 433 // organ=name); "DEPSDONE" -> DEPS-DONE referee (spec row closes when every row that 434 // deps on it is DONE); else REEMIT-referee (delete+re-emit auto_builder deliverable). 435 var is_run: i64 = 0 436 if nc_len(spec) == 3 { if spec[0] == (82 as u8) { if spec[1] == (85 as u8) { if spec[2] == (78 as u8) { is_run = 1 } } } } 437 var is_deps: i64 = 0 438 if nc_len(spec) == 8 { if spec[0] == (68 as u8) { if spec[1] == (69 as u8) { if spec[2] == (80 as u8) { if spec[3] == (83 as u8) { if spec[4] == (68 as u8) { if spec[5] == (79 as u8) { if spec[6] == (78 as u8) { if spec[7] == (69 as u8) { is_deps = 1 } } } } } } } } } 439 var is_file: i64 = 0 440 if nc_len(spec) == 9 { if spec[0] == (70 as u8) { if spec[1] == (73 as u8) { if spec[2] == (76 as u8) { if spec[3] == (69 as u8) { if spec[4] == (67 as u8) { if spec[5] == (72 as u8) { if spec[6] == (69 as u8) { if spec[7] == (67 as u8) { if spec[8] == (75 as u8) { is_file = 1 } } } } } } } } } } 441 var passr: i64 = 0 442 if is_run == 1 { passr = nc_referee_run(name, green) } else { if is_deps == 1 { passr = nc_referee_deps(id, qpath) } else { if is_file == 1 { passr = nc_referee_file(name, green) } else { passr = nc_referee(name, spec, green) } } } 443 if passr == 1 { 444 // serialize the live-queue RMW against the beat + other side-organs via the SHARED 445 // queue lock (qpath + ".lock"); degrade-gracefully on giveup (-1) so the close never 446 // wedges (O_EXCL stale-steal bounds a crashed holder to 30s). [nx_registry_lock] 447 let nclkp: *u8 = sys_mmap(512) 448 nc_cat(nclkp, nc_cat(nclkp, 0, qpath), ".lock" as *u8) 449 let nclkfd: i64 = rt_lock(nclkp) 450 if nc_write_close(qpath, id) == 1 { 451 flips = flips + 1 452 nc_w(1, "NOVELCLOSE-FLIP row=" as *u8); nc_w(1, id) 453 if is_run == 1 { nc_w(1, " referee=RUN-GREEN verdict=CLOSED\n" as *u8) } else { if is_deps == 1 { nc_w(1, " referee=DEPSDONE-GREEN verdict=CLOSED\n" as *u8) } else { if is_file == 1 { nc_w(1, " referee=FILECHECK-GREEN verdict=CLOSED\n" as *u8) } else { nc_w(1, " referee=REEMIT-GREEN verdict=CLOSED\n" as *u8) } } } 454 if do_log == 1 { if lfd >= 0 { 455 nc_w(lfd, "NOVELCLOSE row=" as *u8); nc_w(lfd, id) 456 if is_run == 1 { nc_w(lfd, " referee=RUN-GREEN verdict=CLOSED\n" as *u8) } else { if is_deps == 1 { nc_w(lfd, " referee=DEPSDONE-GREEN verdict=CLOSED\n" as *u8) } else { if is_file == 1 { nc_w(lfd, " referee=FILECHECK-GREEN verdict=CLOSED\n" as *u8) } else { nc_w(lfd, " referee=REEMIT-GREEN verdict=CLOSED\n" as *u8) } } } 457 } } 458 } 459 if nclkfd >= 0 { rt_unlock(nclkp, nclkfd) } 460 } else { 461 nc_w(1, "NOVELCLOSE-SKIP row=" as *u8); nc_w(1, id) 462 nc_w(1, " referee=FAIL (not closed, deliverable intact)\n" as *u8) 463 } 464 } 465 c = c + 1 466 } 467 return flips 468} 469 470// Load knowledge/registry/novel_close.tsv: lines "id<TAB>spec<TAB>name<TAB>green"; 471// '#'-prefixed lines skipped. Fills parallel id/spec/name/green pools; returns count. 472func nc_load_candidates(ids: *i64, specs: *i64, names: *i64, greens: *i64) -> i64 { 473 let buf: *u8 = sys_mmap(Q_MAGIC_65536) 474 let n: i64 = nc_read("knowledge/registry/novel_close.tsv" as *u8, buf, Q_MAGIC_65536) 475 if n <= 0 { return 0 } 476 var cnt: i64 = 0 477 var ls: i64 = 0 478 var i: i64 = 0 479 while i <= n { 480 var eol: i64 = 0 481 if i == n { eol = 1 } else { if buf[i] == (10 as u8) { eol = 1 } } 482 if eol == 1 { 483 if i > ls { if buf[ls] != (35 as u8) { 484 if cnt < MAXCAND { 485 let fid: *u8 = sys_mmap(256) 486 let fsp: *u8 = sys_mmap(512) 487 let fnm: *u8 = sys_mmap(256) 488 let fgr: *u8 = sys_mmap(512) 489 var field: i64 = 0 490 var k: i64 = 0 491 var p: i64 = ls 492 while p < i { 493 if buf[p] == (9 as u8) { field = field + 1; k = 0 } else { 494 if field == 0 { fid[k] = buf[p]; fid[k+1] = 0 as u8 } 495 if field == 1 { fsp[k] = buf[p]; fsp[k+1] = 0 as u8 } 496 if field == 2 { fnm[k] = buf[p]; fnm[k+1] = 0 as u8 } 497 if field == 3 { fgr[k] = buf[p]; fgr[k+1] = 0 as u8 } 498 k = k + 1 499 } 500 p = p + 1 501 } 502 if field >= 3 { 503 ids[cnt] = fid as i64; specs[cnt] = fsp as i64 504 names[cnt] = fnm as i64; greens[cnt] = fgr as i64 505 cnt = cnt + 1 506 } 507 } 508 } } 509 ls = i + 1 510 } 511 i = i + 1 512 } 513 return cnt 514} 515 516// ===================== BAKED SELF-TEST ===================== 517// control_pos: scratch queue NOVEL row SELFTEST-POS mapped to the PROVEN erf 518// pipeline (real spec/deliverable) -> referee GREEN -> MUST close (closed==1). 519// control_neg: scratch NOVEL row SELFTEST-NEG mapped to a NON-EXISTENT spec -> 520// auto_builder REFUSED (exit!=0, no green) -> MUST NOT close (closed==0). 521// Runs on /tmp scratch queues; the real erf deliverable is backed up + restored. 522func nc_write_scratch_queue(path: *u8, status_line: *u8) -> i64 { 523 let fd: i64 = sys_openat_wr(path, 0x1a4) 524 if fd < 0 { return 0 } 525 nc_w(fd, status_line) 526 sys_close(fd) 527 return 1 528} 529 530// self-sufficiency: the REEMIT referee/control execs the PREBUILT /tmp/nx_auto_builder.sov.elf 531// (the now-gone autorun daemon used to keep it fresh). Build it if absent (the tp_run "heal" 532// pattern) so nx_novel_close never refuses-live just because that artifact is missing. 1 if present. 533func nc_ensure_auto_builder() -> i64 { 534 if nc_exists("/tmp/nx_auto_builder.sov.elf" as *u8) == 1 { return 1 } 535 let pid: i64 = sys_fork() 536 if pid == 0 { 537 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 538 if dn >= 0 { sys_dup3(dn, 1, 0); sys_dup3(dn, 2, 0) } 539 let lane: *u8 = "./_offc/nx_sov_build_run.elf" as *u8 540 let argv: *i64 = sys_mmap(32) as *i64 541 argv[0] = lane as i64; argv[1] = "nx_auto_builder" as *u8 as i64; argv[2] = 0 542 let envp: *i64 = sys_mmap(16) as *i64; envp[0] = 0 543 sys_execve(lane, argv, envp) 544 sys_exit(127) 545 } 546 let st: *i64 = sys_mmap(16) as *i64 547 sys_wait4(pid, st, 0) 548 return nc_exists("/tmp/nx_auto_builder.sov.elf" as *u8) 549} 550 551func nc_selftest() -> i64 { 552 nc_ensure_auto_builder() // ensure the REEMIT control's prebuilt elf exists -> self-sufficient 553 let erf_d: *u8 = "runtime/_hdl_build/_ab_mk_erf.nx" as *u8 554 let erf_t: *u8 = "runtime/_hdl_build/_ab_mk_erf_test.nx" as *u8 555 let erf_d_bak: *u8 = "/tmp/_nc_st_erf_d.bak" as *u8 556 let erf_t_bak: *u8 = "/tmp/_nc_st_erf_t.bak" as *u8 557 let had_d: i64 = nc_exists(erf_d); if had_d == 1 { nc_copy(erf_d, erf_d_bak) } 558 let had_t: i64 = nc_exists(erf_t); if had_t == 1 { nc_copy(erf_t, erf_t_bak) } 559 560 let ids: *i64 = sys_mmap(8 * 4) as *i64 561 let specs: *i64 = sys_mmap(8 * 4) as *i64 562 let names: *i64 = sys_mmap(8 * 4) as *i64 563 let greens: *i64 = sys_mmap(8 * 4) as *i64 564 565 // ---- control_pos ---- 566 let qp: *u8 = "/tmp/_nc_st_pos.tsv" as *u8 567 nc_write_scratch_queue(qp, "SELFTEST-POS\tX\t9\tM\tBuilder\tNOVEL\tnone\tgate\tselftest pos row\n" as *u8) 568 ids[0] = "SELFTEST-POS" as *u8 as i64 569 specs[0] = "runtime/_hdl_build/_ab_mk_erf.spec" as *u8 as i64 570 names[0] = "_ab_mk_erf" as *u8 as i64 571 greens[0] = "AUTO-BUILD GREEN: _ab_mk_erf shape=11 KAT green" as *u8 as i64 572 nc_process(qp, ids, specs, names, greens, 1, 0, 0 - 1) 573 let pbuf: *u8 = sys_mmap(Q_MAGIC_4096) 574 let pn: i64 = nc_read(qp, pbuf, Q_MAGIC_4096) 575 var pos_closed: i64 = 0 576 if nc_contains(pbuf, pn, "\tDONE\t" as *u8) == 1 { pos_closed = 1 } 577 578 // ---- control_neg ---- (non-existent spec -> referee FAIL -> no close) 579 let qn: *u8 = "/tmp/_nc_st_neg.tsv" as *u8 580 nc_write_scratch_queue(qn, "SELFTEST-NEG\tX\t9\tM\tBuilder\tNOVEL\tnone\tgate\tselftest neg row\n" as *u8) 581 ids[0] = "SELFTEST-NEG" as *u8 as i64 582 specs[0] = "knowledge/specs/_NO_SUCH_SPEC_selftest.spec" as *u8 as i64 583 names[0] = "_nc_selftest_neg" as *u8 as i64 584 greens[0] = "AUTO-BUILD GREEN: _nc_selftest_neg" as *u8 as i64 585 nc_process(qn, ids, specs, names, greens, 1, 0, 0 - 1) 586 let nbuf: *u8 = sys_mmap(Q_MAGIC_4096) 587 let nn: i64 = nc_read(qn, nbuf, Q_MAGIC_4096) 588 var neg_closed: i64 = 1 589 if nc_contains(nbuf, nn, "\tNOVEL\t" as *u8) == 1 { neg_closed = 0 } 590 if nc_contains(nbuf, nn, "\tDONE\t" as *u8) == 1 { neg_closed = 1 } 591 592 // ---- control_run_pos ---- (RUN-referee: organ emits the green -> MUST close) 593 let qrp: *u8 = "/tmp/_nc_st_runpos.tsv" as *u8 594 nc_write_scratch_queue(qrp, "SELFTEST-RUNPOS\tX\t9\tM\tBuilder\tNOVEL\tnone\tgate\tselftest run pos\n" as *u8) 595 ids[0] = "SELFTEST-RUNPOS" as *u8 as i64 596 specs[0] = "RUN" as *u8 as i64 597 names[0] = "nx_cms_wp_scorecard" as *u8 as i64 598 greens[0] = "verdict=MEASURED" as *u8 as i64 599 nc_process(qrp, ids, specs, names, greens, 1, 0, 0 - 1) 600 let rpbuf: *u8 = sys_mmap(Q_MAGIC_4096) 601 let rpn: i64 = nc_read(qrp, rpbuf, Q_MAGIC_4096) 602 var runpos_closed: i64 = 0 603 if nc_contains(rpbuf, rpn, "\tDONE\t" as *u8) == 1 { runpos_closed = 1 } 604 605 // ---- control_run_neg ---- (RUN-referee: green absent -> MUST NOT close) 606 let qrn: *u8 = "/tmp/_nc_st_runneg.tsv" as *u8 607 nc_write_scratch_queue(qrn, "SELFTEST-RUNNEG\tX\t9\tM\tBuilder\tNOVEL\tnone\tgate\tselftest run neg\n" as *u8) 608 ids[0] = "SELFTEST-RUNNEG" as *u8 as i64 609 specs[0] = "RUN" as *u8 as i64 610 names[0] = "nx_cms_wp_scorecard" as *u8 as i64 611 greens[0] = "ZZ_NEVER_APPEARS_RUNNEG" as *u8 as i64 612 nc_process(qrn, ids, specs, names, greens, 1, 0, 0 - 1) 613 let rnbuf: *u8 = sys_mmap(Q_MAGIC_4096) 614 let rnn: i64 = nc_read(qrn, rnbuf, Q_MAGIC_4096) 615 var runneg_closed: i64 = 1 616 if nc_contains(rnbuf, rnn, "\tNOVEL\t" as *u8) == 1 { runneg_closed = 0 } 617 if nc_contains(rnbuf, rnn, "\tDONE\t" as *u8) == 1 { runneg_closed = 1 } 618 619 // ---- control_deps_pos ---- (DEPS-DONE: spec row whose only child is DONE -> MUST close) 620 let qdp: *u8 = "/tmp/_nc_st_depspos.tsv" as *u8 621 nc_write_scratch_queue(qdp, "SPECPOS\tX\t9\tM\tPM\tNOVEL\t-\tspec\tumbrella spec row\nCHILDPOS\tX\t9\tM\tBuilder\tDONE\tSPECPOS\tgate\tchild built\n" as *u8) 622 ids[0] = "SPECPOS" as *u8 as i64 623 specs[0] = "DEPSDONE" as *u8 as i64 624 names[0] = "-" as *u8 as i64 625 greens[0] = "-" as *u8 as i64 626 nc_process(qdp, ids, specs, names, greens, 1, 0, 0 - 1) 627 let dpbuf: *u8 = sys_mmap(Q_MAGIC_4096) 628 let dpn: i64 = nc_read(qdp, dpbuf, Q_MAGIC_4096) 629 let dplsp: *i64 = sys_mmap(16) as *i64 630 dplsp[0] = 0 - 1 631 var deps_pos_closed: i64 = 0 632 if nc_find_novel(dpbuf, dpn, "SPECPOS" as *u8, dplsp) == 0 { deps_pos_closed = 1 } 633 634 // ---- control_deps_neg ---- (DEPS-DONE: spec row whose child is still NOVEL -> MUST NOT close) 635 let qdn2: *u8 = "/tmp/_nc_st_depsneg.tsv" as *u8 636 nc_write_scratch_queue(qdn2, "SPECNEG\tX\t9\tM\tPM\tNOVEL\t-\tspec\tumbrella spec row\nCHILDNEG\tX\t9\tM\tBuilder\tNOVEL\tSPECNEG\tgate\tchild not built\n" as *u8) 637 ids[0] = "SPECNEG" as *u8 as i64 638 specs[0] = "DEPSDONE" as *u8 as i64 639 names[0] = "-" as *u8 as i64 640 greens[0] = "-" as *u8 as i64 641 nc_process(qdn2, ids, specs, names, greens, 1, 0, 0 - 1) 642 let dnbuf: *u8 = sys_mmap(Q_MAGIC_4096) 643 let dnn2: i64 = nc_read(qdn2, dnbuf, Q_MAGIC_4096) 644 let dnlsp: *i64 = sys_mmap(16) as *i64 645 dnlsp[0] = 0 - 1 646 var deps_neg_closed: i64 = 0 647 if nc_find_novel(dnbuf, dnn2, "SPECNEG" as *u8, dnlsp) == 0 { deps_neg_closed = 1 } 648 649 // ---- control_file_pos ---- (FILECHECK: deliverable file carries anchor -> MUST close) 650 let qfp: *u8 = "/tmp/_nc_st_filepos.tsv" as *u8 651 nc_write_scratch_queue(qfp, "FILEPOS\tX\t9\tM\tResearcher\tNOVEL\t-\tgate\tfile pos row\n" as *u8) 652 nc_write_scratch_queue("/tmp/_nc_st_file_pos.txt" as *u8, "header line\nWhen MARKER appears here exactly\nfooter line\n" as *u8) 653 ids[0] = "FILEPOS" as *u8 as i64 654 specs[0] = "FILECHECK" as *u8 as i64 655 names[0] = "/tmp/_nc_st_file_pos.txt" as *u8 as i64 656 greens[0] = "When MARKER appears here exactly" as *u8 as i64 657 nc_process(qfp, ids, specs, names, greens, 1, 0, 0 - 1) 658 let fpbuf: *u8 = sys_mmap(Q_MAGIC_4096) 659 let fpn: i64 = nc_read(qfp, fpbuf, Q_MAGIC_4096) 660 var file_pos_closed: i64 = 0 661 if nc_contains(fpbuf, fpn, "\tDONE\t" as *u8) == 1 { file_pos_closed = 1 } 662 663 // ---- control_file_neg ---- (FILECHECK: anchor absent in file -> MUST NOT close) 664 let qfn2: *u8 = "/tmp/_nc_st_fileneg.tsv" as *u8 665 nc_write_scratch_queue(qfn2, "FILENEG\tX\t9\tM\tResearcher\tNOVEL\t-\tgate\tfile neg row\n" as *u8) 666 nc_write_scratch_queue("/tmp/_nc_st_file_neg.txt" as *u8, "header line\nno marker present at all here\nfooter line\n" as *u8) 667 ids[0] = "FILENEG" as *u8 as i64 668 specs[0] = "FILECHECK" as *u8 as i64 669 names[0] = "/tmp/_nc_st_file_neg.txt" as *u8 as i64 670 greens[0] = "ZZ_NEVER_IN_FILE_NEG" as *u8 as i64 671 nc_process(qfn2, ids, specs, names, greens, 1, 0, 0 - 1) 672 let fnbuf: *u8 = sys_mmap(Q_MAGIC_4096) 673 let fnn2: i64 = nc_read(qfn2, fnbuf, Q_MAGIC_4096) 674 var file_neg_closed: i64 = 1 675 if nc_contains(fnbuf, fnn2, "\tNOVEL\t" as *u8) == 1 { file_neg_closed = 0 } 676 if nc_contains(fnbuf, fnn2, "\tDONE\t" as *u8) == 1 { file_neg_closed = 1 } 677 678 // restore the real erf deliverable regardless (history sacred) 679 if had_d == 1 { nc_copy(erf_d_bak, erf_d) } 680 if had_t == 1 { nc_copy(erf_t_bak, erf_t) } 681 682 nc_w(1, "SELFTEST control_pos=" as *u8); nc_wn(1, pos_closed) 683 nc_w(1, " control_neg=" as *u8); nc_wn(1, neg_closed) 684 nc_w(1, " control_run_pos=" as *u8); nc_wn(1, runpos_closed) 685 nc_w(1, " control_run_neg=" as *u8); nc_wn(1, runneg_closed) 686 nc_w(1, " control_deps_pos=" as *u8); nc_wn(1, deps_pos_closed) 687 nc_w(1, " control_deps_neg=" as *u8); nc_wn(1, deps_neg_closed) 688 nc_w(1, " control_file_pos=" as *u8); nc_wn(1, file_pos_closed) 689 nc_w(1, " control_file_neg=" as *u8); nc_wn(1, file_neg_closed) 690 var allok: i64 = 0 691 if pos_closed == 1 { if neg_closed == 0 { if runpos_closed == 1 { if runneg_closed == 0 { if deps_pos_closed == 1 { if deps_neg_closed == 0 { if file_pos_closed == 1 { if file_neg_closed == 0 { allok = 1 } } } } } } } } 692 if allok == 1 { nc_w(1, " verdict=GREEN\n" as *u8); return 1 } 693 nc_w(1, " verdict=RED\n" as *u8) 694 return 0 695} 696 697func main(argc: i64, argv: *i64) -> i64 { 698 // 1) BAKED SELF-TEST FIRST -- abort (no real-queue write) on any control mismatch. 699 if nc_selftest() == 0 { 700 nc_w(1, "NOVELCLOSE verdict=RED reason=selftest-failed (real queue UNTOUCHED)\n" as *u8) 701 sys_exit(7); return 7 702 } 703 704 // 2) target queue + live-ness 705 var qp: *u8 = "knowledge/registry/assignment_queue.tsv" as *u8 706 var is_live: i64 = 1 707 if argc >= 2 { qp = argv[1] as *u8; is_live = 0 } 708 709 // 3) LIVE run: write .bak of the real queue BEFORE any mutation 710 if is_live == 1 { 711 nc_copy("knowledge/registry/assignment_queue.tsv" as *u8, 712 "knowledge/registry/assignment_queue.tsv.bak" as *u8) 713 } 714 715 // 4) load DATA candidate table 716 let ids: *i64 = sys_mmap(8 * MAXCAND) as *i64 717 let specs: *i64 = sys_mmap(8 * MAXCAND) as *i64 718 let names: *i64 = sys_mmap(8 * MAXCAND) as *i64 719 let greens: *i64 = sys_mmap(8 * MAXCAND) as *i64 720 let ncand: i64 = nc_load_candidates(ids, specs, names, greens) 721 nc_w(1, "NOVELCLOSE candidates=" as *u8); nc_wn(1, ncand) 722 nc_w(1, " queue=" as *u8); nc_w(1, qp) 723 if is_live == 1 { nc_w(1, " mode=LIVE\n" as *u8) } else { nc_w(1, " mode=DRYRUN\n" as *u8) } 724 725 // 5) durable log (append-only) -- only LIVE runs append durable history 726 var lfd: i64 = 0 - 1 727 var do_log: i64 = 0 728 if is_live == 1 { 729 lfd = sys_openat_append("knowledge/status/novel_close.log" as *u8, 0x1a4) 730 do_log = 1 731 } 732 733 let flips: i64 = nc_process(qp, ids, specs, names, greens, ncand, do_log, lfd) 734 if flips < 0 { 735 nc_w(1, "NOVELCLOSE verdict=RED reason=queue-missing\n" as *u8) 736 sys_exit(101); return 101 737 } 738 739 nc_w(1, "NOVELCLOSE closed=" as *u8); nc_wn(1, flips) 740 nc_w(1, " verdict=GREEN epoch=" as *u8); nc_wn(1, sys_now_realtime_sec()); nc_w(1, "\n" as *u8) 741 if do_log == 1 { if lfd >= 0 { 742 nc_w(lfd, "NOVELCLOSE closed=" as *u8); nc_wn(lfd, flips) 743 nc_w(lfd, " verdict=GREEN epoch=" as *u8); nc_wn(lfd, sys_now_realtime_sec()); nc_w(lfd, "\n" as *u8) 744 sys_close(lfd) 745 } } 746 sys_exit(0) 747 return 0 748}