nx_crashresume_census.nx source
↩ module page · 206 lines · 9155 B
1// nx_crashresume_census.nx -- ONE-SHOT crash-resume census CLI (CR-R0, crash-resume->SOTA roadmap
2// 2026-07-15). Measures whether the workstream capture plane is LIVE so a crash costs minutes, not
3// hand archaeology: HEARTBEAT staleness + REGISTRY staleness + CAPTURE lag (sessions vs captured
4// state) + MEMORY lag (sessions vs banked memory). Prints per-cell verdicts + permille and appends
5// one summary line to knowledge/status/crashresume_census.log (append-only journal).
6// usage: nx_crashresume_census [conf] [hb_log] [reg_path] [sessions_dir] [memory_dir]
7// conf rows: "hb_window_sec N" / "reg_window_sec N" / "cap_window_sec N" / "mem_window_sec N"
8// ('#' comments; malformed rows dropped fail-safe). No conf -> documented defaults below (the
9// conf is the rule-11 lever; defaults exist so a read-only census still runs on a bare tree).
10// Missing evidence -> UNKNOWN, never fabricated. ALWAYS exits 0 (a census must never fail its
11// caller); the verdict lives in the output + journal. Read-only apart from the journal append.
12// license_tier: ORIGINAL expect_exit: 0
13import "nx_syscalls.nx"
14import "nx_crashresume_census_core.nx"
15const K_MAGIC_86400: i64 = 86400
16const K_MAGIC_3600: i64 = 3600
17const K_MAGIC_8192: i64 = 8192
18const K_MAGIC_8191: i64 = 8191
19const K_MAGIC_262144: i64 = 262144
20const K_MAGIC_262143: i64 = 262143
21const K_MAGIC_1024: i64 = 1024
22
23func c_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
24
25// MIGRATED to the shared emitter 2026-08-06 (debt 1785516350). The old body mmapped a 32-byte
26// scratch and never freed it -- 4096B leaked per call at page granularity. nxi_out runs the SAME
27// ccz_cat_num digits through a shim that always frees, so emitted bytes are identical.
28func c_putn(v: i64) -> i64 { nxi_out(v); return 0 }
29
30func c_vname(v: i64) -> *u8 {
31 if v == CR_GREEN { return "GREEN" as *u8 }
32 if v == CR_RED { return "RED" as *u8 }
33 return "UNKNOWN" as *u8
34}
35
36// does buf[ws..we) equal the NUL-terminated key?
37func c_word_is(buf: *u8, ws: i64, we: i64, key: *u8) -> i64 {
38 let kl: i64 = ccz_slen(key)
39 if we - ws != kl { return 0 }
40 var i: i64 = 0
41 while i < kl { if buf[ws+i] != key[i] { return 0 } i = i + 1 }
42 return 1
43}
44
45// print one cell line: CRZ cell=<name> ts=<ts> age_s=<age|-1> window=<w> v=<verdict>
46func c_cell(name: *u8, ts: i64, now: i64, w: i64, v: i64) -> i64 {
47 c_puts("CRZ cell=" as *u8)
48 c_puts(name)
49 c_puts(" ts=" as *u8)
50 c_putn(ts)
51 c_puts(" age_s=" as *u8)
52 if ts > 0 { c_putn(now - ts) } else { c_putn(0 - 1) }
53 c_puts(" window=" as *u8)
54 c_putn(w)
55 c_puts(" v=" as *u8)
56 c_puts(c_vname(v))
57 c_puts("\n" as *u8)
58 return 0
59}
60
61func main(argc: i64, argv: *i64) -> i64 {
62 var confp: *u8 = "knowledge/crashresume_census.conf" as *u8
63 var hbp: *u8 = "knowledge/status/wms_heartbeat.log" as *u8
64 var regp: *u8 = "knowledge/store/ws-manifest.txt" as *u8
65 var sesp: *u8 = "/mnt/c/Users/elder/.claude/projects/C--Users-elder" as *u8
66 var memp: *u8 = "/mnt/c/Users/elder/.claude/projects/C--Users-elder/memory" as *u8
67 if argc >= 2 { confp = argv[1] as *u8 }
68 if argc >= 3 { hbp = argv[2] as *u8 }
69 if argc >= 4 { regp = argv[3] as *u8 }
70 if argc >= 5 { sesp = argv[4] as *u8 }
71 if argc >= 6 { memp = argv[5] as *u8 }
72
73 // default windows (overridden by conf rows -- the config lever)
74 var hb_w: i64 = K_MAGIC_86400
75 var reg_w: i64 = K_MAGIC_86400
76 var cap_w: i64 = K_MAGIC_3600
77 var mem_w: i64 = K_MAGIC_86400
78
79 let conf: *u8 = sys_mmap(K_MAGIC_8192)
80 let cn: i64 = ccz_read(confp, conf, K_MAGIC_8191)
81 if cn > 0 {
82 let ep: *i64 = sys_mmap(16) as *i64
83 var ls: i64 = 0
84 while ls < cn {
85 var le: i64 = ls
86 var go: i64 = 1
87 while go == 1 { go = 0; if le < cn { if conf[le] != (10 as u8) { le = le + 1; go = 1 } } }
88 // skip leading ws
89 var i: i64 = ls
90 go = 1
91 while go == 1 { go = 0; if i < le { let c: i64 = conf[i] as i64; if c == 32 { i = i + 1; go = 1 } else { if c == 9 { i = i + 1; go = 1 } } } }
92 if i < le { if conf[i] != (35 as u8) {
93 let ws: i64 = i
94 go = 1
95 while go == 1 { go = 0; if i < le { let c: i64 = conf[i] as i64; if c != 32 { if c != 9 { i = i + 1; go = 1 } } } }
96 let we: i64 = i
97 go = 1
98 while go == 1 { go = 0; if i < le { let c: i64 = conf[i] as i64; if c == 32 { i = i + 1; go = 1 } else { if c == 9 { i = i + 1; go = 1 } } } }
99 let v: i64 = ccz_num_at(conf, le, i, ep)
100 if v >= 1 {
101 if c_word_is(conf, ws, we, "hb_window_sec" as *u8) == 1 { hb_w = v }
102 if c_word_is(conf, ws, we, "reg_window_sec" as *u8) == 1 { reg_w = v }
103 if c_word_is(conf, ws, we, "cap_window_sec" as *u8) == 1 { cap_w = v }
104 if c_word_is(conf, ws, we, "mem_window_sec" as *u8) == 1 { mem_w = v }
105 }
106 } }
107 ls = le + 1
108 }
109 }
110
111 let now: i64 = sys_now_realtime_sec()
112
113 // CELL 1: heartbeat staleness (content epochs -- wall-clock ground truth written by beaters)
114 let hbbuf: *u8 = sys_mmap(K_MAGIC_262144)
115 let hn: i64 = ccz_read(hbp, hbbuf, K_MAGIC_262143)
116 var hb_ts: i64 = 0
117 if hn > 0 { hb_ts = ccz_max_epoch(hbbuf, hn) }
118 let v_hb: i64 = ccz_stale_verdict(hb_ts, now, hb_w)
119
120 // CELL 2: registry SSOT staleness (manifest mtime)
121 let reg_ts: i64 = ccz_mtime(regp)
122 let v_reg: i64 = ccz_stale_verdict(reg_ts, now, reg_w)
123
124 // CELL 3: capture lag -- newest session transcript vs newest captured state (hb or registry)
125 let ses_ts: i64 = ccz_newest_mtime_ext(sesp, ".jsonl" as *u8)
126 let cap_ts: i64 = ccz_max(hb_ts, reg_ts)
127 let v_cap: i64 = ccz_lag_verdict(ses_ts, cap_ts, cap_w)
128
129 // CELL 4: memory lag -- newest session transcript vs newest banked memory file
130 let mem_ts: i64 = ccz_newest_mtime_ext(memp, ".md" as *u8)
131 let v_mem: i64 = ccz_lag_verdict(ses_ts, mem_ts, mem_w)
132
133 c_puts("CRZ now=" as *u8)
134 c_putn(now)
135 c_puts("\n" as *u8)
136 c_cell("heartbeat" as *u8, hb_ts, now, hb_w, v_hb)
137 c_cell("registry" as *u8, reg_ts, now, reg_w, v_reg)
138 c_puts("CRZ cell=capture_lag ses_ts=" as *u8)
139 c_putn(ses_ts)
140 c_puts(" cap_ts=" as *u8)
141 c_putn(cap_ts)
142 c_puts(" lag_s=" as *u8)
143 if ses_ts > 0 { if cap_ts > 0 { c_putn(ses_ts - cap_ts) } else { c_putn(0 - 1) } } else { c_putn(0 - 1) }
144 c_puts(" window=" as *u8)
145 c_putn(cap_w)
146 c_puts(" v=" as *u8)
147 c_puts(c_vname(v_cap))
148 c_puts("\n" as *u8)
149 c_puts("CRZ cell=memory_lag ses_ts=" as *u8)
150 c_putn(ses_ts)
151 c_puts(" mem_ts=" as *u8)
152 c_putn(mem_ts)
153 c_puts(" lag_s=" as *u8)
154 if ses_ts > 0 { if mem_ts > 0 { c_putn(ses_ts - mem_ts) } else { c_putn(0 - 1) } } else { c_putn(0 - 1) }
155 c_puts(" window=" as *u8)
156 c_putn(mem_w)
157 c_puts(" v=" as *u8)
158 c_puts(c_vname(v_mem))
159 c_puts("\n" as *u8)
160
161 var greens: i64 = 0
162 var reds: i64 = 0
163 var unknowns: i64 = 0
164 if v_hb == CR_GREEN { greens = greens + 1 } else { if v_hb == CR_RED { reds = reds + 1 } else { unknowns = unknowns + 1 } }
165 if v_reg == CR_GREEN { greens = greens + 1 } else { if v_reg == CR_RED { reds = reds + 1 } else { unknowns = unknowns + 1 } }
166 if v_cap == CR_GREEN { greens = greens + 1 } else { if v_cap == CR_RED { reds = reds + 1 } else { unknowns = unknowns + 1 } }
167 if v_mem == CR_GREEN { greens = greens + 1 } else { if v_mem == CR_RED { reds = reds + 1 } else { unknowns = unknowns + 1 } }
168 let permille: i64 = greens * 1000 / 4
169 var verdict: *u8 = "GREEN" as *u8
170 if unknowns > 0 { verdict = "UNKNOWN" as *u8 }
171 if reds > 0 { verdict = "RED" as *u8 }
172
173 // summary line -> stdout + append-only journal
174 let line: *u8 = sys_mmap(K_MAGIC_1024)
175 var o: i64 = 0
176 o = ccz_cat_str(line, o, "CRZ-SUM ts=" as *u8)
177 o = ccz_cat_num(line, o, now)
178 o = ccz_cat_str(line, o, " permille=" as *u8)
179 o = ccz_cat_num(line, o, permille)
180 o = ccz_cat_str(line, o, " green=" as *u8)
181 o = ccz_cat_num(line, o, greens)
182 o = ccz_cat_str(line, o, " red=" as *u8)
183 o = ccz_cat_num(line, o, reds)
184 o = ccz_cat_str(line, o, " unknown=" as *u8)
185 o = ccz_cat_num(line, o, unknowns)
186 o = ccz_cat_str(line, o, " hb=" as *u8)
187 o = ccz_cat_str(line, o, c_vname(v_hb))
188 o = ccz_cat_str(line, o, " reg=" as *u8)
189 o = ccz_cat_str(line, o, c_vname(v_reg))
190 o = ccz_cat_str(line, o, " cap=" as *u8)
191 o = ccz_cat_str(line, o, c_vname(v_cap))
192 o = ccz_cat_str(line, o, " mem=" as *u8)
193 o = ccz_cat_str(line, o, c_vname(v_mem))
194 o = ccz_cat_str(line, o, " verdict=" as *u8)
195 o = ccz_cat_str(line, o, verdict)
196 o = ccz_cat_str(line, o, "\n" as *u8)
197 sys_write(1, line, o)
198 let lfd: i64 = sys_openat_append("knowledge/status/crashresume_census.log" as *u8, 420)
199 if lfd >= 0 {
200 sys_write(lfd, line, o)
201 sys_close(lfd)
202 } else {
203 c_puts("CRZ note=journal-open-failed (stdout only)\n" as *u8)
204 }
205 return 0
206}