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}