code wiki / _hdl_build / nx_clobber_guard.nx

nx_clobber_guard.nx source

↩ module page · 60 lines · 3104 B

1// nx_clobber_guard.nx -- SOTA anti-clobber guard for dual-copy artifacts (acl lane, F744). 2// Content-reconciliation with OPTIMISTIC-CONCURRENCY / git-non-fast-forward semantics: compare two 3// SURFACE copies of one logical artifact (e.g. laptop SSOT vs NAS buildroot, or a store's two segments' 4// exports). A would-be push that OVERWRITES a DIVERGED target is REFUSED (exit 3) so the writer must 5// reconcile first -- never silent last-writer-wins. Byte-exact compare (same idiom as nx_drift_watch / 6// nx_stale_check byte compare), no crypto dependency, no hardware writes (Rule 26). 7// nx_clobber_guard cmp <pathA> <pathB> 8// Machine contract (exit code): 0 CONVERGED (safe to push) | 3 DIVERGED (would-clobber, refuse) | 9// 4 ABSENT (a surface is missing) | 2 usage. The stdout line carries the verdict + sizes for logs. 10// license_tier: ORIGINAL expect_exit: 0 11import "nx_syscalls.nx" 12import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 13const K_MAGIC_8388608: i64 = 8388608 14 15func cg_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 } 16// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 17// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 18// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 19// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 20func cg_wn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 } 21func cg_read(path: *u8, buf: *u8, cap: i64) -> i64 { 22 let fd: i64 = sys_openat_rd(path) 23 if fd < 0 { return 0 - 1 } 24 var n: i64 = 0 25 var go: i64 = 1 26 while go == 1 { 27 let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - n) 28 if r <= 0 { go = 0 } else { n = n + r } 29 if n >= cap { go = 0 } 30 } 31 sys_close(fd) 32 return n 33} 34func main(argc: i64, argv: *i64) -> i64 { 35 if argc < 4 { cg_w(2, "usage: nx_clobber_guard cmp <pathA> <pathB>\n" as *u8); sys_exit(2); return 2 } 36 let pa: *u8 = argv[2] as *u8 37 let pb: *u8 = argv[3] as *u8 38 let cap: i64 = K_MAGIC_8388608 39 let ba: *u8 = sys_mmap(cap) 40 let bb: *u8 = sys_mmap(cap) 41 let na: i64 = cg_read(pa, ba, cap) 42 let nb: i64 = cg_read(pb, bb, cap) 43 if na < 0 { cg_w(1, "RECONCILE verdict=ABSENT surface=A path=" as *u8); cg_w(1, pa); cg_w(1, "\n" as *u8); sys_exit(4); return 4 } 44 if nb < 0 { cg_w(1, "RECONCILE verdict=ABSENT surface=B path=" as *u8); cg_w(1, pb); cg_w(1, "\n" as *u8); sys_exit(4); return 4 } 45 var diverged: i64 = 0 46 if na != nb { diverged = 1 } else { 47 var i: i64 = 0 48 while i < na { if ba[i] != bb[i] { diverged = 1; i = na } else { i = i + 1 } } 49 } 50 cg_w(1, "RECONCILE a_bytes=" as *u8); cg_wn(1, na) 51 cg_w(1, " b_bytes=" as *u8); cg_wn(1, nb) 52 if diverged == 1 { 53 cg_w(1, " verdict=DIVERGED (would-clobber: reconcile before push -- git-non-fast-forward)\n" as *u8) 54 sys_exit(3) 55 return 3 56 } 57 cg_w(1, " verdict=CONVERGED\n" as *u8) 58 sys_exit(0) 59 return 0 60}