code wiki / (root) / nx_drift_watch.nx

nx_drift_watch.nx source

↩ module page · 104 lines · 6905 B

1// nx_drift_watch.nx -- STANDING deploy-drift guardrail (zero-Claude, cron-run; arch-board 06:20 precedent). 2// The F-004 stale serve AND the compare-generator drifts both accumulated SILENTLY -- nothing watched for 3// "deployed binary lags its source" (esp. after a compiler/toolchain change, which staleness-flags EVERY 4// pre-fix binary). This daily check reads a data-driven watch-list and, per target, rebuilds it --build-only 5// and byte-compares to the deployed buildroot/_offc/<t>.elf (the SAME logic as nx_stale_check, INLINED to 6// stay single-nest -- a double-nested fork of nx_stale_check-of-nx_sov_build_run fails builds). Stub-trap 7// guarded (fresh<<deployed => AMBIGUOUS, not STALE). Logs verdicts + a tally to knowledge/status/drift_watch.log. 8// nx_drift_watch [listpath] [broot] list default knowledge/registry/drift_watch.list ; broot default buildroot 9// Exit 0 always (a guardrail never fails the fleet); the LOG carries the verdict. license_tier: ORIGINAL 10import "nx_tool_run.nx" 11const K_MAGIC_4096: i64 = 4096 12const K_MAGIC_65536: i64 = 65536 13const K_MAGIC_65535: i64 = 65535 14const K_MAGIC_8388608: i64 = 8388608 15 16func 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 } 17func wn(fd: i64, v: i64) -> i64 { var m: i64=v; if m<0{w(fd,"-" as *u8);m=0-m} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let o: *u8=sys_mmap(28); var i: i64=0; while i<k{o[i]=t[k-1-i];i=i+1} sys_write(fd,o,k); return 0 } 18func d_cat(dst: *u8, off: i64, src: *u8) -> i64 { var o: i64=off; var j: i64=0; while src[j]!=(0 as u8){dst[o]=src[j];o=o+1;j=j+1} return o } 19func d_read(path: *u8, buf: *u8, cap: i64) -> i64 { 20 let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 - 1 } 21 var n: i64 = 0; var go: i64 = 1 22 while go == 1 { let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap { go = 0 } } 23 sys_close(fd); return n 24} 25// returns 1 CURRENT, 2 STALE, 3 AMBIGUOUS, 4 BUILDFAIL, 5 NOELF, 6 NOSOURCE. writes fresh/dep sizes to sz[0]/sz[1]. 26func d_check(tgt: *u8, out: *u8, ocap: i64, ol: *i64, fb: *u8, db: *u8, fcap: i64, sz: *i64) -> i64 { 27 // source present? 28 let s1: *u8 = sys_mmap(256); var o1: i64 = d_cat(s1, 0, "runtime/" as *u8); o1 = d_cat(s1, o1, tgt); o1 = d_cat(s1, o1, ".nx" as *u8); s1[o1] = 0 as u8 29 let s2: *u8 = sys_mmap(256); var o2: i64 = d_cat(s2, 0, "runtime/_hdl_build/" as *u8); o2 = d_cat(s2, o2, tgt); o2 = d_cat(s2, o2, ".nx" as *u8); s2[o2] = 0 as u8 30 let f1: i64 = sys_openat_rd(s1); var have: i64 = 0; if f1 >= 0 { sys_close(f1); have = 1 } 31 if have == 0 { let f2: i64 = sys_openat_rd(s2); if f2 >= 0 { sys_close(f2); have = 1 } } 32 if have == 0 { return 6 } 33 // build --build-only (single nested fork -- the reliable pattern) 34 let av: *i64 = sys_mmap(64) as *i64 35 av[0] = "_offc/nx_sov_build_run.elf" as i64; av[1] = tgt as i64; av[2] = "--build-only" as i64; av[3] = 0 36 let rc: i64 = tr_run_capture("_offc/nx_sov_build_run.elf" as *u8, av, out, ocap, ol) 37 if rc != 0 { return 4 } 38 let fresh: *u8 = sys_mmap(256); var of: i64 = d_cat(fresh, 0, "/tmp/" as *u8); of = d_cat(fresh, of, tgt); of = d_cat(fresh, of, ".sov.elf" as *u8); fresh[of] = 0 as u8 39 let dep: *u8 = sys_mmap(256); var od: i64 = d_cat(dep, 0, "_offc/" as *u8); od = d_cat(dep, od, tgt); od = d_cat(dep, od, ".elf" as *u8); dep[od] = 0 as u8 40 let fn: i64 = d_read(fresh, fb, fcap) 41 let dn: i64 = d_read(dep, db, fcap) 42 sz[0] = fn; sz[1] = dn 43 if fn < 0 { return 4 } 44 if dn < 0 { return 5 } 45 if fn == dn { var i: i64 = 0; var same: i64 = 1; while i < fn { if fb[i] != db[i] { same = 0; i = fn } else { i = i + 1 } } if same == 1 { return 1 } } 46 if fn * 2 < dn { if fn < K_MAGIC_4096 { return 3 } } 47 return 2 48} 49 50func main(argc: i64, argv: *i64) -> i64 { 51 var listp: *u8 = "knowledge/registry/drift_watch.list" as *u8 52 if argc >= 2 { listp = argv[1] as *u8 } 53 var broot: *u8 = "buildroot" as *u8 54 if argc >= 3 { broot = argv[2] as *u8 } 55 56 let lst: *u8 = sys_mmap(K_MAGIC_65536) 57 let ln: i64 = d_read(listp, lst, K_MAGIC_65535) 58 if ln <= 0 { w(1, "nx_drift_watch: watch-list missing\n" as *u8); sys_exit(0); return 0 } 59 // resolve the log path BEFORE chdir (it is relative to the run cwd), then chdir into the build tree. 60 let lfd: i64 = sys_openat_append("knowledge/status/drift_watch.log" as *u8, 0x1a4) 61 if sys_chdir(broot) != 0 { w(1, "nx_drift_watch: cannot chdir build tree\n" as *u8); if lfd>=0 { sys_close(lfd) } sys_exit(0); return 0 } 62 63 let ocap: i64 = K_MAGIC_65536 64 let out: *u8 = sys_mmap(ocap) 65 let ol: *i64 = sys_mmap(16) as *i64 66 let fcap: i64 = K_MAGIC_8388608 67 let fb: *u8 = sys_mmap(fcap) 68 let db: *u8 = sys_mmap(fcap) 69 let sz: *i64 = sys_mmap(16) as *i64 70 let tgt: *u8 = sys_mmap(128) 71 72 var nstale: i64=0; var namb: i64=0; var ncur: i64=0; var noth: i64=0; var ntot: i64=0 73 var p: i64 = 0 74 while p < ln { 75 var q: i64 = p 76 while q < ln { if lst[q] == (10 as u8) { break } q = q + 1 } 77 var ti: i64 = 0; var s: i64 = p 78 while s < q { let c: i64 = lst[s]; if c == 13 { s = q } else { if ti < 120 { tgt[ti] = lst[s] as u8; ti = ti + 1 } s = s + 1 } } 79 tgt[ti] = 0 as u8 80 p = q + 1 81 if ti == 0 { } else { if tgt[0] == (35 as u8) { } else { 82 ntot = ntot + 1 83 let v: i64 = d_check(tgt, out, ocap, ol, fb, db, fcap, sz) 84 if v == 1 { ncur = ncur + 1 } else { 85 if v == 2 { nstale = nstale + 1 } else { if v == 3 { namb = namb + 1 } else { noth = noth + 1 } } 86 if lfd >= 0 { 87 w(lfd, " " as *u8) 88 if v == 2 { w(lfd, "STALE " as *u8) } else { if v == 3 { w(lfd, "AMBIGUOUS " as *u8) } else { if v == 4 { w(lfd, "BUILDFAIL " as *u8) } else { if v == 5 { w(lfd, "NOELF " as *u8) } else { w(lfd, "NOSOURCE " as *u8) } } } } 89 w(lfd, tgt); w(lfd, " (fresh=" as *u8); wn(lfd, sz[0]); w(lfd, " deployed=" as *u8); wn(lfd, sz[1]); w(lfd, ")\n" as *u8) 90 } 91 } 92 } } 93 } 94 if lfd >= 0 { 95 w(lfd, "DRIFT-WATCH epoch=" as *u8); wn(lfd, sys_now_realtime_sec()) 96 w(lfd, " checked=" as *u8); wn(lfd, ntot); w(lfd, " current=" as *u8); wn(lfd, ncur) 97 w(lfd, " STALE=" as *u8); wn(lfd, nstale); w(lfd, " ambiguous=" as *u8); wn(lfd, namb); w(lfd, " other=" as *u8); wn(lfd, noth) 98 if nstale > 0 { w(lfd, " verdict=DRIFT-DETECTED\n" as *u8) } else { w(lfd, " verdict=CLEAN\n" as *u8) } 99 sys_close(lfd) 100 } 101 w(1, "nx_drift_watch: checked=" as *u8); wn(1, ntot); w(1, " current=" as *u8); wn(1, ncur); w(1, " STALE=" as *u8); wn(1, nstale); w(1, " ambiguous=" as *u8); wn(1, namb); w(1, " other=" as *u8); wn(1, noth); w(1, "\n" as *u8) 102 sys_exit(0) 103 return 0 104}