code wiki / (root) / nx_ident.nx

nx_ident.nx source

↩ module page · 223 lines · 9646 B

1// nx_ident.nx -- ARTIFACT IDENTITY ORACLE: "which binary is ACTUALLY running, 2// and does it match anything I built?" 3// 4// WHY THIS EXISTS (four self-corrections in one session, 2026-07-30): 5// 1. I debugged a "commit SEGV" in nx_mvault_walk for a long arc. There was 6// no bug. A promote that returned FETCH-FAIL had SUCCEEDED, a rollback 7// that died on a closed socket had ALSO applied, and the live elf ended up 8// at 156,572 B -- matching NEITHER my build (229,700) NOR .prev (193,788) 9// NOR .prev-vw02b (164,804). The symptom was a STALE ARTIFACT, not code. 10// 2. I declared a freshly-built mgmt binary "wedged on startup". An A/B on 11// throwaway ports cleared it; the real defect was elsewhere. 12// Both collapse to ONE missing capability: no cheap way to ask WHAT IS LIVE. 13// 14// ★★★★★LAW: BEFORE DEBUGGING A BEHAVIOUR, PROVE WHICH ARTIFACT IS EXECUTING. 15// A symptom is only evidence about the bytes that actually ran. 16// 17// THE VERDICT THAT MATTERS MOST is LIVE-MATCHES-NOTHING: the live binary is 18// byte-sized like no build, no .prev, and no banked variant. That is the 19// signature of a half-applied deploy/rollback -- exactly case (1) -- and it is 20// the state in which every downstream conclusion is worthless. It is reported 21// LOUDLY rather than folded into "stale", because its remedy is different: 22// stale means "promote"; matches-nothing means "STOP, establish provenance". 23// 24// nx_ident <organ-name> e.g. nx_ident nx_mvault_walk 25// 26// Reports live / staged / prev / every banked <name>.* variant with BYTES, and 27// a verdict. Read-only. license_tier: ORIGINAL No hw writes (Rule 26). 28 29import "nx_syscalls.nx" 30 31const ID_DIRBUF: i64 = 1048576 32const ID_MAXV: i64 = 64 // variants reported; overflow is DECLARED 33const ID_NAME: i64 = 256 34const ID_OUT: i64 = 65536 35const ID_SEEK_END: i64 = 2 36 37func id_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 38 39func id_cat(d: *u8, o: i64, s: *u8) -> i64 { 40 var p: i64 = o 41 var i: i64 = 0 42 while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } 43 return p 44} 45 46func id_ch(d: *u8, o: i64, c: i64) -> i64 { d[o] = c as u8; return o + 1 } 47 48func id_dec(d: *u8, o: i64, v: i64) -> i64 { 49 if v < 0 { return id_cat(d, o, "-1" as *u8) } 50 if v == 0 { d[o] = 48 as u8; return o + 1 } 51 let t: *u8 = sys_mmap(32) 52 var m: i64 = v 53 var k: i64 = 0 54 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 55 var p: i64 = o 56 var i: i64 = k - 1 57 while i >= 0 { d[p] = t[i]; p = p + 1; i = i - 1 } 58 sys_munmap(t, 32) 59 return p 60} 61 62// byte length of a file, or -1 when absent/unopenable 63func id_size(path: *u8) -> i64 { 64 let fd: i64 = sys_openat_rd(path) 65 if fd < 0 { return 0 - 1 } 66 let n: i64 = sys_lseek(fd, 0, ID_SEEK_END) 67 sys_close(fd) 68 return n 69} 70 71// does `name` start with `pfx`? 72func id_starts(name: *u8, pfx: *u8) -> i64 { 73 var i: i64 = 0 74 while pfx[i] != (0 as u8) { 75 if name[i] != pfx[i] { return 0 } 76 i = i + 1 77 } 78 return 1 79} 80 81func id_eq(a: *u8, b: *u8) -> i64 { 82 var i: i64 = 0 83 while 1 == 1 { 84 if a[i] != b[i] { return 0 } 85 if a[i] == (0 as u8) { return 1 } 86 i = i + 1 87 } 88 return 0 89} 90 91func main(argc: i64, argv: *i64) -> i64 { 92 if argc < 2 { 93 sys_write(2, "usage: nx_ident <organ-name>\n" as *u8, 29) 94 return 2 95 } 96 let nm: *u8 = (argv[1]) as *u8 97 98 // canonical roles 99 let live: *u8 = sys_mmap(ID_NAME) 100 let stag: *u8 = sys_mmap(ID_NAME) 101 let prev: *u8 = sys_mmap(ID_NAME) 102 var o1: i64 = id_cat(live, 0, nm); o1 = id_cat(live, o1, ".elf" as *u8); live[o1] = 0 as u8 103 var o2: i64 = id_cat(stag, 0, nm); o2 = id_cat(stag, o2, ".sov.elf.new" as *u8); stag[o2] = 0 as u8 104 var o3: i64 = id_cat(prev, 0, nm); o3 = id_cat(prev, o3, ".elf.prev" as *u8); prev[o3] = 0 as u8 105 106 let live_b: i64 = id_size(live) 107 let stag_b: i64 = id_size(stag) 108 let prev_b: i64 = id_size(prev) 109 110 // scan CWD for EVERY banked variant "<name>." so MATCHES-NOTHING is 111 // trustworthy -- a verdict that only checked 3 names could call a legit 112 // banked artifact "unknown". 113 let pfx: *u8 = sys_mmap(ID_NAME) 114 var op: i64 = id_cat(pfx, 0, nm); pfx[op] = 46 as u8; pfx[op + 1] = 0 as u8 115 let dbuf: *u8 = sys_mmap(ID_DIRBUF) 116 let vname: *i64 = sys_mmap(8 * ID_MAXV) as *i64 117 let vsize: *i64 = sys_mmap(8 * ID_MAXV) as *i64 118 let arena: *u8 = sys_mmap(ID_MAXV * ID_NAME) 119 var ao: i64 = 0 120 var nv: i64 = 0 121 var overflow: i64 = 0 122 var matched: i64 = 0 // live bytes equal some non-live artifact? 123 124 let dfd: i64 = sys_openat_rd("." as *u8) 125 if dfd >= 0 { 126 var done: i64 = 0 127 while done == 0 { 128 let nread: i64 = sys_getdents64(dfd, dbuf, ID_DIRBUF) 129 if nread <= 0 { done = 1 } else { 130 var off: i64 = 0 131 while off < nread { 132 let drec: *u8 = ((dbuf as i64) + off) as *u8 133 let reclen: i64 = dirent_reclen(drec) 134 let name: *u8 = dirent_name(drec) 135 if id_starts(name, pfx) == 1 { 136 if id_eq(name, live) == 0 { 137 if nv >= ID_MAXV { overflow = overflow + 1 } else { 138 let sz: i64 = id_size(name) 139 let dst: *u8 = ((arena as i64) + ao) as *u8 140 var c: i64 = 0 141 while name[c] != (0 as u8) { dst[c] = name[c]; c = c + 1 } 142 dst[c] = 0 as u8 143 vname[nv] = dst as i64 144 vsize[nv] = sz 145 ao = ao + c + 1 146 nv = nv + 1 147 if sz == live_b { if live_b > 0 { matched = matched + 1 } } 148 } 149 } 150 } 151 if reclen <= 0 { off = nread } else { off = off + reclen } 152 } 153 } 154 } 155 sys_close(dfd) 156 } 157 158 let out: *u8 = sys_mmap(ID_OUT) 159 var o: i64 = 0 160 o = id_cat(out, o, "=== nx_ident -- WHICH ARTIFACT IS ACTUALLY EXECUTING ===\norgan=" as *u8) 161 o = id_cat(out, o, nm) 162 o = id_cat(out, o, "\n live " as *u8); o = id_cat(out, o, live) 163 o = id_cat(out, o, " bytes=" as *u8); o = id_dec(out, o, live_b) 164 o = id_cat(out, o, "\n staged " as *u8); o = id_cat(out, o, stag) 165 o = id_cat(out, o, " bytes=" as *u8); o = id_dec(out, o, stag_b) 166 o = id_cat(out, o, "\n prev " as *u8); o = id_cat(out, o, prev) 167 o = id_cat(out, o, " bytes=" as *u8); o = id_dec(out, o, prev_b) 168 o = id_ch(out, o, 10) 169 o = id_cat(out, o, " banked variants=" as *u8); o = id_dec(out, o, nv) 170 if overflow > 0 { 171 o = id_cat(out, o, " OVERFLOW=" as *u8); o = id_dec(out, o, overflow) 172 o = id_cat(out, o, " (raise ID_MAXV; NOT a silent cap)" as *u8) 173 } 174 o = id_ch(out, o, 10) 175 var i: i64 = 0 176 while i < nv { 177 o = id_cat(out, o, " " as *u8) 178 o = id_cat(out, o, (vname[i]) as *u8) 179 o = id_cat(out, o, " bytes=" as *u8) 180 o = id_dec(out, o, vsize[i]) 181 if vsize[i] == live_b { if live_b > 0 { o = id_cat(out, o, " <== SAME SIZE AS LIVE" as *u8) } } 182 o = id_ch(out, o, 10) 183 i = i + 1 184 } 185 186 o = id_cat(out, o, "\nNX-IDENT verdict=" as *u8) 187 var rc: i64 = 0 188 if live_b < 0 { 189 o = id_cat(out, o, "NO-LIVE (nothing deployed under that name)\n" as *u8) 190 rc = 3 191 } else { 192 if live_b == stag_b { 193 o = id_cat(out, o, "LIVE-IS-STAGED -- the running bytes match the current build.\n" as *u8) 194 rc = 0 195 } else { 196 // ⚠SELF-CORRECTION 2026-07-30, caught by this tool ON ITS OWN FIRST 197 // RUN: /api/promote CONSUMES the staged .sov.elf.new, so a CORRECTLY 198 // promoted organ has no staged artifact to compare against. Calling 199 // that MATCHES-NOTHING conflated ABSENCE OF EVIDENCE with 200 // CONTRADICTORY EVIDENCE -- the exact error class this organ exists 201 // to prevent. UNVERIFIABLE is the honest verdict, and it is a 202 // DIFFERENT remedy: matches-nothing means "stop, establish 203 // provenance"; unverifiable means "the ecosystem kept no record". 204 // ★THE DEEPER GAP: promote DESTROYS the provenance record. The fix 205 // is a promote LEDGER -- the current mgmt already emits sha256 on 206 // promote, so nx_ident should verify live's digest against it. 207 if stag_b < 0 { 208 o = id_cat(out, o, "UNVERIFIABLE -- no staged build to compare against (promote consumes it). NOT evidence of a problem, and NOT proof of health: provenance simply was not recorded. Verify against the promote ledger sha256.\n" as *u8) 209 rc = 2 210 } else { 211 if matched > 0 { 212 o = id_cat(out, o, "LIVE-BEHIND-STAGED -- live matches a BANKED artifact but not the staged build; promote to ship it.\n" as *u8) 213 rc = 1 214 } else { 215 o = id_cat(out, o, "LIVE-MATCHES-NOTHING -- STOP. The running bytes match NO build, NO .prev and NO banked variant. This is the signature of a HALF-APPLIED deploy or rollback (a FETCH-FAIL/503 that actually succeeded). Every conclusion drawn from this binary's behaviour is unsound until provenance is re-established.\n" as *u8) 216 rc = 4 217 } 218 } 219 } 220 } 221 sys_write(1, out, o) 222 return rc 223}