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}