code wiki / _hdl_build / nx_doc_build_resolve.nx

nx_doc_build_resolve.nx source

↩ module page · 123 lines · 7325 B

1// nx_doc_build_resolve.nx -- Automatically builds, diagnoses, and heals modules with real-time error resolution and rebuild verification. 2import "nx_gate_gn.nx" 3// nx_doc_build_resolve.nx -- the ACTIVE autonomous build-resolve loop (the closest thing to the Doctor wire-in 4// that needs no other-workstream edit: it COMPOSES nx_sov_build_run by FORKING it, never modifies it). Given a 5// module name it: (1) builds it via nx_sov_build_run with the child's stdout+stderr redirected to a log -- so the 6// ASSEMBLER's own message (e.g. "UNDEFINED label: main") is captured, not just the runner's wrapper text; (2) on 7// failure reads that log as the real diagnostic and runs the autonomous resolve (dah_resolve recall->route->fix-> 8// verify); (3) for a HEALED source writes a <name>_healed twin and REBUILDS it (--build-only, no smoke side 9// effects) to prove fail->green autonomously; (4) for NOFIX prints the recalled remedy + the library / reserved-kw 10// diagnosis; (5) for UNKNOWN flags a novel class to teach. Run the ELF DIRECTLY (not under the runner's smoke) so 11// the nested builds never trip NX-GATE-NESTED-BUILD. run: nx_doc_build_resolve.elf <module> license_tier: ORIGINAL 12import "nx_syscalls.nx" 13import "nx_doc_autoheal.nx" 14import "nx_doc_kwscan.nx" 15import "nx_doc_mainscan.nx" 16const K_MAGIC_8192: i64 = 8192 17const K_MAGIC_2048: i64 = 2048 18 19func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 20func slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 21func dcat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var i: i64=0; while s[i]!=(0 as u8){ dst[o]=s[i]; o=o+1; i=i+1 } dst[o]=0 as u8; return o } 22 23// fork + redirect stdout/stderr + execve; parent waits; returns WEXITSTATUS (or 128+signal). Mirrors sbr_run. 24func dbr_run(path: *u8, argv: *i64, envp: *i64, ro: i64, re: i64) -> i64 { 25 let pid: i64 = sys_fork() 26 if pid == 0 { 27 if ro >= 0 { sys_dup3(ro, 1, 0) } 28 if re >= 0 { sys_dup3(re, 2, 0) } 29 sys_execve(path, argv, envp) 30 sys_exit(127) 31 } 32 let st: *i64 = sys_mmap(16) as *i64 33 sys_wait4(pid, st, 0) 34 let sig: i64 = st[0] & 0x7f 35 if sig != 0 { return 128 + sig } 36 return (st[0] >> 8) & 0xff 37} 38// build <name> via nx_sov_build_run, stdout+stderr -> logpath. buildonly=1 passes --build-only (skip the smoke run). 39func dbr_build(name: *u8, buildonly: i64, logpath: *u8) -> i64 { 40 let exe: *u8 = "_offc/nx_sov_build_run.elf" as *u8 41 let fd: i64 = sys_openat_wr(logpath, 420) 42 let a: *i64 = sys_mmap(8*4) as *i64 43 a[0] = exe as i64; a[1] = name as i64 44 if buildonly == 1 { a[2] = "--build-only" as *u8 as i64; a[3] = 0 } else { a[2] = 0 } 45 let envp: *i64 = sys_mmap(16) as *i64; envp[0] = 0 46 let rc: i64 = dbr_run(exe, a, envp, fd, fd) 47 if fd >= 0 { sys_close(fd) } 48 return rc 49} 50func write_all(path: *u8, buf: *u8, len: i64) -> i64 { 51 let fd: i64 = sys_openat_wr(path, 420); if fd < 0 { return 0-1 } 52 let w: i64 = sys_write(fd, buf, len); sys_close(fd); return w 53} 54 55func main(argc: i64, argv: *i64) -> i64 { 56 if argc < 2 { 57 gp("nx_doc_build_resolve: usage: nx_doc_build_resolve <module>\n" as *u8) 58 gp(" builds <module>; on failure auto-captures the real diagnostic, resolves (heal/diagnose), and rebuilds a healed twin.\n" as *u8) 59 return 0 60 } 61 let name: *u8 = argv[1] as *u8 62 63 // locate the source: runtime/_hdl_build/<name>.nx, else runtime/<name>.nx 64 let srcpath: *u8 = sys_mmap(512); var o: i64 = 0 65 o = dcat(srcpath, 0, "runtime/_hdl_build/" as *u8); o = dcat(srcpath, o, name); o = dcat(srcpath, o, ".nx" as *u8) 66 var in_hdl: i64 = 1 67 let chk: i64 = sys_openat_rd(srcpath) 68 if chk < 0 { in_hdl = 0; o = 0; o = dcat(srcpath, 0, "runtime/" as *u8); o = dcat(srcpath, o, name); o = dcat(srcpath, o, ".nx" as *u8) } else { sys_close(chk) } 69 70 let log: *u8 = sys_mmap(256); o = 0; o = dcat(log, 0, "/tmp/_dbr_" as *u8); o = dcat(log, o, name); o = dcat(log, o, ".log" as *u8) 71 72 gp("=== nx_doc_build_resolve: " as *u8); gp(name); gp(" ===\n" as *u8) 73 let rc1: i64 = dbr_build(name, 0, log) 74 gp(" initial build rc=" as *u8); gn(rc1); gp("\n" as *u8) 75 if rc1 == 0 { gp(" GREEN: built clean, nothing to resolve.\n" as *u8); return 0 } 76 77 // read the captured diagnostic (runner message + assembler stderr) and the source 78 let lp: *i64 = sys_mmap(16) as *i64; lp[0] = 0 79 let diag: *u8 = sys_read_file(log, lp); var dn: i64 = 0 80 if (diag as i64) != 0 { dn = lp[0] } 81 gp(" captured diagnostic:\n" as *u8); if dn > 0 { sys_write(1, diag, dn) } 82 83 let sp: *i64 = sys_mmap(16) as *i64; sp[0] = 0 84 let src: *u8 = sys_read_file(srcpath, sp) 85 if (src as i64) == 0 { gp(" ERROR: cannot read source " as *u8); gp(srcpath); gp("\n" as *u8); return 1 } 86 let n: i64 = sp[0] 87 88 let out: *u8 = sys_mmap(n + K_MAGIC_8192); let oid: *u8 = sys_mmap(128); let orem: *u8 = sys_mmap(K_MAGIC_2048) 89 let r: i64 = dah_resolve(diag, dn, src, n, out, n + K_MAGIC_8192, oid, orem) 90 91 if r == 1 { 92 let hname: *u8 = sys_mmap(256); var ho: i64 = 0; ho = dcat(hname, 0, name); ho = dcat(hname, ho, "_healed" as *u8) 93 let hpath: *u8 = sys_mmap(512); var hp: i64 = 0 94 if in_hdl == 1 { hp = dcat(hpath, 0, "runtime/_hdl_build/" as *u8) } else { hp = dcat(hpath, 0, "runtime/" as *u8) } 95 hp = dcat(hpath, hp, hname); hp = dcat(hpath, hp, ".nx" as *u8) 96 write_all(hpath, out, slen(out)) 97 gp(" HEALED (recall=" as *u8); gp(oid); gp("): wrote healed twin -> " as *u8); gp(hpath); gp("\n" as *u8) 98 let log2: *u8 = sys_mmap(256); var l2: i64 = 0; l2 = dcat(log2, 0, "/tmp/_dbr_" as *u8); l2 = dcat(log2, l2, hname); l2 = dcat(log2, l2, ".log" as *u8) 99 let rc2: i64 = dbr_build(hname, 1, log2) 100 gp(" rebuild " as *u8); gp(hname); gp(" (build-only) rc=" as *u8); gn(rc2); gp("\n" as *u8) 101 if rc2 == 0 { gp(" => AUTONOMOUS RESOLVE PROVEN: fail -> green (apply with: cp " as *u8); gp(hpath); gp(" " as *u8); gp(srcpath); gp(").\n" as *u8) } 102 else { gp(" => healed twin still fails to build; needs manual attention.\n" as *u8) } 103 return 0 104 } 105 if r == 0 { 106 gp(" NOFIX (recall=" as *u8); gp(oid); gp("): no source rewrite applied.\n" as *u8) 107 if slen(orem) > 0 { gp(" recalled remedy: " as *u8); gp(orem); gp("\n" as *u8) } 108 if ms_is_library_build_error(diag, dn, src, n) == 1 { 109 gp(" LIBRARY-BUILD: no `func main` + missing-entry error -> a LIBRARY built standalone. Build it through its consumer/gate (do NOT add a fake main).\n" as *u8) 110 return 0 111 } 112 let kw: *u8 = sys_mmap(64); let pos: *i64 = sys_mmap(16) as *i64 113 if kws_scan(src, n, kw, pos) == 1 { 114 let sug: *u8 = sys_mmap(64); kws_suggest(kw, sug) 115 gp(" RESERVED-KW: `" as *u8); gp(kw); gp("` used as an identifier at byte offset " as *u8); gn(pos[0]); gp(" -> rename to `" as *u8); gp(sug); gp("` (manual).\n" as *u8) 116 return 0 117 } 118 gp(" no auto-diagnosis matched; recall-and-report only.\n" as *u8) 119 return 0 120 } 121 gp(" UNKNOWN: no lesson recalled for this diagnostic = a NOVEL class. Diagnose it, then teach the team (seed a ki- lesson via nx_meet_bug_train) so it auto-recalls next time.\n" as *u8) 122 return 0 123}