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}