code wiki / (root) / nx_aimode_read.nx

nx_aimode_read.nx source

↩ module page · 175 lines · 9071 B

1// nx_aimode_read.nx -- CLI for BR50: read a Google AI Mode share link as its answer text. 2// nx_aimode_read <share-url> [out-path] 3// Writes knowledge/fetched/aimode_<id>.answer.txt (or <out-path>): 4// # nx_aimode_read v1 5// # share_url=<the url the operator pasted -- the CITED url> 6// # final_url=<the /search url the share resolved to> 7// # fetched_at=<epoch> 8// # citations=<N> 9// <blank> 10// <answer text> 11// <blank> 12// ## Citations (<N>) -- the server-rendered /url? beacon references (opaque Google redirect tokens) 13// <one per line> 14// then appends a provenance row prov|<epoch>|<share url>|<mirror>|<sha256>|<bytes>|<hops> to the shared 15// fetch_provenance.jrnl (the CITED url is the SHARE url, never an internal endpoint -- refs-gate contract). 16// Refuses BY NAME: REFUSED-CONSENT-WALL / REFUSED-SIGNIN / REFUSED-NO-ANSWER / REFUSED-EMPTY-BODY (+fetch). 17// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 18import "nx_syscalls.nx" 19import "nx_x509_trust_store.nx" 20import "nx_trust_store_load_from_certdata.nx" 21import "nx_aimode_lib.nx" 22import "nx_sha256.nx" 23import "nx_atomic_rewrite.nx" 24 25const R_CERTCAP: i64 = 4194304 26const R_OUTCAP: i64 = 8388608 27const R_CITECAP: i64 = 262144 28const R_URLCAP: i64 = 16384 29const R_DOCCAP: i64 = 8912896 30 31func pw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 32func pe(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 } 33func pn(v: i64) -> i64 { 34 let b: *u8 = sys_mmap(24); var m: i64 = v; var i: i64 = 23 35 if m == 0 { i = i - 1; b[i] = 48 as u8 } 36 while m > 0 { i = i - 1; b[i] = (48 + (m % 10)) as u8; m = m / 10 } 37 sys_write(1, (b as i64 + i) as *u8, 23 - i); return 0 38} 39func rcat(dst: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } return o } 40func rcatn(dst: *u8, o: i64, v: i64) -> i64 { 41 if v == 0 { dst[o] = 48 as u8; return o + 1 } 42 let t: *u8 = sys_mmap(24); var m: i64 = v; var k: i64 = 0 43 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 44 var j: i64 = k - 1 45 while j >= 0 { dst[o] = t[j]; o = o + 1; j = j - 1 } 46 return o 47} 48func rslen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 49 50// extract the share id after the LAST "aimode/" into out (id chars: alnum, - and _). Returns len. 51func r_share_id(url: *u8, out: *u8) -> i64 { 52 let ul: i64 = rslen(url) 53 let mark: *u8 = "aimode/" as *u8 54 var mpos: i64 = 0 - 1 55 var i: i64 = 0 56 while i + 7 <= ul { 57 var m: i64 = 1; var j: i64 = 0 58 while j < 7 { if (url[i+j]&0xff) != (mark[j]&0xff) { m = 0; j = 7 } else { j = j + 1 } } 59 if m == 1 { mpos = i + 7 } 60 i = i + 1 61 } 62 if mpos < 0 { out[0] = 0 as u8; return 0 } 63 var o: i64 = 0 64 var k: i64 = mpos 65 while k < ul { 66 let c: i64 = url[k] & 0xff 67 var ok: i64 = 0 68 if c >= 48 { if c <= 57 { ok = 1 } } 69 if c >= 65 { if c <= 90 { ok = 1 } } 70 if c >= 97 { if c <= 122 { ok = 1 } } 71 if c == 45 { ok = 1 } 72 if c == 95 { ok = 1 } 73 if ok == 0 { k = ul } else { out[o] = c as u8; o = o + 1; k = k + 1 } 74 } 75 out[o] = 0 as u8 76 return o 77} 78 79func r_hex32(dst: *u8, o: i64, digest: *u8) -> i64 { 80 var i: i64 = 0 81 while i < 32 { 82 let b: i64 = digest[i] & 0xff 83 let hi: i64 = (b >> 4) & 15 84 let lo: i64 = b & 15 85 if hi < 10 { dst[o] = (48 + hi) as u8 } else { dst[o] = (87 + hi) as u8 } 86 if lo < 10 { dst[o+1] = (48 + lo) as u8 } else { dst[o+1] = (87 + lo) as u8 } 87 o = o + 2; i = i + 1 88 } 89 return o 90} 91 92func main(argc: i64, argv: *i64) -> i64 { 93 if argc < 2 { 94 pe("usage: nx_aimode_read <share-url> [out-path]\n" as *u8) 95 sys_exit(2); return 2 96 } 97 let share_url: *u8 = argv[1] as *u8 98 let id: *u8 = sys_mmap(256); let idl: i64 = r_share_id(share_url, id) 99 100 // out path 101 let path: *u8 = sys_mmap(1024) 102 var pp: i64 = 0 103 if argc >= 3 { pp = rcat(path, 0, argv[2] as *u8) } 104 else { 105 pp = rcat(path, 0, "knowledge/fetched/aimode_" as *u8) 106 if idl > 0 { var q: i64 = 0; while id[q] != (0 as u8) { path[pp] = id[q]; pp = pp + 1; q = q + 1 } } 107 else { pp = rcat(path, pp, "unknown" as *u8) } 108 pp = rcat(path, pp, ".answer.txt" as *u8) 109 } 110 path[pp] = 0 as u8 111 112 let store: *TrustStore = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt" as *u8, 512, R_CERTCAP) as *TrustStore 113 if (store as i64) == 0 { pe("REFUSED-FETCH: trust store load failed\n" as *u8); sys_exit(14); return 14 } 114 115 let out: *u8 = sys_mmap(R_OUTCAP) 116 let cites: *u8 = sys_mmap(R_CITECAP) 117 let finalu: *u8 = sys_mmap(R_URLCAP) 118 let ncit: *i64 = (sys_mmap(8)) as *i64 119 let tlen: *i64 = (sys_mmap(8)) as *i64 120 121 let rc: i64 = br_share_read(share_url, store, out, R_OUTCAP, cites, R_CITECAP, finalu, R_URLCAP, ncit, tlen, 1) 122 if rc != AM_OK { 123 if rc == AM_CONSENT { pe("REFUSED-CONSENT-WALL: a Google consent wall stands between the share link and its answer\n" as *u8); sys_exit(11); return 11 } 124 if rc == AM_SIGNIN { pe("REFUSED-SIGNIN: the share link demands a signed-in session\n" as *u8); sys_exit(10); return 10 } 125 if rc == AM_EMPTY { pe("REFUSED-EMPTY-BODY: a pass returned status but an empty body\n" as *u8); sys_exit(13); return 13 } 126 if rc == AM_NOCONT { pe("REFUSED-NO-ANSWER: the warm search document carried no /async/folwr continuation and no inline answer\n" as *u8); sys_exit(12); return 12 } 127 if rc == AM_NO_ANSWER { pe("REFUSED-NO-ANSWER: the continuation returned a shell with no answer text\n" as *u8); sys_exit(12); return 12 } 128 if rc == AM_NOFINAL { pe("REFUSED-NO-ANSWER: the share link never resolved to a search document (redirects did not settle)\n" as *u8); sys_exit(15); return 15 } 129 pe("REFUSED-FETCH: could not fetch a pass over sovereign TLS\n" as *u8); sys_exit(14); return 14 130 } 131 132 // build the output document: header, answer text, citation list. 133 let doc: *u8 = sys_mmap(R_DOCCAP) 134 var d: i64 = rcat(doc, 0, "# nx_aimode_read v1\n# share_url=" as *u8) 135 d = rcat(doc, d, share_url); doc[d] = 10 as u8; d = d + 1 136 d = rcat(doc, d, "# final_url=" as *u8); d = rcat(doc, d, finalu); doc[d] = 10 as u8; d = d + 1 137 d = rcat(doc, d, "# fetched_at=" as *u8); d = rcatn(doc, d, sys_now_realtime_sec()); doc[d] = 10 as u8; d = d + 1 138 d = rcat(doc, d, "# extraction_coverage=unknown; complete_conversation_not_established\n" as *u8) 139 d = rcat(doc, d, "# citations=" as *u8); d = rcatn(doc, d, ncit[0]); doc[d] = 10 as u8; d = d + 1 140 doc[d] = 10 as u8; d = d + 1 141 var a: i64 = 0 142 while a < tlen[0] { doc[d] = out[a]; d = d + 1; a = a + 1 } 143 doc[d] = 10 as u8; d = d + 1; doc[d] = 10 as u8; d = d + 1 144 d = rcat(doc, d, "## Citations (" as *u8); d = rcatn(doc, d, ncit[0]); d = rcat(doc, d, ") -- server-rendered /url? beacon references (opaque Google redirect tokens)\n" as *u8) 145 var cl: i64 = 0; while cites[cl] != (0 as u8) { doc[d] = cites[cl]; d = d + 1; cl = cl + 1 } 146 147 let write_rc: i64 = atomic_rewrite_checked(path, doc, d) 148 if write_rc != 0 { 149 if write_rc == AR_CHECK_UNCERTAIN { 150 pe("AIMODE-OUTPUT-COMMIT-UNCERTAIN: rename occurred but durability/readback failed; inspect output before retry\n" as *u8) 151 sys_exit(17); return 17 152 } 153 pe("REFUSED-OUTPUT-WRITE: checked atomic output failed before verified commit; shared writer reason=" as *u8) 154 pn(0 - write_rc); pe("\n" as *u8) 155 sys_exit(16); return 16 156 } 157 158 // provenance: the CITED url is the SHARE url (never the internal /search or /async endpoint). 159 let digest: *u8 = sys_mmap(32) 160 sha256_digest(doc, d, digest) 161 let row: *u8 = sys_mmap(4096) 162 var rp: i64 = rcat(row, 0, "prov|" as *u8) 163 rp = rcatn(row, rp, sys_now_realtime_sec()); row[rp] = 124 as u8; rp = rp + 1 164 rp = rcat(row, rp, share_url); row[rp] = 124 as u8; rp = rp + 1 165 rp = rcat(row, rp, path); row[rp] = 124 as u8; rp = rp + 1 166 rp = r_hex32(row, rp, digest); row[rp] = 124 as u8; rp = rp + 1 167 rp = rcatn(row, rp, d); row[rp] = 124 as u8; rp = rp + 1 168 rp = rcatn(row, rp, 2); row[rp] = 10 as u8; rp = rp + 1 // hops: share.google's measured double redirect 169 let jfd: i64 = sys_openat_append("knowledge/status/fetch_provenance.jrnl" as *u8, MODE_0644) 170 if jfd >= 0 { let prov_written:i64=sys_write(jfd,row,rp);let prov_closed:i64=sys_close(jfd);if prov_written!=rp||prov_closed!=0{pe("AIMODE-PROVENANCE-UNWRITTEN: incomplete append/close; output exists but provenance requires inspection\n" as *u8)} } 171 else { pe("AIMODE-PROVENANCE-UNWRITTEN: cannot append fetch_provenance.jrnl -- this mirror reads UNPROVEN to the refs gate\n" as *u8) } 172 173 pw("NX-AIMODE-READ OK id=" as *u8); pw(id); pw(" citations=" as *u8); pn(ncit[0]); pw(" text_bytes=" as *u8); pn(tlen[0]); pw(" file=" as *u8); pw(path); pw("\n" as *u8) 174 sys_exit(0); return 0 175}