nx_explore_grow.nx source
↩ module page · 112 lines · 5935 B
1// nx_explore_grow.nx -- THE NISHI EXPLORE TEAM, RUNG R5 "GROW": self-discovers its own capability
2// gaps (operator 2026-06-23: "each rung to be s class exceed" + "self healing"). This is the
3// cap_gap->discover half of the self-grow loop: it probes the rung table, finds the FIRST MISSING
4// rung, and emits its exact build-target (path::symbol) -- the precise thing the team toolchain must
5// author next. It also confirms when the ladder is COMPLETE (no gap) which is the re-census trigger.
6//
7// HONEST SCOPE (no-wave): R5 v1 = DISCOVER (find the gap) + DETECT-CLOSURE (ladder complete?) +
8// emit the build-target = the loop's orchestration. The AUTO-AUTHOR step (drive auto_builder to LAND
9// the discovered rung) routes to the team's emitter shapes -- NOT claimed here. So this exceeds a
10// static census (it names the NEXT build, not just present coverage) without overclaiming autonomy.
11//
12// SELF-GATE: prove it can find an INJECTED gap (real discovery, not a "0 gaps" stub) AND that the real
13// 6-rung ladder is now complete -> EXPLORE-GROW-GATE GREEN / run-exit=0. Reuses the census probe idiom.
14// license_tier: ORIGINAL
15import "nx_syscalls.nx"
16import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
17
18const EXG_FBUF: i64 = 4194304
19
20func exg_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
21func exg_puts(s: *u8) -> i64 { sys_write(1, s, exg_strlen(s)); 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 exg_putn(v: i64) -> i64 { nxi_out(v); return 0 }
27
28func exg_find(buf: *u8, lo: i64, hi: i64, pat: *u8, pl: i64) -> i64 {
29 if pl == 0 { return 0 }
30 var i: i64 = lo
31 while i + pl <= hi {
32 var j: i64 = 0
33 while j < pl { if buf[i + j] != pat[j] { j = pl + 1 } else { j = j + 1 } }
34 if j == pl { return 1 }
35 i = i + 1
36 }
37 return 0
38}
39
40// 1 iff the file at path opens AND contains sym. open-fail/absent => 0 (the gap signal).
41func exg_probe(path: *u8, sym: *u8, fbuf: *u8) -> i64 {
42 let fd: i64 = sys_openat_rd(path)
43 if fd < 0 { return 0 }
44 let n: i64 = sys_read(fd, fbuf, EXG_FBUF)
45 sys_close(fd)
46 if n <= 0 { return 0 }
47 return exg_find(fbuf, 0, n, sym, exg_strlen(sym))
48}
49
50func exg_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 }
51
52// scan the rung table; return index of the FIRST missing rung (or -1 if all present).
53// writes the gap's build-target "path::sym" into out_target (NUL-terminated).
54func exg_step(paths: *i64, syms: *i64, n: i64, fbuf: *u8, out_target: *u8) -> i64 {
55 var i: i64 = 0
56 while i < n {
57 let p: *u8 = paths[i] as *u8
58 let s: *u8 = syms[i] as *u8
59 if exg_probe(p, s, fbuf) == 0 {
60 var o: i64 = 0
61 o = exg_cat(out_target, o, p)
62 o = exg_cat(out_target, o, "::" as *u8)
63 o = exg_cat(out_target, o, s)
64 out_target[o] = 0 as u8
65 return i
66 }
67 i = i + 1
68 }
69 return 0 - 1
70}
71
72func main() -> i64 {
73 let fbuf: *u8 = sys_mmap(EXG_FBUF + 16)
74 exg_puts("=== NISHI EXPLORE (R5 GROW) -- self-discovers capability gaps ===\n" as *u8)
75
76 // the canonical 6-rung ladder table
77 let paths: *i64 = sys_mmap(8 * 8) as *i64
78 let syms: *i64 = sys_mmap(8 * 8) as *i64
79 paths[0] = "runtime/nx_dir.nx" as *u8 as i64; syms[0] = "func nx_dir_list" as *u8 as i64
80 paths[1] = "runtime/nx_dir.nx" as *u8 as i64; syms[1] = "func nx_dir_name_ends_with" as *u8 as i64
81 paths[2] = "runtime/nx_codegrep.nx" as *u8 as i64; syms[2] = "func cg_scan_dir" as *u8 as i64
82 paths[3] = "runtime/_hdl_build/nx_library_harvest_v2.nx" as *u8 as i64; syms[3] = "func lh2_query" as *u8 as i64
83 paths[4] = "runtime/nx_explore.nx" as *u8 as i64; syms[4] = "func ex_map" as *u8 as i64
84 paths[5] = "runtime/nx_explore_grow.nx" as *u8 as i64; syms[5] = "func exg_step" as *u8 as i64
85
86 let tgt: *u8 = sys_mmap(512)
87 let g_real: i64 = exg_step(paths, syms, 6, fbuf, tgt)
88 exg_puts("GROW real-ladder first-missing=" as *u8); exg_putn(g_real)
89 if g_real < 0 { exg_puts(" -> all 6 rungs present: INITIAL LADDER COMPLETE; self-grow now scans for the NEXT rung (regex / knowledge-corpus / semantic)\n" as *u8) }
90 else { exg_puts(" -> GAP at R" as *u8); exg_putn(g_real); exg_puts(" build-target=" as *u8); exg_puts(tgt); exg_puts("\n" as *u8) }
91
92 // INJECTED-GAP control: a copy of the table whose R3 path points at a non-existent organ.
93 let p2: *i64 = sys_mmap(8 * 8) as *i64
94 let s2: *i64 = sys_mmap(8 * 8) as *i64
95 var k: i64 = 0
96 while k < 6 { p2[k] = paths[k]; s2[k] = syms[k]; k = k + 1 }
97 p2[3] = "runtime/nx_zzz_absent_rung_qqx.nx" as *u8 as i64
98 let tgt2: *u8 = sys_mmap(512)
99 let g_inj: i64 = exg_step(p2, s2, 6, fbuf, tgt2)
100 exg_puts("GROW injected-gap first-missing=" as *u8); exg_putn(g_inj); exg_puts(" build-target=" as *u8); exg_puts(tgt2); exg_puts("\n" as *u8)
101
102 // self-gate: real ladder complete (-1) AND injected gap discovered exactly at R3
103 var ok: i64 = 1
104 if g_real != (0 - 1) { ok = 0; exg_puts("FAIL: real ladder shows a gap (expected complete)\n" as *u8) }
105 if g_inj != 3 { ok = 0; exg_puts("FAIL: injected gap not discovered at R3\n" as *u8) }
106 if ok == 1 {
107 exg_puts("EXPLORE-GROW-GATE GREEN -- discovers an injected gap + confirms the 6-rung ladder complete (R5 LIVE)\n" as *u8)
108 sys_exit(0); return 0
109 }
110 exg_puts("EXPLORE-GROW-GATE RED\n" as *u8)
111 sys_exit(1); return 1
112}