code wiki / (root) / nx_ledger_gate.nx

nx_ledger_gate.nx source

↩ module page · 186 lines · 8862 B

1// nx_ledger_gate.nx -- F981 INDEPENDENT GATE for the sovereign double-entry ledger. 2// Imports the lib and proves its contract by BEHAVIOUR on a live seg-store plane. 3// 4// ★NON-VACUITY NOTE (stated plainly rather than dressed up): conservation is STRUCTURAL here -- 5// one record carries BOTH legs (dr and cr), so a one-sided entry is INEXPRESSIBLE and a global 6// "drift == 0" assertion would be a TAUTOLOGY. Asserting it alone would be fake rigor. So the 7// measured tests are the ones that CAN fail: 8// * per-account balances summed across every account must total 0 -- this cross-checks the 9// per-account FILTER against global conservation; a broken match would break it. 10// * exact expected deltas (not merely non-zero) -- a sign flip or a wrong field would fail. 11// * every refusal path must refuse AND leave ZERO state change. 12// All assertions are DELTAS against a pre-read baseline, so the gate is re-runnable on a plane 13// that already holds history (append-only = prior runs persist by design). 14// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 15 16import "nx_ledger_lib.nx" 17 18const LG_PFX: i64 = 0 19 20func lg_puts(s: *u8) -> i64 { 21 var n: i64 = 0 22 while s[n] != (0 as u8) { n = n + 1 } 23 sys_write(1, s, n) 24 return 0 25} 26func lg_putn(v: i64) -> i64 { 27 let t: *u8 = sys_mmap(32) 28 var o: i64 = 0 29 var m: i64 = v 30 if m < 0 { t[o] = 45 as u8; o = o + 1; m = 0 - m } 31 let d: *u8 = sys_mmap(32) 32 var k: i64 = 0 33 if m == 0 { d[0] = 48 as u8; k = 1 } 34 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 35 var i: i64 = 0 36 while i < k { t[o] = d[k - 1 - i]; o = o + 1; i = i + 1 } 37 sys_write(1, t, o) 38 return 0 39} 40// cnt[0]=pass cnt[1]=fail -- counters live in an mmap'd slot (no module-level mutable globals) 41func lg_ck(cnt: *i64, name: *u8, got: i64, want: i64) -> i64 { 42 if got == want { 43 cnt[0] = cnt[0] + 1 44 lg_puts(" PASS " as *u8); lg_puts(name); lg_puts(" = " as *u8); lg_putn(got); lg_puts("\n" as *u8) 45 return 1 46 } 47 cnt[1] = cnt[1] + 1 48 lg_puts(" FAIL " as *u8); lg_puts(name); lg_puts(" got " as *u8); lg_putn(got) 49 lg_puts(" want " as *u8); lg_putn(want); lg_puts("\n" as *u8) 50 return 0 51} 52 53// build a run-unique id: <tag><nonce> 54func lg_id(tag: *u8, nonce: i64, out: *u8) -> i64 { 55 var o: i64 = mt_catcopy(out, 0, tag) 56 o = mt_catn(out, o, nonce) 57 out[o] = 0 as u8 58 return o 59} 60 61func main(argc: i64, argv: *i64) -> i64 { 62 // FIXTURE MOVED OUT OF THE SWEPT STORE (2026-08-07). knowledge/store/ is walked every 600s by the 63 // nx_segguard beat, which has folded THIS gate's fixture 17 times -- more than any other gate in 64 // the corpus. A fold landing mid-run rewrites the manifest under the code being measured, so a RED 65 // here could not be attributed to the ledger logic at all. Proven on the sibling defect: the SAME 66 // code went RED on a knowledge/store fixture and GREEN 24/24 on a /tmp one. 67 // The run-unique account names below were the earlier mitigation -- they keep the DELTAS clean but 68 // leave the plane accumulating in production, which is precisely what let it grow past the fold 69 // threshold. ★MAKING THE DATA UNIQUE IS NOT THE SAME AS MAKING THE LOCATION ISOLATED. 70 // Created at SETUP, not teardown: a teardown does not run when a run crashes. 71 sys_mkdir("/tmp/ledgergate\x00" as *u8, 0x1ed) 72 let pfx: *u8 = "/tmp/ledgergate/ledgergate-" as *u8 73 let nonce: i64 = sys_now_us() 74 let cnt: *i64 = sys_mmap(16) as *i64 75 cnt[0] = 0 76 cnt[1] = 0 77 78 // run-unique account names so deltas are clean even though the plane is append-only 79 let A: *u8 = sys_mmap(64) 80 let B: *u8 = sys_mmap(64) 81 let C: *u8 = sys_mmap(64) 82 lg_id("acctA" as *u8, nonce, A) 83 lg_id("acctB" as *u8, nonce, B) 84 lg_id("acctC" as *u8, nonce, C) 85 86 let i1: *u8 = sys_mmap(64) 87 let i2: *u8 = sys_mmap(64) 88 let i3: *u8 = sys_mmap(64) 89 let i4: *u8 = sys_mmap(64) 90 let i5: *u8 = sys_mmap(64) 91 lg_id("t1_" as *u8, nonce, i1) 92 lg_id("t2_" as *u8, nonce, i2) 93 lg_id("t3_" as *u8, nonce, i3) 94 lg_id("t4_" as *u8, nonce, i4) 95 lg_id("t5_" as *u8, nonce, i5) 96 97 lg_puts("NISHI-LEDGER-GATE (F981 double-entry, integer minor units)\n" as *u8) 98 99 // ---- T1/T2: a posted transfer moves EXACTLY the amount, both directions ---- 100 led_xfer(pfx, i1, A, B, 10000, "posted" as *u8) 101 lg_ck(cnt, "T1 debit side bal(A) after A->B $100.00" as *u8, led_balance(pfx, A), 0 - 10000) 102 lg_ck(cnt, "T2 credit side bal(B) after A->B $100.00" as *u8, led_balance(pfx, B), 10000) 103 104 // ---- T3: second transfer, exact cumulative deltas (a sign flip or wrong field fails here) ---- 105 led_xfer(pfx, i2, B, C, 2500, "posted" as *u8) 106 lg_ck(cnt, "T3 bal(B) after B->C $25.00" as *u8, led_balance(pfx, B), 7500) 107 108 // ---- T4: THE CROSS-CHECK -- per-account balances must sum to ZERO ---- 109 // NOT structural: this validates the per-account filter against global conservation. 110 let sum3: i64 = led_balance(pfx, A) + led_balance(pfx, B) + led_balance(pfx, C) 111 lg_ck(cnt, "T4 sum of per-account balances (conservation)" as *u8, sum3, 0) 112 113 // ---- T5/T6: refusals must refuse AND write nothing ---- 114 let bA: i64 = led_balance(pfx, A) 115 lg_ck(cnt, "T5 negative amount REFUSED" as *u8, led_xfer(pfx, i3, A, B, 0 - 500, "posted" as *u8), 0 - 1) 116 lg_ck(cnt, "T5b refusal left bal(A) untouched" as *u8, led_balance(pfx, A), bA) 117 lg_ck(cnt, "T6 self-transfer REFUSED" as *u8, led_xfer(pfx, i3, A, A, 500, "posted" as *u8), 0 - 2) 118 lg_ck(cnt, "T6b refusal left bal(A) untouched" as *u8, led_balance(pfx, A), bA) 119 120 // ---- T7/T8: two-phase pending reserves without moving posted money ---- 121 let bB: i64 = led_balance(pfx, B) 122 let avB: i64 = led_available(pfx, B) 123 led_xfer(pfx, i3, B, C, 1000, "pending" as *u8) 124 lg_ck(cnt, "T7 pending does NOT move posted bal(B)" as *u8, led_balance(pfx, B), bB) 125 lg_ck(cnt, "T8 pending DOES reduce available(B) by $10.00" as *u8, led_available(pfx, B), avB - 1000) 126 127 // ---- T9: post the pending -> money moves, available unchanged from the reserved state ---- 128 led_resolve(pfx, i3, "post" as *u8) 129 lg_ck(cnt, "T9 after post, bal(B) moved by the pending amount" as *u8, led_balance(pfx, B), bB - 1000) 130 131 // ---- T10/T11: a VOIDED pending must restore available and never touch posted ---- 132 let bB2: i64 = led_balance(pfx, B) 133 let avB2: i64 = led_available(pfx, B) 134 led_xfer(pfx, i4, B, C, 3000, "pending" as *u8) 135 led_resolve(pfx, i4, "void" as *u8) 136 lg_ck(cnt, "T10 voided pending left posted bal(B) unchanged" as *u8, led_balance(pfx, B), bB2) 137 lg_ck(cnt, "T11 voided pending RESTORED available(B)" as *u8, led_available(pfx, B), avB2) 138 139 // ---- T12/T13: linked chain atomicity -- underfunded chain writes NOTHING ---- 140 let ids: *i64 = sys_mmap(8 * 2) as *i64 141 let drs: *i64 = sys_mmap(8 * 2) as *i64 142 let crs: *i64 = sys_mmap(8 * 2) as *i64 143 let amts: *i64 = sys_mmap(8 * 2) as *i64 144 let c1: *u8 = sys_mmap(64) 145 let c2: *u8 = sys_mmap(64) 146 lg_id("c1_" as *u8, nonce, c1) 147 lg_id("c2_" as *u8, nonce, c2) 148 ids[0] = c1 as i64 149 ids[1] = c2 as i64 150 drs[0] = C as i64 151 drs[1] = C as i64 152 crs[0] = A as i64 153 crs[1] = B as i64 154 amts[0] = 500000 155 amts[1] = 500000 156 let bC: i64 = led_balance(pfx, C) 157 let bA2: i64 = led_balance(pfx, A) 158 lg_ck(cnt, "T12 underfunded chain REFUSED" as *u8, led_chain(pfx, ids, drs, crs, amts, 2, C), 0 - 3) 159 lg_ck(cnt, "T12b refused chain left bal(C) untouched (zero partial state)" as *u8, led_balance(pfx, C), bC) 160 lg_ck(cnt, "T12c refused chain left bal(A) untouched" as *u8, led_balance(pfx, A), bA2) 161 162 // ---- T13: a funded chain commits EVERY leg, conservation still holds ---- 163 amts[0] = 100 164 amts[1] = 100 165 lg_ck(cnt, "T13 funded chain committed both legs" as *u8, led_chain(pfx, ids, drs, crs, amts, 2, "" as *u8), 2) 166 let sum4: i64 = led_balance(pfx, A) + led_balance(pfx, B) + led_balance(pfx, C) 167 lg_ck(cnt, "T13b conservation holds after the chain" as *u8, sum4, 0) 168 169 // ---- T14: chain leg validation refuses the WHOLE chain on one bad leg ---- 170 amts[0] = 100 171 amts[1] = 0 - 5 172 let bC2: i64 = led_balance(pfx, C) 173 lg_ck(cnt, "T14 one bad leg REFUSES the whole chain" as *u8, led_chain(pfx, ids, drs, crs, amts, 2, "" as *u8), 0 - 1) 174 lg_ck(cnt, "T14b bad-leg refusal wrote NOTHING" as *u8, led_balance(pfx, C), bC2) 175 176 lg_puts("nx_ledger_gate: pass=" as *u8); lg_putn(cnt[0]) 177 lg_puts(" fail=" as *u8); lg_putn(cnt[1]); lg_puts("\n" as *u8) 178 if cnt[1] == 0 { 179 lg_puts("F981 nx_ledger: VERDICT=GREEN (conservation cross-checked, refusals leave zero state)\n" as *u8) 180 sys_exit(0) 181 return 0 182 } 183 lg_puts("F981 nx_ledger: VERDICT=RED\n" as *u8) 184 sys_exit(1) 185 return 1 186}