code wiki / _hdl_build / nx_evidence_gather.nx

nx_evidence_gather.nx source

↩ module page · 199 lines · 8672 B

1// nx_evidence_gather.nx -- the ANALYST's EVIDENCE GATHER (AN9, the irrefutability rung): every 2// load-bearing source URL is fetched over the team's OWN validated HTTPS (sovereign DNS+TCP+ 3// TLS1.3+X.509 -- the proven nx_https_get path), content-hashed (sha256), stored content- 4// addressed under knowledge/analyst/evidence/, self-verified by re-read+re-hash, and recorded in 5// an append-only provenance ledger. A cited number stops being a citation and becomes BYTES ON 6// DISK with a pin -- re-fetchable, diffable, irrefutable. Refusals (bot walls, redirects, TLS 7// alerts) are recorded HONESTLY per URL, never papered over; the run is GREEN if every row got a 8// definite verdict (FETCHED or REFUSED) and at least one FETCHED+VERIFIED. 9// URL list = DATA: knowledge/analyst/evidence_urls.txt (`tag | url`). Polite: 1.5s pacing. 10// x86-lane only (mkdirat 258 direct, the media-gather lesson). license_tier: ORIGINAL 11import "nx_str.nx" 12import "nx_syscalls.nx" 13import "nx_csprng.nx" 14import "nx_x509_trust_store.nx" 15import "nx_pem_loader.nx" 16import "nx_https_get.nx" 17import "nx_sha256.nx" 18const EG_MAGIC_4096: i64 = 4096 19const EG_MAGIC_1500: i64 = 1500 20 21const EG_PAGE_CAP: i64 = 4194304 22const EG_MAX_URLS: i64 = 32 23 24func eg_puts(s: *u8) -> i64 { sys_write(1, s, nx_str_len(s)); return 0 } 25func eg_pi(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 } 26func eg_w(fd: i64, s: *u8) -> i64 { sys_write(fd, s, nx_str_len(s)); return 0 } 27func eg_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(fd,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(fd,bb,k); return 0 } 28func eg_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off+i]=s[i];i=i+1} return off+i } 29func eg_mkdir(path: *u8) -> i64 { return __syscall(258, -100, path, 0x1ed, 0, 0, 0) } 30 31func eg_hex(d: *u8, out: *u8) -> i64 { 32 let hx: *u8 = "0123456789abcdef" as *u8 33 var i: i64 = 0 34 while i < 32 { 35 let b: i64 = d[i] as i64 36 out[i*2] = hx[(b >> 4) & 15] 37 out[i*2+1] = hx[b & 15] 38 i = i + 1 39 } 40 out[64] = 0 as u8 41 return 64 42} 43 44func eg_line_end(b: *u8, i: i64, n: i64) -> i64 { 45 var e: i64 = i 46 while e < n { if b[e] == (10 as u8) { return e } e = e + 1 } 47 return n 48} 49func eg_skip(b: *u8, i0: i64, e: i64) -> i64 { 50 var i: i64 = i0 51 while i < e { if b[i] != (32 as u8) { return i } i = i + 1 } 52 return e 53} 54func eg_pipe(b: *u8, i: i64, e: i64) -> i64 { 55 var j: i64 = i 56 while j < e { if b[j] == (124 as u8) { return j } j = j + 1 } 57 return e 58} 59// copy [i,e) right-trimmed into dst, NUL-terminate; returns len 60func eg_slice(b: *u8, i: i64, e: i64, dst: *u8) -> i64 { 61 var te: i64 = e 62 var trimming: i64 = 1 63 while trimming == 1 { 64 trimming = 0 65 if te > i { if b[te-1] == (32 as u8) { te = te - 1; trimming = 1 } } 66 if te > i { if b[te-1] == (13 as u8) { te = te - 1; trimming = 1 } } 67 } 68 var o: i64 = 0 69 var j: i64 = i 70 while j < te { dst[o] = b[j]; o = o + 1; j = j + 1 } 71 dst[o] = 0 as u8 72 return o 73} 74 75func eg_write_file(path: *u8, buf: *u8, n: i64) -> i64 { 76 let fd: i64 = sys_openat_wr(path, 0x1a4) 77 if fd < 0 { return 0 - 1 } 78 var off: i64 = 0 79 while off < n { 80 let w: i64 = sys_write(fd, ((buf as i64) + off) as *u8, n - off) 81 if w <= 0 { sys_close(fd); return 0 - 1 } 82 off = off + w 83 } 84 sys_close(fd) 85 return n 86} 87 88// fetch one url; store + verify + ledger. returns 1 FETCHED+VERIFIED, 0 REFUSED (recorded). 89func eg_one(tag: *u8, url: *u8, store: *TrustStore, lg: i64) -> i64 { 90 let cr: *u8 = sys_mmap(32); nx_csprng_fill(cr, 32) 91 let pk: *u8 = sys_mmap(32); nx_csprng_fill(pk, 32) 92 let page: *u8 = sys_mmap(EG_PAGE_CAP) 93 let pr: i64 = nx_https_get(url, cr, pk, store, sys_now_realtime_sec(), page, EG_PAGE_CAP) 94 eg_puts(" " as *u8); eg_puts(tag); eg_puts(" bytes=" as *u8); eg_pi(pr) 95 if pr <= 0 { 96 eg_puts(" REFUSED\n" as *u8) 97 eg_w(lg, tag); eg_w(lg, "\t" as *u8); eg_w(lg, url) 98 eg_w(lg, "\t" as *u8); eg_wn(lg, pr) 99 eg_w(lg, "\t-\tREFUSED\n" as *u8) 100 return 0 101 } 102 let dg: *u8 = sys_mmap(32) 103 sha256_digest(page, pr, dg) 104 let hex: *u8 = sys_mmap(72) 105 eg_hex(dg, hex) 106 let fpath: *u8 = sys_mmap(EG_MAGIC_4096) 107 var fo: i64 = eg_cat(fpath, 0, "knowledge/analyst/evidence/" as *u8) 108 fo = eg_cat(fpath, fo, hex) 109 fo = eg_cat(fpath, fo, ".bin" as *u8) 110 fpath[fo] = 0 as u8 111 let wr: i64 = eg_write_file(fpath, page, pr) 112 // self-verify: re-read + re-hash (store proven, not assumed) 113 var verified: i64 = 0 114 if wr == pr { 115 let lenbox: *i64 = sys_mmap(16) as *i64 116 let back: *u8 = sys_read_file(fpath, lenbox) 117 if lenbox[0] == pr { 118 let dg2: *u8 = sys_mmap(32) 119 sha256_digest(back, lenbox[0], dg2) 120 var same: i64 = 1 121 var b: i64 = 0 122 while b < 32 { if dg[b] != dg2[b] { same = 0 } b = b + 1 } 123 verified = same 124 } 125 } 126 eg_puts(" sha256=" as *u8); eg_puts(hex) 127 eg_puts(" verified=" as *u8); eg_pi(verified); eg_puts("\n" as *u8) 128 eg_w(lg, tag); eg_w(lg, "\t" as *u8); eg_w(lg, url) 129 eg_w(lg, "\t" as *u8); eg_wn(lg, pr) 130 eg_w(lg, "\t" as *u8); eg_w(lg, hex) 131 if verified == 1 { eg_w(lg, "\tVERIFIED\n" as *u8) } 132 if verified != 1 { eg_w(lg, "\tSTORE-FAIL\n" as *u8) } 133 return verified 134} 135 136func main() -> i64 { 137 eg_puts("=== EVIDENCE GATHER (AN9): own-TLS fetch -> sha256 CAS -> provenance ledger ===\n" as *u8) 138 let store: *TrustStore = trust_store_alloc(400) 139 let nroots: i64 = nx_pem_trust_load_file("/etc/ssl/certs/ca-certificates.crt" as *u8, store) 140 eg_puts(" trust roots=" as *u8); eg_pi(nroots); eg_puts("\n" as *u8) 141 if nroots <= 0 { eg_puts("EVIDENCE-GATHER-FAIL no-roots\n" as *u8); sys_exit(1); return 1 } 142 eg_mkdir("knowledge/analyst" as *u8) 143 eg_mkdir("knowledge/analyst/evidence" as *u8) 144 145 let lenp: *i64 = sys_mmap(16) as *i64 146 let b: *u8 = sys_read_file("knowledge/analyst/evidence_urls.txt" as *u8, lenp) 147 if lenp[0] <= 0 { eg_puts("EVIDENCE-GATHER-FAIL no-url-list\n" as *u8); sys_exit(1); return 1 } 148 let lg: i64 = sys_openat_append("knowledge/analyst/evidence_ledger.tsv" as *u8, 0x1a4) 149 if lg < 0 { eg_puts("EVIDENCE-GATHER-FAIL no-ledger\n" as *u8); sys_exit(1); return 1 } 150 151 var rows: i64 = 0 152 var fetched: i64 = 0 153 var refused: i64 = 0 154 let tag: *u8 = sys_mmap(256) 155 let url: *u8 = sys_mmap(EG_MAGIC_4096) 156 var i: i64 = 0 157 let n: i64 = lenp[0] 158 while i < n { 159 let e: i64 = eg_line_end(b, i, n) 160 let s: i64 = eg_skip(b, i, e) 161 var data: i64 = 0 162 if s < e { if b[s] != (35 as u8) { data = 1 } } 163 if data == 1 { 164 let p1: i64 = eg_pipe(b, s, e) 165 if p1 < e { 166 if rows < EG_MAX_URLS { 167 eg_slice(b, s, p1, tag) 168 eg_slice(b, eg_skip(b, p1+1, e), e, url) 169 if rows > 0 { sys_sleep_ms(EG_MAGIC_1500) } // polite pacing 170 let ok: i64 = eg_one(tag, url, store, lg) 171 if ok == 1 { fetched = fetched + 1 } 172 if ok == 0 { refused = refused + 1 } 173 rows = rows + 1 174 } 175 } 176 } 177 i = e + 1 178 } 179 sys_close(lg) 180 eg_puts(" rows=" as *u8); eg_pi(rows) 181 eg_puts(" fetched-verified=" as *u8); eg_pi(fetched) 182 eg_puts(" refused=" as *u8); eg_pi(refused); eg_puts("\n" as *u8) 183 // durable anchor: every row got a definite verdict AND at least one source pinned 184 let dfd: i64 = sys_openat_append("knowledge/status/analyst_evidence_gate.log" as *u8, 0x1a4) 185 var green: i64 = 0 186 if rows > 0 { if fetched > 0 { if fetched + refused == rows { green = 1 } } } 187 if dfd >= 0 { 188 if green == 1 { eg_w(dfd, "ANALYST-EVID verdict=GREEN " as *u8) } 189 if green != 1 { eg_w(dfd, "ANALYST-EVID verdict=RED " as *u8) } 190 eg_wn(dfd, fetched); eg_w(dfd, "/" as *u8); eg_wn(dfd, rows) 191 eg_w(dfd, " refusals-named=" as *u8); eg_wn(dfd, refused) 192 eg_w(dfd, "\n" as *u8) 193 sys_close(dfd) 194 } 195 if green == 1 { eg_puts("EVIDENCE-GATHER-OK\n" as *u8); sys_exit(0); return 0 } 196 eg_puts("EVIDENCE-GATHER-FAIL\n" as *u8) 197 sys_exit(1) 198 return 1 199}