code wiki / (root) / nx_billing_gate.nx

nx_billing_gate.nx source

↩ module page · 140 lines · 7443 B

1// nx_billing_gate.nx -- INDEPENDENT gate for time & billing (imports the SAME shipped 2// nx_billing_lib = atlas validation edge). Proves: per-matter time totals, matter isolation, 3// integer-cents exactness, RPC 1.15 fee application from trust, exact trust decrement, 4// NO-OVERDRAW refusal, and refused-leaves-trust-untouched. SELF-PUBLISHES 5// knowledge/status/office_billing_gate.log. license_tier: ORIGINAL 6 7import "nx_billing_lib.nx" 8import "nx_gate_verdict.nx" 9 10// '-', separating the base from the run id. NAMED because a bare 45 stored into a 11// byte is a character code no reader can decode -- the estate already names these 12// (MG_NL=10, MG_QU=34, MG_BSL=92) and a raw one beside them is the odd man out. 13const BG_DASH: i64 = 45 14// The widest decimal an i64 can print: 9223372036854775807 is 19 digits. The 15// scratch buffer is DERIVED from it rather than guessed. 16const BG_I64_DIGITS: i64 = 19 17 18// Build "<base><uq>-" in a fresh buffer, so every run gets its OWN scratch plane. 19// Sized from its inputs: the base text + the widest possible run id + the 20// separator + the NUL. The first cut wrote sys_mmap(128) and a bare 45 -- a 21// guessed capacity and an unnamed character code, i.e. exactly the two defects 22// this campaign existed to remove, caught only by running nx_magic over my own 23// edit. AN AUTHOR IS THE LAST PERSON WHO WILL NOTICE THEIR OWN MAGIC NUMBER. 24func bg_scratch(base: *u8, uq: i64) -> *u8 { 25 let p: *u8 = sys_mmap(reg_strlen(base) + BG_I64_DIGITS + 2) 26 var o: i64 = mt_catcopy(p, 0, base) 27 o = mt_catn(p, o, uq) 28 p[o] = BG_DASH as u8 29 o = o + 1 30 p[o] = 0 as u8 31 return p 32} 33 34func main() -> i64 { 35 var pass: i64 = 0 36 // PER-RUN UNIQUE SCRATCH. These planes are APPEND-ONLY, so a FIXED prefix made 37 // this gate GREEN exactly once per clean /tmp: run 1 leaves a $1050 38 // disbursement, run 2's trust can no longer cover the invoice, T4 refuses, and 39 // the gate reads RED while the code under test is perfect. MEASURED 2026-08-15: 40 // clean 7/7 GREEN, immediate re-run 6/7 RED, same binary both times. 41 // A teardown cannot fix this -- it does not run when a run crashes -- so the 42 // prefix itself carries the run identity and the staleness class is gone by 43 // construction. 44 let uq: i64 = sys_now_us() 45 let bp: *u8 = bg_scratch("/tmp/nx_billing_gate-" as *u8, uq) 46 let tp: *u8 = bg_scratch("/tmp/nx_billing_gatetrust-" as *u8, uq) 47 trust_put(tp, "acme" as *u8, 0, "M-001" as *u8, "deposit" as *u8, 200000) 48 bl_time_put(bp, "M-001" as *u8, 0, 250, 30000, "research" as *u8) 49 bl_time_put(bp, "M-001" as *u8, 1, 100, 30000, "drafting" as *u8) 50 bl_time_put(bp, "M-002" as *u8, 0, 1000, 30000, "trial" as *u8) 51 // ★MIGRATED onto nx_gate_verdict with PER-TOOTH gv_check. The old form counted into a bare `pass` 52 // and then printed ALL SEVEN tooth names concatenated regardless of outcome, so a 6/7 row never said 53 // WHICH conjunct failed -- the reader had to guess, and this row consequently sat unactioned in the 54 // fleet rollup. gv_check names each tooth as it runs and makes declared==executed by construction. 55 let ctr: *i64 = gv_ctr() 56 57 // Every measured value is captured FIRST and PRINTED below, because a gate that reports only a 58 // boolean cannot say why it failed. 59 let v_m001: i64 = bl_matter_total(bp, "M-001" as *u8) 60 let v_m002: i64 = bl_matter_total(bp, "M-002" as *u8) 61 let ep: *u8 = bg_scratch("/tmp/nx_billing_gateexact-" as *u8, uq) 62 bl_time_put(ep, "MX" as *u8, 0, 150, 33333, "x" as *u8) 63 let v_exact: i64 = bl_matter_total(ep, "MX" as *u8) 64 let applied: i64 = bl_bill_from_trust(bp, "acme" as *u8, "M-001" as *u8, tp, 1) 65 let v_bal1: i64 = trust_balance(tp, "acme" as *u8) 66 let m2: i64 = bl_bill_from_trust(bp, "acme" as *u8, "M-002" as *u8, tp, 2) 67 let v_bal2: i64 = trust_balance(tp, "acme" as *u8) 68 69 let dg: *u8 = sys_mmap(512) 70 var dgo: i64 = 0 71 dgo = mt_catcopy(dg, dgo, " values: m001=" as *u8) 72 dgo = mt_catn(dg, dgo, v_m001) 73 dgo = mt_catcopy(dg, dgo, " m002=" as *u8) 74 dgo = mt_catn(dg, dgo, v_m002) 75 dgo = mt_catcopy(dg, dgo, " exact=" as *u8) 76 dgo = mt_catn(dg, dgo, v_exact) 77 dgo = mt_catcopy(dg, dgo, " applied=" as *u8) 78 dgo = mt_catn(dg, dgo, applied) 79 dgo = mt_catcopy(dg, dgo, " bal_after_bill=" as *u8) 80 dgo = mt_catn(dg, dgo, v_bal1) 81 dgo = mt_catcopy(dg, dgo, " overdraw_rc=" as *u8) 82 dgo = mt_catn(dg, dgo, m2) 83 dgo = mt_catcopy(dg, dgo, " bal_after_refusal=" as *u8) 84 dgo = mt_catn(dg, dgo, v_bal2) 85 dg[dgo] = 10 as u8 86 dgo = dgo + 1 87 sys_write(1, dg, dgo) 88 89 var c: i64 = 0 90 if v_m001 == 105000 { c = 1 } 91 let r1: i64 = gv_check("time-total (M-001 = $750+$300 = 105000c)" as *u8, c, ctr) 92 c = 0 93 if v_m002 == 300000 { c = 1 } 94 let r2: i64 = gv_check("matter-isolation (M-002 tracked separately = 300000c)" as *u8, c, ctr) 95 c = 0 96 if v_exact == 49999 { c = 1 } 97 let r3: i64 = gv_check("integer-cents-exact (150 x 33333 / 100 = 49999c, no float drift)" as *u8, c, ctr) 98 c = 0 99 if applied == 105000 { c = 1 } 100 let r4: i64 = gv_check("bill-from-trust (trust covers the invoice -> applied 105000c)" as *u8, c, ctr) 101 c = 0 102 if v_bal1 == 95000 { c = 1 } 103 let r5: i64 = gv_check("trust-decremented (200000c - 105000c = 95000c exactly)" as *u8, c, ctr) 104 c = 0 105 if m2 == 0 - 1 { c = 1 } 106 let r6: i64 = gv_check("neg-control-no-overdraw-refused (M-002 300000c > 95000c -> REFUSE)" as *u8, c, ctr) 107 c = 0 108 if v_bal2 == 95000 { c = 1 } 109 let r7: i64 = gv_check("refused-untouched (a refused billing moves no money)" as *u8, c, ctr) 110 111 pass = ctr[0] 112 113 let out: *u8 = sys_mmap(512) 114 var o: i64 = 0 115 o = mt_catcopy(out, o, "OFFICE-BILLING-GATE tests=7 pass=" as *u8) 116 o = mt_catn(out, o, pass) 117 // ★The middle field now names the FAILING teeth instead of reciting the full roster. It used to 118 // print all seven names concatenated whatever the outcome, so the fleet rollup -- which shows only 119 // this one line -- reported "tests=7 pass=6" beside a list in which SIX of the seven names were 120 // passing teeth. A row that cannot name its failing conjunct is one nobody can act on, and this one 121 // sat unactioned for exactly that reason. Field ORDER and the trailing VERDICT= are unchanged, so 122 // the rollup's parse is untouched (rule 19). 123 o = mt_catcopy(out, o, " failed=" as *u8) 124 if pass == 7 { o = mt_catcopy(out, o, "(none)" as *u8) } 125 if r1 == 0 { o = mt_catcopy(out, o, "time-total," as *u8) } 126 if r2 == 0 { o = mt_catcopy(out, o, "matter-isolation," as *u8) } 127 if r3 == 0 { o = mt_catcopy(out, o, "integer-cents-exact," as *u8) } 128 if r4 == 0 { o = mt_catcopy(out, o, "bill-from-trust," as *u8) } 129 if r5 == 0 { o = mt_catcopy(out, o, "trust-decremented," as *u8) } 130 if r6 == 0 { o = mt_catcopy(out, o, "no-overdraw-refused," as *u8) } 131 if r7 == 0 { o = mt_catcopy(out, o, "refused-untouched," as *u8) } 132 o = mt_catcopy(out, o, " VERDICT=" as *u8) 133 if pass == 7 { o = mt_catcopy(out, o, "GREEN" as *u8) } 134 if pass != 7 { o = mt_catcopy(out, o, "RED" as *u8) } 135 out[o] = 10 as u8 136 o = o + 1 137 ss_writefile("knowledge/status/office_billing_gate.log" as *u8, out, o) 138 sys_write(1, out, o) 139 return gv_verdict("OFFICE-BILLING-GATE" as *u8, ctr, "teeth unchanged; per-tooth gv_check names the failing conjunct, and the log line now carries failed=" as *u8) 140}