code wiki / (root) / nx_research_verify.nx

nx_research_verify.nx source

↩ module page · 176 lines · 9471 B

1// nx_research_verify.nx -- the RESEARCH-VERIFICATION STAGE: batch, autonomous, sovereign claim verification. 2// Upgrades the researcher from "fetch + extract" to "fetch + extract + VERIFY against the cited source" -- the 3// SOTA research behavior. Reads a claims TSV (a researcher's findings), FETCHES each cited source itself over the 4// sovereign TLS-1.3 stack, extracts the real value, and banks a verdict ledger + a summary. Composes the proven 5// single-claim primitive (nx_claim_verify) over a batch; the anti-gaming discipline made a pipeline stage: 6// every claim is CONFIRMED/DISCREDITED against real fetched evidence, or UNVERIFIABLE (never fabricated). 7// 8// INPUT (argv[1] or default knowledge/index/rv_claims.tsv): lines of label<TAB>url<TAB>pattern<TAB>claim_tenths<TAB>tol_tenths 9// OUTPUT knowledge/index/rv_verified.tsv: label<TAB>source<TAB>extracted<TAB>claim<TAB>verdict + a stdout summary. 10// license_tier: ORIGINAL expect_exit: 0 11import "nx_syscalls.nx" 12import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 13import "nx_x509_trust_store.nx" 14import "nx_trust_store_load_from_certdata.nx" 15import "nx_https_fetch_follow.nx" 16const K_MAGIC_262144: i64 = 262144 17const K_MAGIC_4194304: i64 = 4194304 18const K_MAGIC_1024: i64 = 1024 19const K_MAGIC_1500: i64 = 1500 20 21func rv_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 22// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 23// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 24// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 25// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 26func rv_putn(v: i64) -> i64 { nxi_out(v); return 0 } 27func rv_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 28func rv_iabs(x: i64) -> i64 { if x < 0 { return 0-x } return x } 29 30// find pat in buf[0..blen); index just AFTER the match, or -1. 31func rv_find_after(buf: *u8, blen: i64, pat: *u8, patlen: i64) -> i64 { 32 if patlen == 0 { return 0-1 } 33 var i: i64 = 0 34 while i + patlen <= blen { 35 var k: i64 = 0 36 var ok: i64 = 1 37 while k < patlen { if ok == 1 { if buf[i+k] != pat[k] { ok = 0 } } k = k + 1 } 38 if ok == 1 { return i + patlen } 39 i = i + 1 40 } 41 return 0-1 42} 43// parse decimal at buf[off..] as TENTHS ("86.8"->868); -1 if no digit. 44func rv_parse_tenths(buf: *u8, blen: i64, off: i64) -> i64 { 45 if off < 0 { return 0-1 } 46 var i: i64 = off 47 var whole: i64 = 0 48 var any: i64 = 0 49 var go: i64 = 1 50 while go == 1 { 51 go = 0 52 if i < blen { let c: i64 = buf[i] as i64 53 if c >= 48 { if c <= 57 { whole = whole*10 + (c-48); any = 1; i = i + 1; go = 1 } } } 54 } 55 if any == 0 { return 0-1 } 56 var tenths: i64 = whole * 10 57 if i < blen { if (buf[i] as i64) == 46 { 58 if i+1 < blen { let d: i64 = buf[i+1] as i64 59 if d >= 48 { if d <= 57 { tenths = tenths + (d-48) } } } } } 60 return tenths 61} 62func rv_int(s: *u8, n: i64) -> i64 { // parse an unsigned int from s[0..n) 63 var v: i64 = 0; var i: i64 = 0 64 while i < n { let c: i64 = s[i] as i64; if c >= 48 { if c <= 57 { v = v*10 + (c-48) } } i = i + 1 } 65 return v 66} 67 68func main(argc: i64, argv: *i64) -> i64 { 69 var inpath: *u8 = "knowledge/index/rv_claims.tsv\x00" as *u8 70 if argc >= 2 { inpath = argv[1] as *u8 } 71 72 // load the claims file 73 let ifd: i64 = sys_openat_rd(inpath) 74 if ifd < 0 { rv_puts("nx_research_verify: cannot open claims file\n" as *u8); return 1 } 75 let cap: i64 = K_MAGIC_262144 76 let raw: *u8 = sys_mmap(cap) 77 var got: i64 = 0 78 var r: i64 = 1 79 while r > 0 { r = sys_read(ifd, (raw as i64 + got) as *u8, cap-got); if r > 0 { got = got + r } } 80 sys_close(ifd) 81 82 // trust store (once) + fetch scratch 83 let ts: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt\x00" as *u8, 512, K_MAGIC_4194304) 84 if ts <= 0 { rv_puts("nx_research_verify: certdata load failed\n" as *u8); return 1 } 85 let store: *TrustStore = ts as *TrustStore 86 let out: *u8 = sys_mmap(K_MAGIC_4194304) 87 let status: *i64 = sys_mmap(8) as *i64 88 89 // output ledger (truncate) 90 let ofd: i64 = sys_openat_wr("knowledge/index/rv_verified.tsv\x00" as *u8, 420) 91 92 rv_puts("=== nx_research_verify: verify each cited claim against its FETCHED source ===\n\n" as *u8) 93 var nconf: i64 = 0; var ndisc: i64 = 0; var nunv: i64 = 0; var nfail: i64 = 0 94 95 // iterate lines; split each into 5 TAB fields: label, url, pattern, claim_tenths, tol_tenths 96 var p: i64 = 0 97 while p < got { 98 // line end = index of the next '\n' at/after p (or got). go-flag scan (preserves the position). 99 var lineend: i64 = p 100 var goL: i64 = 1 101 while goL == 1 { goL = 0; if lineend < got { if (raw[lineend] as i64) != 10 { lineend = lineend + 1; goL = 1 } } } 102 // field boundaries (TAB=9) within [p, lineend) 103 let fstart: *i64 = sys_mmap(6*8) as *i64 104 let fend: *i64 = sys_mmap(6*8) as *i64 105 var nf: i64 = 0 106 var fs: i64 = p 107 var i: i64 = p 108 while i <= lineend { 109 var cut: i64 = 0 110 if i == lineend { cut = 1 } else { if (raw[i] as i64) == 9 { cut = 1 } } 111 if cut == 1 { if nf < 6 { fstart[nf] = fs; fend[nf] = i; nf = nf + 1 } fs = i + 1 } 112 i = i + 1 113 } 114 // skip blank/short lines (need 5 fields); also skip a leading '#' comment 115 var iscomment: i64 = 0 116 if fend[0] > fstart[0] { if (raw[fstart[0]] as i64) == 35 { iscomment = 1 } } 117 if nf >= 5 { if iscomment == 0 { 118 // NUL-terminate label, url, pattern into fresh buffers; parse claim + tol 119 let lbl: *u8 = sys_mmap(256) 120 let url: *u8 = sys_mmap(K_MAGIC_1024) 121 let pat: *u8 = sys_mmap(512) 122 var a: i64 = 0 123 var q: i64 = fstart[0]; while q < fend[0] { if a < 255 { lbl[a] = raw[q]; a = a + 1 } q = q + 1 } lbl[a] = 0 as u8 124 a = 0; q = fstart[1]; while q < fend[1] { if a < 1023 { url[a] = raw[q]; a = a + 1 } q = q + 1 } url[a] = 0 as u8 125 a = 0; q = fstart[2]; while q < fend[2] { if a < 511 { pat[a] = raw[q]; a = a + 1 } q = q + 1 } pat[a] = 0 as u8 126 let claim: i64 = rv_int((raw as i64 + fstart[3]) as *u8, fend[3]-fstart[3]) 127 let tol: i64 = rv_int((raw as i64 + fstart[4]) as *u8, fend[4]-fstart[4]) 128 129 // fetch + extract + verdict 130 var n: i64 = nx_https_fetch_follow_best(url, store, out, K_MAGIC_4194304, 6, status) 131 if n <= 0 { sys_sleep_ms(K_MAGIC_1500); n = nx_https_fetch_follow_best(url, store, out, K_MAGIC_4194304, 6, status) } 132 var http: i64 = 0 133 if n > 0 { http = status[0] } 134 var ext: i64 = 0-1 135 var verdict: *u8 = "FETCH-FAILED" as *u8 136 if n > 0 { if http < 400 { 137 ext = rv_parse_tenths(out, n, rv_find_after(out, n, pat, rv_slen(pat))) 138 if ext < 0 { verdict = "UNVERIFIABLE" as *u8; nunv = nunv + 1 } else { 139 if rv_iabs(ext - claim) <= tol { verdict = "CONFIRMED" as *u8; nconf = nconf + 1 } else { verdict = "DISCREDITED" as *u8; ndisc = ndisc + 1 } 140 } 141 } } 142 var isfail: i64 = 1 143 if n > 0 { if http < 400 { isfail = 0 } } 144 if isfail == 1 { nfail = nfail + 1 } 145 146 // print row 147 rv_puts(" " as *u8); rv_puts(verdict); rv_puts(" " as *u8); rv_puts(lbl) 148 rv_puts(" (extracted=" as *u8); rv_putn(ext); rv_puts(" claim=" as *u8); rv_putn(claim) 149 rv_puts(" http=" as *u8); rv_putn(http); rv_puts(")\n" as *u8) 150 // bank ledger row: label\tsource\textracted\tclaim\tverdict\n 151 if ofd >= 0 { 152 sys_write(ofd, lbl, rv_slen(lbl)); sys_write(ofd, "\t" as *u8, 1) 153 sys_write(ofd, url, rv_slen(url)); sys_write(ofd, "\t" as *u8, 1) 154 let nb: *u8 = sys_mmap(32); var ne: i64 = 0 155 if ext < 0 { nb[0] = 45 as u8; ne = 1 } else { var tv: i64 = ext; if tv==0 { nb[0]=48 as u8; ne=1 } else { let tmp: *u8=sys_mmap(24); var tk: i64=0; while tv>0 { tmp[tk]=(48+(tv%10)) as u8; tv=tv/10; tk=tk+1 } while ne<tk { nb[ne]=tmp[tk-1-ne]; ne=ne+1 } } } 156 sys_write(ofd, nb, ne); sys_write(ofd, "\t" as *u8, 1) 157 let cb: *u8 = sys_mmap(32); var ce: i64 = 0; var cv: i64 = claim; if cv==0 { cb[0]=48 as u8; ce=1 } else { let tmp2: *u8=sys_mmap(24); var ck: i64=0; while cv>0 { tmp2[ck]=(48+(cv%10)) as u8; cv=cv/10; ck=ck+1 } while ce<ck { cb[ce]=tmp2[ck-1-ce]; ce=ce+1 } } 158 sys_write(ofd, cb, ce); sys_write(ofd, "\t" as *u8, 1) 159 sys_write(ofd, verdict, rv_slen(verdict)); sys_write(ofd, "\n" as *u8, 1) 160 } 161 sys_sleep_ms(500) // be polite to rate-limited hosts between claims 162 } } 163 // advance to next line 164 var np: i64 = lineend + 1 165 if np <= p { np = p + 1 } 166 p = np 167 } 168 if ofd >= 0 { sys_close(ofd) } 169 170 rv_puts("\n=== SUMMARY: CONFIRMED=" as *u8); rv_putn(nconf) 171 rv_puts(" DISCREDITED=" as *u8); rv_putn(ndisc) 172 rv_puts(" UNVERIFIABLE=" as *u8); rv_putn(nunv) 173 rv_puts(" FETCH-FAILED=" as *u8); rv_putn(nfail) 174 rv_puts("\nledger -> knowledge/index/rv_verified.tsv\n" as *u8) 175 return 0 176}