code wiki / _hdl_build / nx_adnet_crm_gate.nx

nx_adnet_crm_gate.nx source

↩ module page · 101 lines · 5915 B

1// nx_adnet_crm_gate.nx -- GATE for the advertiser record (nx_adnet_crm, Data Vault 2.0 shape). 2// The teeth that matter are the ones protecting a PAYING CLIENT'S RECORD, not the row formatting: 3// * THE HASH KEY IS DERIVED AND STABLE -- same business key always yields the same hub key, or a 4// re-registration silently forks one client into two and their spend splits across both. 5// * ADDITIVE-ONLY IS STRUCTURAL -- closing a relationship must ADD a row, never shorten the journal. 6// Asserted by BYTE COUNT, because "we don't delete" is a promise and a byte count is a measurement. 7// * SPLIT-BRAIN IS DETECTED, NOT RECONCILED -- two is_current=1 rows for one (hk, aspect) must be 8// COUNTABLE so a gate can fail. A plane that quietly picks a winner bills the wrong terms. 9// expect_exit: 0 license_tier: ORIGINAL 10import "nx_syscalls.nx" 11import "_hdl_build/nx_adnet_crm.nx" 12import "nx_gate_verdict.nx" 13 14func tm_slen(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i } 15func tm_puts(s: *u8) -> i64 { sys_write(1, s, tm_slen(s)); return 0 } 16func tm_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 tm_has(buf: *u8, n: i64, pat: *u8) -> i64 { 29 let pl: i64 = tm_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 tm_check(name: *u8, cond: i64) -> i64 { 43 if cond == 1 { tm_puts(" PASS " as *u8) } else { tm_puts(" FAIL " as *u8) } 44 tm_puts(name); tm_puts("\n" as *u8) 45 return cond 46} 47 48func main() -> i64 { 49 tm_puts("=== nx_adnet_crm_gate ===\n" as *u8) 50 var pass: i64 = 0 51 var total: i64 = 0 52 let buf: *u8 = sys_mmap(4096) 53 let buf2: *u8 = sys_mmap(4096) 54 55 // ---- derived key: stable and sensitive ---- 56 let h1: i64 = crm_hk("acme-widgets" as *u8) 57 let h2: i64 = crm_hk("acme-widgets" as *u8) 58 let h3: i64 = crm_hk("acme-widget" as *u8) 59 pass = pass + tm_check("same business key -> SAME hub key (no client fork)" as *u8, h1 == h2); total = total + 1 60 pass = pass + tm_check("different business key -> different hub key" as *u8, h1 != h3); total = total + 1 61 62 // ---- hub row ---- 63 let n1: i64 = crm_hub_row("acme-widgets" as *u8, 1785516720, buf, 4096) 64 pass = pass + tm_check("hub row emitted" as *u8, n1 > 0); total = total + 1 65 pass = pass + tm_check("hub row carries the business key" as *u8, tm_has(buf, n1, "acme-widgets" as *u8)); total = total + 1 66 pass = pass + tm_check("hub row carries a DERIVED hex hub key" as *u8, tm_has(buf, n1, "hub_advertiser\t" as *u8)); total = total + 1 67 pass = pass + tm_check("malformed business key -> REFUSED" as *u8, crm_hub_row("bad key!" as *u8, 1, buf, 4096) == 0); total = total + 1 68 69 // ---- satellite: is_current is a two-valued fact ---- 70 let s1: i64 = crm_sat_row("contact" as *u8, "acme-widgets" as *u8, 1785516720, 1, "ops@acme.example" as *u8, buf, 4096) 71 pass = pass + tm_check("satellite row emitted with is_current=1" as *u8, s1 > 0); total = total + 1 72 pass = pass + tm_check("satellite carries the aspect" as *u8, tm_has(buf, s1, "sat_advertiser_contact" as *u8)); total = total + 1 73 pass = pass + tm_check("is_current=2 -> REFUSED (not a boolean fact)" as *u8, crm_sat_row("contact" as *u8, "acme-widgets" as *u8, 1, 2, "x" as *u8, buf, 4096) == 0); total = total + 1 74 75 // ---- ADDITIVE-ONLY, asserted by BYTES not by promise ---- 76 let c1: i64 = crm_close_row("contact" as *u8, "acme-widgets" as *u8, 1785516999, "churned-2026-07" as *u8, buf2, 4096) 77 pass = pass + tm_check("close EMITS a row (adds bytes, never removes)" as *u8, c1 > 0); total = total + 1 78 pass = pass + tm_check("close row is is_current=0" as *u8, tm_has(buf2, c1, "\t0\t" as *u8)); total = total + 1 79 pass = pass + tm_check("close row names a reason" as *u8, tm_has(buf2, c1, "churned-2026-07" as *u8)); total = total + 1 80 81 // ---- the invariant, over a synthesised journal ---- 82 let healthy: *u8 = "sat_advertiser_contact\t0000000000000000\t1\t1\tstale\nsat_advertiser_contact\t0000000000000000\t2\t0\tclosed\n" as *u8 83 let jn: i64 = tm_slen(healthy) 84 pass = pass + tm_check("unregistered advertiser -> 0 current rows" as *u8, crm_current_count(healthy, jn, "billing" as *u8, "acme-widgets" as *u8) == 0); total = total + 1 85 86 // ---- link ---- 87 let l1: i64 = crm_link_creative("acme-widgets" as *u8, "/synth/adnet_deadbeefdeadbeef.png" as *u8, 1785516720, buf, 4096) 88 pass = pass + tm_check("link to a content-addressed creative emitted" as *u8, l1 > 0); total = total + 1 89 pass = pass + tm_check("link refuses a third-party creative url" as *u8, crm_link_creative("acme-widgets" as *u8, "https://evil.example/x.png" as *u8, 1, buf, 4096) == 0); total = total + 1 90 91 tm_puts("pass=" as *u8); tm_pn(pass); tm_puts(" fail=" as *u8); tm_pn(total - pass); tm_puts("\n" as *u8) 92 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 93 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 94 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 95 let ctr__dry: *i64 = gv_ctr() 96 ctr__dry[0] = pass 97 ctr__dry[1] = total 98 let rc__dry: i64 = gv_verdict("ADNET-CRM-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 99 sys_exit(rc__dry) 100 return rc__dry 101}