code wiki / _hdl_build / nx_email_mailbox_gate.nx

nx_email_mailbox_gate.nx source

↩ module page · 120 lines · 5791 B

1// nx_email_mailbox_gate.nx -- GATE for EMAIL R3 (mailbox store, nx_email_mailbox). 2// 3// REAL filesystem I/O against a fresh segment-store dir (the harness 4// rm -rf + mkdir's knowledge/status/mbox_test before each run): 5// 6// COMPLETENESS : deliver two messages; fetch each back BYTE-IDENTICAL; 7// fetch a never-delivered id -> absent. 8// SOFT-DELETE : tombstone msg-001; it disappears from the current 9// view (fetch -> tombstoned, exists -> 0) while msg-002 10// is unaffected (per-key isolation). 11// HISTORY : after delete, msg-001 still has 2 retained versions 12// (put + tombstone) -- Cardinal 13, nothing erased. 13// 14// Evidence -> knowledge/status/email_mailbox.log 15// (MBOXGATE authored=organ ... verdict=GREEN) 16// license_tier: ORIGINAL 17import "nx_email_mailbox.nx" 18import "nx_syscalls.nx" 19import "nx_gate_verdict.nx" 20 21const MBOX_LOG: *u8 = "knowledge/status/email_mailbox.log" 22const MBOX_PREFIX: *u8 = "knowledge/status/mbox_test/" 23 24func ew(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 25func ewn(fd: i64, v: i64) -> i64 { 26 let b: *u8 = sys_mmap(28); var m: i64 = v 27 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) } 28 let t: *u8 = sys_mmap(28); var k: i64 = 0 29 if m == 0 { t[0] = 48; k = 1 } 30 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 31 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 } 32 sys_write(fd, b, k); return 0 33} 34func epf(fd: i64, label: *u8, pass: i64) -> i64 { ew(fd, label); if pass == 1 { ew(fd, "PASS" as *u8) } else { ew(fd, "FAIL" as *u8) } return 0 } 35func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 36func memeq(a: *u8, b: *u8, len: i64) -> i64 { var i: i64 = 0; while i < len { if a[i] != b[i] { return 0 } i = i + 1 } return 1 } 37 38func main() -> i64 { 39 var ok: i64 = 1 40 // self-reset for idempotency (rule 10): ensure the store dir exists and 41 // empty its manifest so re-runs don't accumulate stale segments. The 42 // fixed segids 1/2/3 cause ss_write_seg (O_TRUNC) to overwrite seg files. 43 sys_mkdir("knowledge/status/mbox_test" as *u8, 511) 44 let rfd: i64 = sys_openat_wr("knowledge/status/mbox_test/manifest.txt" as *u8, 420) 45 if rfd >= 0 { sys_close(rfd) } 46 let pp: *i64 = sys_mmap(8) as *i64 47 let ll: *i64 = sys_mmap(8) as *i64 48 49 let msg1: *u8 = "Subject: Hello\r\nFrom: a@nishi.test\r\nMessage-ID: <msg-001>\r\n\r\nFirst message body.\r\n" as *u8 50 let msg2: *u8 = "Subject: Second\r\nFrom: b@nishi.test\r\nMessage-ID: <msg-002>\r\n\r\nSecond message body here.\r\n" as *u8 51 let m1len: i64 = slen(msg1) 52 let m2len: i64 = slen(msg2) 53 54 // deliver two 55 if nx_mbox_deliver(MBOX_PREFIX, "msg-001" as *u8, msg1, m1len, 1) != 0 { ok = 0 } 56 if nx_mbox_deliver(MBOX_PREFIX, "msg-002" as *u8, msg2, m2len, 2) != 0 { ok = 0 } 57 58 // fetch each back byte-identical 59 var fetch1: i64 = 0 60 if nx_mbox_fetch(MBOX_PREFIX, "msg-001" as *u8, pp, ll) == 1 { 61 if ll[0] == m1len && memeq(pp[0] as *u8, msg1, m1len) == 1 { fetch1 = 1 } 62 } 63 if fetch1 != 1 { ok = 0 } 64 var fetch2: i64 = 0 65 if nx_mbox_fetch(MBOX_PREFIX, "msg-002" as *u8, pp, ll) == 1 { 66 if ll[0] == m2len && memeq(pp[0] as *u8, msg2, m2len) == 1 { fetch2 = 1 } 67 } 68 if fetch2 != 1 { ok = 0 } 69 70 // absent id 71 var absent: i64 = 0 72 if nx_mbox_fetch(MBOX_PREFIX, "msg-999" as *u8, pp, ll) == (0 - 1) { absent = 1 } else { ok = 0 } 73 74 // soft-delete msg-001 75 if nx_mbox_delete(MBOX_PREFIX, "msg-001" as *u8, 3) != 0 { ok = 0 } 76 var softdel: i64 = 0 77 if nx_mbox_fetch(MBOX_PREFIX, "msg-001" as *u8, pp, ll) == 0 { softdel = 1 } else { ok = 0 } 78 let ex1: i64 = nx_mbox_exists(MBOX_PREFIX, "msg-001" as *u8) 79 let ex2: i64 = nx_mbox_exists(MBOX_PREFIX, "msg-002" as *u8) 80 var isolation: i64 = 0 81 if ex1 == 0 && ex2 == 1 { isolation = 1 } else { ok = 0 } 82 83 // history retained (put + tombstone) 84 let hist: i64 = nx_mbox_history_count(MBOX_PREFIX, "msg-001" as *u8) 85 var history_ok: i64 = 0 86 if hist == 2 { history_ok = 1 } else { ok = 0 } 87 88 // msg-002 still fetchable after deleting msg-001 89 var survive: i64 = 0 90 if nx_mbox_fetch(MBOX_PREFIX, "msg-002" as *u8, pp, ll) == 1 { survive = 1 } else { ok = 0 } 91 92 var fd: i64 = 1 93 while fd >= 1 { 94 ew(fd, "MBOXGATE authored=organ store=nx_seg_store " as *u8) 95 epf(fd, "fetch1_byteexact=" as *u8, fetch1) 96 epf(fd, " fetch2_byteexact=" as *u8, fetch2) 97 epf(fd, " absent_negctrl=" as *u8, absent) 98 epf(fd, " softdelete=" as *u8, softdel) 99 ew(fd, " exists_after_delete=" as *u8); ewn(fd, ex1) 100 epf(fd, " per_key_isolation=" as *u8, isolation) 101 ew(fd, " history_versions=" as *u8); ewn(fd, hist) 102 epf(fd, " history_retained=" as *u8, history_ok) 103 epf(fd, " neighbor_survives=" as *u8, survive) 104 if ok == 1 { ew(fd, " verdict=GREEN\n" as *u8) } else { ew(fd, " verdict=RED\n" as *u8) } 105 if fd == 1 { 106 let lf: i64 = sys_openat_append(MBOX_LOG, 420) 107 if lf >= 1 { fd = lf } else { fd = 0 } 108 } else { sys_close(fd); fd = 0 } 109 } 110 111 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 112 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 113 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 114 let ctr__dry: *i64 = gv_ctr() 115 ctr__dry[0] = ok 116 ctr__dry[1] = 1 117 let rc__dry: i64 = gv_verdict("EMAIL-MAILBOX-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 118 sys_exit(rc__dry) 119 return rc__dry 120}