code wiki / (root) / nx_toolcall_idem_gate.nx

nx_toolcall_idem_gate.nx source

↩ module page · 91 lines · 6304 B

1// nx_toolcall_idem_gate.nx -- IN-PROCESS gate over nx_toolcall_idem_lib (/compare/dataio DI4 ta_idempotency_key). 2// Fixtures under /tmp/<gate>/ (never a production plane). Proves: the decision states, the reservation, the replay, 3// the release, the row grammar, the digest naming -- and named negatives (a key with whitespace is refused before 4// anything executes; a second key never sees the first's outcome; two keys never share a digest name). 5// exit: 0 GREEN / 1 RED (gv_verdict law). 6import "nx_syscalls.nx" 7import "nx_gate_verdict.nx" 8import "nx_gatekit_lib.nx" 9import "nx_toolcall_idem_lib.nx" 10 11const TG_DIR: *u8 = "/tmp/nx_toolcall_idem_gate" as *u8 12const TG_LEDGER: *u8 = "/tmp/nx_toolcall_idem_gate/toolcall_idem.jrnl" as *u8 13const TG_NOW: i64 = 1788640000 14 15func tg_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 } 16func tg_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] == b[i] { if a[i] == (0 as u8) { return 1 } i = i + 1 } return 0 } 17 18func main() -> i64 { 19 let ctr: *i64 = gv_ctr() 20 gv_head("nx_toolcall_idem_gate -- a keyed tools/call is reserved, applied once, replayed, or released" as *u8) 21 gk_mkdir(TG_DIR) 22 gk_rm(TG_LEDGER) 23 let hex: *u8 = sys_mmap(TI_HEX_CH + 8) 24 let row: *u8 = sys_mmap(TI_ROW_CAP) 25 let k1: *u8 = "seat-a/write-42" as *u8 26 let k2: *u8 = "seat-a/write-43" as *u8 27 let kbad: *u8 = "has space" as *u8 28 let ktab: *u8 = sys_mmap(16) 29 ktab[0] = 104 as u8 30 ktab[1] = 97 as u8 31 ktab[2] = 115 as u8 32 ktab[3] = 9 as u8 33 ktab[4] = 116 as u8 34 ktab[5] = 0 as u8 35 // the fixture must start clean: no claims for the keys used here 36 ti_key_hex(k1, ti_slen(k1), hex) 37 ti_release(TG_DIR, hex) 38 ti_key_hex(k2, ti_slen(k2), hex) 39 ti_release(TG_DIR, hex) 40 41 gv_check_eq("T1 no key present (pointer 0) is NOKEY: the call behaves exactly as before" as *u8, ti_classify(TG_LEDGER, TG_DIR, 0 as *u8, 0, hex, row, TI_ROW_CAP, TG_NOW), TI_NOKEY, ctr) 42 gv_check_eq("neg-control-T2 a key with a SPACE is BADKEY before anything executes" as *u8, ti_classify(TG_LEDGER, TG_DIR, kbad, ti_slen(kbad), hex, row, TI_ROW_CAP, TG_NOW), TI_BADKEY, ctr) 43 gv_check_eq("neg-control-T3 a key with a TAB is BADKEY (it would corrupt the ledger row)" as *u8, ti_classify(TG_LEDGER, TG_DIR, ktab, ti_slen(ktab), hex, row, TI_ROW_CAP, TG_NOW), TI_BADKEY, ctr) 44 gv_check_eq("T4 an empty-but-present key is BADKEY, not NOKEY" as *u8, ti_classify(TG_LEDGER, TG_DIR, k1, 0, hex, row, TI_ROW_CAP, TG_NOW), TI_BADKEY, ctr) 45 46 let st1: i64 = ti_classify(TG_LEDGER, TG_DIR, k1, ti_slen(k1), hex, row, TI_ROW_CAP, TG_NOW) 47 gv_check_eq("T5 a fresh key is NEW (reserved by this call)" as *u8, st1, TI_NEW, ctr) 48 let cp: *u8 = sys_mmap(TI_PATH_CAP) 49 ti_claim_path(TG_DIR, hex, cp) 50 gv_check("T5b fixture reached the condition: the claim file exists after NEW" as *u8, tg_exists(cp), ctr) 51 gv_check_eq("T5c the claim carries its reservation time (age 0 s at the same clock)" as *u8, ti_claim_age(TG_DIR, hex, TG_NOW), 0, ctr) 52 gv_check_eq("T6 the same key again, before any outcome is recorded, is INFLIGHT (never executed twice)" as *u8, ti_classify(TG_LEDGER, TG_DIR, k1, ti_slen(k1), hex, row, TI_ROW_CAP, TG_NOW), TI_INFLIGHT, ctr) 53 54 let arow: *u8 = sys_mmap(TI_ROW_CAP) 55 let arl: i64 = ti_row_job(arow, TI_ROW_CAP, "async" as *u8, "nx_fs_write" as *u8, 11, 1788640077) 56 gv_check("T7 the async outcome row reads lane=async tool=nx_fs_write job=1788640077" as *u8, tg_streq(arow, "lane=async tool=nx_fs_write job=1788640077" as *u8), ctr) 57 gv_check_eq("T7b the row records under the key (first-write-wins ledger)" as *u8, ti_record(TG_LEDGER, k1, ti_slen(k1), arow, arl), 1, ctr) 58 let st2: i64 = ti_classify(TG_LEDGER, TG_DIR, k1, ti_slen(k1), hex, row, TI_ROW_CAP, TG_NOW) 59 gv_check_eq("T8 the same key after the record is REPLAY (the first outcome, never a second execution)" as *u8, st2, TI_REPLAY, ctr) 60 gv_check_eq("T8b the replayed row hands back the job id" as *u8, ti_row_int(row, "job=" as *u8), 1788640077, ctr) 61 gv_check("T8c the replayed row is the recorded row, byte for byte" as *u8, tg_streq(row, arow), ctr) 62 63 let st3: i64 = ti_classify(TG_LEDGER, TG_DIR, k2, ti_slen(k2), hex, row, TI_ROW_CAP, TG_NOW) 64 gv_check_eq("neg-control-T9 a DIFFERENT key never sees the first key's outcome: NEW" as *u8, st3, TI_NEW, ctr) 65 gv_check_eq("T10 releasing an unrecorded key makes it NEW again (a refusal must be judged afresh)" as *u8, ti_release(TG_DIR, hex), 1, ctr) 66 gv_check_eq("T10b after release the key reserves again" as *u8, ti_classify(TG_LEDGER, TG_DIR, k2, ti_slen(k2), hex, row, TI_ROW_CAP, TG_NOW), TI_NEW, ctr) 67 68 let srow: *u8 = sys_mmap(TI_ROW_CAP) 69 ti_row_sync(srow, TI_ROW_CAP, "sync" as *u8, "nx_fs" as *u8, 5, 3, 12, TG_DIR, hex) 70 gv_check("T11 the sync outcome row carries exit, bytes and the replay artifact path" as *u8, ti_row_has(srow, "lane=sync tool=nx_fs exit=3 bytes=12 out=/tmp/nx_toolcall_idem_gate/idem_" as *u8), ctr) 71 gv_check_eq("T11b the sync row's exit parses back" as *u8, ti_row_int(srow, "exit=" as *u8), 3, ctr) 72 73 let h1: *u8 = sys_mmap(TI_HEX_CH + 8) 74 let h1b: *u8 = sys_mmap(TI_HEX_CH + 8) 75 let h2: *u8 = sys_mmap(TI_HEX_CH + 8) 76 ti_key_hex(k1, ti_slen(k1), h1) 77 ti_key_hex(k1, ti_slen(k1), h1b) 78 ti_key_hex(k2, ti_slen(k2), h2) 79 gv_check_eq("T12 the digest name is 16 hex chars" as *u8, ti_slen(h1), TI_HEX_CH, ctr) 80 gv_check("T12b the digest name is deterministic for one key" as *u8, tg_streq(h1, h1b), ctr) 81 gv_check("neg-control-T12c two keys never share a digest name" as *u8, (tg_streq(h1, h2) == 0) as i64, ctr) 82 gv_check_eq("T13 an absent claim has no age (-1), so a caller is never told a fake age" as *u8, ti_claim_age(TG_DIR, "0000000000000000" as *u8, TG_NOW), 0 - 1, ctr) 83 84 // leave the fixture clean for the next run 85 ti_key_hex(k1, ti_slen(k1), hex) 86 ti_release(TG_DIR, hex) 87 ti_key_hex(k2, ti_slen(k2), hex) 88 ti_release(TG_DIR, hex) 89 gk_rm(TG_LEDGER) 90 return gv_verdict("nx_toolcall_idem_gate" as *u8, ctr, "a keyed call is reserved before it executes, applied once, replayed from its recorded outcome, released when nothing was applied, and refused when the key is not a token" as *u8) 91}