code wiki / (root) / nx_refdrift.nx

nx_refdrift.nx source

↩ module page · 600 lines · 33275 B

1// nx_refdrift.nx -- DOES THE URL STILL SERVE THE BYTES WE PINNED? The refs referee proves the mirror matches 2// its pin, which is a claim about OUR disk. It says so about itself in its own verdict note: "fetch-time 3// provenance proves the mirror is OF the url. It does NOT prove the url still serves those bytes." This 4// organ closes that residual, and it exists because the gap was measured the hard way on 2026-09-04: two 5// pinned standards had MOVED upstream since they were fetched, and a seat only discovered it by re-fetching 6// them for an unrelated reason. A CITATION THAT DRIFTS SILENTLY IS A CLAIM WITH AN EXPIRY DATE NOBODY 7// RECORDED -- the pin still matches the mirror, the mirror still matches the pin, and the source has changed. 8// 9// IT COMPARES BYTES, NOT HASHES, AND THAT IS DELIBERATE. The refs referee already proves pin == filehash of 10// the mirror, so the mirror IS the pinned bytes. Re-fetching and byte-comparing against the mirror therefore 11// answers the drift question exactly, with no second hash implementation to drift from the first. One ruler. 12// 13// IT IS BOUNDED BY CONSTRUCTION AND SAYS SO. The operator's standing law is that hammering the estate is a 14// defect in its own right, so this organ takes ONE refs file and a MAXIMUM number of rows per run, both from 15// argv, and it PRINTS the bound beside the result. A run that stops at its cap declares checked and total, so 16// a partial pass can never read as a clean sweep -- the self-ceiling defect this estate names as law L011. 17// 18// nx_refdrift check <refsfile> [max] -> per-row MATCH / DRIFTED / UNREACHABLE, plus a summing partition 19// nx_refdrift selftest -> teeth, exit 0 GREEN / 1 RED 20// Exit: 0 no drift found | 1 DRIFTED rows exist | 2 usage | 3 UNREADABLE refs file. verdict= is LAST. 21// license_tier: ORIGINAL. Forks the sovereign fetcher, writes one reused temp mirror. No hw writes (Rule 26). 22import "nx_syscalls.nx" 23import "nx_tool_run.nx" 24import "nx_rowparse_lib.nx" 25import "nx_mirrorintegrity_lib.nx" 26 27const RD_EXIT_OK: i64 = 0 28const RD_EXIT_DRIFT: i64 = 1 29const RD_EXIT_USAGE: i64 = 2 30const RD_EXIT_UNREAD: i64 = 3 31const RD_SPAN: i64 = 8 32const RD_OUT: i64 = 262144 33const RD_REFS_CAP: i64 = 1048576 34const RD_BODY_CAP: i64 = 8388608 35const RD_FETCH_OUT: i64 = 65536 36const RD_PATH: i64 = 4096 37const RD_SEEK_END: i64 = 2 38// DEFAULT ROWS PER RUN. Derived, not picked: a refs file averages a dozen rows and each check is one network 39// fetch, so a full small file fits in one pass while a large one is covered across runs. Override with argv. 40const RD_MAX_DEFAULT: i64 = 12 41const RD_COL_KEY: i64 = 1 42const RD_COL_URL: i64 = 3 43const RD_COL_MIRROR: i64 = 4 44const RD_ARGV_SLOTS: i64 = 4 45const RD_PROBE: *u8 = "knowledge/fetched/refdrift_probe.tmp" 46const RD_FETCHER: *u8 = "nx_research_fetch.elf" 47const RD_PROBE_NAME: *u8 = "refdrift_probe.tmp" 48const RD_PROBE_B: *u8 = "knowledge/fetched/refdrift_probe_b.tmp" 49const RD_PROBE_B_NAME: *u8 = "refdrift_probe_b.tmp" 50 51// whole-file read, sized from the file so there is no cap to guess and no short read to miss 52func rd_slurp(path: *u8, buf: *u8, cap: i64) -> i64 { 53 let fd: i64 = sys_openat_rd(path) 54 if fd < 0 { return 0 - 1 } 55 let sz: i64 = sys_lseek(fd, 0, RD_SEEK_END) 56 if sz < 0 { sys_close(fd); return 0 - 1 } 57 if sz > cap { sys_close(fd); return 0 - 2 } 58 sys_lseek(fd, 0, 0) 59 let n: i64 = sys_read(fd, buf, sz) 60 sys_close(fd) 61 return n 62} 63// 1 if the two byte ranges are identical 64 65// ---- RECITE (2026-09-05): consume the refs gate's MOVED worklist ---- 66// `MOVED <dom>.refs <key> <mirror> <canonical>` rows (space-separated, written by nx_compare_refs_gate). For each one: 67// fetch the CANONICAL url into the probe and classify it; refuse a body the completeness classifier calls truncated or 68// suspect (the mirror is untouched); dry-run prints WOULD-RECITE; apply fetches again under the mirror's OWN name so the 69// fetcher journals fresh provenance for that mirror, hashes it with the ONE hasher, and rewrites the row's url, pin and 70// accessed columns in place (temp + rename). Every row prints its own verdict and the run is bounded like check. 71const RD_SPACE: i64 = 32 72const RD_WL_COL_DOM: i64 = 1 73const RD_WL_COL_KEY: i64 = 2 74const RD_WL_COL_MIRROR: i64 = 3 75const RD_WL_COL_CANON: i64 = 4 76const RD_COL_PIN: i64 = 5 77const RD_COL_ACCESSED: i64 = 6 78const RD_REFS_DIR: *u8 = "buildroot/knowledge/compare/" 79const RD_HASHER: *u8 = "nx_filehash.elf" 80const RD_SHA_TAG: *u8 = "sha256" 81const RD_JSON_QCQ: i64 = 3 82const RD_HEXLEN: i64 = 64 83const RD_TMP_SUFFIX: *u8 = ".recite.tmp" 84const RD_WL_TAG: *u8 = "MOVED" 85// optional argv `key=<k>`: only that worklist row is tried (the others are counted as skipped_by_filter), so an apply 86// can be selective -- a canonical that lands on a HOMEPAGE re-cites a specific claim to a landing page and needs a read first 87const RD_KEYARG: *u8 = "key=" 88// civil date from epoch seconds (Hinnant's civil_from_days) for the accessed column; every constant is the algorithm's own 89const RD_SECS_PER_DAY: i64 = 86400 90const RD_DAYS_EPOCH_TO_ERA0: i64 = 719468 91const RD_DAYS_PER_ERA: i64 = 146097 92const RD_ERA_YEARS: i64 = 400 93const RD_DOE_4Y: i64 = 1460 94const RD_DOE_100Y: i64 = 36524 95const RD_DOE_ERA_LAST: i64 = 146096 96const RD_DAYS_PER_YEAR: i64 = 365 97const RD_LEAP_4: i64 = 4 98const RD_LEAP_100: i64 = 100 99const RD_MP_SCALE: i64 = 5 100const RD_MP_OFF: i64 = 2 101const RD_MP_DIV: i64 = 153 102const RD_MP_MARCH: i64 = 3 103const RD_MP_WRAP: i64 = 9 104const RD_MP_JAN: i64 = 10 105const RD_TWO_DIGIT: i64 = 10 106func rd_put2(out: *u8, o: i64, v: i64) -> i64 { 107 var p: i64 = o 108 if v < RD_TWO_DIGIT { out[p] = 48 as u8; p = p + 1 } 109 return rp_putn(out, p, v) 110} 111func rd_ymd(epoch: i64, out: *u8) -> i64 { 112 let z: i64 = epoch / RD_SECS_PER_DAY + RD_DAYS_EPOCH_TO_ERA0 113 let era: i64 = z / RD_DAYS_PER_ERA 114 let doe: i64 = z - era * RD_DAYS_PER_ERA 115 let yoe: i64 = (doe - doe / RD_DOE_4Y + doe / RD_DOE_100Y - doe / RD_DOE_ERA_LAST) / RD_DAYS_PER_YEAR 116 var y: i64 = yoe + era * RD_ERA_YEARS 117 let doy: i64 = doe - (RD_DAYS_PER_YEAR * yoe + yoe / RD_LEAP_4 - yoe / RD_LEAP_100) 118 let mp: i64 = (RD_MP_SCALE * doy + RD_MP_OFF) / RD_MP_DIV 119 let d: i64 = doy - (RD_MP_DIV * mp + RD_MP_OFF) / RD_MP_SCALE + 1 120 var m: i64 = mp + RD_MP_MARCH 121 if mp >= RD_MP_JAN { m = mp - RD_MP_WRAP } 122 if m <= RD_MP_OFF { y = y + 1 } 123 var o: i64 = rp_putn(out, 0, y) 124 out[o] = 45 as u8 125 o = rd_put2(out, o + 1, m) 126 out[o] = 45 as u8 127 o = rd_put2(out, o + 1, d) 128 out[o] = 0 as u8 129 return o 130} 131func rd_basename(p: *u8) -> *u8 { 132 var i: i64 = 0 133 var last: i64 = 0 134 while p[i] != (0 as u8) { if p[i] == (47 as u8) { last = i + 1 } i = i + 1 } 135 return ((p as i64) + last) as *u8 136} 137// sha256 hex of a file via the ONE hasher, forked: 1 ok (out = 64 hex + NUL), 0 when it failed or printed no digest 138func rd_sha(path: *u8, out: *u8, fo: *u8, folen: *i64, av: *i64) -> i64 { 139 av[0] = RD_HASHER as i64 140 av[1] = path as i64 141 av[2] = 0 142 let rc: i64 = tr_run_capture(RD_HASHER, av, fo, RD_FETCH_OUT, folen) 143 if rc != 0 { return 0 } 144 let n: i64 = folen[0] 145 let tl: i64 = rp_slen(RD_SHA_TAG) 146 var i: i64 = 0 147 while i + tl + RD_JSON_QCQ + RD_HEXLEN <= n { 148 if rp_lit_eq(fo, i, tl, RD_SHA_TAG) == 1 { 149 let hs: i64 = i + tl + RD_JSON_QCQ 150 var k: i64 = 0 151 while k < RD_HEXLEN { out[k] = fo[hs + k]; k = k + 1 } 152 out[RD_HEXLEN] = 0 as u8 153 return 1 154 } 155 i = i + 1 156 } 157 return 0 158} 159// rewrite ONE refs row (col 1 == key): url -> newurl, pin -> h<sha>, accessed -> ymd, every other column verbatim by 160// walking the pipes (no dependence on a column parser's last-field rule). returns rows rewritten (0 = key absent), -1 io. 161// temp + rename, so a crash mid-write leaves the register whole. 162func rd_recite_row(refs: *u8, key: *u8, newurl: *u8, sha: *u8, ymd: *u8, rb: *u8, ob: *u8, c: *i64) -> i64 { 163 let rn: i64 = rd_slurp(refs, rb, RD_REFS_CAP) 164 if rn <= 0 { return 0 - 1 } 165 var o: i64 = 0 166 var hit: i64 = 0 167 var i: i64 = 0 168 while i < rn { 169 let e: i64 = rp_le(rb, i, rn) 170 var copied: i64 = 0 171 if e > i { if rb[i] == (114 as u8) { 172 if rp_col_pipe(rb, i, e, RD_COL_KEY, c) == 1 { 173 if rp_lit_eq(rb, c[0], c[1], key) == 1 { 174 var f: i64 = 0 175 var p: i64 = i 176 var fs: i64 = i 177 while p <= e { 178 var atend: i64 = 0 179 if p == e { atend = 1 } else { if rb[p] == (124 as u8) { atend = 1 } } 180 if atend == 1 { 181 if f > 0 { ob[o] = 124 as u8; o = o + 1 } 182 if f == RD_COL_URL { o = rp_put(ob, o, newurl) } else { 183 if f == RD_COL_PIN { ob[o] = 104 as u8; o = o + 1; o = rp_put(ob, o, sha) } else { 184 if f == RD_COL_ACCESSED { o = rp_put(ob, o, ymd) } else { o = rp_putspan(ob, o, rb, fs, p - fs) } 185 } 186 } 187 f = f + 1 188 fs = p + 1 189 } 190 p = p + 1 191 } 192 ob[o] = 10 as u8 193 o = o + 1 194 hit = hit + 1 195 copied = 1 196 } 197 } 198 } } 199 if copied == 0 { o = rp_putspan(ob, o, rb, i, e - i); ob[o] = 10 as u8; o = o + 1 } 200 i = e + 1 201 } 202 if hit == 0 { return 0 } 203 let tp: *u8 = sys_mmap(RD_PATH) 204 var tpo: i64 = rp_put(tp, 0, refs) 205 tpo = rp_put(tp, tpo, RD_TMP_SUFFIX) 206 tp[tpo] = 0 as u8 207 let fd: i64 = sys_openat_wr(tp, MODE_0644) 208 if fd < 0 { return 0 - 1 } 209 let w: i64 = sys_write(fd, ob, o) 210 sys_close(fd) 211 if w != o { return 0 - 1 } 212 if sys_renameat(tp, refs) < 0 { return 0 - 1 } 213 return hit 214} 215// RD_SAME -- THE FOUR-STATE DRIFT CLASSIFIER, given its contracted name 2026-09-06. 216// WHY THIS EXISTS AS A FUNCTION AT ALL: /compare/deepresearch published a row claiming exceed=1 on symbol rd_same in 217// THIS organ, and nx_domain_admit reported it UNGROUNDED. The capability was real and correct -- it simply ran inline 218// in main and its contracted entry point had never been written. A grep for the symbol name found `func rd_same` in 219// exactly one file estate-wide and it was nx_rebuild_drain.nx, an unrelated organ sharing the rd_ prefix, so a 220// name-only verification would have CONFIRMED the false claim. VERIFY A SYMBOL IN THE ORGAN THAT NAMES IT. 221// 222// IT DOES NOT RE-IMPLEMENT THE BYTE COMPARE. rp_same (nx_rowparse_lib) is and remains the ONE byte comparator; a 223// second one here would be the duplicate-ruler defect. What was missing was a NAME for the four-state decision that 224// wraps it, which is the thing the board actually contracted. 225// MATCH the mirror equals what the url serves now 226// DRIFTED the mirror and the url disagree, and the url agrees with ITSELF across two fetches 227// DYNAMIC the two fetches disagree with EACH OTHER, so the page varies per request and NO byte compare can 228// judge it -- never clean and never drifted. Folding this into DRIFTED would ship a false-positive 229// generator, which this estate ranks as worse than no detector at all. 230// UNREACHABLE nothing readable came back, which is not a statement about drift in either direction 231// PURE AND EXTRACTED WITHOUT WIDENING: the caller still performs both fetches and both slurps under exactly the 232// guards it used before, so this is a behaviour-preserving extraction and not a change of contract. 233const RD_V_MATCH: i64 = 0 234const RD_V_DRIFTED: i64 = 1 235const RD_V_UNREACHABLE: i64 = 2 236const RD_V_DYNAMIC: i64 = 3 237 238func rd_same(mb: *u8, mn: i64, pb: *u8, pn: i64, qb: *u8, qn: i64) -> i64 { 239 if pn <= 0 { return RD_V_UNREACHABLE } 240 if qn <= 0 { return RD_V_UNREACHABLE } 241 if rp_same(pb, pn, qb, qn) == 0 { return RD_V_DYNAMIC } 242 if rp_same(mb, mn, pb, pn) == 1 { return RD_V_MATCH } 243 return RD_V_DRIFTED 244} 245 246func main(argc: i64, argv: **u8) -> i64 { 247 var mode: i64 = 0 - 1 248 if argc > 1 { 249 let v: *u8 = argv[1] as *u8 250 if rp_slen(v) == 5 { if v[0] == (99 as u8) { mode = 0 } } 251 if rp_slen(v) == 8 { if v[0] == (115 as u8) { mode = 1 } } 252 if rp_slen(v) == 6 { if v[0] == (114 as u8) { mode = 2 } } 253 } 254 if mode < 0 { 255 sys_write(2, "usage: nx_refdrift {check <refsfile> [max] | selftest}\n" as *u8, 54) 256 sys_exit(RD_EXIT_USAGE) 257 return RD_EXIT_USAGE 258 } 259 let out: *u8 = sys_mmap(RD_OUT) 260 var o: i64 = 0 261 if mode == 1 { 262 var pass: i64 = 0 263 var tot: i64 = 0 264 let fx: *u8 = sys_mmap(4096) 265 var fn: i64 = 0 266 fn = rp_put(fx, fn, "ref|kk|Some citation prose|https://example.invalid/x|knowledge/fetched/m.html|habc|2026-09-04|vendor-doc|A row label\n" as *u8) 267 let c: *i64 = sys_mmap(RD_SPAN * 2) as *i64 268 let e: i64 = rp_le(fx, 0, fn) 269 // the 9-field pipe schema must yield key, url and mirror at their declared columns, or every later 270 // verdict would be about the wrong string 271 tot = tot + 1 272 if rp_col_pipe(fx, 0, e, RD_COL_KEY, c) == 1 { if c[1] == 2 { pass = pass + 1 } } 273 tot = tot + 1 274 if rp_col_pipe(fx, 0, e, RD_COL_URL, c) == 1 { if fx[c[0]] == (104 as u8) { pass = pass + 1 } } 275 tot = tot + 1 276 if rp_col_pipe(fx, 0, e, RD_COL_MIRROR, c) == 1 { if fx[c[0]] == (107 as u8) { pass = pass + 1 } } 277 // THE COMPARATOR, both directions. A byte compare that answered "same" for everything would report a 278 // permanently clean fleet, which is the guard-that-refuses-nothing failure. 279 let a1: *u8 = sys_mmap(64) 280 let b1: *u8 = sys_mmap(64) 281 a1[0] = 65 as u8 282 a1[1] = 66 as u8 283 b1[0] = 65 as u8 284 b1[1] = 66 as u8 285 tot = tot + 1 286 if rp_same(a1, 2, b1, 2) == 1 { pass = pass + 1 } 287 b1[1] = 67 as u8 288 tot = tot + 1 289 if rp_same(a1, 2, b1, 2) == 0 { pass = pass + 1 } 290 // neg-control: a LENGTH difference alone must read as drift. A comparator that only checked the 291 // overlapping prefix would call a truncated re-fetch identical, which is the exact silent case. 292 tot = tot + 1 293 if rp_same(a1, 2, b1, 1) == 0 { pass = pass + 1 } 294 // fixture-reached-the-condition: the row really parsed, so the schema teeth are not passing on empties 295 tot = tot + 1 296 if e > 40 { pass = pass + 1 } 297 o = rp_put(out, o, "NX-REFDRIFT-SELFTEST passed " as *u8) 298 o = rp_putn(out, o, pass) 299 o = rp_put(out, o, "/" as *u8) 300 o = rp_putn(out, o, tot) 301 if pass == tot { o = rp_put(out, o, " verdict=GREEN\n" as *u8) } else { o = rp_put(out, o, " verdict=RED\n" as *u8) } 302 sys_write(1, out, o) 303 if pass == tot { sys_exit(RD_EXIT_OK); return RD_EXIT_OK } 304 sys_exit(RD_EXIT_DRIFT) 305 return RD_EXIT_DRIFT 306 } 307 if mode == 2 { 308 if argc < 3 { 309 let u2: *u8 = "usage: nx_refdrift recite <moved-worklist> [max] [apply]\n" as *u8 310 sys_write(2, u2, rp_slen(u2)) 311 sys_exit(RD_EXIT_USAGE) 312 return RD_EXIT_USAGE 313 } 314 let wl: *u8 = argv[2] as *u8 315 var rmax: i64 = RD_MAX_DEFAULT 316 var apply: i64 = 0 317 var keyf: *u8 = 0 as *u8 318 var skipped: i64 = 0 319 let kal: i64 = rp_slen(RD_KEYARG) 320 var ai: i64 = 3 321 while ai < argc { 322 let s2: *u8 = argv[ai] as *u8 323 if s2[0] == (97 as u8) { apply = 1 } else { 324 var iskey: i64 = 0 325 if rp_slen(s2) > kal { if rp_lit_eq(s2, 0, kal, RD_KEYARG) == 1 { keyf = ((s2 as i64) + kal) as *u8; iskey = 1 } } 326 if iskey == 0 { 327 let m2: i64 = rp_num(s2, 0, rp_slen(s2)) 328 if m2 > 0 { rmax = m2 } 329 } 330 } 331 ai = ai + 1 332 } 333 let wb: *u8 = sys_mmap(RD_REFS_CAP) 334 let wn: i64 = rd_slurp(wl, wb, RD_REFS_CAP) 335 if wn <= 0 { 336 let u3: *u8 = "NX-REFDRIFT-RECITE UNREADABLE: the worklist did not read -- nothing is recited from nothing\n" as *u8 337 sys_write(2, u3, rp_slen(u3)) 338 sys_exit(RD_EXIT_UNREAD) 339 return RD_EXIT_UNREAD 340 } 341 let c: *i64 = sys_mmap(RD_SPAN * 2) as *i64 342 let dom: *u8 = sys_mmap(RD_PATH) 343 let key: *u8 = sys_mmap(RD_PATH) 344 let mir: *u8 = sys_mmap(RD_PATH) 345 let canon: *u8 = sys_mmap(RD_PATH) 346 let refs: *u8 = sys_mmap(RD_PATH) 347 let sha: *u8 = sys_mmap(RD_PATH) 348 let ymd: *u8 = sys_mmap(RD_PATH) 349 let fo: *u8 = sys_mmap(RD_FETCH_OUT) 350 let folen: *i64 = sys_mmap(RD_SPAN) as *i64 351 let av: *i64 = sys_mmap(RD_SPAN * RD_ARGV_SLOTS) as *i64 352 let rb: *u8 = sys_mmap(RD_REFS_CAP) 353 let ob: *u8 = sys_mmap(RD_REFS_CAP) 354 let hb: *u8 = sys_mmap(MI_HEAD) 355 let tb: *u8 = sys_mmap(MI_TAIL) 356 let rcode: *i64 = sys_mmap(RD_SPAN) as *i64 357 let szo: *i64 = sys_mmap(RD_SPAN) as *i64 358 let decl: *i64 = sys_mmap(RD_SPAN) as *i64 359 let ts: *i64 = sys_mmap(RD_SPAN * 2) as *i64 360 sys_clock_gettime_real(ts) 361 rd_ymd(ts[0], ymd) 362 var total: i64 = 0 363 var tried: i64 = 0 364 var recited: i64 = 0 365 var would: i64 = 0 366 var refused: i64 = 0 367 var ffail: i64 = 0 368 var absent: i64 = 0 369 var ioerr: i64 = 0 370 let tagl: i64 = rp_slen(RD_WL_TAG) 371 var i: i64 = 0 372 while i < wn { 373 let e: i64 = rp_le(wb, i, wn) 374 if e > i + tagl { if rp_lit_eq(wb, i, tagl, RD_WL_TAG) == 1 { 375 total = total + 1 376 if tried < rmax { 377 var ok: i64 = 1 378 if rp_col(wb, i, e, RD_WL_COL_DOM, RD_SPACE, c) == 1 { rp_cstr(dom, wb, c[0], c[1]) } else { ok = 0 } 379 if rp_col(wb, i, e, RD_WL_COL_KEY, RD_SPACE, c) == 1 { rp_cstr(key, wb, c[0], c[1]) } else { ok = 0 } 380 if rp_col(wb, i, e, RD_WL_COL_MIRROR, RD_SPACE, c) == 1 { rp_cstr(mir, wb, c[0], c[1]) } else { ok = 0 } 381 if rp_col(wb, i, e, RD_WL_COL_CANON, RD_SPACE, c) == 1 { rp_cstr(canon, wb, c[0], c[1]) } else { ok = 0 } 382 if ok == 1 { if (keyf as i64) != 0 { if rp_lit_eq(key, 0, rp_slen(key), keyf) == 0 { ok = 0; skipped = skipped + 1 } } } 383 if ok == 1 { 384 tried = tried + 1 385 var ro: i64 = rp_put(refs, 0, RD_REFS_DIR) 386 ro = rp_put(refs, ro, dom) 387 refs[ro] = 0 as u8 388 av[0] = RD_FETCHER as i64 389 av[1] = canon as i64 390 av[2] = RD_PROBE_NAME as i64 391 av[3] = 0 392 let rc: i64 = tr_run_capture(RD_FETCHER, av, fo, RD_FETCH_OUT, folen) 393 if rc != 0 { 394 ffail = ffail + 1 395 o = rp_put(out, o, "FETCH-FAILED key=" as *u8); o = rp_put(out, o, key); o = rp_put(out, o, " canonical=" as *u8); o = rp_put(out, o, canon); o = rp_put(out, o, " rc=" as *u8); o = rp_putn(out, o, rc); o = rp_put(out, o, "\n" as *u8) 396 } else { 397 let cls: i64 = mi_classify(RD_PROBE, hb, tb, rcode, szo, decl) 398 var bad: i64 = 0 399 if cls == MI_PROVEN { bad = 1 } 400 if cls == MI_SUSPECT { bad = 1 } 401 if bad == 1 { 402 refused = refused + 1 403 o = rp_put(out, o, "REFUSED-BODY key=" as *u8); o = rp_put(out, o, key); o = rp_put(out, o, " class=" as *u8); o = rp_putn(out, o, cls); o = rp_put(out, o, " bytes=" as *u8); o = rp_putn(out, o, szo[0]); o = rp_put(out, o, " canonical=" as *u8); o = rp_put(out, o, canon); o = rp_put(out, o, " <== the canonical fetched short or suspect; the row is NOT re-cited and the mirror is untouched\n" as *u8) 404 } else { 405 if apply == 0 { 406 would = would + 1 407 o = rp_put(out, o, "WOULD-RECITE key=" as *u8); o = rp_put(out, o, key); o = rp_put(out, o, " refs=" as *u8); o = rp_put(out, o, refs); o = rp_put(out, o, " canonical=" as *u8); o = rp_put(out, o, canon); o = rp_put(out, o, " bytes=" as *u8); o = rp_putn(out, o, szo[0]); o = rp_put(out, o, " class=" as *u8); o = rp_putn(out, o, cls); o = rp_put(out, o, "\n" as *u8) 408 } else { 409 av[0] = RD_FETCHER as i64 410 av[1] = canon as i64 411 av[2] = rd_basename(mir) as i64 412 av[3] = 0 413 let rc2: i64 = tr_run_capture(RD_FETCHER, av, fo, RD_FETCH_OUT, folen) 414 if rc2 != 0 { 415 ffail = ffail + 1 416 o = rp_put(out, o, "FETCH-FAILED key=" as *u8); o = rp_put(out, o, key); o = rp_put(out, o, " canonical=" as *u8); o = rp_put(out, o, canon); o = rp_put(out, o, " rc=" as *u8); o = rp_putn(out, o, rc2); o = rp_put(out, o, " <== on the APPLY fetch under the mirror name\n" as *u8) 417 } else { 418 if rd_sha(mir, sha, fo, folen, av) == 0 { 419 ioerr = ioerr + 1 420 o = rp_put(out, o, "HASH-FAILED key=" as *u8); o = rp_put(out, o, key); o = rp_put(out, o, " mirror=" as *u8); o = rp_put(out, o, mir); o = rp_put(out, o, "\n" as *u8) 421 } else { 422 let rw: i64 = rd_recite_row(refs, key, canon, sha, ymd, rb, ob, c) 423 if rw > 0 { 424 recited = recited + 1 425 o = rp_put(out, o, "RECITED key=" as *u8); o = rp_put(out, o, key); o = rp_put(out, o, " refs=" as *u8); o = rp_put(out, o, refs); o = rp_put(out, o, " url=" as *u8); o = rp_put(out, o, canon); o = rp_put(out, o, " pin=h" as *u8); o = rp_put(out, o, sha); o = rp_put(out, o, " accessed=" as *u8); o = rp_put(out, o, ymd); o = rp_put(out, o, "\n" as *u8) 426 } 427 if rw == 0 { 428 absent = absent + 1 429 o = rp_put(out, o, "ROW-ABSENT key=" as *u8); o = rp_put(out, o, key); o = rp_put(out, o, " refs=" as *u8); o = rp_put(out, o, refs); o = rp_put(out, o, " <== the worklist names a key this register no longer carries; the mirror WAS re-fetched under the canonical url\n" as *u8) 430 } 431 if rw < 0 { 432 ioerr = ioerr + 1 433 o = rp_put(out, o, "IO-ERROR key=" as *u8); o = rp_put(out, o, key); o = rp_put(out, o, " refs=" as *u8); o = rp_put(out, o, refs); o = rp_put(out, o, "\n" as *u8) 434 } 435 } 436 } 437 } 438 } 439 } 440 } 441 } 442 } } 443 // append each row's verdict as it is decided: a run interrupted at row 20 keeps 20 rows, not none 444 if o > 0 { sys_write(1, out, o); o = 0 } 445 i = e + 1 446 } 447 o = rp_put(out, o, "ENVELOPE moved_total=" as *u8); o = rp_putn(out, o, total) 448 o = rp_put(out, o, " tried=" as *u8); o = rp_putn(out, o, tried) 449 o = rp_put(out, o, " skipped_by_filter=" as *u8); o = rp_putn(out, o, skipped) 450 o = rp_put(out, o, " recited=" as *u8); o = rp_putn(out, o, recited) 451 o = rp_put(out, o, " would_recite=" as *u8); o = rp_putn(out, o, would) 452 o = rp_put(out, o, " refused_body=" as *u8); o = rp_putn(out, o, refused) 453 o = rp_put(out, o, " fetch_failed=" as *u8); o = rp_putn(out, o, ffail) 454 o = rp_put(out, o, " row_absent=" as *u8); o = rp_putn(out, o, absent) 455 o = rp_put(out, o, " io_err=" as *u8); o = rp_putn(out, o, ioerr) 456 o = rp_put(out, o, " sum=" as *u8); o = rp_putn(out, o, recited + would + refused + ffail + absent + ioerr) 457 o = rp_put(out, o, " max_per_run=" as *u8); o = rp_putn(out, o, rmax) 458 o = rp_put(out, o, " apply=" as *u8); o = rp_putn(out, o, apply) 459 o = rp_put(out, o, " accessed=" as *u8); o = rp_put(out, o, ymd) 460 if tried + skipped < total { o = rp_put(out, o, " PARTIAL=1 <== A PREFIX OF THE WORKLIST, NOT A SWEEP: raise max or run again" as *u8) } else { o = rp_put(out, o, " PARTIAL=0" as *u8) } 461 o = rp_put(out, o, "\n" as *u8) 462 // the verdict names what HAPPENED, never the mode: an apply that recited nothing is not RECITED (measured on the 463 // first live batch -- a refused body with recited=0 printed RECITED and read as success) 464 var bad2: i64 = ffail + ioerr 465 if bad2 > 0 { o = rp_put(out, o, "NX-REFDRIFT-RECITE verdict=FAILURES\n" as *u8) } else { 466 if apply == 0 { o = rp_put(out, o, "NX-REFDRIFT-RECITE verdict=DRY\n" as *u8) } else { 467 if recited == 0 { bad2 = 1; o = rp_put(out, o, "NX-REFDRIFT-RECITE verdict=NOTHING-RECITED\n" as *u8) } else { 468 if refused > 0 { o = rp_put(out, o, "NX-REFDRIFT-RECITE verdict=RECITED-WITH-REFUSALS\n" as *u8) } else { o = rp_put(out, o, "NX-REFDRIFT-RECITE verdict=RECITED\n" as *u8) } 469 } 470 } 471 } 472 sys_write(1, out, o) 473 if bad2 > 0 { sys_exit(RD_EXIT_DRIFT); return RD_EXIT_DRIFT } 474 sys_exit(RD_EXIT_OK) 475 return RD_EXIT_OK 476 } 477 if argc < 3 { 478 sys_write(2, "usage: nx_refdrift check <refsfile> [max]\n" as *u8, 41) 479 sys_exit(RD_EXIT_USAGE) 480 return RD_EXIT_USAGE 481 } 482 let refs: *u8 = argv[2] as *u8 483 var maxrows: i64 = RD_MAX_DEFAULT 484 if argc > 3 { 485 var m: i64 = 0 486 let s: *u8 = argv[3] as *u8 487 var i0: i64 = 0 488 let l0: i64 = rp_slen(s) 489 while i0 < l0 { 490 let ch: i64 = s[i0] as i64 491 if ch < 48 { i0 = l0 } else { if ch > 57 { i0 = l0 } else { m = m * 10 + (ch - 48); i0 = i0 + 1 } } 492 } 493 if m > 0 { maxrows = m } 494 } 495 let rb: *u8 = sys_mmap(RD_REFS_CAP) 496 let rn: i64 = rd_slurp(refs, rb, RD_REFS_CAP) 497 if rn <= 0 { 498 sys_write(2, "NX-REFDRIFT UNREADABLE: the refs file did not read -- no drift verdict is published from nothing\n" as *u8, 95) 499 sys_exit(RD_EXIT_UNREAD) 500 return RD_EXIT_UNREAD 501 } 502 let c: *i64 = sys_mmap(RD_SPAN * 2) as *i64 503 let url: *u8 = sys_mmap(RD_PATH) 504 let mir: *u8 = sys_mmap(RD_PATH) 505 let key: *u8 = sys_mmap(RD_PATH) 506 let mb: *u8 = sys_mmap(RD_BODY_CAP) 507 let pb: *u8 = sys_mmap(RD_BODY_CAP) 508 let qb: *u8 = sys_mmap(RD_BODY_CAP) 509 let fo: *u8 = sys_mmap(RD_FETCH_OUT) 510 let folen: *i64 = sys_mmap(RD_SPAN) as *i64 511 let av: *i64 = sys_mmap(RD_SPAN * RD_ARGV_SLOTS) as *i64 512 var total: i64 = 0 513 var checked: i64 = 0 514 var match_n: i64 = 0 515 var drift: i64 = 0 516 var unreach: i64 = 0 517 var dynamic: i64 = 0 518 var i: i64 = 0 519 while i < rn { 520 let e: i64 = rp_le(rb, i, rn) 521 if e > i { if rb[i] == (114 as u8) { 522 if rp_col_pipe(rb, i, e, 0, c) == 1 { if c[1] == 3 { 523 total = total + 1 524 if checked < maxrows { 525 var ok: i64 = 0 526 if rp_col_pipe(rb, i, e, RD_COL_KEY, c) == 1 { rp_cstr(key, rb, c[0], c[1]); ok = 1 } 527 if ok == 1 { if rp_col_pipe(rb, i, e, RD_COL_URL, c) == 1 { rp_cstr(url, rb, c[0], c[1]) } else { ok = 0 } } 528 if ok == 1 { if rp_col_pipe(rb, i, e, RD_COL_MIRROR, c) == 1 { rp_cstr(mir, rb, c[0], c[1]) } else { ok = 0 } } 529 if ok == 1 { 530 let mn: i64 = rd_slurp(mir, mb, RD_BODY_CAP) 531 if mn <= 0 { ok = 0 } 532 if ok == 1 { 533 checked = checked + 1 534 av[0] = RD_FETCHER as i64 535 av[1] = url as i64 536 av[2] = RD_PROBE_NAME as i64 537 av[3] = 0 538 let rc: i64 = tr_run_capture(RD_FETCHER, av, fo, RD_FETCH_OUT, folen) 539 // FETCH TWICE. A page that varies against ITSELF cannot be judged by a byte 540 // compare at all, and calling that DRIFTED would be a false-positive generator 541 // -- worse than no detector, because the fleet would learn to ignore it. 542 // MEASURED 2026-09-04 on the very first live run: one url returned THREE 543 // DIFFERENT HASHES ACROSS THREE FETCHES AT AN IDENTICAL 106703 BYTES, so a size 544 // check calls it stable and a hash check calls it drifted and BOTH ARE WRONG. 545 // The second fetch is the discriminator and it costs one request. 546 av[2] = RD_PROBE_B_NAME as i64 547 let rc2: i64 = tr_run_capture(RD_FETCHER, av, fo, RD_FETCH_OUT, folen) 548 av[2] = RD_PROBE_NAME as i64 549 var verdict: i64 = RD_V_UNREACHABLE 550 if rc == 0 { if rc2 == 0 { 551 let pn: i64 = rd_slurp(RD_PROBE, pb, RD_BODY_CAP) 552 let qn: i64 = rd_slurp(RD_PROBE_B, qb, RD_BODY_CAP) 553 verdict = rd_same(mb, mn, pb, pn, qb, qn) 554 } } 555 if verdict == 0 { match_n = match_n + 1; o = rp_put(out, o, "MATCH key=" as *u8) } 556 if verdict == 1 { drift = drift + 1; o = rp_put(out, o, "DRIFTED key=" as *u8) } 557 if verdict == 2 { unreach = unreach + 1; o = rp_put(out, o, "UNREACHABLE key=" as *u8) } 558 if verdict == 3 { dynamic = dynamic + 1; o = rp_put(out, o, "DYNAMIC key=" as *u8) } 559 o = rp_put(out, o, key) 560 o = rp_put(out, o, " mirror_bytes=" as *u8) 561 o = rp_putn(out, o, mn) 562 o = rp_put(out, o, " url=" as *u8) 563 o = rp_put(out, o, url) 564 if verdict == 1 { o = rp_put(out, o, " <== THE SOURCE HAS MOVED SINCE IT WAS PINNED: the mirror and its pin still agree, so every pin check stays green while the citation now points at different bytes. Re-fetch, re-pin, and re-read the claim it grounds" as *u8) } 565 if verdict == 2 { o = rp_put(out, o, " <== NOT A DRIFT VERDICT: the fetch did not complete, so this row is UNJUDGED rather than clean" as *u8) } 566 if verdict == 3 { o = rp_put(out, o, " <== NOT A DRIFT VERDICT EITHER: two consecutive fetches of this url disagree with EACH OTHER, so the page varies per request and a byte compare cannot judge it. This is UNJUDGEABLE, never clean and never drifted; pin a stable artifact or cite a versioned URL if this reference must be checkable" as *u8) } 567 o = rp_put(out, o, "\n" as *u8) 568 } 569 } 570 } 571 } } 572 } } 573 i = e + 1 574 } 575 o = rp_put(out, o, "ENVELOPE refs_total=" as *u8) 576 o = rp_putn(out, o, total) 577 o = rp_put(out, o, " checked=" as *u8) 578 o = rp_putn(out, o, checked) 579 o = rp_put(out, o, " match=" as *u8) 580 o = rp_putn(out, o, match_n) 581 o = rp_put(out, o, " drifted=" as *u8) 582 o = rp_putn(out, o, drift) 583 o = rp_put(out, o, " unreachable=" as *u8) 584 o = rp_putn(out, o, unreach) 585 o = rp_put(out, o, " dynamic=" as *u8) 586 o = rp_putn(out, o, dynamic) 587 o = rp_put(out, o, " sum=" as *u8) 588 o = rp_putn(out, o, match_n + drift + unreach + dynamic) 589 o = rp_put(out, o, " max_per_run=" as *u8) 590 o = rp_putn(out, o, maxrows) 591 if checked < total { 592 o = rp_put(out, o, " PARTIAL=1 <== THIS RUN IS A PREFIX OF THE FILE, NOT A SWEEP: raise max or run again to cover the rest, and do NOT read this as a clean bill for the unchecked rows" as *u8) 593 } else { o = rp_put(out, o, " PARTIAL=0" as *u8) } 594 o = rp_put(out, o, "\n" as *u8) 595 if drift > 0 { o = rp_put(out, o, "NX-REFDRIFT verdict=DRIFTED\n" as *u8) } else { o = rp_put(out, o, "NX-REFDRIFT verdict=GREEN\n" as *u8) } 596 sys_write(1, out, o) 597 if drift > 0 { sys_exit(RD_EXIT_DRIFT); return RD_EXIT_DRIFT } 598 sys_exit(RD_EXIT_OK) 599 return RD_EXIT_OK 600}