code wiki / (root) / nx_coa_gate.nx

nx_coa_gate.nx source

↩ module page · 163 lines · 7605 B

1// nx_coa_gate.nx -- F982 INDEPENDENT GATE: chart of accounts + period close. 2// Proves the sign convention actually inverts per account KIND, that the type->side map is genuinely 3// data-driven (a NEW kind invented at runtime works with no code change), that unknown types 4// FAIL CLOSED instead of guessing a side, and that a closed period refuses postings. 5// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 6 7import "nx_coa_lib.nx" 8 9func cg_puts(s: *u8) -> i64 { 10 var n: i64 = 0 11 while s[n] != (0 as u8) { n = n + 1 } 12 sys_write(1, s, n) 13 return 0 14} 15func cg_putn(v: i64) -> i64 { 16 let t: *u8 = sys_mmap(32) 17 var o: i64 = 0 18 var m: i64 = v 19 if m < 0 { t[o] = 45 as u8; o = o + 1; m = 0 - m } 20 let d: *u8 = sys_mmap(32) 21 var k: i64 = 0 22 if m == 0 { d[0] = 48 as u8; k = 1 } 23 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 24 var i: i64 = 0 25 while i < k { t[o] = d[k - 1 - i]; o = o + 1; i = i + 1 } 26 sys_write(1, t, o) 27 return 0 28} 29func cg_ck(cnt: *i64, name: *u8, got: i64, want: i64) -> i64 { 30 if got == want { 31 cnt[0] = cnt[0] + 1 32 cg_puts(" PASS " as *u8); cg_puts(name); cg_puts(" = " as *u8); cg_putn(got); cg_puts("\n" as *u8) 33 return 1 34 } 35 cnt[1] = cnt[1] + 1 36 cg_puts(" FAIL " as *u8); cg_puts(name); cg_puts(" got " as *u8); cg_putn(got) 37 cg_puts(" want " as *u8); cg_putn(want); cg_puts("\n" as *u8) 38 return 0 39} 40func cg_id(tag: *u8, nonce: i64, out: *u8) -> i64 { 41 var o: i64 = mt_catcopy(out, 0, tag) 42 o = mt_catn(out, o, nonce) 43 out[o] = 0 as u8 44 return o 45} 46 47func main(argc: i64, argv: *i64) -> i64 { 48 // FIXTURE MOVED OUT OF THE SWEPT STORE (2026-08-07). knowledge/store/ is walked every 600s by 49 // the nx_segguard beat; this gate's fixture is one of TEN measured as actually folded by it. A 50 // fold landing mid-run rewrites the manifest under the code being measured, so a RED could not 51 // be attributed. Proven on the sibling defect: the SAME code went RED on a knowledge/store 52 // fixture and GREEN 24/24 on a /tmp one -- the RED tracked the FIXTURE, not the code. 53 // Created at SETUP, not teardown: a teardown does not run when a run crashes. 54 sys_mkdir("/tmp/coagate\x00" as *u8, 0x1ed) 55 let lp: *u8 = "/tmp/coagate/coagate-led-" as *u8 56 let cp: *u8 = "/tmp/coagate/coagate-coa-" as *u8 57 let nonce: i64 = sys_now_us() 58 let cnt: *i64 = sys_mmap(16) as *i64 59 cnt[0] = 0 60 cnt[1] = 0 61 62 let cash: *u8 = sys_mmap(64) 63 let loan: *u8 = sys_mmap(64) 64 let ghost: *u8 = sys_mmap(64) 65 let weird: *u8 = sys_mmap(64) 66 // ★NONCE THE KIND TOO (2026-07-31). Every ACCOUNT here is nonced per run, but the KIND was the 67 // hardcoded literal "unobtainium" -- and C6 REGISTERS a side for it in a PERSISTENT plane 68 // (the coagate-coa- plane). So C5, which requires that kind to have NO registered side, 69 // passed only on a virgin store and failed on every run afterwards: the gate poisoned its own 70 // fixture and violated rule 10 (safe to run twice). Nonce it and the C5->C6 pair stays intact 71 // and idempotent, with no fixture deletion needed. 72 let wkind: *u8 = sys_mmap(64) 73 cg_id("cash_" as *u8, nonce, cash) 74 cg_id("loan_" as *u8, nonce, loan) 75 cg_id("ghost_" as *u8, nonce, ghost) 76 cg_id("weird_" as *u8, nonce, weird) 77 cg_id("unobtainium_" as *u8, nonce, wkind) 78 79 let x1: *u8 = sys_mmap(64) 80 let x2: *u8 = sys_mmap(64) 81 cg_id("cx1_" as *u8, nonce, x1) 82 cg_id("cx2_" as *u8, nonce, x2) 83 84 let per: *u8 = sys_mmap(64) 85 let per2: *u8 = sys_mmap(64) 86 cg_id("2026-07_" as *u8, nonce, per) 87 cg_id("2026-08_" as *u8, nonce, per2) 88 89 let out: *i64 = sys_mmap(16) as *i64 90 91 cg_puts("NISHI-COA-GATE (F982 chart of accounts + period close)\n" as *u8) 92 93 // data-driven side map 94 coa_type_put(cp, "asset" as *u8, "debit" as *u8) 95 coa_type_put(cp, "liability" as *u8, "credit" as *u8) 96 coa_put(cp, cash, "asset" as *u8) 97 coa_put(cp, loan, "liability" as *u8) 98 99 // fund cash $1000.00 from the loan: debits cash, credits loan 100 led_xfer(lp, x1, cash, loan, 100000, "posted" as *u8) 101 102 // ---- C1: the RAW ledger balance is credits-debits, so cash reads NEGATIVE ---- 103 cg_ck(cnt, "C1 raw led_balance(cash) is credits-debits" as *u8, led_balance(lp, cash), 0 - 100000) 104 105 // ---- C2: the CHART inverts it -- an asset reads its natural POSITIVE balance ---- 106 cg_ck(cnt, "C2 coa_natural(cash) resolved (1=ok)" as *u8, coa_natural(lp, cp, cash, out), 1) 107 cg_ck(cnt, "C2a asset natural balance is POSITIVE $1000.00" as *u8, out[0], 100000) 108 109 // ---- C3: a liability is credit-normal, so it also reads positive ---- 110 cg_ck(cnt, "C3 coa_natural(loan) resolved" as *u8, coa_natural(lp, cp, loan, out), 1) 111 cg_ck(cnt, "C3a liability natural balance is POSITIVE $1000.00" as *u8, out[0], 100000) 112 113 // ---- C4: FAIL-CLOSED -- an account with no registered type must NOT guess a side ---- 114 out[0] = 424242 115 cg_ck(cnt, "C4 unregistered account FAILS CLOSED (0)" as *u8, coa_natural(lp, cp, ghost, out), 0) 116 cg_ck(cnt, "C4a fail-closed wrote NOTHING to out" as *u8, out[0], 424242) 117 118 // ---- C5: FAIL-CLOSED -- a known account whose KIND has no registered side ---- 119 coa_put(cp, weird, wkind) 120 out[0] = 777777 121 cg_ck(cnt, "C5 unknown account KIND FAILS CLOSED (0)" as *u8, coa_natural(lp, cp, weird, out), 0) 122 cg_ck(cnt, "C5a fail-closed wrote NOTHING to out" as *u8, out[0], 777777) 123 124 // ---- C6: DATA-DRIVEN PROOF -- register the new kind's side at RUNTIME, no code change ---- 125 coa_type_put(cp, wkind, "credit" as *u8) 126 cg_ck(cnt, "C6 new account KIND works after a DATA write alone" as *u8, 127 coa_natural(lp, cp, weird, out), 1) 128 cg_ck(cnt, "C6a and it resolves to a real balance" as *u8, out[0], 0) 129 130 // ---- C7/C8: period close is a fail-closed posting guard ---- 131 cg_ck(cnt, "C7 open period ALLOWS posting" as *u8, coa_post_ok(cp, per), 1) 132 // C7a: the gate must PROVE its own setup landed. reg_put returns <0 on failure and 133 // coa_period_close returns it verbatim; discarding it made a FAILED CLOSE indistinguishable 134 // from a successful one, so the flake surfaced as whichever assertion read the store next 135 // (C8 in some runs, C2 in others -- a MOVING tooth is the signature of unchecked setup). 136 let cl1: i64 = coa_period_close(cp, per) 137 var cl1ok: i64 = 0 138 if cl1 >= 0 { cl1ok = 1 } 139 cg_ck(cnt, "C7a period close SUCCEEDS (setup proven, never assumed)" as *u8, cl1ok, 1) 140 cg_ck(cnt, "C8 closed period REFUSES posting" as *u8, coa_post_ok(cp, per), 0) 141 cg_ck(cnt, "C8a and reports itself closed" as *u8, coa_period_closed(cp, per), 1) 142 143 // ---- C9: closing is IDEMPOTENT (rule 10) ---- 144 let cl2: i64 = coa_period_close(cp, per) 145 var cl2ok: i64 = 0 146 if cl2 >= 0 { cl2ok = 1 } 147 cg_ck(cnt, "C9a re-close also SUCCEEDS (idempotent path is a write too)" as *u8, cl2ok, 1) 148 cg_ck(cnt, "C9 re-closing is idempotent, still closed" as *u8, coa_period_closed(cp, per), 1) 149 150 // ---- C10: closing ONE period must not lock the next ---- 151 cg_ck(cnt, "C10 the NEXT period is still open" as *u8, coa_post_ok(cp, per2), 1) 152 153 cg_puts("nx_coa_gate: pass=" as *u8); cg_putn(cnt[0]) 154 cg_puts(" fail=" as *u8); cg_putn(cnt[1]); cg_puts("\n" as *u8) 155 if cnt[1] == 0 { 156 cg_puts("F982 nx_coa: VERDICT=GREEN (sign per kind, data-driven side map, fail-closed on unknown, period lock)\n" as *u8) 157 sys_exit(0) 158 return 0 159 } 160 cg_puts("F982 nx_coa: VERDICT=RED\n" as *u8) 161 sys_exit(1) 162 return 1 163}