code wiki / _hdl_build / nx_doctor_datadriven_test.nx
nx_doctor_datadriven_test.nx source
↩ module page · 87 lines · 5166 B
1// nx_doctor_datadriven_test.nx -- DATA-DRIVEN self-heal with CLEAN RACI. The Doctor is
2// NOT told which keyword to fix; it LEARNS the offending token from the Engineer's
3// captured diagnostic, then heals exactly that. This generalizes the fixer beyond a
4// hardcoded match/in pair to ANY reserved-keyword-as-identifier the compiler flags.
5// ENGINEER (R: detect) eng_compile_diag -> compile-fail + captures the diagnostic
6// DOCTOR (R: diagnose+fix) doc_offending_kw reads the artifact -> learns 'match';
7// doc_heal_token renames exactly that token
8// ENGINEER (R: verify) eng_compile -> re-verifies the healed candidate
9// WARDEN/COUNCIL (A) cc_council -> ACTs only on the Engineer's verdict
10// The fixer never names its own target (data, not guess) and never blesses its own fix.
11// Known answer: original FAILS, learned token = "match", healed COMPILES, council ACT.
12
13import "nx_doctor_fix.nx" // DOCTOR (diagnose-the-fix + apply)
14import "nx_engineer_crash.nx" // ENGINEER (detect + capture diagnostic + re-verify)
15import "nx_crew_council.nx" // WARDEN/COUNCIL (govern)
16
17func dd_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
18func dd_num(v: i64) -> i64 {
19 let b: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m }
20 let t: *u8 = sys_mmap(28); var k: i64 = 0
21 if m == 0 { t[0] = 48; k = 1 }
22 while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 }
23 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
24 sys_write(1, b, k); return 0
25}
26func dd_streq(a: *u8, b: *u8) -> i64 {
27 var i: i64 = 0
28 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 }
29 if b[i] != (0 as u8) { return 0 }
30 return 1
31}
32
33// NOTE on structure: each step's verdict is stored to a MEMORY array r[] the instant it
34// is computed, then tallied at the end. A previous version held each result in a local
35// across the ~12 calls to the gate and the known-good compiler MISCOMPILED it (a value
36// live across many calls was not spilled -- register pressure), so rc_bad read as -3 in
37// the print yet >=0 at the gate. Storing to memory immediately keeps live ranges short
38// and the gate honest. (The Engineer catches crashes/compile-fails; a comparison-
39// flipping logic miscompile like this is the harder class the codegen arc still owes.)
40func main() -> i64 {
41 dd_puts("=== DATA-DRIVEN self-heal: DOCTOR learns the token from the ENGINEER's diagnostic ===\n" as *u8)
42 let kg: *u8 = "_offc/nx_cc_known_good.elf" as *u8
43 let bad: *u8 = "runtime/_hdl_build/nx_eng_badsrc.nx" as *u8
44 let healed: *u8 = "runtime/_hdl_build/_doctor_dd_healed.nx" as *u8
45 let tok: *u8 = sys_mmap(64)
46 let a: *CrewAction = sys_mmap(64) as *CrewAction
47 let why: *i64 = sys_mmap(8) as *i64
48 let r: *i64 = sys_mmap(8 * 8) as *i64 // verdict slots, memory-backed
49
50 // 1. ENGINEER detects AND captures the diagnostic artifact (does not fix)
51 let rc_bad: i64 = eng_compile_diag(kg, bad, "/tmp/dd.s" as *u8, "/tmp/dd.err" as *u8)
52 r[0] = 0; if rc_bad < 0 { r[0] = 1 }
53 dd_puts(" ENGINEER detect : original compiles? " as *u8); if rc_bad < 0 { dd_puts("NO -- diagnostic captured\n" as *u8) } else { dd_puts("yes (nothing to fix?!)\n" as *u8) }
54
55 // 2. DOCTOR diagnoses the fix from the artifact -- LEARNS the token (not told it)
56 let tlen: i64 = doc_offending_kw("/tmp/dd.err" as *u8, tok)
57 r[1] = dd_streq(tok, "match" as *u8)
58 dd_puts(" DOCTOR learn : offending keyword from diagnostic = '" as *u8); dd_puts(tok); dd_puts("' (len " as *u8); dd_num(tlen); dd_puts(")\n" as *u8)
59
60 // 3. DOCTOR heals exactly that learned token (does not verify/admit)
61 let renames: i64 = doc_heal_token(bad, healed, tok)
62 r[2] = 0; if renames > 0 { r[2] = 1 }
63 dd_puts(" DOCTOR fix : renamed '" as *u8); dd_puts(tok); dd_puts("' -> '" as *u8); dd_puts(tok); dd_puts("_', chars added = " as *u8); dd_num(renames); dd_puts("\n" as *u8)
64
65 // 4. ENGINEER re-verifies (separate organ)
66 let rc_heal: i64 = eng_compile(kg, healed, "/tmp/dd2.s" as *u8)
67 r[3] = 0; if rc_heal == 0 { r[3] = 1 }
68 dd_puts(" ENGINEER verify : healed compiles? " as *u8); if rc_heal == 0 { dd_puts("YES\n" as *u8) } else { dd_puts("no (heal failed)\n" as *u8) }
69
70 // 5. WARDEN/COUNCIL govern -- ACT only on the Engineer's verdict
71 var ok: i64 = 0
72 if rc_heal == 0 { ok = 1 }
73 cc_set(a, "admit data-driven heal of learned reserved keyword" as *u8, ok, 1, 1, 1, 1)
74 let vd: i64 = cc_council(a, why)
75 r[4] = 0; if vd == CC_ACT { r[4] = 1 }
76 dd_puts(" COUNCIL govern : verdict = " as *u8); dd_puts(cc_verdict_name(vd)); dd_puts("\n" as *u8)
77
78 dd_puts("----------------------------------------------------------------\n" as *u8)
79 dd_puts(" Doctor learned the target from the diagnostic -- heals ANY flagged keyword, not a fixed list.\n" as *u8)
80
81 // GATE: tally the memory-backed verdicts. exit 0 only if all five passed.
82 var ec: i64 = 0
83 var i: i64 = 0
84 while i < 5 { if r[i] != 1 { if ec == 0 { ec = i + 1 } } i = i + 1 }
85 sys_exit(ec)
86 return ec
87}