code wiki / _hdl_build / nx_apistack_idempotency_gate.nx
nx_apistack_idempotency_gate.nx source
↩ module page · 43 lines · 2988 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_apistack_idempotency_gate.nx -- hermetic gate for CAP-API-IDEMPOTENCY. Proves a keyed write is exactly-once:
4// a new key executes, a seen key returns the CACHED result (no re-execute), distinct keys are independent, and the
5// first result wins (a retry can't overwrite). Sovereign: nx_syscalls + nx_apistack_idempotency. expect_exit: 0
6import "nx_syscalls.nx"
7import "nx_apistack_idempotency.nx"
8
9func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
10" as *u8); return ok }
11func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
12func g_eq(a: *u8, b: *u8, n: i64) -> i64 { var i: i64=0; while i<n { if a[i]!=b[i] { return 0 } i=i+1 } return 1 }
13
14func main(argc: i64, argv: *i64) -> i64 {
15 gp("=== nx_apistack_idempotency_gate (exactly-once writes over /api) ===\n" as *u8)
16 let L: *u8 = "/tmp/id_ledger.tsv" as *u8
17 // fresh slate: truncate the ledger
18 let fd: i64 = sys_openat_wr(L, 0x1a4); if fd >= 0 { sys_close(fd) }
19 let K1: *u8 = "deploy-2026-07-01-abc" as *u8; let K1n: i64 = g_slen(K1)
20 let K2: *u8 = "restart-xyz" as *u8; let K2n: i64 = g_slen(K2)
21 var pass: i64 = 0; var fail: i64 = 0
22
23 // T1 new key -> not seen (must execute)
24 if id_seen(L, K1, K1n) == 0 { pass=pass+1; gp(" T1 new key -> NOT seen (executes) PASS\n" as *u8) } else { fail=fail+1; gp(" T1 FAIL\n" as *u8) }
25
26 // T2 record result -> now seen + cached result returned
27 id_record(L, K1, K1n, "{\"action\":\"DEPLOY\",\"rc\":0}" as *u8, g_slen("{\"action\":\"DEPLOY\",\"rc\":0}" as *u8))
28 let s2: i64 = id_seen(L, K1, K1n)
29 let rb: *u8 = sys_mmap(256); let rl: i64 = id_lookup(L, K1, K1n, rb, 256)
30 if s2 == 1 { if g_eq(rb, "{\"action\":\"DEPLOY\",\"rc\":0}" as *u8, rl) == 1 { pass=pass+1; gp(" T2 seen -> returns CACHED result (no re-execute) PASS\n" as *u8) } else { fail=fail+1; gp(" T2 FAIL cached content\n" as *u8) } } else { fail=fail+1; gp(" T2 FAIL not seen\n" as *u8) }
31
32 // T3 distinct key -> independent (not seen)
33 if id_seen(L, K2, K2n) == 0 { pass=pass+1; gp(" T3 distinct key -> independent (not seen) PASS\n" as *u8) } else { fail=fail+1; gp(" T3 FAIL\n" as *u8) }
34
35 // T4 first-write-wins: a retry recording a DIFFERENT result does not overwrite the cached one
36 id_record(L, K1, K1n, "{\"action\":\"DEPLOY\",\"rc\":99}" as *u8, g_slen("{\"action\":\"DEPLOY\",\"rc\":99}" as *u8))
37 let rb2: *u8 = sys_mmap(256); let rl2: i64 = id_lookup(L, K1, K1n, rb2, 256)
38 if g_eq(rb2, "{\"action\":\"DEPLOY\",\"rc\":0}" as *u8, rl2) == 1 { pass=pass+1; gp(" T4 first-write-wins (retry can't overwrite) PASS\n" as *u8) } else { fail=fail+1; gp(" T4 FAIL overwrote\n" as *u8) }
39
40 gp("RESULT pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail)
41 if fail == 0 { gp(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
42 gp(" verdict=RED\n" as *u8); sys_exit(1); return 1
43}