code wiki / _hdl_build / nx_adnet_invoice_gate.nx

nx_adnet_invoice_gate.nx source

↩ module page · 131 lines · 8336 B

1// nx_adnet_invoice_gate.nx -- GATE for the billing pipeline (nx_adnet_invoice). 2// Independent re-derivation over fixture journals, not a call into the code under test to describe itself. 3// The teeth that matter are the REFUSALS -- a biller is dangerous in the direction of over-charging: 4// * an ad with NO rate row must emit an explicit REFUSED line, never a zero-priced or omitted one 5// * an ad measured but never viewable must bill 0, not its served count 6// * a rate card with a malformed number must REFUSE, not parse-to-zero 7// * SPEND (the number a budget ceiling consumes) must be UNMEASURABLE rather than 0 when unpriced -- 8// assuming zero spend is exactly how an exhausted campaign keeps serving 9// expect_exit: 0 license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "_hdl_build/nx_adnet_invoice.nx" 12import "nx_gate_verdict.nx" 13 14func ti_slen(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i } 15func ti_puts(s: *u8) -> i64 { sys_write(1, s, ti_slen(s)); return 0 } 16func ti_pn(v: i64) -> i64 { 17 let b: *u8 = sys_mmap(32) 18 if v == 0 { b[0] = 48 as u8; sys_write(1, b, 1); return 0 } 19 var n: i64 = 0 20 var x: i64 = v 21 while x > 0 { b[n] = ((x - (x / 10) * 10) + 48) as u8; n = n + 1; x = x / 10 } 22 let r: *u8 = sys_mmap(32) 23 var i: i64 = 0 24 while i < n { r[i] = b[n - 1 - i]; i = i + 1 } 25 sys_write(1, r, n) 26 return 0 27} 28func ti_has(buf: *u8, n: i64, pat: *u8) -> i64 { 29 let pl: i64 = ti_slen(pat) 30 if pl == 0 { return 0 } 31 if pl > n { return 0 } 32 var i: i64 = 0 33 while i <= n - pl { 34 var k: i64 = 0 35 var ok: i64 = 1 36 while k < pl { if buf[i + k] != pat[k] { ok = 0; break } k = k + 1 } 37 if ok == 1 { return 1 } 38 i = i + 1 39 } 40 return 0 41} 42func ti_check(name: *u8, cond: i64) -> i64 { 43 if cond == 1 { ti_puts(" PASS " as *u8) } else { ti_puts(" FAIL " as *u8) } 44 ti_puts(name); ti_puts("\n" as *u8) 45 return cond 46} 47 48func main() -> i64 { 49 ti_puts("=== nx_adnet_invoice_gate ===\n" as *u8) 50 var pass: i64 = 0 51 var total: i64 = 0 52 let buf: *u8 = sys_mmap(8192) 53 54 // fixtures: ha-video priced, ha-world DELIBERATELY unpriced, ha-bad has a malformed cpm 55 let rates: *u8 = "# id\tcpm_milli\tcpc_milli\tcap_milli\nha-video\t5000\t100\t-1\nha-bad\tzzz\t100\t-1\n" as *u8 56 let inv: *u8 = "@host\tnishifamily.com\nha-video\tNishi Video\t/synth/v.png\t/video\tany\t1\nha-world\tNishi World\t/synth/w.png\t/world\tany\t1\n" as *u8 57 let slog: *u8 = "ha-video\nha-video\nha-video\nha-video\nha-world\n" as *u8 58 let vlog: *u8 = "ha-video\n" as *u8 59 let clog: *u8 = "ha-video\n" as *u8 60 let rl: i64 = ti_slen(rates) 61 let il: i64 = ti_slen(inv) 62 let sl: i64 = ti_slen(slog) 63 let vl: i64 = ti_slen(vlog) 64 let cl: i64 = ti_slen(clog) 65 66 // ---- rate card parsing ---- 67 pass = pass + ti_check("rate lookup: cpm found" as *u8, ainv_rate(rates, rl, "ha-video" as *u8, 1) == 5000); total = total + 1 68 pass = pass + ti_check("rate lookup: cpc found" as *u8, ainv_rate(rates, rl, "ha-video" as *u8, 2) == 100); total = total + 1 69 pass = pass + ti_check("unpriced ad -> rate REFUSED" as *u8, ainv_rate(rates, rl, "ha-world" as *u8, 1) == 0 - 1); total = total + 1 70 pass = pass + ti_check("malformed rate -> REFUSED not zero" as *u8, ainv_rate(rates, rl, "ha-bad" as *u8, 1) == 0 - 1); total = total + 1 71 72 // ---- one priced line: served=4 viewable=1 clicks=1 cpm=5000 -> (1*5000)/1000 + 100 = 105 ---- 73 let n1: i64 = ainv_line_for(rates, rl, slog, sl, vlog, vl, clog, cl, "ha-video" as *u8, buf, 8192) 74 pass = pass + ti_check("priced ad -> line emitted" as *u8, n1 > 0); total = total + 1 75 pass = pass + ti_check("bills VIEWABLE=1 not SERVED=4 (due 105)" as *u8, ti_has(buf, n1, "due_milli=105" as *u8)); total = total + 1 76 pass = pass + ti_check("served=4 reported honestly" as *u8, ti_has(buf, n1, "served=4" as *u8)); total = total + 1 77 pass = pass + ti_check("delivery ratio 250 permille" as *u8, ti_has(buf, n1, "deliv_permille=250" as *u8)); total = total + 1 78 79 // ---- the refusal that protects the client ---- 80 let n2: i64 = ainv_line_for(rates, rl, slog, sl, vlog, vl, clog, cl, "ha-world" as *u8, buf, 8192) 81 pass = pass + ti_check("unpriced ad -> REFUSED line, not omitted" as *u8, ti_has(buf, n2, "due_milli=REFUSED" as *u8)); total = total + 1 82 pass = pass + ti_check("unpriced ad -> reason is named" as *u8, ti_has(buf, n2, "reason=no-rate-row" as *u8)); total = total + 1 83 84 // ---- full report covers EVERY inventory ad, priced or not ---- 85 let n3: i64 = ainv_report(inv, il, rates, rl, slog, sl, vlog, vl, clog, cl, buf, 8192) 86 pass = pass + ti_check("report covers the priced ad" as *u8, ti_has(buf, n3, "id=ha-video" as *u8)); total = total + 1 87 pass = pass + ti_check("report covers the UNPRICED ad too" as *u8, ti_has(buf, n3, "id=ha-world" as *u8)); total = total + 1 88 pass = pass + ti_check("report skips the @host directive row" as *u8, ti_has(buf, n3, "id=@host" as *u8) == 0); total = total + 1 89 90 // ---- SPEND: the number a budget ceiling consumes ---- 91 pass = pass + ti_check("spend for a priced ad = the viewable-basis figure (105)" as *u8, ainv_spent_milli(rates, rl, slog, sl, vlog, vl, clog, cl, "ha-video" as *u8) == 105); total = total + 1 92 pass = pass + ti_check("spend for an UNPRICED ad -> UNMEASURABLE, never 0" as *u8, ainv_spent_milli(rates, rl, slog, sl, vlog, vl, clog, cl, "ha-world" as *u8) == 0 - 1); total = total + 1 93 let forged: *u8 = "ha-video\nha-video\nha-video\nha-video\nha-video\nha-video\nha-video\nha-video\nha-video\nha-video\n" as *u8 94 pass = pass + ti_check("forged viewable > served -> spend UNMEASURABLE (cannot authorise)" as *u8, ainv_spent_milli(rates, rl, vlog, vl, forged, ti_slen(forged), clog, cl, "ha-video" as *u8) == 0 - 1); total = total + 1 95 pass = pass + ti_check("malformed ad id -> spend UNMEASURABLE" as *u8, ainv_spent_milli(rates, rl, slog, sl, vlog, vl, clog, cl, "bad id!" as *u8) == 0 - 1); total = total + 1 96 97 // ---- PER-ADVERTISER SCOPING: an advertiser must never see another's spend ---- 98 let camps2: *u8 = "camp-a acme /synth/v.png 1000 2000 -1 live 0 99camp-b rival /synth/w.png 1000 2000 -1 live 0 100" as *u8 101 let rates2: *u8 = "camp-a 5000 100 -1 102camp-b 7000 100 -1 103" as *u8 104 let slog2: *u8 = "camp-a 105camp-a 106camp-b 107" as *u8 108 let vlog2: *u8 = "camp-a 109camp-b 110" as *u8 111 let clog2: *u8 = "" as *u8 112 let c2: i64 = ti_slen(camps2) 113 let r2: i64 = ti_slen(rates2) 114 let n7: i64 = ainv_report_for_advertiser(camps2, c2, "acme" as *u8, rates2, r2, slog2, ti_slen(slog2), vlog2, ti_slen(vlog2), clog2, 0, buf, 8192) 115 pass = pass + ti_check("advertiser report emitted" as *u8, n7 > 0); total = total + 1 116 pass = pass + ti_check("includes OWN campaign" as *u8, ti_has(buf, n7, "id=camp-a" as *u8)); total = total + 1 117 pass = pass + ti_check("EXCLUDES a rival campaign (whitelist, not redaction)" as *u8, ti_has(buf, n7, "id=camp-b" as *u8) == 0); total = total + 1 118 pass = pass + ti_check("shows served and viewable side by side (the public promise)" as *u8, ti_has(buf, n7, "served=2" as *u8)); total = total + 1 119 pass = pass + ti_check("unknown advertiser -> empty report, not everyone's" as *u8, ainv_report_for_advertiser(camps2, c2, "nobody" as *u8, rates2, r2, slog2, ti_slen(slog2), vlog2, ti_slen(vlog2), clog2, 0, buf, 8192) == 0); total = total + 1 120 pass = pass + ti_check("malformed advertiser id -> empty, never a full dump" as *u8, ainv_report_for_advertiser(camps2, c2, "bad id!" as *u8, rates2, r2, slog2, ti_slen(slog2), vlog2, ti_slen(vlog2), clog2, 0, buf, 8192) == 0); total = total + 1 121 122 ti_puts("pass=" as *u8); ti_pn(pass); ti_puts(" fail=" as *u8); ti_pn(total - pass); ti_puts("\n" as *u8) 123 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 124 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 125 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 126 let ctr__dry: *i64 = gv_ctr() 127 ctr__dry[0] = pass 128 ctr__dry[1] = total 129 let rc__dry: i64 = gv_verdict("ADNET-INVOICE-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 130 sys_exit(rc__dry) 131 return rc__dry 132}