code wiki / _hdl_build / nx_train_triage_sweep.nx
nx_train_triage_sweep.nx source
↩ module page · 136 lines · 6018 B
1// nx_train_triage_sweep.nx -- the CONDUCTOR's pulse step that closes the triage wiring callout:
2// every training report on file is diagnosed EVERY BEAT, and a verdict CHANGE auto-files a
3// PM-ESCALATION row (the sentinel pattern) so a sick training lane becomes backlog work without
4// Claude in the loop. Idempotent by construction (law 10): the PM row is filed ONLY when the
5// verdict differs from the LAST swept verdict for that report (read back from the triage log).
6// Conf-driven (law 11): knowledge/status/train_reports.conf rows "R <path>" -- adding a training
7// lane = adding a row, never code. Recovery to CONVERGED-HEALTHY logs but does not escalate.
8// BROKEN-REPORT escalates AND exits nonzero (the emitting lane itself is the defect -> pulse
9// ATTENTION). argv overrides (conf, triage-log, pm-log) = the Engineer's gate lane.
10// license_tier: ORIGINAL
11import "nx_train_triage.nx"
12
13func tsw_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 } dst[off+i] = 0 as u8; return off + i }
14
15// last swept verdict for a report: scan tlog for the LAST "TRIAGESWEEP report=<path> verdict="
16// row and copy its verdict token into out (NUL-terminated); returns 1 if found
17func tsw_prev_verdict(tlog: *u8, rpath: *u8, out: *u8) -> i64 {
18 let lenp: *i64 = sys_mmap(16) as *i64
19 let b: *u8 = sys_read_file(tlog, lenp)
20 let n: i64 = lenp[0]
21 if n <= 0 { return 0 }
22 let pre: *u8 = sys_mmap(256)
23 var o: i64 = 0
24 o = tsw_cat(pre, o, "TRIAGESWEEP report=" as *u8)
25 o = tsw_cat(pre, o, rpath)
26 o = tsw_cat(pre, o, " verdict=" as *u8)
27 var found: i64 = 0
28 var ls: i64 = 0
29 while ls < n {
30 var le: i64 = ls
31 var stop: i64 = 0
32 while stop == 0 {
33 if le >= n { stop = 1 } else { if b[le] == (10 as u8) { stop = 1 } else { le = le + 1 } }
34 }
35 if tt_match(b, ls, le, pre) == 1 {
36 var p: i64 = ls + o
37 var k: i64 = 0
38 var stop2: i64 = 0
39 while stop2 == 0 {
40 if p >= le { stop2 = 1 } else { if b[p] == (32 as u8) { stop2 = 1 } else {
41 if k < 40 { out[k] = b[p]; k = k + 1 }
42 p = p + 1
43 } }
44 }
45 out[k] = 0 as u8
46 found = 1
47 }
48 ls = le + 1
49 }
50 return found
51}
52func tsw_streq(a: *u8, b: *u8) -> i64 {
53 var i: i64 = 0
54 while a[i] != (0 as u8) {
55 if a[i] != b[i] { return 0 }
56 i = i + 1
57 }
58 if b[i] == (0 as u8) { return 1 }
59 return 0
60}
61
62func main(argc: i64, argv: *i64) -> i64 {
63 var conf: *u8 = "knowledge/status/train_reports.conf" as *u8
64 var tlog: *u8 = "knowledge/status/train_triage.log" as *u8
65 var pmlog: *u8 = "knowledge/status/pm_plan_durable.log" as *u8
66 if argc >= 2 { conf = argv[1] as *u8 }
67 if argc >= 3 { tlog = argv[2] as *u8 }
68 if argc >= 4 { pmlog = argv[3] as *u8 }
69 tt_w(1, "=== TRAIN-TRIAGE SWEEP (Conductor: diagnose every training report; escalate verdict CHANGES) ===\n" as *u8)
70 let lenp: *i64 = sys_mmap(16) as *i64
71 let b: *u8 = sys_read_file(conf, lenp)
72 let n: i64 = lenp[0]
73 if n <= 0 { tt_w(1, " conf missing/empty: " as *u8); tt_w(1, conf); tt_w(1, "\n" as *u8); sys_exit(1); return 1 }
74 var swept: i64 = 0
75 var escalated: i64 = 0
76 var broken: i64 = 0
77 var ls: i64 = 0
78 while ls < n {
79 var le: i64 = ls
80 var stop: i64 = 0
81 while stop == 0 {
82 if le >= n { stop = 1 } else { if b[le] == (10 as u8) { stop = 1 } else { le = le + 1 } }
83 }
84 if tt_match(b, ls, le, "R " as *u8) == 1 {
85 let rpath: *u8 = sys_mmap(256)
86 var k: i64 = 0
87 var p: i64 = ls + 2
88 var stop2: i64 = 0
89 while stop2 == 0 {
90 if p >= le { stop2 = 1 } else { if b[p] == (32 as u8) { stop2 = 1 } else {
91 if k < 200 { rpath[k] = b[p]; k = k + 1 }
92 p = p + 1
93 } }
94 }
95 rpath[k] = 0 as u8
96 if k > 0 {
97 let id: i64 = tt_diagnose(rpath)
98 let cur: *u8 = tt_name(id)
99 let prev: *u8 = sys_mmap(64)
100 let hadprev: i64 = tsw_prev_verdict(tlog, rpath, prev)
101 var changed: i64 = 1
102 if hadprev == 1 { if tsw_streq(cur, prev) == 1 { changed = 0 } }
103 tt_w(1, " report=" as *u8); tt_w(1, rpath)
104 tt_w(1, " verdict=" as *u8); tt_w(1, cur)
105 if changed == 1 { tt_w(1, " (CHANGED)\n" as *u8) } else { tt_w(1, " (steady)\n" as *u8) }
106 let lfd: i64 = sys_openat_append(tlog, 0x1a4)
107 if lfd >= 0 {
108 tt_w(lfd, "TRIAGESWEEP report=" as *u8); tt_w(lfd, rpath)
109 tt_w(lfd, " verdict=" as *u8); tt_w(lfd, cur)
110 tt_w(lfd, " epoch=" as *u8); tt_wn(lfd, sys_now_realtime_sec()); tt_w(lfd, "\n" as *u8)
111 sys_close(lfd)
112 }
113 if changed == 1 { if id != TT_HEALTHY {
114 let pfd: i64 = sys_openat_append(pmlog, 0x1a4)
115 if pfd >= 0 {
116 tt_w(pfd, "PM-ESCALATION source=train-triage report=" as *u8); tt_w(pfd, rpath)
117 tt_w(pfd, " verdict=" as *u8); tt_w(pfd, cur)
118 tt_w(pfd, " :: fix=" as *u8); tt_w(pfd, tt_fix(id)); tt_w(pfd, "\n" as *u8)
119 sys_close(pfd)
120 escalated = escalated + 1
121 }
122 } }
123 if id == TT_BROKEN { broken = broken + 1 }
124 swept = swept + 1
125 }
126 }
127 ls = le + 1
128 }
129 tt_w(1, " SWEEP: reports=" as *u8); tt_wn(1, swept)
130 tt_w(1, " escalated=" as *u8); tt_wn(1, escalated)
131 tt_w(1, " broken=" as *u8); tt_wn(1, broken); tt_w(1, "\n" as *u8)
132 if swept == 0 { sys_exit(1); return 1 }
133 if broken > 0 { sys_exit(1); return 1 }
134 sys_exit(0)
135 return 0
136}