code wiki / _hdl_build / nx_research_gaps.nx

nx_research_gaps.nx source

↩ module page · 96 lines · 4830 B

1// nx_research_gaps.nx -- THE CLEAN OPEN-GAPS DIGEST (the actionable feedback signal to operator + Claude). The 2// raw research_gaps.txt is append-only history (cluttered with resolved + duplicate flags); the research_queue is 3// the SOURCE OF TRUTH (live statuses). This reads the queue, collects the DISTINCT topics whose status is still 4// INADEQUATE, and writes knowledge/index/research_open_gaps.txt -- the precise, deduped list of what the 5// researcher still cannot serve = where to improve / fetch deeper to unblock the auto-builder. Loose coupling: 6// consumes the queue artifact, writes a digest artifact. expect_exit: 0 license_tier: ORIGINAL 7import "nx_search_inverted_persist.nx" // brings syscalls 8import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 9 10const RGP_CAP: i64 = 8192 11 12func rgp_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 13// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 14// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 15// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 16// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 17func rgp_num(v: i64) -> i64 { nxi_out(v); return 0 } 18func rgp_line_end(buf: *u8, i: i64, end: i64) -> i64 { 19 var p: i64=i; var stop: i64=0 20 while stop==0 { if p>=end { stop=1 } else { if buf[p]==(10 as u8) { stop=1 } else { p=p+1 } } } 21 return p 22} 23func rgp_scan(buf: *u8, i: i64, end: i64) -> i64 { 24 var p: i64=i; var stop: i64=0 25 while stop==0 { if p>=end { stop=1 } else { if buf[p]==(32 as u8) { stop=1 } else { if buf[p]==(10 as u8) { stop=1 } else { p=p+1 } } } } 26 return p 27} 28// equal-range compare: buf[a_off..a_off+a_len) vs buf[b_off..b_off+b_len) 29func rgp_eq(buf: *u8, a_off: i64, a_len: i64, b_off: i64, b_len: i64) -> i64 { 30 if a_len != b_len { return 0 } 31 var i: i64=0 32 while i < a_len { if buf[a_off+i] != buf[b_off+i] { return 0 } i=i+1 } 33 return 1 34} 35 36func main() -> i64 { 37 rgp_puts("=== nx_research_gaps: clean open-gaps digest (currently INADEQUATE topics) ===\n" as *u8) 38 let qbox: *i64 = sys_mmap(16) as *i64 39 let q: *u8 = sys_read_file("knowledge/index/research_queue.txt" as *u8, qbox) 40 if q == 0 as *u8 { rgp_puts(" queue empty -- no requests\n" as *u8); sys_exit(0); return 0 } 41 let qlen: i64 = qbox[0] 42 43 let off: *i64 = sys_mmap(8*RGP_CAP) as *i64 // distinct open-gap topic offsets into q 44 let len: *i64 = sys_mmap(8*RGP_CAP) as *i64 45 var nopen: i64 = 0 46 var served: i64 = 0 47 var i: i64 = 0 48 while i < qlen { 49 let ls: i64 = i 50 let le: i64 = rgp_line_end(q, i, qlen) 51 if le > ls { 52 // <id> <status> <topic> 53 let e1: i64 = rgp_scan(q, ls, le) 54 var j: i64 = e1; if j<le { if q[j]==(32 as u8) { j=j+1 } } 55 let e2: i64 = rgp_scan(q, j, le) 56 let st_off: i64 = j; let st_len: i64 = e2 - j 57 var p: i64 = e2; if p<le { if q[p]==(32 as u8) { p=p+1 } } 58 let topic_off: i64 = p; let topic_len: i64 = le - p 59 // status == SERVED ? (6 chars, 'S') 60 if st_len == 6 { if q[st_off]==(83 as u8) { served = served + 1 } } 61 // status == INADEQUATE ? (10 chars, 'I') 62 if st_len == 10 { if q[st_off]==(73 as u8) { 63 if topic_len > 0 { 64 // dedup against already-collected open topics 65 var dup: i64 = 0 66 var k: i64 = 0 67 while k < nopen { if rgp_eq(q, off[k], len[k], topic_off, topic_len)==1 { dup=1 } k=k+1 } 68 if dup == 0 { if nopen < RGP_CAP { off[nopen]=topic_off; len[nopen]=topic_len; nopen=nopen+1 } } 69 } 70 } } 71 } 72 i = le; if i < qlen { i = i + 1 } 73 } 74 75 // write the clean digest 76 let fd: i64 = sys_openat_wr("knowledge/index/research_open_gaps.txt" as *u8, 0x1a4) 77 var w: i64 = 0 78 while w < nopen { 79 if fd >= 0 { sys_write(fd, ((q as i64)+off[w]) as *u8, len[w]); sys_write(fd, "\n" as *u8, 1) } 80 w = w + 1 81 } 82 if fd >= 0 { sys_close(fd) } 83 84 rgp_puts(" served="); rgp_num(served); rgp_puts(" OPEN GAPS (distinct, still inadequate)="); rgp_num(nopen) 85 rgp_puts(" -> knowledge/index/research_open_gaps.txt\n" as *u8) 86 if nopen > 0 { 87 rgp_puts(" IMPROVE THE RESEARCHER / FETCH DEEPER for:\n" as *u8) 88 var r: i64 = 0 89 while r < nopen { 90 rgp_puts(" - "); sys_write(1, ((q as i64)+off[r]) as *u8, len[r]); rgp_puts("\n" as *u8) 91 r = r + 1 92 } 93 } else { rgp_puts(" no open gaps -- the researcher currently serves every requested topic\n" as *u8) } 94 rgp_puts(" GAPS-OK\n" as *u8) 95 sys_exit(0); return 0 96}