code wiki / _hdl_build / nx_infomgmt_gate.nx

nx_infomgmt_gate.nx source

↩ module page · 672 lines · 26571 B

1// nx_infomgmt_gate.nx -- THE INFORMATION-MANAGEMENT GATE: one command re-proves 2// the sovereign storage substrate rung-1 claim set (segment store + canonical 3// CID), evidence-driven + durable. Pure NishiLang, NO SQL, no .sh. 4// 5// Rows (each = a claim; FAIL on any row = RED, never silenced): 6// canon-determinism same logical record, two field insertion orders 7// => IDENTICAL canonical bytes => IDENTICAL CID 8// canon-distinct different record => different CID (no collisions by 9// construction of the encoding) 10// fresh-process-read records written+committed by a CHILD PROCESS that 11// exits; parent reads byte-exact (no shared memory -- 12// the bytes came off disk) 13// time-travel v2 shadows v1 on get(); BOTH versions remain readable 14// in history (the additive law as a query surface) 15// tombstone-additive delete = tombstone: get() says GONE, history still 16// serves the old bytes (nothing is ever destroyed) 17// crash-invisibility fault injection: child dies BEFORE the commit point 18// (temp written, no rename/manifest) => key absent, 19// prior data intact, manifest unchanged 20// reopen-determinism all reads repeated from scratch are byte-identical 21// and the canonical CID re-derives identically 22// 23// EXCEED rows vs SQL-class stores: time-travel + tombstone-additive + 24// crash-invisibility are capabilities SQLite does not give by default. 25// Durable verdicts: knowledge/status/infomgmt_gate.log. 26// license_tier: ORIGINAL 27 28import "nx_syscalls.nx" 29import "nx_canon_cid.nx" 30import "nx_seg_store.nx" 31 32const IG_ROWS: i64 = 15 33 34func ig_p(s: *u8) -> i64 { 35 var n: i64 = 0 36 while s[n] != (0 as u8) { n = n + 1 } 37 sys_write(1, s, n) 38 return 0 39} 40 41func ig_fp(fd: i64, s: *u8) -> i64 { 42 var n: i64 = 0 43 while s[n] != (0 as u8) { n = n + 1 } 44 sys_write(fd, s, n) 45 return 0 46} 47 48func ig_fn(fd: i64, v: i64) -> i64 { 49 let bb: *u8 = sys_mmap(28) 50 var m: i64 = v 51 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) } 52 let t: *u8 = sys_mmap(28) 53 var k: i64 = 0 54 if m == 0 { t[0] = 48 as u8; k = 1 } 55 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 56 var i: i64 = 0 57 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 58 sys_write(fd, bb, k) 59 return 0 60} 61 62func ig_memeq(a: *u8, b: *u8, n: i64) -> i64 { 63 var i: i64 = 0 64 while i < n { 65 if a[i] != b[i] { return 0 } 66 i = i + 1 67 } 68 return 1 69} 70 71func ig_streq(a: *u8, b: *u8) -> i64 { 72 var i: i64 = 0 73 while 1 == 1 { 74 if a[i] != b[i] { return 0 } 75 if a[i] == (0 as u8) { return 1 } 76 i = i + 1 77 } 78 return 0 79} 80 81func ig_report(logfd: i64, name: *u8, pass: i64) -> i64 { 82 var fdi: i64 = 0 83 while fdi < 2 { 84 var fd: i64 = 1 85 if fdi == 1 { fd = logfd } 86 if fd > 0 { 87 ig_fp(fd, "INFOMGMT-GATE row=" as *u8) 88 ig_fp(fd, name) 89 if pass == 1 { ig_fp(fd, " verdict=PASS\n" as *u8) } 90 if pass != 1 { ig_fp(fd, " verdict=FAIL\n" as *u8) } 91 } 92 fdi = fdi + 1 93 } 94 return 0 95} 96 97// fork a child that writes records into segid then commits (mode 1) or 98// crash-writes only the temp (mode 2); parent waits. Records are passed as 99// (kind,key,val,vlen) quads in q[], nq of them. 100func ig_child_write(prefix: *u8, segid: i64, mode: i64, q: *i64, nq: i64) -> i64 { 101 let pid: i64 = sys_fork() 102 if pid == 0 { 103 let w: *i64 = ss_begin() 104 var i: i64 = 0 105 while i < nq { 106 ss_add(w, q[i * 4], (q[i * 4 + 1]) as *u8, (q[i * 4 + 2]) as *u8, q[i * 4 + 3]) 107 i = i + 1 108 } 109 var rc: i64 = 0 110 if mode == 1 { rc = ss_commit(prefix, w, segid) } 111 if mode == 2 { rc = ss_crashwrite(prefix, w, segid) } 112 if rc != 0 { sys_exit(9) } 113 sys_exit(0) 114 } 115 let st: *i64 = sys_mmap(16) as *i64 116 sys_wait4(pid, st, 0) 117 return st[0] 118} 119 120func main() -> i64 { 121 let logfd: i64 = sys_openat_append("knowledge/status/infomgmt_gate.log" as *u8, 0x1a4) 122 if logfd > 0 { 123 ig_fp(logfd, "INFOMGMT-GATE epoch=" as *u8) 124 ig_fn(logfd, sys_now_realtime_sec()) 125 ig_fp(logfd, " run-start rung=1 (segment-store + canonical-cid)\n" as *u8) 126 } 127 128 // fresh per-run store prefix (flat files; no mkdir needed) 129 let prefix: *u8 = sys_mmap(128) 130 var po: i64 = 0 131 po = ss_cat(prefix, po, "/tmp/im" as *u8) 132 po = ss_catn(prefix, po, sys_now_us()) 133 po = ss_cat(prefix, po, "-" as *u8) 134 prefix[po] = 0 as u8 135 136 var passed: i64 = 0 137 138 // ---- record A: same logical record, two insertion orders ---- 139 let k1: *i64 = sys_mmap(8 * 4) as *i64 140 let v1: *i64 = sys_mmap(8 * 4) as *i64 141 k1[0] = "name" as *u8 as i64 142 v1[0] = "diora_baird" as *u8 as i64 143 k1[1] = "layer" as *u8 as i64 144 v1[1] = "L6" as *u8 as i64 145 k1[2] = "maturity" as *u8 as i64 146 v1[2] = "functional" as *u8 as i64 147 let k2: *i64 = sys_mmap(8 * 4) as *i64 148 let v2: *i64 = sys_mmap(8 * 4) as *i64 149 k2[0] = "maturity" as *u8 as i64 150 v2[0] = "functional" as *u8 as i64 151 k2[1] = "name" as *u8 as i64 152 v2[1] = "diora_baird" as *u8 as i64 153 k2[2] = "layer" as *u8 as i64 154 v2[2] = "L6" as *u8 as i64 155 156 let encA: *u8 = sys_mmap(4096) 157 let encA2: *u8 = sys_mmap(4096) 158 let lenA: i64 = canon_encode(k1, v1, 3, encA) 159 let lenA2: i64 = canon_encode(k2, v2, 3, encA2) 160 let cidA: *u8 = sys_mmap(80) 161 let cidA2: *u8 = sys_mmap(80) 162 cid_of(encA, lenA, cidA) 163 cid_of(encA2, lenA2, cidA2) 164 var ok: i64 = 0 165 if lenA == lenA2 { if ig_memeq(encA, encA2, lenA) == 1 { if ig_streq(cidA, cidA2) == 1 { ok = 1 } } } 166 ig_report(logfd, "canon-determinism" as *u8, ok) 167 passed = passed + ok 168 169 // ---- record B: one value differs => different CID ---- 170 let v3: *i64 = sys_mmap(8 * 4) as *i64 171 v3[0] = "diora_baird" as *u8 as i64 172 v3[1] = "L6" as *u8 as i64 173 v3[2] = "production" as *u8 as i64 174 let encB: *u8 = sys_mmap(4096) 175 let lenB: i64 = canon_encode(k1, v3, 3, encB) 176 let cidB: *u8 = sys_mmap(80) 177 cid_of(encB, lenB, cidB) 178 ok = 0 179 if ig_streq(cidA, cidB) == 0 { ok = 1 } 180 ig_report(logfd, "canon-distinct" as *u8, ok) 181 passed = passed + ok 182 183 // ---- seg 1 written + committed by a fresh child process ---- 184 let q1: *i64 = sys_mmap(8 * 8) as *i64 185 q1[0] = 1 186 q1[1] = "cap:diora" as *u8 as i64 187 q1[2] = encA as i64 188 q1[3] = lenA 189 q1[4] = 1 190 q1[5] = "cap:search" as *u8 as i64 191 q1[6] = encB as i64 192 q1[7] = lenB 193 let st1: i64 = ig_child_write(prefix, 1, 1, q1, 2) 194 let pp: *i64 = sys_mmap(16) as *i64 195 let ll: *i64 = sys_mmap(16) as *i64 196 ok = 0 197 if st1 == 0 { 198 let g1: i64 = ss_get(prefix, "cap:diora" as *u8, pp, ll) 199 if g1 == 1 { if ll[0] == lenA { if ig_memeq(pp[0] as *u8, encA, lenA) == 1 { 200 let g2: i64 = ss_get(prefix, "cap:search" as *u8, pp, ll) 201 if g2 == 1 { if ll[0] == lenB { if ig_memeq(pp[0] as *u8, encB, lenB) == 1 { ok = 1 } } } 202 } } } 203 } 204 ig_report(logfd, "fresh-process-read" as *u8, ok) 205 passed = passed + ok 206 207 // ---- seg 2: v2 of cap:diora (record B bytes) => shadows v1, history keeps both ---- 208 let q2: *i64 = sys_mmap(8 * 4) as *i64 209 q2[0] = 1 210 q2[1] = "cap:diora" as *u8 as i64 211 q2[2] = encB as i64 212 q2[3] = lenB 213 let st2: i64 = ig_child_write(prefix, 2, 1, q2, 1) 214 let kinds: *i64 = sys_mmap(8 * 260) as *i64 215 let ptrs: *i64 = sys_mmap(8 * 260) as *i64 216 let lens: *i64 = sys_mmap(8 * 260) as *i64 217 ok = 0 218 if st2 == 0 { 219 let g3: i64 = ss_get(prefix, "cap:diora" as *u8, pp, ll) 220 if g3 == 1 { if ll[0] == lenB { if ig_memeq(pp[0] as *u8, encB, lenB) == 1 { 221 let hn: i64 = ss_scan(prefix, "cap:diora" as *u8, kinds, ptrs, lens) 222 if hn == 2 { if lens[0] == lenA { if ig_memeq(ptrs[0] as *u8, encA, lenA) == 1 { ok = 1 } } } 223 } } } 224 } 225 ig_report(logfd, "time-travel" as *u8, ok) 226 passed = passed + ok 227 228 // ---- seg 3: tombstone cap:search => GONE on get, history additive ---- 229 let q3: *i64 = sys_mmap(8 * 4) as *i64 230 q3[0] = 2 231 q3[1] = "cap:search" as *u8 as i64 232 q3[2] = "" as *u8 as i64 233 q3[3] = 0 234 let st3: i64 = ig_child_write(prefix, 3, 1, q3, 1) 235 ok = 0 236 if st3 == 0 { 237 let g4: i64 = ss_get(prefix, "cap:search" as *u8, pp, ll) 238 if g4 == 0 { 239 let hn2: i64 = ss_scan(prefix, "cap:search" as *u8, kinds, ptrs, lens) 240 if hn2 == 2 { if lens[0] == lenB { if ig_memeq(ptrs[0] as *u8, encB, lenB) == 1 { ok = 1 } } } 241 } 242 } 243 ig_report(logfd, "tombstone-additive" as *u8, ok) 244 passed = passed + ok 245 246 // ---- seg 4: FAULT INJECTION -- child dies before the commit point ---- 247 let q4: *i64 = sys_mmap(8 * 4) as *i64 248 q4[0] = 1 249 q4[1] = "cap:ghost" as *u8 as i64 250 q4[2] = encB as i64 251 q4[3] = lenB 252 let st4: i64 = ig_child_write(prefix, 4, 2, q4, 1) 253 let segs: *i64 = sys_mmap(8 * 260) as *i64 254 ok = 0 255 if st4 == 0 { 256 let g5: i64 = ss_get(prefix, "cap:ghost" as *u8, pp, ll) 257 if g5 == (0 - 1) { 258 let g6: i64 = ss_get(prefix, "cap:diora" as *u8, pp, ll) 259 if g6 == 1 { if ig_memeq(pp[0] as *u8, encB, lenB) == 1 { 260 let ms: i64 = ss_manifest(prefix, segs) 261 if ms == 3 { ok = 1 } 262 } } 263 } 264 } 265 ig_report(logfd, "crash-invisibility" as *u8, ok) 266 passed = passed + ok 267 268 // ---- reopen-determinism: every read again from scratch + CID re-derives ---- 269 ok = 0 270 let g7: i64 = ss_get(prefix, "cap:diora" as *u8, pp, ll) 271 if g7 == 1 { if ig_memeq(pp[0] as *u8, encB, lenB) == 1 { 272 let cidR: *u8 = sys_mmap(80) 273 cid_of(pp[0] as *u8, ll[0], cidR) 274 if ig_streq(cidR, cidB) == 1 { 275 let g8: i64 = ss_get(prefix, "cap:search" as *u8, pp, ll) 276 if g8 == 0 { ok = 1 } 277 } 278 } } 279 ig_report(logfd, "reopen-determinism" as *u8, ok) 280 passed = passed + ok 281 282 // ---- fsync-durability (IM3): wrapper discriminates real fds, commit path green ---- 283 // sys_fsync must return 0 on a valid fd and EBADF on a junk fd (proves the 284 // syscall is wired, not a no-op), and a commit through the fsync'd path 285 // must still read back byte-exact. 286 ok = 0 287 let mfp: *u8 = sys_mmap(512) 288 var mo: i64 = 0 289 mo = ss_cat(mfp, mo, prefix) 290 mo = ss_cat(mfp, mo, "manifest.txt" as *u8) 291 mfp[mo] = 0 as u8 292 let ffd: i64 = sys_openat_rd(mfp) 293 if ffd >= 0 { 294 let f1: i64 = sys_fsync(ffd) 295 sys_close(ffd) 296 let f2: i64 = sys_fsync(0 - 1) 297 if f1 == 0 { if f2 == (0 - 9) { 298 let q5: *i64 = sys_mmap(8 * 4) as *i64 299 q5[0] = 1 300 q5[1] = "cap:fsync" as *u8 as i64 301 q5[2] = encA as i64 302 q5[3] = lenA 303 let st5: i64 = ig_child_write(prefix, 5, 1, q5, 1) 304 if st5 == 0 { 305 let g9: i64 = ss_get(prefix, "cap:fsync" as *u8, pp, ll) 306 if g9 == 1 { if ig_memeq(pp[0] as *u8, encA, lenA) == 1 { ok = 1 } } 307 } 308 } } 309 } 310 ig_report(logfd, "fsync-durability" as *u8, ok) 311 passed = passed + ok 312 313 // ---- key-index-oracle (IM2): binary-search reads == chronological scan ---- 314 // The scan path is the ORACLE; the index must agree on verdict AND bytes 315 // for every key state: live (cap:diora=v2), tombstoned (cap:search), 316 // never-written (cap:ghost), fresh single-segment (cap:fsync). 317 ok = 1 318 let pp2: *i64 = sys_mmap(16) as *i64 319 let ll2: *i64 = sys_mmap(16) as *i64 320 let names9: *i64 = sys_mmap(8 * 4) as *i64 321 names9[0] = "cap:diora" as *u8 as i64 322 names9[1] = "cap:search" as *u8 as i64 323 names9[2] = "cap:ghost" as *u8 as i64 324 names9[3] = "cap:fsync" as *u8 as i64 325 let hh: *i64 = ss_open(prefix) 326 let pp3: *i64 = sys_mmap(16) as *i64 327 let ll3: *i64 = sys_mmap(16) as *i64 328 var ki: i64 = 0 329 while ki < 4 { 330 let kk: *u8 = names9[ki] as *u8 331 let vs: i64 = ss_get(prefix, kk, pp, ll) 332 let vi: i64 = ss_get_idx(prefix, kk, pp2, ll2) 333 let vh: i64 = ss_hget(hh, kk, pp3, ll3) 334 if vs != vi { ok = 0 } 335 if vs != vh { ok = 0 } 336 if vs == 1 { if vi == 1 { 337 if ll[0] != ll2[0] { ok = 0 } 338 if ok == 1 { if ig_memeq(pp[0] as *u8, pp2[0] as *u8, ll[0]) == 0 { ok = 0 } } 339 if ll[0] != ll3[0] { ok = 0 } 340 if ok == 1 { if ig_memeq(pp[0] as *u8, pp3[0] as *u8, ll[0]) == 0 { ok = 0 } } 341 } } 342 ki = ki + 1 343 } 344 ig_report(logfd, "key-index-oracle" as *u8, ok) 345 passed = passed + ok 346 347 // ---- term-postings-oracle (IM2b): postings path == brute-force tokenize ---- 348 // Expectation computed by the ORACLE path (ss_hget + ss_tok_has per key); 349 // ss_term must return the same count AND every returned key's current 350 // record must actually contain the term. Terms chosen to exercise: 351 // multi-hit ("diora": 2 records), shadowed-version + tombstone exclusion 352 // ("production": only cap:diora's v2 -- cap:search had it but is 353 // tombstoned), and the negative ("zzznope": 0). 354 ok = 1 355 let qterms: *i64 = sys_mmap(8 * 4) as *i64 356 qterms[0] = "diora" as *u8 as i64 357 qterms[1] = "production" as *u8 as i64 358 qterms[2] = "zzznope" as *u8 as i64 359 let tkp: *i64 = sys_mmap(8 * 20) as *i64 360 let tkl: *i64 = sys_mmap(8 * 20) as *i64 361 let kcopy: *u8 = sys_mmap(256) 362 var exp_diora: i64 = 0 363 var exp_prod: i64 = 0 364 var qi: i64 = 0 365 while qi < 3 { 366 let qt: *u8 = qterms[qi] as *u8 367 var exp: i64 = 0 368 var oi: i64 = 0 369 while oi < 4 { 370 let g: i64 = ss_hget(hh, names9[oi] as *u8, pp3, ll3) 371 if g == 1 { if ss_tok_has(pp3[0] as *u8, ll3[0], qt) == 1 { exp = exp + 1 } } 372 oi = oi + 1 373 } 374 if qi == 0 { exp_diora = exp } 375 if qi == 1 { exp_prod = exp } 376 let got: i64 = ss_term(hh, qt, tkp, tkl, 16) 377 if got != exp { ok = 0 } 378 // membership: every returned key's current record contains the term 379 var ri: i64 = 0 380 while ri < got { 381 var x: i64 = 0 382 let ks: *u8 = tkp[ri] as *u8 383 while x < tkl[ri] { kcopy[x] = ks[x]; x = x + 1 } 384 kcopy[x] = 0 as u8 385 let g2: i64 = ss_hget(hh, kcopy, pp3, ll3) 386 if g2 != 1 { ok = 0 } 387 if g2 == 1 { if ss_tok_has(pp3[0] as *u8, ll3[0], qt) == 0 { ok = 0 } } 388 ri = ri + 1 389 } 390 qi = qi + 1 391 } 392 // sanity teeth: the multi-hit and single-hit expectations must be real 393 if exp_diora != 2 { ok = 0 } 394 if exp_prod != 1 { ok = 0 } 395 ig_report(logfd, "term-postings-oracle" as *u8, ok) 396 passed = passed + ok 397 398 // ---- multi-term-and-oracle (IM2c): postings intersection == full-scan AND ---- 399 // ORACLE = for every known key: current bytes (ss_hget) contain ALL terms 400 // (ss_tok_has, the same single tokenizer). Queries chosen to exercise: 401 // q0 diora+production -> 1 (cap:search ALSO had both but is 402 // tombstoned -- AND must exclude it) 403 // q1 diora+functional -> 1 (cap:diora's v1 had both; its CURRENT 404 // v2 lost "functional" -- the stale 405 // version must NOT answer = currency) 406 // q2 diora+zzznope -> 0 (empty intersection) 407 // q3 diora+layer+production-> 1 (3-term query) 408 // Runs PRE-compaction so shadowed versions still sit in live segments. 409 ok = 1 410 let qn: *i64 = sys_mmap(8 * 8) as *i64 411 let qts: *i64 = sys_mmap(8 * 16) as *i64 412 qn[0] = 2 413 qts[0] = "diora" as *u8 as i64 414 qts[1] = "production" as *u8 as i64 415 qn[1] = 2 416 qts[3] = "diora" as *u8 as i64 417 qts[4] = "functional" as *u8 as i64 418 qn[2] = 2 419 qts[6] = "diora" as *u8 as i64 420 qts[7] = "zzznope" as *u8 as i64 421 qn[3] = 3 422 qts[9] = "diora" as *u8 as i64 423 qts[10] = "layer" as *u8 as i64 424 qts[11] = "production" as *u8 as i64 425 let teeth: *i64 = sys_mmap(8 * 8) as *i64 426 teeth[0] = 1 427 teeth[1] = 1 428 teeth[2] = 0 429 teeth[3] = 1 430 let akp: *i64 = sys_mmap(8 * 20) as *i64 431 let akl: *i64 = sys_mmap(8 * 20) as *i64 432 let aterms: *i64 = sys_mmap(8 * 4) as *i64 433 var aq: i64 = 0 434 while aq < 4 { 435 let nt: i64 = qn[aq] 436 var ti: i64 = 0 437 while ti < nt { aterms[ti] = qts[aq * 3 + ti]; ti = ti + 1 } 438 // oracle expectation: full scan of known keys, ALL terms in current bytes 439 var exp: i64 = 0 440 var oi: i64 = 0 441 while oi < 4 { 442 let g: i64 = ss_hget(hh, names9[oi] as *u8, pp3, ll3) 443 if g == 1 { 444 var all: i64 = 1 445 ti = 0 446 while ti < nt { 447 if ss_tok_has(pp3[0] as *u8, ll3[0], aterms[ti] as *u8) == 0 { all = 0 } 448 ti = ti + 1 449 } 450 if all == 1 { exp = exp + 1 } 451 } 452 oi = oi + 1 453 } 454 if exp != teeth[aq] { ok = 0 } 455 let got: i64 = ss_term_and(hh, aterms, nt, akp, akl, 16) 456 if got != exp { ok = 0 } 457 // membership: every returned key's current record contains EVERY term 458 var ri: i64 = 0 459 while ri < got { 460 var x: i64 = 0 461 let ks: *u8 = akp[ri] as *u8 462 while x < akl[ri] { kcopy[x] = ks[x]; x = x + 1 } 463 kcopy[x] = 0 as u8 464 let g2: i64 = ss_hget(hh, kcopy, pp3, ll3) 465 if g2 != 1 { ok = 0 } 466 if g2 == 1 { 467 ti = 0 468 while ti < nt { 469 if ss_tok_has(pp3[0] as *u8, ll3[0], aterms[ti] as *u8) == 0 { ok = 0 } 470 ti = ti + 1 471 } 472 } 473 ri = ri + 1 474 } 475 aq = aq + 1 476 } 477 // single-term consistency: AND of one term == ss_term exactly 478 aterms[0] = "diora" as *u8 as i64 479 if ss_term_and(hh, aterms, 1, akp, akl, 16) != exp_diora { ok = 0 } 480 ig_report(logfd, "multi-term-and-oracle" as *u8, ok) 481 passed = passed + ok 482 483 // ---- compaction-equivalence (IM4): get() identical across the fold ---- 484 // Pre-compaction expectations (proven by earlier rows): cap:diora=encB, 485 // cap:search=GONE(0), cap:ghost=ABSENT(-1), cap:fsync=encA. Compact, then 486 // every key must answer IDENTICALLY on BOTH read paths, and the live 487 // manifest must hold exactly the one merged segment. 488 ok = 0 489 let cseg: i64 = ss_compact(prefix, 9000001) 490 if cseg == 9000001 { 491 ok = 1 492 let gd: i64 = ss_get(prefix, "cap:diora" as *u8, pp, ll) 493 if gd != 1 { ok = 0 } 494 if ok == 1 { if ig_memeq(pp[0] as *u8, encB, lenB) == 0 { ok = 0 } } 495 let gdi: i64 = ss_get_idx(prefix, "cap:diora" as *u8, pp2, ll2) 496 if gdi != 1 { ok = 0 } 497 if ok == 1 { if ig_memeq(pp2[0] as *u8, encB, lenB) == 0 { ok = 0 } } 498 if ss_get(prefix, "cap:search" as *u8, pp, ll) != 0 { ok = 0 } 499 if ss_get_idx(prefix, "cap:search" as *u8, pp2, ll2) != 0 { ok = 0 } 500 if ss_get(prefix, "cap:ghost" as *u8, pp, ll) != (0 - 1) { ok = 0 } 501 if ss_get_idx(prefix, "cap:ghost" as *u8, pp2, ll2) != (0 - 1) { ok = 0 } 502 let gf: i64 = ss_get(prefix, "cap:fsync" as *u8, pp, ll) 503 if gf != 1 { ok = 0 } 504 if ok == 1 { if ig_memeq(pp[0] as *u8, encA, lenA) == 0 { ok = 0 } } 505 let ms2: i64 = ss_manifest(prefix, segs) 506 if ms2 != 1 { ok = 0 } 507 // term search survives the fold with identical answers (fresh handle) 508 let hc: *i64 = ss_open(prefix) 509 let ckp: *i64 = sys_mmap(8 * 20) as *i64 510 let ckl: *i64 = sys_mmap(8 * 20) as *i64 511 if ss_term(hc, "diora" as *u8, ckp, ckl, 16) != exp_diora { ok = 0 } 512 if ss_term(hc, "production" as *u8, ckp, ckl, 16) != exp_prod { ok = 0 } 513 if ss_term(hc, "zzznope" as *u8, ckp, ckl, 16) != 0 { ok = 0 } 514 // AND queries survive the fold with identical answers 515 aterms[0] = "diora" as *u8 as i64 516 aterms[1] = "production" as *u8 as i64 517 if ss_term_and(hc, aterms, 2, ckp, ckl, 16) != 1 { ok = 0 } 518 aterms[1] = "functional" as *u8 as i64 519 if ss_term_and(hc, aterms, 2, ckp, ckl, 16) != 1 { ok = 0 } 520 aterms[1] = "zzznope" as *u8 as i64 521 if ss_term_and(hc, aterms, 2, ckp, ckl, 16) != 0 { ok = 0 } 522 } 523 ig_report(logfd, "compaction-equivalence" as *u8, ok) 524 passed = passed + ok 525 526 // ---- compaction-archive (IM4): history files survive, archive names them ---- 527 ok = 1 528 let arcp: *u8 = sys_mmap(512) 529 var aro: i64 = 0 530 aro = ss_cat(arcp, aro, prefix) 531 aro = ss_cat(arcp, aro, "manifest-archive.txt" as *u8) 532 arcp[aro] = 0 as u8 533 let aszp: *i64 = sys_mmap(16) as *i64 534 let ab: *u8 = ss_readall(arcp, aszp) 535 if aszp[0] <= 0 { ok = 0 } 536 // archive must list 4 retired segments (one line each) 537 var alines: i64 = 0 538 var ai: i64 = 0 539 while ai < aszp[0] { 540 if ab[ai] == (10 as u8) { alines = alines + 1 } 541 ai = ai + 1 542 } 543 if alines != 4 { ok = 0 } 544 // every retired segment's .docs file is STILL on disk and readable 545 var sg: i64 = 1 546 while sg < 6 { 547 if sg != 4 { 548 let sp9: *u8 = sys_mmap(512) 549 ss_segname(prefix, sg, 0, sp9) 550 let sfd9: i64 = sys_openat_rd(sp9) 551 if sfd9 < 0 { ok = 0 } 552 if sfd9 >= 0 { sys_close(sfd9) } 553 } 554 sg = sg + 1 555 } 556 ig_report(logfd, "compaction-archive" as *u8, ok) 557 passed = passed + ok 558 559 // ---- archive-time-travel (IM-AR): FULL history readable AFTER the fold ---- 560 // ss_scan_all = archived segments (srcs=0, chronological) then live (srcs=1). 561 // Post-compaction expectations derive from the proven fixture history: 562 // cap:diora -> 3 rows: archived v1=encA, archived v2=encB, live fold-copy 563 // =encB (pre-fold history BYTE-EXACT = nothing destroyed) 564 // cap:search -> 3 rows: archived put=encB, archived TOMBSTONE, live 565 // TOMBSTONE (deletes preserved in history) 566 // cap:fsync -> 2 rows: archived encA, live encA 567 // cap:ghost -> 0 rows (crash-written temp never entered ANY manifest) 568 ok = 1 569 let wsrc: *i64 = sys_mmap(8 * 260) as *i64 570 let na1: i64 = ss_scan_all(prefix, "cap:diora" as *u8, kinds, ptrs, lens, wsrc) 571 if na1 != 3 { ok = 0 } 572 if ok == 1 { 573 if kinds[0] != 1 { ok = 0 } 574 if lens[0] != lenA { ok = 0 } 575 if ok == 1 { if ig_memeq(ptrs[0] as *u8, encA, lenA) == 0 { ok = 0 } } 576 if kinds[1] != 1 { ok = 0 } 577 if lens[1] != lenB { ok = 0 } 578 if ok == 1 { if ig_memeq(ptrs[1] as *u8, encB, lenB) == 0 { ok = 0 } } 579 if kinds[2] != 1 { ok = 0 } 580 if lens[2] != lenB { ok = 0 } 581 if ok == 1 { if ig_memeq(ptrs[2] as *u8, encB, lenB) == 0 { ok = 0 } } 582 if wsrc[0] != 0 { ok = 0 } 583 if wsrc[1] != 0 { ok = 0 } 584 if wsrc[2] != 1 { ok = 0 } 585 } 586 let na2: i64 = ss_scan_all(prefix, "cap:search" as *u8, kinds, ptrs, lens, wsrc) 587 if na2 != 3 { ok = 0 } 588 if ok == 1 { 589 if kinds[0] != 1 { ok = 0 } 590 if lens[0] != lenB { ok = 0 } 591 if ok == 1 { if ig_memeq(ptrs[0] as *u8, encB, lenB) == 0 { ok = 0 } } 592 if kinds[1] != 2 { ok = 0 } 593 if kinds[2] != 2 { ok = 0 } 594 if wsrc[1] != 0 { ok = 0 } 595 if wsrc[2] != 1 { ok = 0 } 596 } 597 let na3: i64 = ss_scan_all(prefix, "cap:fsync" as *u8, kinds, ptrs, lens, wsrc) 598 if na3 != 2 { ok = 0 } 599 if ok == 1 { 600 if lens[0] != lenA { ok = 0 } 601 if lens[1] != lenA { ok = 0 } 602 if ig_memeq(ptrs[0] as *u8, encA, lenA) == 0 { ok = 0 } 603 if ig_memeq(ptrs[1] as *u8, encA, lenA) == 0 { ok = 0 } 604 if wsrc[0] != 0 { ok = 0 } 605 if wsrc[1] != 1 { ok = 0 } 606 } 607 if ss_scan_all(prefix, "cap:ghost" as *u8, kinds, ptrs, lens, wsrc) != 0 { ok = 0 } 608 ig_report(logfd, "archive-time-travel" as *u8, ok) 609 passed = passed + ok 610 611 // ---- postings-scale-bulk: a 4097-doc segment commits AND is searchable ---- 612 // 4097 docs exceeds the OLD fixed 4096 docs/segment cap (which silently 613 // emitted uninitialized doc offsets and dropped terms/pairs = silent 614 // search misses). Capacities are now DATA-DRIVEN from the writer size: 615 // the bulk commit must SUCCEED, term search must count EXACTLY 4097 616 // (every doc, none silently dropped), keyed reads of first/last bulk doc 617 // and the prior store must answer byte-exact. 618 ok = 0 619 let wbig: *i64 = ss_begin() 620 let kb9: *u8 = sys_mmap(64) 621 var bi: i64 = 0 622 var addrc: i64 = 0 623 while bi < 4097 { 624 var ko9: i64 = 0 625 ko9 = ss_cat(kb9, ko9, "bulk:" as *u8) 626 ko9 = ss_catn(kb9, ko9, bi) 627 kb9[ko9] = 0 as u8 628 if ss_add(wbig, 1, kb9, "vv bulkdoc" as *u8, 10) != 0 { addrc = 1 } 629 bi = bi + 1 630 } 631 let crc: i64 = ss_commit(prefix, wbig, 7777) 632 if addrc == 0 { if crc == 0 { 633 let ms9: i64 = ss_manifest(prefix, segs) 634 if ms9 == 2 { 635 let hb: *i64 = ss_open(prefix) 636 let bkp: *i64 = sys_mmap(8 * 4200) as *i64 637 let bkl: *i64 = sys_mmap(8 * 4200) as *i64 638 let nvv: i64 = ss_term(hb, "bulkdoc" as *u8, bkp, bkl, 4200) 639 if nvv == 4097 { 640 let gf1: i64 = ss_hget(hb, "bulk:0" as *u8, pp3, ll3) 641 let gf2: i64 = ss_hget(hb, "bulk:4096" as *u8, pp3, ll3) 642 if gf1 == 1 { if gf2 == 1 { if ll3[0] == 10 { 643 let g10: i64 = ss_get(prefix, "cap:diora" as *u8, pp, ll) 644 if g10 == 1 { if ig_memeq(pp[0] as *u8, encB, lenB) == 1 { ok = 1 } } 645 } } } 646 } 647 } 648 } } 649 ig_report(logfd, "postings-scale-bulk" as *u8, ok) 650 passed = passed + ok 651 652 let permil: i64 = (passed * 1000) / IG_ROWS 653 var fdi: i64 = 0 654 while fdi < 2 { 655 var fd: i64 = 1 656 if fdi == 1 { fd = logfd } 657 if fd > 0 { 658 ig_fp(fd, "INFOMGMT-GATE rows=" as *u8) 659 ig_fn(fd, IG_ROWS) 660 ig_fp(fd, " passed=" as *u8) 661 ig_fn(fd, passed) 662 ig_fp(fd, " permil=" as *u8) 663 ig_fn(fd, permil) 664 if passed == IG_ROWS { ig_fp(fd, " verdict=GREEN\n" as *u8) } 665 if passed != IG_ROWS { ig_fp(fd, " verdict=RED\n" as *u8) } 666 } 667 fdi = fdi + 1 668 } 669 if logfd > 0 { sys_close(logfd) } 670 if passed == IG_ROWS { return 0 } 671 return 1 672}