code wiki / (root) / nx_framed_append_gate.nx

nx_framed_append_gate.nx source

↩ module page · 293 lines · 12238 B

1// nx_framed_append_gate.nx -- the REFEREE for WMS-R0 (atomic framed-append). 2// 3// Proves the nx_framed_append primitive defeats concurrent-appender tearing, AND 4// proves the test can actually DETECT tearing (the mandatory negative control). 5// 6// GOOD lane: N workers fork concurrently, each emits NRECS records via the NEW 7// single-write primitive fa_append(GOODPATH, ...). Expect ZERO torn 8// lines and ALL N*NRECS lines present (nothing lost, nothing torn). 9// BAD lane (NEGATIVE CONTROL): the SAME concurrency, but each record is emitted 10// the OLD way -- a SEQUENCE of separate sys_write() calls per record. 11// O_APPEND only makes ONE write atomic, not the sequence, so workers 12// interleave -> torn lines MUST appear. bad_torn == 0 => the detector 13// is worthless => RED (no false green). 14// TAMPER: an oversized record (rec_len+1 > cap) must be REJECTED with -2, 15// never silently written/torn. 16// 17// A line is WELL-FORMED iff it starts "FA w=" AND the bytes just before its '\n' 18// are "END" AND it contains exactly one " END" token. Any interleaving violates 19// one of those -> counted as torn. Output: rows -> stdout + the evidence log 20// knowledge/status/framed_append_gate.log, then a final verdict line. Exit 0 on 21// GREEN, 1 on RED. Sovereign: only nx_syscalls + nx_framed_append. 22// license_tier: ORIGINAL 23import "nx_syscalls.nx" 24import "nx_framed_append.nx" 25 26const NWORKERS: i64 = 16 // concurrency (raised so the neg-control tears robustly) 27const NRECS: i64 = 300 // records per worker 28const RECCAP: i64 = 256 // bounded record size for the primitive 29 30// dual-sink writer: stdout (fd 1) AND the evidence log fd 31func gp(logfd: i64, s: *u8) -> i64 { 32 var n: i64 = 0 33 while s[n] != (0 as u8) { n = n + 1 } 34 sys_write(1, s, n) 35 if logfd > 0 { sys_write(logfd, s, n) } 36 return 0 37} 38func gn(logfd: i64, v: i64) -> i64 { 39 let bb: *u8 = sys_mmap(28) 40 var m: i64 = v 41 if m < 0 { sys_write(1, "-\x00" as *u8, 1); if logfd > 0 { sys_write(logfd, "-\x00" as *u8, 1) } m = 0 - m } 42 let t: *u8 = sys_mmap(28) 43 var k: i64 = 0 44 if m == 0 { t[0] = 48 as u8; k = 1 } 45 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 46 var i: i64 = 0 47 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 48 sys_write(1, bb, k) 49 if logfd > 0 { sys_write(logfd, bb, k) } 50 return 0 51} 52 53// assemble one record into buf (NO trailing newline): "FA w=<wid> i=<seq> pid=<pid> END" 54// returns rec_len. The trailing " END" sentinel is what the parser checks for. 55func build_rec(buf: *u8, wid: i64, seq: i64, pid: i64) -> i64 { 56 var o: i64 = 0 57 o = fa_cat(buf, o, "FA w=\x00" as *u8) 58 o = fa_catn(buf, o, wid) 59 o = fa_cat(buf, o, " i=\x00" as *u8) 60 o = fa_catn(buf, o, seq) 61 o = fa_cat(buf, o, " pid=\x00" as *u8) 62 o = fa_catn(buf, o, pid) 63 o = fa_cat(buf, o, " END\x00" as *u8) 64 return o 65} 66 67// GOOD worker: NRECS framed single-write appends, then exit. 68func good_worker(wid: i64) -> i64 { 69 let pid: i64 = __syscall(39, 0, 0, 0, 0, 0, 0) // getpid 70 let buf: *u8 = sys_mmap(RECCAP + 16) 71 var i: i64 = 0 72 while i < NRECS { 73 let rl: i64 = build_rec(buf, wid, i, pid) 74 fa_append("/tmp/fa_good.log\x00" as *u8, buf, rl, RECCAP) 75 i = i + 1 76 } 77 return 0 78} 79 80// BAD worker (NEGATIVE CONTROL): same records, but emitted as a SEQUENCE of 81// separate sys_write() calls per record -- exactly the torn-line bug. Opens the 82// file ONCE in O_APPEND, then per record: many little writes + a final newline. 83// Concurrent workers interleave between these writes -> torn lines. 84func bad_worker(wid: i64) -> i64 { 85 let pid: i64 = __syscall(39, 0, 0, 0, 0, 0, 0) // getpid 86 let fd: i64 = sys_openat_append("/tmp/fa_bad.log\x00" as *u8, 0x1a4) 87 if fd < 0 { return 0 - 1 } 88 let nb: *u8 = sys_mmap(28) 89 var i: i64 = 0 90 while i < NRECS { 91 sys_write(fd, "FA w=\x00" as *u8, 5) 92 var l: i64 = 0; var m: i64 = wid 93 if m == 0 { nb[0] = 48 as u8; l = 1 } 94 while m > 0 { nb[l] = (48 + (m % 10)) as u8; m = m / 10; l = l + 1 } 95 var x: i64 = 0 96 let d1: *u8 = sys_mmap(28) 97 while x < l { d1[x] = nb[l - 1 - x]; x = x + 1 } 98 sys_write(fd, d1, l) 99 sys_write(fd, " i=\x00" as *u8, 3) 100 l = 0; m = i 101 if m == 0 { nb[0] = 48 as u8; l = 1 } 102 while m > 0 { nb[l] = (48 + (m % 10)) as u8; m = m / 10; l = l + 1 } 103 let d2: *u8 = sys_mmap(28); x = 0 104 while x < l { d2[x] = nb[l - 1 - x]; x = x + 1 } 105 sys_write(fd, d2, l) 106 sys_write(fd, " pid=\x00" as *u8, 6) 107 l = 0; m = pid 108 if m == 0 { nb[0] = 48 as u8; l = 1 } 109 while m > 0 { nb[l] = (48 + (m % 10)) as u8; m = m / 10; l = l + 1 } 110 let d3: *u8 = sys_mmap(28); x = 0 111 while x < l { d3[x] = nb[l - 1 - x]; x = x + 1 } 112 sys_write(fd, d3, l) 113 sys_write(fd, " END\x00" as *u8, 4) 114 sys_write(fd, "\n\x00" as *u8, 1) 115 i = i + 1 116 } 117 sys_close(fd) 118 return 0 119} 120 121// spawn NWORKERS children running f(wid), wait all. which: 0=good, 1=bad. 122func spawn_all(which: i64) -> i64 { 123 let pids: *i64 = sys_mmap(8 * (NWORKERS + 4)) as *i64 124 var w: i64 = 0 125 while w < NWORKERS { 126 let pid: i64 = sys_fork() 127 if pid == 0 { 128 if which == 0 { good_worker(w) } 129 if which == 1 { bad_worker(w) } 130 sys_exit(0) 131 } 132 pids[w] = pid 133 w = w + 1 134 } 135 let st: *i64 = sys_mmap(16) as *i64 136 w = 0 137 while w < NWORKERS { 138 sys_wait4(pids[w], st, 0) 139 w = w + 1 140 } 141 return 0 142} 143 144// parse a file: total_lines into outs[0], torn_count returned. 145// A '\n'-terminated line is WELL-FORMED iff: 146// - it begins with "FA w=" 147// - the 4 bytes immediately before the '\n' are " END" (space,E,N,D) 148// - it contains exactly one " END" occurrence (no embedded second record head) 149// Anything else (interleaved fragments, a record head mid-line, missing sentinel) 150// is TORN. An empty trailing segment (file ends with '\n') is not a line. 151func count_torn(path: *u8, outs: *i64) -> i64 { 152 let szp: *i64 = sys_mmap(16) as *i64 153 let b: *u8 = sys_read_file(path, szp) 154 let sz: i64 = szp[0] 155 var torn: i64 = 0 156 var lines: i64 = 0 157 var ls: i64 = 0 158 var i: i64 = 0 159 while i < sz { 160 if b[i] == (10 as u8) { 161 let llen: i64 = i - ls 162 lines = lines + 1 163 var ok: i64 = 1 164 // prefix "FA w=" (5 bytes) 165 if llen < 9 { ok = 0 } 166 if ok == 1 { 167 if b[ls] != (70 as u8) { ok = 0 } // F 168 if b[ls + 1] != (65 as u8) { ok = 0 } // A 169 if b[ls + 2] != (32 as u8) { ok = 0 } // space 170 if b[ls + 3] != (119 as u8) { ok = 0 } // w 171 if b[ls + 4] != (61 as u8) { ok = 0 } // = 172 } 173 // suffix " END" immediately before '\n' 174 if ok == 1 { 175 let e: i64 = i - 1 176 if b[e - 3] != (32 as u8) { ok = 0 } // space 177 if b[e - 2] != (69 as u8) { ok = 0 } // E 178 if b[e - 1] != (78 as u8) { ok = 0 } // N 179 if b[e] != (68 as u8) { ok = 0 } // D 180 } 181 // exactly one " END" token inside the line (no interleaved 2nd record) 182 if ok == 1 { 183 var ends: i64 = 0 184 var j: i64 = ls 185 while j + 3 < i + 1 { 186 if b[j] == (32 as u8) { 187 if b[j + 1] == (69 as u8) { 188 if b[j + 2] == (78 as u8) { 189 if b[j + 3] == (68 as u8) { ends = ends + 1 } 190 } 191 } 192 } 193 j = j + 1 194 } 195 if ends != 1 { ok = 0 } 196 // also: no second "FA w=" record-head embedded (head appears only at ls) 197 var k: i64 = ls + 1 198 while k + 4 < i + 1 { 199 if b[k] == (70 as u8) { 200 if b[k + 1] == (65 as u8) { 201 if b[k + 2] == (32 as u8) { 202 if b[k + 3] == (119 as u8) { 203 if b[k + 4] == (61 as u8) { ok = 0 } 204 } 205 } 206 } 207 } 208 k = k + 1 209 } 210 } 211 if ok == 0 { torn = torn + 1 } 212 ls = i + 1 213 } 214 i = i + 1 215 } 216 outs[0] = lines 217 return torn 218} 219 220func main() -> i64 { 221 let logfd: i64 = sys_openat_append("knowledge/status/framed_append_gate.log\x00" as *u8, 0x1a4) 222 gp(logfd, "FRAMED-APPEND epoch=\x00" as *u8) 223 gn(logfd, sys_now_realtime_sec()) 224 gp(logfd, " workers=\x00" as *u8); gn(logfd, NWORKERS) 225 gp(logfd, " recs=\x00" as *u8); gn(logfd, NRECS) 226 gp(logfd, " cap=\x00" as *u8); gn(logfd, RECCAP) 227 gp(logfd, "\n\x00" as *u8) 228 229 // fresh files each run (truncate) 230 let gtr: i64 = sys_openat_wr("/tmp/fa_good.log\x00" as *u8, 0x1a4) 231 if gtr > 0 { sys_close(gtr) } 232 let btr: i64 = sys_openat_wr("/tmp/fa_bad.log\x00" as *u8, 0x1a4) 233 if btr > 0 { sys_close(btr) } 234 235 // GOOD lane: concurrent framed single-write appends 236 spawn_all(0) 237 // BAD lane (NEGATIVE CONTROL): same concurrency, OLD multi-write pattern 238 spawn_all(1) 239 240 let outs: *i64 = sys_mmap(16) as *i64 241 let good_torn: i64 = count_torn("/tmp/fa_good.log\x00" as *u8, outs) 242 let good_lines: i64 = outs[0] 243 let bad_torn: i64 = count_torn("/tmp/fa_bad.log\x00" as *u8, outs) 244 let bad_lines: i64 = outs[0] 245 let want_lines: i64 = NWORKERS * NRECS 246 247 // TAMPER: oversized record (rec_len+1 > cap=8) must be REJECTED with -2 248 let trec: *u8 = sys_mmap(64) 249 var ti: i64 = 0 250 while ti < 32 { trec[ti] = 65 as u8; ti = ti + 1 } // 32 'A's, way over cap=8 251 let tamper_rc: i64 = fa_append("/tmp/fa_tamper.log\x00" as *u8, trec, 32, 8) 252 253 gp(logfd, "FA row=good_lines got=\x00" as *u8); gn(logfd, good_lines) 254 gp(logfd, " want=\x00" as *u8); gn(logfd, want_lines) 255 if good_lines == want_lines { gp(logfd, " verdict=PASS\n\x00" as *u8) } else { gp(logfd, " verdict=FAIL\n\x00" as *u8) } 256 257 gp(logfd, "FA row=good_torn got=\x00" as *u8); gn(logfd, good_torn) 258 gp(logfd, " want=0\x00" as *u8) 259 if good_torn == 0 { gp(logfd, " verdict=PASS\n\x00" as *u8) } else { gp(logfd, " verdict=FAIL\n\x00" as *u8) } 260 261 gp(logfd, "FA row=neg_control bad_lines=\x00" as *u8); gn(logfd, bad_lines) 262 gp(logfd, " bad_torn=\x00" as *u8); gn(logfd, bad_torn) 263 gp(logfd, " want=POSITIVE\x00" as *u8) 264 if bad_torn > 0 { gp(logfd, " verdict=PASS(detector-sees-tearing)\n\x00" as *u8) } else { gp(logfd, " verdict=FAIL(no-tearing-detected)\n\x00" as *u8) } 265 266 gp(logfd, "FA row=tamper_oversize got=\x00" as *u8); gn(logfd, tamper_rc) 267 gp(logfd, " want=-2\x00" as *u8) 268 if tamper_rc == (0 - 2) { gp(logfd, " verdict=PASS\n\x00" as *u8) } else { gp(logfd, " verdict=FAIL\n\x00" as *u8) } 269 270 var green: i64 = 1 271 if good_lines != want_lines { green = 0 } 272 if good_torn != 0 { green = 0 } 273 if bad_torn <= 0 { green = 0 } 274 if tamper_rc != (0 - 2) { green = 0 } 275 276 gp(logfd, "FRAMED-APPEND verdict=\x00" as *u8) 277 if green == 1 { gp(logfd, "GREEN\x00" as *u8) } else { gp(logfd, "RED\x00" as *u8) } 278 gp(logfd, " good_lines=\x00" as *u8); gn(logfd, good_lines) 279 gp(logfd, " good_torn=\x00" as *u8); gn(logfd, good_torn) 280 gp(logfd, " bad_torn=\x00" as *u8); gn(logfd, bad_torn) 281 gp(logfd, " tamper=\x00" as *u8); gn(logfd, tamper_rc) 282 if green == 0 { 283 gp(logfd, " reason=\x00" as *u8) 284 if good_lines != want_lines { gp(logfd, "good-lines-lost \x00" as *u8) } 285 if good_torn != 0 { gp(logfd, "GOOD-TORE \x00" as *u8) } 286 if bad_torn <= 0 { gp(logfd, "neg-control-saw-no-tearing \x00" as *u8) } 287 if tamper_rc != (0 - 2) { gp(logfd, "oversize-not-rejected \x00" as *u8) } 288 } 289 gp(logfd, "\n\x00" as *u8) 290 if logfd > 0 { sys_close(logfd) } 291 if green == 1 { return 0 } 292 return 1 293}