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}