nx_crashresume_census_gate.nx source
↩ module page · 128 lines · 5900 B
1// nx_crashresume_census_gate.nx -- liar-killed GATE for the crash-resume census core (CR-R0).
2// Proves the cells DISCRIMINATE and never fabricate: fresh evidence -> GREEN, stale -> RED, missing
3// -> UNKNOWN (not GREEN, not RED-from-nothing), garbage tolerated, thresholds are PARAMETERS
4// (neg-control: same stale fixture flips GREEN under a huge window -- no hardcoded verdicts), mtime
5// cells driven by forged deterministic mtimes (sys_utimensat), dir walk honors the extension filter.
6// Fixtures live under /tmp (ext4, wiped-safe: everything recreated per run). Exit 0 only on 9/9.
7// license_tier: ORIGINAL expect_exit: 0
8import "nx_syscalls.nx"
9import "nx_crashresume_census_core.nx"
10
11func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
12
13// MIGRATED to the shared emitter 2026-08-06 (debt 1785516350). The old body mmapped a 32-byte
14// scratch and never freed it -- 4096B leaked per call at page granularity. nxi_out runs the SAME
15// ccz_cat_num digits through a shim that always frees, so emitted bytes are identical.
16func g_putn(v: i64) -> i64 { nxi_out(v); return 0 }
17
18func g_write(path: *u8, s: *u8) -> i64 {
19 let fd: i64 = sys_openat_wr(path, 420)
20 if fd < 0 { return 0 - 1 }
21 sys_write(fd, s, ccz_slen(s))
22 sys_close(fd)
23 return 0
24}
25
26// forge atime+mtime = e (deterministic staleness)
27func g_touch(path: *u8, e: i64) -> i64 {
28 let t: *i64 = sys_mmap(32) as *i64
29 t[0] = e
30 t[1] = 0
31 t[2] = e
32 t[3] = 0
33 return sys_utimensat(path, t)
34}
35
36func g_check(name: *u8, got: i64, want: i64, passp: *i64) -> i64 {
37 g_puts("T " as *u8)
38 g_puts(name)
39 g_puts(" got=" as *u8)
40 g_putn(got)
41 g_puts(" want=" as *u8)
42 g_putn(want)
43 if got == want { g_puts(" PASS\n" as *u8); passp[0] = passp[0] + 1 } else { g_puts(" FAIL\n" as *u8) }
44 return 0
45}
46
47func main(argc: i64, argv: *i64) -> i64 {
48 let pass: *i64 = sys_mmap(16) as *i64
49 pass[0] = 0
50 let now: i64 = sys_now_realtime_sec()
51 sys_mkdir("/tmp/crz_gate_fix" as *u8, 0x1ed)
52 sys_mkdir("/tmp/crz_gate_fix/dw" as *u8, 0x1ed)
53 let buf: *u8 = sys_mmap(65536)
54 let lb: *u8 = sys_mmap(1024)
55
56 // T1 fresh epoch -> GREEN
57 var o: i64 = 0
58 o = ccz_cat_str(lb, o, "HBX ws=T epoch=" as *u8)
59 o = ccz_cat_num(lb, o, now - 10)
60 o = ccz_cat_str(lb, o, " seq=1 actor=1 END\n" as *u8)
61 g_write("/tmp/crz_gate_fix/hb_fresh.log" as *u8, lb)
62 var n: i64 = ccz_read("/tmp/crz_gate_fix/hb_fresh.log" as *u8, buf, 65535)
63 var ts: i64 = ccz_max_epoch(buf, n)
64 g_check("fresh-epoch-GREEN" as *u8, ccz_stale_verdict(ts, now, 86400), CR_GREEN, pass)
65
66 // T2 stale epoch -> RED
67 o = 0
68 o = ccz_cat_str(lb, o, "HBX ws=T epoch=" as *u8)
69 o = ccz_cat_num(lb, o, now - 200000)
70 o = ccz_cat_str(lb, o, " seq=1 actor=1 END\n" as *u8)
71 g_write("/tmp/crz_gate_fix/hb_stale.log" as *u8, lb)
72 n = ccz_read("/tmp/crz_gate_fix/hb_stale.log" as *u8, buf, 65535)
73 let ts_stale: i64 = ccz_max_epoch(buf, n)
74 g_check("stale-epoch-RED" as *u8, ccz_stale_verdict(ts_stale, now, 86400), CR_RED, pass)
75
76 // T3 missing log -> UNKNOWN (never fabricated)
77 n = ccz_read("/tmp/crz_gate_fix/absent.log" as *u8, buf, 65535)
78 var ts3: i64 = 0
79 if n > 0 { ts3 = ccz_max_epoch(buf, n) }
80 g_check("missing-log-UNKNOWN" as *u8, ccz_stale_verdict(ts3, now, 86400), CR_UNKNOWN, pass)
81
82 // T4 garbage tolerated, valid old epoch still parsed -> RED (not crash, not GREEN)
83 o = 0
84 o = ccz_cat_str(lb, o, "epoch= epoch=zz junk\nHBX ws=T epoch=" as *u8)
85 o = ccz_cat_num(lb, o, now - 200000)
86 o = ccz_cat_str(lb, o, " END\ntrailing epoch=\n" as *u8)
87 g_write("/tmp/crz_gate_fix/hb_garbage.log" as *u8, lb)
88 n = ccz_read("/tmp/crz_gate_fix/hb_garbage.log" as *u8, buf, 65535)
89 let ts4: i64 = ccz_max_epoch(buf, n)
90 g_check("garbage-tolerated-RED" as *u8, ccz_stale_verdict(ts4, now, 86400), CR_RED, pass)
91
92 // T5 NEG-CONTROL: the SAME stale fixture flips GREEN under a huge window (threshold is a
93 // parameter, not a hardcoded verdict -- the conf lever is real)
94 g_check("negctl-window-param-GREEN" as *u8, ccz_stale_verdict(ts_stale, now, 10000000), CR_GREEN, pass)
95
96 // T6 mtime stale -> RED (forged mtime)
97 g_write("/tmp/crz_gate_fix/reg.txt" as *u8, "seg-1\n" as *u8)
98 g_touch("/tmp/crz_gate_fix/reg.txt" as *u8, now - 500000)
99 g_check("mtime-stale-RED" as *u8, ccz_stale_verdict(ccz_mtime("/tmp/crz_gate_fix/reg.txt" as *u8), now, 86400), CR_RED, pass)
100
101 // T7 mtime fresh -> GREEN
102 g_touch("/tmp/crz_gate_fix/reg.txt" as *u8, now - 10)
103 g_check("mtime-fresh-GREEN" as *u8, ccz_stale_verdict(ccz_mtime("/tmp/crz_gate_fix/reg.txt" as *u8), now, 86400), CR_GREEN, pass)
104
105 // T8 lag verdicts: capture behind -> RED; capture keeping up -> GREEN; no activity -> UNKNOWN
106 var ok8: i64 = 1
107 if ccz_lag_verdict(now - 10, now - 100000, 3600) != CR_RED { ok8 = 0 }
108 if ccz_lag_verdict(now - 10, now - 20, 3600) != CR_GREEN { ok8 = 0 }
109 if ccz_lag_verdict(0 - 1, now - 20, 3600) != CR_UNKNOWN { ok8 = 0 }
110 if ccz_lag_verdict(now - 10, 0 - 1, 3600) != CR_RED { ok8 = 0 }
111 g_check("lag-verdicts" as *u8, ok8, 1, pass)
112
113 // T9 dir walk honors the ext filter: a.jsonl older than b.txt; newest .jsonl must be a's mtime
114 g_write("/tmp/crz_gate_fix/dw/a.jsonl" as *u8, "x\n" as *u8)
115 g_write("/tmp/crz_gate_fix/dw/b.txt" as *u8, "y\n" as *u8)
116 g_touch("/tmp/crz_gate_fix/dw/a.jsonl" as *u8, now - 50)
117 g_touch("/tmp/crz_gate_fix/dw/b.txt" as *u8, now - 5)
118 var ok9: i64 = 0
119 if ccz_newest_mtime_ext("/tmp/crz_gate_fix/dw" as *u8, ".jsonl" as *u8) == now - 50 { ok9 = 1 }
120 g_check("dirwalk-ext-filter" as *u8, ok9, 1, pass)
121
122 g_puts("CRZ-GATE pass=" as *u8)
123 g_putn(pass[0])
124 g_puts("/9 verdict=" as *u8)
125 if pass[0] == 9 { g_puts("GREEN\n" as *u8); return 0 }
126 g_puts("RED\n" as *u8)
127 return 1
128}